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