iwin8.cc

Go to the documentation of this file.
00001 
00007 /*
00008 Copyright (C) 1998 Jeffrey S. Freedman
00009 
00010 This library is free software; you can redistribute it and/or
00011 modify it under the terms of the GNU Library General Public
00012 License as published by the Free Software Foundation; either
00013 version 2 of the License, or (at your option) any later version.
00014 
00015 This library is distributed in the hope that it will be useful,
00016 but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 Library General Public License for more details.
00019 
00020 You should have received a copy of the GNU Library General Public
00021 License along with this library; if not, write to the
00022 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00023 Boston, MA  02111-1307, USA.
00024 */
00025 
00026 
00027 #ifdef HAVE_CONFIG_H
00028 #  include <config.h>
00029 #endif
00030 
00031 #ifndef ALPHA_LINUX_CXX
00032 #  include <cstring>
00033 #endif
00034 #include "SDL_video.h"
00035 #include "iwin8.h"
00036 #include "exult_types.h"
00037 #include "gamma.h"
00038 #include <limits.h>
00039 
00040 #ifndef UNDER_CE
00041 using std::memmove;
00042 #endif
00043 
00044 GammaTable<uint8> Image_window8::GammaRed(256);
00045 GammaTable<uint8> Image_window8::GammaBlue(256);
00046 GammaTable<uint8> Image_window8::GammaGreen(256);
00047 
00048 Image_window8::Image_window8(unsigned int w, unsigned int h, 
00049         int scl, bool fs, int sclr)
00050   : Image_window(new Image_buffer8(w, h, (Image_buffer *) 0), 
00051     scl, fs, sclr)
00052 {
00053   ib8 = (Image_buffer8 *) ibuf;
00054 }
00055 
00056 Image_window8::~Image_window8()
00057 {
00058 }
00059 
00060 
00061 void Image_window8::get_gamma (float &r, float &g, float &b)
00062 {
00063   r = GammaRed.get_gamma();
00064   g = GammaGreen.get_gamma();
00065   b = GammaBlue.get_gamma();
00066 }
00067 
00068 void Image_window8::set_gamma (float r, float g, float b)
00069 {
00070   GammaRed.set_gamma(r);
00071   GammaGreen.set_gamma(g);
00072   GammaBlue.set_gamma(b);
00073 }
00074 
00075 /*
00076  *  Convert rgb value.
00077  */
00078 
00079 inline unsigned short Get_color8
00080   (
00081   unsigned char val,
00082   int maxval,
00083   int brightness      // 100=normal.
00084   )
00085   {
00086   uint32 c = (((uint32) val)*brightness*255L)/
00087               (100*maxval);
00088   return (c <= 255L ? (unsigned short) c : 255);
00089   }
00090 
00091 /*
00092  *  Set palette.
00093  */
00094 
00095 void Image_window8::set_palette
00096   (
00097   unsigned char *rgbs,    // 256 3-byte entries.
00098   int maxval,     // Highest val. for each color.
00099   int brightness      // Brightness control (100 = normal).
00100   )
00101 {
00102           // Get the colors.
00103   SDL_Color colors2[256];
00104   for (int i = 0; i < 256; i++)
00105   {
00106     colors2[i].r = colors[i*3] = GammaRed[Get_color8(rgbs[3*i], maxval, brightness)];
00107     colors2[i].g = colors[i*3+1]  = GammaGreen[Get_color8(rgbs[3*i + 1], maxval, brightness)];
00108     colors2[i].b = colors[i*3+2]  = GammaBlue[Get_color8(rgbs[3*i + 2], maxval, brightness)];
00109   }
00110   SDL_SetColors(surface, colors2, 0, 256);
00111 
00112   if (surface != unscaled_surface)
00113     SDL_SetColors(unscaled_surface, colors2, 0, 256);
00114 }
00115 
00116 /*
00117  *  Rotate a range of colors.
00118  */
00119 
00120 void Image_window8::rotate_colors
00121   (
00122   int first,      // Palette index of 1st.
00123   int num,      // # in range.
00124   int upd       // 1 to update hardware palette.
00125   )
00126 {
00127   first *= 3;
00128   num *= 3;
00129   int cnt = num - 3;    // Shift downward.
00130   unsigned char c0 = colors[first+num-3];
00131   unsigned char c1 = colors[first+num-2];
00132   unsigned char c2 = colors[first+num-1];
00133   memmove(colors+first+3,colors+first,cnt);
00134   colors[first ] = c0;  // Shift 1st to end.
00135   colors[first+1] = c1; // Shift 1st to end.
00136   colors[first+2] = c2; // Shift 1st to end.
00137   if (upd)      // Take effect now?
00138   {
00139     SDL_Color colors2[256];
00140     for (int i = 0; i < 256; i++)
00141     {
00142       colors2[i].r = colors[i*3];
00143       colors2[i].g = colors[i*3+1];
00144       colors2[i].b = colors[i*3+2];
00145     }
00146     SDL_SetColors(surface, colors2, 0, 256);
00147 
00148     if (surface != unscaled_surface)
00149       SDL_SetColors(unscaled_surface, colors2, 0, 256);
00150   }
00151 }
00152 
00153 //a nearest-average-colour 1/3 scaler
00154 unsigned char* Image_window8::mini_screenshot()
00155 {
00156   int i;
00157   if (!surface) return 0;
00158 
00159   unsigned char* pixels = ibuf->get_bits();
00160   int pitch = ibuf->get_line_width();
00161   unsigned char* buf = new Uint8[96*60];
00162   const int w = 3*96, h = 3*60;
00163 
00164   for (int y = 0; y < h; y+=3)
00165     for (int x = 0; x < w; x+=3)
00166 #if 0
00167       buf[y*w/9 + x/3] = pixels[
00168         pitch * (y + (get_height()-h)/2) +
00169         x + (get_width()-w)/2 ];
00170 #else
00171     {
00172       //calculate average colour
00173       int r=0, g=0, b=0;
00174       for (i=0; i<3; i++)
00175         for (int j=0; j<3; j++) {
00176           r+=colors[0 + 3*pixels[
00177         pitch * (j + y + (get_height()-h)/2) +
00178         i + x + (get_width()-w)/2 ]];
00179           g+=colors[1 + 3*pixels[
00180         pitch * (j + y + (get_height()-h)/2) +
00181         i + x + (get_width()-w)/2 ]];
00182           b+=colors[2 + 3*pixels[
00183         pitch * (j + y + (get_height()-h)/2) +
00184         i + x + (get_width()-w)/2 ]];
00185         }
00186       r = r/9; g = g/9; b = b/9;
00187 
00188       //find nearest-colour in non-rotating palette
00189       int bestdist = INT_MAX, bestindex = -1;
00190       for (i=0; i<224; i++) {
00191         int dist = (colors[0+3*i]-r)*(colors[0+3*i]-r)+
00192           (colors[1+3*i]-g)*(colors[1+3*i]-g)+
00193           (colors[2+3*i]-b)*(colors[2+3*i]-b);
00194         if (dist < bestdist) {
00195           bestdist = dist;
00196           bestindex = i;
00197         }
00198       }
00199       buf[y*w/9 + x/3] = bestindex;
00200     }
00201         
00202 #endif
00203 
00204   return buf;
00205 }

Generated on Mon Jul 9 14:42:47 2007 for ExultEngine by  doxygen 1.5.1