Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bbdd39ca85 | ||
|
|
449aa491ee | ||
|
|
0a958c3bf6 | ||
|
|
b9cc73bfdd | ||
|
|
72a1c612b6 | ||
|
|
847412de2a | ||
|
|
5f760e5c67 | ||
|
|
fd582a8059 | ||
|
|
d77d6be968 | ||
|
|
6be8e4c4f3 | ||
|
|
4c0770a03a | ||
|
|
e7fa947298 | ||
|
|
5b8ad106ac | ||
|
|
2817355eb2 | ||
|
|
07b4b2ebb7 | ||
|
|
0360c1f6d5 | ||
|
|
30a917c464 | ||
|
|
3f52f0eb0d | ||
|
|
be2c2e60c9 | ||
|
|
e5ed803156 |
@@ -1,45 +0,0 @@
|
|||||||
name: Build and Deploy to GitHub Pages
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ master ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v4
|
|
||||||
with:
|
|
||||||
python-version: '3.x'
|
|
||||||
|
|
||||||
- name: Set up Emscripten
|
|
||||||
uses: mymindstorm/setup-emsdk@v14
|
|
||||||
with:
|
|
||||||
version: 3.1.55
|
|
||||||
|
|
||||||
- name: Generate data.pak
|
|
||||||
run: |
|
|
||||||
python3 makepak.py Data data.pak
|
|
||||||
|
|
||||||
- name: Build with emcc
|
|
||||||
run: |
|
|
||||||
make -f Makefile.emcc
|
|
||||||
|
|
||||||
- name: Prepare deployment folder
|
|
||||||
run: |
|
|
||||||
mkdir deploy
|
|
||||||
cp index.html deploy/
|
|
||||||
cp index.js deploy/
|
|
||||||
cp index.wasm deploy/
|
|
||||||
cp data.pak deploy/
|
|
||||||
|
|
||||||
- name: Deploy to GitHub Pages
|
|
||||||
uses: peaceiris/actions-gh-pages@v4
|
|
||||||
with:
|
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
publish_dir: ./deploy
|
|
||||||
-56
@@ -1,56 +0,0 @@
|
|||||||
# Prerequisites
|
|
||||||
*.d
|
|
||||||
|
|
||||||
# Compiled Object files
|
|
||||||
*.slo
|
|
||||||
*.lo
|
|
||||||
*.o
|
|
||||||
*.obj
|
|
||||||
|
|
||||||
# Precompiled Headers
|
|
||||||
*.gch
|
|
||||||
*.pch
|
|
||||||
|
|
||||||
# Linker files
|
|
||||||
*.ilk
|
|
||||||
|
|
||||||
# Debugger Files
|
|
||||||
*.pdb
|
|
||||||
|
|
||||||
# Compiled Dynamic libraries
|
|
||||||
*.so
|
|
||||||
*.dylib
|
|
||||||
*.dll
|
|
||||||
|
|
||||||
# Fortran module files
|
|
||||||
*.mod
|
|
||||||
*.smod
|
|
||||||
|
|
||||||
# Compiled Static libraries
|
|
||||||
*.lai
|
|
||||||
*.la
|
|
||||||
*.a
|
|
||||||
*.lib
|
|
||||||
|
|
||||||
# Executables
|
|
||||||
*.exe
|
|
||||||
*.out
|
|
||||||
*.app
|
|
||||||
|
|
||||||
# debug information files
|
|
||||||
*.dwo
|
|
||||||
|
|
||||||
# Binary archives
|
|
||||||
[Dd]ata.pak
|
|
||||||
|
|
||||||
# Misc
|
|
||||||
[Oo]utdated
|
|
||||||
[Jj]unk
|
|
||||||
[Tt]rash
|
|
||||||
[Oo]ld
|
|
||||||
|
|
||||||
# Binaries
|
|
||||||
eulamadness
|
|
||||||
eulamadness.html
|
|
||||||
eulamadness.wasm
|
|
||||||
eulamadness.js
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
Bitmap font by gnsh
|
|
||||||
https://opengameart.org/content/bitmap-font-0
|
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,3 +0,0 @@
|
|||||||
Bitmap font by gnsh
|
|
||||||
https://opengameart.org/content/bitmap-font-0
|
|
||||||
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
Texture Texture/Font.bmp
|
|
||||||
Frame 200 60 5 12
|
|
||||||
Frame 205 60 5 12
|
|
||||||
Frame 210 60 5 12
|
|
||||||
Frame 215 60 5 12
|
|
||||||
Frame 220 60 5 12
|
|
||||||
Frame 225 60 5 12
|
|
||||||
Frame 230 60 5 12
|
|
||||||
Frame 235 60 5 12
|
|
||||||
Frame 240 60 5 12
|
|
||||||
Frame 245 60 5 12
|
|
||||||
Frame 250 60 5 12
|
|
||||||
Frame 255 60 5 12
|
|
||||||
Frame 260 60 5 12
|
|
||||||
Frame 265 60 5 12
|
|
||||||
Frame 270 60 5 12
|
|
||||||
Frame 275 60 5 12
|
|
||||||
Frame 280 60 5 12
|
|
||||||
Frame 285 60 5 12
|
|
||||||
Frame 290 60 5 12
|
|
||||||
Frame 295 60 5 12
|
|
||||||
Frame 200 72 5 12
|
|
||||||
Frame 205 72 5 12
|
|
||||||
Frame 210 72 5 12
|
|
||||||
Frame 215 72 5 12
|
|
||||||
Frame 220 72 5 12
|
|
||||||
Frame 225 72 5 12
|
|
||||||
Frame 230 72 5 12
|
|
||||||
Frame 235 72 5 12
|
|
||||||
Frame 240 72 5 12
|
|
||||||
Frame 245 72 5 12
|
|
||||||
Frame 250 72 5 12
|
|
||||||
Frame 255 72 5 12
|
|
||||||
Frame 260 72 5 12
|
|
||||||
Frame 265 72 5 12
|
|
||||||
Frame 270 72 5 12
|
|
||||||
Frame 275 72 5 12
|
|
||||||
Frame 280 72 5 12
|
|
||||||
Frame 285 72 5 12
|
|
||||||
Frame 290 72 5 12
|
|
||||||
Frame 295 72 5 12
|
|
||||||
Frame 200 84 5 12
|
|
||||||
Frame 205 84 5 12
|
|
||||||
Frame 210 84 5 12
|
|
||||||
Frame 215 84 5 12
|
|
||||||
Frame 220 84 5 12
|
|
||||||
Frame 225 84 5 12
|
|
||||||
Frame 230 84 5 12
|
|
||||||
Frame 235 84 5 12
|
|
||||||
Frame 240 84 5 12
|
|
||||||
Frame 245 84 5 12
|
|
||||||
Frame 250 84 5 12
|
|
||||||
Frame 255 84 5 12
|
|
||||||
Frame 260 84 5 12
|
|
||||||
Frame 265 84 5 12
|
|
||||||
Frame 270 84 5 12
|
|
||||||
Frame 275 84 5 12
|
|
||||||
Frame 280 84 5 12
|
|
||||||
Frame 285 84 5 12
|
|
||||||
Frame 290 84 5 12
|
|
||||||
Frame 295 84 5 12
|
|
||||||
Frame 200 96 5 12
|
|
||||||
Frame 205 96 5 12
|
|
||||||
Frame 210 96 5 12
|
|
||||||
Frame 215 96 5 12
|
|
||||||
Frame 220 96 5 12
|
|
||||||
Frame 225 96 5 12
|
|
||||||
Frame 230 96 5 12
|
|
||||||
Frame 235 96 5 12
|
|
||||||
Frame 240 96 5 12
|
|
||||||
Frame 245 96 5 12
|
|
||||||
Frame 250 96 5 12
|
|
||||||
Frame 255 96 5 12
|
|
||||||
Frame 260 96 5 12
|
|
||||||
Frame 265 96 5 12
|
|
||||||
Frame 270 96 5 12
|
|
||||||
Frame 275 96 5 12
|
|
||||||
Frame 280 96 5 12
|
|
||||||
Frame 285 96 5 12
|
|
||||||
Frame 290 96 5 12
|
|
||||||
Frame 295 96 5 12
|
|
||||||
Frame 200 108 5 12
|
|
||||||
Frame 205 108 5 12
|
|
||||||
Frame 210 108 5 12
|
|
||||||
Frame 215 108 5 12
|
|
||||||
Frame 220 108 5 12
|
|
||||||
Frame 225 108 5 12
|
|
||||||
Frame 230 108 5 12
|
|
||||||
Frame 235 108 5 12
|
|
||||||
Frame 240 108 5 12
|
|
||||||
Frame 245 108 5 12
|
|
||||||
Frame 250 108 5 12
|
|
||||||
Frame 255 108 5 12
|
|
||||||
Frame 260 108 5 12
|
|
||||||
Frame 265 108 5 12
|
|
||||||
Frame 270 108 5 12
|
|
||||||
Frame 275 108 5 12
|
|
||||||
Frame 280 108 5 12
|
|
||||||
Frame 285 108 5 12
|
|
||||||
Frame 290 108 5 12
|
|
||||||
Frame 295 108 5 12
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
Texture Texture/Font.bmp
|
|
||||||
Frame 0 0 5 12
|
|
||||||
Frame 5 0 5 12
|
|
||||||
Frame 10 0 5 12
|
|
||||||
Frame 15 0 5 12
|
|
||||||
Frame 20 0 5 12
|
|
||||||
Frame 25 0 5 12
|
|
||||||
Frame 30 0 5 12
|
|
||||||
Frame 35 0 5 12
|
|
||||||
Frame 40 0 5 12
|
|
||||||
Frame 45 0 5 12
|
|
||||||
Frame 50 0 5 12
|
|
||||||
Frame 55 0 5 12
|
|
||||||
Frame 60 0 5 12
|
|
||||||
Frame 65 0 5 12
|
|
||||||
Frame 70 0 5 12
|
|
||||||
Frame 75 0 5 12
|
|
||||||
Frame 80 0 5 12
|
|
||||||
Frame 85 0 5 12
|
|
||||||
Frame 90 0 5 12
|
|
||||||
Frame 95 0 5 12
|
|
||||||
Frame 0 12 5 12
|
|
||||||
Frame 5 12 5 12
|
|
||||||
Frame 10 12 5 12
|
|
||||||
Frame 15 12 5 12
|
|
||||||
Frame 20 12 5 12
|
|
||||||
Frame 25 12 5 12
|
|
||||||
Frame 30 12 5 12
|
|
||||||
Frame 35 12 5 12
|
|
||||||
Frame 40 12 5 12
|
|
||||||
Frame 45 12 5 12
|
|
||||||
Frame 50 12 5 12
|
|
||||||
Frame 55 12 5 12
|
|
||||||
Frame 60 12 5 12
|
|
||||||
Frame 65 12 5 12
|
|
||||||
Frame 70 12 5 12
|
|
||||||
Frame 75 12 5 12
|
|
||||||
Frame 80 12 5 12
|
|
||||||
Frame 85 12 5 12
|
|
||||||
Frame 90 12 5 12
|
|
||||||
Frame 95 12 5 12
|
|
||||||
Frame 0 24 5 12
|
|
||||||
Frame 5 24 5 12
|
|
||||||
Frame 10 24 5 12
|
|
||||||
Frame 15 24 5 12
|
|
||||||
Frame 20 24 5 12
|
|
||||||
Frame 25 24 5 12
|
|
||||||
Frame 30 24 5 12
|
|
||||||
Frame 35 24 5 12
|
|
||||||
Frame 40 24 5 12
|
|
||||||
Frame 45 24 5 12
|
|
||||||
Frame 50 24 5 12
|
|
||||||
Frame 55 24 5 12
|
|
||||||
Frame 60 24 5 12
|
|
||||||
Frame 65 24 5 12
|
|
||||||
Frame 70 24 5 12
|
|
||||||
Frame 75 24 5 12
|
|
||||||
Frame 80 24 5 12
|
|
||||||
Frame 85 24 5 12
|
|
||||||
Frame 90 24 5 12
|
|
||||||
Frame 95 24 5 12
|
|
||||||
Frame 0 36 5 12
|
|
||||||
Frame 5 36 5 12
|
|
||||||
Frame 10 36 5 12
|
|
||||||
Frame 15 36 5 12
|
|
||||||
Frame 20 36 5 12
|
|
||||||
Frame 25 36 5 12
|
|
||||||
Frame 30 36 5 12
|
|
||||||
Frame 35 36 5 12
|
|
||||||
Frame 40 36 5 12
|
|
||||||
Frame 45 36 5 12
|
|
||||||
Frame 50 36 5 12
|
|
||||||
Frame 55 36 5 12
|
|
||||||
Frame 60 36 5 12
|
|
||||||
Frame 65 36 5 12
|
|
||||||
Frame 70 36 5 12
|
|
||||||
Frame 75 36 5 12
|
|
||||||
Frame 80 36 5 12
|
|
||||||
Frame 85 36 5 12
|
|
||||||
Frame 90 36 5 12
|
|
||||||
Frame 95 36 5 12
|
|
||||||
Frame 0 48 5 12
|
|
||||||
Frame 5 48 5 12
|
|
||||||
Frame 10 48 5 12
|
|
||||||
Frame 15 48 5 12
|
|
||||||
Frame 20 48 5 12
|
|
||||||
Frame 25 48 5 12
|
|
||||||
Frame 30 48 5 12
|
|
||||||
Frame 35 48 5 12
|
|
||||||
Frame 40 48 5 12
|
|
||||||
Frame 45 48 5 12
|
|
||||||
Frame 50 48 5 12
|
|
||||||
Frame 55 48 5 12
|
|
||||||
Frame 60 48 5 12
|
|
||||||
Frame 65 48 5 12
|
|
||||||
Frame 70 48 5 12
|
|
||||||
Frame 75 48 5 12
|
|
||||||
Frame 80 48 5 12
|
|
||||||
Frame 85 48 5 12
|
|
||||||
Frame 90 48 5 12
|
|
||||||
Frame 95 48 5 12
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
Texture Texture/Font.bmp
|
|
||||||
Frame 0 120 5 12
|
|
||||||
Frame 5 120 5 12
|
|
||||||
Frame 10 120 5 12
|
|
||||||
Frame 15 120 5 12
|
|
||||||
Frame 20 120 5 12
|
|
||||||
Frame 25 120 5 12
|
|
||||||
Frame 30 120 5 12
|
|
||||||
Frame 35 120 5 12
|
|
||||||
Frame 40 120 5 12
|
|
||||||
Frame 45 120 5 12
|
|
||||||
Frame 50 120 5 12
|
|
||||||
Frame 55 120 5 12
|
|
||||||
Frame 60 120 5 12
|
|
||||||
Frame 65 120 5 12
|
|
||||||
Frame 70 120 5 12
|
|
||||||
Frame 75 120 5 12
|
|
||||||
Frame 80 120 5 12
|
|
||||||
Frame 85 120 5 12
|
|
||||||
Frame 90 120 5 12
|
|
||||||
Frame 95 120 5 12
|
|
||||||
Frame 0 132 5 12
|
|
||||||
Frame 5 132 5 12
|
|
||||||
Frame 10 132 5 12
|
|
||||||
Frame 15 132 5 12
|
|
||||||
Frame 20 132 5 12
|
|
||||||
Frame 25 132 5 12
|
|
||||||
Frame 30 132 5 12
|
|
||||||
Frame 35 132 5 12
|
|
||||||
Frame 40 132 5 12
|
|
||||||
Frame 45 132 5 12
|
|
||||||
Frame 50 132 5 12
|
|
||||||
Frame 55 132 5 12
|
|
||||||
Frame 60 132 5 12
|
|
||||||
Frame 65 132 5 12
|
|
||||||
Frame 70 132 5 12
|
|
||||||
Frame 75 132 5 12
|
|
||||||
Frame 80 132 5 12
|
|
||||||
Frame 85 132 5 12
|
|
||||||
Frame 90 132 5 12
|
|
||||||
Frame 95 132 5 12
|
|
||||||
Frame 0 144 5 12
|
|
||||||
Frame 5 144 5 12
|
|
||||||
Frame 10 144 5 12
|
|
||||||
Frame 15 144 5 12
|
|
||||||
Frame 20 144 5 12
|
|
||||||
Frame 25 144 5 12
|
|
||||||
Frame 30 144 5 12
|
|
||||||
Frame 35 144 5 12
|
|
||||||
Frame 40 144 5 12
|
|
||||||
Frame 45 144 5 12
|
|
||||||
Frame 50 144 5 12
|
|
||||||
Frame 55 144 5 12
|
|
||||||
Frame 60 144 5 12
|
|
||||||
Frame 65 144 5 12
|
|
||||||
Frame 70 144 5 12
|
|
||||||
Frame 75 144 5 12
|
|
||||||
Frame 80 144 5 12
|
|
||||||
Frame 85 144 5 12
|
|
||||||
Frame 90 144 5 12
|
|
||||||
Frame 95 144 5 12
|
|
||||||
Frame 0 156 5 12
|
|
||||||
Frame 5 156 5 12
|
|
||||||
Frame 10 156 5 12
|
|
||||||
Frame 15 156 5 12
|
|
||||||
Frame 20 156 5 12
|
|
||||||
Frame 25 156 5 12
|
|
||||||
Frame 30 156 5 12
|
|
||||||
Frame 35 156 5 12
|
|
||||||
Frame 40 156 5 12
|
|
||||||
Frame 45 156 5 12
|
|
||||||
Frame 50 156 5 12
|
|
||||||
Frame 55 156 5 12
|
|
||||||
Frame 60 156 5 12
|
|
||||||
Frame 65 156 5 12
|
|
||||||
Frame 70 156 5 12
|
|
||||||
Frame 75 156 5 12
|
|
||||||
Frame 80 156 5 12
|
|
||||||
Frame 85 156 5 12
|
|
||||||
Frame 90 156 5 12
|
|
||||||
Frame 95 156 5 12
|
|
||||||
Frame 0 168 5 12
|
|
||||||
Frame 5 168 5 12
|
|
||||||
Frame 10 168 5 12
|
|
||||||
Frame 15 168 5 12
|
|
||||||
Frame 20 168 5 12
|
|
||||||
Frame 25 168 5 12
|
|
||||||
Frame 30 168 5 12
|
|
||||||
Frame 35 168 5 12
|
|
||||||
Frame 40 168 5 12
|
|
||||||
Frame 45 168 5 12
|
|
||||||
Frame 50 168 5 12
|
|
||||||
Frame 55 168 5 12
|
|
||||||
Frame 60 168 5 12
|
|
||||||
Frame 65 168 5 12
|
|
||||||
Frame 70 168 5 12
|
|
||||||
Frame 75 168 5 12
|
|
||||||
Frame 80 168 5 12
|
|
||||||
Frame 85 168 5 12
|
|
||||||
Frame 90 168 5 12
|
|
||||||
Frame 95 168 5 12
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
Texture Texture/Font.bmp
|
|
||||||
Frame 200 0 5 12
|
|
||||||
Frame 205 0 5 12
|
|
||||||
Frame 210 0 5 12
|
|
||||||
Frame 215 0 5 12
|
|
||||||
Frame 220 0 5 12
|
|
||||||
Frame 225 0 5 12
|
|
||||||
Frame 230 0 5 12
|
|
||||||
Frame 235 0 5 12
|
|
||||||
Frame 240 0 5 12
|
|
||||||
Frame 245 0 5 12
|
|
||||||
Frame 250 0 5 12
|
|
||||||
Frame 255 0 5 12
|
|
||||||
Frame 260 0 5 12
|
|
||||||
Frame 265 0 5 12
|
|
||||||
Frame 270 0 5 12
|
|
||||||
Frame 275 0 5 12
|
|
||||||
Frame 280 0 5 12
|
|
||||||
Frame 285 0 5 12
|
|
||||||
Frame 290 0 5 12
|
|
||||||
Frame 295 0 5 12
|
|
||||||
Frame 200 12 5 12
|
|
||||||
Frame 205 12 5 12
|
|
||||||
Frame 210 12 5 12
|
|
||||||
Frame 215 12 5 12
|
|
||||||
Frame 220 12 5 12
|
|
||||||
Frame 225 12 5 12
|
|
||||||
Frame 230 12 5 12
|
|
||||||
Frame 235 12 5 12
|
|
||||||
Frame 240 12 5 12
|
|
||||||
Frame 245 12 5 12
|
|
||||||
Frame 250 12 5 12
|
|
||||||
Frame 255 12 5 12
|
|
||||||
Frame 260 12 5 12
|
|
||||||
Frame 265 12 5 12
|
|
||||||
Frame 270 12 5 12
|
|
||||||
Frame 275 12 5 12
|
|
||||||
Frame 280 12 5 12
|
|
||||||
Frame 285 12 5 12
|
|
||||||
Frame 290 12 5 12
|
|
||||||
Frame 295 12 5 12
|
|
||||||
Frame 200 24 5 12
|
|
||||||
Frame 205 24 5 12
|
|
||||||
Frame 210 24 5 12
|
|
||||||
Frame 215 24 5 12
|
|
||||||
Frame 220 24 5 12
|
|
||||||
Frame 225 24 5 12
|
|
||||||
Frame 230 24 5 12
|
|
||||||
Frame 235 24 5 12
|
|
||||||
Frame 240 24 5 12
|
|
||||||
Frame 245 24 5 12
|
|
||||||
Frame 250 24 5 12
|
|
||||||
Frame 255 24 5 12
|
|
||||||
Frame 260 24 5 12
|
|
||||||
Frame 265 24 5 12
|
|
||||||
Frame 270 24 5 12
|
|
||||||
Frame 275 24 5 12
|
|
||||||
Frame 280 24 5 12
|
|
||||||
Frame 285 24 5 12
|
|
||||||
Frame 290 24 5 12
|
|
||||||
Frame 295 24 5 12
|
|
||||||
Frame 200 36 5 12
|
|
||||||
Frame 205 36 5 12
|
|
||||||
Frame 210 36 5 12
|
|
||||||
Frame 215 36 5 12
|
|
||||||
Frame 220 36 5 12
|
|
||||||
Frame 225 36 5 12
|
|
||||||
Frame 230 36 5 12
|
|
||||||
Frame 235 36 5 12
|
|
||||||
Frame 240 36 5 12
|
|
||||||
Frame 245 36 5 12
|
|
||||||
Frame 250 36 5 12
|
|
||||||
Frame 255 36 5 12
|
|
||||||
Frame 260 36 5 12
|
|
||||||
Frame 265 36 5 12
|
|
||||||
Frame 270 36 5 12
|
|
||||||
Frame 275 36 5 12
|
|
||||||
Frame 280 36 5 12
|
|
||||||
Frame 285 36 5 12
|
|
||||||
Frame 290 36 5 12
|
|
||||||
Frame 295 36 5 12
|
|
||||||
Frame 200 48 5 12
|
|
||||||
Frame 205 48 5 12
|
|
||||||
Frame 210 48 5 12
|
|
||||||
Frame 215 48 5 12
|
|
||||||
Frame 220 48 5 12
|
|
||||||
Frame 225 48 5 12
|
|
||||||
Frame 230 48 5 12
|
|
||||||
Frame 235 48 5 12
|
|
||||||
Frame 240 48 5 12
|
|
||||||
Frame 245 48 5 12
|
|
||||||
Frame 250 48 5 12
|
|
||||||
Frame 255 48 5 12
|
|
||||||
Frame 260 48 5 12
|
|
||||||
Frame 265 48 5 12
|
|
||||||
Frame 270 48 5 12
|
|
||||||
Frame 275 48 5 12
|
|
||||||
Frame 280 48 5 12
|
|
||||||
Frame 285 48 5 12
|
|
||||||
Frame 290 48 5 12
|
|
||||||
Frame 295 48 5 12
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
Texture Texture/Font.bmp
|
|
||||||
Frame 0 60 5 12
|
|
||||||
Frame 5 60 5 12
|
|
||||||
Frame 10 60 5 12
|
|
||||||
Frame 15 60 5 12
|
|
||||||
Frame 20 60 5 12
|
|
||||||
Frame 25 60 5 12
|
|
||||||
Frame 30 60 5 12
|
|
||||||
Frame 35 60 5 12
|
|
||||||
Frame 40 60 5 12
|
|
||||||
Frame 45 60 5 12
|
|
||||||
Frame 50 60 5 12
|
|
||||||
Frame 55 60 5 12
|
|
||||||
Frame 60 60 5 12
|
|
||||||
Frame 65 60 5 12
|
|
||||||
Frame 70 60 5 12
|
|
||||||
Frame 75 60 5 12
|
|
||||||
Frame 80 60 5 12
|
|
||||||
Frame 85 60 5 12
|
|
||||||
Frame 90 60 5 12
|
|
||||||
Frame 95 60 5 12
|
|
||||||
Frame 0 72 5 12
|
|
||||||
Frame 5 72 5 12
|
|
||||||
Frame 10 72 5 12
|
|
||||||
Frame 15 72 5 12
|
|
||||||
Frame 20 72 5 12
|
|
||||||
Frame 25 72 5 12
|
|
||||||
Frame 30 72 5 12
|
|
||||||
Frame 35 72 5 12
|
|
||||||
Frame 40 72 5 12
|
|
||||||
Frame 45 72 5 12
|
|
||||||
Frame 50 72 5 12
|
|
||||||
Frame 55 72 5 12
|
|
||||||
Frame 60 72 5 12
|
|
||||||
Frame 65 72 5 12
|
|
||||||
Frame 70 72 5 12
|
|
||||||
Frame 75 72 5 12
|
|
||||||
Frame 80 72 5 12
|
|
||||||
Frame 85 72 5 12
|
|
||||||
Frame 90 72 5 12
|
|
||||||
Frame 95 72 5 12
|
|
||||||
Frame 0 84 5 12
|
|
||||||
Frame 5 84 5 12
|
|
||||||
Frame 10 84 5 12
|
|
||||||
Frame 15 84 5 12
|
|
||||||
Frame 20 84 5 12
|
|
||||||
Frame 25 84 5 12
|
|
||||||
Frame 30 84 5 12
|
|
||||||
Frame 35 84 5 12
|
|
||||||
Frame 40 84 5 12
|
|
||||||
Frame 45 84 5 12
|
|
||||||
Frame 50 84 5 12
|
|
||||||
Frame 55 84 5 12
|
|
||||||
Frame 60 84 5 12
|
|
||||||
Frame 65 84 5 12
|
|
||||||
Frame 70 84 5 12
|
|
||||||
Frame 75 84 5 12
|
|
||||||
Frame 80 84 5 12
|
|
||||||
Frame 85 84 5 12
|
|
||||||
Frame 90 84 5 12
|
|
||||||
Frame 95 84 5 12
|
|
||||||
Frame 0 96 5 12
|
|
||||||
Frame 5 96 5 12
|
|
||||||
Frame 10 96 5 12
|
|
||||||
Frame 15 96 5 12
|
|
||||||
Frame 20 96 5 12
|
|
||||||
Frame 25 96 5 12
|
|
||||||
Frame 30 96 5 12
|
|
||||||
Frame 35 96 5 12
|
|
||||||
Frame 40 96 5 12
|
|
||||||
Frame 45 96 5 12
|
|
||||||
Frame 50 96 5 12
|
|
||||||
Frame 55 96 5 12
|
|
||||||
Frame 60 96 5 12
|
|
||||||
Frame 65 96 5 12
|
|
||||||
Frame 70 96 5 12
|
|
||||||
Frame 75 96 5 12
|
|
||||||
Frame 80 96 5 12
|
|
||||||
Frame 85 96 5 12
|
|
||||||
Frame 90 96 5 12
|
|
||||||
Frame 95 96 5 12
|
|
||||||
Frame 0 108 5 12
|
|
||||||
Frame 5 108 5 12
|
|
||||||
Frame 10 108 5 12
|
|
||||||
Frame 15 108 5 12
|
|
||||||
Frame 20 108 5 12
|
|
||||||
Frame 25 108 5 12
|
|
||||||
Frame 30 108 5 12
|
|
||||||
Frame 35 108 5 12
|
|
||||||
Frame 40 108 5 12
|
|
||||||
Frame 45 108 5 12
|
|
||||||
Frame 50 108 5 12
|
|
||||||
Frame 55 108 5 12
|
|
||||||
Frame 60 108 5 12
|
|
||||||
Frame 65 108 5 12
|
|
||||||
Frame 70 108 5 12
|
|
||||||
Frame 75 108 5 12
|
|
||||||
Frame 80 108 5 12
|
|
||||||
Frame 85 108 5 12
|
|
||||||
Frame 90 108 5 12
|
|
||||||
Frame 95 108 5 12
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
Texture Texture/Font.bmp
|
|
||||||
Frame 100 60 5 12
|
|
||||||
Frame 105 60 5 12
|
|
||||||
Frame 110 60 5 12
|
|
||||||
Frame 115 60 5 12
|
|
||||||
Frame 120 60 5 12
|
|
||||||
Frame 125 60 5 12
|
|
||||||
Frame 130 60 5 12
|
|
||||||
Frame 135 60 5 12
|
|
||||||
Frame 140 60 5 12
|
|
||||||
Frame 145 60 5 12
|
|
||||||
Frame 150 60 5 12
|
|
||||||
Frame 155 60 5 12
|
|
||||||
Frame 160 60 5 12
|
|
||||||
Frame 165 60 5 12
|
|
||||||
Frame 170 60 5 12
|
|
||||||
Frame 175 60 5 12
|
|
||||||
Frame 180 60 5 12
|
|
||||||
Frame 185 60 5 12
|
|
||||||
Frame 190 60 5 12
|
|
||||||
Frame 195 60 5 12
|
|
||||||
Frame 100 72 5 12
|
|
||||||
Frame 105 72 5 12
|
|
||||||
Frame 110 72 5 12
|
|
||||||
Frame 115 72 5 12
|
|
||||||
Frame 120 72 5 12
|
|
||||||
Frame 125 72 5 12
|
|
||||||
Frame 130 72 5 12
|
|
||||||
Frame 135 72 5 12
|
|
||||||
Frame 140 72 5 12
|
|
||||||
Frame 145 72 5 12
|
|
||||||
Frame 150 72 5 12
|
|
||||||
Frame 155 72 5 12
|
|
||||||
Frame 160 72 5 12
|
|
||||||
Frame 165 72 5 12
|
|
||||||
Frame 170 72 5 12
|
|
||||||
Frame 175 72 5 12
|
|
||||||
Frame 180 72 5 12
|
|
||||||
Frame 185 72 5 12
|
|
||||||
Frame 190 72 5 12
|
|
||||||
Frame 195 72 5 12
|
|
||||||
Frame 100 84 5 12
|
|
||||||
Frame 105 84 5 12
|
|
||||||
Frame 110 84 5 12
|
|
||||||
Frame 115 84 5 12
|
|
||||||
Frame 120 84 5 12
|
|
||||||
Frame 125 84 5 12
|
|
||||||
Frame 130 84 5 12
|
|
||||||
Frame 135 84 5 12
|
|
||||||
Frame 140 84 5 12
|
|
||||||
Frame 145 84 5 12
|
|
||||||
Frame 150 84 5 12
|
|
||||||
Frame 155 84 5 12
|
|
||||||
Frame 160 84 5 12
|
|
||||||
Frame 165 84 5 12
|
|
||||||
Frame 170 84 5 12
|
|
||||||
Frame 175 84 5 12
|
|
||||||
Frame 180 84 5 12
|
|
||||||
Frame 185 84 5 12
|
|
||||||
Frame 190 84 5 12
|
|
||||||
Frame 195 84 5 12
|
|
||||||
Frame 100 96 5 12
|
|
||||||
Frame 105 96 5 12
|
|
||||||
Frame 110 96 5 12
|
|
||||||
Frame 115 96 5 12
|
|
||||||
Frame 120 96 5 12
|
|
||||||
Frame 125 96 5 12
|
|
||||||
Frame 130 96 5 12
|
|
||||||
Frame 135 96 5 12
|
|
||||||
Frame 140 96 5 12
|
|
||||||
Frame 145 96 5 12
|
|
||||||
Frame 150 96 5 12
|
|
||||||
Frame 155 96 5 12
|
|
||||||
Frame 160 96 5 12
|
|
||||||
Frame 165 96 5 12
|
|
||||||
Frame 170 96 5 12
|
|
||||||
Frame 175 96 5 12
|
|
||||||
Frame 180 96 5 12
|
|
||||||
Frame 185 96 5 12
|
|
||||||
Frame 190 96 5 12
|
|
||||||
Frame 195 96 5 12
|
|
||||||
Frame 100 108 5 12
|
|
||||||
Frame 105 108 5 12
|
|
||||||
Frame 110 108 5 12
|
|
||||||
Frame 115 108 5 12
|
|
||||||
Frame 120 108 5 12
|
|
||||||
Frame 125 108 5 12
|
|
||||||
Frame 130 108 5 12
|
|
||||||
Frame 135 108 5 12
|
|
||||||
Frame 140 108 5 12
|
|
||||||
Frame 145 108 5 12
|
|
||||||
Frame 150 108 5 12
|
|
||||||
Frame 155 108 5 12
|
|
||||||
Frame 160 108 5 12
|
|
||||||
Frame 165 108 5 12
|
|
||||||
Frame 170 108 5 12
|
|
||||||
Frame 175 108 5 12
|
|
||||||
Frame 180 108 5 12
|
|
||||||
Frame 185 108 5 12
|
|
||||||
Frame 190 108 5 12
|
|
||||||
Frame 195 108 5 12
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
Texture Texture/Font.bmp
|
|
||||||
Frame 100 0 5 12
|
|
||||||
Frame 105 0 5 12
|
|
||||||
Frame 110 0 5 12
|
|
||||||
Frame 115 0 5 12
|
|
||||||
Frame 120 0 5 12
|
|
||||||
Frame 125 0 5 12
|
|
||||||
Frame 130 0 5 12
|
|
||||||
Frame 135 0 5 12
|
|
||||||
Frame 140 0 5 12
|
|
||||||
Frame 145 0 5 12
|
|
||||||
Frame 150 0 5 12
|
|
||||||
Frame 155 0 5 12
|
|
||||||
Frame 160 0 5 12
|
|
||||||
Frame 165 0 5 12
|
|
||||||
Frame 170 0 5 12
|
|
||||||
Frame 175 0 5 12
|
|
||||||
Frame 180 0 5 12
|
|
||||||
Frame 185 0 5 12
|
|
||||||
Frame 190 0 5 12
|
|
||||||
Frame 195 0 5 12
|
|
||||||
Frame 100 12 5 12
|
|
||||||
Frame 105 12 5 12
|
|
||||||
Frame 110 12 5 12
|
|
||||||
Frame 115 12 5 12
|
|
||||||
Frame 120 12 5 12
|
|
||||||
Frame 125 12 5 12
|
|
||||||
Frame 130 12 5 12
|
|
||||||
Frame 135 12 5 12
|
|
||||||
Frame 140 12 5 12
|
|
||||||
Frame 145 12 5 12
|
|
||||||
Frame 150 12 5 12
|
|
||||||
Frame 155 12 5 12
|
|
||||||
Frame 160 12 5 12
|
|
||||||
Frame 165 12 5 12
|
|
||||||
Frame 170 12 5 12
|
|
||||||
Frame 175 12 5 12
|
|
||||||
Frame 180 12 5 12
|
|
||||||
Frame 185 12 5 12
|
|
||||||
Frame 190 12 5 12
|
|
||||||
Frame 195 12 5 12
|
|
||||||
Frame 100 24 5 12
|
|
||||||
Frame 105 24 5 12
|
|
||||||
Frame 110 24 5 12
|
|
||||||
Frame 115 24 5 12
|
|
||||||
Frame 120 24 5 12
|
|
||||||
Frame 125 24 5 12
|
|
||||||
Frame 130 24 5 12
|
|
||||||
Frame 135 24 5 12
|
|
||||||
Frame 140 24 5 12
|
|
||||||
Frame 145 24 5 12
|
|
||||||
Frame 150 24 5 12
|
|
||||||
Frame 155 24 5 12
|
|
||||||
Frame 160 24 5 12
|
|
||||||
Frame 165 24 5 12
|
|
||||||
Frame 170 24 5 12
|
|
||||||
Frame 175 24 5 12
|
|
||||||
Frame 180 24 5 12
|
|
||||||
Frame 185 24 5 12
|
|
||||||
Frame 190 24 5 12
|
|
||||||
Frame 195 24 5 12
|
|
||||||
Frame 100 36 5 12
|
|
||||||
Frame 105 36 5 12
|
|
||||||
Frame 110 36 5 12
|
|
||||||
Frame 115 36 5 12
|
|
||||||
Frame 120 36 5 12
|
|
||||||
Frame 125 36 5 12
|
|
||||||
Frame 130 36 5 12
|
|
||||||
Frame 135 36 5 12
|
|
||||||
Frame 140 36 5 12
|
|
||||||
Frame 145 36 5 12
|
|
||||||
Frame 150 36 5 12
|
|
||||||
Frame 155 36 5 12
|
|
||||||
Frame 160 36 5 12
|
|
||||||
Frame 165 36 5 12
|
|
||||||
Frame 170 36 5 12
|
|
||||||
Frame 175 36 5 12
|
|
||||||
Frame 180 36 5 12
|
|
||||||
Frame 185 36 5 12
|
|
||||||
Frame 190 36 5 12
|
|
||||||
Frame 195 36 5 12
|
|
||||||
Frame 100 48 5 12
|
|
||||||
Frame 105 48 5 12
|
|
||||||
Frame 110 48 5 12
|
|
||||||
Frame 115 48 5 12
|
|
||||||
Frame 120 48 5 12
|
|
||||||
Frame 125 48 5 12
|
|
||||||
Frame 130 48 5 12
|
|
||||||
Frame 135 48 5 12
|
|
||||||
Frame 140 48 5 12
|
|
||||||
Frame 145 48 5 12
|
|
||||||
Frame 150 48 5 12
|
|
||||||
Frame 155 48 5 12
|
|
||||||
Frame 160 48 5 12
|
|
||||||
Frame 165 48 5 12
|
|
||||||
Frame 170 48 5 12
|
|
||||||
Frame 175 48 5 12
|
|
||||||
Frame 180 48 5 12
|
|
||||||
Frame 185 48 5 12
|
|
||||||
Frame 190 48 5 12
|
|
||||||
Frame 195 48 5 12
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
Texture Texture/Font.bmp
|
|
||||||
Frame 200 120 5 12
|
|
||||||
Frame 205 120 5 12
|
|
||||||
Frame 210 120 5 12
|
|
||||||
Frame 215 120 5 12
|
|
||||||
Frame 220 120 5 12
|
|
||||||
Frame 225 120 5 12
|
|
||||||
Frame 230 120 5 12
|
|
||||||
Frame 235 120 5 12
|
|
||||||
Frame 240 120 5 12
|
|
||||||
Frame 245 120 5 12
|
|
||||||
Frame 250 120 5 12
|
|
||||||
Frame 255 120 5 12
|
|
||||||
Frame 260 120 5 12
|
|
||||||
Frame 265 120 5 12
|
|
||||||
Frame 270 120 5 12
|
|
||||||
Frame 275 120 5 12
|
|
||||||
Frame 280 120 5 12
|
|
||||||
Frame 285 120 5 12
|
|
||||||
Frame 290 120 5 12
|
|
||||||
Frame 295 120 5 12
|
|
||||||
Frame 200 132 5 12
|
|
||||||
Frame 205 132 5 12
|
|
||||||
Frame 210 132 5 12
|
|
||||||
Frame 215 132 5 12
|
|
||||||
Frame 220 132 5 12
|
|
||||||
Frame 225 132 5 12
|
|
||||||
Frame 230 132 5 12
|
|
||||||
Frame 235 132 5 12
|
|
||||||
Frame 240 132 5 12
|
|
||||||
Frame 245 132 5 12
|
|
||||||
Frame 250 132 5 12
|
|
||||||
Frame 255 132 5 12
|
|
||||||
Frame 260 132 5 12
|
|
||||||
Frame 265 132 5 12
|
|
||||||
Frame 270 132 5 12
|
|
||||||
Frame 275 132 5 12
|
|
||||||
Frame 280 132 5 12
|
|
||||||
Frame 285 132 5 12
|
|
||||||
Frame 290 132 5 12
|
|
||||||
Frame 295 132 5 12
|
|
||||||
Frame 200 144 5 12
|
|
||||||
Frame 205 144 5 12
|
|
||||||
Frame 210 144 5 12
|
|
||||||
Frame 215 144 5 12
|
|
||||||
Frame 220 144 5 12
|
|
||||||
Frame 225 144 5 12
|
|
||||||
Frame 230 144 5 12
|
|
||||||
Frame 235 144 5 12
|
|
||||||
Frame 240 144 5 12
|
|
||||||
Frame 245 144 5 12
|
|
||||||
Frame 250 144 5 12
|
|
||||||
Frame 255 144 5 12
|
|
||||||
Frame 260 144 5 12
|
|
||||||
Frame 265 144 5 12
|
|
||||||
Frame 270 144 5 12
|
|
||||||
Frame 275 144 5 12
|
|
||||||
Frame 280 144 5 12
|
|
||||||
Frame 285 144 5 12
|
|
||||||
Frame 290 144 5 12
|
|
||||||
Frame 295 144 5 12
|
|
||||||
Frame 200 156 5 12
|
|
||||||
Frame 205 156 5 12
|
|
||||||
Frame 210 156 5 12
|
|
||||||
Frame 215 156 5 12
|
|
||||||
Frame 220 156 5 12
|
|
||||||
Frame 225 156 5 12
|
|
||||||
Frame 230 156 5 12
|
|
||||||
Frame 235 156 5 12
|
|
||||||
Frame 240 156 5 12
|
|
||||||
Frame 245 156 5 12
|
|
||||||
Frame 250 156 5 12
|
|
||||||
Frame 255 156 5 12
|
|
||||||
Frame 260 156 5 12
|
|
||||||
Frame 265 156 5 12
|
|
||||||
Frame 270 156 5 12
|
|
||||||
Frame 275 156 5 12
|
|
||||||
Frame 280 156 5 12
|
|
||||||
Frame 285 156 5 12
|
|
||||||
Frame 290 156 5 12
|
|
||||||
Frame 295 156 5 12
|
|
||||||
Frame 200 168 5 12
|
|
||||||
Frame 205 168 5 12
|
|
||||||
Frame 210 168 5 12
|
|
||||||
Frame 215 168 5 12
|
|
||||||
Frame 220 168 5 12
|
|
||||||
Frame 225 168 5 12
|
|
||||||
Frame 230 168 5 12
|
|
||||||
Frame 235 168 5 12
|
|
||||||
Frame 240 168 5 12
|
|
||||||
Frame 245 168 5 12
|
|
||||||
Frame 250 168 5 12
|
|
||||||
Frame 255 168 5 12
|
|
||||||
Frame 260 168 5 12
|
|
||||||
Frame 265 168 5 12
|
|
||||||
Frame 270 168 5 12
|
|
||||||
Frame 275 168 5 12
|
|
||||||
Frame 280 168 5 12
|
|
||||||
Frame 285 168 5 12
|
|
||||||
Frame 290 168 5 12
|
|
||||||
Frame 295 168 5 12
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
Texture Texture/Font.bmp
|
|
||||||
Frame 100 120 5 12
|
|
||||||
Frame 105 120 5 12
|
|
||||||
Frame 110 120 5 12
|
|
||||||
Frame 115 120 5 12
|
|
||||||
Frame 120 120 5 12
|
|
||||||
Frame 125 120 5 12
|
|
||||||
Frame 130 120 5 12
|
|
||||||
Frame 135 120 5 12
|
|
||||||
Frame 140 120 5 12
|
|
||||||
Frame 145 120 5 12
|
|
||||||
Frame 150 120 5 12
|
|
||||||
Frame 155 120 5 12
|
|
||||||
Frame 160 120 5 12
|
|
||||||
Frame 165 120 5 12
|
|
||||||
Frame 170 120 5 12
|
|
||||||
Frame 175 120 5 12
|
|
||||||
Frame 180 120 5 12
|
|
||||||
Frame 185 120 5 12
|
|
||||||
Frame 190 120 5 12
|
|
||||||
Frame 195 120 5 12
|
|
||||||
Frame 100 132 5 12
|
|
||||||
Frame 105 132 5 12
|
|
||||||
Frame 110 132 5 12
|
|
||||||
Frame 115 132 5 12
|
|
||||||
Frame 120 132 5 12
|
|
||||||
Frame 125 132 5 12
|
|
||||||
Frame 130 132 5 12
|
|
||||||
Frame 135 132 5 12
|
|
||||||
Frame 140 132 5 12
|
|
||||||
Frame 145 132 5 12
|
|
||||||
Frame 150 132 5 12
|
|
||||||
Frame 155 132 5 12
|
|
||||||
Frame 160 132 5 12
|
|
||||||
Frame 165 132 5 12
|
|
||||||
Frame 170 132 5 12
|
|
||||||
Frame 175 132 5 12
|
|
||||||
Frame 180 132 5 12
|
|
||||||
Frame 185 132 5 12
|
|
||||||
Frame 190 132 5 12
|
|
||||||
Frame 195 132 5 12
|
|
||||||
Frame 100 144 5 12
|
|
||||||
Frame 105 144 5 12
|
|
||||||
Frame 110 144 5 12
|
|
||||||
Frame 115 144 5 12
|
|
||||||
Frame 120 144 5 12
|
|
||||||
Frame 125 144 5 12
|
|
||||||
Frame 130 144 5 12
|
|
||||||
Frame 135 144 5 12
|
|
||||||
Frame 140 144 5 12
|
|
||||||
Frame 145 144 5 12
|
|
||||||
Frame 150 144 5 12
|
|
||||||
Frame 155 144 5 12
|
|
||||||
Frame 160 144 5 12
|
|
||||||
Frame 165 144 5 12
|
|
||||||
Frame 170 144 5 12
|
|
||||||
Frame 175 144 5 12
|
|
||||||
Frame 180 144 5 12
|
|
||||||
Frame 185 144 5 12
|
|
||||||
Frame 190 144 5 12
|
|
||||||
Frame 195 144 5 12
|
|
||||||
Frame 100 156 5 12
|
|
||||||
Frame 105 156 5 12
|
|
||||||
Frame 110 156 5 12
|
|
||||||
Frame 115 156 5 12
|
|
||||||
Frame 120 156 5 12
|
|
||||||
Frame 125 156 5 12
|
|
||||||
Frame 130 156 5 12
|
|
||||||
Frame 135 156 5 12
|
|
||||||
Frame 140 156 5 12
|
|
||||||
Frame 145 156 5 12
|
|
||||||
Frame 150 156 5 12
|
|
||||||
Frame 155 156 5 12
|
|
||||||
Frame 160 156 5 12
|
|
||||||
Frame 165 156 5 12
|
|
||||||
Frame 170 156 5 12
|
|
||||||
Frame 175 156 5 12
|
|
||||||
Frame 180 156 5 12
|
|
||||||
Frame 185 156 5 12
|
|
||||||
Frame 190 156 5 12
|
|
||||||
Frame 195 156 5 12
|
|
||||||
Frame 100 168 5 12
|
|
||||||
Frame 105 168 5 12
|
|
||||||
Frame 110 168 5 12
|
|
||||||
Frame 115 168 5 12
|
|
||||||
Frame 120 168 5 12
|
|
||||||
Frame 125 168 5 12
|
|
||||||
Frame 130 168 5 12
|
|
||||||
Frame 135 168 5 12
|
|
||||||
Frame 140 168 5 12
|
|
||||||
Frame 145 168 5 12
|
|
||||||
Frame 150 168 5 12
|
|
||||||
Frame 155 168 5 12
|
|
||||||
Frame 160 168 5 12
|
|
||||||
Frame 165 168 5 12
|
|
||||||
Frame 170 168 5 12
|
|
||||||
Frame 175 168 5 12
|
|
||||||
Frame 180 168 5 12
|
|
||||||
Frame 185 168 5 12
|
|
||||||
Frame 190 168 5 12
|
|
||||||
Frame 195 168 5 12
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
Texture Texture/Main.bmp
|
|
||||||
Frame 0 48 16 16 Right
|
|
||||||
Frame 16 48 16 16 Up
|
|
||||||
Frame 32 48 16 16 Left
|
|
||||||
Frame 48 48 16 16 Down
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
Texture Texture/Main.bmp
|
|
||||||
Frame 101 21 6 6
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
Texture Texture/Main.bmp
|
|
||||||
Frame 64 48 16 16 Up
|
|
||||||
Frame 80 48 16 16 Left
|
|
||||||
Frame 64 64 16 16 Down
|
|
||||||
Frame 80 64 16 16 Right
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
Texture Texture/Main.bmp
|
|
||||||
Frame 0 0 16 16 Z
|
|
||||||
Frame 16 0 16 16 X
|
|
||||||
Frame 32 0 16 16 C
|
|
||||||
Frame 48 0 16 16 Right
|
|
||||||
Frame 64 0 16 16 Up
|
|
||||||
Frame 80 0 16 16 Left
|
|
||||||
Frame 96 0 16 16 Down
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
Texture Texture/Digits.bmp
|
|
||||||
Frame 0 0 7 12
|
|
||||||
Frame 7 0 7 12
|
|
||||||
Frame 14 0 7 12
|
|
||||||
Frame 21 0 7 12
|
|
||||||
Frame 28 0 7 12
|
|
||||||
Frame 35 0 7 12
|
|
||||||
Frame 42 0 7 12
|
|
||||||
Frame 49 0 7 12
|
|
||||||
Frame 56 0 7 12
|
|
||||||
Frame 63 0 7 12
|
|
||||||
Frame 70 0 7 12
|
|
||||||
Frame 0 12 7 12
|
|
||||||
Frame 7 12 7 12
|
|
||||||
Frame 14 12 7 12
|
|
||||||
Frame 21 12 7 12
|
|
||||||
Frame 28 12 7 12
|
|
||||||
Frame 35 12 7 12
|
|
||||||
Frame 42 12 7 12
|
|
||||||
Frame 49 12 7 12
|
|
||||||
Frame 56 12 7 12
|
|
||||||
Frame 63 12 7 12
|
|
||||||
Frame 70 12 7 12
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
Texture Texture/Main.bmp
|
|
||||||
Frame 0 96 16 16
|
|
||||||
Frame 112 0 16 16
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
Texture Texture/Main.bmp
|
|
||||||
Frame 116 20 9 9 Normal
|
|
||||||
Frame 116 36 9 9 Live
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
Texture Texture/Main.bmp
|
|
||||||
Frame 0 80 16 16 Stand
|
|
||||||
Frame 16 80 16 16 Hold
|
|
||||||
Frame 32 80 16 16 Jump
|
|
||||||
Frame 48 80 16 16 Run
|
|
||||||
Frame 64 80 16 16 Dead
|
|
||||||
Frame 32 96 16 16 Climb
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
Texture Texture/Main.bmp
|
|
||||||
Frame 0 64 16 16 Time
|
|
||||||
Frame 16 64 16 16 Bullet
|
|
||||||
Frame 32 64 16 16 Torch
|
|
||||||
Frame 48 64 16 16 Key
|
|
||||||
Frame 80 16 16 16 Rope
|
|
||||||
Frame 16 96 16 16 Rock
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
Texture Texture/Main.bmp
|
|
||||||
Frame 64 16 16 16 Ladder
|
|
||||||
Frame 80 16 16 16 Rope
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
Texture Texture/Main.bmp
|
|
||||||
Frame 80 80 48 48 Main
|
|
||||||
Frame 48 96 32 32 Orange
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
Texture Texture/Main.bmp
|
|
||||||
Frame 80 32 16 16
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
Texture Texture/Main.bmp
|
|
||||||
Frame 32 32 16 16 Closed
|
|
||||||
Frame 48 32 16 16 Open
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
Texture Texture/Main.bmp
|
|
||||||
Frame 96 32 16 16
|
|
||||||
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Texture Texture/possum.bmp
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
Texture Texture/Main.bmp
|
|
||||||
Frame 48 16 16 16
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
Texture Texture/Main.bmp
|
|
||||||
Frame 0 32 16 16 Clean
|
|
||||||
Frame 16 32 16 16 Bloody
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
Texture Texture/Main.bmp
|
|
||||||
Frame 20 100 8 8
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
Texture Texture/Main.bmp
|
|
||||||
Frame 0 16 16 16 Backdrop
|
|
||||||
Frame 16 16 16 16 Dirt
|
|
||||||
Frame 32 16 16 16 Grass
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
Room
|
|
||||||
gggggggggg
|
|
||||||
g8ggg8g8gg
|
|
||||||
g8ggg8g8gg
|
|
||||||
g888g858gg
|
|
||||||
g8g8g8g8gg
|
|
||||||
g858g8g8gg
|
|
||||||
|
|
||||||
Room
|
|
||||||
0000l00000
|
|
||||||
0000l00000
|
|
||||||
7775557757
|
|
||||||
5557775575
|
|
||||||
00t0000t00
|
|
||||||
GGGGGGGGGG
|
|
||||||
|
|
||||||
Room
|
|
||||||
g0g0gg0g0g
|
|
||||||
g00000000g
|
|
||||||
g00000000g
|
|
||||||
00t0000t00
|
|
||||||
0DDDDDDDD0
|
|
||||||
GGGGGGGGGG
|
|
||||||
|
|
||||||
Room
|
|
||||||
0gggggggg0
|
|
||||||
0gtggggtg0
|
|
||||||
dgdgddgdgd
|
|
||||||
gggggggggg
|
|
||||||
gggggggggg
|
|
||||||
gggggggggg
|
|
||||||
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
Room
|
|
||||||
5555555555
|
|
||||||
0000000000
|
|
||||||
0000000000
|
|
||||||
00t0000t00
|
|
||||||
0D00DD0pD0
|
|
||||||
GGGGGGGGGG
|
|
||||||
|
|
||||||
Room
|
|
||||||
5555555555
|
|
||||||
0000000000
|
|
||||||
0000000000
|
|
||||||
00t0000t00
|
|
||||||
0d00000p00
|
|
||||||
GGGGGGGGGG
|
|
||||||
|
|
||||||
|
|
||||||
Room
|
|
||||||
5555555555
|
|
||||||
00t00p0t00
|
|
||||||
000lGGGGl0
|
|
||||||
000lggggl0
|
|
||||||
000lggggl0
|
|
||||||
GGGGggggGG
|
|
||||||
|
|
||||||
Room
|
|
||||||
5555555555
|
|
||||||
00t00pdt00
|
|
||||||
000lGGGGl0
|
|
||||||
000lggggl0
|
|
||||||
000lggggl0
|
|
||||||
GGGGggggGG
|
|
||||||
|
|
||||||
Room
|
|
||||||
0000000000
|
|
||||||
00t00p0t00
|
|
||||||
0lg00g00gl
|
|
||||||
0l000g000l
|
|
||||||
0lDDDgDDDl
|
|
||||||
GGGGGGGGGG
|
|
||||||
|
|
||||||
Room
|
|
||||||
0000000000
|
|
||||||
00t00p0t00
|
|
||||||
0lg00g00gl
|
|
||||||
0l000g000l
|
|
||||||
0lDdDgDdDl
|
|
||||||
GGGGGGGGGG
|
|
||||||
|
|
||||||
Room
|
|
||||||
0000000000
|
|
||||||
00t0000t00
|
|
||||||
000D0pD000
|
|
||||||
00gggggg00
|
|
||||||
0gggggggg0
|
|
||||||
GggggggggG
|
|
||||||
|
|
||||||
Room
|
|
||||||
0000000000
|
|
||||||
00t0000t00
|
|
||||||
00000pd000
|
|
||||||
00gggggg00
|
|
||||||
0gggggggg0
|
|
||||||
GggggggggG
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
Room
|
|
||||||
0000000000
|
|
||||||
0000000000
|
|
||||||
0000000000
|
|
||||||
0000000000
|
|
||||||
0tp00000t0
|
|
||||||
GGGGPPPPGG
|
|
||||||
|
|
||||||
Room
|
|
||||||
0000000000
|
|
||||||
0000000000
|
|
||||||
00t00000t0
|
|
||||||
0000000000
|
|
||||||
0dp0000000
|
|
||||||
GGGGPPPPGG
|
|
||||||
|
|
||||||
Room
|
|
||||||
0000000000
|
|
||||||
0000000000
|
|
||||||
0t000p00t0
|
|
||||||
00ggggggg0
|
|
||||||
00000000g0
|
|
||||||
GGGGPPPPgG
|
|
||||||
|
|
||||||
Room
|
|
||||||
0000000000
|
|
||||||
0000000000
|
|
||||||
0000000000
|
|
||||||
0t000000t0
|
|
||||||
000000p000
|
|
||||||
GPPGPPGPPG
|
|
||||||
|
|
||||||
Room
|
|
||||||
0000000000
|
|
||||||
0000000000
|
|
||||||
0000000000
|
|
||||||
0t000000t0
|
|
||||||
000d00p000
|
|
||||||
GPPGPPGPPG
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
Room
|
|
||||||
0000l00000
|
|
||||||
0000l00000
|
|
||||||
0000l00000
|
|
||||||
0t00l000t0
|
|
||||||
0000l0p000
|
|
||||||
GGGGGGGGGG
|
|
||||||
|
|
||||||
Room
|
|
||||||
0000l00000
|
|
||||||
0000l00000
|
|
||||||
0000l00000
|
|
||||||
0t00l000t0
|
|
||||||
000dldp000
|
|
||||||
GGGGGGGGGG
|
|
||||||
|
|
||||||
|
|
||||||
Room
|
|
||||||
0000l00000
|
|
||||||
00t0l00t00
|
|
||||||
0lggggggl0
|
|
||||||
0l000000l0
|
|
||||||
0l00p000l0
|
|
||||||
GGGGGGGGGG
|
|
||||||
|
|
||||||
Room
|
|
||||||
0000l00000
|
|
||||||
00t0l00t00
|
|
||||||
0lggggggl0
|
|
||||||
0l000000l0
|
|
||||||
0ld0p000l0
|
|
||||||
GGGGGGGGGG
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
Room
|
|
||||||
0000l00000
|
|
||||||
0000l00000
|
|
||||||
0000l00000
|
|
||||||
0t00l000t0
|
|
||||||
0p00l00000
|
|
||||||
GGPPlPPPGG
|
|
||||||
|
|
||||||
Room
|
|
||||||
0000l00000
|
|
||||||
0000l00000
|
|
||||||
0000l00000
|
|
||||||
0t00l000t0
|
|
||||||
0p00l0d000
|
|
||||||
GGPPlPPPGG
|
|
||||||
|
|
||||||
Room
|
|
||||||
0000l00000
|
|
||||||
0t00l000t0
|
|
||||||
ggggggglgg
|
|
||||||
0000000l00
|
|
||||||
0000l0pl00
|
|
||||||
GGPPlGGGGG
|
|
||||||
|
|
||||||
Room
|
|
||||||
0000l00000
|
|
||||||
0t00l000t0
|
|
||||||
ggggggglgg
|
|
||||||
0000000l00
|
|
||||||
0d00l0pl00
|
|
||||||
GGPPlGGGGG
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 7.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 211 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 64 KiB |
@@ -1,28 +0,0 @@
|
|||||||
# GNU makefile
|
|
||||||
|
|
||||||
# User configuration
|
|
||||||
CXXFLAGS ?= -Og -std=c++17 -Iinclude
|
|
||||||
LDFLAGS ?= -lSDL2
|
|
||||||
TARGET = eulamadness
|
|
||||||
|
|
||||||
# System configuration
|
|
||||||
include Makefile.srcs
|
|
||||||
|
|
||||||
EXE = $(TARGET)
|
|
||||||
OBJS = $(SRCS:.cpp=.o)
|
|
||||||
|
|
||||||
# Targets
|
|
||||||
all: $(EXE)
|
|
||||||
|
|
||||||
dist: $(EXE)
|
|
||||||
mkdir -p dist
|
|
||||||
cp $(EXE) dist/
|
|
||||||
|
|
||||||
$(EXE): $(OBJS)
|
|
||||||
$(CXX) -o $@ $(OBJS) $(LDFLAGS)
|
|
||||||
|
|
||||||
.cpp.o:
|
|
||||||
$(CXX) $(CXXFLAGS) -c $< -o $@
|
|
||||||
|
|
||||||
clean:
|
|
||||||
-rm -rf $(OBJS) $(EXE) dist
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
# GNU makefile
|
|
||||||
|
|
||||||
# User configuration
|
|
||||||
CC = emcc
|
|
||||||
CXX = emcc
|
|
||||||
CXXFLAGS ?= -sUSE_SDL=2 -O3 -std=c++17 -Iinclude -fexceptions
|
|
||||||
LDFLAGS ?= -sUSE_SDL=2 -O3 -fexceptions --embed-file=data.pak@data.pak -sMAX_WEBGL_VERSION=2
|
|
||||||
TARGET = index.html
|
|
||||||
|
|
||||||
# System configuration
|
|
||||||
include Makefile.srcs
|
|
||||||
|
|
||||||
EXE = $(TARGET)
|
|
||||||
OBJS = $(SRCS:.cpp=.o)
|
|
||||||
|
|
||||||
# Targets
|
|
||||||
all: $(EXE)
|
|
||||||
|
|
||||||
dist: $(EXE)
|
|
||||||
mkdir -p dist
|
|
||||||
cp $(EXE) dist/
|
|
||||||
|
|
||||||
$(EXE): $(OBJS)
|
|
||||||
$(CXX) -o $@ $(OBJS) $(LDFLAGS)
|
|
||||||
cp index.template.html $(EXE)
|
|
||||||
|
|
||||||
.cpp.o:
|
|
||||||
$(CXX) $(CXXFLAGS) -c $< -o $@
|
|
||||||
|
|
||||||
clean:
|
|
||||||
-rm -rf $(OBJS) $(EXE) index.js index.wasm index.data dist
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
# Source files
|
|
||||||
|
|
||||||
SRCS = \
|
|
||||||
src/Alarm.cpp \
|
|
||||||
src/App.cpp \
|
|
||||||
src/AudioManager.cpp \
|
|
||||||
src/Common.cpp \
|
|
||||||
src/DigitManager.cpp \
|
|
||||||
src/Entity.cpp \
|
|
||||||
src/EntityManager.cpp \
|
|
||||||
src/FileManager.cpp \
|
|
||||||
src/FontManager.cpp \
|
|
||||||
src/Gridmap.cpp \
|
|
||||||
src/Main.cpp \
|
|
||||||
src/RenderManager.cpp \
|
|
||||||
src/RoomEntity.cpp \
|
|
||||||
src/SpriteManager.cpp \
|
|
||||||
src/State.cpp \
|
|
||||||
src/SurfaceManager.cpp \
|
|
||||||
src/Variable.cpp
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
# Game
|
|
||||||
|
|
||||||
Game should be available here: https://blankhex.github.io/jam-game/index.html
|
|
||||||
|
|
||||||
Everything here is under CC0
|
|
||||||
|
|
||||||
# Building
|
|
||||||
|
|
||||||
## Common
|
|
||||||
|
|
||||||
Build data archive
|
|
||||||
|
|
||||||
```sh
|
|
||||||
python3 makepak.py Data data.pak
|
|
||||||
```
|
|
||||||
|
|
||||||
## Linux/MacOS
|
|
||||||
|
|
||||||
```sh
|
|
||||||
make clean all
|
|
||||||
```
|
|
||||||
|
|
||||||
## Emscripten
|
|
||||||
|
|
||||||
```sh
|
|
||||||
emmake make -f Makefile.emcc clean all
|
|
||||||
```
|
|
||||||
|
|
||||||
## Notes
|
|
||||||
|
|
||||||
This is a test of migrations
|
|
||||||
|
|
||||||
Test #2
|
|
||||||
Executable
BIN
Binary file not shown.
-43
@@ -1,43 +0,0 @@
|
|||||||
import sys
|
|
||||||
import struct
|
|
||||||
import os
|
|
||||||
|
|
||||||
#dummy class for stuffing the file headers into
|
|
||||||
class FileEntry:
|
|
||||||
pass
|
|
||||||
|
|
||||||
#arguments are source directory, then target filename e.g. "pak1.pak"
|
|
||||||
rootdir = sys.argv[1]
|
|
||||||
pakfilename = sys.argv[2]
|
|
||||||
|
|
||||||
pakfile = open(pakfilename,"wb")
|
|
||||||
|
|
||||||
#write a dummy header to start with
|
|
||||||
pakfile.write(struct.Struct("<4s2l").pack(b"PACK",0,0))
|
|
||||||
|
|
||||||
#walk the directory recursively, add the files and record the file entries
|
|
||||||
offset = 12
|
|
||||||
fileentries = []
|
|
||||||
for root, subFolders, files in os.walk(rootdir):
|
|
||||||
for file in files:
|
|
||||||
entry = FileEntry()
|
|
||||||
impfilename = os.path.join(root,file)
|
|
||||||
entry.filename = os.path.relpath(impfilename,rootdir).replace("\\","/")
|
|
||||||
with open(impfilename, "rb") as importfile:
|
|
||||||
pakfile.write(importfile.read())
|
|
||||||
entry.offset = offset
|
|
||||||
entry.length = importfile.tell()
|
|
||||||
offset = offset + entry.length
|
|
||||||
fileentries.append(entry)
|
|
||||||
tablesize = 0
|
|
||||||
|
|
||||||
#after all the file data, write the list of entries
|
|
||||||
for entry in fileentries:
|
|
||||||
pakfile.write(struct.Struct("<56s").pack(entry.filename.encode("ascii")))
|
|
||||||
pakfile.write(struct.Struct("<l").pack(entry.offset))
|
|
||||||
pakfile.write(struct.Struct("<l").pack(entry.length))
|
|
||||||
tablesize = tablesize + 64
|
|
||||||
|
|
||||||
#return to the header and write the values correctly
|
|
||||||
pakfile.seek(0)
|
|
||||||
pakfile.write(struct.Struct("<4s2l").pack(b"PACK",offset,tablesize))
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
#include "Alarm.h"
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
void TAlarm::Set(TId id, std::uint32_t millis) {
|
|
||||||
auto& data = Alarms_[id];
|
|
||||||
data.Target = millis;
|
|
||||||
data.Current = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TAlarm::Unset(TId id) {
|
|
||||||
auto& data = Alarms_[id];
|
|
||||||
data.Target = 0;
|
|
||||||
data.Current = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TAlarm::Update(std::uint32_t delta) {
|
|
||||||
for (auto it = Alarms_.begin(); it != Alarms_.end(); ++it) {
|
|
||||||
auto& alarm = it->second;
|
|
||||||
if (alarm.Target) {
|
|
||||||
alarm.Current += delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (alarm.Current >= alarm.Target) {
|
|
||||||
DueAlarms_.push(it->first);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TAlarm::Next(TId& id) {
|
|
||||||
bool repeat;
|
|
||||||
|
|
||||||
do {
|
|
||||||
repeat = false;
|
|
||||||
|
|
||||||
if (DueAlarms_.empty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
id = DueAlarms_.front();
|
|
||||||
DueAlarms_.pop();
|
|
||||||
|
|
||||||
auto& alarm = Alarms_[id];
|
|
||||||
if (alarm.Target) {
|
|
||||||
if (alarm.Current >= alarm.Target) {
|
|
||||||
alarm.Current -= alarm.Target;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (alarm.Current >= alarm.Target) {
|
|
||||||
DueAlarms_.push(id);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
alarm.Current = 0;
|
|
||||||
repeat = true;
|
|
||||||
}
|
|
||||||
} while (repeat);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TAlarm::IsSet(TId id) const {
|
|
||||||
auto it = Alarms_.find(id);
|
|
||||||
|
|
||||||
if (it == Alarms_.end()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!it->second.Target) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
-31
@@ -1,31 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Common.h"
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <queue>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
class TAlarm {
|
|
||||||
public:
|
|
||||||
using TId = int;
|
|
||||||
|
|
||||||
void Set(TId id, std::uint32_t millis);
|
|
||||||
void Unset(TId id);
|
|
||||||
void Update(std::uint32_t delta);
|
|
||||||
bool Next(TId& id);
|
|
||||||
bool IsSet(TId id) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct TData {
|
|
||||||
std::uint32_t Target;
|
|
||||||
std::uint32_t Current;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::unordered_map<TId, TData> Alarms_;
|
|
||||||
std::queue<TId> DueAlarms_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
-127
@@ -1,127 +0,0 @@
|
|||||||
#include "App.h"
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#ifdef __EMSCRIPTEN__
|
|
||||||
#include <emscripten.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
TApp* TApp::Instance() {
|
|
||||||
static TApp* instance = nullptr;
|
|
||||||
|
|
||||||
if (!instance) {
|
|
||||||
instance = new TApp();
|
|
||||||
}
|
|
||||||
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
TApp::TApp() {
|
|
||||||
FileManager_ = std::make_unique<TFileManager>("Data", "data.pak");
|
|
||||||
SurfaceManager_ = std::make_unique<TSurfaceManager>(*FileManager_);
|
|
||||||
RenderManager_ = std::make_unique<TRenderManager>(*SurfaceManager_, 320, 240, "EULAMadness");
|
|
||||||
SpriteManager_ = std::make_unique<TSpriteManager>(*FileManager_, *RenderManager_);
|
|
||||||
EntityManager_ = std::make_unique<TEntityManager>(*RenderManager_, 1000 / 60);
|
|
||||||
FontManager_ = std::make_unique<TFontManager>(*SpriteManager_);
|
|
||||||
DigitManager_ = std::make_unique<TDigitManager>(*SpriteManager_);
|
|
||||||
AudioManager_ = std::make_unique<TAudioManager>(*FileManager_);
|
|
||||||
}
|
|
||||||
|
|
||||||
TApp::~TApp() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void TApp::Process() {
|
|
||||||
if (!RenderManager_->IsRunning()) {
|
|
||||||
#ifdef __EMSCRIPTEN__
|
|
||||||
emscripten_cancel_main_loop(); /* this should "kill" the app. */
|
|
||||||
#else
|
|
||||||
exit(0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderManager_->Reset();
|
|
||||||
EntityManager_->Run();
|
|
||||||
RenderManager_->Run();
|
|
||||||
AudioManager_->Run();
|
|
||||||
}
|
|
||||||
|
|
||||||
int TApp::Run() {
|
|
||||||
Process();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
TState& TApp::State() {
|
|
||||||
return State_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TState& TApp::State() const {
|
|
||||||
return State_;
|
|
||||||
}
|
|
||||||
|
|
||||||
TFileManager& TApp::FileManager() {
|
|
||||||
return *FileManager_;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRenderManager& TApp::RenderManager() {
|
|
||||||
return *RenderManager_;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEntityManager& TApp::EntityManager() {
|
|
||||||
return *EntityManager_;
|
|
||||||
}
|
|
||||||
|
|
||||||
TSurfaceManager& TApp::SurfaceManager() {
|
|
||||||
return *SurfaceManager_;
|
|
||||||
}
|
|
||||||
|
|
||||||
TSpriteManager& TApp::SpriteManager() {
|
|
||||||
return *SpriteManager_;
|
|
||||||
}
|
|
||||||
|
|
||||||
TFontManager& TApp::FontManager() {
|
|
||||||
return *FontManager_;
|
|
||||||
}
|
|
||||||
|
|
||||||
TDigitManager& TApp::DigitManager() {
|
|
||||||
return *DigitManager_;
|
|
||||||
}
|
|
||||||
|
|
||||||
TAudioManager& TApp::AudioManager() {
|
|
||||||
return *AudioManager_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TFileManager& TApp::FileManager() const {
|
|
||||||
return *FileManager_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TRenderManager& TApp::RenderManager() const {
|
|
||||||
return *RenderManager_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TEntityManager& TApp::EntityManager() const {
|
|
||||||
return *EntityManager_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TSurfaceManager& TApp::SurfaceManager() const {
|
|
||||||
return *SurfaceManager_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TSpriteManager& TApp::SpriteManager() const {
|
|
||||||
return *SpriteManager_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TFontManager& TApp::FontManager() const {
|
|
||||||
return *FontManager_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TDigitManager& TApp::DigitManager() const {
|
|
||||||
return *DigitManager_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TAudioManager& TApp::AudioManager() const {
|
|
||||||
return *AudioManager_;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Common.h"
|
|
||||||
|
|
||||||
#include "AudioManager.h"
|
|
||||||
#include "DigitManager.h"
|
|
||||||
#include "EntityManager.h"
|
|
||||||
#include "FileManager.h"
|
|
||||||
#include "FontManager.h"
|
|
||||||
#include "RenderManager.h"
|
|
||||||
#include "SpriteManager.h"
|
|
||||||
#include "State.h"
|
|
||||||
#include "SurfaceManager.h"
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <memory>
|
|
||||||
#include <SDL2/SDL_render.h>
|
|
||||||
#include <SDL2/SDL.h>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
class TApp {
|
|
||||||
public:
|
|
||||||
static TApp* Instance();
|
|
||||||
int Run();
|
|
||||||
|
|
||||||
TState& State();
|
|
||||||
const TState& State() const;
|
|
||||||
|
|
||||||
TFileManager& FileManager();
|
|
||||||
TRenderManager& RenderManager();
|
|
||||||
TEntityManager& EntityManager();
|
|
||||||
TSurfaceManager& SurfaceManager();
|
|
||||||
TSpriteManager& SpriteManager();
|
|
||||||
TFontManager& FontManager();
|
|
||||||
TDigitManager& DigitManager();
|
|
||||||
TAudioManager& AudioManager();
|
|
||||||
|
|
||||||
const TFileManager& FileManager() const;
|
|
||||||
const TRenderManager& RenderManager() const;
|
|
||||||
const TEntityManager& EntityManager() const;
|
|
||||||
const TSurfaceManager& SurfaceManager() const;
|
|
||||||
const TSpriteManager& SpriteManager() const;
|
|
||||||
const TFontManager& FontManager() const;
|
|
||||||
const TDigitManager& DigitManager() const;
|
|
||||||
const TAudioManager& AudioManager() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
TApp();
|
|
||||||
~TApp();
|
|
||||||
void Process();
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::unique_ptr<TFileManager> FileManager_;
|
|
||||||
std::unique_ptr<TRenderManager> RenderManager_;
|
|
||||||
std::unique_ptr<TEntityManager> EntityManager_;
|
|
||||||
std::unique_ptr<TSurfaceManager> SurfaceManager_;
|
|
||||||
std::unique_ptr<TSpriteManager> SpriteManager_;
|
|
||||||
std::unique_ptr<TFontManager> FontManager_;
|
|
||||||
std::unique_ptr<TDigitManager> DigitManager_;
|
|
||||||
std::unique_ptr<TAudioManager> AudioManager_;
|
|
||||||
TState State_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
|
|
||||||
@@ -1,150 +0,0 @@
|
|||||||
#include "AudioManager.h"
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
TAudioManager::TAudioManager(TFileManager& fileManager)
|
|
||||||
: FileManager_(fileManager) {
|
|
||||||
|
|
||||||
SDL_AudioSpec desired;
|
|
||||||
desired.freq = 48000;
|
|
||||||
desired.format = AUDIO_F32;
|
|
||||||
desired.channels = 2;
|
|
||||||
desired.samples = 2048;
|
|
||||||
desired.callback = NULL;
|
|
||||||
|
|
||||||
Device_ = SDL_OpenAudioDevice(NULL, 0, &desired, NULL, 0);
|
|
||||||
if (!Device_) {
|
|
||||||
throw std::runtime_error("no audio device");
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream_ = SDL_NewAudioStream(AUDIO_U8, 1, 22050, AUDIO_F32, 2, 48000);
|
|
||||||
if (!Stream_) {
|
|
||||||
throw std::runtime_error("can't create audio stream");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < 16; ++i) {
|
|
||||||
Channels_[i].InUse = false;
|
|
||||||
}
|
|
||||||
SDL_PauseAudioDevice(Device_, SDL_FALSE);
|
|
||||||
|
|
||||||
LastTick_ = SDL_GetTicks();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TAudioManager::Run() {
|
|
||||||
std::uint32_t currentTick = SDL_GetTicks();
|
|
||||||
|
|
||||||
Paint(Stream_, currentTick - LastTick_);
|
|
||||||
if (SDL_GetQueuedAudioSize(Device_) < 8192) {
|
|
||||||
const int bytesRemaining = SDL_AudioStreamAvailable(Stream_);
|
|
||||||
if (bytesRemaining > 0) {
|
|
||||||
const int samplesRemaining = SDL_min(bytesRemaining, 32 * 1024);
|
|
||||||
static Uint8 convertedBuffer[32 * 1024];
|
|
||||||
auto bytesRead = SDL_AudioStreamGet(Stream_, convertedBuffer, samplesRemaining);
|
|
||||||
SDL_QueueAudio(Device_, convertedBuffer, bytesRead);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LastTick_ = currentTick;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TAudioManager::Play(const std::string& path) {
|
|
||||||
TSound* sound = Load(path);
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < 16; i++) {
|
|
||||||
if (Channels_[i].InUse) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Channels_[i].InUse = true;
|
|
||||||
Channels_[i].Position = 0;
|
|
||||||
Channels_[i].Sound = sound;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TAudioManager::Paint(SDL_AudioStream* stream, std::uint32_t ticks) {
|
|
||||||
std::uint8_t temporary[1024];
|
|
||||||
std::size_t samples = std::min((ticks * 22050 + 999) / 1000, 1024u);
|
|
||||||
|
|
||||||
// Mix
|
|
||||||
for (size_t i = 0; i < samples; ++i) {
|
|
||||||
int16_t accumulator = 0;
|
|
||||||
|
|
||||||
for (size_t j = 0; j < 16; j++) {
|
|
||||||
auto& channel = Channels_[j];
|
|
||||||
if (!channel.InUse) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
accumulator += channel.Sound->Data[channel.Position];
|
|
||||||
accumulator -= 128;
|
|
||||||
channel.Position++;
|
|
||||||
|
|
||||||
if (channel.Position > channel.Sound->Size) {
|
|
||||||
channel.InUse = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
accumulator *= Volume_;
|
|
||||||
|
|
||||||
accumulator += 128;
|
|
||||||
if (accumulator < 0) {
|
|
||||||
accumulator = 0;
|
|
||||||
}
|
|
||||||
if (accumulator > 255) {
|
|
||||||
accumulator = 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
temporary[i] = accumulator;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output
|
|
||||||
if (samples > 0) {
|
|
||||||
SDL_AudioStreamPut(stream, temporary, samples * sizeof (std::uint8_t));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TAudioManager::SetVolume(float volume) {
|
|
||||||
if (volume > 1) {
|
|
||||||
volume = 1;
|
|
||||||
} else if (volume < 0) {
|
|
||||||
volume = 0;
|
|
||||||
}
|
|
||||||
Volume_ = volume;
|
|
||||||
}
|
|
||||||
|
|
||||||
float TAudioManager::Volume() const {
|
|
||||||
return Volume_;
|
|
||||||
}
|
|
||||||
|
|
||||||
TAudioManager::TSound* TAudioManager::Load(const std::string& path) {
|
|
||||||
auto it = Sounds_.find(path);
|
|
||||||
if (it != Sounds_.end()) {
|
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
TSound* newSound = new TSound;
|
|
||||||
auto data = FileManager_.Get(path);
|
|
||||||
SDL_RWops* rw = SDL_RWFromConstMem(data.data(), data.size());
|
|
||||||
if (!SDL_LoadWAV_RW(rw, 1, &newSound->Spec, &newSound->Data, &newSound->Size)) {
|
|
||||||
throw std::runtime_error("can't read WAV file " + path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newSound->Spec.channels != 1) {
|
|
||||||
throw std::runtime_error("not mono WAV file " + path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newSound->Spec.format != AUDIO_U8) {
|
|
||||||
throw std::runtime_error("not 8bit pcm WAV file " + path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newSound->Spec.freq != 22050) {
|
|
||||||
throw std::runtime_error("not 22050hz WAV file " + path);
|
|
||||||
}
|
|
||||||
|
|
||||||
Sounds_[path] = newSound;
|
|
||||||
return newSound;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Common.h"
|
|
||||||
|
|
||||||
#include "FileManager.h"
|
|
||||||
#include <SDL2/SDL.h>
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
class TAudioManager {
|
|
||||||
public:
|
|
||||||
TAudioManager(TFileManager& fileManager);
|
|
||||||
DELETE_COPY(TAudioManager)
|
|
||||||
|
|
||||||
void Run();
|
|
||||||
void Play(const std::string& sound);
|
|
||||||
void Paint(SDL_AudioStream* stream, std::uint32_t ticks);
|
|
||||||
void SetVolume(float volume);
|
|
||||||
float Volume() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct TSound {
|
|
||||||
SDL_AudioSpec Spec;
|
|
||||||
std::uint8_t* Data;
|
|
||||||
std::uint32_t Size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TSoundChannel {
|
|
||||||
bool InUse;
|
|
||||||
TSound* Sound;
|
|
||||||
std::uint32_t Position;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
TSound* Load(const std::string& sound);
|
|
||||||
|
|
||||||
private:
|
|
||||||
TFileManager& FileManager_;
|
|
||||||
float Volume_ = 1.0;
|
|
||||||
TSoundChannel Channels_[16];
|
|
||||||
std::unordered_map<std::string, TSound*> Sounds_;
|
|
||||||
SDL_AudioDeviceID Device_;
|
|
||||||
SDL_AudioStream* Stream_;
|
|
||||||
std::uint32_t LastTick_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
#include "Common.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cctype>
|
|
||||||
#include <iterator>
|
|
||||||
#include <string_view>
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
std::string ToUpper(const std::string_view& value) {
|
|
||||||
std::string result;
|
|
||||||
result.resize(value.size());
|
|
||||||
|
|
||||||
std::transform(value.begin(), value.end(), result.begin(), ::toupper);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ToLower(const std::string_view& value) {
|
|
||||||
std::string result;
|
|
||||||
result.resize(value.size());
|
|
||||||
|
|
||||||
std::transform(value.begin(), value.end(), result.begin(), ::tolower);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string_view LeftTrim(const std::string_view& value) {
|
|
||||||
auto firstNonSpace = std::find_if(value.begin(), value.end(), [](char symbol) {
|
|
||||||
return !std::isspace(symbol);
|
|
||||||
});
|
|
||||||
|
|
||||||
auto length = std::distance(firstNonSpace, value.end());
|
|
||||||
return std::string_view(&*firstNonSpace, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string_view RightTrim(const std::string_view& value) {
|
|
||||||
auto lastNonSpace = std::find_if(value.rbegin(), value.rend(), [](char symbol) {
|
|
||||||
return !std::isspace(symbol);
|
|
||||||
});
|
|
||||||
|
|
||||||
auto index = value.size() - std::distance(value.rbegin(), lastNonSpace);
|
|
||||||
auto length = std::distance(value.begin(), value.begin() + index);
|
|
||||||
return std::string_view(&*value.begin(), length);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string_view Trim(const std::string_view& value) {
|
|
||||||
return LeftTrim(RightTrim(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string_view NextToken(std::string_view& value, const std::string_view& token) {
|
|
||||||
auto position = value.find(token);
|
|
||||||
auto result = value.substr(0, position);
|
|
||||||
|
|
||||||
if (position == std::string_view::npos) {
|
|
||||||
value = {};
|
|
||||||
} else {
|
|
||||||
value = value.substr(position + token.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RectContains(const Vec2i& position, const Vec2i& size, const Vec2i& point) {
|
|
||||||
if (point.X < position.X || point.X - position.X > size.X ||
|
|
||||||
point.Y < position.Y || point.Y - position.Y > size.Y) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RectOverlaps(const Vec2i& positionA, const Vec2i& sizeA, const Vec2i& positionB, const Vec2i& sizeB) {
|
|
||||||
if (positionB.X + sizeB.X <= positionA.X ||
|
|
||||||
positionA.X + sizeA.X <= positionB.X ||
|
|
||||||
positionB.Y + sizeB.Y <= positionA.Y ||
|
|
||||||
positionA.Y + sizeA.Y <= positionB.Y) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
-174
@@ -1,174 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <bitset>
|
|
||||||
#include <cmath>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <string_view>
|
|
||||||
#include <string>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
#define GAME_UNUSED(x) (void)(x)
|
|
||||||
|
|
||||||
#define DELETE_COPY(NAME) \
|
|
||||||
NAME(const NAME&) = delete; \
|
|
||||||
NAME& operator=(const NAME&) = delete;
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
template<class... Ts>
|
|
||||||
struct TOverload : Ts... { using Ts::operator()...; };
|
|
||||||
|
|
||||||
template<class... Ts>
|
|
||||||
TOverload(Ts...) -> TOverload<Ts...>;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct Vec2 {
|
|
||||||
using TType = T;
|
|
||||||
|
|
||||||
Vec2<T>()
|
|
||||||
: X(), Y() {
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec2<T>(T value)
|
|
||||||
: X(value), Y(value) {
|
|
||||||
}
|
|
||||||
Vec2<T>(T x, T y)
|
|
||||||
: X(x), Y(y) {
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec2<T> operator+(const Vec2<T>& other) const {
|
|
||||||
Vec2<T> result(X + other.X, Y + other.Y);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec2<T>& operator+=(const Vec2<T>& other) {
|
|
||||||
X += other.X;
|
|
||||||
Y += other.Y;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec2<T> operator-(const Vec2<T>& other) const {
|
|
||||||
Vec2<T> result(X - other.X, Y - other.Y);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec2<T>& operator-=(const Vec2<T>& other) {
|
|
||||||
X -= other.X;
|
|
||||||
Y -= other.Y;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Q>
|
|
||||||
Vec2<T> operator*(const Vec2<Q>& other) const {
|
|
||||||
Vec2<T> result(X * other.X, Y * other.Y);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Q>
|
|
||||||
Vec2<T>& operator*=(const Vec2<Q>& other) {
|
|
||||||
X *= other.X;
|
|
||||||
Y *= other.Y;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Q>
|
|
||||||
Vec2<T> operator*(const Q& other) const {
|
|
||||||
Vec2<T> result(X * other, Y * other);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Q>
|
|
||||||
Vec2<T>& operator*=(const Q& other) {
|
|
||||||
X *= other;
|
|
||||||
Y *= other;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Q>
|
|
||||||
Vec2<T> operator/(const Vec2<Q>& other) const {
|
|
||||||
Vec2<T> result(X / other.X, Y / other.Y);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Q>
|
|
||||||
Vec2<T>& operator/=(const Vec2<Q>& other) {
|
|
||||||
X /= other.X;
|
|
||||||
Y /= other.Y;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Q>
|
|
||||||
Vec2<T> operator/(const Q& other) const {
|
|
||||||
Vec2<T> result(X / other, Y / other);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Q>
|
|
||||||
Vec2<T>& operator/=(const Q& other) {
|
|
||||||
X /= other;
|
|
||||||
Y /= other;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Q = T, typename = typename std::enable_if<std::is_floating_point<Q>::value>::type>
|
|
||||||
Q Length() const {
|
|
||||||
return std::sqrt(X * X + Y * Y);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Q = T, typename = typename std::enable_if<std::is_floating_point<Q>::value>::type>
|
|
||||||
Vec2<T> Normilize() const {
|
|
||||||
return *this / Length();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Q = T, typename = typename std::enable_if<!std::is_floating_point<Q>::value>::type>
|
|
||||||
float Length() const {
|
|
||||||
return std::sqrt(static_cast<float>(X * X + Y * Y));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const Vec2<T>& other) const {
|
|
||||||
return X == other.X && Y == other.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(const Vec2<T>& other) const {
|
|
||||||
return X != other.X || Y != other.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
T X;
|
|
||||||
T Y;
|
|
||||||
};
|
|
||||||
T Data[2];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
using Vec2f = Vec2<float>;
|
|
||||||
using Vec2i = Vec2<std::int32_t>;
|
|
||||||
|
|
||||||
std::string ToUpper(const std::string_view& value);
|
|
||||||
std::string ToLower(const std::string_view& value);
|
|
||||||
std::string_view LeftTrim(const std::string_view& value);
|
|
||||||
std::string_view RightTrim(const std::string_view& value);
|
|
||||||
std::string_view Trim(const std::string_view& value);
|
|
||||||
std::string_view NextToken(std::string_view& value, const std::string_view& token);
|
|
||||||
|
|
||||||
bool RectContains(const Vec2i& position, const Vec2i& size, const Vec2i& point);
|
|
||||||
bool RectOverlaps(const Vec2i& positionA, const Vec2i& sizeA, const Vec2i& positionB, const Vec2i& sizeB);
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct std::hash<NGame::Vec2i> {
|
|
||||||
std::size_t operator()(const NGame::Vec2i& key) const {
|
|
||||||
return ((static_cast<std::size_t>(key.X) * 73856093) ^
|
|
||||||
(static_cast<std::size_t>(key.Y) * 19349663));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct std::hash<NGame::Vec2f> {
|
|
||||||
std::size_t operator()(const NGame::Vec2f& key) const {
|
|
||||||
return ((static_cast<std::size_t>(key.X) * 73856093) ^
|
|
||||||
(static_cast<std::size_t>(key.Y) * 19349663));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
#include "DigitManager.h"
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
TDigitManager::TDigitManager(TSpriteManager& spriteManager)
|
|
||||||
: SpriteManager_(spriteManager) {
|
|
||||||
Digits_ = SpriteManager_.Get("Sprites/Digits.txt");
|
|
||||||
}
|
|
||||||
|
|
||||||
void TDigitManager::Draw(const Vec2i position, int value, int length, int point) {
|
|
||||||
Vec2i currentPosition = {position.X + length * GlyphSize.X, position.Y};
|
|
||||||
|
|
||||||
for (size_t remainder = length; remainder; --remainder, --point) {
|
|
||||||
if (value) {
|
|
||||||
auto digit = value % 10;
|
|
||||||
value /= 10;
|
|
||||||
|
|
||||||
if (point == 0) {
|
|
||||||
SpriteManager_.Draw(Digits_, digit + 11, currentPosition);
|
|
||||||
} else {
|
|
||||||
SpriteManager_.Draw(Digits_, digit, currentPosition);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (point == 0) {
|
|
||||||
SpriteManager_.Draw(Digits_, 21, currentPosition);
|
|
||||||
} else {
|
|
||||||
SpriteManager_.Draw(Digits_, 10, currentPosition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
currentPosition.X -= GlyphSize.X;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Common.h"
|
|
||||||
|
|
||||||
#include "SpriteManager.h"
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
class TDigitManager {
|
|
||||||
public:
|
|
||||||
TDigitManager(TSpriteManager& spriteManager);
|
|
||||||
DELETE_COPY(TDigitManager)
|
|
||||||
|
|
||||||
void Draw(const Vec2i position, int value, int length, int point);
|
|
||||||
|
|
||||||
private:
|
|
||||||
TSpriteManager& SpriteManager_;
|
|
||||||
const Vec2i GlyphSize = {7, 12};
|
|
||||||
std::shared_ptr<TSpriteManager::TSprite> Digits_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
-113
@@ -1,113 +0,0 @@
|
|||||||
#include "Entity.h"
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
TEntity::TEntity(TEntity::TId id)
|
|
||||||
: Id_(id) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void TEntity::Tick(std::uint32_t delta) {
|
|
||||||
Alarm_.Update(delta);
|
|
||||||
|
|
||||||
TAlarm::TId alarmId;
|
|
||||||
while (Alarm_.Next(alarmId)) {
|
|
||||||
Alarm(alarmId);
|
|
||||||
}
|
|
||||||
Update(delta);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TEntity::Input(SDL_Event* event) {
|
|
||||||
GAME_UNUSED(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TEntity::Update(std::uint32_t delta) {
|
|
||||||
GAME_UNUSED(delta);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TEntity::Alarm(TAlarm::TId id) {
|
|
||||||
GAME_UNUSED(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TEntity::Draw() const {
|
|
||||||
}
|
|
||||||
|
|
||||||
void TEntity::SetPosition(Vec2i value) {
|
|
||||||
Position_ = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TEntity::SetSize(Vec2i value) {
|
|
||||||
Size_ = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Vec2i& TEntity::Position() const {
|
|
||||||
return Position_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Vec2i& TEntity::Size() const {
|
|
||||||
return Size_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Vec2i& TEntity::AckPosition() const {
|
|
||||||
return AckPosition_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Vec2i& TEntity::AckSize() const {
|
|
||||||
return AckSize_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TEntity::HasChanges() const {
|
|
||||||
if (AckPosition_ != Position_ || AckSize_ != Size_)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TEntity::AckChanges() {
|
|
||||||
AckPosition_ = Position_;
|
|
||||||
AckSize_ = Size_;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEntity::TCollisionGroup TEntity::CollisionGroup() const {
|
|
||||||
return CollisionGroup_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TEntity::SetCollisionGroup(TCollisionGroup group) {
|
|
||||||
CollisionGroup_ = group;
|
|
||||||
}
|
|
||||||
|
|
||||||
float TEntity::MovementPerTick(std::uint32_t delta, float speed) {
|
|
||||||
return speed * (delta / 1000.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec2f TEntity::MovementPerTick(std::uint32_t delta, Vec2f speed) {
|
|
||||||
return speed * (delta / 1000.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<std::int32_t, float> TEntity::NextMovement(float speed, float fraction) {
|
|
||||||
std::pair<std::int32_t, float> result;
|
|
||||||
|
|
||||||
result.second = speed + fraction;
|
|
||||||
result.first = static_cast<std::int32_t>(result.second);
|
|
||||||
result.second -= result.first;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEntity::TId TEntity::Id() const {
|
|
||||||
return Id_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TEntity::Remove() {
|
|
||||||
IsRemoved_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TEntity::IsRemoved() const {
|
|
||||||
return IsRemoved_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TEntity::IsPersistent() const {
|
|
||||||
return IsPersistent_;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
-112
@@ -1,112 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Common.h"
|
|
||||||
|
|
||||||
#include "Alarm.h"
|
|
||||||
#include "State.h"
|
|
||||||
|
|
||||||
#include <bitset>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <SDL2/SDL_events.h>
|
|
||||||
#include <SDL2/SDL_render.h>
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
class TEntity {
|
|
||||||
public:
|
|
||||||
using TId = std::uint32_t;
|
|
||||||
using TCollisionGroup = std::bitset<32>;
|
|
||||||
|
|
||||||
TEntity(TEntity::TId id);
|
|
||||||
virtual ~TEntity() = default;
|
|
||||||
void Tick(std::uint32_t delta);
|
|
||||||
virtual void Input(SDL_Event* event);
|
|
||||||
virtual void Update(std::uint32_t delta);
|
|
||||||
virtual void Alarm(TAlarm::TId id);
|
|
||||||
virtual void Draw() const;
|
|
||||||
|
|
||||||
void SetPosition(Vec2i value);
|
|
||||||
void SetSize(Vec2i value);
|
|
||||||
const Vec2i& Position() const;
|
|
||||||
const Vec2i& Size() const;
|
|
||||||
const Vec2i& AckPosition() const;
|
|
||||||
const Vec2i& AckSize() const;
|
|
||||||
bool HasChanges() const;
|
|
||||||
void AckChanges();
|
|
||||||
|
|
||||||
TCollisionGroup CollisionGroup() const;
|
|
||||||
void SetCollisionGroup(TCollisionGroup group);
|
|
||||||
static float MovementPerTick(std::uint32_t delta, float speed);
|
|
||||||
static Vec2f MovementPerTick(std::uint32_t delta, Vec2f speed);
|
|
||||||
std::pair<Vec2i::TType, float> NextMovement(float speed, float fraction);
|
|
||||||
|
|
||||||
template<typename UnaryPredicate>
|
|
||||||
std::pair<Vec2f, std::pair<bool, bool>> MoveWithCondition(Vec2f speed, Vec2f fraction, UnaryPredicate p) {
|
|
||||||
auto distanceX = NextMovement(speed.X, fraction.X);
|
|
||||||
auto distanceY = NextMovement(speed.Y, fraction.Y);
|
|
||||||
auto directionFlags = std::make_pair(true, true);
|
|
||||||
|
|
||||||
Vec2f resultFraction(distanceX.second, distanceY.second);
|
|
||||||
Vec2i resultDistance(distanceX.first, distanceY.first);
|
|
||||||
|
|
||||||
Vec2i newPosition = Position() + resultDistance;
|
|
||||||
if (p(newPosition)) {
|
|
||||||
// There is no problem with the new position, we are done
|
|
||||||
SetPosition(newPosition);
|
|
||||||
} else {
|
|
||||||
// There might be some problem, move 1px at a time
|
|
||||||
Vec2i direction(1, 1);
|
|
||||||
|
|
||||||
if (resultDistance.X < 0) {
|
|
||||||
direction.X = -1;
|
|
||||||
}
|
|
||||||
if (resultDistance.Y < 0) {
|
|
||||||
direction.Y = -1;
|
|
||||||
}
|
|
||||||
resultDistance.X = abs(resultDistance.X);
|
|
||||||
resultDistance.Y = abs(resultDistance.Y);
|
|
||||||
|
|
||||||
for (Vec2i::TType i = 0; i < resultDistance.X; ++i) {
|
|
||||||
newPosition = Position() + Vec2i(direction.X, 0);
|
|
||||||
if (!p(newPosition)) {
|
|
||||||
resultFraction.X = 0;
|
|
||||||
directionFlags.first = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
SetPosition(newPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Vec2i::TType i = 0; i < resultDistance.Y; ++i) {
|
|
||||||
newPosition = Position() + Vec2i(0, direction.Y);
|
|
||||||
if (!p(newPosition)) {
|
|
||||||
resultFraction.Y = 0;
|
|
||||||
directionFlags.second = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
SetPosition(newPosition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::make_pair(resultFraction, directionFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEntity::TId Id() const;
|
|
||||||
void Remove();
|
|
||||||
bool IsRemoved() const;
|
|
||||||
bool IsPersistent() const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
TAlarm Alarm_;
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool IsPersistent_ = false;
|
|
||||||
bool IsRemoved_ = false;
|
|
||||||
TEntity::TId Id_;
|
|
||||||
TCollisionGroup CollisionGroup_;
|
|
||||||
Vec2i Position_;
|
|
||||||
Vec2i Size_;
|
|
||||||
Vec2i AckPosition_;
|
|
||||||
Vec2i AckSize_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
@@ -1,173 +0,0 @@
|
|||||||
#include "EntityManager.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <SDL2/SDL_timer.h>
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
TEntityManager::TEntityManager(TRenderManager& renderManager, std::size_t timestep)
|
|
||||||
: RenderManager_(renderManager), Timestep_(timestep) {
|
|
||||||
LastUpdateTick_ = SDL_GetTicks();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TEntityManager::Run() {
|
|
||||||
if (PendingReset_) {
|
|
||||||
PendingReset_ = false;
|
|
||||||
Entities_.clear();
|
|
||||||
Gridmap_.Reset();
|
|
||||||
for (const auto& name : DeferredEntities_) {
|
|
||||||
MakeEntityByName(name);
|
|
||||||
}
|
|
||||||
DeferredEntities_.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
Input();
|
|
||||||
Update();
|
|
||||||
Draw();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<TEntity> TEntityManager::Entity(TEntity::TId id) {
|
|
||||||
auto it = Entities_.find(id);
|
|
||||||
if (it != Entities_.end()) {
|
|
||||||
return it->second;
|
|
||||||
}
|
|
||||||
throw std::runtime_error("Could not find entity with id: " + std::to_string(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
void TEntityManager::UpdateCollision(TEntity::TId id) {
|
|
||||||
auto entity = Entity(id);
|
|
||||||
UpdateCollision(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TEntityManager::UpdateCollision(std::shared_ptr<TEntity> entity) {
|
|
||||||
if (entity->HasChanges()) {
|
|
||||||
Gridmap_.Remove(entity->AckPosition(), entity->AckSize(), entity->Id());
|
|
||||||
Gridmap_.Add(entity->Position(), entity->Size(), entity->Id());
|
|
||||||
entity->AckChanges();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<TEntity> TEntityManager::MakeEntityByName(const std::string& name) {
|
|
||||||
if (EntityFactories_.find(name) == EntityFactories_.end()) {
|
|
||||||
throw std::runtime_error("can't create entity with name " + name);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto entity = EntityFactories_[name](++IdCounter_);
|
|
||||||
Entities_[entity->Id()] = entity;
|
|
||||||
|
|
||||||
// Explicilty ack changes in entity colision boxes
|
|
||||||
Gridmap_.Add(entity->Position(), entity->Size(), entity->Id());
|
|
||||||
entity->AckChanges();
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TEntityManager::IsPlaceEmpty(const Vec2i& position, const Vec2i& size, TEntity::TCollisionGroup group, TEntity::TId ignoreId) {
|
|
||||||
auto query = Gridmap_.Query(position, size);
|
|
||||||
|
|
||||||
return !std::any_of(query.begin(), query.end(), [&](auto id) {
|
|
||||||
auto entity = Entity(id);
|
|
||||||
if (id == ignoreId)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!(entity->CollisionGroup() & group).any())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return RectOverlaps(position, size, entity->Position(), entity->Size());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unordered_set<TEntity::TId> TEntityManager::CollisionList(const Vec2i& position, const Vec2i& size, TEntity::TCollisionGroup group, TEntity::TId ignoreId) {
|
|
||||||
auto query = Gridmap_.Query(position, size);
|
|
||||||
|
|
||||||
for (auto it = query.begin(); it != query.end(); ) {
|
|
||||||
auto entity = Entity(*it);
|
|
||||||
|
|
||||||
if (entity->Id() == ignoreId || !(entity->CollisionGroup() & group).any()) {
|
|
||||||
it = query.erase(it);
|
|
||||||
} else {
|
|
||||||
if (RectOverlaps(position, size, entity->Position(), entity->Size())) {
|
|
||||||
++it;
|
|
||||||
} else {
|
|
||||||
it = query.erase(it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return query;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<TEntity::TId> TEntityManager::Ids() const {
|
|
||||||
std::vector<TEntity::TId> result;
|
|
||||||
|
|
||||||
result.reserve(Entities_.size());
|
|
||||||
for (const auto& entity : Entities_) {
|
|
||||||
result.push_back(entity.first);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TEntityManager::AddToDeferred(const std::string& name) {
|
|
||||||
DeferredEntities_.push_back(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TEntityManager::Reset() {
|
|
||||||
PendingReset_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TEntityManager::Input() {
|
|
||||||
SDL_Event event;
|
|
||||||
while (RenderManager_.Input(&event)) {
|
|
||||||
std::for_each(Entities_.begin(), Entities_.end(), [&](auto& entity) {
|
|
||||||
entity.second->Input(&event);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TEntityManager::Update() {
|
|
||||||
std::uint32_t currentTick = SDL_GetTicks();
|
|
||||||
std::size_t attempts = 5;
|
|
||||||
|
|
||||||
while (--attempts && (currentTick - LastUpdateTick_ > Timestep_)) {
|
|
||||||
LastUpdateTick_ += Timestep_;
|
|
||||||
|
|
||||||
std::queue<TEntity::TId> idForRemoval;
|
|
||||||
|
|
||||||
// Update each enitity
|
|
||||||
std::for_each(Entities_.begin(), Entities_.end(), [&](auto& pair) {
|
|
||||||
auto& entity = pair.second;
|
|
||||||
|
|
||||||
if (!entity->IsRemoved()) {
|
|
||||||
entity->Tick(Timestep_);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entity->IsRemoved()) {
|
|
||||||
// Explicitly remove collision
|
|
||||||
Gridmap_.Remove(entity->AckPosition(), entity->AckSize(), entity->Id());
|
|
||||||
idForRemoval.emplace(pair.first);
|
|
||||||
} else {
|
|
||||||
UpdateCollision(entity);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Remove removed entities
|
|
||||||
while (!idForRemoval.empty()) {
|
|
||||||
Entities_.erase(idForRemoval.front());
|
|
||||||
idForRemoval.pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Failsafe when we run out of attempts
|
|
||||||
if (!attempts) {
|
|
||||||
LastUpdateTick_ = currentTick;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TEntityManager::Draw() {
|
|
||||||
std::for_each(Entities_.begin(), Entities_.end(), [&](auto& pair) {
|
|
||||||
auto& entity = pair.second;
|
|
||||||
entity->Draw();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Common.h"
|
|
||||||
|
|
||||||
#include "Entity.h"
|
|
||||||
#include "Gridmap.h"
|
|
||||||
#include "RenderManager.h"
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
class TEntityManager {
|
|
||||||
public:
|
|
||||||
TEntityManager(TRenderManager& renderManager, const std::size_t timestep = 1000 / 30);
|
|
||||||
DELETE_COPY(TEntityManager)
|
|
||||||
|
|
||||||
void Run();
|
|
||||||
std::shared_ptr<TEntity> Entity(TEntity::TId id);
|
|
||||||
void UpdateCollision(TEntity::TId id);
|
|
||||||
void UpdateCollision(std::shared_ptr<TEntity> entity);
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void RegisterEntity(const std::string& name) {
|
|
||||||
if (EntityFactories_.find(name) != EntityFactories_.end()) {
|
|
||||||
throw std::runtime_error("can't register duplicate entity with name " + name);
|
|
||||||
}
|
|
||||||
EntityFactories_[name] = &MakeEntityFactory<T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T, class... Args>
|
|
||||||
std::shared_ptr<TEntity> MakeEntity(Args&&... args) {
|
|
||||||
auto entity = std::make_shared<T>(++IdCounter_, std::forward<Args>(args)...);
|
|
||||||
Entities_[entity->Id()] = entity;
|
|
||||||
|
|
||||||
// Explicilty ack changes in entity colision boxes
|
|
||||||
Gridmap_.Add(entity->Position(), entity->Size(), entity->Id());
|
|
||||||
entity->AckChanges();
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<TEntity> MakeEntityByName(const std::string& name);
|
|
||||||
bool IsPlaceEmpty(const Vec2i& position, const Vec2i& size, TEntity::TCollisionGroup group, TEntity::TId ignoreId = {});
|
|
||||||
std::unordered_set<TEntity::TId> CollisionList(const Vec2i& position, const Vec2i& size, TEntity::TCollisionGroup group, TEntity::TId ignoreId = {});
|
|
||||||
std::vector<TEntity::TId> Ids() const;
|
|
||||||
void AddToDeferred(const std::string& name);
|
|
||||||
void Reset();
|
|
||||||
|
|
||||||
private:
|
|
||||||
using TFactoryMethod = std::shared_ptr<TEntity>(*)(TEntity::TId);
|
|
||||||
|
|
||||||
void Input();
|
|
||||||
void Update();
|
|
||||||
void Draw();
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static std::shared_ptr<TEntity> MakeEntityFactory(TEntity::TId id) {
|
|
||||||
return std::make_shared<T>(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
TRenderManager& RenderManager_;
|
|
||||||
std::unordered_map<TEntity::TId, std::shared_ptr<TEntity>> Entities_;
|
|
||||||
std::unordered_map<std::string, TFactoryMethod> EntityFactories_;
|
|
||||||
std::vector<std::string> DeferredEntities_;
|
|
||||||
std::uint32_t LastUpdateTick_;
|
|
||||||
TEntity::TId IdCounter_;
|
|
||||||
std::size_t Timestep_;
|
|
||||||
TGridmap Gridmap_;
|
|
||||||
bool PendingReset_ = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
#include "FileManager.h"
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
TFileManager::TFileManager(const std::string& dataDirectory, const std::string& archivePath, std::size_t cacheSize)
|
|
||||||
: DataDirectory_(dataDirectory), ArchivePath_(archivePath), Cache_(cacheSize) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string TFileManager::Get(const std::string& path) {
|
|
||||||
if (Cache_.Contains(path)) {
|
|
||||||
return Cache_.Get(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto getAttempt = FromFilesystem(path);
|
|
||||||
if (getAttempt.second) {
|
|
||||||
Cache_.Set(path, getAttempt.first);
|
|
||||||
return getAttempt.first;
|
|
||||||
}
|
|
||||||
|
|
||||||
getAttempt = FromArchive(path);
|
|
||||||
if (getAttempt.second) {
|
|
||||||
Cache_.Set(path, getAttempt.first);
|
|
||||||
return getAttempt.first;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw std::runtime_error("can't find file " + path);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<std::string, bool> TFileManager::FromFilesystem(const std::string& path) {
|
|
||||||
auto finalPath = DataDirectory_ + "/" + path;
|
|
||||||
|
|
||||||
std::ifstream fileStream(finalPath, std::ios::in | std::ios::binary);
|
|
||||||
if (!fileStream.is_open()) {
|
|
||||||
return std::make_pair<std::string, bool>({}, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stringstream fileStringStream;
|
|
||||||
fileStringStream << fileStream.rdbuf();
|
|
||||||
return std::make_pair(fileStringStream.str(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<std::string, bool> TFileManager::FromArchive(const std::string& path) {
|
|
||||||
std::ifstream archiveStream(ArchivePath_, std::ios::in | std::ios::binary);
|
|
||||||
if (!archiveStream.is_open()) {
|
|
||||||
return std::make_pair<std::string, bool>({}, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Identify and validate PAK file
|
|
||||||
char identifier[4];
|
|
||||||
archiveStream.read(identifier, 4);
|
|
||||||
if (std::memcmp(identifier, "PACK", 4)) {
|
|
||||||
return std::make_pair<std::string, bool>({}, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::uint32_t tocOffset = ReadInt32(archiveStream);
|
|
||||||
std::uint32_t tocSize = ReadInt32(archiveStream) / 64;
|
|
||||||
|
|
||||||
if (!tocSize || tocOffset < 12) {
|
|
||||||
return std::make_pair<std::string, bool>({}, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find requested file
|
|
||||||
archiveStream.seekg(tocOffset);
|
|
||||||
|
|
||||||
for (std::uint32_t index = 0; index < tocSize; ++index) {
|
|
||||||
char name[56];
|
|
||||||
|
|
||||||
archiveStream.read(name, 56);
|
|
||||||
std::uint32_t fileOffset = ReadInt32(archiveStream);
|
|
||||||
std::uint32_t fileSize = ReadInt32(archiveStream);
|
|
||||||
|
|
||||||
if (std::strncmp(name, path.c_str(), 56)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
archiveStream.seekg(fileOffset);
|
|
||||||
std::string result(fileSize, 0);
|
|
||||||
archiveStream.read(result.data(), result.size());
|
|
||||||
|
|
||||||
return std::make_pair(result, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::make_pair<std::string, bool>({}, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::uint32_t TFileManager::ReadInt32(std::ifstream& stream) {
|
|
||||||
unsigned char bytes[4];
|
|
||||||
stream.read(reinterpret_cast<char*>(bytes), 4);
|
|
||||||
return (bytes[0] << 0) | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Common.h"
|
|
||||||
|
|
||||||
#include "LRU.h"
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
class TFileManager {
|
|
||||||
public:
|
|
||||||
TFileManager(const std::string& dataDirectory, const std::string& archivePath, std::size_t cacheSize = 4);
|
|
||||||
DELETE_COPY(TFileManager)
|
|
||||||
|
|
||||||
std::string Get(const std::string& path);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::pair<std::string, bool> FromFilesystem(const std::string& path);
|
|
||||||
std::pair<std::string, bool> FromArchive(const std::string& path);
|
|
||||||
std::uint32_t ReadInt32(std::ifstream& stream);
|
|
||||||
|
|
||||||
private:
|
|
||||||
const std::string DataDirectory_;
|
|
||||||
const std::string ArchivePath_;
|
|
||||||
TLRU<std::string, std::string> Cache_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
#include "FontManager.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
TFontManager::TFontManager(TSpriteManager& spriteManager)
|
|
||||||
: SpriteManager_(spriteManager) {
|
|
||||||
Fonts_[White] = SpriteManager_.Get("Fonts/White.txt");
|
|
||||||
Fonts_[Gray] = SpriteManager_.Get("Fonts/Gray.txt");
|
|
||||||
Fonts_[Red] = SpriteManager_.Get("Fonts/Red.txt");
|
|
||||||
Fonts_[Green] = SpriteManager_.Get("Fonts/Green.txt");
|
|
||||||
Fonts_[Blue] = SpriteManager_.Get("Fonts/Blue.txt");
|
|
||||||
Fonts_[Purple] = SpriteManager_.Get("Fonts/Purple.txt");
|
|
||||||
Fonts_[Gold] = SpriteManager_.Get("Fonts/Gold.txt");
|
|
||||||
Fonts_[Swamp] = SpriteManager_.Get("Fonts/Swamp.txt");
|
|
||||||
Fonts_[LightBlue] = SpriteManager_.Get("Fonts/LightBlue.txt");
|
|
||||||
}
|
|
||||||
|
|
||||||
void TFontManager::Draw(EColor color, const Vec2i position, const std::string& text) {
|
|
||||||
Vec2i currentPosition = position;
|
|
||||||
|
|
||||||
for (const auto& symbol : text) {
|
|
||||||
if (symbol >= ' ' && symbol <= '~') {
|
|
||||||
SpriteManager_.Draw(Fonts_[color], (unsigned char)symbol - ' ', currentPosition);
|
|
||||||
currentPosition += Vec2i(GlyphSize.X, 0);
|
|
||||||
} else if (symbol == '\n') {
|
|
||||||
currentPosition = Vec2i(position.X, currentPosition.Y + GlyphSize.Y);
|
|
||||||
} else if (symbol == '\t') {
|
|
||||||
currentPosition += Vec2i(GlyphSize.X * 4, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Common.h"
|
|
||||||
|
|
||||||
#include "SpriteManager.h"
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
class TFontManager {
|
|
||||||
public:
|
|
||||||
enum EColor {
|
|
||||||
White,
|
|
||||||
Gray,
|
|
||||||
Red,
|
|
||||||
Green,
|
|
||||||
Blue,
|
|
||||||
Purple,
|
|
||||||
Gold,
|
|
||||||
Swamp,
|
|
||||||
LightBlue,
|
|
||||||
SentinelMax
|
|
||||||
};
|
|
||||||
|
|
||||||
TFontManager(TSpriteManager& spriteManager);
|
|
||||||
DELETE_COPY(TFontManager)
|
|
||||||
|
|
||||||
void Draw(EColor color, const Vec2i position, const std::string& text);
|
|
||||||
|
|
||||||
private:
|
|
||||||
TSpriteManager& SpriteManager_;
|
|
||||||
const Vec2i GlyphSize = {5, 12};
|
|
||||||
std::array<std::shared_ptr<TSpriteManager::TSprite>, SentinelMax> Fonts_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
#include "Gridmap.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <unordered_set>
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
std::unordered_set<TEntity::TId> TGridmap::Query(const Vec2i& position, const Vec2i& size) const {
|
|
||||||
Vec2i cellPosition = position / CellSize_;
|
|
||||||
Vec2i cellEnd = cellPosition + ((size + (CellSize_ - 1)) / CellSize_);
|
|
||||||
|
|
||||||
std::unordered_set<TEntity::TId> result;
|
|
||||||
for (Vec2i::TType i = cellPosition.X; i <= cellEnd.X; ++i) {
|
|
||||||
for (Vec2i::TType j = cellPosition.Y; j <= cellEnd.Y; ++j) {
|
|
||||||
TId gridId = GridId(Vec2i(i, j));
|
|
||||||
const auto& cell = Grid_[gridId];
|
|
||||||
for (auto id : cell) {
|
|
||||||
result.insert(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TGridmap::Remove(const Vec2i& position, const Vec2i& size, TEntity::TId id) {
|
|
||||||
Vec2i cellPosition = position / CellSize_;
|
|
||||||
Vec2i cellEnd = cellPosition + ((size + (CellSize_ - 1)) / CellSize_);
|
|
||||||
|
|
||||||
std::unordered_set<TEntity::TId> result;
|
|
||||||
for (Vec2i::TType i = cellPosition.X; i <= cellEnd.X; ++i) {
|
|
||||||
for (Vec2i::TType j = cellPosition.Y; j <= cellEnd.Y; ++j) {
|
|
||||||
TId gridId = GridId(Vec2i(i, j));
|
|
||||||
auto& cell = Grid_[gridId];
|
|
||||||
auto it = std::remove(cell.begin(), cell.end(), id);
|
|
||||||
cell.erase(it, cell.end());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TGridmap::Add(const Vec2i& position, const Vec2i& size, TEntity::TId id) {
|
|
||||||
Vec2i cellPosition = position / CellSize_;
|
|
||||||
Vec2i cellEnd = cellPosition + ((size + (CellSize_ - 1)) / CellSize_);
|
|
||||||
|
|
||||||
std::unordered_set<TEntity::TId> result;
|
|
||||||
for (Vec2i::TType i = cellPosition.X; i <= cellEnd.X; ++i) {
|
|
||||||
for (Vec2i::TType j = cellPosition.Y; j <= cellEnd.Y; ++j) {
|
|
||||||
TId gridId = GridId(Vec2i(i, j));
|
|
||||||
Grid_[gridId].push_back(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TGridmap::Reset() {
|
|
||||||
for (auto& cell : Grid_) {
|
|
||||||
cell.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TGridmap::TId TGridmap::GridId(const Vec2i& point) const {
|
|
||||||
return std::hash<Vec2i>{}(point) % Grid_.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Common.h"
|
|
||||||
|
|
||||||
#include "Entity.h"
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <unordered_set>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
class TGridmap {
|
|
||||||
public:
|
|
||||||
std::unordered_set<TEntity::TId> Query(const Vec2i& position, const Vec2i& size) const;
|
|
||||||
void Remove(const Vec2i& position, const Vec2i& size, TEntity::TId id);
|
|
||||||
void Add(const Vec2i& position, const Vec2i& size, TEntity::TId id);
|
|
||||||
void Reset();
|
|
||||||
|
|
||||||
private:
|
|
||||||
using TId = size_t;
|
|
||||||
TId GridId(const Vec2i& point) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::array<std::vector<TEntity::TId>, 32768> Grid_;
|
|
||||||
const std::uint32_t CellSize_ = 128;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <list>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
template<typename Key, typename Value>
|
|
||||||
class TLRU {
|
|
||||||
public:
|
|
||||||
using TPair = std::pair<Key, Value>;
|
|
||||||
using TKey = Key;
|
|
||||||
using TValue = Value;
|
|
||||||
|
|
||||||
TLRU(std::size_t capacity)
|
|
||||||
: Capacity_(capacity) {
|
|
||||||
}
|
|
||||||
|
|
||||||
const Value& Get(const Key& key) const {
|
|
||||||
auto it = Map_.find(key);
|
|
||||||
if (it == Map_.end()) {
|
|
||||||
throw std::runtime_error("lru cache miss");
|
|
||||||
}
|
|
||||||
|
|
||||||
Cache_.splice(Cache_.begin(), Cache_, it->second);
|
|
||||||
return it->second->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Set(const Key& key, const Value& value) {
|
|
||||||
Set(key, value, [](auto& value){});
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename UnaryPredicate>
|
|
||||||
void Set(const Key& key, const Value& value, UnaryPredicate p) {
|
|
||||||
auto it = Map_.find(key);
|
|
||||||
if (it != Map_.end()) {
|
|
||||||
p(*it->second);
|
|
||||||
Cache_.erase(it->second);
|
|
||||||
Map_.erase(it);
|
|
||||||
}
|
|
||||||
|
|
||||||
Cache_.push_front(std::make_pair(key, value));
|
|
||||||
Map_[key] = Cache_.begin();
|
|
||||||
|
|
||||||
while (Map_.size() > Capacity_) {
|
|
||||||
auto lastElement = --(Cache_.end());
|
|
||||||
p(*lastElement);
|
|
||||||
Map_.erase(lastElement->first);
|
|
||||||
Cache_.erase(lastElement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Contains(const Key& key) const {
|
|
||||||
return Map_.find(key) != Map_.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t Size() const {
|
|
||||||
return Map_.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t Capacity() const {
|
|
||||||
return Capacity_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Clear() {
|
|
||||||
Cache_.clear();
|
|
||||||
Map_.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
using TIterator = typename std::list<TPair>::iterator;
|
|
||||||
|
|
||||||
mutable std::list<TPair> Cache_;
|
|
||||||
mutable std::unordered_map<Key, TIterator> Map_;
|
|
||||||
std::size_t Capacity_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
#include "App.h"
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
#include "RoomEntity.h"
|
|
||||||
#include <iostream>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#ifdef __EMSCRIPTEN__
|
|
||||||
#include <emscripten.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static NGame::TApp *app = nullptr;
|
|
||||||
|
|
||||||
static void InitApp(void) {
|
|
||||||
app = NGame::TApp::Instance();
|
|
||||||
|
|
||||||
app->EntityManager().RegisterEntity<THero>("HeroEntity");
|
|
||||||
app->EntityManager().RegisterEntity<TDirtEntity>("DirtEntity");
|
|
||||||
app->EntityManager().RegisterEntity<TGrassEntity>("GrassEntity");
|
|
||||||
app->EntityManager().RegisterEntity<TPlankEntity>("PlankEntity");
|
|
||||||
app->EntityManager().RegisterEntity<TStoneEntity>("StoneEntity");
|
|
||||||
app->EntityManager().RegisterEntity<TLadderEntity>("LadderEntity");
|
|
||||||
app->EntityManager().RegisterEntity<TExplosionEntity>("ExplosionEntity");
|
|
||||||
app->EntityManager().RegisterEntity<TKeyEntity>("KeyEntity");
|
|
||||||
app->EntityManager().RegisterEntity<TMineEntity>("MineEntity");
|
|
||||||
app->EntityManager().RegisterEntity<TCurseEntity>("CurseEntity");
|
|
||||||
app->EntityManager().RegisterEntity<TSpikeEntity>("SpikeEntity");
|
|
||||||
app->EntityManager().RegisterEntity<TEntranceEntity>("EntranceEntity");
|
|
||||||
app->EntityManager().RegisterEntity<TExitEntity>("ExitEntity");
|
|
||||||
app->EntityManager().RegisterEntity<TFloatingTextEntity>("FloatingTextEntity");
|
|
||||||
app->EntityManager().RegisterEntity<TBackgroundTiler>("BackgroundTiler");
|
|
||||||
app->EntityManager().RegisterEntity<TRoomEntity>("RoomEntity");
|
|
||||||
app->EntityManager().RegisterEntity<TRubbleEntity>("RubbleEntity");
|
|
||||||
app->EntityManager().RegisterEntity<TMainMenu>("MainMenu");
|
|
||||||
app->EntityManager().RegisterEntity<TIntroMenu>("IntroMenu");
|
|
||||||
app->EntityManager().RegisterEntity<TOutroMenu>("OutroMenu");
|
|
||||||
app->EntityManager().RegisterEntity<TEulaMenu>("EulaMenu");
|
|
||||||
app->EntityManager().RegisterEntity<TTorchEntity>("TorchEntity");
|
|
||||||
app->EntityManager().RegisterEntity<TGrenadeEntity>("GrenadeEntity");
|
|
||||||
|
|
||||||
app->AudioManager().SetVolume(.3);
|
|
||||||
app->EntityManager().AddToDeferred("IntroMenu");
|
|
||||||
app->EntityManager().Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void MainLoop(void) {
|
|
||||||
if (app) {
|
|
||||||
app->Run();
|
|
||||||
} else {
|
|
||||||
InitApp();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
|
|
||||||
|
|
||||||
srand(time(NULL));
|
|
||||||
|
|
||||||
#ifdef __EMSCRIPTEN__
|
|
||||||
emscripten_set_main_loop(MainLoop, -1, true);
|
|
||||||
#else
|
|
||||||
while (true) { MainLoop(); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,347 +0,0 @@
|
|||||||
#include "RenderManager.h"
|
|
||||||
|
|
||||||
#include <SDL2/SDL_blendmode.h>
|
|
||||||
#include <SDL2/SDL_events.h>
|
|
||||||
#include <SDL2/SDL_render.h>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
TRenderManager::TRenderManager(TSurfaceManager& surfaceManager, int width, int height, const std::string& title, std::size_t cacheSize)
|
|
||||||
: SurfaceManager_(surfaceManager), Cache_(cacheSize), Size_(width, height) {
|
|
||||||
Window_ = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_UNDEFINED,
|
|
||||||
SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_RESIZABLE);
|
|
||||||
if (!Window_) {
|
|
||||||
throw std::runtime_error("Can't create window");
|
|
||||||
}
|
|
||||||
|
|
||||||
Renderer_ = SDL_CreateRenderer(Window_, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
|
||||||
if (!Renderer_) {
|
|
||||||
SDL_DestroyWindow(Window_);
|
|
||||||
throw std::runtime_error("Can't create renderer");
|
|
||||||
}
|
|
||||||
|
|
||||||
ScreenTexture_ = SDL_CreateTexture(Renderer_, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_TARGET, width, height);
|
|
||||||
if (!ScreenTexture_) {
|
|
||||||
SDL_DestroyRenderer(Renderer_);
|
|
||||||
SDL_DestroyWindow(Window_);
|
|
||||||
throw std::runtime_error("Can't create screen texture");
|
|
||||||
}
|
|
||||||
|
|
||||||
LightTexture_ = SDL_CreateTexture(Renderer_, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_TARGET, width, height);
|
|
||||||
if (!LightTexture_) {
|
|
||||||
SDL_DestroyTexture(ScreenTexture_);
|
|
||||||
SDL_DestroyRenderer(Renderer_);
|
|
||||||
SDL_DestroyWindow(Window_);
|
|
||||||
throw std::runtime_error("Can't create light texture");
|
|
||||||
}
|
|
||||||
SDL_SetTextureBlendMode(LightTexture_, SDL_BLENDMODE_MOD);
|
|
||||||
|
|
||||||
// Make window bigger
|
|
||||||
if (width < 640 && height < 480) {
|
|
||||||
SDL_SetWindowSize(Window_, 640, 480);
|
|
||||||
}
|
|
||||||
|
|
||||||
Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<SDL_Texture> TRenderManager::Get(const std::string& path) {
|
|
||||||
if (Cache_.Contains(path)) {
|
|
||||||
return Cache_.Get(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<SDL_Surface> surface = SurfaceManager_.Get(path);
|
|
||||||
SDL_Texture* texture = SDL_CreateTextureFromSurface(Renderer_, surface.get());
|
|
||||||
if (!texture) {
|
|
||||||
std::runtime_error("Can't create texture from surface " + path);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<SDL_Texture> result(texture, [](SDL_Texture* texture) { SDL_DestroyTexture(texture); });
|
|
||||||
Cache_.Set(path, result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TRenderManager::SetLayer(ELayer layer) {
|
|
||||||
Layer_ = layer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TRenderManager::SetColor(std::uint8_t red, std::uint8_t green, std::uint8_t blue, std::uint8_t alpha) {
|
|
||||||
Commands_[Layer_].push_back(TColorCommand{red, green, blue, alpha});
|
|
||||||
}
|
|
||||||
|
|
||||||
void TRenderManager::SetTexture(const std::shared_ptr<SDL_Texture>& texture) {
|
|
||||||
if (ActiveTextures_[Layer_] != texture) {
|
|
||||||
Commands_[Layer_].push_back(TTextureCommand{texture});
|
|
||||||
ActiveTextures_[Layer_] = texture;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TRenderManager::DrawRect(const Vec2i& position, const Vec2i& size, bool filled) {
|
|
||||||
Commands_[Layer_].push_back(TRectCommand{position, size, filled});
|
|
||||||
}
|
|
||||||
|
|
||||||
void TRenderManager::DrawLine(const Vec2i& start, const Vec2i& end) {
|
|
||||||
Commands_[Layer_].push_back(TLineCommand{start, end});
|
|
||||||
}
|
|
||||||
|
|
||||||
void TRenderManager::DrawSprite(const Vec2i& texturePosition, const Vec2i& textureSize, const Vec2i& targetPosition, const Vec2i& targetSize, SDL_RendererFlip flip) {
|
|
||||||
if (!ActiveTextures_[Layer_]) {
|
|
||||||
throw std::runtime_error("layer has not active texture");
|
|
||||||
}
|
|
||||||
Commands_[Layer_].push_back(TSpriteCommand{texturePosition, textureSize, targetPosition, targetSize, flip});
|
|
||||||
}
|
|
||||||
|
|
||||||
void TRenderManager::DrawGeometry(const SDL_Vertex* vertices, std::size_t verticesCount, const int* indices, std::size_t indicesCount) {
|
|
||||||
if (!ActiveTextures_[Layer_]) {
|
|
||||||
throw std::runtime_error("layer has not active texture");
|
|
||||||
}
|
|
||||||
|
|
||||||
Commands_[Layer_].push_back(TGeometryCommand{vertices, verticesCount, indices, indicesCount});
|
|
||||||
}
|
|
||||||
|
|
||||||
void TRenderManager::SetCamera(const Vec2i& position) {
|
|
||||||
Camera_ = position;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Vec2i& TRenderManager::Camera() const {
|
|
||||||
return Camera_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Vec2i& TRenderManager::Size() const {
|
|
||||||
return Size_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TRenderManager::IsLightEnabled() const {
|
|
||||||
return LightEnabled_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TRenderManager::EnableLight(bool value) {
|
|
||||||
LightEnabled_ = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TRenderManager::SetDefaultLightColor(std::uint8_t red, std::uint8_t green, std::uint8_t blue) {
|
|
||||||
DefaultLightColor_ = {red, green, blue, 255};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::uint8_t TRenderManager::DefaultLightRed() const {
|
|
||||||
return DefaultLightColor_.Red;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::uint8_t TRenderManager::DefaultLightGreen() const {
|
|
||||||
return DefaultLightColor_.Green;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::uint8_t TRenderManager::DefaultLightBlue() const {
|
|
||||||
return DefaultLightColor_.Blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void TRenderManager::Run() {
|
|
||||||
if (!IsRunning()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t layer = 0; layer < SentinelMax; ++layer) {
|
|
||||||
switch (layer) {
|
|
||||||
case ELayer::BackgroundGlow:
|
|
||||||
case ELayer::ForegroundGlow:
|
|
||||||
case ELayer::EffectsGlow:
|
|
||||||
if (SDL_SetRenderDrawBlendMode(Renderer_, SDL_BlendMode::SDL_BLENDMODE_ADD)) {
|
|
||||||
std::runtime_error("can't set blendmode");
|
|
||||||
}
|
|
||||||
if (SDL_SetRenderTarget(Renderer_, ScreenTexture_)) {
|
|
||||||
std::runtime_error("can't set render target");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ELayer::Light:
|
|
||||||
if (!IsLightEnabled()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (SDL_SetRenderDrawBlendMode(Renderer_, SDL_BlendMode::SDL_BLENDMODE_BLEND)) {
|
|
||||||
std::runtime_error("can't set blendmode");
|
|
||||||
}
|
|
||||||
if (SDL_SetRenderTarget(Renderer_, LightTexture_)) {
|
|
||||||
std::runtime_error("can't set render target");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if (SDL_SetRenderDrawBlendMode(Renderer_, SDL_BlendMode::SDL_BLENDMODE_BLEND)) {
|
|
||||||
std::runtime_error("can't set blendmode");
|
|
||||||
}
|
|
||||||
if (SDL_SetRenderTarget(Renderer_, ScreenTexture_)) {
|
|
||||||
std::runtime_error("can't set render target");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_Texture* activeTexture = nullptr;
|
|
||||||
|
|
||||||
for (const auto& command : Commands_[layer]) {
|
|
||||||
auto drawOperation = TOverload {
|
|
||||||
[&](const TColorCommand& value) {
|
|
||||||
SDL_SetRenderDrawColor(Renderer_, value.Red, value.Green, value.Blue, value.Alpha);
|
|
||||||
},
|
|
||||||
[&](const TRectCommand& value) {
|
|
||||||
SDL_Rect rect;
|
|
||||||
rect.x = value.Position.X;
|
|
||||||
rect.y = value.Position.Y;
|
|
||||||
rect.w = value.Size.X;
|
|
||||||
rect.h = value.Size.Y;
|
|
||||||
|
|
||||||
if (layer != ELayer::Interface) {
|
|
||||||
rect.x -= Camera_.X;
|
|
||||||
rect.y -= Camera_.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value.ShouldFill) {
|
|
||||||
SDL_RenderFillRect(Renderer_, &rect);
|
|
||||||
} else {
|
|
||||||
SDL_RenderDrawRect(Renderer_, &rect);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[&](const TLineCommand& value) {
|
|
||||||
if (layer != ELayer::Interface) {
|
|
||||||
SDL_RenderDrawLine(Renderer_, value.Start.X - Camera_.X, value.Start.Y - Camera_.Y, value.End.X - Camera_.X, value.End.Y - Camera_.Y);
|
|
||||||
} else {
|
|
||||||
SDL_RenderDrawLine(Renderer_, value.Start.X, value.Start.Y, value.End.X, value.End.Y);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[&](const TTextureCommand& value) {
|
|
||||||
activeTexture = value.Texture.get();
|
|
||||||
|
|
||||||
switch (layer) {
|
|
||||||
case ELayer::BackgroundGlow:
|
|
||||||
case ELayer::ForegroundGlow:
|
|
||||||
case ELayer::EffectsGlow:
|
|
||||||
if (SDL_SetTextureBlendMode(activeTexture, SDL_BlendMode::SDL_BLENDMODE_ADD)) {
|
|
||||||
std::runtime_error("can't set texture blend mode");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if (SDL_SetTextureBlendMode(activeTexture, SDL_BlendMode::SDL_BLENDMODE_BLEND)) {
|
|
||||||
std::runtime_error("can't set texture blend mode");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[&](const TSpriteCommand& value) {
|
|
||||||
SDL_Rect sourceRect;
|
|
||||||
sourceRect.x = value.TexturePosition.X;
|
|
||||||
sourceRect.y = value.TexturePosition.Y;
|
|
||||||
sourceRect.w = value.TextureSize.X;
|
|
||||||
sourceRect.h = value.TextureSize.Y;
|
|
||||||
|
|
||||||
SDL_Rect destinationRect;
|
|
||||||
destinationRect.x = value.TargetPosition.X;
|
|
||||||
destinationRect.y = value.TargetPosition.Y;
|
|
||||||
destinationRect.w = value.TargetSize.X;
|
|
||||||
destinationRect.h = value.TargetSize.Y;
|
|
||||||
|
|
||||||
if (layer != ELayer::Interface) {
|
|
||||||
destinationRect.x -= Camera_.X;
|
|
||||||
destinationRect.y -= Camera_.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_RenderCopyEx(Renderer_, activeTexture, &sourceRect, &destinationRect, 0, NULL, value.Flip);
|
|
||||||
},
|
|
||||||
[&](const TGeometryCommand& value) {
|
|
||||||
if (layer == ELayer::Interface) {
|
|
||||||
SDL_RenderGeometry(Renderer_, activeTexture, value.Vertices, value.VerticesCount, value.Indices, value.IndicesCount);
|
|
||||||
} else {
|
|
||||||
VerticesBuffer_.clear();
|
|
||||||
for (std::size_t i = 0; i < value.VerticesCount; ++i) {
|
|
||||||
SDL_Vertex convertedVertex = value.Vertices[i];
|
|
||||||
convertedVertex.position.x -= Camera_.X;
|
|
||||||
convertedVertex.position.y -= Camera_.Y;
|
|
||||||
VerticesBuffer_.push_back(convertedVertex);
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_RenderGeometry(Renderer_, activeTexture, VerticesBuffer_.data(), VerticesBuffer_.size(), value.Indices, value.IndicesCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
std::visit(drawOperation, command);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply light
|
|
||||||
if (layer == ELayer::Light) {
|
|
||||||
SDL_SetRenderTarget(Renderer_, ScreenTexture_);
|
|
||||||
SDL_RenderCopy(Renderer_, LightTexture_, NULL, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keep logical resolution the same
|
|
||||||
int windowWidth, windowHeight;
|
|
||||||
SDL_GetWindowSize(Window_, &windowWidth, &windowHeight);
|
|
||||||
Vec2f scaleFactors = {float(windowWidth) / Size_.X, float(windowHeight) / Size_.Y};
|
|
||||||
float targetFactor = std::min(scaleFactors.X, scaleFactors.Y);
|
|
||||||
|
|
||||||
SDL_Rect destinationRect;
|
|
||||||
destinationRect.w = targetFactor * Size_.X;
|
|
||||||
destinationRect.h = targetFactor * Size_.Y;
|
|
||||||
destinationRect.x = (windowWidth - destinationRect.w) / 2;
|
|
||||||
destinationRect.y = (windowHeight - destinationRect.h) / 2;
|
|
||||||
|
|
||||||
SDL_SetRenderTarget(Renderer_, NULL);
|
|
||||||
SDL_RenderCopy(Renderer_, ScreenTexture_, NULL, &destinationRect);
|
|
||||||
SDL_RenderPresent(Renderer_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TRenderManager::Input(SDL_Event* event) {
|
|
||||||
bool result = SDL_PollEvent(event);
|
|
||||||
|
|
||||||
if (result && event->type == SDL_QUIT) {
|
|
||||||
Shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TRenderManager::IsRunning() {
|
|
||||||
return Window_ != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TRenderManager::Shutdown() {
|
|
||||||
if (IsRunning()) {
|
|
||||||
Reset();
|
|
||||||
SDL_DestroyTexture(LightTexture_);
|
|
||||||
SDL_DestroyTexture(ScreenTexture_);
|
|
||||||
SDL_DestroyRenderer(Renderer_);
|
|
||||||
SDL_DestroyWindow(Window_);
|
|
||||||
ScreenTexture_ = nullptr;
|
|
||||||
Renderer_ = nullptr;
|
|
||||||
Window_ = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TRenderManager::Reset() {
|
|
||||||
Layer_ = Tile;
|
|
||||||
ActiveTextures_.fill(nullptr);
|
|
||||||
for (auto& queue : Commands_) {
|
|
||||||
queue.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_Rect a;
|
|
||||||
SDL_RenderGetViewport(Renderer_, &a);
|
|
||||||
|
|
||||||
SDL_SetRenderDrawColor(Renderer_, 0, 0, 0, 0);
|
|
||||||
SDL_SetRenderTarget(Renderer_, NULL);
|
|
||||||
SDL_RenderClear(Renderer_);
|
|
||||||
|
|
||||||
SDL_SetRenderDrawColor(Renderer_, 0, 0, 0, 0);
|
|
||||||
SDL_SetRenderTarget(Renderer_, ScreenTexture_);
|
|
||||||
SDL_RenderClear(Renderer_);
|
|
||||||
|
|
||||||
if (IsLightEnabled()) {
|
|
||||||
SDL_SetRenderDrawColor(Renderer_, DefaultLightColor_.Red, DefaultLightColor_.Green, DefaultLightColor_.Blue, DefaultLightColor_.Alpha);
|
|
||||||
SDL_SetRenderTarget(Renderer_, LightTexture_);
|
|
||||||
SDL_RenderClear(Renderer_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Common.h"
|
|
||||||
|
|
||||||
#include "LRU.h"
|
|
||||||
#include "SurfaceManager.h"
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <memory>
|
|
||||||
#include <SDL2/SDL_events.h>
|
|
||||||
#include <SDL2/SDL_render.h>
|
|
||||||
#include <variant>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
class TRenderManager {
|
|
||||||
public:
|
|
||||||
enum ELayer {
|
|
||||||
Tile,
|
|
||||||
Background,
|
|
||||||
BackgroundGlow,
|
|
||||||
Foreground,
|
|
||||||
ForegroundGlow,
|
|
||||||
Effects,
|
|
||||||
EffectsGlow,
|
|
||||||
Light,
|
|
||||||
AfterLightEffects,
|
|
||||||
Interface,
|
|
||||||
SentinelMax
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TColorCommand {
|
|
||||||
std::uint8_t Red;
|
|
||||||
std::uint8_t Green;
|
|
||||||
std::uint8_t Blue;
|
|
||||||
std::uint8_t Alpha;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TRectCommand {
|
|
||||||
Vec2i Position;
|
|
||||||
Vec2i Size;
|
|
||||||
bool ShouldFill;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TLineCommand {
|
|
||||||
Vec2i Start;
|
|
||||||
Vec2i End;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TTextureCommand {
|
|
||||||
std::shared_ptr<SDL_Texture> Texture;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TSpriteCommand {
|
|
||||||
Vec2i TexturePosition;
|
|
||||||
Vec2i TextureSize;
|
|
||||||
Vec2i TargetPosition;
|
|
||||||
Vec2i TargetSize;
|
|
||||||
SDL_RendererFlip Flip;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TGeometryCommand {
|
|
||||||
const SDL_Vertex* Vertices;
|
|
||||||
std::size_t VerticesCount;
|
|
||||||
const int* Indices;
|
|
||||||
std::size_t IndicesCount;
|
|
||||||
};
|
|
||||||
|
|
||||||
using TCommand = std::variant<TColorCommand, TRectCommand, TLineCommand, TTextureCommand, TSpriteCommand, TGeometryCommand>;
|
|
||||||
|
|
||||||
TRenderManager(TSurfaceManager& surfaceManager, int width = 640, int height = 480, const std::string& title = "Game", std::size_t cacheSize = 4);
|
|
||||||
DELETE_COPY(TRenderManager)
|
|
||||||
|
|
||||||
std::shared_ptr<SDL_Texture> Get(const std::string& path);
|
|
||||||
void SetLayer(ELayer layer);
|
|
||||||
void SetColor(std::uint8_t red, std::uint8_t green, std::uint8_t blue, std::uint8_t alpha = 255);
|
|
||||||
void SetTexture(const std::shared_ptr<SDL_Texture>& texture);
|
|
||||||
void DrawRect(const Vec2i& position, const Vec2i& size, bool filled = false);
|
|
||||||
void DrawLine(const Vec2i& start, const Vec2i& end);
|
|
||||||
void DrawSprite(const Vec2i& texturePosition, const Vec2i& textureSize, const Vec2i& targetPosition, const Vec2i& targetSize, SDL_RendererFlip flip = SDL_FLIP_NONE);
|
|
||||||
void DrawGeometry(const SDL_Vertex* vertices, std::size_t verticesCount, const int* indices, std::size_t indicesCount);
|
|
||||||
|
|
||||||
void SetCamera(const Vec2i& position);
|
|
||||||
const Vec2i& Camera() const;
|
|
||||||
const Vec2i& Size() const;
|
|
||||||
|
|
||||||
bool IsLightEnabled() const;
|
|
||||||
void EnableLight(bool value);
|
|
||||||
void SetDefaultLightColor(std::uint8_t red, std::uint8_t green, std::uint8_t blue);
|
|
||||||
std::uint8_t DefaultLightRed() const;
|
|
||||||
std::uint8_t DefaultLightGreen() const;
|
|
||||||
std::uint8_t DefaultLightBlue() const;
|
|
||||||
|
|
||||||
void Reset();
|
|
||||||
void Run();
|
|
||||||
bool Input(SDL_Event* event);
|
|
||||||
bool IsRunning();
|
|
||||||
void Shutdown();
|
|
||||||
|
|
||||||
private:
|
|
||||||
SDL_Window* Window_;
|
|
||||||
SDL_Renderer* Renderer_;
|
|
||||||
TSurfaceManager& SurfaceManager_;
|
|
||||||
TLRU<std::string, std::shared_ptr<SDL_Texture>> Cache_;
|
|
||||||
std::array<std::vector<TCommand>, SentinelMax> Commands_;
|
|
||||||
std::array<std::shared_ptr<SDL_Texture>, SentinelMax> ActiveTextures_;
|
|
||||||
SDL_Texture* ScreenTexture_;
|
|
||||||
SDL_Texture* LightTexture_;
|
|
||||||
TColorCommand DefaultLightColor_;
|
|
||||||
bool LightEnabled_ = false;
|
|
||||||
ELayer Layer_;
|
|
||||||
Vec2i Camera_;
|
|
||||||
Vec2i Size_;
|
|
||||||
std::vector<SDL_Vertex> VerticesBuffer_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
-1622
File diff suppressed because it is too large
Load Diff
@@ -1,461 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "App.h"
|
|
||||||
|
|
||||||
#define TERRAIN_GROUP 0x01
|
|
||||||
#define LADDER_GROUP 0x02
|
|
||||||
#define DAMAGE_GROUP 0x04
|
|
||||||
#define ITEM_GROUP 0x08
|
|
||||||
#define PASSAGE_GROUP 0x10
|
|
||||||
#define PLANK_GROUP 0x20
|
|
||||||
#define HERO_GROUP 0x40
|
|
||||||
|
|
||||||
class TDirtEntity : public NGame::TEntity {
|
|
||||||
public:
|
|
||||||
TDirtEntity(NGame::TEntity::TId id);
|
|
||||||
|
|
||||||
virtual void Update(std::uint32_t delta) override;
|
|
||||||
virtual void Draw() const override;
|
|
||||||
virtual void Alarm(NGame::TAlarm::TId id) override;
|
|
||||||
void Destroy();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
NGame::TApp* App_;
|
|
||||||
NGame::TSpriteManager& SpriteManager_;
|
|
||||||
NGame::TRenderManager& RenderManager_;
|
|
||||||
|
|
||||||
std::shared_ptr<NGame::TSpriteManager::TSprite> Sprite_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TGrassEntity : public TDirtEntity {
|
|
||||||
public:
|
|
||||||
TGrassEntity(NGame::TEntity::TId id);
|
|
||||||
virtual void Draw() const override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TPlankEntity : public NGame::TEntity {
|
|
||||||
public:
|
|
||||||
TPlankEntity(NGame::TEntity::TId id);
|
|
||||||
|
|
||||||
virtual void Update(std::uint32_t delta) override;
|
|
||||||
virtual void Draw() const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
NGame::TApp* App_;
|
|
||||||
NGame::TSpriteManager& SpriteManager_;
|
|
||||||
NGame::TRenderManager& RenderManager_;
|
|
||||||
std::shared_ptr<NGame::TSpriteManager::TSprite> Sprite_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TStoneEntity : public NGame::TEntity {
|
|
||||||
public:
|
|
||||||
TStoneEntity(NGame::TEntity::TId id);
|
|
||||||
|
|
||||||
virtual void Update(std::uint32_t delta) override;
|
|
||||||
virtual void Draw() const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
NGame::TApp* App_;
|
|
||||||
NGame::TSpriteManager& SpriteManager_;
|
|
||||||
NGame::TRenderManager& RenderManager_;
|
|
||||||
std::shared_ptr<NGame::TSpriteManager::TSprite> Sprite_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TLadderEntity : public NGame::TEntity {
|
|
||||||
public:
|
|
||||||
TLadderEntity(NGame::TEntity::TId id);
|
|
||||||
|
|
||||||
virtual void Update(std::uint32_t delta) override;
|
|
||||||
virtual void Draw() const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
NGame::TApp* App_;
|
|
||||||
NGame::TSpriteManager& SpriteManager_;
|
|
||||||
NGame::TRenderManager& RenderManager_;
|
|
||||||
std::shared_ptr<NGame::TSpriteManager::TSprite> Sprite_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TExplosionEntity : public NGame::TEntity {
|
|
||||||
public:
|
|
||||||
TExplosionEntity(NGame::TEntity::TId id);
|
|
||||||
|
|
||||||
virtual void Update(std::uint32_t delta) override;
|
|
||||||
virtual void Draw() const override;
|
|
||||||
virtual void Alarm(NGame::TAlarm::TId id) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
NGame::TApp* App_;
|
|
||||||
NGame::TSpriteManager& SpriteManager_;
|
|
||||||
NGame::TRenderManager& RenderManager_;
|
|
||||||
std::shared_ptr<NGame::TSpriteManager::TSprite> Sprite_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TKeyEntity : public NGame::TEntity {
|
|
||||||
public:
|
|
||||||
TKeyEntity(NGame::TEntity::TId id);
|
|
||||||
|
|
||||||
virtual void Update(std::uint32_t delta) override;
|
|
||||||
virtual void Draw() const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
NGame::TApp* App_;
|
|
||||||
NGame::TSpriteManager& SpriteManager_;
|
|
||||||
NGame::TRenderManager& RenderManager_;
|
|
||||||
std::shared_ptr<NGame::TSpriteManager::TSprite> Sprite_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TMineEntity : public NGame::TEntity {
|
|
||||||
public:
|
|
||||||
enum EState {
|
|
||||||
Dormant,
|
|
||||||
Active
|
|
||||||
};
|
|
||||||
|
|
||||||
TMineEntity(NGame::TEntity::TId id);
|
|
||||||
|
|
||||||
virtual void Update(std::uint32_t delta) override;
|
|
||||||
virtual void Draw() const override;
|
|
||||||
virtual void Alarm(NGame::TAlarm::TId id) override;
|
|
||||||
void Explode();
|
|
||||||
|
|
||||||
private:
|
|
||||||
NGame::TApp* App_;
|
|
||||||
NGame::TSpriteManager& SpriteManager_;
|
|
||||||
NGame::TRenderManager& RenderManager_;
|
|
||||||
|
|
||||||
bool AlternateBlink_ = false;
|
|
||||||
std::size_t Remaining_ = 0;
|
|
||||||
EState State_ = Dormant;
|
|
||||||
std::shared_ptr<NGame::TSpriteManager::TSprite> Sprite_;
|
|
||||||
std::shared_ptr<NGame::TSpriteManager::TSprite> Blinking_;
|
|
||||||
const NGame::Vec2i TriggerRadius_ = {8, 8};
|
|
||||||
};
|
|
||||||
|
|
||||||
class TCurseEntity : public NGame::TEntity {
|
|
||||||
public:
|
|
||||||
TCurseEntity(NGame::TEntity::TId id);
|
|
||||||
|
|
||||||
virtual void Update(std::uint32_t delta) override;
|
|
||||||
virtual void Draw() const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
NGame::TApp* App_;
|
|
||||||
NGame::TSpriteManager& SpriteManager_;
|
|
||||||
NGame::TRenderManager& RenderManager_;
|
|
||||||
|
|
||||||
std::shared_ptr<NGame::TSpriteManager::TSprite> Sprite_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TSpikeEntity : public NGame::TEntity {
|
|
||||||
public:
|
|
||||||
TSpikeEntity(NGame::TEntity::TId id);
|
|
||||||
|
|
||||||
virtual void Update(std::uint32_t delta) override;
|
|
||||||
virtual void Draw() const override;
|
|
||||||
bool IsBloody() const;
|
|
||||||
void SetBloody(bool value);
|
|
||||||
|
|
||||||
private:
|
|
||||||
NGame::TApp* App_;
|
|
||||||
NGame::TSpriteManager& SpriteManager_;
|
|
||||||
NGame::TRenderManager& RenderManager_;
|
|
||||||
|
|
||||||
bool IsBloody_ = false;
|
|
||||||
std::shared_ptr<NGame::TSpriteManager::TSprite> Sprite_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TEntranceEntity : public NGame::TEntity {
|
|
||||||
public:
|
|
||||||
TEntranceEntity(NGame::TEntity::TId id);
|
|
||||||
|
|
||||||
virtual void Update(std::uint32_t delta) override;
|
|
||||||
virtual void Draw() const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
NGame::TApp* App_;
|
|
||||||
NGame::TSpriteManager& SpriteManager_;
|
|
||||||
NGame::TRenderManager& RenderManager_;
|
|
||||||
|
|
||||||
std::shared_ptr<NGame::TSpriteManager::TSprite> Sprite_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TExitEntity : public NGame::TEntity {
|
|
||||||
public:
|
|
||||||
TExitEntity(NGame::TEntity::TId id);
|
|
||||||
|
|
||||||
virtual void Update(std::uint32_t delta) override;
|
|
||||||
virtual void Draw() const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::shared_ptr<NGame::TSpriteManager::TSprite> Sprite_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TFloatingTextEntity : public NGame::TEntity {
|
|
||||||
public:
|
|
||||||
TFloatingTextEntity(NGame::TEntity::TId id);
|
|
||||||
|
|
||||||
void SetText(const std::string& text);
|
|
||||||
void SetColor(NGame::TFontManager::EColor color);
|
|
||||||
|
|
||||||
virtual void Update(std::uint32_t delta) override;
|
|
||||||
virtual void Draw() const override;
|
|
||||||
virtual void Alarm(NGame::TAlarm::TId id) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
NGame::TApp* App_;
|
|
||||||
NGame::TSpriteManager& SpriteManager_;
|
|
||||||
NGame::TRenderManager& RenderManager_;
|
|
||||||
|
|
||||||
std::string Text_;
|
|
||||||
NGame::TFontManager::EColor Color_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TRoomEntity : public NGame::TEntity {
|
|
||||||
public:
|
|
||||||
TRoomEntity(NGame::TEntity::TId id);
|
|
||||||
|
|
||||||
private:
|
|
||||||
enum EType {
|
|
||||||
None,
|
|
||||||
Left = 0x0001,
|
|
||||||
Right = 0x0002,
|
|
||||||
Up = 0x0004,
|
|
||||||
Down = 0x0008,
|
|
||||||
Start = 0x0010,
|
|
||||||
Exit = 0x0020,
|
|
||||||
LeftRight = Left | Right,
|
|
||||||
LeftRightDown = Left | Right | Down,
|
|
||||||
LeftRightUp = Left | Right | Up,
|
|
||||||
LeftRightUpDown = Left | Right | Up | Down,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum ETile {
|
|
||||||
Empty,
|
|
||||||
Dirt,
|
|
||||||
Grass,
|
|
||||||
HighDirt,
|
|
||||||
Ladder,
|
|
||||||
LowDirt,
|
|
||||||
MidDirt,
|
|
||||||
Mine,
|
|
||||||
Passage,
|
|
||||||
Plank,
|
|
||||||
Spike,
|
|
||||||
Torch
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TRoom {
|
|
||||||
ETile data[60];
|
|
||||||
};
|
|
||||||
|
|
||||||
void LoadTemplates();
|
|
||||||
void ParseRooms(const std::string& data, std::vector<TRoom>& rooms);
|
|
||||||
bool ParseRoom(std::istringstream& stream, TRoom& room);
|
|
||||||
void FillRow(const std::string& data, std::size_t row, TRoom& room);
|
|
||||||
bool GoLeft(int* maze, NGame::Vec2i& position);
|
|
||||||
bool GoRight(int* maze, NGame::Vec2i& position);
|
|
||||||
bool GoDown(int* maze, NGame::Vec2i& position);
|
|
||||||
void GenerateLayout();
|
|
||||||
void GenerateRoom(int* maze, const NGame::Vec2i& position);
|
|
||||||
void SelectRoom(int type, TRoom& room);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<TRoom> LRRooms_;
|
|
||||||
std::vector<TRoom> LRURooms_;
|
|
||||||
std::vector<TRoom> LRDRooms_;
|
|
||||||
std::vector<TRoom> LRUDRooms_;
|
|
||||||
std::vector<TRoom> AnyRooms_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class THero : public NGame::TEntity {
|
|
||||||
public:
|
|
||||||
THero(NGame::TEntity::TId id);
|
|
||||||
|
|
||||||
enum class EKeys {
|
|
||||||
Left,
|
|
||||||
Right,
|
|
||||||
Up,
|
|
||||||
Down,
|
|
||||||
X,
|
|
||||||
Z,
|
|
||||||
C,
|
|
||||||
Shift,
|
|
||||||
Escape,
|
|
||||||
MaxSentinel
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class EState {
|
|
||||||
Normal,
|
|
||||||
Jump,
|
|
||||||
Fall,
|
|
||||||
Climb,
|
|
||||||
Hold,
|
|
||||||
Dead,
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual void Input(SDL_Event* event) override;
|
|
||||||
virtual void Update(std::uint32_t delta) override;
|
|
||||||
virtual void Draw() const override;
|
|
||||||
virtual void Alarm(NGame::TAlarm::TId id) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
NGame::TApp* App_;
|
|
||||||
NGame::TSpriteManager& SpriteManager_;
|
|
||||||
NGame::TRenderManager& RenderManager_;
|
|
||||||
|
|
||||||
bool KeysPressed_[static_cast<int>(EKeys::MaxSentinel)] = {};
|
|
||||||
bool KeysHeld_[static_cast<int>(EKeys::MaxSentinel)] = {};
|
|
||||||
bool FaceLeft_ = false;
|
|
||||||
bool IgnorePlanks_ = false;
|
|
||||||
bool AlternateRun_ = false;
|
|
||||||
EState State_ = EState::Normal;
|
|
||||||
|
|
||||||
const float Gravity_ = 500.0;
|
|
||||||
NGame::Vec2i LastStablePosition_ = {};
|
|
||||||
NGame::Vec2f Speed_ = NGame::Vec2f(0.0, 0.0);
|
|
||||||
NGame::Vec2f Fraction_ = NGame::Vec2f(0.0, 0.0);
|
|
||||||
NGame::Vec2i ExitPosition_;
|
|
||||||
|
|
||||||
bool DisplayEnd_ = false;
|
|
||||||
bool WhiteFade_ = false;
|
|
||||||
std::size_t FadeAmount_ = 0;
|
|
||||||
double RemainingTime_ = 0;
|
|
||||||
int Grenades_ = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TBackgroundTiler : public NGame::TEntity {
|
|
||||||
public:
|
|
||||||
TBackgroundTiler(NGame::TEntity::TId id);
|
|
||||||
virtual void Draw() const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
NGame::TApp* App_;
|
|
||||||
NGame::TSpriteManager& SpriteManager_;
|
|
||||||
NGame::TRenderManager& RenderManager_;
|
|
||||||
|
|
||||||
std::shared_ptr<NGame::TSpriteManager::TSprite> Background_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TRubbleEntity : public NGame::TEntity {
|
|
||||||
public:
|
|
||||||
TRubbleEntity(NGame::TEntity::TId id);
|
|
||||||
|
|
||||||
virtual void Update(std::uint32_t delta) override;
|
|
||||||
virtual void Draw() const override;
|
|
||||||
virtual void Alarm(NGame::TAlarm::TId id) override;
|
|
||||||
|
|
||||||
const NGame::Vec2f& Speed() const;
|
|
||||||
void SetSpeed(const NGame::Vec2f& speed);
|
|
||||||
|
|
||||||
private:
|
|
||||||
NGame::TApp* App_;
|
|
||||||
NGame::TSpriteManager& SpriteManager_;
|
|
||||||
NGame::TRenderManager& RenderManager_;
|
|
||||||
|
|
||||||
const float Gravity_ = 500;
|
|
||||||
std::shared_ptr<NGame::TSpriteManager::TSprite> Sprite_;
|
|
||||||
NGame::Vec2f Speed_ = NGame::Vec2f(0.0, 0.0);
|
|
||||||
NGame::Vec2f Fraction_ = NGame::Vec2f(0.0, 0.0);
|
|
||||||
bool Flip_ = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TMainMenu : public NGame::TEntity {
|
|
||||||
public:
|
|
||||||
TMainMenu(NGame::TEntity::TId id);
|
|
||||||
|
|
||||||
virtual void Input(SDL_Event* event) override;
|
|
||||||
virtual void Update(std::uint32_t delta) override;
|
|
||||||
virtual void Draw() const override;
|
|
||||||
virtual void Alarm(NGame::TAlarm::TId id) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
NGame::TApp* App_;
|
|
||||||
NGame::TSpriteManager& SpriteManager_;
|
|
||||||
NGame::TRenderManager& RenderManager_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TEulaMenu : public NGame::TEntity {
|
|
||||||
public:
|
|
||||||
TEulaMenu(NGame::TEntity::TId id);
|
|
||||||
|
|
||||||
virtual void Input(SDL_Event* event) override;
|
|
||||||
virtual void Update(std::uint32_t delta) override;
|
|
||||||
virtual void Draw() const override;
|
|
||||||
virtual void Alarm(NGame::TAlarm::TId id) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
NGame::TApp* App_;
|
|
||||||
NGame::TSpriteManager& SpriteManager_;
|
|
||||||
NGame::TRenderManager& RenderManager_;
|
|
||||||
std::string Choice_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TIntroMenu : public NGame::TEntity {
|
|
||||||
public:
|
|
||||||
TIntroMenu(NGame::TEntity::TId id);
|
|
||||||
|
|
||||||
virtual void Input(SDL_Event* event) override;
|
|
||||||
virtual void Update(std::uint32_t delta) override;
|
|
||||||
virtual void Draw() const override;
|
|
||||||
virtual void Alarm(NGame::TAlarm::TId id) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
NGame::TApp* App_;
|
|
||||||
NGame::TSpriteManager& SpriteManager_;
|
|
||||||
NGame::TRenderManager& RenderManager_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TOutroMenu : public NGame::TEntity {
|
|
||||||
public:
|
|
||||||
TOutroMenu(NGame::TEntity::TId id);
|
|
||||||
|
|
||||||
virtual void Input(SDL_Event* event) override;
|
|
||||||
virtual void Update(std::uint32_t delta) override;
|
|
||||||
virtual void Draw() const override;
|
|
||||||
virtual void Alarm(NGame::TAlarm::TId id) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
NGame::TApp* App_;
|
|
||||||
NGame::TSpriteManager& SpriteManager_;
|
|
||||||
NGame::TRenderManager& RenderManager_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TTorchEntity : public NGame::TEntity {
|
|
||||||
public:
|
|
||||||
TTorchEntity(NGame::TEntity::TId id);
|
|
||||||
|
|
||||||
virtual void Update(std::uint32_t delta) override;
|
|
||||||
virtual void Draw() const override;
|
|
||||||
virtual void Alarm(NGame::TAlarm::TId id) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::shared_ptr<NGame::TSpriteManager::TSprite> Sprite_;
|
|
||||||
std::shared_ptr<NGame::TSpriteManager::TSprite> LightSprite_;
|
|
||||||
NGame::TApp* App_;
|
|
||||||
NGame::TSpriteManager& SpriteManager_;
|
|
||||||
NGame::TRenderManager& RenderManager_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TGrenadeEntity : public NGame::TEntity {
|
|
||||||
public:
|
|
||||||
TGrenadeEntity(NGame::TEntity::TId id);
|
|
||||||
|
|
||||||
virtual void Update(std::uint32_t delta) override;
|
|
||||||
virtual void Draw() const override;
|
|
||||||
virtual void Alarm(NGame::TAlarm::TId id) override;
|
|
||||||
|
|
||||||
void Explode();
|
|
||||||
const NGame::Vec2f& Speed() const;
|
|
||||||
void SetSpeed(const NGame::Vec2f& speed);
|
|
||||||
|
|
||||||
private:
|
|
||||||
NGame::TApp* App_;
|
|
||||||
NGame::TSpriteManager& SpriteManager_;
|
|
||||||
NGame::TRenderManager& RenderManager_;
|
|
||||||
|
|
||||||
const float Gravity_ = 500;
|
|
||||||
std::shared_ptr<NGame::TSpriteManager::TSprite> Sprite_;
|
|
||||||
NGame::Vec2f Speed_ = NGame::Vec2f(0.0, 0.0);
|
|
||||||
NGame::Vec2f Fraction_ = NGame::Vec2f(0.0, 0.0);
|
|
||||||
bool AlternateBlink_ = false;
|
|
||||||
};
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
#include "SpriteManager.h"
|
|
||||||
|
|
||||||
#include <SDL2/SDL_render.h>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
TSpriteManager::TSpriteManager(TFileManager& fileManager, TRenderManager& renderManager, std::size_t cacheSize)
|
|
||||||
: FileManager_(fileManager), RenderManager_(renderManager), Cache_(cacheSize) {
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<TSpriteManager::TSprite> TSpriteManager::Get(const std::string& path) {
|
|
||||||
if (Cache_.Contains(path)) {
|
|
||||||
return Cache_.Get(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto result = std::make_shared<TSprite>(ParseInfoFile(path));
|
|
||||||
Cache_.Set(path, result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TSpriteManager::Draw(const std::shared_ptr<TSprite>& sprite, size_t frame, const Vec2i& position, const Vec2f& scale) {
|
|
||||||
const auto& frameData = sprite->Frames[frame];
|
|
||||||
|
|
||||||
int flip = 0;
|
|
||||||
Vec2i size = frameData.Size * scale;
|
|
||||||
|
|
||||||
if (size.X < 0) {
|
|
||||||
size.X = -size.X;
|
|
||||||
flip |= SDL_FLIP_HORIZONTAL;
|
|
||||||
}
|
|
||||||
if (size.Y < 0) {
|
|
||||||
size.Y = -size.Y;
|
|
||||||
flip |= SDL_FLIP_VERTICAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderManager_.SetTexture(sprite->Texture);
|
|
||||||
RenderManager_.DrawSprite(frameData.Position, frameData.Size, position, size, static_cast<SDL_RendererFlip>(flip));
|
|
||||||
}
|
|
||||||
|
|
||||||
TSpriteManager::TSprite TSpriteManager::ParseInfoFile(const std::string& path) {
|
|
||||||
std::string data = FileManager_.Get(path);
|
|
||||||
std::istringstream inputStream(data);
|
|
||||||
|
|
||||||
std::shared_ptr<SDL_Texture> currentTexture;
|
|
||||||
std::vector<TFrame> currentFrames;
|
|
||||||
|
|
||||||
for (std::string line; std::getline(inputStream, line); ) {
|
|
||||||
auto remainder = Trim(std::string_view(line));
|
|
||||||
|
|
||||||
auto action = RightTrim(NextToken(remainder, " "));
|
|
||||||
if (action == "Texture") {
|
|
||||||
auto textureString = Trim(NextToken(remainder, " "));
|
|
||||||
if (textureString.empty()) {
|
|
||||||
throw std::runtime_error("texture name should not be empty for " + path);
|
|
||||||
}
|
|
||||||
currentTexture = RenderManager_.Get(std::string(textureString));
|
|
||||||
} else if (action == "Frame") {
|
|
||||||
auto xString = Trim(NextToken(remainder, " "));
|
|
||||||
auto yString = Trim(NextToken(remainder, " "));
|
|
||||||
auto widthString = Trim(NextToken(remainder, " "));
|
|
||||||
auto heightString = Trim(NextToken(remainder, " "));
|
|
||||||
|
|
||||||
|
|
||||||
TFrame frame;
|
|
||||||
|
|
||||||
if (xString.empty() && yString.empty()) {
|
|
||||||
frame.Position.X = 0;
|
|
||||||
frame.Position.Y = 0;
|
|
||||||
} else {
|
|
||||||
frame.Position.X = std::stoi(std::string(xString));
|
|
||||||
frame.Position.Y = std::stoi(std::string(yString));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (widthString.empty() && heightString.empty()) {
|
|
||||||
int width, height;
|
|
||||||
|
|
||||||
if (SDL_QueryTexture(currentTexture.get(), NULL, NULL, &width, &height)) {
|
|
||||||
throw std::runtime_error("can't query texture information for " + path);
|
|
||||||
}
|
|
||||||
|
|
||||||
frame.Size.X = width;
|
|
||||||
frame.Size.Y = height;
|
|
||||||
} else {
|
|
||||||
frame.Size.X = std::stoi(std::string(widthString));
|
|
||||||
frame.Size.Y = std::stoi(std::string(heightString));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xString.empty() || yString.empty() || widthString.empty() || heightString.empty()) {
|
|
||||||
throw std::runtime_error("frame should have x, y, width, height parameters for " + path);
|
|
||||||
}
|
|
||||||
|
|
||||||
currentFrames.push_back(frame);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!currentTexture) {
|
|
||||||
std::runtime_error("no texture for " + path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentFrames.empty()) {
|
|
||||||
TFrame frame;
|
|
||||||
int width, height;
|
|
||||||
if (SDL_QueryTexture(currentTexture.get(), NULL, NULL, &width, &height)) {
|
|
||||||
throw std::runtime_error("can't query texture information for " + path);
|
|
||||||
}
|
|
||||||
|
|
||||||
frame.Position.X = 0;
|
|
||||||
frame.Position.Y = 0;
|
|
||||||
frame.Size.X = width;
|
|
||||||
frame.Size.Y = height;
|
|
||||||
currentFrames.push_back(frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {currentTexture, currentFrames};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Common.h"
|
|
||||||
|
|
||||||
#include "FileManager.h"
|
|
||||||
#include "LRU.h"
|
|
||||||
#include "RenderManager.h"
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
class TSpriteManager {
|
|
||||||
public:
|
|
||||||
struct TFrame {
|
|
||||||
Vec2i Position;
|
|
||||||
Vec2i Size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TSprite {
|
|
||||||
std::shared_ptr<SDL_Texture> Texture;
|
|
||||||
std::vector<TFrame> Frames;
|
|
||||||
};
|
|
||||||
|
|
||||||
TSpriteManager(TFileManager& fileManager, TRenderManager& renderManager, std::size_t cacheSize = 4);
|
|
||||||
DELETE_COPY(TSpriteManager)
|
|
||||||
|
|
||||||
std::shared_ptr<TSprite> Get(const std::string& path);
|
|
||||||
void Draw(const std::shared_ptr<TSprite>& sprite, size_t frame, const Vec2i& position, const Vec2f& scale = {1.0f, 1.0f});
|
|
||||||
|
|
||||||
private:
|
|
||||||
TSprite ParseInfoFile(const std::string& path);
|
|
||||||
|
|
||||||
private:
|
|
||||||
TFileManager& FileManager_;
|
|
||||||
TRenderManager& RenderManager_;
|
|
||||||
TLRU<std::string, std::shared_ptr<TSprite>> Cache_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
#include "State.h"
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
TVariable& TState::Variable(const std::string_view& name) {
|
|
||||||
auto stringName = std::string(name);
|
|
||||||
auto iterator = Variables_.find(stringName);
|
|
||||||
|
|
||||||
if (iterator != Variables_.end()) {
|
|
||||||
return iterator->second;
|
|
||||||
} else {
|
|
||||||
return SetVariable(name, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const TVariable& TState::Variable(const std::string_view& name) const {
|
|
||||||
auto stringName = std::string(name);
|
|
||||||
auto iterator = Variables_.find(stringName);
|
|
||||||
|
|
||||||
if (iterator != Variables_.end()) {
|
|
||||||
return iterator->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw std::runtime_error("Attempting to access non-existing variable");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TState::ContainsVariable(const std::string_view& name) const {
|
|
||||||
auto stringName = std::string(name);
|
|
||||||
auto iterator = Variables_.find(stringName);
|
|
||||||
|
|
||||||
if (iterator != Variables_.end()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
-36
@@ -1,36 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Common.h"
|
|
||||||
|
|
||||||
#include "Variable.h"
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <string_view>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
class TState {
|
|
||||||
public:
|
|
||||||
TVariable& Variable(const std::string_view& name);
|
|
||||||
const TVariable& Variable(const std::string_view& name) const;
|
|
||||||
bool ContainsVariable(const std::string_view& name) const;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
TVariable& SetVariable(const std::string_view& name, const T& value) {
|
|
||||||
auto stringName = std::string(name);
|
|
||||||
auto result = Variables_.emplace(std::make_pair(stringName, value));
|
|
||||||
if (result.second) {
|
|
||||||
return result.first->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw std::runtime_error("Failed to set variable");
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::unordered_map<std::string, TVariable> Variables_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
#include "SurfaceManager.h"
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <SDL2/SDL_rwops.h>
|
|
||||||
#include <SDL2/SDL_surface.h>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
TSurfaceManager::TSurfaceManager(TFileManager& fileManager, std::size_t cacheSize)
|
|
||||||
: FileManager_(fileManager), Cache_(cacheSize) {
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<SDL_Surface> TSurfaceManager::Get(const std::string& path) {
|
|
||||||
if (Cache_.Contains(path)) {
|
|
||||||
return Cache_.Get(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string data = FileManager_.Get(path);
|
|
||||||
SDL_RWops* rw = SDL_RWFromConstMem(data.data(), data.size());
|
|
||||||
SDL_Surface* surface = SDL_LoadBMP_RW(rw, 1);
|
|
||||||
|
|
||||||
if (!surface) {
|
|
||||||
std::runtime_error("Can't create surface from file " + path);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<SDL_Surface> result(surface, [](SDL_Surface* surface) { SDL_FreeSurface(surface); });
|
|
||||||
Cache_.Set(path, result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Common.h"
|
|
||||||
|
|
||||||
#include "LRU.h"
|
|
||||||
#include "FileManager.h"
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <SDL2/SDL_surface.h>
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
class TSurfaceManager {
|
|
||||||
public:
|
|
||||||
TSurfaceManager(TFileManager& fileManager, std::size_t cacheSize = 4);
|
|
||||||
DELETE_COPY(TSurfaceManager)
|
|
||||||
|
|
||||||
std::shared_ptr<SDL_Surface> Get(const std::string& path);
|
|
||||||
|
|
||||||
private:
|
|
||||||
TFileManager& FileManager_;
|
|
||||||
TLRU<std::string, std::shared_ptr<SDL_Surface>> Cache_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
#include "Variable.h"
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
void TVariable::SetDouble(double value) {
|
|
||||||
Data_ = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TVariable::SetString(const std::string& value) {
|
|
||||||
Data_ = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TVariable::SetInt(int value) {
|
|
||||||
Data_ = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TVariable::SetBool(bool value) {
|
|
||||||
Data_ = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
double TVariable::Double() const {
|
|
||||||
const auto asDouble = TOverload {
|
|
||||||
[](int value) { return double(value); },
|
|
||||||
[](double value) { return value; },
|
|
||||||
[](const std::string value) {
|
|
||||||
try {
|
|
||||||
return std::stod(value);
|
|
||||||
} catch (...) {
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[](bool value) { return double(value); }
|
|
||||||
};
|
|
||||||
|
|
||||||
return std::visit(asDouble, Data_);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string TVariable::String() const {
|
|
||||||
const auto asString = TOverload {
|
|
||||||
[](int value) { return std::to_string(value); },
|
|
||||||
[](double value) { return std::to_string(value); },
|
|
||||||
[](const std::string value) { return value; },
|
|
||||||
[](bool value) { return std::to_string(value); }
|
|
||||||
};
|
|
||||||
|
|
||||||
return std::visit(asString, Data_);
|
|
||||||
}
|
|
||||||
|
|
||||||
int TVariable::Int() const {
|
|
||||||
const auto asInt = TOverload {
|
|
||||||
[](int value) { return value; },
|
|
||||||
[](double value) { return int(value); },
|
|
||||||
[](const std::string value) {
|
|
||||||
try {
|
|
||||||
return std::stoi(value);
|
|
||||||
} catch (...) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[](bool value) { return int(value); }
|
|
||||||
};
|
|
||||||
|
|
||||||
return std::visit(asInt, Data_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TVariable::Bool() const {
|
|
||||||
const auto asBool = TOverload {
|
|
||||||
[](int value) { return value != 0; },
|
|
||||||
[](double value) { return value != 0; },
|
|
||||||
[](const std::string value) {
|
|
||||||
std::string caseFolded = ToUpper(Trim(value));
|
|
||||||
if (caseFolded == "TRUE") {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
[](bool value) { return value; }
|
|
||||||
};
|
|
||||||
|
|
||||||
return std::visit(asBool, Data_);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Common.h"
|
|
||||||
|
|
||||||
#include <variant>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace NGame {
|
|
||||||
|
|
||||||
class TVariable {
|
|
||||||
public:
|
|
||||||
TVariable() = default;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
TVariable(const T& value)
|
|
||||||
: Data_(value) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetDouble(double value);
|
|
||||||
void SetString(const std::string& value);
|
|
||||||
void SetInt(int value);
|
|
||||||
void SetBool(bool value);
|
|
||||||
|
|
||||||
double Double() const;
|
|
||||||
std::string String() const;
|
|
||||||
int Int() const;
|
|
||||||
bool Bool() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::variant<double, std::string, int, bool> Data_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace NGame
|
|
||||||
Reference in New Issue
Block a user