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 );
101 Assert( fsize == 9472 );
102 cfread( gr_palette, 256*3, 1, fp );
103 cfread( gr_fade_table, 256*34, 1, fp );
106 // This is the TRANSPARENCY COLOR
107 for (i=0; i<GR_FADE_LEVELS; i++ ) {
108 gr_fade_table[i*256+255] = 255;
111 Num_computed_colors = 0; // Flush palette cache.
112 #if defined(POLY_ACC)
113 pa_update_clut(gr_palette, 0, 256, 0);
117 // Add a computed color (by gr_find_closest_color) to list of computed colors in Computed_colors.
118 // If list wasn't full already, increment Num_computed_colors.
119 // If was full, replace a random one.
120 void add_computed_color(int r, int g, int b, int color_num)
124 if (Num_computed_colors < MAX_COMPUTED_COLORS) {
125 add_index = Num_computed_colors;
126 Num_computed_colors++;
128 add_index = (rand() * MAX_COMPUTED_COLORS) >> 15;
130 Computed_colors[add_index].r = r;
131 Computed_colors[add_index].g = g;
132 Computed_colors[add_index].b = b;
133 Computed_colors[add_index].color_num = color_num;
136 void init_computed_colors(void)
140 for (i=0; i<MAX_COMPUTED_COLORS; i++)
141 Computed_colors[i].r = 255; // Make impossible to match.
144 int gr_find_closest_color( int r, int g, int b )
147 int best_value, best_index, value;
149 if (Num_computed_colors == 0)
150 init_computed_colors();
152 // If we've already computed this color, return it!
153 for (i=0; i<Num_computed_colors; i++)
154 if (r == Computed_colors[i].r)
155 if (g == Computed_colors[i].g)
156 if (b == Computed_colors[i].b) {
159 trec = Computed_colors[i-1];
160 Computed_colors[i-1] = Computed_colors[i];
161 Computed_colors[i] = trec;
162 return Computed_colors[i-1].color_num;
164 return Computed_colors[i].color_num;
171 best_value = SQUARE(r-gr_palette[0])+SQUARE(g-gr_palette[1])+SQUARE(b-gr_palette[2]);
174 add_computed_color(r, g, b, best_index);
178 // only go to 255, 'cause we dont want to check the transparent color.
179 for (i=1; i<254; i++ ) {
181 value = SQUARE(r-gr_palette[j])+SQUARE(g-gr_palette[j+1])+SQUARE(b-gr_palette[j+2]);
182 if ( value < best_value ) {
184 add_computed_color(r, g, b, i);
191 add_computed_color(r, g, b, best_index);
195 int gr_find_closest_color_15bpp( int rgb )
197 return gr_find_closest_color( ((rgb>>10)&31)*2, ((rgb>>5)&31)*2, (rgb&31)*2 );
201 int gr_find_closest_color_current( int r, int g, int b )
204 int best_value, best_index, value;
210 best_value = SQUARE(r-gr_current_pal[0])+SQUARE(g-gr_current_pal[1])+SQUARE(b-gr_current_pal[2]);
216 // only go to 255, 'cause we dont want to check the transparent color.
217 for (i=1; i<254; i++ ) {
219 value = SQUARE(r-gr_current_pal[j])+SQUARE(g-gr_current_pal[j+1])+SQUARE(b-gr_current_pal[j+2]);
220 if ( value < best_value ) {
231 static int last_r=0, last_g=0, last_b=0;
233 void gr_palette_step_up( int r, int g, int b )
239 if (gr_palette_faded_out) return;
241 #if !defined(POLY_ACC) // need this called always.
242 if ( (r==last_r) && (g==last_g) && (b==last_b) ) return;
248 #if defined(POLY_ACC)
249 if ( (r==0) && (g==0) && (b==0) ) return;
257 for (i=0; i<256; i++ ) {
258 temp = (int)(*p++) + r + gr_palette_gamma;
260 else if (temp>63) temp=63;
262 temp = (int)(*p++) + g + gr_palette_gamma;
264 else if (temp>63) temp=63;
266 temp = (int)(*p++) + b + gr_palette_gamma;
268 else if (temp>63) temp=63;
273 // This steps up all gun values, leaving black and white to always be black and white.
274 void gr_palette_step_up_vr( int r, int g, int b, int white_index, int black_index )
280 if (gr_palette_faded_out) return;
282 if ( (r==last_r) && (g==last_g) && (b==last_b) ) return;
287 #if defined(POLY_ACC)
294 for (i=0; i<256; i++ ) {
295 temp = (int)(*p++) + r + gr_palette_gamma;
297 else if (temp>63) temp=63;
298 if ( i==white_index ) temp = 63;
299 else if ( i==black_index ) temp = 0;
301 temp = (int)(*p++) + g + gr_palette_gamma;
303 else if (temp>63) temp=63;
304 if ( i==white_index ) temp = 63;
305 else if ( i==black_index ) temp = 0;
307 temp = (int)(*p++) + b + gr_palette_gamma;
309 else if (temp>63) temp=63;
310 if ( i==white_index ) temp = 63;
311 else if ( i==black_index ) temp = 0;
317 void gr_palette_clear()
320 #if !defined(POLY_ACC)
323 for (i=0; i<768; i++ ) {
327 gr_palette_faded_out = 1;
330 void gr_palette_load( ubyte * pal )
334 #if !defined(POLY_ACC)
337 for (i=0; i<768; i++ ) {
338 c = pal[i] + gr_palette_gamma;
339 if ( c > 63 ) c = 63;
341 gr_current_pal[i] = pal[i];
344 for (i=0; i<768; i++ ) {
345 c = pal[i] + gr_palette_gamma;
346 if ( c > 63 ) c = 63;
347 gr_current_pal[i] = c;
349 pa_update_clut(gr_current_pal, 0, 256, 0);
351 gr_palette_faded_out = 0;
353 // init_computed_colors();
356 extern void gr_sync_display(void);
358 int gr_palette_fade_out(ubyte *pal, int nsteps, int allow_keys )
362 fix fade_palette[768];
363 fix fade_palette_delta[768];
365 allow_keys = allow_keys;
367 if (gr_palette_faded_out) return 0;
370 if (grd_fades_disabled) {
376 #if defined(POLY_ACC)
380 for (i=0; i<768; i++ ) {
381 fade_palette[i] = i2f(pal[i]+gr_palette_gamma);
382 fade_palette_delta[i] = fade_palette[i] / nsteps;
385 for (j=0; j<nsteps; j++ ) {
389 for (i=0; i<768; i++ ) {
390 fade_palette[i] -= fade_palette_delta[i];
391 if (fade_palette[i] < 0 )
393 c = f2i(fade_palette[i]);
394 if ( c > 63 ) c = 63;
398 gr_palette_faded_out = 1;
402 int gr_palette_fade_in(ubyte *pal, int nsteps, int allow_keys)
406 fix fade_palette[768];
407 fix fade_palette_delta[768];
409 allow_keys = allow_keys;
411 if (!gr_palette_faded_out) return 0;
414 if (grd_fades_disabled) {
415 gr_palette_load(pal);
420 #if defined(POLY_ACC)
421 gr_palette_load(pal);
425 for (i=0; i<768; i++ ) {
426 gr_current_pal[i] = pal[i];
428 fade_palette_delta[i] = i2f(pal[i]+gr_palette_gamma) / nsteps;
431 for (j=0; j<nsteps; j++ ) {
435 for (i=0; i<768; i++ ) {
436 fade_palette[i] += fade_palette_delta[i];
437 if (fade_palette[i] > i2f(pal[i]+gr_palette_gamma) )
438 fade_palette[i] = i2f(pal[i]+gr_palette_gamma);
439 c = f2i(fade_palette[i]);
440 if ( c > 63 ) c = 63;
444 gr_palette_faded_out = 0;
448 void gr_make_cthru_table(ubyte * table, ubyte r, ubyte g, ubyte b )
453 for (i=0; i<256; i++ ) {
454 r1 = gr_palette[i*3+0] + r;
455 if ( r1 > 63 ) r1 = 63;
456 g1 = gr_palette[i*3+1] + g;
457 if ( g1 > 63 ) g1 = 63;
458 b1 = gr_palette[i*3+2] + b;
459 if ( b1 > 63 ) b1 = 63;
460 table[i] = gr_find_closest_color( r1, g1, b1 );
464 void gr_palette_read(ubyte * palette)
468 #if defined(POLY_ACC)
469 for(i = 0; i != 256; ++i)
471 *palette++ = (pa_clut[i] >> 9) & 0x3E;
472 *palette++ = (pa_clut[i] >> 4) & 0x3E;
473 *palette++ = (pa_clut[i] << 1) & 0x3E;
478 for (i=0; i<768; i++ ) {
479 *palette++ = inp( 0x3c9 );