]> icculus.org git repositories - btb/d2x.git/blob - unused/vga/new/palette.c
Stuff
[btb/d2x.git] / unused / vga / new / 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         Assert( fsize == 9472 );
102         cfread( gr_palette, 256*3, 1, fp );
103         cfread( gr_fade_table, 256*34, 1, fp );
104         cfclose(fp);
105
106         // This is the TRANSPARENCY COLOR
107         for (i=0; i<GR_FADE_LEVELS; i++ )       {
108                 gr_fade_table[i*256+255] = 255;
109         }
110
111         Num_computed_colors = 0;        //      Flush palette cache.
112 #if defined(POLY_ACC)
113     pa_update_clut(gr_palette, 0, 256, 0);
114 #endif
115 }
116
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)
121 {
122         int     add_index;
123
124         if (Num_computed_colors < MAX_COMPUTED_COLORS) {
125                 add_index = Num_computed_colors;
126                 Num_computed_colors++;
127         } else
128                 add_index = (rand() * MAX_COMPUTED_COLORS) >> 15;
129
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;
134 }
135
136 void init_computed_colors(void)
137 {
138         int     i;
139
140         for (i=0; i<MAX_COMPUTED_COLORS; i++)
141                 Computed_colors[i].r = 255;             //      Make impossible to match.
142 }
143
144 int gr_find_closest_color( int r, int g, int b )
145 {
146         int i, j;
147         int best_value, best_index, value;
148
149         if (Num_computed_colors == 0)
150                 init_computed_colors();
151
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) {
157                                         if (i > 4) {
158                                                 color_record    trec;
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;
163                                         }
164                                         return Computed_colors[i].color_num;
165                                 }
166
167 //      r &= 63;
168 //      g &= 63;
169 //      b &= 63;
170
171         best_value = SQUARE(r-gr_palette[0])+SQUARE(g-gr_palette[1])+SQUARE(b-gr_palette[2]);
172         best_index = 0;
173         if (best_value==0) {
174                 add_computed_color(r, g, b, best_index);
175                 return best_index;
176         }
177         j=0;
178         // only go to 255, 'cause we dont want to check the transparent color.
179         for (i=1; i<254; i++ )  {
180                 j += 3;
181                 value = SQUARE(r-gr_palette[j])+SQUARE(g-gr_palette[j+1])+SQUARE(b-gr_palette[j+2]);
182                 if ( value < best_value )       {
183                         if (value==0) {
184                                 add_computed_color(r, g, b, i);
185                                 return i;
186                         }
187                         best_value = value;
188                         best_index = i;
189                 }
190         }
191         add_computed_color(r, g, b, best_index);
192         return best_index;
193 }
194
195 int gr_find_closest_color_15bpp( int rgb )
196 {
197         return gr_find_closest_color( ((rgb>>10)&31)*2, ((rgb>>5)&31)*2, (rgb&31)*2 );
198 }
199
200
201 int gr_find_closest_color_current( int r, int g, int b )
202 {
203         int i, j;
204         int best_value, best_index, value;
205
206 //      r &= 63;
207 //      g &= 63;
208 //      b &= 63;
209
210         best_value = SQUARE(r-gr_current_pal[0])+SQUARE(g-gr_current_pal[1])+SQUARE(b-gr_current_pal[2]);
211         best_index = 0;
212         if (best_value==0)
213                 return best_index;
214
215         j=0;
216         // only go to 255, 'cause we dont want to check the transparent color.
217         for (i=1; i<254; i++ )  {
218                 j += 3;
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 )       {
221                         if (value==0)
222                                 return i;
223                         best_value = value;
224                         best_index = i;
225                 }
226         }
227         return best_index;
228 }
229
230
231 static int last_r=0, last_g=0, last_b=0;
232
233 void gr_palette_step_up( int r, int g, int b )
234 {
235         int i;
236         ubyte *p;
237         int temp;
238
239         if (gr_palette_faded_out) return;
240
241 #if !defined(POLY_ACC)      // need this called always.
242         if ( (r==last_r) && (g==last_g) && (b==last_b) ) return;
243 #endif
244
245         last_r = r;
246         last_g = g;
247         last_b = b;
248 #if defined(POLY_ACC)
249     if ( (r==0) && (g==0) && (b==0) ) return;
250     pa_step_up(r, g, b);
251     return; //POLY_ACC
252 #endif
253
254         outp( 0x3c6, 0xff );
255         outp( 0x3c8, 0 );
256         p=gr_palette;
257         for (i=0; i<256; i++ )  {
258                 temp = (int)(*p++) + r + gr_palette_gamma;
259                 if (temp<0) temp=0;
260                 else if (temp>63) temp=63;
261                 outp( 0x3c9, temp );
262                 temp = (int)(*p++) + g + gr_palette_gamma;
263                 if (temp<0) temp=0;
264                 else if (temp>63) temp=63;
265                 outp( 0x3c9, temp );
266                 temp = (int)(*p++) + b + gr_palette_gamma;
267                 if (temp<0) temp=0;
268                 else if (temp>63) temp=63;
269                 outp( 0x3c9, temp );
270         }
271 }
272
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 )
275 {
276         int i;
277         ubyte *p;
278         int temp;
279
280         if (gr_palette_faded_out) return;
281
282         if ( (r==last_r) && (g==last_g) && (b==last_b) ) return;
283
284         last_r = r;
285         last_g = g;
286         last_b = b;
287 #if defined(POLY_ACC)
288     return; //POLY_ACC
289 #endif
290
291         outp( 0x3c6, 0xff );
292         outp( 0x3c8, 0 );
293         p=gr_palette;
294         for (i=0; i<256; i++ )  {
295                 temp = (int)(*p++) + r + gr_palette_gamma;
296                 if (temp<0) temp=0;
297                 else if (temp>63) temp=63;
298                 if ( i==white_index )   temp = 63;
299                 else if ( i==black_index ) temp = 0;
300                 outp( 0x3c9, temp );
301                 temp = (int)(*p++) + g + gr_palette_gamma;
302                 if (temp<0) temp=0;
303                 else if (temp>63) temp=63;
304                 if ( i==white_index )   temp = 63;
305                 else if ( i==black_index ) temp = 0;
306                 outp( 0x3c9, temp );
307                 temp = (int)(*p++) + b + gr_palette_gamma;
308                 if (temp<0) temp=0;
309                 else if (temp>63) temp=63;
310                 if ( i==white_index )   temp = 63;
311                 else if ( i==black_index ) temp = 0;
312                 outp( 0x3c9, temp );
313         }
314 }
315
316
317 void gr_palette_clear()
318 {
319         int i;
320 #if !defined(POLY_ACC)
321         outp( 0x3c6, 0xff );
322         outp( 0x3c8, 0 );
323         for (i=0; i<768; i++ )  {
324                 outp( 0x3c9, 0 );
325         }
326 #endif
327         gr_palette_faded_out = 1;
328 }
329
330 void gr_palette_load( ubyte * pal )     
331 {
332         int i;
333         ubyte c;
334 #if !defined(POLY_ACC)
335         outp( 0x3c6, 0xff );
336         outp( 0x3c8, 0 );
337         for (i=0; i<768; i++ )  {
338                 c = pal[i] + gr_palette_gamma;
339                 if ( c > 63 ) c = 63;
340                 outp( 0x3c9,c);
341                 gr_current_pal[i] = pal[i];
342         }
343 #else
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;
348         }
349         pa_update_clut(gr_current_pal, 0, 256, 0);
350 #endif
351         gr_palette_faded_out = 0;
352
353 //      init_computed_colors();
354 }
355
356 extern void gr_sync_display(void);
357
358 int gr_palette_fade_out(ubyte *pal, int nsteps, int allow_keys )        
359 {
360         ubyte c;
361         int i,j;
362         fix fade_palette[768];
363         fix fade_palette_delta[768];
364
365         allow_keys  = allow_keys;
366
367         if (gr_palette_faded_out) return 0;
368
369         #ifndef NDEBUG
370         if (grd_fades_disabled) {
371                 gr_palette_clear();
372                 return 0;
373         }
374         #endif
375
376 #if defined(POLY_ACC)
377         return 0;
378 #endif
379
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;
383         }
384
385         for (j=0; j<nsteps; j++ )       {
386                 gr_sync_display();
387                 outp( 0x3c6, 0xff );
388                 outp( 0x3c8, 0 );
389                 for (i=0; i<768; i++ )  {               
390                         fade_palette[i] -= fade_palette_delta[i];
391                         if (fade_palette[i] < 0 )
392                                 fade_palette[i] = 0;
393                         c = f2i(fade_palette[i]);
394                         if ( c > 63 ) c = 63;
395                         outp( 0x3c9, c );                                                               
396                 }
397         }
398         gr_palette_faded_out = 1;
399         return 0;
400 }
401
402 int gr_palette_fade_in(ubyte *pal, int nsteps, int allow_keys)  
403 {
404         int i,j;
405         ubyte c;
406         fix fade_palette[768];
407         fix fade_palette_delta[768];
408
409         allow_keys  = allow_keys;
410
411         if (!gr_palette_faded_out) return 0;
412
413         #ifndef NDEBUG
414         if (grd_fades_disabled) {
415                 gr_palette_load(pal);
416                 return 0;
417         }
418         #endif
419
420 #if defined(POLY_ACC)
421         gr_palette_load(pal);
422                 return 0;
423 #endif
424
425         for (i=0; i<768; i++ )  {
426                 gr_current_pal[i] = pal[i];
427                 fade_palette[i] = 0;
428                 fade_palette_delta[i] = i2f(pal[i]+gr_palette_gamma) / nsteps;
429         }
430
431         for (j=0; j<nsteps; j++ )       {
432                 gr_sync_display();
433                 outp( 0x3c6, 0xff );
434                 outp( 0x3c8, 0 );
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;
441                         outp( 0x3c9, c );                                                               
442                 }
443         }
444         gr_palette_faded_out = 0;
445         return 0;
446 }
447
448 void gr_make_cthru_table(ubyte * table, ubyte r, ubyte g, ubyte b )
449 {
450         int i;
451         ubyte r1, g1, b1;
452
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 );
461         }
462 }
463
464 void gr_palette_read(ubyte * palette)
465 {
466         int i;
467
468 #if defined(POLY_ACC)
469     for(i = 0; i != 256; ++i)
470     {
471         *palette++ = (pa_clut[i] >> 9) & 0x3E;
472         *palette++ = (pa_clut[i] >> 4) & 0x3E;
473         *palette++ = (pa_clut[i] << 1) & 0x3E;
474     }
475 #else
476         outp( 0x3c6, 0xff );
477         outp( 0x3c7, 0 );
478         for (i=0; i<768; i++ )  {
479                 *palette++ = inp( 0x3c9 );
480         }
481 #endif
482
483 }
484