2 * $Logfile: /Freespace2/code/Graphics/Colors.cpp $
7 * Functions to deal with colors & alphacolors
10 * Revision 1.2 2002/05/07 03:16:45 theoddone33
11 * The Great Newline Fix
13 * Revision 1.1.1.1 2002/05/03 03:28:09 root
17 * 7 7/08/99 10:52a Dave
18 * New multiplayer interpolation scheme. Not 100% done yet, but still
19 * better than the old way.
21 * 6 1/14/99 12:48a Dave
22 * Todo list bug fixes. Made a pass at putting briefing icons back into
23 * FRED. Sort of works :(
25 * 5 12/02/98 5:47p Dave
26 * Put in interface xstr code. Converted barracks screen to new format.
28 * 4 11/30/98 5:31p Dave
29 * Fixed up Fred support for software mode.
31 * 3 11/30/98 1:07p Dave
32 * 16 bit conversion, first run.
34 * 2 10/07/98 10:52a Dave
37 * 1 10/07/98 10:48a Dave
39 * 35 5/19/98 3:32p John
42 * 34 5/13/98 10:22p John
43 * Added cfile functions to read/write rle compressed blocks of data.
44 * Made palman use it for .clr files. Made alphacolors calculate on the
45 * fly rather than caching to/from disk.
47 * 33 4/30/98 4:53p John
48 * Restructured and cleaned up cfile code. Added capability to read off
49 * of CD-ROM drive and out of multiple pack files.
51 * 32 4/10/98 5:20p John
52 * Changed RGB in lighting structure to be ubytes. Removed old
53 * not-necessary 24 bpp software stuff.
55 * 31 4/09/98 11:04p John
56 * Changed ID's in output files to make more sense.
58 * 30 4/01/98 3:05p Adam
59 * Reduced gamma on text.
61 * 29 3/29/98 2:36p John
62 * fixed bug with reloading fullscreen colros
64 * 28 3/25/98 8:07p John
65 * Restructured software rendering into two modules; One for windowed
66 * debug mode and one for DirectX fullscreen.
68 * 27 3/24/98 4:22p John
71 * 26 3/24/98 3:58p John
72 * Put in (hopefully) final gamma setting code.
74 * 25 3/10/98 4:18p John
75 * Cleaned up graphics lib. Took out most unused gr functions. Made D3D
76 * & Glide have popups and print screen. Took out all >8bpp software
77 * support. Made Fred zbuffer. Made zbuffer allocate dynamically to
78 * support Fred. Made zbuffering key off of functions rather than one
81 * 24 2/07/98 7:50p John
82 * Added code so that we can use the old blending type of alphacolors if
83 * we want to. Made the stars use them.
85 * 23 1/13/98 10:20a John
86 * Added code to support "glass" in alphacolors
88 * 22 1/02/98 9:10p Lawrance
89 * Big changes to how colors get set on the HUD.
91 * 21 12/30/97 4:32p John
93 * 20 12/02/97 3:59p John
94 * Added first rev of thruster glow, along with variable levels of
95 * translucency, which retquired some restructing of palman.
97 * 19 11/30/97 4:26p John
98 * Added 32-bpp antialiased line. Took gamma out of alphacolor
101 * 18 11/29/97 2:06p John
102 * added mode 16-bpp support
104 * 17 11/21/97 11:32a John
105 * Added nebulas. Fixed some warpout bugs.
107 * 16 11/14/97 12:30p John
108 * Fixed some DirectX bugs. Moved the 8-16 xlat tables into Graphics
109 * libs. Made 16-bpp DirectX modes know what bitmap format they're in.
111 * 15 11/05/97 11:20p Lawrance
112 * increase number of alpha colors to 52
114 * 14 11/04/97 6:32p Hoffoss
115 * Changes to hotkey screen. Needed to add new colors for
116 * Color_text_active*.
118 * 13 10/31/97 10:47a John
119 * upped clr version to force rebuild after changing palette code.
121 * 12 10/14/97 4:50p John
124 * 11 10/14/97 8:08a John
125 * added a bunch more 16 bit support
127 * 10 10/09/97 5:23p John
128 * Added support for more 16-bpp functions
130 * 9 10/03/97 9:10a John
131 * added better antialiased line drawer
133 * 8 9/20/97 8:16a John
134 * Made .clr files go into the Cache directory. Replaced cfopen(name,NULL)
135 * to delete a file with cf_delete.
137 * 7 9/09/97 10:46a Sandeep
138 * fixed warning level 4
140 * 6 7/18/97 12:40p John
141 * cached alphacolors to disk. Also made cfopen be able to delete a file
142 * by passing NULL for mode.
144 * 5 7/16/97 3:07p John
146 * 4 6/18/97 12:07p John
147 * fixed some color bugs
149 * 3 6/18/97 9:46a John
150 * added first rev of d3d shader. Made HUD target use medium detail
151 * models. Took out some color debug messages.
153 * 2 6/17/97 7:04p John
154 * added d3d support for gradients.
155 * fixed some color bugs by adding screen signatures instead of watching
156 * flags and palette changes.
158 * 1 6/17/97 12:01p John
165 #include "grinternal.h"
169 #include "systemvars.h"
171 //#define MAX_ALPHACOLORS 36
172 #define MAX_ALPHACOLORS 72
174 alphacolor Alphacolors[MAX_ALPHACOLORS];
175 static int Alphacolors_intited = 0;
177 alphacolor * Current_alphacolor = NULL;
180 void calc_alphacolor_hud_type( alphacolor * ac )
182 #ifndef HARDWARE_ONLY
184 int tr,tg,tb, Sr, Sg, Sb;
189 Assert(Alphacolors_intited);
191 // mprintf(( "Calculating alphacolor for %d,%d,%d,%d\n", ac->r, ac->g, ac->b, ac->alpha ));
193 falpha = i2fl(ac->alpha)/255.0f;
194 if ( falpha<0.0f ) falpha = 0.0f; else if ( falpha > 1.0f ) falpha = 1.0f;
196 alpha = ac->alpha >> 4;
197 if (alpha < 0 ) alpha = 0; else if (alpha > 15 ) alpha = 15;
199 if (r < 0 ) r = 0; else if (r > 255 ) r = 255;
201 if (g < 0 ) g = 0; else if (g > 255 ) g = 255;
203 if (b < 0 ) b = 0; else if (b > 255 ) b = 255;
207 for (j=1; j<15; j++ ) {
209 // JAS: Use 1.5/Gamma instead of 1/Gamma because on Adam's
210 // PC a gamma of 1.2 makes text look good, but his gamma is
211 // really 1.8. 1.8/1.2 = 1.5
212 float factor = falpha * (float)pow(i2fl(j)/14.0f, 1.5f/Gr_gamma);
213 //float factor = i2fl(j)/14.0f;
215 tr = fl2i( i2fl(r) * factor );
216 tg = fl2i( i2fl(g) * factor );
217 tb = fl2i( i2fl(b) * factor );
220 if ( tg > ii[j] ) ii[j] = tg;
221 if ( tb > ii[j] ) ii[j] = tb;
230 ubyte ri[256], gi[256], bi[256];
233 for (i=0; i<256; i++ ) {
234 ri[i] = ubyte((i*r)/m);
235 gi[i] = ubyte((i*g)/m);
236 bi[i] = ubyte((i*b)/m);
239 for (i=0; i<256; i++ ) {
246 for (i=0; i<256; i++ ) {
252 int dst_intensity = Sr;
253 if ( Sg > dst_intensity ) dst_intensity = Sg;
254 if ( Sb > dst_intensity ) dst_intensity = Sb;
256 ac->table.lookup[0][i] = (unsigned char)i;
258 for (j=1; j<15; j++ ) {
260 int tmp_i = max( ii[j], dst_intensity );
262 ac->table.lookup[j][i] = (unsigned char)palette_find(ri[tmp_i],gi[tmp_i],bi[tmp_i]);
265 float di = (i2fl(Sr)*.30f+i2fl(Sg)*0.60f+i2fl(Sb)*.10f)/255.0f;
266 float factor = 0.0f + di*0.75f;
268 tr = fl2i( factor*i2fl(r)*falpha );
269 tg = fl2i( factor*i2fl(g)*falpha );
270 tb = fl2i( factor*i2fl(b)*falpha );
272 if ( tr > 255 ) tr = 255; else if ( tr < 0 ) tr = 0;
273 if ( tg > 255 ) tg = 255; else if ( tg < 0 ) tg = 0;
274 if ( tb > 255 ) tb = 255; else if ( tb < 0 ) tb = 0;
276 ac->table.lookup[15][i] = (unsigned char)palette_find(tr,tg,tb);
277 //ac->table.lookup[15][i] = (unsigned char)palette_find(255,0,0);
283 // Old way to calculate alpha colors
285 void calc_alphacolor_blend_type( alphacolor * ac )
287 #ifndef HARDWARE_ONLY
289 int tr,tg,tb, Sr, Sg, Sb;
294 Assert(Alphacolors_intited);
296 // mprintf(( "Calculating alphacolor for %d,%d,%d,%d\n", ac->r, ac->g, ac->b, ac->alpha ));
298 alpha = ac->alpha >> 4;
299 if (alpha < 0 ) alpha = 0; else if (alpha > 15 ) alpha = 15;
301 if (r < 0 ) r = 0; else if (r > 255 ) r = 255;
303 if (g < 0 ) g = 0; else if (g > 255 ) g = 255;
305 if (b < 0 ) b = 0; else if (b > 255 ) b = 255;
309 for (j=1; j<16; j++ ) {
310 // JAS: Use 1.5/Gamma instead of 1/Gamma because on Adam's
311 // PC a gamma of 1.2 makes text look good, but his gamma is
312 // really 1.8. 1.8/1.2 = 1.5
313 gamma_j1[j] = (int)((pow(i2fl(j)/15.0f, 1.5f/Gr_gamma)*16.0f) + 0.5);
318 for (i=0; i<256; i++ ) {
324 Dr = ( Sr*(16-alpha) + (r*alpha) ) >> 4;
325 Dg = ( Sg*(16-alpha) + (g*alpha) ) >> 4;
326 Db = ( Sb*(16-alpha) + (b*alpha) ) >> 4;
328 ac->table.lookup[0][i] = (unsigned char)i;
330 for (j=1; j<16; j++ ) {
332 int j1 = gamma_j1[j];
334 tr = ( Sr*(16-j1) + (Dr*j1) ) >> 4;
335 tg = ( Sg*(16-j1) + (Dg*j1) ) >> 4;
336 tb = ( Sb*(16-j1) + (Db*j1) ) >> 4;
338 if ( tr > 255 ) tr = 255; else if ( tr < 0 ) tr = 0;
339 if ( tg > 255 ) tg = 255; else if ( tg < 0 ) tg = 0;
340 if ( tb > 255 ) tb = 255; else if ( tb < 0 ) tb = 0;
342 ac->table.lookup[j][i] = (unsigned char)palette_find(tr,tg,tb);
348 void calc_alphacolor( alphacolor * ac )
352 calc_alphacolor_hud_type(ac);
355 calc_alphacolor_blend_type(ac);
358 Int3(); // Passing an invalid type of alphacolor!
362 void grx_init_alphacolors()
366 Alphacolors_intited = 1;
368 for (i=0; i<MAX_ALPHACOLORS; i++ ) {
369 Alphacolors[i].used = 0;
370 Alphacolors[i].clr = NULL;
373 Current_alphacolor = NULL;
378 void grx_init_alphacolor( color *clr, int r, int g, int b, int alpha, int type )
383 if(Game_mode & GM_STANDALONE_SERVER){
387 if (!Alphacolors_intited) return;
389 if ( alpha < 0 ) alpha = 0;
390 if ( alpha > 255 ) alpha = 255;
393 if ( (clr->magic == 0xAC01) && (clr->is_alphacolor) ) {
394 if ( (clr->alphacolor >= 0) && (clr->alphacolor < MAX_ALPHACOLORS)) {
395 if ( Alphacolors[clr->alphacolor].used && (Alphacolors[clr->alphacolor].clr==clr) ) {
404 for (n=0; n<MAX_ALPHACOLORS; n++ ) {
405 if (!Alphacolors[n].used) break;
407 if ( n == MAX_ALPHACOLORS )
408 Error( LOCATION, "Out of alphacolors!\n" );
414 // Create the alphacolor
415 ac = &Alphacolors[n];
417 if ( changed && (ac->r!=r || ac->g!=g || ac->b!=b || ac->alpha!=alpha || ac->type != type ) ) {
418 // we're changing the color, so delete the old cache file
419 //mprintf(( "Changing ac from %d,%d,%d,%d to %d,%d,%d,%d\n", ac->r, ac->g, ac->b, ac->alpha, r, g, b, alpha ));
420 //ac_delete_cached(ac);
433 grx_init_color( clr, r, g, b );
435 // Link the alphacolor to the color
436 clr->alpha = (unsigned char)alpha;
437 clr->ac_type = (ubyte)type;
439 clr->is_alphacolor = 1;
443 void grx_get_color( int * r, int * g, int * b )
445 if (r) *r = gr_screen.current_color.red;
446 if (g) *g = gr_screen.current_color.green;
447 if (b) *b = gr_screen.current_color.blue;
450 void grx_init_color( color * dst, int r, int g, int b )
452 dst->screen_sig = gr_screen.signature;
453 dst->red = (unsigned char)r;
454 dst->green = (unsigned char)g;
455 dst->blue = (unsigned char)b;
457 dst->ac_type = AC_TYPE_NONE;
458 dst->is_alphacolor = 0;
459 dst->alphacolor = -1;
462 dst->raw8 = (unsigned char)palette_find( r, g, b );
465 void grx_set_color_fast( color * dst )
467 if ( dst->magic != 0xAC01 ) return;
469 if ( dst->screen_sig != gr_screen.signature ) {
470 if ( dst->is_alphacolor ) {
471 grx_init_alphacolor( dst, dst->red, dst->green, dst->blue, dst->alpha, dst->ac_type );
473 grx_init_color( dst, dst->red, dst->green, dst->blue );
477 gr_screen.current_color = *dst;
479 if ( dst->is_alphacolor ) {
480 Assert( dst->alphacolor > -1 );
481 Assert( dst->alphacolor <= MAX_ALPHACOLORS );
482 Assert( Alphacolors[dst->alphacolor].used );
484 // Current_alphacolor = &Alphacolors[dst->alphacolor];
485 Current_alphacolor = NULL;
487 Current_alphacolor = NULL;
492 void grx_set_color( int r, int g, int b )
494 Assert((r >= 0) && (r < 256));
495 Assert((g >= 0) && (g < 256));
496 Assert((b >= 0) && (b < 256));
498 // if ( r!=0 || g!=0 || b!=0 ) {
499 // mprintf(( "Setcolor: %d,%d,%d\n", r,g,b ));
501 grx_init_color( &gr_screen.current_color, r, g, b );
502 Current_alphacolor = NULL;
505 void calc_alphacolor_hud_type_old( alphacolor_old * ac )
508 int tr,tg,tb, Sr, Sg, Sb;
513 // Assert(Alphacolors_intited);
515 // mprintf(( "Calculating alphacolor for %d,%d,%d,%d\n", ac->r, ac->g, ac->b, ac->alpha ));
517 falpha = i2fl(ac->alpha)/255.0f;
518 if ( falpha<0.0f ) falpha = 0.0f; else if ( falpha > 1.0f ) falpha = 1.0f;
520 alpha = ac->alpha >> 4;
521 if (alpha < 0 ) alpha = 0; else if (alpha > 15 ) alpha = 15;
523 if (r < 0 ) r = 0; else if (r > 255 ) r = 255;
525 if (g < 0 ) g = 0; else if (g > 255 ) g = 255;
527 if (b < 0 ) b = 0; else if (b > 255 ) b = 255;
531 for (j=1; j<15; j++ ) {
533 // JAS: Use 1.5/Gamma instead of 1/Gamma because on Adam's
534 // PC a gamma of 1.2 makes text look good, but his gamma is
535 // really 1.8. 1.8/1.2 = 1.5
536 float factor = falpha * (float)pow(i2fl(j)/14.0f, 1.5f/Gr_gamma);
537 //float factor = i2fl(j)/14.0f;
539 tr = fl2i( i2fl(r) * factor );
540 tg = fl2i( i2fl(g) * factor );
541 tb = fl2i( i2fl(b) * factor );
544 if ( tg > ii[j] ) ii[j] = tg;
545 if ( tb > ii[j] ) ii[j] = tb;
554 ubyte ri[256], gi[256], bi[256];
557 for (i=0; i<256; i++ ) {
558 ri[i] = ubyte((i*r)/m);
559 gi[i] = ubyte((i*g)/m);
560 bi[i] = ubyte((i*b)/m);
563 for (i=0; i<256; i++ ) {
570 for (i=0; i<256; i++ ) {
576 int dst_intensity = Sr;
577 if ( Sg > dst_intensity ) dst_intensity = Sg;
578 if ( Sb > dst_intensity ) dst_intensity = Sb;
580 ac->table.lookup[0][i] = (unsigned char)i;
582 for (j=1; j<15; j++ ) {
584 int tmp_i = max( ii[j], dst_intensity );
586 ac->table.lookup[j][i] = (unsigned char)palette_find(ri[tmp_i],gi[tmp_i],bi[tmp_i]);
589 float di = (i2fl(Sr)*.30f+i2fl(Sg)*0.60f+i2fl(Sb)*.10f)/255.0f;
590 float factor = 0.0f + di*0.75f;
592 tr = fl2i( factor*i2fl(r)*falpha );
593 tg = fl2i( factor*i2fl(g)*falpha );
594 tb = fl2i( factor*i2fl(b)*falpha );
596 if ( tr > 255 ) tr = 255; else if ( tr < 0 ) tr = 0;
597 if ( tg > 255 ) tg = 255; else if ( tg < 0 ) tg = 0;
598 if ( tb > 255 ) tb = 255; else if ( tb < 0 ) tb = 0;
600 ac->table.lookup[15][i] = (unsigned char)palette_find(tr,tg,tb);
601 //ac->table.lookup[15][i] = (unsigned char)palette_find(255,0,0);
605 void calc_alphacolor_old(alphacolor_old *ac)
607 Assert(Fred_running);
608 calc_alphacolor_hud_type_old(ac);