summary refs log tree commit diff stats
path: root/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp191
1 files changed, 171 insertions, 20 deletions
diff --git a/src/main.cpp b/src/main.cpp index 2840439..c02fdd5 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>
@@ -15,6 +16,14 @@ public:
15 } 16 }
16}; 17};
17 18
19class img_error : public std::logic_error {
20public:
21
22 img_error() : std::logic_error(IMG_GetError())
23 {
24 }
25};
26
18class window_deleter { 27class window_deleter {
19public: 28public:
20 29
@@ -37,6 +46,28 @@ public:
37 46
38using renderer_ptr = std::unique_ptr<SDL_Renderer, renderer_deleter>; 47using renderer_ptr = std::unique_ptr<SDL_Renderer, renderer_deleter>;
39 48
49class surface_deleter {
50public:
51
52 void operator()(SDL_Surface* ptr)
53 {
54 SDL_FreeSurface(ptr);
55 }
56};
57
58using surface_ptr = std::unique_ptr<SDL_Surface, surface_deleter>;
59
60class texture_deleter {
61public:
62
63 void operator()(SDL_Texture* ptr)
64 {
65 SDL_DestroyTexture(ptr);
66 }
67};
68
69using texture_ptr = std::unique_ptr<SDL_Texture, texture_deleter>;
70
40enum class Tile { 71enum class Tile {
41 Floor, 72 Floor,
42 Wall, 73 Wall,
@@ -44,6 +75,13 @@ enum class Tile {
44 Lamp 75 Lamp
45}; 76};
46 77
78enum class Source {
79 None,
80 Dust,
81 Lamp,
82 Player
83};
84
47const int GAME_WIDTH = 640*2; 85const int GAME_WIDTH = 640*2;
48const int GAME_HEIGHT = 480*2; 86const int GAME_HEIGHT = 480*2;
49const int TILE_WIDTH = 8*2; 87const int TILE_WIDTH = 8*2;
@@ -65,7 +103,8 @@ public:
65 Map() : 103 Map() :
66 tiles(VIEW_WIDTH*VIEW_HEIGHT, Tile::Floor), 104 tiles(VIEW_WIDTH*VIEW_HEIGHT, Tile::Floor),
67 lighting(VIEW_WIDTH*VIEW_HEIGHT, false), 105 lighting(VIEW_WIDTH*VIEW_HEIGHT, false),
68 lightStrength(VIEW_WIDTH*VIEW_HEIGHT, 0.0) 106 lightStrength(VIEW_WIDTH*VIEW_HEIGHT, 0.0),
107 lightSource(VIEW_WIDTH*VIEW_HEIGHT, Source::None)
69 { 108 {
70 } 109 }
71 110
@@ -73,6 +112,7 @@ public:
73 std::vector<bool> lighting; 112 std::vector<bool> lighting;
74 std::vector<bool> oldLighting; 113 std::vector<bool> oldLighting;
75 std::vector<double> lightStrength; 114 std::vector<double> lightStrength;
115 std::vector<Source> lightSource;
76 int lightedSpots = 0; 116 int lightedSpots = 0;
77}; 117};
78 118
@@ -84,7 +124,53 @@ void render(
84 const Map& map, 124 const Map& map,
85 bool drawDark = true) 125 bool drawDark = true)
86{ 126{
87 SDL_SetRenderDrawColor(ren, rand() % 255, rand() % 255, rand() % 255, 255); 127 texture_ptr playerFade;
128 {
129 surface_ptr pfs(IMG_Load("../res/lighting.png"));
130 if (!pfs)
131 {
132 throw img_error();
133 }
134
135 playerFade = texture_ptr(SDL_CreateTextureFromSurface(ren, pfs.get()));
136 }
137
138 texture_ptr lampFade(
139 SDL_CreateTexture(
140 ren,
141 SDL_PIXELFORMAT_RGBA4444,
142 SDL_TEXTUREACCESS_TARGET,
143 144,
144 144));
145
146 {
147 SDL_SetRenderTarget(ren, lampFade.get());
148
149 SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_NONE);
150 SDL_SetRenderDrawColor(ren, 255, 255, 255, 0);
151 SDL_RenderFillRect(ren, nullptr);
152
153 SDL_RenderCopy(ren, playerFade.get(), nullptr, nullptr);
154
155 SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_MOD);
156 SDL_SetRenderDrawColor(ren, 255, 180, 0, 255);
157 SDL_RenderFillRect(ren, nullptr);
158
159 SDL_SetRenderTarget(ren, nullptr);
160 }
161
162 int darkR = 40;
163 int darkG = 40;
164 int darkB = 40;
165
166 if (!drawDark)
167 {
168 darkR = rand() % 255;
169 darkG = rand() % 255;
170 darkB = rand() % 255;
171 }
172
173 SDL_SetRenderDrawColor(ren, darkR, darkG, darkB, 255);
88 SDL_RenderClear(ren); 174 SDL_RenderClear(ren);
89 175
90 for (int y = 0; y < VIEW_HEIGHT; y++) 176 for (int y = 0; y < VIEW_HEIGHT; y++)
@@ -98,36 +184,40 @@ void render(
98 SDL_SetRenderDrawColor(ren, 255, 255, 0, 255); 184 SDL_SetRenderDrawColor(ren, 255, 255, 0, 255);
99 } else if (!map.lighting.at(x+VIEW_WIDTH*y)) 185 } else if (!map.lighting.at(x+VIEW_WIDTH*y))
100 { 186 {
101 if (drawDark) 187 /*if (drawDark)
102 { 188 {
103 SDL_SetRenderDrawColor(ren, 40, 40, 40, 255); 189 SDL_SetRenderDrawColor(ren, 40, 40, 40, 255);
104 } else { 190 } else {
105 draw = false; 191 draw = false;
106 } 192 }*/
193 draw = false;
107 } else { 194 } else {
195 int alpha = map.lightStrength.at(x+y*VIEW_WIDTH) * 255;
196 alpha = 255;
197
108 switch (map.tiles.at(x+y*VIEW_WIDTH)) 198 switch (map.tiles.at(x+y*VIEW_WIDTH))
109 { 199 {
110 case Tile::Floor: 200 case Tile::Floor:
111 { 201 {
112 SDL_SetRenderDrawColor(ren, 210, 210, 210, 255); 202 SDL_SetRenderDrawColor(ren, 210, 210, 210, alpha);
113 break; 203 break;
114 } 204 }
115 205
116 case Tile::Wall: 206 case Tile::Wall:
117 { 207 {
118 SDL_SetRenderDrawColor(ren, 100, 100, 100, 255); 208 SDL_SetRenderDrawColor(ren, 100, 100, 100, alpha);
119 break; 209 break;
120 } 210 }
121 211
122 case Tile::Dust: 212 case Tile::Dust:
123 { 213 {
124 SDL_SetRenderDrawColor(ren, 128, 40, 255, 255); 214 SDL_SetRenderDrawColor(ren, 128, 40, 255, alpha);
125 break; 215 break;
126 } 216 }
127 217
128 case Tile::Lamp: 218 case Tile::Lamp:
129 { 219 {
130 SDL_SetRenderDrawColor(ren, 0, 255, 255, 255); 220 SDL_SetRenderDrawColor(ren, 0, 255, 255, alpha);
131 break; 221 break;
132 } 222 }
133 } 223 }
@@ -136,10 +226,53 @@ void render(
136 if (draw) 226 if (draw)
137 { 227 {
138 SDL_Rect rect{x*TILE_WIDTH, y*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT}; 228 SDL_Rect rect{x*TILE_WIDTH, y*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT};
229
230 SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_BLEND);
139 SDL_RenderFillRect(ren, &rect); 231 SDL_RenderFillRect(ren, &rect);
140 232
141 int alpha = (1.0 - map.lightStrength.at(x+y*VIEW_WIDTH)) * 255; 233
142 SDL_SetRenderDrawColor(ren, 40, 40, 40, alpha); 234 }
235 }
236 }
237
238 for (int y = 0; y < VIEW_HEIGHT; y++)
239 {
240 for (int x = 0; x < VIEW_WIDTH; x++)
241 {
242 if (map.lightSource.at(x+VIEW_WIDTH*y) != Source::None)
243 {
244 SDL_Rect fadeRect{x*TILE_WIDTH + (TILE_WIDTH/2) - (144/2), y*TILE_HEIGHT + (TILE_HEIGHT/2) - (144/2), 144, 144};
245 if (map.lightSource.at(x+VIEW_WIDTH*y) == Source::Lamp)
246 {
247 //SDL_SetTextureBlendMode(lampFade.get(), SDL_BLENDMODE_MOD);
248 SDL_RenderCopy(ren, lampFade.get(), nullptr, &fadeRect);
249 //SDL_SetRenderDrawColor(ren, 255, 180, 0, 50);
250 //SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_BLEND);
251 //SDL_RenderFillRect(ren, &rect);
252 } else if (map.lightSource.at(x+VIEW_WIDTH*y) == Source::Player)
253 {
254 //SDL_SetTextureBlendMode(playerFade.get(), SDL_BLENDMODE_MOD);
255 SDL_RenderCopy(ren, playerFade.get(), nullptr, &fadeRect);
256 }
257
258 /*SDL_SetRenderDrawColor(ren, 40, 40, 40, alpha);
259 SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_BLEND);
260 SDL_RenderFillRect(ren, &rect);*/
261 }
262 }
263 }
264
265 SDL_SetRenderDrawBlendMode(ren, SDL_BLENDMODE_NONE);
266 SDL_SetRenderDrawColor(ren, darkR, darkG, darkB, 255);
267
268 for (int y = 0; y < VIEW_HEIGHT; y++)
269 {
270 for (int x = 0; x < VIEW_WIDTH; x++)
271 {
272 if (!map.lighting.at(x+VIEW_WIDTH*y))
273 {
274 SDL_Rect rect{x*TILE_WIDTH, y*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT};
275
143 SDL_RenderFillRect(ren, &rect); 276 SDL_RenderFillRect(ren, &rect);
144 } 277 }
145 } 278 }
@@ -227,6 +360,7 @@ void recalculateLighting(Map& map, fov_settings_type* fov)
227 map.lighting = std::vector<bool>(VIEW_WIDTH*VIEW_HEIGHT, false); 360 map.lighting = std::vector<bool>(VIEW_WIDTH*VIEW_HEIGHT, false);
228 map.lightStrength = std::vector<double>(VIEW_WIDTH*VIEW_HEIGHT, 0.0); 361 map.lightStrength = std::vector<double>(VIEW_WIDTH*VIEW_HEIGHT, 0.0);
229 map.lightedSpots = 0; 362 map.lightedSpots = 0;
363 map.lightSource = std::vector<Source>(VIEW_WIDTH*VIEW_HEIGHT, Source::None);
230 364
231 fov_settings_set_opacity_test_function( 365 fov_settings_set_opacity_test_function(
232 fov, 366 fov,
@@ -241,7 +375,7 @@ void recalculateLighting(Map& map, fov_settings_type* fov)
241 375
242 fov_settings_set_apply_lighting_function( 376 fov_settings_set_apply_lighting_function(
243 fov, 377 fov,
244 [] (void* map, int x, int y, int dx, int dy, void*) { 378 [] (void* map, int x, int y, int dx, int dy, void* source) {
245 if ((x >= 0) && (x < VIEW_WIDTH) && (y >= 0) && (y < VIEW_HEIGHT)) 379 if ((x >= 0) && (x < VIEW_WIDTH) && (y >= 0) && (y < VIEW_HEIGHT))
246 { 380 {
247 Map& m = *static_cast<Map*>(map); 381 Map& m = *static_cast<Map*>(map);
@@ -259,6 +393,12 @@ void recalculateLighting(Map& map, fov_settings_type* fov)
259 0.0, 393 0.0,
260 1.0 - std::sqrt(dx * dx + dy * dy) / static_cast<double>(RADIUS)), 394 1.0 - std::sqrt(dx * dx + dy * dy) / static_cast<double>(RADIUS)),
261 1.0/3.0)); 395 1.0/3.0));
396
397 Source ls = *static_cast<Source*>(source);
398 if (static_cast<size_t>(ls) > static_cast<size_t>(m.lightSource[x+VIEW_WIDTH*y]))
399 {
400 //m.lightSource[x+VIEW_WIDTH*y] = ls;
401 }
262 } 402 }
263 }); 403 });
264 404
@@ -266,22 +406,29 @@ void recalculateLighting(Map& map, fov_settings_type* fov)
266 { 406 {
267 for (int x = 0; x < VIEW_WIDTH; x++) 407 for (int x = 0; x < VIEW_WIDTH; x++)
268 { 408 {
269 if ((player_x == x && player_y == y) || map.tiles[x+VIEW_WIDTH*y] == Tile::Dust || map.tiles[x+VIEW_WIDTH*y] == Tile::Lamp) 409 Source ls = Source::None;
410
411 if (player_x == x && player_y == y)
412 {
413 ls = Source::Player;
414 } else if (map.tiles[x+VIEW_WIDTH*y] == Tile::Dust)
270 { 415 {
271 fov_circle(fov, static_cast<void*>(&map), nullptr, x, y, RADIUS); 416 ls = Source::Dust;
417 } else if (map.tiles[x+VIEW_WIDTH*y] == Tile::Lamp)
418 {
419 ls = Source::Lamp;
272 } 420 }
273 421
274 if (map.tiles[x+VIEW_WIDTH*y] == Tile::Lamp || 422 if (ls != Source::None)
275 map.tiles[x+VIEW_WIDTH*y] == Tile::Dust)
276 { 423 {
424 fov_circle(fov, static_cast<void*>(&map), static_cast<void*>(&ls), x, y, RADIUS);
425
277 map.lighting[x+VIEW_WIDTH*y] = true; 426 map.lighting[x+VIEW_WIDTH*y] = true;
278 map.lightStrength[x+VIEW_WIDTH*y] = 1.0; 427 map.lightStrength[x+VIEW_WIDTH*y] = 1.0;
428 map.lightSource[x+VIEW_WIDTH*y] = ls;
279 } 429 }
280 } 430 }
281 } 431 }
282
283 map.lighting[player_x+VIEW_WIDTH*player_y] = true;
284 map.lightStrength[player_x+VIEW_WIDTH*player_y] = 1.0;
285} 432}
286 433
287void processKeys(Map& map, const Input& keystate) 434void processKeys(Map& map, const Input& keystate)
@@ -325,6 +472,11 @@ int main(int, char**)
325 throw sdl_error(); 472 throw sdl_error();
326 } 473 }
327 474
475 if (IMG_Init(IMG_INIT_PNG) != IMG_INIT_PNG)
476 {
477 throw img_error();
478 }
479
328 try 480 try
329 { 481 {
330 window_ptr win( 482 window_ptr win(
@@ -346,8 +498,6 @@ int main(int, char**)
346 throw sdl_error(); 498 throw sdl_error();
347 } 499 }
348 500
349 SDL_SetRenderDrawBlendMode(ren.get(), SDL_BLENDMODE_BLEND);
350
351 Map map; 501 Map map;
352 502
353 std::unique_ptr<fov_settings_type> fov(new fov_settings_type()); 503 std::unique_ptr<fov_settings_type> fov(new fov_settings_type());
@@ -527,6 +677,7 @@ int main(int, char**)
527 std::cout << "SDL error (" << ex.what() << ")" << std::endl; 677 std::cout << "SDL error (" << ex.what() << ")" << std::endl;
528 } 678 }
529 679
680 IMG_Quit();
530 SDL_Quit(); 681 SDL_Quit();
531 682
532 return 0; 683 return 0;