diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.cpp | 169 |
1 files changed, 157 insertions, 12 deletions
diff --git a/src/main.cpp b/src/main.cpp index 9534678..2d8adf0 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
@@ -39,6 +39,17 @@ public: | |||
39 | 39 | ||
40 | using renderer_ptr = std::unique_ptr<SDL_Renderer, renderer_deleter>; | 40 | using renderer_ptr = std::unique_ptr<SDL_Renderer, renderer_deleter>; |
41 | 41 | ||
42 | class texture_deleter { | ||
43 | public: | ||
44 | |||
45 | void operator()(SDL_Texture* ptr) | ||
46 | { | ||
47 | SDL_DestroyTexture(ptr); | ||
48 | } | ||
49 | }; | ||
50 | |||
51 | using texture_ptr = std::unique_ptr<SDL_Texture, texture_deleter>; | ||
52 | |||
42 | enum class Tile { | 53 | enum class Tile { |
43 | Floor, | 54 | Floor, |
44 | Wall, | 55 | Wall, |
@@ -56,9 +67,10 @@ enum class LoseState { | |||
56 | const int GAME_WIDTH = 640*2; | 67 | const int GAME_WIDTH = 640*2; |
57 | const int GAME_HEIGHT = 480*2; | 68 | const int GAME_HEIGHT = 480*2; |
58 | const int TILE_WIDTH = 8*2; | 69 | const int TILE_WIDTH = 8*2; |
59 | const int TILE_HEIGHT = 8*2; | 70 | const int TILE_HEIGHT = TILE_WIDTH; |
60 | const int VIEW_WIDTH = GAME_WIDTH / TILE_WIDTH; | 71 | const int INIT_ZOOM = 10; |
61 | const int VIEW_HEIGHT = GAME_HEIGHT / TILE_HEIGHT; | 72 | const int ZOOM_X_FACTOR = 8; |
73 | const int ZOOM_Y_FACTOR = 6; | ||
62 | const int RADIUS = 8; | 74 | const int RADIUS = 8; |
63 | 75 | ||
64 | struct Input { | 76 | struct Input { |
@@ -86,14 +98,21 @@ struct MapData { | |||
86 | class Game { | 98 | class Game { |
87 | public: | 99 | public: |
88 | 100 | ||
89 | Game() : | 101 | Game(std::mt19937& rng) : |
90 | map(-VIEW_WIDTH/2, -VIEW_HEIGHT/2, VIEW_WIDTH, VIEW_HEIGHT) | 102 | rng(rng), |
103 | map( | ||
104 | -INIT_ZOOM * ZOOM_X_FACTOR / 2, | ||
105 | -INIT_ZOOM * ZOOM_Y_FACTOR / 2, | ||
106 | INIT_ZOOM * ZOOM_X_FACTOR, | ||
107 | INIT_ZOOM * ZOOM_Y_FACTOR) | ||
91 | { | 108 | { |
92 | } | 109 | } |
93 | 110 | ||
111 | std::mt19937& rng; | ||
112 | |||
94 | Map<MapData> map; | 113 | Map<MapData> map; |
95 | std::list<Kickup> kickups; | 114 | std::list<Kickup> kickups; |
96 | int lightedSpots = 0; | 115 | int litSpots = 0; |
97 | bool dirtyLighting = true; | 116 | bool dirtyLighting = true; |
98 | size_t numLamps = 0; | 117 | size_t numLamps = 0; |
99 | size_t numDust = 0; | 118 | size_t numDust = 0; |
@@ -101,6 +120,14 @@ public: | |||
101 | int player_x = 0; | 120 | int player_x = 0; |
102 | int player_y = 0; | 121 | int player_y = 0; |
103 | bool renderPlayer = true; | 122 | bool renderPlayer = true; |
123 | |||
124 | int curZoom = INIT_ZOOM; | ||
125 | int maxZoom = INIT_ZOOM; | ||
126 | |||
127 | bool zooming = false; | ||
128 | //size_t oldZoom; | ||
129 | int zoomProgress = 0; | ||
130 | |||
104 | }; | 131 | }; |
105 | 132 | ||
106 | void render( | 133 | void render( |
@@ -108,6 +135,21 @@ void render( | |||
108 | const Game& game, | 135 | const Game& game, |
109 | bool drawDark = true) | 136 | bool drawDark = true) |
110 | { | 137 | { |
138 | texture_ptr canvas( | ||
139 | SDL_CreateTexture( | ||
140 | ren, | ||
141 | SDL_PIXELFORMAT_RGBA8888, | ||
142 | SDL_TEXTUREACCESS_TARGET, | ||
143 | TILE_WIDTH * game.map.getWidth(), | ||
144 | TILE_HEIGHT * game.map.getHeight())); | ||
145 | |||
146 | if (!canvas) | ||
147 | { | ||
148 | throw sdl_error(); | ||
149 | } | ||
150 | |||
151 | SDL_SetRenderTarget(ren, canvas.get()); | ||
152 | |||
111 | SDL_SetRenderDrawColor(ren, rand() % 255, rand() % 255, rand() % 255, 255); | 153 | SDL_SetRenderDrawColor(ren, rand() % 255, rand() % 255, rand() % 255, 255); |
112 | SDL_RenderClear(ren); | 154 | SDL_RenderClear(ren); |
113 | 155 | ||
@@ -174,6 +216,25 @@ void render( | |||
174 | } | 216 | } |
175 | } | 217 | } |
176 | 218 | ||
219 | SDL_SetRenderTarget(ren, nullptr); | ||
220 | |||
221 | if (!game.zooming) | ||
222 | { | ||
223 | SDL_RenderCopy(ren, canvas.get(), nullptr, nullptr); | ||
224 | } else { | ||
225 | // TODO: zooming back in to the player | ||
226 | SDL_Rect zoomRect { | ||
227 | ((game.maxZoom - game.curZoom) * TILE_WIDTH + game.zoomProgress) | ||
228 | * ZOOM_X_FACTOR / 2, | ||
229 | ((game.maxZoom - game.curZoom) * TILE_HEIGHT + game.zoomProgress) | ||
230 | * ZOOM_Y_FACTOR / 2, | ||
231 | (game.curZoom * TILE_WIDTH - game.zoomProgress) * ZOOM_X_FACTOR, | ||
232 | (game.curZoom * TILE_HEIGHT - game.zoomProgress) * ZOOM_Y_FACTOR | ||
233 | }; | ||
234 | |||
235 | SDL_RenderCopy(ren, canvas.get(), &zoomRect, nullptr); | ||
236 | } | ||
237 | |||
177 | SDL_RenderPresent(ren); | 238 | SDL_RenderPresent(ren); |
178 | } | 239 | } |
179 | 240 | ||
@@ -270,7 +331,7 @@ void movePlayer(Game& game, int x, int y) | |||
270 | 331 | ||
271 | void recalculateLighting(Game& game, fov_settings_type* fov) | 332 | void recalculateLighting(Game& game, fov_settings_type* fov) |
272 | { | 333 | { |
273 | game.lightedSpots = 0; | 334 | game.litSpots = 0; |
274 | 335 | ||
275 | for (MapData& md : game.map.data()) | 336 | for (MapData& md : game.map.data()) |
276 | { | 337 | { |
@@ -296,7 +357,7 @@ void recalculateLighting(Game& game, fov_settings_type* fov) | |||
296 | { | 357 | { |
297 | if (!game.map.at(x,y).lit) | 358 | if (!game.map.at(x,y).lit) |
298 | { | 359 | { |
299 | game.lightedSpots++; | 360 | game.litSpots++; |
300 | } | 361 | } |
301 | 362 | ||
302 | game.map.at(x,y).lit = true; | 363 | game.map.at(x,y).lit = true; |
@@ -444,6 +505,61 @@ void processKickup(Game& game) | |||
444 | }); | 505 | }); |
445 | } | 506 | } |
446 | 507 | ||
508 | void growMap(Game& game, size_t zoom) | ||
509 | { | ||
510 | int ol = game.map.getLeft(); | ||
511 | int ot = game.map.getTop(); | ||
512 | int ow = game.map.getWidth(); | ||
513 | int oh = game.map.getHeight(); | ||
514 | |||
515 | game.map.resize( | ||
516 | -zoom * ZOOM_X_FACTOR / 2, | ||
517 | -zoom * ZOOM_Y_FACTOR / 2, | ||
518 | zoom * ZOOM_X_FACTOR, | ||
519 | zoom * ZOOM_Y_FACTOR); | ||
520 | |||
521 | game.maxZoom = zoom; | ||
522 | |||
523 | // TODO: is this working properly? | ||
524 | for (int y = game.map.getTop(); y < game.map.getBottom(); y++) | ||
525 | { | ||
526 | for (int x = game.map.getLeft(); x < game.map.getRight(); x++) | ||
527 | { | ||
528 | if (!(x >= ol && x < (ol + ow) && y >= ot && y < (ot + oh))) | ||
529 | { | ||
530 | if (std::bernoulli_distribution(0.5)(game.rng)) | ||
531 | { | ||
532 | game.map.at(x,y).tile = Tile::Wall; | ||
533 | } | ||
534 | } | ||
535 | } | ||
536 | } | ||
537 | |||
538 | for (int i = 0; i < 3; i++) | ||
539 | { | ||
540 | tick(game, ol, ot, ow, oh, true); | ||
541 | } | ||
542 | } | ||
543 | |||
544 | void setZoom(Game& game, size_t zoom) | ||
545 | { | ||
546 | if (zoom == game.curZoom) | ||
547 | { | ||
548 | return; | ||
549 | } | ||
550 | |||
551 | if (zoom > game.maxZoom) | ||
552 | { | ||
553 | growMap(game, zoom); | ||
554 | } | ||
555 | |||
556 | // TODO: don't think this works well with rapid zoom changes | ||
557 | game.zoomProgress += (zoom - game.curZoom) * TILE_WIDTH; | ||
558 | //game.oldZoom = game.curZoom; | ||
559 | game.curZoom = zoom; | ||
560 | game.zooming = true; | ||
561 | } | ||
562 | |||
447 | int main(int, char**) | 563 | int main(int, char**) |
448 | { | 564 | { |
449 | std::random_device randomEngine; | 565 | std::random_device randomEngine; |
@@ -477,7 +593,7 @@ int main(int, char**) | |||
477 | 593 | ||
478 | SDL_SetRenderDrawBlendMode(ren.get(), SDL_BLENDMODE_BLEND); | 594 | SDL_SetRenderDrawBlendMode(ren.get(), SDL_BLENDMODE_BLEND); |
479 | 595 | ||
480 | Game game; | 596 | Game game(rng); |
481 | 597 | ||
482 | std::unique_ptr<fov_settings_type> fov(new fov_settings_type()); | 598 | std::unique_ptr<fov_settings_type> fov(new fov_settings_type()); |
483 | fov_settings_init(fov.get()); | 599 | fov_settings_init(fov.get()); |
@@ -505,12 +621,15 @@ int main(int, char**) | |||
505 | size_t inputDt = 50; | 621 | size_t inputDt = 50; |
506 | size_t inputAcc = 0; | 622 | size_t inputAcc = 0; |
507 | 623 | ||
508 | size_t losePopLampDt = 1000; | 624 | size_t losePopLampDt = 800; |
509 | size_t losePopLampAcc = losePopLampDt; | 625 | size_t losePopLampAcc = losePopLampDt; |
510 | 626 | ||
511 | size_t losePopPlayerDt = 4000; | 627 | size_t losePopPlayerDt = 3000; |
512 | size_t losePopPlayerAcc = 0; | 628 | size_t losePopPlayerAcc = 0; |
513 | 629 | ||
630 | size_t zoomDt = 62; | ||
631 | size_t zoomAcc = 0; | ||
632 | |||
514 | size_t lastTime = SDL_GetTicks(); | 633 | size_t lastTime = SDL_GetTicks(); |
515 | 634 | ||
516 | while (!quit) | 635 | while (!quit) |
@@ -647,7 +766,7 @@ int main(int, char**) | |||
647 | std::uniform_int_distribution<int> lampDist(0, lamps.size() - 1); | 766 | std::uniform_int_distribution<int> lampDist(0, lamps.size() - 1); |
648 | std::tuple<int, int> popPos = lamps[lampDist(rng)]; | 767 | std::tuple<int, int> popPos = lamps[lampDist(rng)]; |
649 | 768 | ||
650 | popLamp(game, std::get<0>(popPos), std::get<1>(popPos), 0); | 769 | popLamp(game, std::get<0>(popPos), std::get<1>(popPos), 1); |
651 | 770 | ||
652 | losePopLampAcc -= losePopLampDt; | 771 | losePopLampAcc -= losePopLampDt; |
653 | } | 772 | } |
@@ -705,6 +824,32 @@ int main(int, char**) | |||
705 | tick(game, true); | 824 | tick(game, true); |
706 | tick(game, true); | 825 | tick(game, true); |
707 | tick(game, true); | 826 | tick(game, true); |
827 | |||
828 | // TODO: better zoom algorithm | ||
829 | setZoom(game, game.litSpots / 1500 * 2 + INIT_ZOOM); | ||
830 | } | ||
831 | |||
832 | zoomAcc += frameTime; | ||
833 | |||
834 | while (zoomAcc >= zoomDt) | ||
835 | { | ||
836 | if (game.zooming) | ||
837 | { | ||
838 | if (game.zoomProgress > 0) | ||
839 | { | ||
840 | game.zoomProgress--; | ||
841 | } else if (game.zoomProgress < 0) | ||
842 | { | ||
843 | game.zoomProgress++; | ||
844 | } | ||
845 | |||
846 | if (game.zoomProgress == 0) | ||
847 | { | ||
848 | game.zooming = false; | ||
849 | } | ||
850 | } | ||
851 | |||
852 | zoomAcc -= zoomDt; | ||
708 | } | 853 | } |
709 | 854 | ||
710 | render(ren.get(), game, true); | 855 | render(ren.get(), game, true); |