use simpler rcs tags
[btb/d2x.git] / 2d / palette.c
1 /* $Id: palette.c,v 1.3 2002-07-17 21:55:19 bradleyb Exp $ */
2 /*
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.
13 */
14 /*
15  * Graphical routines for setting the palette
16  *
17  */
18
19 #ifdef HAVE_CONFIG_H
20 #include <conf.h>
21 #endif
22
23 #include <stdlib.h>
24 #include <stdio.h>
25
26 #include "pstypes.h"
27 #include "u_mem.h"
28 #include "gr.h"
29 #include "grdef.h"
30 #include "cfile.h"
31 #include "error.h"
32 #include "mono.h"
33 #include "fix.h"
34 //added/remove by dph on 1/9/99
35 //#include "key.h"
36 //end remove
37
38 extern int gr_installed;
39
40 ubyte gr_palette[256*3];
41 ubyte gr_current_pal[256*3];
42 ubyte gr_fade_table[256*34];
43
44 ubyte gr_palette_gamma = 0;
45 int gr_palette_gamma_param = 0;
46 ubyte gr_palette_faded_out = 1;
47
48 extern void gr_palette_load( ubyte * pal );
49
50 void gr_palette_set_gamma( int gamma )
51 {
52         if ( gamma < 0 ) gamma = 0;
53 //added/changed on 10/27/98 by Victor Rachels to increase brightness slider
54         if ( gamma > 16 ) gamma = 16;      //was 8
55 //end this section change - Victor Rachels 
56
57         if (gr_palette_gamma_param != gamma )   {
58                 gr_palette_gamma_param = gamma;
59                 gr_palette_gamma = gamma;
60                 if (!gr_palette_faded_out)
61                         gr_palette_load( gr_palette );
62         }       
63 }
64
65 int gr_palette_get_gamma()
66 {
67         return gr_palette_gamma_param;
68 }
69
70
71 void gr_use_palette_table( char * filename )
72 {
73         CFILE *fp;
74         int i,fsize;
75
76         fp = cfopen( filename, "rb" );
77         if ( fp==NULL)
78                 Error("Can't open palette file <%s>",filename);
79
80         fsize   = cfilelength( fp );
81         Assert( fsize == 9472 );
82         cfread( gr_palette, 256*3, 1, fp );
83         cfread( gr_fade_table, 256*34, 1, fp );
84         cfclose(fp);
85
86         // This is the TRANSPARENCY COLOR
87         for (i=0; i<GR_FADE_LEVELS; i++ )       {
88                 gr_fade_table[i*256+255] = 255;
89         }
90
91 }
92
93 #define SQUARE(x) ((x)*(x))
94
95 #define MAX_COMPUTED_COLORS     32
96
97 int     Num_computed_colors=0;
98
99 typedef struct {
100         ubyte   r,g,b,color_num;
101 } color_record;
102
103 color_record Computed_colors[MAX_COMPUTED_COLORS];
104
105 //      Add a computed color (by gr_find_closest_color) to list of computed colors in Computed_colors.
106 //      If list wasn't full already, increment Num_computed_colors.
107 //      If was full, replace a random one.
108 void add_computed_color(int r, int g, int b, int color_num)
109 {
110         int     add_index;
111
112         if (Num_computed_colors < MAX_COMPUTED_COLORS) {
113                 add_index = Num_computed_colors;
114                 Num_computed_colors++;
115         } else
116                 add_index = (d_rand() * MAX_COMPUTED_COLORS) >> 15;
117
118         Computed_colors[add_index].r = r;
119         Computed_colors[add_index].g = g;
120         Computed_colors[add_index].b = b;
121         Computed_colors[add_index].color_num = color_num;
122 }
123
124 void init_computed_colors(void)
125 {
126         int     i;
127
128         for (i=0; i<MAX_COMPUTED_COLORS; i++)
129                 Computed_colors[i].r = 255;             //      Make impossible to match.
130 }
131
132 int gr_find_closest_color( int r, int g, int b )
133 {
134         int i, j;
135         int best_value, best_index, value;
136
137         if (Num_computed_colors == 0)
138                 init_computed_colors();
139
140         //      If we've already computed this color, return it!
141         for (i=0; i<Num_computed_colors; i++)
142                 if (r == Computed_colors[i].r)
143                         if (g == Computed_colors[i].g)
144                                 if (b == Computed_colors[i].b) {
145                                         if (i > 4) {
146                                                 color_record    trec;
147                                                 trec = Computed_colors[i-1];
148                                                 Computed_colors[i-1] = Computed_colors[i];
149                                                 Computed_colors[i] = trec;
150                                                 return Computed_colors[i-1].color_num;
151                                         }
152                                         return Computed_colors[i].color_num;
153                                 }
154
155 //      r &= 63;
156 //      g &= 63;
157 //      b &= 63;
158
159         best_value = SQUARE(r-gr_palette[0])+SQUARE(g-gr_palette[1])+SQUARE(b-gr_palette[2]);
160         best_index = 0;
161         if (best_value==0) {
162                 add_computed_color(r, g, b, best_index);
163                 return best_index;
164         }
165         j=0;
166         // only go to 255, 'cause we dont want to check the transparent color.
167         for (i=1; i<254; i++ )  {
168                 j += 3;
169                 value = SQUARE(r-gr_palette[j])+SQUARE(g-gr_palette[j+1])+SQUARE(b-gr_palette[j+2]);
170                 if ( value < best_value )       {
171                         if (value==0) {
172                                 add_computed_color(r, g, b, i);
173                                 return i;
174                         }
175                         best_value = value;
176                         best_index = i;
177                 }
178         }
179         add_computed_color(r, g, b, best_index);
180         return best_index;
181 }
182
183 int gr_find_closest_color_15bpp( int rgb )
184 {
185         return gr_find_closest_color( ((rgb>>10)&31)*2, ((rgb>>5)&31)*2, (rgb&31)*2 );
186 }
187
188
189 int gr_find_closest_color_current( int r, int g, int b )
190 {
191         int i, j;
192         int best_value, best_index, value;
193
194 //      r &= 63;
195 //      g &= 63;
196 //      b &= 63;
197
198         best_value = SQUARE(r-gr_current_pal[0])+SQUARE(g-gr_current_pal[1])+SQUARE(b-gr_current_pal[2]);
199         best_index = 0;
200         if (best_value==0)
201                 return best_index;
202
203         j=0;
204         // only go to 255, 'cause we dont want to check the transparent color.
205         for (i=1; i<254; i++ )  {
206                 j += 3;
207                 value = SQUARE(r-gr_current_pal[j])+SQUARE(g-gr_current_pal[j+1])+SQUARE(b-gr_current_pal[j+2]);
208                 if ( value < best_value )       {
209                         if (value==0)
210                                 return i;
211                         best_value = value;
212                         best_index = i;
213                 }
214         }
215         return best_index;
216 }
217
218 void gr_make_cthru_table(ubyte * table, ubyte r, ubyte g, ubyte b )
219 {
220         int i;
221         ubyte r1, g1, b1;
222
223         for (i=0; i<256; i++ )  {
224                 r1 = gr_palette[i*3+0] + r;
225                 if ( r1 > 63 ) r1 = 63;
226                 g1 = gr_palette[i*3+1] + g;
227                 if ( g1 > 63 ) g1 = 63;
228                 b1 = gr_palette[i*3+2] + b;
229                 if ( b1 > 63 ) b1 = 63;
230                 table[i] = gr_find_closest_color( r1, g1, b1 );
231         }
232 }
233