summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/game.cpp195
-rw-r--r--src/game.h4
-rw-r--r--src/map.h94
-rw-r--r--src/renderer.cpp4
4 files changed, 200 insertions, 97 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);
diff --git a/src/game.h b/src/game.h index 637a033..c75d43b 100644 --- a/src/game.h +++ b/src/game.h
@@ -71,7 +71,7 @@ public:
71 bool dirtyRender = true; 71 bool dirtyRender = true;
72 size_t numLamps = 0; 72 size_t numLamps = 0;
73 size_t numDust = 0; 73 size_t numDust = 0;
74 std::vector<MapData> mapDoubleBuffer; 74 std::vector<Tile> mapDoubleBuffer;
75 75
76 int player_x = 0; 76 int player_x = 0;
77 int player_y = 0; 77 int player_y = 0;
@@ -111,6 +111,8 @@ public:
111 111
112private: 112private:
113 113
114 void tickDirty(bool onlyDark);
115
114 void tick( 116 void tick(
115 int x1, 117 int x1,
116 int y1, 118 int y1,
diff --git a/src/map.h b/src/map.h index de74b14..fe3270c 100644 --- a/src/map.h +++ b/src/map.h
@@ -25,7 +25,6 @@ enum class Source {
25}; 25};
26 26
27struct MapData { 27struct MapData {
28 Tile tile = Tile::Floor;
29 bool lit = false; 28 bool lit = false;
30 bool wasLit = false; 29 bool wasLit = false;
31 size_t dustLife = 0; 30 size_t dustLife = 0;
@@ -39,6 +38,7 @@ struct MapData {
39}; 38};
40 39
41struct Chunk { 40struct Chunk {
41 std::array<Tile, CHUNK_WIDTH*CHUNK_HEIGHT> tiles;
42 std::array<MapData, CHUNK_WIDTH*CHUNK_HEIGHT> data; 42 std::array<MapData, CHUNK_WIDTH*CHUNK_HEIGHT> data;
43 int litTiles = 0; 43 int litTiles = 0;
44 int x; 44 int x;
@@ -101,6 +101,16 @@ public:
101 (y < top_ + height_); 101 (y < top_ + height_);
102 } 102 }
103 103
104 inline const Tile& tile(int x, int y) const
105 {
106 return loadedTiles_[(x - left_) + width_ * (y - top_)];
107 }
108
109 inline Tile& tile(int x, int y)
110 {
111 return const_cast<Tile&>(static_cast<const Map&>(*this).tile(x, y));
112 }
113
104 inline const MapData& at(int x, int y) const 114 inline const MapData& at(int x, int y) const
105 { 115 {
106 return loaded_[(x - left_) + width_ * (y - top_)]; 116 return loaded_[(x - left_) + width_ * (y - top_)];
@@ -111,6 +121,16 @@ public:
111 return const_cast<MapData&>(static_cast<const Map&>(*this).at(x, y)); 121 return const_cast<MapData&>(static_cast<const Map&>(*this).at(x, y));
112 } 122 }
113 123
124 inline const std::vector<Tile>& tiles() const
125 {
126 return loadedTiles_;
127 }
128
129 inline std::vector<Tile>& tiles()
130 {
131 return loadedTiles_;
132 }
133
114 inline const std::vector<MapData>& data() const 134 inline const std::vector<MapData>& data() const
115 { 135 {
116 return loaded_; 136 return loaded_;
@@ -139,6 +159,11 @@ public:
139 int startX = chunkX * CHUNK_WIDTH; 159 int startX = chunkX * CHUNK_WIDTH;
140 int startY = chunkY * CHUNK_HEIGHT; 160 int startY = chunkY * CHUNK_HEIGHT;
141 for (int y=0; y<CHUNK_HEIGHT; y++) { 161 for (int y=0; y<CHUNK_HEIGHT; y++) {
162 std::copy(
163 std::next(std::begin(loadedTiles_), (chunkY*CHUNK_HEIGHT + y)*width_ + chunkX*CHUNK_WIDTH),
164 std::next(std::begin(loadedTiles_), (chunkY*CHUNK_HEIGHT + y)*width_ + (chunkX+1)*CHUNK_WIDTH),
165 std::next(std::begin(chunk.tiles), y*CHUNK_WIDTH));
166
142 for (int x=0; x<CHUNK_WIDTH; x++) { 167 for (int x=0; x<CHUNK_WIDTH; x++) {
143 chunk.data[x+y*CHUNK_WIDTH] = loaded_[startX+x+(startY+y)*width_]; 168 chunk.data[x+y*CHUNK_WIDTH] = loaded_[startX+x+(startY+y)*width_];
144 if (chunk.data[x+y*CHUNK_WIDTH].lit) { 169 if (chunk.data[x+y*CHUNK_WIDTH].lit) {
@@ -169,6 +194,9 @@ public:
169 width_ = chunksHoriz_ * CHUNK_WIDTH; 194 width_ = chunksHoriz_ * CHUNK_WIDTH;
170 height_ = chunksVert_ * CHUNK_HEIGHT; 195 height_ = chunksVert_ * CHUNK_HEIGHT;
171 loaded_ = std::vector<MapData>(width_ * height_); 196 loaded_ = std::vector<MapData>(width_ * height_);
197 loadedTiles_ = std::vector<Tile>(width_ * height_, Tile::Floor);
198 dirtyTiles_.clear();
199 dirtySet_ = std::vector<bool>(width_ * height_, false);
172 200
173 // Load in the requested chunks. 201 // Load in the requested chunks.
174 for (int chunkY = 0; chunkY < chunksVert_; chunkY++) { 202 for (int chunkY = 0; chunkY < chunksVert_; chunkY++) {
@@ -190,14 +218,16 @@ public:
190 chunk.y = topmostChunk_ + chunkY; 218 chunk.y = topmostChunk_ + chunkY;
191 chunk.litTiles = 0; 219 chunk.litTiles = 0;
192 220
193 for (MapData& md : chunk.data) 221 for (Tile& tile : chunk.tiles)
194 { 222 {
195 if (std::bernoulli_distribution(0.5)(rng)) 223 if (std::bernoulli_distribution(0.5)(rng))
196 { 224 {
197 md.tile = Tile::Wall; 225 tile = Tile::Wall;
198 } else { 226 } else {
199 md.tile = Tile::Floor; 227 tile = Tile::Floor;
200 } 228 }
229 }
230 for (MapData& md : chunk.data) {
201 md.dirtyRender = true; 231 md.dirtyRender = true;
202 } 232 }
203 } 233 }
@@ -207,6 +237,10 @@ public:
207 237
208 for (int y = 0; y < CHUNK_HEIGHT; y++) { 238 for (int y = 0; y < CHUNK_HEIGHT; y++) {
209 std::copy( 239 std::copy(
240 std::next(std::begin(chunk.tiles), y*CHUNK_WIDTH),
241 std::next(std::begin(chunk.tiles), (y+1)*CHUNK_WIDTH),
242 std::next(std::begin(loadedTiles_), (chunkY*CHUNK_HEIGHT + y)*width_ + chunkX*CHUNK_WIDTH));
243 std::copy(
210 std::next(std::begin(chunk.data), y*CHUNK_WIDTH), 244 std::next(std::begin(chunk.data), y*CHUNK_WIDTH),
211 std::next(std::begin(chunk.data), (y+1)*CHUNK_WIDTH), 245 std::next(std::begin(chunk.data), (y+1)*CHUNK_WIDTH),
212 std::next(std::begin(loaded_), (chunkY*CHUNK_HEIGHT + y)*width_ + chunkX*CHUNK_WIDTH)); 246 std::next(std::begin(loaded_), (chunkY*CHUNK_HEIGHT + y)*width_ + chunkX*CHUNK_WIDTH));
@@ -215,7 +249,55 @@ public:
215 unloadedLitTiles_ -= chunk.litTiles; 249 unloadedLitTiles_ -= chunk.litTiles;
216 } 250 }
217 } 251 }
252 }
218 253
254 void markDirtyAround(int x, int y) {
255 if (x > left_) {
256 if (y > top_) {
257 markDirty(x-1, y-1);
258 }
259 markDirty(x-1, y );
260 if (y < top_+height_-1) {
261 markDirty(x-1, y+1);
262 }
263 }
264
265 if (y > top_) {
266 markDirty(x , y-1);
267 }
268 markDirty(x , y );
269 if (y < top_+height_-1) {
270 markDirty(x , y+1);
271 }
272
273 if (x < left_+width_-1) {
274 if (y > top_) {
275 markDirty(x+1, y-1);
276 }
277 markDirty(x+1, y );
278 if (y < top_+height_-1) {
279 markDirty(x+1, y+1);
280 }
281 }
282 }
283
284 void markDirty(int x, int y) {
285 size_t index = (x-left_)+(y-top_)*width_;
286 if (!dirtySet_[index]) {
287 dirtySet_[index] = true;
288 dirtyTiles_.emplace_back(x,y);
289 }
290 }
291
292 const std::vector<coord> getDirty() const {
293 return dirtyTiles_;
294 }
295
296 void resetDirty() {
297 for (auto [x,y] : dirtyTiles_) {
298 dirtySet_[(x-left_)+(y-top_)*width_] = false;
299 }
300 dirtyTiles_.clear();
219 } 301 }
220 302
221private: 303private:
@@ -228,6 +310,7 @@ private:
228 int topmostChunk_; 310 int topmostChunk_;
229 int chunksHoriz_; 311 int chunksHoriz_;
230 int chunksVert_; 312 int chunksVert_;
313 std::vector<Tile> loadedTiles_;
231 std::vector<MapData> loaded_; 314 std::vector<MapData> loaded_;
232 315
233 std::vector<Chunk> chunks_; 316 std::vector<Chunk> chunks_;
@@ -235,6 +318,9 @@ private:
235 std::map<int, std::map<int, size_t>> chunkByPos_; // chunkByPos_[X][Y] 318 std::map<int, std::map<int, size_t>> chunkByPos_; // chunkByPos_[X][Y]
236 319
237 int unloadedLitTiles_ = 0; 320 int unloadedLitTiles_ = 0;
321
322 std::vector<coord> dirtyTiles_;
323 std::vector<bool> dirtySet_;
238}; 324};
239 325
240#endif /* end of include guard: MAP_H_3AB00D12 */ 326#endif /* end of include guard: MAP_H_3AB00D12 */
diff --git a/src/renderer.cpp b/src/renderer.cpp index c8c1746..9744e70 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp
@@ -173,7 +173,7 @@ void Renderer::renderGame(
173 173
174 if (draw) 174 if (draw)
175 { 175 {
176 if (game.map.at(x,y).tile != Tile::Wall) { 176 if (game.map.tile(x,y) != Tile::Wall) {
177 SDL_Rect tileRect {17 * 16, 15 * 16, 16, 16}; 177 SDL_Rect tileRect {17 * 16, 15 * 16, 16, 16};
178 SDL_RenderCopy(ren_.get(), tileset_.get(), &tileRect, &rect); 178 SDL_RenderCopy(ren_.get(), tileset_.get(), &tileRect, &rect);
179 179
@@ -192,7 +192,7 @@ void Renderer::renderGame(
192 SDL_RenderCopy(ren_.get(), tileset_.get(), &tileRect, &rect); 192 SDL_RenderCopy(ren_.get(), tileset_.get(), &tileRect, &rect);
193 } 193 }
194 194
195 if (game.map.at(x,y).tile == Tile::Lamp) { 195 if (game.map.tile(x,y) == Tile::Lamp) {
196 SDL_RenderCopy(ren_.get(), lamp_.get(), nullptr, &rect); 196 SDL_RenderCopy(ren_.get(), lamp_.get(), nullptr, &rect);
197 } 197 }
198 198