]> icculus.org git repositories - taylor/freespace2.git/blob - src/graphics/colors.cpp
bunch of cleanup
[taylor/freespace2.git] / src / graphics / colors.cpp
1 /*
2  * Copyright (C) Volition, Inc. 1999.  All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell 
5  * or otherwise commercially exploit the source or things you created based on
6  * the source.
7  */
8
9 /*
10  * $Logfile: /Freespace2/code/Graphics/Colors.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  * Functions to deal with colors & alphacolors
16  *
17  * $Log$
18  * Revision 1.3  2002/06/09 04:41:17  relnev
19  * added copyright header
20  *
21  * Revision 1.2  2002/05/07 03:16:45  theoddone33
22  * The Great Newline Fix
23  *
24  * Revision 1.1.1.1  2002/05/03 03:28:09  root
25  * Initial import.
26  *
27  * 
28  * 7     7/08/99 10:52a Dave
29  * New multiplayer interpolation scheme. Not 100% done yet, but still
30  * better than the old way.
31  * 
32  * 6     1/14/99 12:48a Dave
33  * Todo list bug fixes. Made a pass at putting briefing icons back into
34  * FRED. Sort of works :(
35  * 
36  * 5     12/02/98 5:47p Dave
37  * Put in interface xstr code. Converted barracks screen to new format.
38  * 
39  * 4     11/30/98 5:31p Dave
40  * Fixed up Fred support for software mode.
41  * 
42  * 3     11/30/98 1:07p Dave
43  * 16 bit conversion, first run.
44  * 
45  * 2     10/07/98 10:52a Dave
46  * Initial checkin.
47  * 
48  * 1     10/07/98 10:48a Dave
49  * 
50  * 35    5/19/98 3:32p John
51  * upped alpha colors
52  * 
53  * 34    5/13/98 10:22p John
54  * Added cfile functions to read/write rle compressed blocks of data.
55  * Made palman use it for .clr files.  Made alphacolors calculate on the
56  * fly rather than caching to/from disk.
57  * 
58  * 33    4/30/98 4:53p John
59  * Restructured and cleaned up cfile code.  Added capability to read off
60  * of CD-ROM drive and out of multiple pack files.
61  * 
62  * 32    4/10/98 5:20p John
63  * Changed RGB in lighting structure to be ubytes.  Removed old
64  * not-necessary 24 bpp software stuff.
65  * 
66  * 31    4/09/98 11:04p John
67  * Changed ID's in output files to make more sense.
68  * 
69  * 30    4/01/98 3:05p Adam
70  * Reduced gamma on text.
71  * 
72  * 29    3/29/98 2:36p John
73  * fixed bug with reloading fullscreen colros
74  * 
75  * 28    3/25/98 8:07p John
76  * Restructured software rendering into two modules; One for windowed
77  * debug mode and one for DirectX fullscreen.   
78  * 
79  * 27    3/24/98 4:22p John
80  * fixed warning
81  * 
82  * 26    3/24/98 3:58p John
83  * Put in (hopefully) final gamma setting code.
84  * 
85  * 25    3/10/98 4:18p John
86  * Cleaned up graphics lib.  Took out most unused gr functions.   Made D3D
87  * & Glide have popups and print screen.  Took out all >8bpp software
88  * support.  Made Fred zbuffer.  Made zbuffer allocate dynamically to
89  * support Fred.  Made zbuffering key off of functions rather than one
90  * global variable.
91  * 
92  * 24    2/07/98 7:50p John
93  * Added code so that we can use the old blending type of alphacolors if
94  * we want to.  Made the stars use them.
95  * 
96  * 23    1/13/98 10:20a John
97  * Added code to support "glass" in alphacolors
98  * 
99  * 22    1/02/98 9:10p Lawrance
100  * Big changes to how colors get set on the HUD.
101  * 
102  * 21    12/30/97 4:32p John
103  * 
104  * 20    12/02/97 3:59p John
105  * Added first rev of thruster glow, along with variable levels of
106  * translucency, which retquired some restructing of palman.
107  * 
108  * 19    11/30/97 4:26p John
109  * Added 32-bpp antialiased line.   Took gamma out of alphacolor
110  * calculation.
111  * 
112  * 18    11/29/97 2:06p John
113  * added mode 16-bpp support
114  * 
115  * 17    11/21/97 11:32a John
116  * Added nebulas.   Fixed some warpout bugs.
117  * 
118  * 16    11/14/97 12:30p John
119  * Fixed some DirectX bugs.  Moved the 8-16 xlat tables into Graphics
120  * libs.  Made 16-bpp DirectX modes know what bitmap format they're in.
121  * 
122  * 15    11/05/97 11:20p Lawrance
123  * increase number of alpha colors to 52
124  * 
125  * 14    11/04/97 6:32p Hoffoss
126  * Changes to hotkey screen.  Needed to add new colors for
127  * Color_text_active*.
128  * 
129  * 13    10/31/97 10:47a John
130  * upped clr version to force rebuild after changing palette code.
131  * 
132  * 12    10/14/97 4:50p John
133  * more 16 bpp stuff.
134  * 
135  * 11    10/14/97 8:08a John
136  * added a bunch more 16 bit support
137  * 
138  * 10    10/09/97 5:23p John
139  * Added support for more 16-bpp functions
140  * 
141  * 9     10/03/97 9:10a John
142  * added better antialiased line drawer
143  * 
144  * 8     9/20/97 8:16a John
145  * Made .clr files go into the Cache directory. Replaced cfopen(name,NULL)
146  * to delete a file with cf_delete.
147  * 
148  * 7     9/09/97 10:46a Sandeep
149  * fixed warning level 4
150  * 
151  * 6     7/18/97 12:40p John
152  * cached alphacolors to disk.  Also made cfopen be able to delete a file
153  * by passing NULL for mode.
154  * 
155  * 5     7/16/97 3:07p John
156  * 
157  * 4     6/18/97 12:07p John
158  * fixed some color bugs
159  * 
160  * 3     6/18/97 9:46a John
161  * added first rev of d3d shader.   Made HUD target use medium detail
162  * models.  Took out some color debug messages.
163  * 
164  * 2     6/17/97 7:04p John
165  * added d3d support for gradients.
166  * fixed some color bugs by adding screen signatures instead of watching
167  * flags and palette changes.
168  * 
169  * 1     6/17/97 12:01p John
170  *
171  * $NoKeywords: $
172  */
173
174 #include "pstypes.h"
175 #include "2d.h"
176 #include "grinternal.h"
177 #include "colors.h"
178 #include "palman.h"
179 #include "cfile.h"
180 #include "systemvars.h"
181
182 //#define MAX_ALPHACOLORS 36
183 #define MAX_ALPHACOLORS 72
184
185 alphacolor Alphacolors[MAX_ALPHACOLORS];
186 static int Alphacolors_intited = 0;
187
188 alphacolor * Current_alphacolor = NULL;
189
190
191 void calc_alphacolor_hud_type( alphacolor * ac )
192 {
193 #ifndef HARDWARE_ONLY
194         int i,j;
195         int tr,tg,tb, Sr, Sg, Sb;
196         ubyte * pal;
197         int r, g, b, alpha;
198         float falpha;
199
200         SDL_assert(Alphacolors_intited);
201
202 //      mprintf(( "Calculating alphacolor for %d,%d,%d,%d\n", ac->r, ac->g, ac->b, ac->alpha ));
203
204         falpha = i2fl(ac->alpha)/255.0f;
205         if ( falpha<0.0f ) falpha = 0.0f; else if ( falpha > 1.0f ) falpha = 1.0f;
206
207         alpha = ac->alpha >> 4;
208         if (alpha < 0 ) alpha = 0; else if (alpha > 15 ) alpha = 15;
209         r = ac->r;
210         if (r < 0 ) r = 0; else if (r > 255 ) r = 255;
211         g = ac->g;
212         if (g < 0 ) g = 0; else if (g > 255 ) g = 255;
213         b = ac->b;
214         if (b < 0 ) b = 0; else if (b > 255 ) b = 255;
215
216         int ii[16];
217
218         for (j=1; j<15; j++ )   {
219
220                 // JAS: Use 1.5/Gamma instead of 1/Gamma because on Adam's
221                 // PC a gamma of 1.2 makes text look good, but his gamma is
222                 // really 1.8.   1.8/1.2 = 1.5
223                 float factor = falpha * (float)pow(i2fl(j)/14.0f, 1.5f/Gr_gamma);
224                 //float factor = i2fl(j)/14.0f;
225
226                 tr = fl2i( i2fl(r) * factor );
227                 tg = fl2i( i2fl(g) * factor );
228                 tb = fl2i( i2fl(b) * factor );
229
230                 ii[j] = tr;
231                 if ( tg > ii[j] )       ii[j] = tg;
232                 if ( tb > ii[j] )       ii[j] = tb;
233         }
234
235         pal = gr_palette;
236
237         int m = r;
238         if ( g > m ) m = g;
239         if ( b > m ) m = b;
240
241         ubyte ri[256], gi[256], bi[256];
242
243         if ( m > 0 )    {
244                 for (i=0; i<256; i++ )  {
245                         ri[i] = ubyte((i*r)/m);
246                         gi[i] = ubyte((i*g)/m);
247                         bi[i] = ubyte((i*b)/m);
248                 }
249         } else {
250                 for (i=0; i<256; i++ )  {
251                         ri[i] = 0;
252                         gi[i] = 0;
253                         bi[i] = 0;
254                 }
255         }
256
257         for (i=0; i<256; i++ )  {
258                 Sr = pal[0];
259                 Sg = pal[1];
260                 Sb = pal[2];
261                 pal += 3;
262
263                 int dst_intensity = Sr;
264                 if ( Sg > dst_intensity ) dst_intensity = Sg;
265                 if ( Sb > dst_intensity ) dst_intensity = Sb;
266
267                 ac->table.lookup[0][i] = (unsigned char)i;
268
269                 for (j=1; j<15; j++ )   {
270
271                         int tmp_i = max( ii[j], dst_intensity );
272
273                         ac->table.lookup[j][i] = (unsigned char)palette_find(ri[tmp_i],gi[tmp_i],bi[tmp_i]);
274                 }
275
276                 float di = (i2fl(Sr)*.30f+i2fl(Sg)*0.60f+i2fl(Sb)*.10f)/255.0f;
277                 float factor = 0.0f + di*0.75f;
278
279                 tr = fl2i( factor*i2fl(r)*falpha );
280                 tg = fl2i( factor*i2fl(g)*falpha );
281                 tb = fl2i( factor*i2fl(b)*falpha );
282
283                 if ( tr > 255 ) tr = 255; else if ( tr < 0 ) tr = 0;
284                 if ( tg > 255 ) tg = 255; else if ( tg < 0 ) tg = 0; 
285                 if ( tb > 255 ) tb = 255; else if ( tb < 0 ) tb = 0;
286
287                 ac->table.lookup[15][i] = (unsigned char)palette_find(tr,tg,tb);
288                 //ac->table.lookup[15][i] = (unsigned char)palette_find(255,0,0);
289
290         }
291 #endif
292 }
293
294 // Old way to calculate alpha colors
295
296 void calc_alphacolor_blend_type( alphacolor * ac )
297 {
298 #ifndef HARDWARE_ONLY
299         int i,j;
300         int tr,tg,tb, Sr, Sg, Sb;
301         int Dr, Dg, Db;
302         ubyte * pal;
303         int r, g, b, alpha;
304
305         SDL_assert(Alphacolors_intited);
306
307 //      mprintf(( "Calculating alphacolor for %d,%d,%d,%d\n", ac->r, ac->g, ac->b, ac->alpha ));
308
309         alpha = ac->alpha >> 4;
310         if (alpha < 0 ) alpha = 0; else if (alpha > 15 ) alpha = 15;
311         r = ac->r;
312         if (r < 0 ) r = 0; else if (r > 255 ) r = 255;
313         g = ac->g;
314         if (g < 0 ) g = 0; else if (g > 255 ) g = 255;
315         b = ac->b;
316         if (b < 0 ) b = 0; else if (b > 255 ) b = 255;
317
318         int gamma_j1[16];
319
320         for (j=1; j<16; j++ )   {
321                 // JAS: Use 1.5/Gamma instead of 1/Gamma because on Adam's
322                 // PC a gamma of 1.2 makes text look good, but his gamma is
323                 // really 1.8.   1.8/1.2 = 1.5
324                 gamma_j1[j] = (int)((pow(i2fl(j)/15.0f, 1.5f/Gr_gamma)*16.0f) + 0.5);
325         }
326
327         pal = gr_palette;
328
329         for (i=0; i<256; i++ )  {
330                 Sr = pal[0];
331                 Sg = pal[1];
332                 Sb = pal[2];
333                 pal += 3;
334         
335                 Dr = ( Sr*(16-alpha) + (r*alpha) ) >> 4;
336                 Dg = ( Sg*(16-alpha) + (g*alpha) ) >> 4;
337                 Db = ( Sb*(16-alpha) + (b*alpha) ) >> 4;
338
339                 ac->table.lookup[0][i] = (unsigned char)i;
340
341                 for (j=1; j<16; j++ )   {
342
343                         int j1 = gamma_j1[j];
344
345                         tr = ( Sr*(16-j1) + (Dr*j1) ) >> 4;
346                         tg = ( Sg*(16-j1) + (Dg*j1) ) >> 4;
347                         tb = ( Sb*(16-j1) + (Db*j1) ) >> 4;
348
349                         if ( tr > 255 ) tr = 255; else if ( tr < 0 ) tr = 0;
350                         if ( tg > 255 ) tg = 255; else if ( tg < 0 ) tg = 0; 
351                         if ( tb > 255 ) tb = 255; else if ( tb < 0 ) tb = 0;
352
353                         ac->table.lookup[j][i] = (unsigned char)palette_find(tr,tg,tb);
354                 }
355         }
356 #endif
357 }
358
359 void calc_alphacolor( alphacolor * ac )
360 {
361         switch(ac->type)        {
362         case AC_TYPE_HUD:
363                 calc_alphacolor_hud_type(ac);
364                 break;
365         case AC_TYPE_BLEND:
366                 calc_alphacolor_blend_type(ac);
367                 break;
368         default:
369                 Int3();         // Passing an invalid type of alphacolor!
370         }
371 }
372
373 void grx_init_alphacolors()
374 {
375         int i;
376         
377         Alphacolors_intited = 1;
378
379         for (i=0; i<MAX_ALPHACOLORS; i++ )      {
380                 Alphacolors[i].used = 0;
381                 Alphacolors[i].clr = NULL;
382         }
383
384         Current_alphacolor = NULL;
385 }
386
387
388
389 void grx_init_alphacolor( color *clr, int r, int g, int b, int alpha, int type )
390 {
391         int n;
392         alphacolor *ac;
393         
394         if(Game_mode & GM_STANDALONE_SERVER){
395                 return;
396         }
397
398         if (!Alphacolors_intited) return;
399
400         if ( alpha < 0 ) alpha = 0;
401         if ( alpha > 255 ) alpha = 255;
402
403         n = -1;
404         if ( (clr->magic == 0xAC01) && (clr->is_alphacolor) )   {
405                 if ( (clr->alphacolor >= 0) && (clr->alphacolor < MAX_ALPHACOLORS))     {
406                         if ( Alphacolors[clr->alphacolor].used && (Alphacolors[clr->alphacolor].clr==clr) )     {
407                                 n = clr->alphacolor;
408                         }
409                 }
410         }
411
412         int changed = 0;
413
414         if ( n==-1 )    {
415                 for (n=0; n<MAX_ALPHACOLORS; n++ )      {
416                         if (!Alphacolors[n].used) break;
417                 }
418                 if ( n == MAX_ALPHACOLORS )     
419                         Error( LOCATION, "Out of alphacolors!\n" );
420         } else {
421                 changed = 1;
422         }
423
424
425         // Create the alphacolor
426         ac = &Alphacolors[n];
427
428         if ( changed && (ac->r!=r || ac->g!=g || ac->b!=b || ac->alpha!=alpha || ac->type != type ) )   {
429                 // we're changing the color, so delete the old cache file
430                 //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 ));
431                 //ac_delete_cached(ac);
432         }
433
434         ac->used = 1;
435         ac->r = r;
436         ac->g = g;
437         ac->b = b;
438         ac->alpha = alpha;
439         ac->type = type;
440         ac->clr=clr;
441         
442         calc_alphacolor(ac);
443
444         grx_init_color( clr, r, g, b );
445
446         // Link the alphacolor to the color
447         clr->alpha = (unsigned char)alpha;
448         clr->ac_type = (ubyte)type;
449         clr->alphacolor = n;
450         clr->is_alphacolor = 1;
451 }
452
453
454 void grx_get_color( int * r, int * g, int * b )
455 {
456         if (r) *r = gr_screen.current_color.red;
457         if (g) *g = gr_screen.current_color.green;
458         if (b) *b = gr_screen.current_color.blue;
459 }
460
461 void grx_init_color( color * dst, int r, int g, int b )
462 {
463         dst->screen_sig = gr_screen.signature;
464         dst->red = (unsigned char)r;
465         dst->green = (unsigned char)g;
466         dst->blue = (unsigned char)b;
467         dst->alpha = 255;
468         dst->ac_type = AC_TYPE_NONE;
469         dst->is_alphacolor = 0;
470         dst->alphacolor = -1;
471         dst->magic = 0xAC01;
472
473         dst->raw8 = (unsigned char)palette_find( r, g, b );
474 }
475
476 void grx_set_color_fast( color * dst )
477 {
478         if ( dst->magic != 0xAC01 ) return;
479
480         if ( dst->screen_sig != gr_screen.signature )   {
481                 if ( dst->is_alphacolor )       {
482                         grx_init_alphacolor( dst, dst->red, dst->green, dst->blue, dst->alpha, dst->ac_type );
483                 } else {
484                         grx_init_color( dst, dst->red, dst->green, dst->blue );
485                 }
486         }
487
488         gr_screen.current_color = *dst;
489         
490         if ( dst->is_alphacolor )       {
491                 SDL_assert( dst->alphacolor > -1 );
492                 SDL_assert( dst->alphacolor <= MAX_ALPHACOLORS );
493                 SDL_assert( Alphacolors[dst->alphacolor].used );
494
495                 // Current_alphacolor = &Alphacolors[dst->alphacolor];
496                 Current_alphacolor = NULL;
497         } else {
498                 Current_alphacolor = NULL;
499         }
500 }
501
502
503 void grx_set_color( int r, int g, int b )
504 {
505         SDL_assert((r >= 0) && (r < 256));
506         SDL_assert((g >= 0) && (g < 256));
507         SDL_assert((b >= 0) && (b < 256));
508
509 //      if ( r!=0 || g!=0 || b!=0 )     {
510 //              mprintf(( "Setcolor: %d,%d,%d\n", r,g,b ));
511 //      }
512         grx_init_color( &gr_screen.current_color, r, g, b );
513         Current_alphacolor = NULL;
514 }
515
516 void calc_alphacolor_hud_type_old( alphacolor_old * ac )
517 {
518         int i,j;
519         int tr,tg,tb, Sr, Sg, Sb;
520         ubyte * pal;
521         int r, g, b, alpha;
522         float falpha;
523
524         // SDL_assert(Alphacolors_intited);
525
526 //      mprintf(( "Calculating alphacolor for %d,%d,%d,%d\n", ac->r, ac->g, ac->b, ac->alpha ));
527
528         falpha = i2fl(ac->alpha)/255.0f;
529         if ( falpha<0.0f ) falpha = 0.0f; else if ( falpha > 1.0f ) falpha = 1.0f;
530
531         alpha = ac->alpha >> 4;
532         if (alpha < 0 ) alpha = 0; else if (alpha > 15 ) alpha = 15;
533         r = ac->r;
534         if (r < 0 ) r = 0; else if (r > 255 ) r = 255;
535         g = ac->g;
536         if (g < 0 ) g = 0; else if (g > 255 ) g = 255;
537         b = ac->b;
538         if (b < 0 ) b = 0; else if (b > 255 ) b = 255;
539
540         int ii[16];
541
542         for (j=1; j<15; j++ )   {
543
544                 // JAS: Use 1.5/Gamma instead of 1/Gamma because on Adam's
545                 // PC a gamma of 1.2 makes text look good, but his gamma is
546                 // really 1.8.   1.8/1.2 = 1.5
547                 float factor = falpha * (float)pow(i2fl(j)/14.0f, 1.5f/Gr_gamma);
548                 //float factor = i2fl(j)/14.0f;
549
550                 tr = fl2i( i2fl(r) * factor );
551                 tg = fl2i( i2fl(g) * factor );
552                 tb = fl2i( i2fl(b) * factor );
553
554                 ii[j] = tr;
555                 if ( tg > ii[j] )       ii[j] = tg;
556                 if ( tb > ii[j] )       ii[j] = tb;
557         }
558
559         pal = gr_palette;
560
561         int m = r;
562         if ( g > m ) m = g;
563         if ( b > m ) m = b;
564
565         ubyte ri[256], gi[256], bi[256];
566
567         if ( m > 0 )    {
568                 for (i=0; i<256; i++ )  {
569                         ri[i] = ubyte((i*r)/m);
570                         gi[i] = ubyte((i*g)/m);
571                         bi[i] = ubyte((i*b)/m);
572                 }
573         } else {
574                 for (i=0; i<256; i++ )  {
575                         ri[i] = 0;
576                         gi[i] = 0;
577                         bi[i] = 0;
578                 }
579         }
580
581         for (i=0; i<256; i++ )  {
582                 Sr = pal[0];
583                 Sg = pal[1];
584                 Sb = pal[2];
585                 pal += 3;
586
587                 int dst_intensity = Sr;
588                 if ( Sg > dst_intensity ) dst_intensity = Sg;
589                 if ( Sb > dst_intensity ) dst_intensity = Sb;
590
591                 ac->table.lookup[0][i] = (unsigned char)i;
592
593                 for (j=1; j<15; j++ )   {
594
595                         int tmp_i = max( ii[j], dst_intensity );
596
597                         ac->table.lookup[j][i] = (unsigned char)palette_find(ri[tmp_i],gi[tmp_i],bi[tmp_i]);
598                 }
599
600                 float di = (i2fl(Sr)*.30f+i2fl(Sg)*0.60f+i2fl(Sb)*.10f)/255.0f;
601                 float factor = 0.0f + di*0.75f;
602
603                 tr = fl2i( factor*i2fl(r)*falpha );
604                 tg = fl2i( factor*i2fl(g)*falpha );
605                 tb = fl2i( factor*i2fl(b)*falpha );
606
607                 if ( tr > 255 ) tr = 255; else if ( tr < 0 ) tr = 0;
608                 if ( tg > 255 ) tg = 255; else if ( tg < 0 ) tg = 0; 
609                 if ( tb > 255 ) tb = 255; else if ( tb < 0 ) tb = 0;
610
611                 ac->table.lookup[15][i] = (unsigned char)palette_find(tr,tg,tb);
612                 //ac->table.lookup[15][i] = (unsigned char)palette_find(255,0,0);
613         }
614 }
615
616 void calc_alphacolor_old(alphacolor_old *ac)
617 {
618         SDL_assert(Fred_running);
619         calc_alphacolor_hud_type_old(ac);
620 }