summary refs log tree commit diff stats
path: root/src/game.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game.cpp')
-rw-r--r--src/game.cpp195
1 files changed, 105 insertions, 90 deletions
diff --git a/src/game.cpp b/src/game.cpp index 088ab4d..9d557e3 100644 --- a/src/game.cpp +++ b/src/game.cpp
@@ -20,7 +20,7 @@ Game::Game(std::mt19937& rng, Muxer& muxer, Renderer& renderer) :
20 { 20 {
21 for (int x = -1; x <= 1; x++) 21 for (int x = -1; x <= 1; x++)
22 { 22 {
23 map.at(x,y).tile = Tile::Floor; 23 map.tile(x,y) = Tile::Floor;
24 } 24 }
25 } 25 }
26 26
@@ -35,12 +35,12 @@ Game::Game(std::mt19937& rng, Muxer& muxer, Renderer& renderer) :
35 35
36inline bool isTileSetOrNotLit(const Map& map, int x, int y) 36inline bool isTileSetOrNotLit(const Map& map, int x, int y)
37{ 37{
38 return (map.inBounds(x, y) && (map.at(x,y).tile == Tile::Wall || !map.at(x,y).lit)); 38 return (map.inBounds(x, y) && (map.tile(x,y) == Tile::Wall || !map.at(x,y).lit));
39} 39}
40 40
41inline bool isTileSet(const Map& map, int x, int y, Tile val = Tile::Wall) 41inline bool isTileSet(const Map& map, int x, int y, Tile val = Tile::Wall)
42{ 42{
43 return (map.inBounds(x, y) && map.at(x,y).tile == val); 43 return (map.inBounds(x, y) && map.tile(x,y) == val);
44} 44}
45 45
46inline void incrementIfSet(const Game& game, int& count, int x, int y, Tile val = Tile::Wall) 46inline void incrementIfSet(const Game& game, int& count, int x, int y, Tile val = Tile::Wall)
@@ -55,6 +55,56 @@ inline int getZoomLevel(const Game& game) {
55 return game.curZoom - INIT_ZOOM; 55 return game.curZoom - INIT_ZOOM;
56} 56}
57 57
58inline void tickIndividual(Game& game, std::vector<Tile>& mapDoubleBuffer, int x, int y, bool onlyDark) {
59 if (onlyDark && game.map.at(x,y).lit)
60 {
61 return;
62 }
63
64 if (game.map.tile(x,y) == Tile::Lamp)
65 {
66 return;
67 }
68
69 int count = 0;
70
71 incrementIfSet(game, count, x-1, y-1);
72 incrementIfSet(game, count, x-1, y );
73 incrementIfSet(game, count, x-1, y+1);
74 incrementIfSet(game, count, x , y-1);
75 incrementIfSet(game, count, x , y );
76 incrementIfSet(game, count, x , y+1);
77 incrementIfSet(game, count, x+1, y-1);
78 incrementIfSet(game, count, x+1, y );
79 incrementIfSet(game, count, x+1, y+1);
80
81 int tempIndex = game.map.getTrueX(x) + game.map.getTrueY(y) * game.map.getWidth();
82 if (count >= 5)
83 {
84 mapDoubleBuffer[tempIndex] = Tile::Wall;
85 } else {
86 mapDoubleBuffer[tempIndex] = Tile::Floor;
87 }
88
89 if (mapDoubleBuffer[tempIndex] != game.map.tile(x,y)) {
90 game.map.at(x,y).dirtyRender = true;
91 game.dirtyRender = true;
92 game.map.markDirtyAround(x,y);
93 }
94}
95
96void Game::tickDirty(bool onlyDark) {
97 mapDoubleBuffer = map.tiles();
98 std::vector<coord> dirty = map.getDirty();
99 map.resetDirty();
100
101 for (auto [x,y] : dirty) {
102 tickIndividual(*this, mapDoubleBuffer, x, y, onlyDark);
103 }
104
105 std::swap(map.tiles(), mapDoubleBuffer);
106}
107
58void Game::tick( 108void Game::tick(
59 int x1, 109 int x1,
60 int y1, 110 int y1,
@@ -63,7 +113,8 @@ void Game::tick(
63 bool invert, 113 bool invert,
64 bool onlyDark) 114 bool onlyDark)
65{ 115{
66 mapDoubleBuffer = map.data(); 116 mapDoubleBuffer = map.tiles();
117 map.resetDirty();
67 118
68 for (int y = map.getTop(); y < map.getBottom(); y++) 119 for (int y = map.getTop(); y < map.getBottom(); y++)
69 { 120 {
@@ -74,44 +125,11 @@ void Game::tick(
74 continue; 125 continue;
75 } 126 }
76 127
77 if (onlyDark && map.at(x,y).lit) 128 tickIndividual(*this, mapDoubleBuffer, x, y, onlyDark);
78 {
79 continue;
80 }
81
82 if (map.at(x,y).tile == Tile::Lamp)
83 {
84 continue;
85 }
86
87 int count = 0;
88
89 incrementIfSet(*this, count, x-1, y-1);
90 incrementIfSet(*this, count, x-1, y );
91 incrementIfSet(*this, count, x-1, y+1);
92 incrementIfSet(*this, count, x , y-1);
93 incrementIfSet(*this, count, x , y );
94 incrementIfSet(*this, count, x , y+1);
95 incrementIfSet(*this, count, x+1, y-1);
96 incrementIfSet(*this, count, x+1, y );
97 incrementIfSet(*this, count, x+1, y+1);
98
99 int tempIndex = map.getTrueX(x) + map.getTrueY(y) * map.getWidth();
100 if (count >= 5)
101 {
102 mapDoubleBuffer[tempIndex].tile = Tile::Wall;
103 } else {
104 mapDoubleBuffer[tempIndex].tile = Tile::Floor;
105 }
106
107 if (mapDoubleBuffer[tempIndex].tile != map.at(x,y).tile) {
108 mapDoubleBuffer[tempIndex].dirtyRender = true;
109 dirtyRender = true;
110 }
111 } 129 }
112 } 130 }
113 131
114 std::swap(map.data(), mapDoubleBuffer); 132 std::swap(map.tiles(), mapDoubleBuffer);
115} 133}
116 134
117void Game::tick(bool onlyDark) 135void Game::tick(bool onlyDark)
@@ -127,11 +145,11 @@ void Game::tick(bool onlyDark)
127 145
128bool Game::movePlayer(int x, int y) 146bool Game::movePlayer(int x, int y)
129{ 147{
130 if (map.at(x,y).tile == Tile::Floor && !map.at(x,y).sign) 148 if (map.tile(x,y) == Tile::Floor && !map.at(x,y).sign)
131 { 149 {
132 if (map.at(player_x, player_y).tile == Tile::Floor) 150 if (map.tile(player_x, player_y) == Tile::Floor)
133 { 151 {
134 map.at(player_x, player_y).tile = Tile::Dust; 152 map.tile(player_x, player_y) = Tile::Dust;
135 map.at(player_x, player_y).dustLife = 1; 153 map.at(player_x, player_y).dustLife = 1;
136 numDust++; 154 numDust++;
137 } 155 }
@@ -169,14 +187,15 @@ void Game::recalculateLighting()
169 litSpots = 0; 187 litSpots = 0;
170 dirtyRender = true; 188 dirtyRender = true;
171 189
172 for (MapData& md : map.data()) 190 for (int y=map.getTop(); y<map.getBottom(); y++) {
173 { 191 for (int x=map.getLeft(); x<map.getRight(); x++) {
174 md.wasLit = md.lit; 192 map.at(x,y).wasLit = map.at(x,y).lit;
175 md.lit = false; 193 map.at(x,y).lit = false;
176 md.litTiles.clear(); 194 map.at(x,y).litTiles.clear();
177 195
178 if (md.tile == Tile::Wall) { 196 if (map.tile(x,y) == Tile::Wall) {
179 md.dirtyRender = true; 197 map.at(x,y).dirtyRender = true;
198 }
180 } 199 }
181 } 200 }
182 201
@@ -188,7 +207,7 @@ void Game::recalculateLighting()
188 [] (void* data, int x, int y) { 207 [] (void* data, int x, int y) {
189 Game& game = *static_cast<Game*>(data); 208 Game& game = *static_cast<Game*>(data);
190 209
191 return game.map.inBounds(x,y) && game.map.at(x,y).tile == Tile::Wall; 210 return game.map.inBounds(x,y) && game.map.tile(x,y) == Tile::Wall;
192 }); 211 });
193 212
194 fov_settings_set_apply_lighting_function( 213 fov_settings_set_apply_lighting_function(
@@ -223,11 +242,11 @@ void Game::recalculateLighting()
223 { 242 {
224 ls = Source::Player; 243 ls = Source::Player;
225 lightRadius = RADIUS; 244 lightRadius = RADIUS;
226 } else if (map.at(x,y).tile == Tile::Dust) 245 } else if (map.tile(x,y) == Tile::Dust)
227 { 246 {
228 ls = Source::Dust; 247 ls = Source::Dust;
229 lightRadius = 2; 248 lightRadius = 2;
230 } else if (map.at(x,y).tile == Tile::Lamp) 249 } else if (map.tile(x,y) == Tile::Lamp)
231 { 250 {
232 ls = Source::Lamp; 251 ls = Source::Lamp;
233 lightRadius = RADIUS; 252 lightRadius = RADIUS;
@@ -265,7 +284,7 @@ void Game::recalculateRender() {
265 if (map.at(x,y).dirtyRender) { 284 if (map.at(x,y).dirtyRender) {
266 map.at(x,y).dirtyRender = false; 285 map.at(x,y).dirtyRender = false;
267 286
268 if (map.at(x,y).tile == Tile::Floor) { 287 if (map.tile(x,y) == Tile::Floor) {
269 int renderDesc = 0; 288 int renderDesc = 0;
270 if (isTileSetOrNotLit(map, x-1, y-1)) renderDesc |= (1 << 7); 289 if (isTileSetOrNotLit(map, x-1, y-1)) renderDesc |= (1 << 7);
271 if (isTileSetOrNotLit(map, x , y-1)) renderDesc |= (1 << 6); 290 if (isTileSetOrNotLit(map, x , y-1)) renderDesc |= (1 << 6);
@@ -297,7 +316,7 @@ void Game::recalculateRender() {
297 map.at(x,y).renderId = -1; 316 map.at(x,y).renderId = -1;
298 map.at(x,y).sign = false; 317 map.at(x,y).sign = false;
299 } 318 }
300 } else if (map.at(x,y).tile == Tile::Wall) { 319 } else if (map.tile(x,y) == Tile::Wall) {
301 static bool initWalls = false; 320 static bool initWalls = false;
302 static std::vector<int> wallRenders(256, TilesetIndex(0, 0)); 321 static std::vector<int> wallRenders(256, TilesetIndex(0, 0));
303 if (!initWalls) { 322 if (!initWalls) {
@@ -439,12 +458,12 @@ void Game::popLamp(int x, int y, size_t chain)
439{ 458{
440 muxer.playSoundAtPosition("pop", x, y); 459 muxer.playSoundAtPosition("pop", x, y);
441 460
442 if (map.at(x,y).tile == Tile::Lamp) 461 if (map.tile(x,y) == Tile::Lamp)
443 { 462 {
444 numLamps--; 463 numLamps--;
445 } 464 }
446 465
447 map.at(x,y).tile = Tile::Dust; 466 map.tile(x,y) = Tile::Dust;
448 map.at(x,y).dustLife = 2; 467 map.at(x,y).dustLife = 2;
449 numDust++; 468 numDust++;
450 dirtyLighting = true; 469 dirtyLighting = true;
@@ -465,19 +484,19 @@ void Game::processKickup()
465 coord c {x,y}; 484 coord c {x,y};
466 485
467 if (map.inBounds(x,y) && 486 if (map.inBounds(x,y) &&
468 (map.at(x,y).tile == Tile::Floor || map.at(x,y).tile == Tile::Lamp) && 487 (map.tile(x,y) == Tile::Floor || map.tile(x,y) == Tile::Lamp) &&
469 !kickup.done.count(c)) 488 !kickup.done.count(c))
470 { 489 {
471 newFront.insert(c); 490 newFront.insert(c);
472 kickup.done.insert(c); 491 kickup.done.insert(c);
473 492
474 if (map.at(x,y).tile == Tile::Floor) 493 if (map.tile(x,y) == Tile::Floor)
475 { 494 {
476 map.at(x,y).tile = Tile::Dust; 495 map.tile(x,y) = Tile::Dust;
477 map.at(x,y).dustLife = 2; 496 map.at(x,y).dustLife = 2;
478 numDust++; 497 numDust++;
479 dirtyLighting = true; 498 dirtyLighting = true;
480 } else if (map.at(x,y).tile == Tile::Lamp) 499 } else if (map.tile(x,y) == Tile::Lamp)
481 { 500 {
482 popLamp(x, y, kickup.chain + 1); 501 popLamp(x, y, kickup.chain + 1);
483 } 502 }
@@ -571,11 +590,11 @@ void Game::setZoom(size_t zoom)
571} 590}
572 591
573void Game::performDash() { 592void Game::performDash() {
574 if (map.at(player_x, player_y).tile == Tile::Floor) { 593 if (map.tile(player_x, player_y) == Tile::Floor) {
575 std::vector<coord> freeSpaces; 594 std::vector<coord> freeSpaces;
576 595
577 auto addIfFree = [&] (int x, int y) { 596 auto addIfFree = [&] (int x, int y) {
578 if (map.inBounds(x,y) && map.at(x,y).tile == Tile::Floor) 597 if (map.inBounds(x,y) && map.tile(x,y) == Tile::Floor)
579 { 598 {
580 freeSpaces.emplace_back(x, y); 599 freeSpaces.emplace_back(x, y);
581 } 600 }
@@ -592,7 +611,7 @@ void Game::performDash() {
592 611
593 if (!freeSpaces.empty()) 612 if (!freeSpaces.empty())
594 { 613 {
595 map.at(player_x, player_y).tile = Tile::Lamp; 614 map.tile(player_x, player_y) = Tile::Lamp;
596 numLamps++; 615 numLamps++;
597 dirtyLighting = true; 616 dirtyLighting = true;
598 kickUpDust(player_x, player_y, 0); 617 kickUpDust(player_x, player_y, 0);
@@ -725,18 +744,19 @@ void Game::updatePlaying(size_t frameTime) {
725 { 744 {
726 numDust = 0; 745 numDust = 0;
727 746
728 for (MapData& md : map.data()) 747 for (int y=map.getTop(); y<map.getBottom(); y++) {
729 { 748 for (int x=map.getLeft(); x<map.getRight(); x++) {
730 if (md.tile == Tile::Dust) 749 if (map.tile(x,y) == Tile::Dust)
731 {
732 md.dustLife--;
733
734 if (md.dustLife <= 0)
735 { 750 {
736 md.tile = Tile::Floor; 751 map.at(x,y).dustLife--;
737 dirtyLighting = true; 752
738 } else { 753 if (map.at(x,y).dustLife <= 0)
739 numDust++; 754 {
755 map.tile(x,y) = Tile::Floor;
756 dirtyLighting = true;
757 } else {
758 numDust++;
759 }
740 } 760 }
741 } 761 }
742 } 762 }
@@ -784,7 +804,7 @@ void Game::updatePlaying(size_t frameTime) {
784 { 804 {
785 for (int x = map.getLeft(); x < map.getRight(); x++) 805 for (int x = map.getLeft(); x < map.getRight(); x++)
786 { 806 {
787 if (map.at(x,y).tile == Tile::Lamp) 807 if (map.tile(x,y) == Tile::Lamp)
788 { 808 {
789 lamps.emplace_back(x, y); 809 lamps.emplace_back(x, y);
790 } 810 }
@@ -874,29 +894,24 @@ void Game::updatePlaying(size_t frameTime) {
874 { 894 {
875 if (!map.at(x,y).lit && map.at(x,y).wasLit) 895 if (!map.at(x,y).lit && map.at(x,y).wasLit)
876 { 896 {
897 Tile oldTile = map.tile(x,y);
877 if (std::bernoulli_distribution(0.5)(rng)) 898 if (std::bernoulli_distribution(0.5)(rng))
878 { 899 {
879 map.at(x,y).tile = Tile::Wall; 900 map.tile(x,y) = Tile::Wall;
880 } else { 901 } else {
881 map.at(x,y).tile = Tile::Floor; 902 map.tile(x,y) = Tile::Floor;
903 }
904 if (map.tile(x,y) != oldTile) {
905 map.at(x,y).dirtyRender = true;
906 map.markDirtyAround(x,y);
882 } 907 }
883 map.at(x,y).dirtyRender = true;
884 } 908 }
885 } 909 }
886 } 910 }
887 911
888 /*int x1 = player_x - curZoom * ZOOM_X_FACTOR / 2 - 1; 912 tickDirty(true);
889 int y1 = player_y - curZoom * ZOOM_Y_FACTOR / 2 - 1; 913 tickDirty(true);
890 int x2 = player_x + curZoom * ZOOM_X_FACTOR / 2 + 2; 914 tickDirty(true);
891 int y2 = player_y + curZoom * ZOOM_Y_FACTOR / 2 + 2;*/
892 int x1 = player_x - CHUNK_WIDTH / 2 - 1;
893 int y1 = player_y - CHUNK_HEIGHT / 2 - 1;
894 int x2 = player_x + CHUNK_WIDTH / 2 + 2;
895 int y2 = player_y + CHUNK_HEIGHT / 2 + 2;
896
897 tick(x1, y1, x2, y2, false, true);
898 tick(x1, y1, x2, y2, false, true);
899 tick(x1, y1, x2, y2, false, true);
900 915
901 // TODO: better zoom algorithm 916 // TODO: better zoom algorithm
902 setZoom(litSpots / 1500 + INIT_ZOOM); 917 setZoom(litSpots / 1500 + INIT_ZOOM);