Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | pmbaty | 1 | /* |
2 | SDLPoP, a port/conversion of the DOS game Prince of Persia. |
||
3 | Copyright (C) 2013-2018 Dávid Nagy |
||
4 | |||
5 | This program is free software: you can redistribute it and/or modify |
||
6 | it under the terms of the GNU General Public License as published by |
||
7 | the Free Software Foundation, either version 3 of the License, or |
||
8 | (at your option) any later version. |
||
9 | |||
10 | This program is distributed in the hope that it will be useful, |
||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
13 | GNU General Public License for more details. |
||
14 | |||
15 | You should have received a copy of the GNU General Public License |
||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
||
17 | |||
18 | The authors of this program may be contacted at http://forum.princed.org |
||
19 | */ |
||
20 | |||
21 | #include "common.h" |
||
22 | |||
23 | #ifdef USE_LIGHTING |
||
24 | |||
25 | image_type* lighting_mask = NULL; |
||
26 | image_type* screen_overlay = NULL; |
||
27 | Uint32 bgcolor; |
||
28 | |||
29 | const char mask_filename[1024] = "data/light.png"; |
||
30 | const Uint8 ambient_level = 128; |
||
31 | |||
32 | // Called once at startup. |
||
33 | void init_lighting() { |
||
34 | if (!enable_lighting) return; |
||
35 | |||
36 | lighting_mask = IMG_Load(mask_filename); |
||
37 | if (lighting_mask == NULL) { |
||
38 | sdlperror("IMG_Load (lighting_mask)"); |
||
39 | enable_lighting = 0; |
||
40 | return; |
||
41 | } |
||
42 | |||
43 | screen_overlay = SDL_CreateRGBSurface(0, 320, 192, 32, 0xFF << 0, 0xFF << 8, 0xFF << 16, 0xFF << 24); |
||
44 | if (screen_overlay == NULL) { |
||
45 | sdlperror("SDL_CreateRGBSurface (screen_overlay)"); |
||
46 | enable_lighting = 0; |
||
47 | return; |
||
48 | } |
||
49 | |||
50 | // "color modulate", i.e. multiply. |
||
51 | int result = SDL_SetSurfaceBlendMode(screen_overlay, SDL_BLENDMODE_MOD); |
||
52 | if (result != 0) { |
||
53 | sdlperror("SDL_SetSurfaceBlendMode (screen_overlay)"); |
||
54 | } |
||
55 | |||
56 | result = SDL_SetSurfaceBlendMode(lighting_mask, SDL_BLENDMODE_ADD); |
||
57 | if (result != 0) { |
||
58 | sdlperror("SDL_SetSurfaceBlendMode (lighting_mask)"); |
||
59 | } |
||
60 | |||
61 | // ambient lighting |
||
62 | bgcolor = SDL_MapRGBA(screen_overlay->format, ambient_level, ambient_level, ambient_level, SDL_ALPHA_OPAQUE); |
||
63 | } |
||
64 | |||
65 | // Recreate the lighting overlay based on the torches in the current room. |
||
66 | // Called when the current room changes. |
||
67 | void redraw_lighting() { |
||
68 | if (!enable_lighting) return; |
||
69 | if (lighting_mask == NULL) return; |
||
70 | if (curr_room_tiles == NULL) return; |
||
71 | if (is_cutscene) return; |
||
72 | |||
73 | int result = SDL_FillRect(screen_overlay, NULL, bgcolor); |
||
74 | if (result != 0) { |
||
75 | sdlperror("SDL_FillRect (screen_overlay)"); |
||
76 | } |
||
77 | |||
78 | // TODO: Also process nearby offscreen torches? |
||
79 | for (int tile_pos = 0; tile_pos < 30; tile_pos++) { |
||
80 | int tile_type = curr_room_tiles[tile_pos] & 0x1F; |
||
81 | if (tile_type == tiles_19_torch || tile_type == tiles_30_torch_with_debris) { |
||
82 | // Center of the flame. |
||
83 | int x = (tile_pos%10)*32+48; |
||
84 | int y = (tile_pos/10)*63+22; |
||
85 | |||
86 | // Align the center of lighting mask to the center of the flame. |
||
87 | SDL_Rect dest_rect; |
||
88 | dest_rect.x = x - lighting_mask->w / 2; |
||
89 | dest_rect.y = y - lighting_mask->h / 2; |
||
90 | dest_rect.w = lighting_mask->w; |
||
91 | dest_rect.h = lighting_mask->h; |
||
92 | |||
93 | int result = SDL_BlitSurface(lighting_mask, NULL, screen_overlay, &dest_rect); |
||
94 | if (result != 0) { |
||
95 | sdlperror("SDL_BlitSurface (lighting_mask)"); |
||
96 | } |
||
97 | } |
||
98 | } |
||
99 | if (upside_down) { |
||
100 | flip_screen(screen_overlay); |
||
101 | } |
||
102 | } |
||
103 | |||
104 | // Copy a part of the lighting overlay onto the screen. |
||
105 | // Called when the screen is updated. |
||
106 | void update_lighting(const rect_type far *target_rect_ptr) { |
||
107 | if (!enable_lighting) return; |
||
108 | if (lighting_mask == NULL) return; |
||
109 | if (curr_room_tiles == NULL) return; |
||
110 | if (is_cutscene) return; |
||
111 | |||
112 | SDL_Rect sdlrect; |
||
113 | rect_to_sdlrect(target_rect_ptr, &sdlrect); |
||
114 | int result = SDL_BlitSurface(screen_overlay, &sdlrect, onscreen_surface_, &sdlrect); |
||
115 | if (result != 0) { |
||
116 | sdlperror("SDL_BlitSurface (screen_overlay)"); |
||
117 | } |
||
118 | } |
||
119 | |||
120 | #endif // USE_LIGHTING |