1 //-------------------------------------------------------------------------
2 /*
3 Copyright (C) 1997, 2005 - 3D Realms Entertainment
4
5 This file is part of Shadow Warrior version 1.2
6
7 Shadow Warrior is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16 See the GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22 Original Source: 1997 - Frank Maddin and Jim Norwood
23 Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms
24 */
25 //-------------------------------------------------------------------------
26 #include "build.h"
27
28 #include "keys.h"
29 #include "pal.h"
30 #include "game.h"
31
32 short f_c = 3;
33 static unsigned char tempbuf[256];
34 unsigned char DefaultPalette[256 * 32];
35 #if 1
36 VOID
MapColors(short num,COLOR_MAP cm,short create)37 MapColors(short num, COLOR_MAP cm, short create)
38 {
39 int i;
40 float inc;
41
42 if (create)
43 {
44 for (i = 0; i < 256; i++)
45 tempbuf[i] = i;
46 }
47
48 if (cm.FromRange == 0 || num <= 0 || num >= 256)
49 {
50 return;
51 }
52
53 inc = cm.ToRange/((float)cm.FromRange);
54
55 for (i = 0; i < cm.FromRange; i++)
56 tempbuf[i + cm.FromColor] = (i*inc) + cm.ToColor;
57 }
58 #else
59 VOID
MapColors(short num,COLOR_MAP cm,short create)60 MapColors(short num, COLOR_MAP cm, short create)
61 {
62 int i;
63
64 if (create)
65 {
66 for (i = 0; i < 256; i++)
67 tempbuf[i] = i;
68 }
69
70 if (cm.FromRange == 0 || num <= 0 || num >= 256)
71 {
72 return;
73 }
74
75 // from 32 to 32 || 16 to 16
76 if (cm.ToRange == cm.FromRange)
77 {
78 for (i = 0; i < cm.FromRange; i++)
79 tempbuf[i + cm.FromColor] = i + cm.ToColor;
80
81 // Quick fix for grey
82 if(cm.ToColor == LT_GREY)
83 tempbuf[cm.FromColor+31] = 0; // Set to black
84 }
85 else
86 // from 32 to 16
87 if (cm.ToRange == DIV2(cm.FromRange))
88 {
89 for (i = 0; i < cm.FromRange; i++)
90 tempbuf[cm.FromColor + i] = cm.ToColor + DIV2(i);
91 }
92 else
93 // from 16 to 32
94 if (DIV2(cm.ToRange) == cm.FromRange)
95 {
96 for (i = 0; i < cm.FromRange; i++)
97 tempbuf[cm.FromColor + DIV2(i)] = cm.ToColor;
98
99 // Quick fix for grey
100 if(cm.ToColor == LT_GREY)
101 tempbuf[cm.FromColor+31] = 0; // Set to black
102 }
103 }
104 #endif
105
106 #define PLAYER_COLOR_MAPS 15
107 static COLOR_MAP PlayerColorMap[PLAYER_COLOR_MAPS][1] =
108 {
109
110 {
111 {32, 32, LT_BLUE, LT_BROWN},
112 },
113 {
114 {32, 31, LT_BLUE, LT_GREY},
115 },
116 {
117 {32, 16, LT_BLUE, PURPLE}
118 },
119 {
120 {32, 16, LT_BLUE, RUST_RED},
121 },
122 {
123 {32, 16, LT_BLUE, YELLOW},
124 },
125 {
126 {32, 16, LT_BLUE, DK_GREEN},
127 },
128 {
129 {32, 16, LT_BLUE, GREEN},
130 },
131 {
132 {32, 32, LT_BLUE, LT_BLUE}, // Redundant, but has to be here for position
133 },
134 {
135 {32, 32, LT_BLUE, LT_TAN},
136 },
137 {
138 {32, 16, LT_BLUE, RED},
139 },
140 {
141 {32, 16, LT_BLUE, DK_GREY},
142 },
143 {
144 {32, 16, LT_BLUE, BRIGHT_GREEN},
145 },
146 {
147 {32, 16, LT_BLUE, DK_BLUE},
148 },
149 {
150 {32, 16, LT_BLUE, FIRE},
151 },
152 {
153 {32, 16, LT_BLUE, FIRE},
154 }
155
156 };
157
158 VOID
InitPalette(VOID)159 InitPalette(VOID)
160 {
161 static COLOR_MAP AllToRed[] =
162 {
163 {31, 16, LT_GREY, RED},
164 {32, 16, LT_BROWN, RED},
165 {32, 16, LT_TAN, RED},
166 {16, 16, RUST_RED, RED},
167 {16, 16, YELLOW, RED},
168 {16, 16, BRIGHT_GREEN, RED},
169 {16, 16, DK_GREEN, RED},
170 {16, 16, GREEN, RED},
171 {32, 16, LT_BLUE, RED},
172 {16, 16, PURPLE, RED},
173 {16, 16, FIRE, RED}
174 };
175
176 static COLOR_MAP AllToBlue[] =
177 {
178 {31, 32, LT_GREY, LT_BLUE},
179 {32, 32, LT_BROWN, LT_BLUE},
180 {32, 32, LT_TAN, LT_BLUE},
181 {16, 32, RUST_RED, LT_BLUE},
182 {16, 32, YELLOW, LT_BLUE},
183 {16, 32, BRIGHT_GREEN, LT_BLUE},
184 {16, 32, DK_GREEN, LT_BLUE},
185 {16, 32, GREEN, LT_BLUE},
186 {16, 32, RED, LT_BLUE},
187 {16, 32, PURPLE, LT_BLUE},
188 {16, 32, FIRE, LT_BLUE}
189 };
190
191 static COLOR_MAP AllToGreen[] =
192 {
193 {31, 16, LT_GREY, GREEN},
194 {32, 16, LT_BROWN, GREEN},
195 {32, 16, LT_TAN, GREEN},
196 {16, 16, RUST_RED, GREEN},
197 {16, 16, YELLOW, GREEN},
198 {16, 16, BRIGHT_GREEN, GREEN},
199 {16, 16, DK_GREEN, GREEN},
200 {16, 16, GREEN, GREEN},
201 {32, 16, LT_BLUE, GREEN},
202 {16, 16, RED, GREEN},
203 {16, 16, PURPLE, GREEN},
204 {16, 16, FIRE, GREEN}
205 };
206
207 static COLOR_MAP NinjaBasic[] =
208 {
209 {32, 16, LT_TAN, DK_GREY},
210 {32, 16, LT_BROWN,DK_GREY},
211 {32, 31, LT_BLUE,LT_GREY},
212 {16, 16, DK_GREEN,DK_GREY},
213 {16, 16, GREEN, DK_GREY},
214 {16, 16, YELLOW, DK_GREY}
215 };
216
217 static COLOR_MAP NinjaRed[] =
218 {
219 {16, 16, DK_TAN, DK_GREY},
220 {16, 16, GREEN, DK_TAN},
221 {16, 8, DK_BROWN, RED + 8},
222
223 {32, 16, LT_BLUE, RED}
224 };
225
226 static COLOR_MAP NinjaGreen[] =
227 {
228 {16, 16, DK_TAN, DK_GREY},
229 {16, 16, GREEN, DK_TAN},
230 {16, 8, DK_BROWN, GREEN + 6},
231
232 {32, 16, LT_BLUE, GREEN}
233 };
234
235 static COLOR_MAP Illuminate[] =
236 {
237 {16, 8, LT_GREY, BRIGHT_GREEN},
238 {16, 8, DK_GREY, BRIGHT_GREEN},
239 {16, 8, LT_BROWN, BRIGHT_GREEN},
240 {16, 8, DK_BROWN, BRIGHT_GREEN},
241 {16, 8, LT_TAN, BRIGHT_GREEN},
242 {16, 8, DK_TAN, BRIGHT_GREEN},
243 {16, 8, RUST_RED, BRIGHT_GREEN},
244 {16, 8, YELLOW, BRIGHT_GREEN},
245 {16, 8, DK_GREEN, BRIGHT_GREEN},
246 {16, 8, GREEN, BRIGHT_GREEN},
247 {32, 8, LT_BLUE, BRIGHT_GREEN},
248 {16, 8, RED, BRIGHT_GREEN},
249 {16, 8, PURPLE, BRIGHT_GREEN},
250 {16, 8, FIRE, BRIGHT_GREEN}
251 };
252
253 static COLOR_MAP BrownRipper = {31, 32, LT_GREY, LT_TAN};
254
255 static COLOR_MAP SkelGore = {16, 16, RED, BRIGHT_GREEN};
256 static COLOR_MAP ElectroGore = {16, 16, RED, DK_BLUE};
257
258 static COLOR_MAP MenuHighlight = {16, 16, RED, FIRE};
259
260 unsigned int i;
261 short play;
262
263 #if 0
264 // I need this for doing fog... Not sure why it wasn't already here.
265 initfastcolorlookup(1,1,1);
266 #endif
267
268 //
269 // Save default palette
270 //
271
272 memcpy(DefaultPalette, palookup[PALETTE_DEFAULT], 256 * numpalookups);
273
274 //
275 // Dive palettes
276 //
277
278 for (i = 0; i < 256; i++)
279 tempbuf[i] = i;
280 // palette for underwater
281 makepalookup(PALETTE_DIVE, tempbuf, 0, 0, 15, TRUE);
282
283 #define FOG_AMT 15
284 for (i = 0; i < 256; i++)
285 tempbuf[i] = i;
286 makepalookup(PALETTE_FOG, tempbuf, FOG_AMT, FOG_AMT, FOG_AMT, TRUE);
287
288 for (i = 0; i < 256; i++)
289 tempbuf[i] = i;
290 makepalookup(PALETTE_DIVE_LAVA, tempbuf, 11, 0, 0, TRUE);
291
292 //
293 // 1 Range changes
294 //
295
296 MapColors(PALETTE_BROWN_RIPPER, BrownRipper, TRUE);
297 makepalookup(PALETTE_BROWN_RIPPER, tempbuf, 0, 0, 0, TRUE);
298
299 MapColors(PALETTE_SKEL_GORE, SkelGore, TRUE);
300 makepalookup(PALETTE_SKEL_GORE, tempbuf, 0, 0, 0, TRUE);
301
302 MapColors(PALETTE_ELECTRO_GORE, ElectroGore, TRUE);
303 makepalookup(PALETTE_ELECTRO_GORE, tempbuf, 0, 0, 0, TRUE);
304
305 MapColors(PALETTE_MENU_HIGHLIGHT, MenuHighlight, TRUE);
306 makepalookup(PALETTE_MENU_HIGHLIGHT, tempbuf, 0, 0, 0, TRUE);
307
308 //
309 // Multiple range changes
310 //
311
312 MapColors(PALETTE_BASIC_NINJA, NinjaBasic[0], TRUE);
313 for (i = 1; i < SIZ(NinjaBasic); i++)
314 MapColors(PALETTE_BASIC_NINJA, NinjaBasic[i], FALSE);
315 makepalookup(PALETTE_BASIC_NINJA, tempbuf, 0, 0, 0, TRUE);
316
317 MapColors(PALETTE_RED_NINJA, NinjaRed[0], TRUE);
318 for (i = 1; i < SIZ(NinjaRed); i++)
319 MapColors(PALETTE_RED_NINJA, NinjaRed[i], FALSE);
320 makepalookup(PALETTE_RED_NINJA, tempbuf, 0, 0, 0, TRUE);
321
322 MapColors(PALETTE_GREEN_NINJA, NinjaGreen[0], TRUE);
323 for (i = 1; i < SIZ(NinjaGreen); i++)
324 MapColors(PALETTE_GREEN_NINJA, NinjaGreen[i], FALSE);
325 makepalookup(PALETTE_GREEN_NINJA, tempbuf, 0, 0, 0, TRUE);
326
327 MapColors(PALETTE_GREEN_LIGHTING, AllToGreen[0], TRUE);
328 for (i = 1; i < SIZ(AllToGreen); i++)
329 MapColors(PALETTE_GREEN_LIGHTING, AllToGreen[i], FALSE);
330 makepalookup(PALETTE_GREEN_LIGHTING, tempbuf, 0, 0, 0, TRUE);
331
332 MapColors(PALETTE_RED_LIGHTING, AllToRed[0], TRUE);
333 for (i = 1; i < SIZ(AllToRed); i++)
334 MapColors(PALETTE_RED_LIGHTING, AllToRed[i], FALSE);
335 makepalookup(PALETTE_RED_LIGHTING, tempbuf, 0, 0, 0, TRUE);
336
337 MapColors(PALETTE_BLUE_LIGHTING, AllToBlue[0], TRUE);
338 for (i = 1; i < SIZ(AllToBlue); i++)
339 MapColors(PALETTE_BLUE_LIGHTING, AllToBlue[i], FALSE);
340 makepalookup(PALETTE_BLUE_LIGHTING, tempbuf, 0, 0, 0, TRUE);
341
342 MapColors(PALETTE_ILLUMINATE, Illuminate[0], TRUE);
343 for (i = 1; i < SIZ(Illuminate); i++)
344 MapColors(PALETTE_ILLUMINATE, Illuminate[i], FALSE);
345 makepalookup(PALETTE_ILLUMINATE, tempbuf, 0, 0, 0, TRUE);
346
347 // PLAYER COLORS - ALSO USED FOR OTHER THINGS
348 for (play = 0; play < PLAYER_COLOR_MAPS; play++)
349 {
350 MapColors(PALETTE_PLAYER0 + play, PlayerColorMap[play][0], TRUE);
351 MapColors(PALETTE_PLAYER0 + play, PlayerColorMap[play][0], FALSE);
352 makepalookup(PALETTE_PLAYER0 + play, tempbuf, 0, 0, 0, TRUE);
353 }
354
355 //
356 // Special Brown sludge
357 //
358
359 for (i = 0; i < 256; i++)
360 tempbuf[i] = i;
361 // invert the brown palette
362 for (i = 0; i < 32; i++)
363 tempbuf[LT_BROWN + i] = (LT_BROWN + 32) - i;
364 makepalookup(PALETTE_SLUDGE, tempbuf, 0, 0, 0, TRUE);
365
366 }
367
368
369 /*
370 2. You must now use my function to set or get any palette
371 registers.This means that the keywords "3c7", "3c8", and "3c9" should not even exist in your code.I really
372 didn 't want to force you to use my palette functions, but
373 since VESA 2.0 supports non VGA compatible cards, you must
374 do
375 it this way.If you use setbrightness for all of your
376 palette setting, then you can ignore this.Note that the
377 palette format here is VESA 's palette format, which is
378 different than my other palette control functions.It 's
379 4 bytes and RGB are backwards.Here are the function
380 prototypes:
381
382 VBE_setPalette(long palstart, long palnum, char *dapal);
383
384 VBE_getPalette(long palstart, long palnum, char *dapal);
385 palstart is the offset of the first palette to set
386 palnum is the number of the palette entries to set
387 dapal is a pointer to the palette buffer.The palette
388 buffer must be in this format:
389 char Blue, Green, Red, reserved;
390 I think this format stinks, but since VESA 2.0 uses
391 it, the code will run fastest if the buffer is not
392 copied.You can make your own cover up function if
393 you don 't like this format.
394
395 This example sets up a wasteful gray scale palette:
396
397 char mypalette[1024];
398
399 for (i = 0; i < 256; i++)
400 {
401 mypalette[i * 4 + 0] = (i >> 2); // Blue
402 mypalette[i * 4 + 1] = (i >> 2); // Green
403 mypalette[i * 4 + 2] = (i >> 2); // Red
404 mypalette[i * 4 + 3] = 0; // reserved
405 }
406 VBE_setPalette(0, 256, mypalette);
407 */
408
409 #define ORED 0
410 #define OGREEN 1
411 #define OBLUE 2
412
413 #define NBLUE 0
414 #define NGREEN 1
415 #define NRED 2
416 #define NRESERVED 3
417
SetPaletteToVESA(unsigned char * pal)418 VOID SetPaletteToVESA(unsigned char *pal)
419 {
420 /*
421 char pal_buff[1024];
422 short i;
423
424 for (i = 0; i < 256; i++)
425 {
426 pal_buff[i * 4 + NRED] = pal[i * 3 + ORED];
427 pal_buff[i * 4 + NGREEN] = pal[i * 3 + OGREEN];
428 pal_buff[i * 4 + NBLUE] = pal[i * 3 + OBLUE];
429 pal_buff[i * 4 + NRESERVED] = 0;
430 }
431
432 VBE_setPalette(0, 256, pal_buff);
433 */
434 setbrightness(0,pal,4|2);
435 // fprintf(stderr,"SetPaletteToVESA() called\n");
436 }
437
set_pal(unsigned char * pal)438 VOID set_pal(unsigned char *pal)
439 {
440 SetPaletteToVESA(pal);
441 }
442
GetPaletteFromVESA(unsigned char * pal)443 VOID GetPaletteFromVESA(unsigned char *pal)
444 {
445 /*
446 char pal_buff[1024];
447 short i;
448
449 VBE_getPalette(0, 256, pal_buff);
450
451 for (i = 0; i < 256; i++)
452 {
453 pal[i * 3 + ORED] = pal_buff[i * 4 + NRED];
454 pal[i * 3 + OGREEN] = pal_buff[i * 4 + NGREEN];
455 pal[i * 3 + OBLUE] = pal_buff[i * 4 + NBLUE];
456 }
457 */
458 int i;
459 for (i=0;i<256;i++) {
460 pal[i*3+0] = curpalette[i].r>>2;
461 pal[i*3+1] = curpalette[i].g>>2;
462 pal[i*3+2] = curpalette[i].b>>2;
463 }
464 // fprintf(stderr,"GetPaletteFromVESA() called\n");
465 }
466