added cvsignore
[btb/d2x.git] / 2d / palette.c
1 /* $Id: palette.c,v 1.5 2002-08-15 07:17:39 btb 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 #include "palette.h"
39
40 extern int gr_installed;
41
42 ubyte gr_palette[256*3];
43 ubyte gr_current_pal[256*3];
44 ubyte gr_fade_table[256*34];
45
46 ubyte gr_palette_gamma = 0;
47 int gr_palette_gamma_param = 0;
48 ubyte gr_palette_faded_out = 1;
49
50 extern void gr_palette_load( ubyte * pal );
51
52 void gr_palette_set_gamma( int gamma )
53 {
54         if ( gamma < 0 ) gamma = 0;
55 //added/changed on 10/27/98 by Victor Rachels to increase brightness slider
56         if ( gamma > 16 ) gamma = 16;      //was 8
57 //end this section change - Victor Rachels
58
59         if (gr_palette_gamma_param != gamma )   {
60                 gr_palette_gamma_param = gamma;
61                 gr_palette_gamma = gamma;
62                 if (!gr_palette_faded_out)
63                         gr_palette_load( gr_palette );
64         }
65 }
66
67 int gr_palette_get_gamma()
68 {
69         return gr_palette_gamma_param;
70 }
71
72
73 void gr_use_palette_table( char * filename )
74 {
75         CFILE *fp;
76         int i,fsize;
77
78         fp = cfopen( filename, "rb" );
79
80         // the following is a hack to enable the loading of d2 levels
81         // even if only the d2 mac shareware datafiles are present.
82         // However, if the pig file is present but the palette file isn't,
83         // the textures in the level will look wierd...
84         if ( fp==NULL)
85                 fp = cfopen( DEFAULT_LEVEL_PALETTE, "rb" );
86         if ( fp==NULL)
87                 Error("Can open neither palette file <%s> "
88                       "nor default palette file <"
89                       DEFAULT_LEVEL_PALETTE
90                       ">.\n",
91                       filename);
92
93         fsize   = cfilelength( fp );
94         Assert( fsize == 9472 );
95         cfread( gr_palette, 256*3, 1, fp );
96         cfread( gr_fade_table, 256*34, 1, fp );
97         cfclose(fp);
98
99         // This is the TRANSPARENCY COLOR
100         for (i=0; i<GR_FADE_LEVELS; i++ )       {
101                 gr_fade_table[i*256+255] = 255;
102         }
103
104 }
105
106 #define SQUARE(x) ((x)*(x))
107
108 #define MAX_COMPUTED_COLORS     32
109
110 int     Num_computed_colors=0;
111
112 typedef struct {
113         ubyte   r,g,b,color_num;
114 } color_record;
115
116 color_record Computed_colors[MAX_COMPUTED_COLORS];
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 = (d_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 void gr_make_cthru_table(ubyte * table, ubyte r, ubyte g, ubyte b )
232 {
233         int i;
234         ubyte r1, g1, b1;
235
236         for (i=0; i<256; i++ )  {
237                 r1 = gr_palette[i*3+0] + r;
238                 if ( r1 > 63 ) r1 = 63;
239                 g1 = gr_palette[i*3+1] + g;
240                 if ( g1 > 63 ) g1 = 63;
241                 b1 = gr_palette[i*3+2] + b;
242                 if ( b1 > 63 ) b1 = 63;
243                 table[i] = gr_find_closest_color( r1, g1, b1 );
244         }
245 }
246