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 |