summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2018-05-29 21:57:33 -0400
committerKelly Rauchenberger <fefferburbia@gmail.com>2018-05-29 21:57:33 -0400
commitc055e37e57ff365f5ae62d265d4b2140fbdc348a (patch)
tree03dcba961433d3a2a188c777ddc1978275b9203d /src
parent9b1c8e98592cc0e5cec471720498e7bb2a60a449 (diff)
downloadether-c055e37e57ff365f5ae62d265d4b2140fbdc348a.tar.gz
ether-c055e37e57ff365f5ae62d265d4b2140fbdc348a.tar.bz2
ether-c055e37e57ff365f5ae62d265d4b2140fbdc348a.zip
abstracted map data into a class to allow for zooming out
Diffstat (limited to 'src')
-rw-r--r--src/main.cpp366
-rw-r--r--src/map.h127
2 files changed, 316 insertions, 177 deletions
diff --git a/src/main.cpp b/src/main.cpp index c39cdb6..9534678 100644 --- a/src/main.cpp +++ b/src/main.cpp
@@ -7,6 +7,7 @@
7#include <fov.h> 7#include <fov.h>
8#include <iostream> 8#include <iostream>
9#include "util.h" 9#include "util.h"
10#include "map.h"
10 11
11class sdl_error : public std::logic_error { 12class sdl_error : public std::logic_error {
12public: 13public:
@@ -75,49 +76,51 @@ struct Kickup {
75 size_t chain; 76 size_t chain;
76}; 77};
77 78
78class Map { 79struct MapData {
80 Tile tile = Tile::Floor;
81 bool lit = false;
82 bool wasLit = false;
83 double visibility = 0.0;
84};
85
86class Game {
79public: 87public:
80 88
81 Map() : 89 Game() :
82 tiles(VIEW_WIDTH*VIEW_HEIGHT, Tile::Floor), 90 map(-VIEW_WIDTH/2, -VIEW_HEIGHT/2, VIEW_WIDTH, VIEW_HEIGHT)
83 lighting(VIEW_WIDTH*VIEW_HEIGHT, false),
84 lightStrength(VIEW_WIDTH*VIEW_HEIGHT, 0.0)
85 { 91 {
86 } 92 }
87 93
88 std::vector<Tile> tiles; 94 Map<MapData> map;
89 std::vector<bool> lighting;
90 std::vector<bool> oldLighting;
91 std::vector<double> lightStrength;
92 std::list<Kickup> kickups; 95 std::list<Kickup> kickups;
93 int lightedSpots = 0; 96 int lightedSpots = 0;
94 bool dirtyLighting = true; 97 bool dirtyLighting = true;
95 size_t numLamps = 0; 98 size_t numLamps = 0;
96 size_t numDust = 0; 99 size_t numDust = 0;
97};
98 100
99int player_x = VIEW_WIDTH / 2; 101 int player_x = 0;
100int player_y = VIEW_HEIGHT / 2; 102 int player_y = 0;
101bool renderPlayer = true; 103 bool renderPlayer = true;
104};
102 105
103void render( 106void render(
104 SDL_Renderer* ren, 107 SDL_Renderer* ren,
105 const Map& map, 108 const Game& game,
106 bool drawDark = true) 109 bool drawDark = true)
107{ 110{
108 SDL_SetRenderDrawColor(ren, rand() % 255, rand() % 255, rand() % 255, 255); 111 SDL_SetRenderDrawColor(ren, rand() % 255, rand() % 255, rand() % 255, 255);
109 SDL_RenderClear(ren); 112 SDL_RenderClear(ren);
110 113
111 for (int y = 0; y < VIEW_HEIGHT; y++) 114 for (int y = game.map.getTop(); y < game.map.getBottom(); y++)
112 { 115 {
113 for (int x = 0; x < VIEW_WIDTH; x++) 116 for (int x = game.map.getLeft(); x < game.map.getRight(); x++)
114 { 117 {
115 bool draw = true; 118 bool draw = true;
116 119
117 if ((player_x == x && player_y == y) && renderPlayer) 120 if ((game.player_x == x && game.player_y == y) && game.renderPlayer)
118 { 121 {
119 SDL_SetRenderDrawColor(ren, 255, 255, 0, 255); 122 SDL_SetRenderDrawColor(ren, 255, 255, 0, 255);
120 } else if (!map.lighting.at(x+VIEW_WIDTH*y)) 123 } else if (!game.map.at(x,y).lit)
121 { 124 {
122 if (drawDark) 125 if (drawDark)
123 { 126 {
@@ -126,7 +129,7 @@ void render(
126 draw = false; 129 draw = false;
127 } 130 }
128 } else { 131 } else {
129 switch (map.tiles.at(x+y*VIEW_WIDTH)) 132 switch (game.map.at(x,y).tile)
130 { 133 {
131 case Tile::Floor: 134 case Tile::Floor:
132 { 135 {
@@ -156,10 +159,15 @@ void render(
156 159
157 if (draw) 160 if (draw)
158 { 161 {
159 SDL_Rect rect{x*TILE_WIDTH, y*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT}; 162 SDL_Rect rect {
163 game.map.getTrueX(x) * TILE_WIDTH,
164 game.map.getTrueY(y) * TILE_HEIGHT,
165 TILE_WIDTH,
166 TILE_HEIGHT};
167
160 SDL_RenderFillRect(ren, &rect); 168 SDL_RenderFillRect(ren, &rect);
161 169
162 int alpha = (1.0 - map.lightStrength.at(x+y*VIEW_WIDTH)) * 255; 170 int alpha = (1.0 - game.map.at(x,y).visibility) * 255;
163 SDL_SetRenderDrawColor(ren, 40, 40, 40, alpha); 171 SDL_SetRenderDrawColor(ren, 40, 40, 40, alpha);
164 SDL_RenderFillRect(ren, &rect); 172 SDL_RenderFillRect(ren, &rect);
165 } 173 }
@@ -169,115 +177,132 @@ void render(
169 SDL_RenderPresent(ren); 177 SDL_RenderPresent(ren);
170} 178}
171 179
172void incrementIfSet(Map& map, int& count, int x, int y, int w, int h, Tile val = Tile::Wall) 180void incrementIfSet(Game& game, int& count, int x, int y, Tile val = Tile::Wall)
173{ 181{
174 if ((x >= 0) && (x < w) && (y >= 0) && (y < h) && (map.tiles[x+w*y] == val)) 182 if (game.map.inBounds(x, y) && game.map.at(x,y).tile == val)
175 { 183 {
176 count++; 184 count++;
177 } 185 }
178} 186}
179 187
180void tick(Map& map, int x1 = 0, int y1 = 0, int x2 = VIEW_WIDTH, int y2 = VIEW_HEIGHT, bool onlyDark = false) 188void tick(
189 Game& game,
190 int x1,
191 int y1,
192 int x2,
193 int y2,
194 bool invert = false,
195 bool onlyDark = false)
181{ 196{
182 std::vector<Tile> temp(map.tiles); 197 Map<MapData> temp(game.map);
183 198
184 for (int y = std::max(y1, 0); y < std::min(y2, VIEW_HEIGHT); y++) 199 for (int y = game.map.getTop(); y < game.map.getBottom(); y++)
185 { 200 {
186 for (int x = std::max(x1, 0); x < std::min(x2, VIEW_WIDTH); x++) 201 for (int x = game.map.getLeft(); x < game.map.getRight(); x++)
187 { 202 {
188 if (onlyDark && map.lighting[x+y*VIEW_WIDTH]) 203 if (invert == (x >= x1 && x < x2 && y >= y1 && y < y2))
204 {
205 continue;
206 }
207
208 if (onlyDark && game.map.at(x,y).lit)
189 { 209 {
190 continue; 210 continue;
191 } 211 }
192 212
193 if (map.tiles[x+y*VIEW_WIDTH] == Tile::Lamp) 213 if (game.map.at(x,y).tile == Tile::Lamp)
194 { 214 {
195 continue; 215 continue;
196 } 216 }
197 217
198 int count = 0; 218 int count = 0;
199 219
200 incrementIfSet(map, count, x-1, y-1, VIEW_WIDTH, VIEW_HEIGHT); 220 incrementIfSet(game, count, x-1, y-1);
201 incrementIfSet(map, count, x-1, y , VIEW_WIDTH, VIEW_HEIGHT); 221 incrementIfSet(game, count, x-1, y );
202 incrementIfSet(map, count, x-1, y+1, VIEW_WIDTH, VIEW_HEIGHT); 222 incrementIfSet(game, count, x-1, y+1);
203 incrementIfSet(map, count, x , y-1, VIEW_WIDTH, VIEW_HEIGHT); 223 incrementIfSet(game, count, x , y-1);
204 incrementIfSet(map, count, x , y , VIEW_WIDTH, VIEW_HEIGHT); 224 incrementIfSet(game, count, x , y );
205 incrementIfSet(map, count, x , y+1, VIEW_WIDTH, VIEW_HEIGHT); 225 incrementIfSet(game, count, x , y+1);
206 incrementIfSet(map, count, x+1, y-1, VIEW_WIDTH, VIEW_HEIGHT); 226 incrementIfSet(game, count, x+1, y-1);
207 incrementIfSet(map, count, x+1, y , VIEW_WIDTH, VIEW_HEIGHT); 227 incrementIfSet(game, count, x+1, y );
208 incrementIfSet(map, count, x+1, y+1, VIEW_WIDTH, VIEW_HEIGHT); 228 incrementIfSet(game, count, x+1, y+1);
209 229
210 if (count >= 5) 230 if (count >= 5)
211 { 231 {
212 temp[x+VIEW_WIDTH*y] = Tile::Wall; 232 temp.at(x,y).tile = Tile::Wall;
213 } else { 233 } else {
214 temp[x+VIEW_WIDTH*y] = Tile::Floor; 234 temp.at(x,y).tile = Tile::Floor;
215 } 235 }
216 } 236 }
217 } 237 }
218 238
219 map.tiles = temp; 239 game.map = std::move(temp);
240}
241
242void tick(Game& game, bool onlyDark = false)
243{
244 tick(
245 game,
246 game.map.getLeft(),
247 game.map.getTop(),
248 game.map.getRight(),
249 game.map.getBottom(),
250 false,
251 onlyDark);
220} 252}
221 253
222void movePlayer(int x, int y, Map& map) 254void movePlayer(Game& game, int x, int y)
223{ 255{
224 if ((x >= 0) && (x < VIEW_WIDTH) && (y >= 0) && (y < VIEW_HEIGHT) && 256 if (game.map.inBounds(x, y) && game.map.at(x,y).tile == Tile::Floor)
225 map.tiles[x+VIEW_WIDTH*y] == Tile::Floor)
226 { 257 {
227 if (map.tiles[player_x+player_y*VIEW_WIDTH] == Tile::Floor) 258 if (game.map.at(game.player_x, game.player_y).tile == Tile::Floor)
228 { 259 {
229 map.tiles[player_x+player_y*VIEW_WIDTH] = Tile::Dust; 260 game.map.at(game.player_x, game.player_y).tile = Tile::Dust;
230 map.numDust++; 261 game.numDust++;
231 } 262 }
232 263
233 player_x = x; 264 game.player_x = x;
234 player_y = y; 265 game.player_y = y;
235 266
236 map.dirtyLighting = true; 267 game.dirtyLighting = true;
237 } 268 }
238} 269}
239 270
240void setIfValid(Map& map, int x, int y, Tile val) 271void recalculateLighting(Game& game, fov_settings_type* fov)
241{ 272{
242 if ((x >= 0) && (x < VIEW_WIDTH) && (y >= 0) && (y < VIEW_HEIGHT)) 273 game.lightedSpots = 0;
274
275 for (MapData& md : game.map.data())
243 { 276 {
244 map.tiles[x+VIEW_WIDTH*y] = val; 277 md.wasLit = md.lit;
278 md.lit = false;
279 md.visibility = 0.0;
245 } 280 }
246}
247
248void recalculateLighting(Map& map, fov_settings_type* fov)
249{
250 map.oldLighting = map.lighting;
251 map.lighting = std::vector<bool>(VIEW_WIDTH*VIEW_HEIGHT, false);
252 map.lightStrength = std::vector<double>(VIEW_WIDTH*VIEW_HEIGHT, 0.0);
253 map.lightedSpots = 0;
254 281
255 fov_settings_set_opacity_test_function( 282 fov_settings_set_opacity_test_function(
256 fov, 283 fov,
257 [] (void* map, int x, int y) { 284 [] (void* data, int x, int y) {
258 return 285 Game& game = *static_cast<Game*>(data);
259 x >= 0 && 286
260 x < VIEW_WIDTH && 287 return game.map.inBounds(x,y) && game.map.at(x,y).tile == Tile::Wall;
261 y >= 0 &&
262 y < VIEW_HEIGHT &&
263 static_cast<Map*>(map)->tiles.at(x+VIEW_WIDTH*y) == Tile::Wall;
264 }); 288 });
265 289
266 fov_settings_set_apply_lighting_function( 290 fov_settings_set_apply_lighting_function(
267 fov, 291 fov,
268 [] (void* map, int x, int y, int dx, int dy, void*) { 292 [] (void* data, int x, int y, int dx, int dy, void*) {
269 if ((x >= 0) && (x < VIEW_WIDTH) && (y >= 0) && (y < VIEW_HEIGHT)) 293 Game& game = *static_cast<Game*>(data);
294
295 if (game.map.inBounds(x, y))
270 { 296 {
271 Map& m = *static_cast<Map*>(map); 297 if (!game.map.at(x,y).lit)
272 if (!m.lighting[x+VIEW_WIDTH*y])
273 { 298 {
274 m.lightedSpots++; 299 game.lightedSpots++;
275 } 300 }
276 301
277 m.lighting[x+VIEW_WIDTH*y] = true; 302 game.map.at(x,y).lit = true;
278 303
279 m.lightStrength[x+VIEW_WIDTH*y] = std::max( 304 game.map.at(x,y).visibility = std::max(
280 m.lightStrength[x+VIEW_WIDTH*y], 305 game.map.at(x,y).visibility,
281 std::pow( 306 std::pow(
282 std::max( 307 std::max(
283 0.0, 308 0.0,
@@ -286,29 +311,29 @@ void recalculateLighting(Map& map, fov_settings_type* fov)
286 } 311 }
287 }); 312 });
288 313
289 for (int y = 0; y < VIEW_HEIGHT; y++) 314 for (int y = game.map.getTop(); y < game.map.getBottom(); y++)
290 { 315 {
291 for (int x = 0; x < VIEW_WIDTH; x++) 316 for (int x = game.map.getLeft(); x < game.map.getRight(); x++)
292 { 317 {
293 if ((player_x == x && player_y == y && renderPlayer) || 318 if ((game.player_x == x && game.player_y == y && game.renderPlayer) ||
294 map.tiles[x+VIEW_WIDTH*y] == Tile::Dust || 319 game.map.at(x,y).tile == Tile::Dust ||
295 map.tiles[x+VIEW_WIDTH*y] == Tile::Lamp) 320 game.map.at(x,y).tile == Tile::Lamp)
296 { 321 {
297 fov_circle(fov, static_cast<void*>(&map), nullptr, x, y, RADIUS); 322 fov_circle(fov, static_cast<void*>(&game), nullptr, x, y, RADIUS);
298 323
299 map.lighting[x+VIEW_WIDTH*y] = true; 324 game.map.at(x,y).lit = true;
300 map.lightStrength[x+VIEW_WIDTH*y] = 1.0; 325 game.map.at(x,y).visibility = 1.0;
301 } 326 }
302 } 327 }
303 } 328 }
304 329
305 map.dirtyLighting = false; 330 game.dirtyLighting = false;
306} 331}
307 332
308void processKeys(Map& map, const Input& keystate) 333void processKeys(Game& game, const Input& keystate)
309{ 334{
310 int px = player_x; 335 int px = game.player_x;
311 int py = player_y; 336 int py = game.player_y;
312 337
313 if (keystate.up) 338 if (keystate.up)
314 { 339 {
@@ -330,13 +355,13 @@ void processKeys(Map& map, const Input& keystate)
330 px++; 355 px++;
331 } 356 }
332 357
333 if (!(player_x == px && player_y == py)) 358 if (!(game.player_x == px && game.player_y == py))
334 { 359 {
335 movePlayer(px, py, map); 360 movePlayer(game, px, py);
336 } 361 }
337} 362}
338 363
339void kickUpDust(Map& map, int x, int y, size_t chain) 364void kickUpDust(Game& game, int x, int y, size_t chain)
340{ 365{
341 Kickup dk; 366 Kickup dk;
342 dk.x = x; 367 dk.x = x;
@@ -345,71 +370,67 @@ void kickUpDust(Map& map, int x, int y, size_t chain)
345 dk.cur = 0; 370 dk.cur = 0;
346 dk.radius = RADIUS + (chain + 1) * (chain + 1); 371 dk.radius = RADIUS + (chain + 1) * (chain + 1);
347 372
348 map.kickups.push_back(dk); 373 game.kickups.push_back(dk);
349} 374}
350 375
351void popLamp(Map& map, int x, int y, size_t chain) 376void popLamp(Game& game, int x, int y, size_t chain)
352{ 377{
353 if (map.tiles[x+VIEW_WIDTH*y] == Tile::Lamp) 378 if (game.map.at(x,y).tile == Tile::Lamp)
354 { 379 {
355 map.numLamps--; 380 game.numLamps--;
356 } 381 }
357 382
358 map.tiles[x+VIEW_WIDTH*y] = Tile::Dust; 383 game.map.at(x,y).tile = Tile::Dust;
359 map.numDust++; 384 game.numDust++;
360 map.dirtyLighting = true; 385 game.dirtyLighting = true;
361 386
362 kickUpDust(map, x, y, chain); 387 kickUpDust(game, x, y, chain);
363} 388}
364 389
365void processKickup(Map& map) 390void processKickup(Game& game)
366{ 391{
367 for (Kickup& kickup : map.kickups) 392 for (Kickup& kickup : game.kickups)
368 { 393 {
369 kickup.cur++; 394 kickup.cur++;
370 395
371 if (map.tiles[kickup.x+VIEW_WIDTH*kickup.y] == Tile::Floor) 396 if (game.map.at(kickup.x, kickup.y).tile == Tile::Floor)
372 { 397 {
373 map.tiles[kickup.x+VIEW_WIDTH*kickup.y] = Tile::Dust; 398 game.map.at(kickup.x, kickup.y).tile = Tile::Dust;
374 map.numDust++; 399 game.numDust++;
375 } 400 }
376 401
377 std::unique_ptr<fov_settings_type> dusty(new fov_settings_type); 402 std::unique_ptr<fov_settings_type> dusty(new fov_settings_type);
378 fov_settings_set_opacity_test_function( 403 fov_settings_set_opacity_test_function(
379 dusty.get(), 404 dusty.get(),
380 [] (void* map, int x, int y) { 405 [] (void* data, int x, int y) {
381 return 406 Game& game = *static_cast<Game*>(data);
382 x >= 0 && 407
383 x < VIEW_WIDTH && 408 return game.map.inBounds(x,y) && game.map.at(x,y).tile == Tile::Wall;
384 y >= 0 &&
385 y < VIEW_HEIGHT &&
386 static_cast<Map*>(map)->tiles.at(x+VIEW_WIDTH*y) == Tile::Wall;
387 }); 409 });
388 410
389 fov_settings_set_apply_lighting_function( 411 fov_settings_set_apply_lighting_function(
390 dusty.get(), 412 dusty.get(),
391 [] (void* data, int x, int y, int, int, void* source) { 413 [] (void* data, int x, int y, int, int, void* source) {
392 Map& map = *static_cast<Map*>(data); 414 Game& game = *static_cast<Game*>(data);
393 Kickup& kickup = *static_cast<Kickup*>(source); 415 Kickup& kickup = *static_cast<Kickup*>(source);
394 416
395 if ((x >= 0) && (x < VIEW_WIDTH) && 417 if (game.map.inBounds(x,y))
396 (y >= 0) && (y < VIEW_HEIGHT))
397 { 418 {
398 if (map.tiles[x+VIEW_WIDTH*y] == Tile::Floor) 419 if (game.map.at(x,y).tile == Tile::Floor)
399 { 420 {
400 map.tiles[x+VIEW_WIDTH*y] = Tile::Dust; 421 game.map.at(x,y).tile = Tile::Dust;
401 map.numDust++; 422 game.numDust++;
402 map.dirtyLighting = true; 423 game.dirtyLighting = true;
403 } else if (map.tiles[x+VIEW_WIDTH*y] == Tile::Lamp) 424 } else if (game.map.at(x,y).tile == Tile::Lamp)
404 { 425 {
405 popLamp(map, x, y, kickup.chain + 1); 426 popLamp(game, x, y, kickup.chain + 1);
406 } 427 }
407 } 428 }
408 }); 429 });
409 430
410 fov_circle( 431 fov_circle(
411 dusty.get(), 432 dusty.get(),
412 static_cast<void*>(&map), 433 static_cast<void*>(&game),
413 static_cast<void*>(&kickup), 434 static_cast<void*>(&kickup),
414 kickup.x, 435 kickup.x,
415 kickup.y, 436 kickup.y,
@@ -417,7 +438,7 @@ void processKickup(Map& map)
417 } 438 }
418 439
419 erase_if( 440 erase_if(
420 map.kickups, 441 game.kickups,
421 [] (const Kickup& kickup) { 442 [] (const Kickup& kickup) {
422 return kickup.cur == kickup.radius; 443 return kickup.cur == kickup.radius;
423 }); 444 });
@@ -456,25 +477,22 @@ int main(int, char**)
456 477
457 SDL_SetRenderDrawBlendMode(ren.get(), SDL_BLENDMODE_BLEND); 478 SDL_SetRenderDrawBlendMode(ren.get(), SDL_BLENDMODE_BLEND);
458 479
459 Map map; 480 Game game;
460 481
461 std::unique_ptr<fov_settings_type> fov(new fov_settings_type()); 482 std::unique_ptr<fov_settings_type> fov(new fov_settings_type());
462 fov_settings_init(fov.get()); 483 fov_settings_init(fov.get());
463 484
464 for (int y = 0; y < VIEW_HEIGHT; y++) 485 for (MapData& md : game.map.data())
465 { 486 {
466 for (int x = 0; x < VIEW_WIDTH; x++) 487 if (std::bernoulli_distribution(0.5)(rng))
467 { 488 {
468 if (std::bernoulli_distribution(0.5)(rng)) 489 md.tile = Tile::Wall;
469 {
470 map.tiles[x+y*VIEW_WIDTH] = Tile::Wall;
471 }
472 } 490 }
473 } 491 }
474 492
475 tick(map); 493 tick(game);
476 tick(map); 494 tick(game);
477 tick(map); 495 tick(game);
478 496
479 bool quit = false; 497 bool quit = false;
480 LoseState losing = LoseState::None; 498 LoseState losing = LoseState::None;
@@ -531,26 +549,24 @@ int main(int, char**)
531 { 549 {
532 if (losing == LoseState::None) 550 if (losing == LoseState::None)
533 { 551 {
534 if (map.tiles[player_x+VIEW_WIDTH*player_y] == Tile::Floor) 552 if (game.map.at(game.player_x, game.player_y).tile ==
553 Tile::Floor)
535 { 554 {
536 map.tiles[player_x+VIEW_WIDTH*player_y] = Tile::Lamp; 555 game.map.at(game.player_x, game.player_y).tile = Tile::Lamp;
537 map.numLamps++; 556 game.numLamps++;
538 map.dirtyLighting = true; 557 game.dirtyLighting = true;
539 kickUpDust(map, player_x, player_y, 0); 558 kickUpDust(game, game.player_x, game.player_y, 0);
540 559
541 for (int i = 0; i < 5; i++) 560 for (int i = 0; i < 5; i++)
542 { 561 {
543 processKeys(map, keystate); 562 processKeys(game, keystate);
544 563
545 tick( 564 tick(
546 map, 565 game,
547 player_x - (RADIUS - 1), 566 game.player_x - (RADIUS - 1),
548 player_y - (RADIUS - 1), 567 game.player_y - (RADIUS - 1),
549 player_x + RADIUS, 568 game.player_x + RADIUS,
550 player_y + RADIUS); 569 game.player_y + RADIUS);
551
552 //render(ren.get(), map, false);
553 //SDL_Delay(30);
554 } 570 }
555 } 571 }
556 } 572 }
@@ -572,21 +588,18 @@ int main(int, char**)
572 588
573 while (dustAcc >= dustDt) 589 while (dustAcc >= dustDt)
574 { 590 {
575 for (int y = 0; y < VIEW_HEIGHT; y++) 591 for (MapData& md : game.map.data())
576 { 592 {
577 for (int x = 0; x < VIEW_WIDTH; x++) 593 if (md.tile == Tile::Dust)
578 { 594 {
579 if (map.tiles[x+y*VIEW_WIDTH] == Tile::Dust) 595 md.tile = Tile::Floor;
580 { 596 game.dirtyLighting = true;
581 map.tiles[x+y*VIEW_WIDTH] = Tile::Floor;
582 map.dirtyLighting = true;
583 }
584 } 597 }
585 } 598 }
586 599
587 map.numDust = 0; 600 game.numDust = 0;
588 601
589 processKickup(map); 602 processKickup(game);
590 603
591 dustAcc -= dustDt; 604 dustAcc -= dustDt;
592 } 605 }
@@ -597,7 +610,7 @@ int main(int, char**)
597 { 610 {
598 while (inputAcc >= inputDt) 611 while (inputAcc >= inputDt)
599 { 612 {
600 processKeys(map, keystate); 613 processKeys(game, keystate);
601 614
602 inputAcc -= inputDt; 615 inputAcc -= inputDt;
603 } 616 }
@@ -607,9 +620,9 @@ int main(int, char**)
607 620
608 case LoseState::PoppingLamps: 621 case LoseState::PoppingLamps:
609 { 622 {
610 if (map.numLamps == 0) 623 if (game.numLamps == 0)
611 { 624 {
612 if (map.numDust == 0) 625 if (game.numDust == 0)
613 { 626 {
614 losing = LoseState::PoppingPlayer; 627 losing = LoseState::PoppingPlayer;
615 } 628 }
@@ -620,11 +633,11 @@ int main(int, char**)
620 { 633 {
621 std::vector<std::tuple<int, int>> lamps; 634 std::vector<std::tuple<int, int>> lamps;
622 635
623 for (int y = 0; y < VIEW_HEIGHT; y++) 636 for (int y = game.map.getTop(); y < game.map.getBottom(); y++)
624 { 637 {
625 for (int x = 0; x < VIEW_WIDTH; x++) 638 for (int x = game.map.getLeft(); x < game.map.getRight(); x++)
626 { 639 {
627 if (map.tiles[x+VIEW_WIDTH*y] == Tile::Lamp) 640 if (game.map.at(x,y).tile == Tile::Lamp)
628 { 641 {
629 lamps.emplace_back(x, y); 642 lamps.emplace_back(x, y);
630 } 643 }
@@ -634,7 +647,7 @@ int main(int, char**)
634 std::uniform_int_distribution<int> lampDist(0, lamps.size() - 1); 647 std::uniform_int_distribution<int> lampDist(0, lamps.size() - 1);
635 std::tuple<int, int> popPos = lamps[lampDist(rng)]; 648 std::tuple<int, int> popPos = lamps[lampDist(rng)];
636 649
637 popLamp(map, std::get<0>(popPos), std::get<1>(popPos), 0); 650 popLamp(game, std::get<0>(popPos), std::get<1>(popPos), 0);
638 651
639 losePopLampAcc -= losePopLampDt; 652 losePopLampAcc -= losePopLampDt;
640 } 653 }
@@ -649,8 +662,8 @@ int main(int, char**)
649 662
650 if (losePopPlayerAcc >= losePopPlayerDt) 663 if (losePopPlayerAcc >= losePopPlayerDt)
651 { 664 {
652 popLamp(map, player_x, player_y, 10); 665 popLamp(game, game.player_x, game.player_y, 10);
653 renderPlayer = false; 666 game.renderPlayer = false;
654 667
655 losing = LoseState::Outro; 668 losing = LoseState::Outro;
656 } 669 }
@@ -660,7 +673,7 @@ int main(int, char**)
660 673
661 case LoseState::Outro: 674 case LoseState::Outro:
662 { 675 {
663 if (map.numDust == 0) 676 if (game.numDust == 0)
664 { 677 {
665 quit = true; 678 quit = true;
666 } 679 }
@@ -669,33 +682,32 @@ int main(int, char**)
669 } 682 }
670 } 683 }
671 684
672 if (map.dirtyLighting) 685 if (game.dirtyLighting)
673 { 686 {
674 recalculateLighting(map, fov.get()); 687 recalculateLighting(game, fov.get());
675 688
676 for (int y = 0; y < VIEW_HEIGHT; y++) 689 for (int y = game.map.getTop(); y < game.map.getBottom(); y++)
677 { 690 {
678 for (int x = 0; x < VIEW_WIDTH; x++) 691 for (int x = game.map.getLeft(); x < game.map.getRight(); x++)
679 { 692 {
680 if (!map.lighting[x+y*VIEW_WIDTH] && map.oldLighting[x+y*VIEW_WIDTH]) 693 if (!game.map.at(x,y).lit && game.map.at(x,y).wasLit)
681 { 694 {
682 if (std::bernoulli_distribution(0.5)(rng)) 695 if (std::bernoulli_distribution(0.5)(rng))
683 { 696 {
684 map.tiles[x+y*VIEW_WIDTH] = Tile::Wall; 697 game.map.at(x,y).tile = Tile::Wall;
685 } else { 698 } else {
686 map.tiles[x+y*VIEW_WIDTH] = Tile::Floor; 699 game.map.at(x,y).tile = Tile::Floor;
687 } 700 }
688 } 701 }
689 } 702 }
690 } 703 }
691 704
692 tick(map, 0, 0, VIEW_WIDTH, VIEW_HEIGHT, true); 705 tick(game, true);
693 tick(map, 0, 0, VIEW_WIDTH, VIEW_HEIGHT, true); 706 tick(game, true);
694 tick(map, 0, 0, VIEW_WIDTH, VIEW_HEIGHT, true); 707 tick(game, true);
695 } 708 }
696 709
697 render(ren.get(), map, true); 710 render(ren.get(), game, true);
698 //SDL_Delay(50);
699 } 711 }
700 } catch (const sdl_error& ex) 712 } catch (const sdl_error& ex)
701 { 713 {
diff --git a/src/map.h b/src/map.h new file mode 100644 index 0000000..329553c --- /dev/null +++ b/src/map.h
@@ -0,0 +1,127 @@
1#ifndef MAP_H_3AB00D12
2#define MAP_H_3AB00D12
3
4#include <vector>
5#include <algorithm>
6
7template <typename T>
8class Map {
9public:
10
11 Map(
12 int left,
13 int top,
14 int width,
15 int height) :
16 left_(left),
17 top_(top),
18 width_(width),
19 height_(height),
20 data_(width_*height_)
21 {
22 }
23
24 inline int getLeft() const
25 {
26 return left_;
27 }
28
29 inline int getRight() const
30 {
31 return left_ + width_;
32 }
33
34 inline int getTop() const
35 {
36 return top_;
37 }
38
39 inline int getBottom() const
40 {
41 return top_ + height_;
42 }
43
44 inline int getWidth() const
45 {
46 return width_;
47 }
48
49 inline int getHeight() const
50 {
51 return height_;
52 }
53
54 inline int getTrueX(int x) const
55 {
56 return (x - left_);
57 }
58
59 inline int getTrueY(int y) const
60 {
61 return (y - top_);
62 }
63
64 inline bool inBounds(int x, int y) const
65 {
66 return (x >= left_) &&
67 (x < left_ + width_) &&
68 (y >= top_) &&
69 (y < top_ + height_);
70 }
71
72 inline const T& at(int x, int y) const
73 {
74 return data_.at((x - left_) + width_ * (y - top_));
75 }
76
77 inline T& at(int x, int y)
78 {
79 return const_cast<T&>(static_cast<const Map&>(*this).at(x, y));
80 }
81
82 inline const std::vector<T>& data() const
83 {
84 return data_;
85 }
86
87 inline std::vector<T>& data()
88 {
89 return data_;
90 }
91
92 void resize(int newLeft, int newTop, int newWidth, int newHeight)
93 {
94 std::vector<T> newData(newWidth * newHeight);
95
96 int winTop = std::max(top_, newTop);
97 int winBottom = std::min(top_ + height_, newTop + newHeight);
98 int winLeft = std::max(left_, newLeft);
99 int winRight = std::min(left_ + width_, newLeft + newWidth);
100
101 for (int y = winTop; y < winBottom; y++)
102 {
103 std::move(
104 std::next(std::begin(data_), (winLeft - left_) + width_ * (y - top_)),
105 std::next(std::begin(data_), (winRight - left_) + width_ * (y - top_)),
106 std::next(std::begin(newData),
107 (winLeft - newLeft) + newWidth * (y - newTop)));
108 }
109
110 left_ = newLeft;
111 top_ = newTop;
112 width_ = newWidth;
113 height_ = newHeight;
114 data_.swap(newData);
115 }
116
117private:
118
119 int left_;
120 int top_;
121 int width_;
122 int height_;
123
124 std::vector<T> data_;
125};
126
127#endif /* end of include guard: MAP_H_3AB00D12 */