diff options
Diffstat (limited to 'src/map.h')
-rw-r--r-- | src/map.h | 94 |
1 files changed, 90 insertions, 4 deletions
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 | ||
27 | struct MapData { | 27 | struct 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 | ||
41 | struct Chunk { | 40 | struct 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 | ||
221 | private: | 303 | private: |
@@ -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 */ |