]> icculus.org git repositories - btb/d2x.git/blob - unused/vga/palette.c
remove rcs tags
[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 #include <conio.h>
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <io.h>
18 #include <string.h>
19
20 #include "pa_enabl.h"                   //$$POLY_ACC
21 #include "types.h"
22 #include "mem.h"
23 #include "gr.h"
24 #include "grdef.h"
25 #include "cfile.h"
26 #include "error.h"
27 #include "mono.h"
28 #include "fix.h"
29 #include "key.h"
30
31 #if defined(POLY_ACC)
32 #include "poly_acc.h"
33 #endif
34
35 extern int gr_installed;
36
37 #define SQUARE(x) ((x)*(x))
38
39 #define MAX_COMPUTED_COLORS     32
40
41 int     Num_computed_colors=0;
42
43 typedef struct {
44         ubyte   r,g,b,color_num;
45 } color_record;
46
47 color_record Computed_colors[MAX_COMPUTED_COLORS];
48
49 ubyte gr_palette[256*3];
50 ubyte gr_current_pal[256*3];
51 ubyte gr_fade_table[256*34];
52
53 // ushort gr_palette_selector;
54 // ushort gr_fade_table_selector;
55
56 ubyte gr_palette_gamma = 0;
57 int gr_palette_gamma_param = 0;
58 ubyte gr_palette_faded_out = 1;
59
60 //to speed up development
61 int grd_fades_disabled=0;
62
63 void gr_palette_set_gamma( int gamma )
64 {
65         if ( gamma < 0 ) gamma = 0;
66         if ( gamma > 8 ) gamma = 8;
67
68         if (gr_palette_gamma_param != gamma )   {
69                 gr_palette_gamma_param = gamma;
70                 gr_palette_gamma = gamma;
71                 if (!gr_palette_faded_out)
72                         gr_palette_load( gr_palette );
73         }       
74 }
75
76 int gr_palette_get_gamma()
77 {
78         return gr_palette_gamma_param;
79 }
80
81
82 void gr_copy_palette(ubyte *gr_palette, ubyte *pal, int size)
83 {
84         memcpy(gr_palette, pal, size);
85
86         Num_computed_colors = 0;
87 }
88
89 void gr_use_palette_table( char * filename )
90 {
91         CFILE *fp;
92         int i,fsize;
93
94         fp = cfopen( filename, "rb" );
95         if ( fp==NULL)
96                 Error("Can't open palette file <%s>",filename);
97
98         fsize   = cfilelength( fp );
99         if ( fsize != 9472)
100                 Error("Palette file <%s> is wrong size",filename);
101         cfread( gr_palette, 256*3, 1, fp );
102         cfread( gr_fade_table, 256*34, 1, fp );
103         cfclose(fp);
104
105         // This is the TRANSPARENCY COLOR
106         for (i=0; i<GR_FADE_LEVELS; i++ )       {
107                 gr_fade_table[i*256+255] = 255;
108         }
109
110         Num_computed_colors = 0;        //      Flush palette cache.
111 #if defined(POLY_ACC)
112     pa_update_clut(gr_palette, 0, 256, 0);
113 #endif
114 }
115
116 //      Add a computed color (by gr_find_closest_color) to list of computed colors in Computed_colors.
117 //      If list wasn't full already, increment Num_computed_colors.
118 //      If was full, replace a random one.
119 void add_computed_color(int r, int g, int b, int color_num)
120 {
121         int     add_index;
122
123         if (Num_computed_colors < MAX_COMPUTED_COLORS) {
124                 add_index = Num_computed_colors;
125                 Num_computed_colors++;
126         } else
127                 add_index = (rand() * MAX_COMPUTED_COLORS) >> 15;
128
129         Computed_colors[add_index].r = r;
130         Computed_colors[add_index].g = g;
131         Computed_colors[add_index].b = b;
132         Computed_colors[add_index].color_num = color_num;
133 }
134
135 void init_computed_colors(void)
136 {
137         int     i;
138
139         for (i=0; i<MAX_COMPUTED_COLORS; i++)
140                 Computed_colors[i].r = 255;             //      Make impossible to match.
141 }
142
143 int gr_find_closest_color( int r, int g, int b )
144 {
145         int i, j;
146         int best_value, best_index, value;
147
148         if (Num_computed_colors == 0)
149                 init_computed_colors();
150
151         //      If we've already computed this color, return it!
152         for (i=0; i<Num_computed_colors; i++)
153                 if (r == Computed_colors[i].r)
154                         if (g == Computed_colors[i].g)
155                                 if (b == Computed_colors[i].b) {
156                                         if (i > 4) {
157                                                 color_record    trec;
158                                                 trec = Computed_colors[i-1];
159                                                 Computed_colors[i-1] = Computed_colors[i];
160                                                 Computed_colors[i] = trec;
161                                                 return Computed_colors[i-1].color_num;
162                                         }
163                                         return Computed_colors[i].color_num;
164                                 }
165
166 //      r &= 63;
167 //      g &= 63;
168 //      b &= 63;
169
170         best_value = SQUARE(r-gr_palette[0])+SQUARE(g-gr_palette[1])+SQUARE(b-gr_palette[2]);
171         best_index = 0;
172         if (best_value==0) {
173                 add_computed_color(r, g, b, best_index);
174                 return best_index;
175         }
176         j=0;
177         // only go to 255, 'cause we dont want to check the transparent color.
178         for (i=1; i<254; i++ )  {
179                 j += 3;
180                 value = SQUARE(r-gr_palette[j])+SQUARE(g-gr_palette[j+1])+SQUARE(b-gr_palette[j+2]);
181                 if ( value < best_value )       {
182                         if (value==0) {
183                                 add_computed_color(r, g, b, i);
184                                 return i;
185                         }
186                         best_value = value;
187                         best_index = i;
188                 }
189         }
190         add_computed_color(r, g, b, best_index);
191         return best_index;
192 }
193
194 int gr_find_closest_color_15bpp( int rgb )
195 {
196         return gr_find_closest_color( ((rgb>>10)&31)*2, ((rgb>>5)&31)*2, (rgb&31)*2 );
197 }
198
199
200 int gr_find_closest_color_current( int r, int g, int b )
201 {
202         int i, j;
203         int best_value, best_index, value;
204
205 //      r &= 63;
206 //      g &= 63;
207 //      b &= 63;
208
209         best_value = SQUARE(r-gr_current_pal[0])+SQUARE(g-gr_current_pal[1])+SQUARE(b-gr_current_pal[2]);
210         best_index = 0;
211         if (best_value==0)
212                 return best_index;
213
214         j=0;
215         // only go to 255, 'cause we dont want to check the transparent color.
216         for (i=1; i<254; i++ )  {
217                 j += 3;
218                 value = SQUARE(r-gr_current_pal[j])+SQUARE(g-gr_current_pal[j+1])+SQUARE(b-gr_current_pal[j+2]);
219                 if ( value < best_value )       {
220                         if (value==0)
221                                 return i;
222                         best_value = value;
223                         best_index = i;
224                 }
225         }
226         return best_index;
227 }
228
229
230 static int last_r=0, last_g=0, last_b=0;
231
232 void gr_palette_step_up( int r, int g, int b )
233 {
234         int i;
235         ubyte *p;
236         int temp;
237
238         if (gr_palette_faded_out) return;
239
240 #if !defined(POLY_ACC)      // need this called always.
241         if ( (r==last_r) && (g==last_g) && (b==last_b) ) return;
242 #endif
243
244         last_r = r;
245         last_g = g;
246         last_b = b;
247 #if defined(POLY_ACC)
248     if ( (r==0) && (g==0) && (b==0) ) return;
249          PA_DFX (pa_set_backbuffer_current());  
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