diff options
Diffstat (limited to 'src/main.cpp')
-rw-r--r-- | src/main.cpp | 298 |
1 files changed, 224 insertions, 74 deletions
diff --git a/src/main.cpp b/src/main.cpp index 5178110..149e1cf 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
@@ -5,15 +5,25 @@ | |||
5 | #include "game.h" | 5 | #include "game.h" |
6 | #include "renderer.h" | 6 | #include "renderer.h" |
7 | 7 | ||
8 | void incrementIfSet(Game& game, int& count, int x, int y, Tile val = Tile::Wall) | 8 | inline bool isTileSetOrNotLit(const Map<MapData>& map, int x, int y) |
9 | { | 9 | { |
10 | if (game.map.inBounds(x, y) && game.map.at(x,y).tile == val) | 10 | return (map.inBounds(x, y) && (map.at(x,y).tile == Tile::Wall || !map.at(x,y).lit)); |
11 | } | ||
12 | |||
13 | inline bool isTileSet(const Map<MapData>& map, int x, int y, Tile val = Tile::Wall) | ||
14 | { | ||
15 | return (map.inBounds(x, y) && map.at(x,y).tile == val); | ||
16 | } | ||
17 | |||
18 | inline void incrementIfSet(const Game& game, int& count, int x, int y, Tile val = Tile::Wall) | ||
19 | { | ||
20 | if (isTileSet(game.map, x, y, val)) | ||
11 | { | 21 | { |
12 | count++; | 22 | count++; |
13 | } | 23 | } |
14 | } | 24 | } |
15 | 25 | ||
16 | int getZoomLevel(const Game& game) { | 26 | inline int getZoomLevel(const Game& game) { |
17 | return (game.curZoom - INIT_ZOOM) / 2; | 27 | return (game.curZoom - INIT_ZOOM) / 2; |
18 | } | 28 | } |
19 | 29 | ||
@@ -65,6 +75,11 @@ void tick( | |||
65 | } else { | 75 | } else { |
66 | temp.at(x,y).tile = Tile::Floor; | 76 | temp.at(x,y).tile = Tile::Floor; |
67 | } | 77 | } |
78 | |||
79 | if (temp.at(x,y).tile != game.map.at(x,y).tile) { | ||
80 | temp.at(x,y).dirtyRender = true; | ||
81 | game.dirtyRender = true; | ||
82 | } | ||
68 | } | 83 | } |
69 | } | 84 | } |
70 | 85 | ||
@@ -98,9 +113,13 @@ bool movePlayer(Game& game, int x, int y) | |||
98 | game.numDust++; | 113 | game.numDust++; |
99 | } | 114 | } |
100 | 115 | ||
116 | game.player_oldx = game.player_x; | ||
117 | game.player_oldy = game.player_y; | ||
101 | game.player_x = x; | 118 | game.player_x = x; |
102 | game.player_y = y; | 119 | game.player_y = y; |
103 | game.muxer.setPlayerLoc(x, y); | 120 | game.muxer.setPlayerLoc(x, y); |
121 | game.moving = true; | ||
122 | game.moveProgress.start(33); | ||
104 | 123 | ||
105 | game.dirtyLighting = true; | 124 | game.dirtyLighting = true; |
106 | 125 | ||
@@ -119,12 +138,17 @@ bool movePlayer(Game& game, int x, int y) | |||
119 | void recalculateLighting(Game& game) | 138 | void recalculateLighting(Game& game) |
120 | { | 139 | { |
121 | game.litSpots = 0; | 140 | game.litSpots = 0; |
141 | game.dirtyRender = true; | ||
122 | 142 | ||
123 | for (MapData& md : game.map.data()) | 143 | for (MapData& md : game.map.data()) |
124 | { | 144 | { |
125 | md.wasLit = md.lit; | 145 | md.wasLit = md.lit; |
126 | md.lit = false; | 146 | md.lit = false; |
127 | md.litTiles.clear(); | 147 | md.litTiles.clear(); |
148 | |||
149 | if (md.tile == Tile::Wall) { | ||
150 | md.dirtyRender = true; | ||
151 | } | ||
128 | } | 152 | } |
129 | 153 | ||
130 | fov_settings_type fov; | 154 | fov_settings_type fov; |
@@ -203,6 +227,103 @@ void recalculateLighting(Game& game) | |||
203 | game.dirtyLighting = false; | 227 | game.dirtyLighting = false; |
204 | } | 228 | } |
205 | 229 | ||
230 | void recalculateRender(Game& game) { | ||
231 | for (int y = game.map.getTop(); y < game.map.getBottom(); y++) | ||
232 | { | ||
233 | for (int x = game.map.getLeft(); x < game.map.getRight(); x++) | ||
234 | { | ||
235 | if (game.map.at(x,y).dirtyRender) { | ||
236 | game.map.at(x,y).dirtyRender = false; | ||
237 | |||
238 | if (game.map.at(x,y).tile == Tile::Floor) { | ||
239 | if (std::bernoulli_distribution(0.05)(game.rng)) { | ||
240 | static const std::vector<int> furnishings { | ||
241 | TilesetIndex(20, 16), | ||
242 | TilesetIndex(21, 2), | ||
243 | TilesetIndex(22, 2), | ||
244 | TilesetIndex(21, 3), | ||
245 | TilesetIndex(22, 3)}; | ||
246 | game.map.at(x,y).renderId = furnishings.at(std::uniform_int_distribution<int>(0, furnishings.size()-1)(game.rng)); | ||
247 | } else { | ||
248 | game.map.at(x,y).renderId = -1; | ||
249 | } | ||
250 | } else if (game.map.at(x,y).tile == Tile::Wall) { | ||
251 | static bool initWalls = false; | ||
252 | static std::vector<int> wallRenders(256, TilesetIndex(0, 0)); | ||
253 | if (!initWalls) { | ||
254 | initWalls = true; | ||
255 | |||
256 | // Start in top left and go clockwise. | ||
257 | wallRenders[0b00011100] = TilesetIndex(16, 14); | ||
258 | wallRenders[0b00111100] = TilesetIndex(16, 14); | ||
259 | wallRenders[0b00011110] = TilesetIndex(16, 14); | ||
260 | wallRenders[0b00111110] = TilesetIndex(16, 14); | ||
261 | |||
262 | wallRenders[0b00011111] = TilesetIndex(17, 14); | ||
263 | wallRenders[0b10011111] = TilesetIndex(17, 14); | ||
264 | wallRenders[0b00111111] = TilesetIndex(17, 14); | ||
265 | wallRenders[0b10111111] = TilesetIndex(17, 14); | ||
266 | |||
267 | wallRenders[0b00000111] = TilesetIndex(18, 14); | ||
268 | wallRenders[0b00001111] = TilesetIndex(18, 14); | ||
269 | wallRenders[0b10000111] = TilesetIndex(18, 14); | ||
270 | wallRenders[0b10001111] = TilesetIndex(18, 14); | ||
271 | |||
272 | wallRenders[0b01111100] = TilesetIndex(16, 15); | ||
273 | wallRenders[0b11111100] = TilesetIndex(16, 15); | ||
274 | wallRenders[0b01111110] = TilesetIndex(16, 15); | ||
275 | wallRenders[0b11111110] = TilesetIndex(16, 15); | ||
276 | |||
277 | wallRenders[0b11000111] = TilesetIndex(18, 15); | ||
278 | wallRenders[0b11001111] = TilesetIndex(18, 15); | ||
279 | wallRenders[0b11100111] = TilesetIndex(18, 15); | ||
280 | wallRenders[0b11101111] = TilesetIndex(18, 15); | ||
281 | |||
282 | wallRenders[0b01110000] = TilesetIndex(16, 16); | ||
283 | wallRenders[0b01111000] = TilesetIndex(16, 16); | ||
284 | wallRenders[0b11110000] = TilesetIndex(16, 16); | ||
285 | wallRenders[0b11111000] = TilesetIndex(16, 16); | ||
286 | |||
287 | wallRenders[0b11110001] = TilesetIndex(17, 16); | ||
288 | wallRenders[0b11110011] = TilesetIndex(17, 16); | ||
289 | wallRenders[0b11111001] = TilesetIndex(17, 16); | ||
290 | wallRenders[0b11111011] = TilesetIndex(17, 16); | ||
291 | |||
292 | wallRenders[0b11000001] = TilesetIndex(18, 16); | ||
293 | wallRenders[0b11000011] = TilesetIndex(18, 16); | ||
294 | wallRenders[0b11100001] = TilesetIndex(18, 16); | ||
295 | wallRenders[0b11100011] = TilesetIndex(18, 16); | ||
296 | |||
297 | |||
298 | wallRenders[0b11110111] = TilesetIndex(21, 14); | ||
299 | wallRenders[0b11111101] = TilesetIndex(22, 14); | ||
300 | wallRenders[0b11011111] = TilesetIndex(21, 15); | ||
301 | wallRenders[0b01111111] = TilesetIndex(22, 15); | ||
302 | } | ||
303 | |||
304 | int renderDesc = 0; | ||
305 | if (isTileSetOrNotLit(game.map, x-1, y-1)) renderDesc |= (1 << 7); | ||
306 | if (isTileSetOrNotLit(game.map, x , y-1)) renderDesc |= (1 << 6); | ||
307 | if (isTileSetOrNotLit(game.map, x+1, y-1)) renderDesc |= (1 << 5); | ||
308 | if (isTileSetOrNotLit(game.map, x+1, y )) renderDesc |= (1 << 4); | ||
309 | if (isTileSetOrNotLit(game.map, x+1, y+1)) renderDesc |= (1 << 3); | ||
310 | if (isTileSetOrNotLit(game.map, x , y+1)) renderDesc |= (1 << 2); | ||
311 | if (isTileSetOrNotLit(game.map, x-1, y+1)) renderDesc |= (1 << 1); | ||
312 | if (isTileSetOrNotLit(game.map, x-1, y )) renderDesc |= (1 << 0); | ||
313 | |||
314 | game.map.at(x,y).renderId = wallRenders.at(renderDesc); | ||
315 | |||
316 | if (wallRenders.at(renderDesc) == 0 && renderDesc != 255) { | ||
317 | std::cout << renderDesc << std::endl; | ||
318 | } | ||
319 | } | ||
320 | } | ||
321 | } | ||
322 | } | ||
323 | |||
324 | game.dirtyRender = false; | ||
325 | } | ||
326 | |||
206 | bool processKeys(Game& game, const Input& keystate) | 327 | bool processKeys(Game& game, const Input& keystate) |
207 | { | 328 | { |
208 | int px = game.player_x; | 329 | int px = game.player_x; |
@@ -435,6 +556,80 @@ void setZoom(Game& game, size_t zoom) | |||
435 | } | 556 | } |
436 | } | 557 | } |
437 | 558 | ||
559 | void performDash(Game& game, std::mt19937& rng) { | ||
560 | if (game.map.at(game.player_x, game.player_y).tile == | ||
561 | Tile::Floor) | ||
562 | { | ||
563 | std::vector<coord> freeSpaces; | ||
564 | |||
565 | auto addIfFree = [&] (int x, int y) { | ||
566 | if (game.map.inBounds(x,y) && | ||
567 | game.map.at(x,y).tile == Tile::Floor) | ||
568 | { | ||
569 | freeSpaces.emplace_back(x, y); | ||
570 | } | ||
571 | }; | ||
572 | |||
573 | addIfFree(game.player_x - 1, game.player_y - 1); | ||
574 | addIfFree(game.player_x , game.player_y - 1); | ||
575 | addIfFree(game.player_x + 1, game.player_y - 1); | ||
576 | addIfFree(game.player_x - 1, game.player_y ); | ||
577 | addIfFree(game.player_x + 1, game.player_y ); | ||
578 | addIfFree(game.player_x - 1, game.player_y + 1); | ||
579 | addIfFree(game.player_x , game.player_y + 1); | ||
580 | addIfFree(game.player_x + 1, game.player_y + 1); | ||
581 | |||
582 | if (!freeSpaces.empty()) | ||
583 | { | ||
584 | game.map.at(game.player_x, game.player_y).tile = Tile::Lamp; | ||
585 | game.numLamps++; | ||
586 | game.dirtyLighting = true; | ||
587 | kickUpDust(game, game.player_x, game.player_y, 0); | ||
588 | game.muxer.playSoundAtPosition("drop", game.player_x, game.player_y); | ||
589 | |||
590 | if (game.firstInput) | ||
591 | { | ||
592 | for (int i = 0; i < 5; i++) | ||
593 | { | ||
594 | if (!processKeys(game, game.lastInput)) | ||
595 | { | ||
596 | std::uniform_int_distribution<int> freeDist( | ||
597 | 0, freeSpaces.size() - 1); | ||
598 | |||
599 | int freeIndex = freeDist(rng); | ||
600 | coord& moveTo = freeSpaces[freeIndex]; | ||
601 | |||
602 | movePlayer( | ||
603 | game, | ||
604 | std::get<0>(moveTo), | ||
605 | std::get<1>(moveTo)); | ||
606 | } | ||
607 | |||
608 | tick( | ||
609 | game, | ||
610 | game.player_x - (RADIUS - 1), | ||
611 | game.player_y - (RADIUS - 1), | ||
612 | game.player_x + RADIUS, | ||
613 | game.player_y + RADIUS); | ||
614 | } | ||
615 | } else { | ||
616 | std::uniform_int_distribution<int> freeDist( | ||
617 | 0, freeSpaces.size() - 1); | ||
618 | |||
619 | int freeIndex = freeDist(rng); | ||
620 | coord& moveTo = freeSpaces[freeIndex]; | ||
621 | |||
622 | movePlayer( | ||
623 | game, | ||
624 | std::get<0>(moveTo), | ||
625 | std::get<1>(moveTo)); | ||
626 | } | ||
627 | |||
628 | //game.muxer.playSoundAtPosition("dash", game.player_x, game.player_y); | ||
629 | } | ||
630 | } | ||
631 | } | ||
632 | |||
438 | int main(int, char**) | 633 | int main(int, char**) |
439 | { | 634 | { |
440 | std::random_device randomEngine; | 635 | std::random_device randomEngine; |
@@ -527,76 +722,10 @@ int main(int, char**) | |||
527 | { | 722 | { |
528 | if (losing == LoseState::None) | 723 | if (losing == LoseState::None) |
529 | { | 724 | { |
530 | if (game.map.at(game.player_x, game.player_y).tile == | 725 | if (game.moving) { |
531 | Tile::Floor) | 726 | game.queueDash = true; |
532 | { | 727 | } else { |
533 | std::vector<coord> freeSpaces; | 728 | performDash(game, rng); |
534 | |||
535 | auto addIfFree = [&] (int x, int y) { | ||
536 | if (game.map.inBounds(x,y) && | ||
537 | game.map.at(x,y).tile == Tile::Floor) | ||
538 | { | ||
539 | freeSpaces.emplace_back(x, y); | ||
540 | } | ||
541 | }; | ||
542 | |||
543 | addIfFree(game.player_x - 1, game.player_y - 1); | ||
544 | addIfFree(game.player_x , game.player_y - 1); | ||
545 | addIfFree(game.player_x + 1, game.player_y - 1); | ||
546 | addIfFree(game.player_x - 1, game.player_y ); | ||
547 | addIfFree(game.player_x + 1, game.player_y ); | ||
548 | addIfFree(game.player_x - 1, game.player_y + 1); | ||
549 | addIfFree(game.player_x , game.player_y + 1); | ||
550 | addIfFree(game.player_x + 1, game.player_y + 1); | ||
551 | |||
552 | if (!freeSpaces.empty()) | ||
553 | { | ||
554 | game.map.at(game.player_x, game.player_y).tile = Tile::Lamp; | ||
555 | game.numLamps++; | ||
556 | game.dirtyLighting = true; | ||
557 | kickUpDust(game, game.player_x, game.player_y, 0); | ||
558 | game.muxer.playSoundAtPosition("drop", game.player_x, game.player_y); | ||
559 | |||
560 | if (game.firstInput) | ||
561 | { | ||
562 | for (int i = 0; i < 5; i++) | ||
563 | { | ||
564 | if (!processKeys(game, game.lastInput)) | ||
565 | { | ||
566 | std::uniform_int_distribution<int> freeDist( | ||
567 | 0, freeSpaces.size() - 1); | ||
568 | |||
569 | int freeIndex = freeDist(rng); | ||
570 | coord& moveTo = freeSpaces[freeIndex]; | ||
571 | |||
572 | movePlayer( | ||
573 | game, | ||
574 | std::get<0>(moveTo), | ||
575 | std::get<1>(moveTo)); | ||
576 | } | ||
577 | |||
578 | tick( | ||
579 | game, | ||
580 | game.player_x - (RADIUS - 1), | ||
581 | game.player_y - (RADIUS - 1), | ||
582 | game.player_x + RADIUS, | ||
583 | game.player_y + RADIUS); | ||
584 | } | ||
585 | } else { | ||
586 | std::uniform_int_distribution<int> freeDist( | ||
587 | 0, freeSpaces.size() - 1); | ||
588 | |||
589 | int freeIndex = freeDist(rng); | ||
590 | coord& moveTo = freeSpaces[freeIndex]; | ||
591 | |||
592 | movePlayer( | ||
593 | game, | ||
594 | std::get<0>(moveTo), | ||
595 | std::get<1>(moveTo)); | ||
596 | } | ||
597 | |||
598 | //game.muxer.playSoundAtPosition("dash", game.player_x, game.player_y); | ||
599 | } | ||
600 | } | 729 | } |
601 | } | 730 | } |
602 | 731 | ||
@@ -617,6 +746,13 @@ int main(int, char**) | |||
617 | game.alreadyBumped = false; | 746 | game.alreadyBumped = false; |
618 | } | 747 | } |
619 | 748 | ||
749 | if (game.queueDash && !game.moving) { | ||
750 | game.queueDash = false; | ||
751 | if (state[SDL_SCANCODE_SPACE]) { | ||
752 | performDash(game, rng); | ||
753 | } | ||
754 | } | ||
755 | |||
620 | if (keystate.left || keystate.right || keystate.up || keystate.down) | 756 | if (keystate.left || keystate.right || keystate.up || keystate.down) |
621 | { | 757 | { |
622 | game.firstInput = true; | 758 | game.firstInput = true; |
@@ -657,9 +793,18 @@ int main(int, char**) | |||
657 | { | 793 | { |
658 | case LoseState::None: | 794 | case LoseState::None: |
659 | { | 795 | { |
796 | if (game.moving) { | ||
797 | game.moveProgress.tick(frameTime); | ||
798 | if (game.moveProgress.isComplete()) { | ||
799 | game.moving = false; | ||
800 | } | ||
801 | } | ||
802 | |||
660 | while (inputAcc >= inputDt) | 803 | while (inputAcc >= inputDt) |
661 | { | 804 | { |
662 | processKeys(game, keystate); | 805 | if (!game.moving) { |
806 | processKeys(game, keystate); | ||
807 | } | ||
663 | 808 | ||
664 | inputAcc -= inputDt; | 809 | inputAcc -= inputDt; |
665 | } | 810 | } |
@@ -747,6 +892,7 @@ int main(int, char**) | |||
747 | } else { | 892 | } else { |
748 | game.map.at(x,y).tile = Tile::Floor; | 893 | game.map.at(x,y).tile = Tile::Floor; |
749 | } | 894 | } |
895 | game.map.at(x,y).dirtyRender = true; | ||
750 | } | 896 | } |
751 | } | 897 | } |
752 | } | 898 | } |
@@ -759,6 +905,10 @@ int main(int, char**) | |||
759 | setZoom(game, game.litSpots / 1500 * 2 + INIT_ZOOM); | 905 | setZoom(game, game.litSpots / 1500 * 2 + INIT_ZOOM); |
760 | } | 906 | } |
761 | 907 | ||
908 | if (game.dirtyRender) { | ||
909 | recalculateRender(game); | ||
910 | } | ||
911 | |||
762 | zoomAcc += frameTime; | 912 | zoomAcc += frameTime; |
763 | 913 | ||
764 | while (zoomAcc >= zoomDt) | 914 | while (zoomAcc >= zoomDt) |