1 /* $Id: palette.c,v 1.12 2004-08-28 23:17:45 schaffner Exp $ */
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
16 * Graphical routines for setting the palette
36 //added/remove by dph on 1/9/99
42 extern int gr_installed;
44 #define SQUARE(x) ((x)*(x))
46 #define MAX_COMPUTED_COLORS 32
48 int Num_computed_colors=0;
51 ubyte r,g,b,color_num;
54 color_record Computed_colors[MAX_COMPUTED_COLORS];
56 ubyte gr_palette[256*3];
57 ubyte gr_current_pal[256*3];
58 ubyte gr_fade_table[256*34];
60 ubyte gr_palette_gamma = 0;
61 int gr_palette_gamma_param = 0;
62 ubyte gr_palette_faded_out = 1;
64 int grd_fades_disabled=0; // Used to skip fading for development
66 void gr_palette_set_gamma( int gamma )
68 if ( gamma < 0 ) gamma = 0;
69 //added/changed on 10/27/98 by Victor Rachels to increase brightness slider
70 if ( gamma > 16 ) gamma = 16; //was 8
71 //end this section change - Victor Rachels
73 if (gr_palette_gamma_param != gamma ) {
74 gr_palette_gamma_param = gamma;
75 gr_palette_gamma = gamma;
76 if (!gr_palette_faded_out)
77 gr_palette_load( gr_palette );
81 int gr_palette_get_gamma()
83 return gr_palette_gamma_param;
87 void gr_copy_palette(ubyte *gr_palette, ubyte *pal, int size)
89 memcpy(gr_palette, pal, size);
91 Num_computed_colors = 0;
95 void gr_use_palette_table( char * filename )
103 fp = cfopen( filename, "rb" );
105 // the following is a hack to enable the loading of d2 levels
106 // even if only the d2 mac shareware datafiles are present.
107 // However, if the pig file is present but the palette file isn't,
108 // the textures in the level will look wierd...
110 fp = cfopen( DEFAULT_LEVEL_PALETTE, "rb" );
112 Error("Can open neither palette file <%s> "
113 "nor default palette file <"
114 DEFAULT_LEVEL_PALETTE
118 fsize = cfilelength( fp );
119 Assert( fsize == 9472 );
120 cfread( gr_palette, 256*3, 1, fp );
121 cfread( gr_fade_table, 256*34, 1, fp );
124 // This is the TRANSPARENCY COLOR
125 for (i=0; i<GR_FADE_LEVELS; i++ ) {
126 gr_fade_table[i*256+255] = 255;
129 Num_computed_colors = 0; // Flush palette cache.
130 #if defined(POLY_ACC)
131 pa_update_clut(gr_palette, 0, 256, 0);
134 // swap colors 0 and 255 of the palette along with fade table entries
137 for (i = 0; i < 3; i++) {
139 gr_palette[i] = gr_palette[765+i];
140 gr_palette[765+i] = c;
143 for (i = 0; i < GR_FADE_LEVELS * 256; i++) {
144 if (gr_fade_table[i] == 0)
145 gr_fade_table[i] = 255;
147 for (i=0; i<GR_FADE_LEVELS; i++)
148 gr_fade_table[i*256] = TRANSPARENCY_COLOR;
152 // Add a computed color (by gr_find_closest_color) to list of computed colors in Computed_colors.
153 // If list wasn't full already, increment Num_computed_colors.
154 // If was full, replace a random one.
155 void add_computed_color(int r, int g, int b, int color_num)
159 if (Num_computed_colors < MAX_COMPUTED_COLORS) {
160 add_index = Num_computed_colors;
161 Num_computed_colors++;
163 add_index = (d_rand() * MAX_COMPUTED_COLORS) >> 15;
165 Computed_colors[add_index].r = r;
166 Computed_colors[add_index].g = g;
167 Computed_colors[add_index].b = b;
168 Computed_colors[add_index].color_num = color_num;
171 void init_computed_colors(void)
175 for (i=0; i<MAX_COMPUTED_COLORS; i++)
176 Computed_colors[i].r = 255; // Make impossible to match.
179 int gr_find_closest_color( int r, int g, int b )
182 int best_value, best_index, value;
184 if (Num_computed_colors == 0)
185 init_computed_colors();
187 // If we've already computed this color, return it!
188 for (i=0; i<Num_computed_colors; i++)
189 if (r == Computed_colors[i].r)
190 if (g == Computed_colors[i].g)
191 if (b == Computed_colors[i].b) {
194 trec = Computed_colors[i-1];
195 Computed_colors[i-1] = Computed_colors[i];
196 Computed_colors[i] = trec;
197 return Computed_colors[i-1].color_num;
199 return Computed_colors[i].color_num;
206 best_value = SQUARE(r-gr_palette[0])+SQUARE(g-gr_palette[1])+SQUARE(b-gr_palette[2]);
209 add_computed_color(r, g, b, best_index);
213 // only go to 255, 'cause we dont want to check the transparent color.
214 for (i=1; i<254; i++ ) {
216 value = SQUARE(r-gr_palette[j])+SQUARE(g-gr_palette[j+1])+SQUARE(b-gr_palette[j+2]);
217 if ( value < best_value ) {
219 add_computed_color(r, g, b, i);
226 add_computed_color(r, g, b, best_index);
230 int gr_find_closest_color_15bpp( int rgb )
232 return gr_find_closest_color( ((rgb>>10)&31)*2, ((rgb>>5)&31)*2, (rgb&31)*2 );
236 int gr_find_closest_color_current( int r, int g, int b )
239 int best_value, best_index, value;
245 best_value = SQUARE(r-gr_current_pal[0])+SQUARE(g-gr_current_pal[1])+SQUARE(b-gr_current_pal[2]);
251 // only go to 255, 'cause we dont want to check the transparent color.
252 for (i=1; i<254; i++ ) {
254 value = SQUARE(r-gr_current_pal[j])+SQUARE(g-gr_current_pal[j+1])+SQUARE(b-gr_current_pal[j+2]);
255 if ( value < best_value ) {
265 void gr_make_cthru_table(ubyte * table, ubyte r, ubyte g, ubyte b )
270 for (i=0; i<256; i++ ) {
271 r1 = gr_palette[i*3+0] + r;
272 if ( r1 > 63 ) r1 = 63;
273 g1 = gr_palette[i*3+1] + g;
274 if ( g1 > 63 ) g1 = 63;
275 b1 = gr_palette[i*3+2] + b;
276 if ( b1 > 63 ) b1 = 63;
277 table[i] = gr_find_closest_color( r1, g1, b1 );
281 void gr_make_blend_table(ubyte *blend_table, ubyte r, ubyte g, ubyte b)
287 for (j = 0; j < GR_FADE_LEVELS; j++)
289 alpha = 1.0 - (float)j / ((float)GR_FADE_LEVELS - 1);
290 for (i = 0; i < 255; i++)
292 r1 = (ubyte)((1.0 - alpha) * (float)gr_palette[i * 3 + 0] + (alpha * (float)r));
293 g1 = (ubyte)((1.0 - alpha) * (float)gr_palette[i * 3 + 1] + (alpha * (float)g));
294 b1 = (ubyte)((1.0 - alpha) * (float)gr_palette[i * 3 + 2] + (alpha * (float)b));
295 blend_table[i + j * 256] = gr_find_closest_color(r1, g1, b1);
297 blend_table[i + j * 256] = 255; // leave white alone