]> icculus.org git repositories - btb/d2x.git/blob - unused/vga/palette.c
utilize hardware multitexturing support if possible (requires GL_NV_texture_env_combi...
[btb/d2x.git] / unused / vga / palette.c
1 /*
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.
12 */
13
14 char palette_rcsid[] = "$Id: palette.c,v 1.1.1.1 2001-01-19 03:30:15 bradleyb Exp $";
15
16 #include <conio.h>
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <io.h>
20 #include <string.h>
21
22 #include "pa_enabl.h"                   //$$POLY_ACC
23 #include "types.h"
24 #include "mem.h"
25 #include "gr.h"
26 #include "grdef.h"
27 #include "cfile.h"
28 #include "error.h"
29 #include "mono.h"
30 #include "fix.h"
31 #include "key.h"
32
33 #if defined(POLY_ACC)
34 #include "poly_acc.h"
35 #endif
36
37 extern int gr_installed;
38
39 #define SQUARE(x) ((x)*(x))
40
41 #define MAX_COMPUTED_COLORS     32
42
43 int     Num_computed_colors=0;
44
45 typedef struct {
46         ubyte   r,g,b,color_num;
47 } color_record;
48
49 color_record Computed_colors[MAX_COMPUTED_COLORS];
50
51 ubyte gr_palette[256*3];
52 ubyte gr_current_pal[256*3];
53 ubyte gr_fade_table[256*34];
54
55 // ushort gr_palette_selector;
56 // ushort gr_fade_table_selector;
57
58 ubyte gr_palette_gamma = 0;
59 int gr_palette_gamma_param = 0;
60 ubyte gr_palette_faded_out = 1;
61
62 //to speed up development
63 int grd_fades_disabled=0;
64
65 void gr_palette_set_gamma( int gamma )
66 {
67         if ( gamma < 0 ) gamma = 0;
68         if ( gamma > 8 ) gamma = 8;
69
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 );
75         }       
76 }
77
78 int gr_palette_get_gamma()
79 {
80         return gr_palette_gamma_param;
81 }
82
83
84 void gr_copy_palette(ubyte *gr_palette, ubyte *pal, int size)
85 {
86         memcpy(gr_palette, pal, size);
87
88         Num_computed_colors = 0;
89 }
90
91 void gr_use_palette_table( char * filename )
92 {
93         CFILE *fp;
94         int i,fsize;
95
96         fp = cfopen( filename, "rb" );
97         if ( fp==NULL)
98                 Error("Can't open palette file <%s>",filename);
99
100         fsize   = cfilelength( fp );
101         if ( fsize != 9472)
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 );
105         cfclose(fp);
106
107         // This is the TRANSPARENCY COLOR
108         for (i=0; i<GR_FADE_LEVELS; i++ )       {
109                 gr_fade_table[i*256+255] = 255;
110         }
111
112         Num_computed_colors = 0;        //      Flush palette cache.
113 #if defined(POLY_ACC)
114     pa_update_clut(gr_palette, 0, 256, 0);
115 #endif
116 }
117
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)
122 {
123         int     add_index;
124
125         if (Num_computed_colors < MAX_COMPUTED_COLORS) {
126                 add_index = Num_computed_colors;
127                 Num_computed_colors++;
128         } else
129                 add_index = (rand() * MAX_COMPUTED_COLORS) >> 15;
130
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;
135 }
136
137 void init_computed_colors(void)
138 {
139         int     i;
140
141         for (i=0; i<MAX_COMPUTED_COLORS; i++)
142                 Computed_colors[i].r = 255;             //      Make impossible to match.
143 }
144
145 int gr_find_closest_color( int r, int g, int b )
146 {
147         int i, j;
148         int best_value, best_index, value;
149
150         if (Num_computed_colors == 0)
151                 init_computed_colors();
152
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) {
158                                         if (i > 4) {
159                                                 color_record    trec;
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;
164                                         }
165                                         return Computed_colors[i].color_num;
166                                 }
167
168 //      r &= 63;
169 //      g &= 63;
170 //      b &= 63;
171
172         best_value = SQUARE(r-gr_palette[0])+SQUARE(g-gr_palette[1])+SQUARE(b-gr_palette[2]);
173         best_index = 0;
174         if (best_value==0) {
175                 add_computed_color(r, g, b, best_index);
176                 return best_index;
177         }
178         j=0;
179         // only go to 255, 'cause we dont want to check the transparent color.
180         for (i=1; i<254; i++ )  {
181                 j += 3;
182                 value = SQUARE(r-gr_palette[j])+SQUARE(g-gr_palette[j+1])+SQUARE(b-gr_palette[j+2]);
183                 if ( value < best_value )       {
184                         if (value==0) {
185                                 add_computed_color(r, g, b, i);
186                                 return i;
187                         }
188                         best_value = value;
189                         best_index = i;
190                 }
191         }
192         add_computed_color(r, g, b, best_index);
193         return best_index;
194 }
195
196 int gr_find_closest_color_15bpp( int rgb )
197 {
198         return gr_find_closest_color( ((rgb>>10)&31)*2, ((rgb>>5)&31)*2, (rgb&31)*2 );
199 }
200
201
202 int gr_find_closest_color_current( int r, int g, int b )
203 {
204         int i, j;
205         int best_value, best_index, value;
206
207 //      r &= 63;
208 //      g &= 63;
209 //      b &= 63;
210
211         best_value = SQUARE(r-gr_current_pal[0])+SQUARE(g-gr_current_pal[1])+SQUARE(b-gr_current_pal[2]);
212         best_index = 0;
213         if (best_value==0)
214                 return best_index;
215
216         j=0;
217         // only go to 255, 'cause we dont want to check the transparent color.
218         for (i=1; i<254; i++ )  {
219                 j += 3;
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 )       {
222                         if (value==0)
223                                 return i;
224                         best_value = value;
225                         best_index = i;
226                 }
227         }
228         return best_index;
229 }
230
231
232 static int last_r=0, last_g=0, last_b=0;
233
234 void gr_palette_step_up( int r, int g, int b )
235 {
236         int i;
237         ubyte *p;
238         int temp;
239
240         if (gr_palette_faded_out) return;
241
242 #if !defined(POLY_ACC)      // need this called always.
243         if ( (r==last_r) && (g==last_g) && (b==last_b) ) return;
244 #endif
245
246         last_r = r;
247         last_g = g;
248         last_b = b;
249 #if defined(POLY_ACC)
250     if ( (r==0) && (g==0) && (b==0) ) return;
251          PA_DFX (pa_set_backbuffer_current());  
252     pa_step_up(r, g, b);
253     return; //POLY_ACC
254 #endif
255
256         outp( 0x3c6, 0xff );
257         outp( 0x3c8, 0 );
258         p=gr_palette;
259         for (i=0; i<256; i++ )  {
260                 temp = (int)(*p++) + r + gr_palette_gamma;
261                 if (temp<0) temp=0;
262                 else if (temp>63) temp=63;
263                 outp( 0x3c9, temp );
264                 temp = (int)(*p++) + g + gr_palette_gamma;
265                 if (temp<0) temp=0;
266                 else if (temp>63) temp=63;
267                 outp( 0x3c9, temp );
268                 temp = (int)(*p++) + b + gr_palette_gamma;
269                 if (temp<0) temp=0;
270                 else if (temp>63) temp=63;
271                 outp( 0x3c9, temp );
272         }
273 }
274
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 )
277 {
278         int i;
279         ubyte *p;
280         int temp;
281
282         if (gr_palette_faded_out) return;
283
284         if ( (r==last_r) && (g==last_g) && (b==last_b) ) return;
285
286         last_r = r;
287         last_g = g;
288         last_b = b;
289 #if defined(POLY_ACC)
290     return; //POLY_ACC
291 #endif
292
293         outp( 0x3c6, 0xff );
294         outp( 0x3c8, 0 );
295         p=gr_palette;
296         for (i=0; i<256; i++ )  {
297                 temp = (int)(*p++) + r + gr_palette_gamma;
298                 if (temp<0) temp=0;
299                 else if (temp>63) temp=63;
300                 if ( i==white_index )   temp = 63;
301                 else if ( i==black_index ) temp = 0;
302                 outp( 0x3c9, temp );
303                 temp = (int)(*p++) + g + gr_palette_gamma;
304                 if (temp<0) temp=0;
305                 else if (temp>63) temp=63;
306                 if ( i==white_index )   temp = 63;
307                 else if ( i==black_index ) temp = 0;
308                 outp( 0x3c9, temp );
309                 temp = (int)(*p++) + b + gr_palette_gamma;
310                 if (temp<0) temp=0;
311                 else if (temp>63) temp=63;
312                 if ( i==white_index )   temp = 63;
313                 else if ( i==black_index ) temp = 0;
314                 outp( 0x3c9, temp );
315         }
316 }
317
318
319 void gr_palette_clear()
320 {
321         int i;
322 #if !defined(POLY_ACC)
323         outp( 0x3c6, 0xff );
324         outp( 0x3c8, 0 );
325         for (i=0; i<768; i++ )  {
326                 outp( 0x3c9, 0 );
327         }
328 #endif
329         gr_palette_faded_out = 1;
330 }
331
332 void gr_palette_load( ubyte * pal )     
333 {
334         int i;
335         ubyte c;
336 #if !defined(POLY_ACC)
337         outp( 0x3c6, 0xff );
338         outp( 0x3c8, 0 );
339         for (i=0; i<768; i++ )  {
340                 c = pal[i] + gr_palette_gamma;
341                 if ( c > 63 ) c = 63;
342                 outp( 0x3c9,c);
343                 gr_current_pal[i] = pal[i];
344         }
345 #else
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;
350         }
351         pa_update_clut(gr_current_pal, 0, 256, 0);
352 #endif
353         gr_palette_faded_out = 0;
354
355 //      init_computed_colors();
356 }
357
358 extern void gr_sync_display(void);
359
360 int gr_palette_fade_out(ubyte *pal, int nsteps, int allow_keys )        
361 {
362         ubyte c;
363         int i,j;
364         fix fade_palette[768];
365         fix fade_palette_delta[768];
366
367         allow_keys  = allow_keys;
368
369         if (gr_palette_faded_out) return 0;
370
371         #ifndef NDEBUG
372         if (grd_fades_disabled) {
373                 gr_palette_clear();
374                 return 0;
375         }
376         #endif
377
378 #if defined(POLY_ACC)
379         return 0;
380 #endif
381
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;
385         }
386
387         for (j=0; j<nsteps; j++ )       {
388                 gr_sync_display();
389                 outp( 0x3c6, 0xff );
390                 outp( 0x3c8, 0 );
391                 for (i=0; i<768; i++ )  {               
392                         fade_palette[i] -= fade_palette_delta[i];
393                         if (fade_palette[i] < 0 )
394                                 fade_palette[i] = 0;
395                         c = f2i(fade_palette[i]);
396                         if ( c > 63 ) c = 63;
397                         outp( 0x3c9, c );                                                               
398                 }
399         }
400         gr_palette_faded_out = 1;
401         return 0;
402 }
403
404 int gr_palette_fade_in(ubyte *pal, int nsteps, int allow_keys)  
405 {
406         int i,j;
407         ubyte c;
408         fix fade_palette[768];
409         fix fade_palette_delta[768];
410
411         allow_keys  = allow_keys;
412
413         if (!gr_palette_faded_out) return 0;
414
415         #ifndef NDEBUG
416         if (grd_fades_disabled) {
417                 gr_palette_load(pal);
418                 return 0;
419         }
420         #endif
421
422 #if defined(POLY_ACC)
423         gr_palette_load(pal);
424                 return 0;
425 #endif
426
427         for (i=0; i<768; i++ )  {
428                 gr_current_pal[i] = pal[i];
429                 fade_palette[i] = 0;
430                 fade_palette_delta[i] = i2f(pal[i]+gr_palette_gamma) / nsteps;
431         }
432
433         for (j=0; j<nsteps; j++ )       {
434                 gr_sync_display();
435                 outp( 0x3c6, 0xff );
436                 outp( 0x3c8, 0 );
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;
443                         outp( 0x3c9, c );                                                               
444                 }
445         }
446         gr_palette_faded_out = 0;
447         return 0;
448 }
449
450 void gr_make_cthru_table(ubyte * table, ubyte r, ubyte g, ubyte b )
451 {
452         int i;
453         ubyte r1, g1, b1;
454
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 );
463         }
464 }
465
466 void gr_palette_read(ubyte * palette)
467 {
468         int i;
469
470 #if defined(POLY_ACC)
471     for(i = 0; i != 256; ++i)
472     {
473         *palette++ = (pa_clut[i] >> 9) & 0x3E;
474         *palette++ = (pa_clut[i] >> 4) & 0x3E;
475         *palette++ = (pa_clut[i] << 1) & 0x3E;
476     }
477 #else
478         outp( 0x3c6, 0xff );
479         outp( 0x3c7, 0 );
480         for (i=0; i<768; i++ )  {
481                 *palette++ = inp( 0x3c9 );
482         }
483 #endif
484
485 }
486