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 */ |
