2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
14 char palette_rcsid[] = "$Id: palette.c,v 1.1.1.1 2001-01-19 03:30:15 bradleyb Exp $";
22 #include "pa_enabl.h" //$$POLY_ACC
37 extern int gr_installed;
39 #define SQUARE(x) ((x)*(x))
41 #define MAX_COMPUTED_COLORS 32
43 int Num_computed_colors=0;
46 ubyte r,g,b,color_num;
49 color_record Computed_colors[MAX_COMPUTED_COLORS];
51 ubyte gr_palette[256*3];
52 ubyte gr_current_pal[256*3];
53 ubyte gr_fade_table[256*34];
55 // ushort gr_palette_selector;
56 // ushort gr_fade_table_selector;
58 ubyte gr_palette_gamma = 0;
59 int gr_palette_gamma_param = 0;
60 ubyte gr_palette_faded_out = 1;
62 //to speed up development
63 int grd_fades_disabled=0;
65 void gr_palette_set_gamma( int gamma )
67 if ( gamma < 0 ) gamma = 0;
68 if ( gamma > 8 ) gamma = 8;
70 if (gr_palette_gamma_param != gamma ) {
71 gr_palette_gamma_param = gamma;
72 gr_palette_gamma = gamma;
73 if (!gr_palette_faded_out)
74 gr_palette_load( gr_palette );
78 int gr_palette_get_gamma()
80 return gr_palette_gamma_param;
84 void gr_copy_palette(ubyte *gr_palette, ubyte *pal, int size)
86 memcpy(gr_palette, pal, size);
88 Num_computed_colors = 0;
91 void gr_use_palette_table( char * filename )
96 fp = cfopen( filename, "rb" );
98 Error("Can't open palette file <%s>",filename);
100 fsize = cfilelength( fp );
102 Error("Palette file <%s> is wrong size",filename);
103 cfread( gr_palette, 256*3, 1, fp );
104 cfread( gr_fade_table, 256*34, 1, fp );
107 // This is the TRANSPARENCY COLOR
108 for (i=0; i<GR_FADE_LEVELS; i++ ) {
109 gr_fade_table[i*256+255] = 255;
112 Num_computed_colors = 0; // Flush palette cache.
113 #if defined(POLY_ACC)
114 pa_update_clut(gr_palette, 0, 256, 0);
118 // Add a computed color (by gr_find_closest_color) to list of computed colors in Computed_colors.
119 // If list wasn't full already, increment Num_computed_colors.
120 // If was full, replace a random one.
121 void add_computed_color(int r, int g, int b, int color_num)
125 if (Num_computed_colors < MAX_COMPUTED_COLORS) {
126 add_index = Num_computed_colors;
127 Num_computed_colors++;
129 add_index = (rand() * MAX_COMPUTED_COLORS) >> 15;
131 Computed_colors[add_index].r = r;
132 Computed_colors[add_index].g = g;
133 Computed_colors[add_index].b = b;
134 Computed_colors[add_index].color_num = color_num;
137 void init_computed_colors(void)
141 for (i=0; i<MAX_COMPUTED_COLORS; i++)
142 Computed_colors[i].r = 255; // Make impossible to match.
145 int gr_find_closest_color( int r, int g, int b )
148 int best_value, best_index, value;
150 if (Num_computed_colors == 0)
151 init_computed_colors();
153 // If we've already computed this color, return it!
154 for (i=0; i<Num_computed_colors; i++)
155 if (r == Computed_colors[i].r)
156 if (g == Computed_colors[i].g)
157 if (b == Computed_colors[i].b) {
160 trec = Computed_colors[i-1];
161 Computed_colors[i-1] = Computed_colors[i];
162 Computed_colors[i] = trec;
163 return Computed_colors[i-1].color_num;
165 return Computed_colors[i].color_num;
172 best_value = SQUARE(r-gr_palette[0])+SQUARE(g-gr_palette[1])+SQUARE(b-gr_palette[2]);
175 add_computed_color(r, g, b, best_index);
179 // only go to 255, 'cause we dont want to check the transparent color.
180 for (i=1; i<254; i++ ) {
182 value = SQUARE(r-gr_palette[j])+SQUARE(g-gr_palette[j+1])+SQUARE(b-gr_palette[j+2]);
183 if ( value < best_value ) {
185 add_computed_color(r, g, b, i);
192 add_computed_color(r, g, b, best_index);
196 int gr_find_closest_color_15bpp( int rgb )
198 return gr_find_closest_color( ((rgb>>10)&31)*2, ((rgb>>5)&31)*2, (rgb&31)*2 );
202 int gr_find_closest_color_current( int r, int g, int b )
205 int best_value, best_index, value;
211 best_value = SQUARE(r-gr_current_pal[0])+SQUARE(g-gr_current_pal[1])+SQUARE(b-gr_current_pal[2]);
217 // only go to 255, 'cause we dont want to check the transparent color.
218 for (i=1; i<254; i++ ) {
220 value = SQUARE(r-gr_current_pal[j])+SQUARE(g-gr_current_pal[j+1])+SQUARE(b-gr_current_pal[j+2]);
221 if ( value < best_value ) {
232 static int last_r=0, last_g=0, last_b=0;
234 void gr_palette_step_up( int r, int g, int b )
240 if (gr_palette_faded_out) return;
242 #if !defined(POLY_ACC) // need this called always.
243 if ( (r==last_r) && (g==last_g) && (b==last_b) ) return;
249 #if defined(POLY_ACC)
250 if ( (r==0) && (g==0) && (b==0) ) return;
251 PA_DFX (pa_set_backbuffer_current());
259 for (i=0; i<256; i++ ) {
260 temp = (int)(*p++) + r + gr_palette_gamma;
262 else if (temp>63) temp=63;
264 temp = (int)(*p++) + g + gr_palette_gamma;
266 else if (temp>63) temp=63;
268 temp = (int)(*p++) + b + gr_palette_gamma;
270 else if (temp>63) temp=63;
275 // This steps up all gun values, leaving black and white to always be black and white.
276 void gr_palette_step_up_vr( int r, int g, int b, int white_index, int black_index )
282 if (gr_palette_faded_out) return;
284 if ( (r==last_r) && (g==last_g) && (b==last_b) ) return;
289 #if defined(POLY_ACC)
296 for (i=0; i<256; i++ ) {
297 temp = (int)(*p++) + r + gr_palette_gamma;
299 else if (temp>63) temp=63;
300 if ( i==white_index ) temp = 63;
301 else if ( i==black_index ) temp = 0;
303 temp = (int)(*p++) + g + gr_palette_gamma;
305 else if (temp>63) temp=63;
306 if ( i==white_index ) temp = 63;
307 else if ( i==black_index ) temp = 0;
309 temp = (int)(*p++) + b + gr_palette_gamma;
311 else if (temp>63) temp=63;
312 if ( i==white_index ) temp = 63;
313 else if ( i==black_index ) temp = 0;
319 void gr_palette_clear()
322 #if !defined(POLY_ACC)
325 for (i=0; i<768; i++ ) {
329 gr_palette_faded_out = 1;
332 void gr_palette_load( ubyte * pal )
336 #if !defined(POLY_ACC)
339 for (i=0; i<768; i++ ) {
340 c = pal[i] + gr_palette_gamma;
341 if ( c > 63 ) c = 63;
343 gr_current_pal[i] = pal[i];
346 for (i=0; i<768; i++ ) {
347 c = pal[i] + gr_palette_gamma;
348 if ( c > 63 ) c = 63;
349 gr_current_pal[i] = c;
351 pa_update_clut(gr_current_pal, 0, 256, 0);
353 gr_palette_faded_out = 0;
355 // init_computed_colors();
358 extern void gr_sync_display(void);
360 int gr_palette_fade_out(ubyte *pal, int nsteps, int allow_keys )
364 fix fade_palette[768];
365 fix fade_palette_delta[768];
367 allow_keys = allow_keys;
369 if (gr_palette_faded_out) return 0;
372 if (grd_fades_disabled) {
378 #if defined(POLY_ACC)
382 for (i=0; i<768; i++ ) {
383 fade_palette[i] = i2f(pal[i]+gr_palette_gamma);
384 fade_palette_delta[i] = fade_palette[i] / nsteps;
387 for (j=0; j<nsteps; j++ ) {
391 for (i=0; i<768; i++ ) {
392 fade_palette[i] -= fade_palette_delta[i];
393 if (fade_palette[i] < 0 )
395 c = f2i(fade_palette[i]);
396 if ( c > 63 ) c = 63;
400 gr_palette_faded_out = 1;
404 int gr_palette_fade_in(ubyte *pal, int nsteps, int allow_keys)
408 fix fade_palette[768];
409 fix fade_palette_delta[768];
411 allow_keys = allow_keys;
413 if (!gr_palette_faded_out) return 0;
416 if (grd_fades_disabled) {
417 gr_palette_load(pal);
422 #if defined(POLY_ACC)
423 gr_palette_load(pal);
427 for (i=0; i<768; i++ ) {
428 gr_current_pal[i] = pal[i];
430 fade_palette_delta[i] = i2f(pal[i]+gr_palette_gamma) / nsteps;
433 for (j=0; j<nsteps; j++ ) {
437 for (i=0; i<768; i++ ) {
438 fade_palette[i] += fade_palette_delta[i];
439 if (fade_palette[i] > i2f(pal[i]+gr_palette_gamma) )
440 fade_palette[i] = i2f(pal[i]+gr_palette_gamma);
441 c = f2i(fade_palette[i]);
442 if ( c > 63 ) c = 63;
446 gr_palette_faded_out = 0;
450 void gr_make_cthru_table(ubyte * table, ubyte r, ubyte g, ubyte b )
455 for (i=0; i<256; i++ ) {
456 r1 = gr_palette[i*3+0] + r;
457 if ( r1 > 63 ) r1 = 63;
458 g1 = gr_palette[i*3+1] + g;
459 if ( g1 > 63 ) g1 = 63;
460 b1 = gr_palette[i*3+2] + b;
461 if ( b1 > 63 ) b1 = 63;
462 table[i] = gr_find_closest_color( r1, g1, b1 );
466 void gr_palette_read(ubyte * palette)
470 #if defined(POLY_ACC)
471 for(i = 0; i != 256; ++i)
473 *palette++ = (pa_clut[i] >> 9) & 0x3E;
474 *palette++ = (pa_clut[i] >> 4) & 0x3E;
475 *palette++ = (pa_clut[i] << 1) & 0x3E;
480 for (i=0; i<768; i++ ) {
481 *palette++ = inp( 0x3c9 );