Subversion Repositories Games.Prince of Persia

Rev

Blame | Last modification | View Log | Download | RSS feed

  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
  121.