summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.cpp269
1 files changed, 243 insertions, 26 deletions
diff --git a/src/main.cpp b/src/main.cpp index 2daf153..dacc646 100644 --- a/src/main.cpp +++ b/src/main.cpp
@@ -1,4 +1,5 @@
1#include <SDL.h> 1#include <SDL.h>
2#include <SDL_image.h>
2#include <stdexcept> 3#include <stdexcept>
3#include <memory> 4#include <memory>
4#include <vector> 5#include <vector>
@@ -19,6 +20,14 @@ public:
19 } 20 }
20}; 21};
21 22
23class img_error : public std::logic_error {
24public:
25
26 img_error() : std::logic_error(IMG_GetError())
27 {
28 }
29};
30
22class window_deleter { 31class window_deleter {
23public: 32public:
24 33
@@ -41,6 +50,17 @@ public:
41 50
42using renderer_ptr = std::unique_ptr<SDL_Renderer, renderer_deleter>; 51using renderer_ptr = std::unique_ptr<SDL_Renderer, renderer_deleter>;
43 52
53class surface_deleter {
54public:
55
56 void operator()(SDL_Surface* ptr)
57 {
58 SDL_FreeSurface(ptr);
59 }
60};
61
62using surface_ptr = std::unique_ptr<SDL_Surface, surface_deleter>;
63
44class texture_deleter { 64class texture_deleter {
45public: 65public:
46 66
@@ -59,6 +79,13 @@ enum class Tile {
59 Lamp 79 Lamp
60}; 80};
61 81
82enum class Source {
83 None,
84 Dust,
85 Lamp,
86 Player
87};
88
62enum class LoseState { 89enum class LoseState {
63 None, 90 None,
64 PoppingLamps, 91 PoppingLamps,
@@ -100,6 +127,9 @@ struct MapData {
100 bool wasLit = false; 127 bool wasLit = false;
101 double visibility = 0.0; 128 double visibility = 0.0;
102 size_t dustLife = 0; 129 size_t dustLife = 0;
130 Source lightType = Source::None;
131 int lightRadius = 0;
132 std::set<coord> litTiles;
103}; 133};
104 134
105class Game { 135class Game {
@@ -142,6 +172,83 @@ void render(
142 const Game& game, 172 const Game& game,
143 bool drawDark = true) 173 bool drawDark = true)
144{ 174{
175 texture_ptr origFade;
176 {
177 surface_ptr pfs(IMG_Load("../res/lighting.png"));
178 if (!pfs)
179 {
180 throw img_error();
181 }
182
183 origFade = texture_ptr(SDL_CreateTextureFromSurface(ren, pfs.get()));
184 }
185
186 SDL_SetTextureBlendMode(origFade.get(), SDL_BLENDMODE_BLEND);
187
188 texture_ptr playerFade(
189 SDL_CreateTexture(
190 ren,
191 SDL_PIXELFORMAT_RGBA4444,
192 SDL_TEXTUREACCESS_TARGET,
193 144,
194 144));
195
196 if (!playerFade)
197 {
198 throw sdl_error();
199 }
200
201 SDL_SetRenderTarget(ren, playerFade.get());
202 SDL_SetRenderDrawColor(ren, 0, 0, 0, 255);
203 SDL_RenderClear(ren);
204 SDL_RenderCopy(ren, origFade.get(), nullptr, nullptr);
205
206 texture_ptr lampFade(
207 SDL_CreateTexture(
208 ren,
209 SDL_PIXELFORMAT_RGBA4444,
210 SDL_TEXTUREACCESS_TARGET,
211 144,
212 144));
213
214 if (!lampFade)
215 {
216 throw sdl_error();
217 }
218
219 SDL_SetRenderTarget(ren, lampFade.get());
220
221 SDL_SetRenderDrawColor(ren, 0, 0, 0, 255);
222 SDL_RenderClear(ren);
223 SDL_RenderCopy(ren, origFade.get(), nullptr, nullptr);
224
225 SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_MOD);
226 SDL_SetRenderDrawColor(ren, 255, 204, 58, 255);
227 SDL_RenderFillRect(ren, nullptr);
228
229 texture_ptr dustFade(
230 SDL_CreateTexture(
231 ren,
232 SDL_PIXELFORMAT_RGBA4444,
233 SDL_TEXTUREACCESS_TARGET,
234 144,
235 144));
236
237 if (!dustFade)
238 {
239 throw sdl_error();
240 }
241
242 SDL_SetRenderTarget(ren, dustFade.get());
243
244 SDL_SetRenderDrawColor(ren, 0, 0, 0, 255);
245 SDL_RenderClear(ren);
246 SDL_RenderCopy(ren, origFade.get(), nullptr, nullptr);
247
248 SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_MOD);
249 SDL_SetRenderDrawColor(ren, 255, 150, 255, 255);
250 SDL_RenderFillRect(ren, nullptr);
251
145 texture_ptr canvas( 252 texture_ptr canvas(
146 SDL_CreateTexture( 253 SDL_CreateTexture(
147 ren, 254 ren,
@@ -156,7 +263,7 @@ void render(
156 } 263 }
157 264
158 SDL_SetRenderTarget(ren, canvas.get()); 265 SDL_SetRenderTarget(ren, canvas.get());
159 266 SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_NONE);
160 SDL_SetRenderDrawColor(ren, rand() % 255, rand() % 255, rand() % 255, 255); 267 SDL_SetRenderDrawColor(ren, rand() % 255, rand() % 255, rand() % 255, 255);
161 SDL_RenderClear(ren); 268 SDL_RenderClear(ren);
162 269
@@ -169,38 +276,40 @@ void render(
169 if ((game.player_x == x && game.player_y == y) && game.renderPlayer) 276 if ((game.player_x == x && game.player_y == y) && game.renderPlayer)
170 { 277 {
171 SDL_SetRenderDrawColor(ren, 255, 255, 0, 255); 278 SDL_SetRenderDrawColor(ren, 255, 255, 0, 255);
172 } else if (!game.map.at(x,y).lit) 279 /*} else if (!game.map.at(x,y).lit)
173 { 280 {
174 if (drawDark) 281 if (drawDark)
175 { 282 {
176 SDL_SetRenderDrawColor(ren, 40, 40, 40, 255); 283 SDL_SetRenderDrawColor(ren, 40, 40, 40, 255);
177 } else { 284 } else {
178 draw = false; 285 draw = false;
179 } 286 }*/
180 } else { 287 } else {
288 int alpha = 255;
289
181 switch (game.map.at(x,y).tile) 290 switch (game.map.at(x,y).tile)
182 { 291 {
183 case Tile::Floor: 292 case Tile::Floor:
184 { 293 {
185 SDL_SetRenderDrawColor(ren, 210, 210, 210, 255); 294 SDL_SetRenderDrawColor(ren, 210, 210, 210, alpha);
186 break; 295 break;
187 } 296 }
188 297
189 case Tile::Wall: 298 case Tile::Wall:
190 { 299 {
191 SDL_SetRenderDrawColor(ren, 100, 100, 100, 255); 300 SDL_SetRenderDrawColor(ren, 100, 100, 100, alpha);
192 break; 301 break;
193 } 302 }
194 303
195 case Tile::Dust: 304 case Tile::Dust:
196 { 305 {
197 SDL_SetRenderDrawColor(ren, 128, 40, 255, 255); 306 SDL_SetRenderDrawColor(ren, 128, 40, 255, alpha);
198 break; 307 break;
199 } 308 }
200 309
201 case Tile::Lamp: 310 case Tile::Lamp:
202 { 311 {
203 SDL_SetRenderDrawColor(ren, 0, 255, 255, 255); 312 SDL_SetRenderDrawColor(ren, 0, 255, 255, alpha);
204 break; 313 break;
205 } 314 }
206 } 315 }
@@ -214,15 +323,97 @@ void render(
214 TILE_WIDTH, 323 TILE_WIDTH,
215 TILE_HEIGHT}; 324 TILE_HEIGHT};
216 325
217 SDL_RenderFillRect(ren, &rect); 326 //SDL_RenderFillRect(ren, &rect);
218 327
219 int alpha = (1.0 - game.map.at(x,y).visibility) * 255; 328 //int alpha = (1.0 - game.map.at(x,y).visibility) * 255;
220 SDL_SetRenderDrawColor(ren, 40, 40, 40, alpha); 329 //SDL_SetRenderDrawColor(ren, 40, 40, 40, 255);
221 SDL_RenderFillRect(ren, &rect); 330 SDL_RenderFillRect(ren, &rect);
222 } 331 }
223 } 332 }
224 } 333 }
225 334
335 texture_ptr mask(
336 SDL_CreateTexture(
337 ren,
338 SDL_PIXELFORMAT_RGBA8888,
339 SDL_TEXTUREACCESS_TARGET,
340 TILE_WIDTH * game.map.getWidth(),
341 TILE_HEIGHT * game.map.getHeight()));
342
343 if (!mask)
344 {
345 throw sdl_error();
346 }
347
348 SDL_SetRenderTarget(ren, mask.get());
349 SDL_SetRenderDrawColor(ren, 0, 0, 0, 255);
350 SDL_RenderClear(ren);
351
352 for (int y = game.map.getTop(); y < game.map.getBottom(); y++)
353 {
354 for (int x = game.map.getLeft(); x < game.map.getRight(); x++)
355 {
356 if (game.map.at(x,y).lightType != Source::None)
357 {
358 texture_ptr sourceMask(
359 SDL_CreateTexture(
360 ren,
361 SDL_PIXELFORMAT_RGBA8888,
362 SDL_TEXTUREACCESS_TARGET,
363 TILE_WIDTH * game.map.getWidth(),
364 TILE_HEIGHT * game.map.getHeight()));
365
366 if (!sourceMask)
367 {
368 throw sdl_error();
369 }
370
371 SDL_SetRenderTarget(ren, sourceMask.get());
372 SDL_SetRenderDrawColor(ren, 0, 0, 0, 255);
373 SDL_RenderClear(ren);
374
375 SDL_SetRenderDrawColor(ren, 255, 255, 255, 255);
376
377 for (const coord& xy : game.map.at(x,y).litTiles)
378 {
379 SDL_Rect rect {
380 game.map.getTrueX(std::get<0>(xy)) * TILE_WIDTH,
381 game.map.getTrueY(std::get<1>(xy)) * TILE_HEIGHT,
382 TILE_WIDTH,
383 TILE_HEIGHT};
384
385 SDL_RenderFillRect(ren, &rect);
386 }
387
388 SDL_Rect fadeRect {
389 (game.map.getTrueX(x) - game.map.at(x,y).lightRadius) * TILE_WIDTH,
390 (game.map.getTrueY(y) - game.map.at(x,y).lightRadius) * TILE_HEIGHT,
391 (game.map.at(x,y).lightRadius * 2 + 1) * TILE_WIDTH,
392 (game.map.at(x,y).lightRadius * 2 + 1) * TILE_HEIGHT};
393
394 if (game.map.at(x,y).lightType == Source::Lamp)
395 {
396 SDL_SetTextureBlendMode(lampFade.get(), SDL_BLENDMODE_MOD);
397 SDL_RenderCopy(ren, lampFade.get(), nullptr, &fadeRect);
398 } else if (game.map.at(x,y).lightType == Source::Player) {
399 SDL_SetTextureBlendMode(playerFade.get(), SDL_BLENDMODE_MOD);
400 SDL_RenderCopy(ren, playerFade.get(), nullptr, &fadeRect);
401 } else if (game.map.at(x,y).lightType == Source::Dust) {
402 SDL_SetTextureBlendMode(dustFade.get(), SDL_BLENDMODE_MOD);
403 SDL_RenderCopy(ren, dustFade.get(), nullptr, &fadeRect);
404 }
405
406 SDL_SetRenderTarget(ren, mask.get());
407 SDL_SetTextureBlendMode(sourceMask.get(), SDL_BLENDMODE_ADD);
408 SDL_RenderCopy(ren, sourceMask.get(), nullptr, nullptr);
409 }
410 }
411 }
412
413 SDL_SetRenderTarget(ren, canvas.get());
414 SDL_SetTextureBlendMode(mask.get(), SDL_BLENDMODE_MOD);
415 SDL_RenderCopy(ren, mask.get(), nullptr, nullptr);
416
226 SDL_SetRenderTarget(ren, nullptr); 417 SDL_SetRenderTarget(ren, nullptr);
227 418
228 if (!game.zooming) 419 if (!game.zooming)
@@ -346,6 +537,7 @@ void recalculateLighting(Game& game, fov_settings_type* fov)
346 md.wasLit = md.lit; 537 md.wasLit = md.lit;
347 md.lit = false; 538 md.lit = false;
348 md.visibility = 0.0; 539 md.visibility = 0.0;
540 md.litTiles.clear();
349 } 541 }
350 542
351 fov_settings_set_opacity_test_function( 543 fov_settings_set_opacity_test_function(
@@ -363,7 +555,8 @@ void recalculateLighting(Game& game, fov_settings_type* fov)
363 555
364 if (game.map.inBounds(x, y)) 556 if (game.map.inBounds(x, y))
365 { 557 {
366 double lightRadius = static_cast<double>(*static_cast<int*>(source)); 558 MapData& sourceData = *static_cast<MapData*>(source);
559 double lightRadius = static_cast<double>(sourceData.lightRadius);
367 560
368 if (!game.map.at(x,y).lit) 561 if (!game.map.at(x,y).lit)
369 { 562 {
@@ -372,13 +565,21 @@ void recalculateLighting(Game& game, fov_settings_type* fov)
372 565
373 game.map.at(x,y).lit = true; 566 game.map.at(x,y).lit = true;
374 567
375 game.map.at(x,y).visibility = std::max( 568 /*game.map.at(x,y).visibility = std::max(
376 game.map.at(x,y).visibility, 569 game.map.at(x,y).visibility,
377 std::pow( 570 std::pow(
378 std::max( 571 std::max(
379 0.0, 572 0.0,
380 1.0 - std::sqrt(dx * dx + dy * dy) / lightRadius), 573 1.0 - std::sqrt(dx * dx + dy * dy) / lightRadius),
381 1.0/3.0)); 574 1.0/3.0));*/
575
576 sourceData.litTiles.emplace(x,y);
577
578 //Source ls = *static_cast<Source*>(source);
579 //if (static_cast<size_t>(ls) > static_cast<size_t>(m.lightSource[x+VIEW_WIDTH*y]))
580 {
581 //m.lightSource[x+VIEW_WIDTH*y] = ls;
582 }
382 } 583 }
383 }); 584 });
384 585
@@ -386,25 +587,35 @@ void recalculateLighting(Game& game, fov_settings_type* fov)
386 { 587 {
387 for (int x = game.map.getLeft(); x < game.map.getRight(); x++) 588 for (int x = game.map.getLeft(); x < game.map.getRight(); x++)
388 { 589 {
389 if ((game.player_x == x && game.player_y == y && game.renderPlayer) || 590 Source ls = Source::None;
390 game.map.at(x,y).tile == Tile::Dust || 591 int lightRadius;
391 game.map.at(x,y).tile == Tile::Lamp) 592
593 if (game.renderPlayer && game.player_x == x && game.player_y == y)
594 {
595 ls = Source::Player;
596 lightRadius = RADIUS;
597 } else if (game.map.at(x,y).tile == Tile::Dust)
392 { 598 {
393 int lightRadius; 599 ls = Source::Dust;
600 lightRadius = 2;
601 } else if (game.map.at(x,y).tile == Tile::Lamp)
602 {
603 ls = Source::Lamp;
604 lightRadius = RADIUS;
605 }
394 606
395 if ((game.player_x == x && game.player_y == y && game.renderPlayer) || 607 game.map.at(x,y).lightType = ls;
396 game.map.at(x,y).tile == Tile::Lamp) 608 //game.map.at(x,y).litTiles.clear();
397 { 609
398 lightRadius = RADIUS; 610 if (ls != Source::None)
399 } else if (game.map.at(x,y).tile == Tile::Dust) 611 {
400 { 612 game.map.at(x,y).lightRadius = lightRadius;
401 lightRadius = 2; 613 game.map.at(x,y).litTiles.emplace(x,y);
402 }
403 614
404 fov_circle( 615 fov_circle(
405 fov, 616 fov,
406 static_cast<void*>(&game), 617 static_cast<void*>(&game),
407 static_cast<void*>(&lightRadius), 618 static_cast<void*>(&game.map.at(x,y)),
408 x, 619 x,
409 y, 620 y,
410 lightRadius); 621 lightRadius);
@@ -611,6 +822,11 @@ int main(int, char**)
611 throw sdl_error(); 822 throw sdl_error();
612 } 823 }
613 824
825 if (IMG_Init(IMG_INIT_PNG) != IMG_INIT_PNG)
826 {
827 throw img_error();
828 }
829
614 try 830 try
615 { 831 {
616 window_ptr win( 832 window_ptr win(
@@ -916,6 +1132,7 @@ int main(int, char**)
916 std::cout << "SDL error (" << ex.what() << ")" << std::endl; 1132 std::cout << "SDL error (" << ex.what() << ")" << std::endl;
917 } 1133 }
918 1134
1135 IMG_Quit();
919 SDL_Quit(); 1136 SDL_Quit();
920 1137
921 return 0; 1138 return 0;