summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--src/main.cpp275
2 files changed, 94 insertions, 182 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..378eac2 --- /dev/null +++ b/.gitignore
@@ -0,0 +1 @@
build
diff --git a/src/main.cpp b/src/main.cpp index 2fc610b..1b7d198 100644 --- a/src/main.cpp +++ b/src/main.cpp
@@ -5,6 +5,7 @@
5#include <random> 5#include <random>
6#include <fov.h> 6#include <fov.h>
7#include <deque> 7#include <deque>
8#include <iostream>
8 9
9class sdl_error : public std::logic_error { 10class sdl_error : public std::logic_error {
10public: 11public:
@@ -44,10 +45,10 @@ enum class Tile {
44 Lamp 45 Lamp
45}; 46};
46 47
47const int GAME_WIDTH = 640; 48const int GAME_WIDTH = 640*2;
48const int GAME_HEIGHT = 480; 49const int GAME_HEIGHT = 480*2;
49const int TILE_WIDTH = 8; 50const int TILE_WIDTH = 8*2;
50const int TILE_HEIGHT = 8; 51const int TILE_HEIGHT = 8*2;
51const int VIEW_WIDTH = GAME_WIDTH / TILE_WIDTH; 52const int VIEW_WIDTH = GAME_WIDTH / TILE_WIDTH;
52const int VIEW_HEIGHT = GAME_HEIGHT / TILE_HEIGHT; 53const int VIEW_HEIGHT = GAME_HEIGHT / TILE_HEIGHT;
53 54
@@ -62,7 +63,7 @@ public:
62 63
63 std::vector<Tile> tiles; 64 std::vector<Tile> tiles;
64 std::vector<bool> lighting; 65 std::vector<bool> lighting;
65 std::deque<std::tuple<int, int>> playerLocs; 66 int lightedSpots = 0;
66}; 67};
67 68
68int player_x = VIEW_WIDTH / 2; 69int player_x = VIEW_WIDTH / 2;
@@ -123,14 +124,11 @@ void render(
123 } 124 }
124 } 125 }
125 126
126
127 if (draw) 127 if (draw)
128 { 128 {
129 SDL_Rect rect{x*TILE_WIDTH, y*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT}; 129 SDL_Rect rect{x*TILE_WIDTH, y*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT};
130 SDL_RenderFillRect(ren, &rect); 130 SDL_RenderFillRect(ren, &rect);
131 } 131 }
132
133
134 } 132 }
135 } 133 }
136 134
@@ -190,17 +188,8 @@ void movePlayer(int x, int y, Map& map)
190 if (map.tiles[player_x+player_y*VIEW_WIDTH] == Tile::Floor) 188 if (map.tiles[player_x+player_y*VIEW_WIDTH] == Tile::Floor)
191 { 189 {
192 map.tiles[player_x+player_y*VIEW_WIDTH] = Tile::Dust; 190 map.tiles[player_x+player_y*VIEW_WIDTH] = Tile::Dust;
193 map.playerLocs.emplace_front(player_x, player_y);
194
195 if (map.playerLocs.size() > 5)
196 {
197 map.playerLocs.pop_back();
198 }
199 } 191 }
200 192
201
202
203
204 player_x = x; 193 player_x = x;
205 player_y = y; 194 player_y = y;
206 } 195 }
@@ -217,6 +206,7 @@ void setIfValid(Map& map, int x, int y, Tile val)
217void recalculateLighting(Map& map, fov_settings_type* fov) 206void recalculateLighting(Map& map, fov_settings_type* fov)
218{ 207{
219 map.lighting = std::vector<bool>(VIEW_WIDTH*VIEW_HEIGHT, false); 208 map.lighting = std::vector<bool>(VIEW_WIDTH*VIEW_HEIGHT, false);
209 map.lightedSpots = 0;
220 210
221 fov_settings_set_opacity_test_function( 211 fov_settings_set_opacity_test_function(
222 fov, 212 fov,
@@ -234,7 +224,12 @@ void recalculateLighting(Map& map, fov_settings_type* fov)
234 [] (void* map, int x, int y, int, int, void*) { 224 [] (void* map, int x, int y, int, int, void*) {
235 if ((x >= 0) && (x < VIEW_WIDTH) && (y >= 0) && (y < VIEW_HEIGHT)) 225 if ((x >= 0) && (x < VIEW_WIDTH) && (y >= 0) && (y < VIEW_HEIGHT))
236 { 226 {
237 static_cast<Map*>(map)->lighting[x+VIEW_WIDTH*y] = true; 227 Map& m = *static_cast<Map*>(map);
228 if (!m.lighting[x+VIEW_WIDTH*y])
229 {
230 m.lighting[x+VIEW_WIDTH*y] = true;
231 m.lightedSpots++;
232 }
238 } 233 }
239 }); 234 });
240 235
@@ -255,6 +250,31 @@ void recalculateLighting(Map& map, fov_settings_type* fov)
255 } 250 }
256} 251}
257 252
253void processKeys(Map& map)
254{
255 const Uint8* state = SDL_GetKeyboardState(NULL);
256
257 if (state[SDL_SCANCODE_UP])
258 {
259 movePlayer(player_x, player_y-1, map);
260 }
261
262 if (state[SDL_SCANCODE_DOWN])
263 {
264 movePlayer(player_x, player_y+1, map);
265 }
266
267 if (state[SDL_SCANCODE_LEFT])
268 {
269 movePlayer(player_x-1, player_y, map);
270 }
271
272 if (state[SDL_SCANCODE_RIGHT])
273 {
274 movePlayer(player_x+1, player_y, map);
275 }
276}
277
258int main(int, char**) 278int main(int, char**)
259{ 279{
260 std::random_device randomEngine; 280 std::random_device randomEngine;
@@ -286,14 +306,11 @@ int main(int, char**)
286 throw sdl_error(); 306 throw sdl_error();
287 } 307 }
288 308
289 //std::vector<Tile> tiles(VIEW_WIDTH*VIEW_HEIGHT, Tile::Floor);
290 //std::vector<bool> lighting(VIEW_WIDTH*VIEW_HEIGHT, false);
291 Map map; 309 Map map;
292 310
293 std::unique_ptr<fov_settings_type> fov(new fov_settings_type()); 311 std::unique_ptr<fov_settings_type> fov(new fov_settings_type());
294 fov_settings_init(fov.get()); 312 fov_settings_init(fov.get());
295 313
296
297 for (int y = 0; y < VIEW_HEIGHT; y++) 314 for (int y = 0; y < VIEW_HEIGHT; y++)
298 { 315 {
299 for (int x = 0; x < VIEW_WIDTH; x++) 316 for (int x = 0; x < VIEW_WIDTH; x++)
@@ -313,7 +330,6 @@ int main(int, char**)
313 SDL_Event e; 330 SDL_Event e;
314 while (!quit) 331 while (!quit)
315 { 332 {
316 //SDL_PumpEvents();
317 bool input = false; 333 bool input = false;
318 int presses = 0; 334 int presses = 0;
319 while (SDL_PollEvent(&e)) 335 while (SDL_PollEvent(&e))
@@ -327,21 +343,24 @@ int main(int, char**)
327 343
328 switch (e.key.keysym.sym) 344 switch (e.key.keysym.sym)
329 { 345 {
346 case SDLK_ESCAPE:
347 {
348 quit = true;
349 break;
350 }
351
330 case SDLK_SPACE: 352 case SDLK_SPACE:
331 { 353 {
332 input = true; 354 input = true;
333 355
334 setIfValid(map, player_x-1, player_y , Tile::Floor); 356 std::deque<std::tuple<int, int>> lamps;
335 setIfValid(map, player_x+1, player_y , Tile::Floor); 357 lamps.emplace_back(player_x, player_y);
358
336 setIfValid(map, player_x , player_y , Tile::Lamp); 359 setIfValid(map, player_x , player_y , Tile::Lamp);
337 setIfValid(map, player_x , player_y-1, Tile::Floor);
338 setIfValid(map, player_x , player_y+1, Tile::Floor);
339 360
340 auto locs = map.playerLocs; 361 for (int i = 0; i < 5; i++)
341 while (!locs.empty())
342 { 362 {
343 movePlayer(std::get<0>(locs.front()), std::get<1>(locs.front()), map); 363 processKeys(map);
344 locs.pop_front();
345 364
346 tick( 365 tick(
347 map, 366 map,
@@ -354,152 +373,11 @@ int main(int, char**)
354 SDL_Delay(30); 373 SDL_Delay(30);
355 } 374 }
356 375
357 break; 376 while (!lamps.empty())
358 }
359 }
360 } else if (e.type == SDL_KEYUP)
361 {
362 presses++;
363 }
364 }
365
366 if (presses > 0)
367 {
368 for (int y = 0; y < VIEW_HEIGHT; y++)
369 {
370 for (int x = 0; x < VIEW_WIDTH; x++)
371 {
372 if (map.tiles[x+y*VIEW_WIDTH] == Tile::Dust)
373 {
374 map.tiles[x+y*VIEW_WIDTH] = Tile::Floor;
375 }
376 }
377 }
378 }
379
380 const Uint8* state = SDL_GetKeyboardState(NULL);
381
382 for (int i = 0; i < presses; i++)
383 {
384 //switch (e.key.keysym.sym)
385 {
386 //case SDLK_UP:
387 if (state[SDL_SCANCODE_UP])
388 {
389 movePlayer(player_x, player_y-1, map);
390 input = true;
391 //break;
392 }
393
394 //case SDLK_DOWN:
395 if (state[SDL_SCANCODE_DOWN])
396 {
397 movePlayer(player_x, player_y+1, map);
398 input = true;
399 //break;
400 }
401
402 //case SDLK_LEFT:
403 if (state[SDL_SCANCODE_LEFT])
404 {
405 movePlayer(player_x-1, player_y, map);
406 input = true;
407 //break;
408 }
409
410 //case SDLK_RIGHT:
411 if (state[SDL_SCANCODE_RIGHT])
412 {
413 movePlayer(player_x+1, player_y, map);
414 input = true;
415 //break;
416 }
417
418
419 }
420
421 if (input)
422 {
423 //render(ren.get(), tiles, false);
424 //SDL_Delay(1);
425 }
426
427 //}
428 }
429
430 bool checkForDust = true;
431
432 while (checkForDust)
433 {
434 checkForDust = false;
435
436 for (int y = 0; y < VIEW_HEIGHT; y++)
437 {
438 for (int x = 0; x < VIEW_WIDTH; x++)
439 {
440 if (map.tiles[x+y*VIEW_WIDTH] == Tile::Lamp)
441 {
442 int count = 0;
443
444 incrementIfSet(map, count, x-1, y , VIEW_WIDTH, VIEW_HEIGHT, Tile::Dust);
445 incrementIfSet(map, count, x+1, y , VIEW_WIDTH, VIEW_HEIGHT, Tile::Dust);
446 incrementIfSet(map, count, x , y-1, VIEW_WIDTH, VIEW_HEIGHT, Tile::Dust);
447 incrementIfSet(map, count, x , y+1, VIEW_WIDTH, VIEW_HEIGHT, Tile::Dust);
448
449 if (count > 0)
450 { 377 {
451 checkForDust = true; 378 int px, py;
452 379 std::tie(px, py) = lamps.front();
453 map.tiles[x+y*VIEW_WIDTH] = Tile::Dust; 380 lamps.pop_front();
454
455 /*for (int i = 0; i < 4; i++)
456 {
457 tick(
458 map,
459 x - 7,
460 y - 7,
461 x + 8,
462 y + 8);
463
464 for (int l = 0; l < (i*2+1); l++)
465 {
466 int px = x - i + l;
467 int py = y - i + l;
468
469 auto fillInDust = [&] (int sx, int sy) {
470 if (sx > 0 && sx < VIEW_WIDTH &&
471 sy > 0 && sy < VIEW_HEIGHT &&
472 map.tiles[sx+sy*VIEW_WIDTH] == Tile::Floor &&
473 !(player_y == sy && player_x == sx))
474 {
475 map.tiles[sx+sy*VIEW_WIDTH] = Tile::Dust;
476 }
477 };
478
479 fillInDust(px , y - i);
480 fillInDust(px , y + i);
481 fillInDust(x - i, py );
482 fillInDust(x + i, py );
483 }
484
485 render(ren.get(), map, false);
486 SDL_Delay(30);
487 }*/
488
489
490 /*
491
492 for (int py = std::max(0, y - 7); py < std::min(VIEW_HEIGHT, y + 8); py++)
493 {
494 for (int px = std::max(0, x - 7); px < std::min(VIEW_WIDTH, x + 8); px++)
495 {
496 if ((map.tiles[px+py*VIEW_WIDTH] == Tile::Floor) &&
497 !(player_y == py && player_x == px))
498 {
499 map.tiles[px+py*VIEW_WIDTH] = Tile::Dust;
500 }
501 }
502 }*/
503 381
504 std::unique_ptr<fov_settings_type> dusty(new fov_settings_type); 382 std::unique_ptr<fov_settings_type> dusty(new fov_settings_type);
505 fov_settings_set_opacity_test_function( 383 fov_settings_set_opacity_test_function(
@@ -515,32 +393,65 @@ int main(int, char**)
515 393
516 fov_settings_set_apply_lighting_function( 394 fov_settings_set_apply_lighting_function(
517 dusty.get(), 395 dusty.get(),
518 [] (void* map, int x, int y, int, int, void*) { 396 [] (void* map, int x, int y, int, int, void* source) {
397 Map& m = *static_cast<Map*>(map);
398 auto& lamps = *static_cast<std::deque<std::pair<int, int>>*>(source);
399
519 if ((x >= 0) && (x < VIEW_WIDTH) && 400 if ((x >= 0) && (x < VIEW_WIDTH) &&
520 (y >= 0) && (y < VIEW_HEIGHT) && 401 (y >= 0) && (y < VIEW_HEIGHT))
521 (static_cast<Map*>(map)->tiles[x+VIEW_WIDTH*y] == Tile::Floor))
522 { 402 {
523 static_cast<Map*>(map)->tiles[x+VIEW_WIDTH*y] = Tile::Dust; 403 if (m.tiles[x+VIEW_WIDTH*y] == Tile::Floor)
404 {
405 m.tiles[x+VIEW_WIDTH*y] = Tile::Dust;
406 } else if (m.tiles[x+VIEW_WIDTH*y] == Tile::Lamp)
407 {
408 m.tiles[x+VIEW_WIDTH*y] = Tile::Dust;
409 lamps.emplace_back(x, y);
410 }
524 } 411 }
525 }); 412 });
526 413
527 fov_circle(dusty.get(), static_cast<void*>(&map), nullptr, x, y, 8); 414 fov_circle(dusty.get(), static_cast<void*>(&map), static_cast<void*>(&lamps), px, py, 8);
528 415
529 render(ren.get(), map, false); 416 render(ren.get(), map, false);
530 SDL_Delay(50); 417 SDL_Delay(50);
531 } 418 }
419
420 break;
532 } 421 }
533 } 422 }
423 } else if (e.type == SDL_KEYUP)
424 {
425 presses++;
534 } 426 }
535 } 427 }
536 428
429 if (presses > 0)
430 {
431 for (int y = 0; y < VIEW_HEIGHT; y++)
432 {
433 for (int x = 0; x < VIEW_WIDTH; x++)
434 {
435 if (map.tiles[x+y*VIEW_WIDTH] == Tile::Dust)
436 {
437 map.tiles[x+y*VIEW_WIDTH] = Tile::Floor;
438 }
439 }
440 }
441 }
442
443 for (int i = 0; i < presses; i++)
444 {
445 processKeys(map);
446 }
537 447
538 recalculateLighting(map, fov.get()); 448 recalculateLighting(map, fov.get());
539 render(ren.get(), map, true); 449 render(ren.get(), map, true);
540 SDL_Delay(10); 450 SDL_Delay(10);
541 } 451 }
542 } catch (const sdl_error&) 452 } catch (const sdl_error& ex)
543 { 453 {
454 std::cout << "SDL error (" << ex.what() << ")" << std::endl;
544 } 455 }
545 456
546 SDL_Quit(); 457 SDL_Quit();