CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

PALETTEC.CPP (24713B)


      1 //
      2 // Copyright 2020 Electronic Arts Inc.
      3 //
      4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 
      5 // software: you can redistribute it and/or modify it under the terms of 
      6 // the GNU General Public License as published by the Free Software Foundation, 
      7 // either version 3 of the License, or (at your option) any later version.
      8 
      9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 
     10 // in the hope that it will be useful, but with permitted additional restrictions 
     11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 
     12 // distributed with this program. You should have received a copy of the 
     13 // GNU General Public License along with permitted additional restrictions 
     14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
     15 
     16 /* $Header: /CounterStrike/palette.cpp 2     9/23/97 11:00p Steve_t $ */
     17 /***********************************************************************************************
     18  ***              C O N F I D E N T I A L  ---  W E S T W O O D  S T U D I O S               ***
     19  ***********************************************************************************************
     20  *                                                                                             *
     21  *                 Project Name : Command & Conquer                                            *
     22  *                                                                                             *
     23  *                    File Name : PALETTE.CPP                                                  *
     24  *                                                                                             *
     25  *                   Programmer : Joe L. Bostic                                                *
     26  *                                                                                             *
     27  *                   Start Date : 12/02/95                                                     *
     28  *                                                                                             *
     29  *                  Last Update : February 5, 1996 [JLB]                                       *
     30  *                                                                                             *
     31  *---------------------------------------------------------------------------------------------*
     32  * Functions:                                                                                  *
     33  *   PaletteClass::Adjust -- Adjusts the palette toward another palette.                       *
     34  *   PaletteClass::Adjust -- Adjusts this palette toward black.                                *
     35  *   PaletteClass::Closest_Color -- Finds closest match to color specified.                    *
     36  *   PaletteClass::Set -- Fade the display palette to this palette.                            *
     37  *   PaletteClass::PaletteClass -- Constructor that fills palette with color specified.        *
     38  *   PaletteClass::operator = -- Assignment operator for palette objects.                      *
     39  *   PaletteClass::operator == -- Equality operator for palette objects.                       *
     40  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     41 
     42 #ifndef NOINITCLASS
     43 #define NOINITCLASS
     44 struct NoInitClass {
     45 	public:
     46 		void operator () (void) const {};
     47 };
     48 #endif
     49 
     50 void __cdecl Set_Palette(void * palette);
     51 
     52 
     53 #ifndef BITMAPCLASS
     54 #define BITMAPCLASS
     55 class BitmapClass
     56 {
     57 	public:
     58 		BitmapClass(int w, int h, unsigned char * data) :
     59 			Width(w), Height(h), Data(data) {};
     60 
     61 		int Width;
     62 		int Height;
     63 		unsigned char * Data;
     64 };
     65 
     66 class TPoint2D
     67 {
     68 	public:
     69 		TPoint2D(int xx, int yy) : x(xx), y(yy) {};
     70 		TPoint2D(void) : x(0), y(0) {};
     71 
     72 		int x;
     73 		int y;
     74 };
     75 #endif
     76 
     77 #include	"function.h"
     78 #include	"watcom.h"
     79 #include	"palette.h"
     80 #include	"palettec.h"
     81 #include	"ftimer.h"
     82 //#define TIMER_H
     83 #include	"wwlib32.h"
     84 //#include	"timer.h"
     85 #include	<string.h>
     86 
     87 #ifndef SYSTEM_TIMER_CLASS
     88 #define SYSTEM_TIMER_CLASS
     89 
     90 #ifdef WIN32
     91 extern WinTimerClass	*		WindowsTimer;
     92 #endif
     93 
     94 class SystemTimerClass
     95 {
     96 	public:
     97 		#ifdef WIN32
     98 			long operator () (void) const {if (!WindowsTimer) return(0);return(WindowsTimer->Get_System_Tick_Count());};
     99 			operator long (void) const {if (!WindowsTimer) return(0);return(WindowsTimer->Get_System_Tick_Count());};
    100 		#else
    101 			long operator () (void) const {return(Get_System_Tick_Count());};
    102 			operator long (void) const {return(Get_System_Tick_Count());};
    103 		#endif
    104 };
    105 #endif
    106 
    107 
    108 //PaletteClass const PaletteClass::CurrentPalette;
    109 extern "C" unsigned char CurrentPalette[];
    110 
    111 PaletteClass const & PaletteClass::CurrentPalette = *(PaletteClass *)&::CurrentPalette[0];
    112 
    113 
    114 /***********************************************************************************************
    115  * PaletteClass::PaletteClass -- Constructor that fills palette with color specified.          *
    116  *                                                                                             *
    117  *    This constructor will fill the palette with the color specified.                         *
    118  *                                                                                             *
    119  * INPUT:   rgb   -- Reference to the color to fill the entire palette with.                   *
    120  *                                                                                             *
    121  * OUTPUT:  none                                                                               *
    122  *                                                                                             *
    123  * WARNINGS:   none                                                                            *
    124  *                                                                                             *
    125  * HISTORY:                                                                                    *
    126  *   12/02/1995 JLB : Created.                                                                 *
    127  *=============================================================================================*/
    128 PaletteClass::PaletteClass(RGBClass const & rgb)
    129 {
    130 	for (int index = 0; index < COLOR_COUNT; index++) {
    131 		Palette[index] = rgb;
    132 	}
    133 }
    134 
    135 
    136 /***********************************************************************************************
    137  * PaletteClass::operator == -- Equality operator for palette objects.                         *
    138  *                                                                                             *
    139  *    This is the comparison for equality operator. It will compare palette objects to         *
    140  *    determine if they are identical.                                                         *
    141  *                                                                                             *
    142  * INPUT:   palette  -- Reference to the palette to compare to this palette.                   *
    143  *                                                                                             *
    144  * OUTPUT:  Are the two palettes identical?                                                    *
    145  *                                                                                             *
    146  * WARNINGS:   none                                                                            *
    147  *                                                                                             *
    148  * HISTORY:                                                                                    *
    149  *   12/02/1995 JLB : Created.                                                                 *
    150  *=============================================================================================*/
    151 int PaletteClass::operator == (PaletteClass const & palette) const
    152 {
    153 	if (this == &palette) return(true);
    154 	return(memcmp(&Palette[0], &palette.Palette[0], sizeof(Palette)) == 0);
    155 }
    156 
    157 
    158 /***********************************************************************************************
    159  * PaletteClass::operator = -- Assignment operator for palette objects.                        *
    160  *                                                                                             *
    161  *    This is the assignment operator for palette objects. Although the default C++ generated  *
    162  *    assignment operator would function correctly, it would not check for self-assignment    *
    163  *    and thus this routine can be faster.                                                     *
    164  *                                                                                             *
    165  * INPUT:   palette  -- Reference to that palette that will be copied into this palette.       *
    166  *                                                                                             *
    167  * OUTPUT:  Returns with a reference to the newly copied to palette.                           *
    168  *                                                                                             *
    169  * WARNINGS:   none                                                                            *
    170  *                                                                                             *
    171  * HISTORY:                                                                                    *
    172  *   12/02/1995 JLB : Created.                                                                 *
    173  *=============================================================================================*/
    174 PaletteClass & PaletteClass::operator = (PaletteClass const & palette)
    175 {
    176 	if (this == &palette) return(*this);
    177 
    178 	memcpy(&Palette[0], &palette.Palette[0], sizeof(Palette));
    179 	return(*this);
    180 }
    181 
    182 
    183 /***********************************************************************************************
    184  * PaletteClass::Adjust -- Adjusts this palette toward black.                                  *
    185  *                                                                                             *
    186  *    This routine is used to adjust this palette toward black. Typical use of this routine    *
    187  *    is when fading the palette to black.                                                     *
    188  *                                                                                             *
    189  * INPUT:   ratio -- The ratio to fade this palette to black. 0 means no fading at all. 255    *
    190  *                   means 100% faded to black.                                                *
    191  *                                                                                             *
    192  * OUTPUT:  none                                                                               *
    193  *                                                                                             *
    194  * WARNINGS:   This routine doesn't actually set the palette to the video card. Use the Set()  *
    195  *             function to achieve that purpose.                                               *
    196  *                                                                                             *
    197  * HISTORY:                                                                                    *
    198  *   12/02/1995 JLB : Created.                                                                 *
    199  *=============================================================================================*/
    200 void PaletteClass::Adjust(int ratio)
    201 {
    202 	for (int index = 0; index < COLOR_COUNT; index++) {
    203 		Palette[index].Adjust(ratio, BlackColor);
    204 	}
    205 }
    206 
    207 
    208 /***********************************************************************************************
    209  * PaletteClass::Adjust -- Adjusts the palette toward another palette.                         *
    210  *                                                                                             *
    211  *    This routine is used to adjust a palette toward a destination palette by the ratio       *
    212  *    specified. This is primarily used by the palette fading routines.                        *
    213  *                                                                                             *
    214  * INPUT:   palette  -- Reference to the destination palette.                                  *
    215  *                                                                                             *
    216  *          ratio    -- The ratio to adjust this palette toward the destination palette. A     *
    217  *                      value of 0 means no adjustment at all. A value of 255 means 100%       *
    218  *                      adjustment.                                                            *
    219  *                                                                                             *
    220  * OUTPUT:  none                                                                               *
    221  *                                                                                             *
    222  * WARNINGS:   none                                                                            *
    223  *                                                                                             *
    224  * HISTORY:                                                                                    *
    225  *   12/02/1995 JLB : Created.                                                                 *
    226  *=============================================================================================*/
    227 void PaletteClass::Adjust(int ratio, PaletteClass const & palette)
    228 {
    229 	for (int index = 0; index < COLOR_COUNT; index++) {
    230 
    231 //if (index == 1) {
    232 //	Mono_Printf("From R=%d,G=%d,B=%d ", Palette[index].Red_Component(), Palette[index].Green_Component(), Palette[index].Blue_Component());
    233 //	Mono_Printf("To R=%d,G=%d,B=%d [%d] ", palette[index].Red_Component(), palette[index].Green_Component(), palette[index].Blue_Component(), ratio);
    234 //}
    235 		Palette[index].Adjust(ratio, palette[index]);
    236 
    237 //if (index == 1) {
    238 //	Mono_Printf("Equals R=%d,G=%d,B=%d.\n", Palette[index].Red_Component(), Palette[index].Green_Component(), Palette[index].Blue_Component());
    239 //}
    240 
    241 	}
    242 }
    243 
    244 
    245 /***********************************************************************************************
    246  * PaletteClass::Partial_Adjust -- Adjusts the specified parts of this palette toward black.   *
    247  *                                                                                             *
    248  *    This routine is used to adjust this palette toward black. Typical use of this routine    *
    249  *    is when fading the palette to black. The input lookup table is used to determine         *
    250  *    which entries should fade and which should stay the same                                 *
    251  *                                                                                             *
    252  * INPUT:   ratio -- The ratio to fade this palette to black. 0 means no fading at all. 255    *
    253  *                   means 100% faded to black.                                                *
    254  *                                                                                             *
    255  *          lookup	-- ptr to lookup table                                                    *
    256  *                                                                                             *
    257  * OUTPUT:  none                                                                               *
    258  *                                                                                             *
    259  * WARNINGS:   This routine doesn't actually set the palette to the video card. Use the Set()  *
    260  *             function to achieve that purpose.                                               *
    261  *                                                                                             *
    262  * HISTORY:                                                                                    *
    263  *   12/02/1995 JLB : Created.                                                                 *
    264  *=============================================================================================*/
    265 void PaletteClass::Partial_Adjust(int ratio, char *lut)
    266 {
    267 	for (int index = 0; index < COLOR_COUNT; index++) {
    268 		if (lut[index]) {
    269 			Palette[index].Adjust(ratio, BlackColor);
    270 		}
    271 	}
    272 }
    273 
    274 
    275 /***********************************************************************************************
    276  * PaletteClass::Partial_Adjust -- Adjusts the palette toward another palette.                 *
    277  *                                                                                             *
    278  *    This routine is used to adjust a palette toward a destination palette by the ratio       *
    279  *    specified. This is primarily used by the palette fading routines.  The input lookup      *
    280  *    table is used to determine which entries should fade and which should stay the same      *
    281  *                                                                                             *
    282  *                                                                                             *
    283  * INPUT:   palette  -- Reference to the destination palette.                                  *
    284  *                                                                                             *
    285  *          ratio    -- The ratio to adjust this palette toward the destination palette. A     *
    286  *                      value of 0 means no adjustment at all. A value of 255 means 100%       *
    287  *                      adjustment.                                                            *
    288  *                                                                                             *
    289  *          lookup   -- ptr to lookup table                                                    *
    290  *                                                                                             *
    291  *                                                                                             *
    292  * OUTPUT:  none                                                                               *
    293  *                                                                                             *
    294  * WARNINGS:   none                                                                            *
    295  *                                                                                             *
    296  * HISTORY:                                                                                    *
    297  *   12/02/1995 JLB : Created.                                                                 *
    298  *=============================================================================================*/
    299 void PaletteClass::Partial_Adjust(int ratio, PaletteClass const & palette, char *lut)
    300 {
    301 	for (int index = 0; index < COLOR_COUNT; index++) {
    302 		if (lut[index]) {
    303 			Palette[index].Adjust(ratio, palette[index]);
    304 		}
    305 	}
    306 }
    307 
    308 
    309 /***********************************************************************************************
    310  * PaletteClass::Closest_Color -- Finds closest match to color specified.                      *
    311  *                                                                                             *
    312  *    This routine will examine the palette and return with the color index number for the     *
    313  *    color that most closely matches the color specified. Remap operations rely heavily on    *
    314  *    this routine to allow working with a constant palette.                                   *
    315  *                                                                                             *
    316  * INPUT:   rgb   -- Reference to a color to search for in the current palette.                *
    317  *                                                                                             *
    318  * OUTPUT:  Returns with a color index value to most closely matches the specified color.      *
    319  *                                                                                             *
    320  * WARNINGS:   This routine will quite likely not find an exact match.                         *
    321  *                                                                                             *
    322  * HISTORY:                                                                                    *
    323  *   12/02/1995 JLB : Created.                                                                 *
    324  *=============================================================================================*/
    325 int PaletteClass::Closest_Color(RGBClass const & rgb) const
    326 {
    327 	int closest = 0;
    328 	int value = -1;
    329 
    330 	RGBClass const * ptr = &Palette[0];
    331 	for (int index = 0; index < COLOR_COUNT; index++) {
    332 		int difference = rgb.Difference(*ptr++);
    333 		if (value == -1 || difference < value) {
    334 			value = difference;
    335 			closest = index;
    336 		}
    337 	}
    338 	return(closest);
    339 }
    340 
    341 
    342 #ifndef	WIN32
    343 extern void Vsync(void);
    344 #pragma aux Vsync modify [edx ebx eax] = \
    345 	"mov	edx,03DAh"				\
    346 	"mov	ebx,[VertBlank]"		\
    347 	"and	bl,001h"					\
    348 	"shl	bl,3"						\
    349 	"in_vbi:"						\
    350 	"in	al,dx"					\
    351 	"and	al,008h"					\
    352 	"xor	al,bl"					\
    353 	"je	in_vbi"					\
    354 	"out_vbi:"						\
    355 	"in	al,dx"					\
    356 	"and	al,008h"					\
    357 	"xor	al,bl"					\
    358 	"jne	out_vbi"
    359 #endif	//WIN32
    360 
    361 
    362 /***********************************************************************************************
    363  * PaletteClass::Set -- Fade the display palette to this palette.                              *
    364  *                                                                                             *
    365  *    This routine will fade the display palette to match this palette over the time period    *
    366  *    specified. For smooth palette transitions, this is the routine to call.                  *
    367  *                                                                                             *
    368  * INPUT:   time  -- The time period (in system tick increments) to fade the display palette   *
    369  *                   to match this palette.                                                    *
    370  *                                                                                             *
    371  *          callback -- Optional pointer to callback function that, if non-null, will be       *
    372  *                      called as often as possible during the fading process.                 *
    373  *                                                                                             *
    374  * OUTPUT:  none                                                                               *
    375  *                                                                                             *
    376  * WARNINGS:   This routine will not return until the palette is completely faded to the       *
    377  *             destination palette.                                                            *
    378  *                                                                                             *
    379  * HISTORY:                                                                                    *
    380  *   12/02/1995 JLB : Created.                                                                 *
    381  *   02/05/1996 JLB : Uses new timer system.                                                   *
    382  *=============================================================================================*/
    383 void PaletteClass::Set(int time, void (* callback)(void)) const
    384 {
    385 	CDTimerClass<SystemTimerClass> timer = time;
    386 	PaletteClass original = CurrentPalette;
    387 
    388 	while (timer) {
    389 
    390 		/*
    391 		**	Build an intermediate palette that is as close to the destination palette
    392 		**	as the current time is proportional to the ending time.
    393 		*/
    394 		PaletteClass palette = original;
    395 		int adjust = ((time - timer) * 256) / time;
    396 		palette.Adjust(adjust, *this);
    397 
    398 		/*
    399 		**	Remember the current time so that multiple palette sets within the same game
    400 		**	time tick won't occur. This is probably unnecessary since the palette setting
    401 		**	code, at the time of this writing, delays at least one game tick in the process
    402 		**	of setting the palette.
    403 		*/
    404 		long holdtime = timer;
    405 
    406 		/*
    407 		**	Set the palette to this intermediate palette and then loop back
    408 		**	to calculate and set a new intermediate palette.
    409 		*/
    410 #ifdef WIN32
    411 		Set_Palette((void*)&palette[0]);
    412 #else
    413 		palette.Set();
    414 #endif	//WIN32
    415 
    416 		/*
    417 		**	If the callback routine was specified, then call it once per palette
    418 		**	setting loop.
    419 		*/
    420 		if (callback) {
    421 			callback();
    422 		}
    423 
    424 		/*
    425 		**	This loop ensures that the palette won't be set more than once per game tick. Setting
    426 		**	the palette more than once per game tick will have no effect since the calculation will
    427 		**	result in the same intermediate palette that was previously calculated.
    428 		*/
    429 		while (timer == holdtime && holdtime != 0) {
    430 			if (callback) callback();
    431 		}
    432 	}
    433 
    434 	/*
    435 	**	Ensure that the final palette exactly matches the requested
    436 	**	palette before exiting the fading routine.
    437 	*/
    438 #ifndef WIN32
    439 	Vsync();
    440 	RGBClass const * rgbptr = &Palette[0];
    441 	RGBClass::Raw_Color_Prep(0);
    442 	for (int index = 0; index < COLOR_COUNT; index++) {
    443 		rgbptr->Raw_Set();
    444 		rgbptr++;
    445 	}
    446 	((PaletteClass &)CurrentPalette) = *this;
    447 #else	//WIN32
    448 	Set_Palette((void*)&Palette[0]);
    449 #endif
    450 }