00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifdef HAVE_CONFIG_H
00020 # include <config.h>
00021 #endif
00022
00023 #ifndef ALPHA_LINUX_CXX
00024 # include <cstring>
00025 #endif
00026 #include "files/U7file.h"
00027 #include "palette.h"
00028 #include "ibuf8.h"
00029 #include "utils.h"
00030 #include "fnames.h"
00031 #include "gamewin.h"
00032
00033 #include "SDL_timer.h"
00034
00035 #ifndef UNDER_CE
00036 using std::memcpy;
00037 using std::memset;
00038 using std::size_t;
00039 using std::string;
00040 #endif
00041
00042 Palette::Palette()
00043 : win(Game_window::get_instance()->get_win()),
00044 palette(-1), brightness(100),
00045 faded_out(false), fades_enabled(true), max_val(63)
00046 {
00047 }
00048
00049 Palette::~Palette()
00050 {
00051 }
00052
00053
00054
00055
00056
00057
00058 void Palette::fade
00059 (
00060 int cycles,
00061 int inout,
00062 int pal_num
00063 )
00064 {
00065 if (pal_num == -1) pal_num = palette;
00066 load(PALETTES_FLX, pal_num);
00067 if(inout)
00068 fade_in(cycles);
00069 else
00070 fade_out(cycles);
00071 faded_out = !inout;
00072 }
00073
00074
00075
00076
00077
00078 void Palette::flash_red
00079 (
00080 )
00081 {
00082 int savepal = palette;
00083 set(PALETTE_RED);
00084 win->show();
00085 SDL_Delay(100);
00086 set(savepal);
00087 Game_window::get_instance()->set_painted();
00088 }
00089
00090
00091
00092
00093
00094 void Palette::set
00095 (
00096 int pal_num,
00097 int new_brightness,
00098 bool repaint
00099 )
00100 {
00101 if ((palette == pal_num || pal_num == -1) &&
00102 (brightness == new_brightness || new_brightness == -1))
00103 return;
00104 if (pal_num != -1)
00105 palette = pal_num;
00106 if (new_brightness > 0)
00107 brightness = new_brightness;
00108 if (faded_out)
00109 return;
00110
00111 load(PALETTES_FLX, palette);
00112 set_brightness(brightness);
00113 apply(repaint);
00114 }
00115
00116 void Palette::apply(bool repaint)
00117 {
00118 win->set_palette(pal1, max_val, brightness);
00119 if (repaint)
00120 win->show();
00121 }
00122
00123
00124
00125
00126 void Palette::load(const char *fname, int index, const char *xfname, int xindex)
00127 {
00128 size_t len;
00129 char *buf = 0;
00130 if (std::strncmp(fname, "<STATIC>/", sizeof("<STATIC>/") - 1) == 0 &&
00131 is_system_path_defined("<PATCH>"))
00132 {
00133 string pname("<PATCH>/");
00134 pname += fname + sizeof("<STATIC>/") - 1;
00135 U7object pal(pname.c_str(), index);
00136 try {
00137 buf = pal.retrieve(len);
00138 }
00139 catch (exult_exception& e) {
00140 buf = 0;
00141 }
00142 }
00143 if (!buf)
00144 {
00145 U7object pal(fname, index);
00146 buf = pal.retrieve(len);
00147 }
00148 if(len==768) {
00149 if (xindex >= 0) {
00150 U7object xform(xfname, xindex);
00151 unsigned char *xbuf = 0;
00152 size_t xlen;
00153 try {
00154 #if 0
00155 xbuf = new unsigned char[256];
00156 Game_window *gwin =
00157 Game_window::get_instance();
00158 memcpy(xbuf, gwin->get_xform(11 - xindex - 1),
00159 256);
00160 #else
00161 xbuf = (unsigned char *) xform.retrieve( xlen);
00162 #endif
00163 for (int i = 0; i < 256; i++) {
00164 int ix = xbuf[i];
00165 pal1[3*i] = buf[3*ix];
00166 pal1[3*i+1] = buf[3*ix+1];
00167 pal1[3*i+2] = buf[3*ix+2];
00168 }
00169 }
00170 catch( const std::exception & err ) {
00171 xindex = -1;
00172 }
00173 delete [] xbuf;
00174 }
00175 if (xindex < 0)
00176 memcpy(pal1,buf,768);
00177 memset(pal2,0,768);
00178 } else {
00179 for(int i=0; i<768; i++) {
00180 pal1[i]=buf[i*2];
00181 pal2[i]=buf[i*2+1];
00182 }
00183 }
00184 delete [] buf;
00185 }
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 void Palette::set_brightness(int bright)
00223 {
00224 brightness = bright;
00225 }
00226
00227 void Palette::fade_in(int cycles)
00228 {
00229 if (fades_enabled)
00230 {
00231 unsigned char fade_pal[768];
00232 unsigned int ticks = SDL_GetTicks() + 20;
00233 for (int i = 0; i <= cycles; i++)
00234 {
00235 for(int c=0; c < 768; c++)
00236 fade_pal[c] = ((pal1[c]-pal2[c])*i)/cycles+pal2[c];
00237 win->set_palette(fade_pal, max_val, brightness);
00238
00239 if (i == cycles || ticks >= SDL_GetTicks() ||
00240 !Game_window::get_instance()->get_frame_skipping())
00241 win->show();
00242 while (ticks >= SDL_GetTicks())
00243 ;
00244 ticks += 20;
00245 }
00246 }
00247 else
00248 {
00249 win->set_palette(pal1, max_val, brightness);
00250 win->show();
00251 }
00252 }
00253
00254 void Palette::fade_out(int cycles)
00255 {
00256 if (fades_enabled)
00257 {
00258 unsigned char fade_pal[768];
00259 unsigned int ticks = SDL_GetTicks() + 20;
00260 for (int i = cycles; i >= 0; i--)
00261 {
00262 for(int c=0; c < 768; c++)
00263 fade_pal[c] = ((pal1[c]-pal2[c])*i)/cycles+pal2[c];
00264 win->set_palette(fade_pal, max_val, brightness);
00265
00266 if (i == 0 || ticks >= SDL_GetTicks() ||
00267 !Game_window::get_instance()->get_frame_skipping())
00268 win->show();
00269 while (ticks >= SDL_GetTicks())
00270 ;
00271 ticks += 20;
00272 }
00273 }
00274 else
00275 {
00276 win->set_palette(pal2, max_val, brightness);
00277 win->show();
00278 }
00279
00280 }
00281
00282
00283 int Palette::find_color(int r, int g, int b) {
00284 int best_index = -1;
00285 long best_distance = 0xfffffff;
00286
00287 for (int i = 0; i < 0xe0; i++) {
00288
00289 long dr = r - pal1[3*i], dg = g - pal1[3*i + 1],
00290 db = b - pal1[3*i + 2];
00291
00292 long dist = dr*dr + dg*dg + db*db;
00293 if (dist < best_distance) {
00294 best_index = i;
00295 best_distance = dist;
00296 }
00297 }
00298 return best_index;
00299 }
00300
00301
00302
00303
00304
00305
00306 void Palette::create_trans_table
00307 (
00308
00309 unsigned char br, unsigned bg, unsigned bb,
00310 int alpha,
00311 unsigned char *table
00312 )
00313 {
00314 for (int i = 0; i < 256; i++)
00315 {
00316 int newr = ((int) br * alpha)/255 +
00317 ((int) pal1[i*3] * (255 - alpha))/255;
00318 int newg = ((int) bg * alpha)/255 +
00319 ((int) pal1[i*3 + 1] * (255 - alpha))/255;
00320 int newb = ((int) bb * alpha)/255 +
00321 ((int) pal1[i*3 + 2] * (255 - alpha))/255;
00322 table[i] = find_color(newr, newg, newb);
00323 }
00324 }
00325
00326 void Palette::show() {
00327 for (int x = 0; x < 16; x++) {
00328 for (int y = 0; y < 16; y++) {
00329 win->fill8(y*16+x, 8, 8, x*8, y*8);
00330 }
00331 }
00332 }
00333
00334 void Palette::set_color(int nr, int r, int g, int b) {
00335 pal1[nr*3] = r;
00336 pal1[nr*3+1] = g;
00337 pal1[nr*3+2] = b;
00338 }
00339
00340 void Palette::set_palette(unsigned char palnew[768]) {
00341 memcpy(pal1,palnew,768);
00342 memset(pal2,0,768);
00343 }
00344
00345 void Palette::set_max_val(int max)
00346 {
00347 max_val = max;
00348 }
00349
00350 int Palette::get_max_val()
00351 {
00352 return max_val;
00353 }