Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * OpenTyrian: A modern cross-platform port of Tyrian
  3.  * Copyright (C) 2007-2009  The OpenTyrian Development Team
  4.  *
  5.  * This program is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU General Public License
  7.  * as published by the Free Software Foundation; either version 2
  8.  * of the License, or (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, write to the Free Software
  17.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  18.  */
  19. #include "palette.h"
  20.  
  21. #include "file.h"
  22. #include "nortsong.h"
  23. #include "opentyr.h"
  24. #include "video.h"
  25.  
  26. #include <assert.h>
  27.  
  28. static Uint32 rgb_to_yuv( int r, int g, int b );
  29.  
  30. #define PALETTE_COUNT 23
  31.  
  32. Palette palettes[PALETTE_COUNT];
  33. int palette_count;
  34.  
  35. static Palette palette;
  36. Uint32 rgb_palette[256], yuv_palette[256];
  37.  
  38. Palette colors;
  39.  
  40. void JE_loadPals( void )
  41. {
  42.         FILE *f = dir_fopen_die(data_dir(), "palette.dat", "rb");
  43.        
  44.         palette_count = ftell_eof(f) / (256 * 3);
  45.         assert(palette_count == PALETTE_COUNT);
  46.        
  47.         for (int p = 0; p < palette_count; ++p)
  48.         {
  49.                 for (int i = 0; i < 256; ++i)
  50.                 {
  51.                         // The VGA hardware palette used only 6 bits per component, so the values need to be rescaled to
  52.                         // 8 bits. The naive way to do this is to simply do (c << 2), padding it with 0's, however this
  53.                         // makes the maximum value 252 instead of the proper 255. A trick to fix this is to use the upper 2
  54.                         // bits of the original value instead. This ensures that the value goes to 255 as the original goes
  55.                         // to 63.
  56.  
  57.                         int c = getc(f);
  58.                         palettes[p][i].r = (c << 2) | (c >> 4);
  59.                         c = getc(f);
  60.                         palettes[p][i].g = (c << 2) | (c >> 4);
  61.                         c = getc(f);
  62.                         palettes[p][i].b = (c << 2) | (c >> 4);
  63.                 }
  64.         }
  65.        
  66.         fclose(f);
  67. }
  68.  
  69. void set_palette( Palette colors, unsigned int first_color, unsigned int last_color )
  70. {
  71.         SDL_Surface *const surface = SDL_GetVideoSurface();
  72.         const uint bpp = surface->format->BitsPerPixel;
  73.        
  74.         for (uint i = first_color; i <= last_color; ++i)
  75.         {
  76.                 palette[i] = colors[i];
  77.                
  78.                 if (bpp != 8)
  79.                 {
  80.                         rgb_palette[i] = SDL_MapRGB(surface->format, palette[i].r, palette[i].g, palette[i].b);
  81.                         yuv_palette[i] = rgb_to_yuv(palette[i].r, palette[i].g, palette[i].b);
  82.                 }
  83.         }
  84.        
  85.         if (bpp == 8)
  86.                 SDL_SetColors(surface, palette, first_color, last_color - first_color + 1);
  87. }
  88.  
  89. void set_colors( SDL_Color color, unsigned int first_color, unsigned int last_color )
  90. {
  91.         SDL_Surface *const surface = SDL_GetVideoSurface();
  92.         const uint bpp = surface->format->BitsPerPixel;
  93.        
  94.         for (uint i = first_color; i <= last_color; ++i)
  95.         {
  96.                 palette[i] = color;
  97.                
  98.                 if (bpp != 8)
  99.                 {
  100.                         rgb_palette[i] = SDL_MapRGB(surface->format, palette[i].r, palette[i].g, palette[i].b);
  101.                         yuv_palette[i] = rgb_to_yuv(palette[i].r, palette[i].g, palette[i].b);
  102.                 }
  103.         }
  104.        
  105.         if (bpp == 8)
  106.                 SDL_SetColors(surface, palette, first_color, last_color - first_color + 1);
  107. }
  108.  
  109. void init_step_fade_palette( int diff[256][3], Palette colors, unsigned int first_color, unsigned int last_color )
  110. {
  111.         for (unsigned int i = first_color; i <= last_color; i++)
  112.         {
  113.                 diff[i][0] = (int)colors[i].r - palette[i].r;
  114.                 diff[i][1] = (int)colors[i].g - palette[i].g;
  115.                 diff[i][2] = (int)colors[i].b - palette[i].b;
  116.         }
  117. }
  118.  
  119. void init_step_fade_solid( int diff[256][3], SDL_Color color, unsigned int first_color, unsigned int last_color )
  120. {
  121.         for (unsigned int i = first_color; i <= last_color; i++)
  122.         {
  123.                 diff[i][0] = (int)color.r - palette[i].r;
  124.                 diff[i][1] = (int)color.g - palette[i].g;
  125.                 diff[i][2] = (int)color.b - palette[i].b;
  126.         }
  127. }
  128.  
  129. void step_fade_palette( int diff[256][3], int steps, unsigned int first_color, unsigned int last_color )
  130. {
  131.         assert(steps > 0);
  132.        
  133.         SDL_Surface *const surface = SDL_GetVideoSurface();
  134.         const uint bpp = surface->format->BitsPerPixel;
  135.        
  136.         for (unsigned int i = first_color; i <= last_color; i++)
  137.         {
  138.                 int delta[3] = { diff[i][0] / steps, diff[i][1] / steps, diff[i][2] / steps };
  139.                
  140.                 diff[i][0] -= delta[0];
  141.                 diff[i][1] -= delta[1];
  142.                 diff[i][2] -= delta[2];
  143.                
  144.                 palette[i].r += delta[0];
  145.                 palette[i].g += delta[1];
  146.                 palette[i].b += delta[2];
  147.                
  148.                 if (bpp != 8)
  149.                 {
  150.                         rgb_palette[i] = SDL_MapRGB(surface->format, palette[i].r, palette[i].g, palette[i].b);
  151.                         yuv_palette[i] = rgb_to_yuv(palette[i].r, palette[i].g, palette[i].b);
  152.                 }
  153.         }
  154.        
  155.         if (bpp == 8)
  156.                 SDL_SetColors(surface, palette, 0, 256);
  157. }
  158.  
  159.  
  160. void fade_palette( Palette colors, int steps, unsigned int first_color, unsigned int last_color )
  161. {
  162.         assert(steps > 0);
  163.        
  164.         SDL_Surface *const surface = SDL_GetVideoSurface();
  165.         const uint bpp = surface->format->BitsPerPixel;
  166.        
  167.         static int diff[256][3];
  168.         init_step_fade_palette(diff, colors, first_color, last_color);
  169.        
  170.         for (; steps > 0; steps--)
  171.         {
  172.                 setdelay(1);
  173.                
  174.                 step_fade_palette(diff, steps, first_color, last_color);
  175.                
  176.                 if (bpp != 8)
  177.                         JE_showVGA();
  178.                
  179.                 wait_delay();
  180.         }
  181. }
  182.  
  183. void fade_solid( SDL_Color color, int steps, unsigned int first_color, unsigned int last_color )
  184. {
  185.         assert(steps > 0);
  186.        
  187.         SDL_Surface *const surface = SDL_GetVideoSurface();
  188.         const uint bpp = surface->format->BitsPerPixel;
  189.        
  190.         static int diff[256][3];
  191.         init_step_fade_solid(diff, color, first_color, last_color);
  192.        
  193.         for (; steps > 0; steps--)
  194.         {
  195.                 setdelay(1);
  196.                
  197.                 step_fade_palette(diff, steps, first_color, last_color);
  198.                
  199.                 if (bpp != 8)
  200.                         JE_showVGA();
  201.                
  202.                 wait_delay();
  203.         }
  204. }
  205.  
  206. void fade_black( int steps )
  207. {
  208.         SDL_Color black = { 0, 0, 0 };
  209.         fade_solid(black, steps, 0, 255);
  210. }
  211.  
  212. void fade_white( int steps )
  213. {
  214.         SDL_Color white = { 255, 255, 255 };
  215.         fade_solid(white, steps, 0, 255);
  216. }
  217.  
  218. static Uint32 rgb_to_yuv( int r, int g, int b )
  219. {
  220.         int y = (r + g + b) >> 2,
  221.             u = 128 + ((r - b) >> 2),
  222.             v = 128 + ((-r + 2 * g - b) >> 3);
  223.         return (y << 16) + (u << 8) + v;
  224. }
  225.  
  226.