CnC_Remastered_Collection

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

POWER.CPP (24067B)


      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/POWER.CPP 1     3/03/97 10:25a Joe_bostic $ */
     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 : POWER.CPP                                                    *
     24  *                                                                                             *
     25  *                   Programmer : Joe L. Bostic                                                *
     26  *                                                                                             *
     27  *                   Start Date : 12/15/94                                                     *
     28  *                                                                                             *
     29  *                  Last Update : October 14, 1996 [JLB]                                       *
     30  *                                                                                             *
     31  *---------------------------------------------------------------------------------------------*
     32  * Functions:                                                                                  *
     33  *   PowerClass::AI -- Process the power bar logic.                                            *
     34  *   PowerClass::Draw_It -- Renders the power bar graphic.                                     *
     35  *   PowerClass::Init_Clear -- Clears all the power bar variables.                             *
     36  *   PowerClass::One_Time -- One time processing for the power bar.                            *
     37  *   PowerClass::PowerButtonClass::Action -- Handles the mouse over the power bar area.        *
     38  *   PowerClass::PowerClass -- Default constructor for the power bar class.                    *
     39  *   PowerClass::Refresh_Cells -- Intercepts the redraw logic to see if sidebar to redraw too. *
     40  *   PowerClass::Power_Height -- Given a value figure where it falls on bar                    *
     41  *   PowerClass::Flash_Power -- Flag the power bar to flash.                                   *
     42  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     43 
     44 #include	"function.h"
     45 
     46 
     47 /*
     48 **	Points to the shape to use for the "desired" power level indicator.
     49 */
     50 void const * PowerClass::PowerShape;
     51 void const * PowerClass::PowerBarShape;
     52 
     53 PowerClass::PowerButtonClass PowerClass::PowerButton;
     54 
     55 
     56 /***********************************************************************************************
     57  * PowerClass::PowerClass -- Default constructor for the power bar class.                      *
     58  *                                                                                             *
     59  *    This is the default constructor for the power bar class. It doesn't really do anything.  *
     60  *                                                                                             *
     61  * INPUT:   none                                                                               *
     62  *                                                                                             *
     63  * OUTPUT:  none                                                                               *
     64  *                                                                                             *
     65  * WARNINGS:   none                                                                            *
     66  *                                                                                             *
     67  * HISTORY:                                                                                    *
     68  *   12/20/1994 JLB : Created.                                                                 *
     69  *=============================================================================================*/
     70 PowerClass::PowerClass(void) :
     71 	IsToRedraw(false),
     72 	IsActive(false),
     73 	FlashTimer(0),
     74 	RecordedDrain(-1),
     75 	RecordedPower(-1),
     76 	DesiredDrainHeight(0),
     77 	DesiredPowerHeight(0),
     78 	DrainHeight(0),
     79 	PowerHeight(0),
     80 	DrainBounce(0),
     81 	PowerBounce(0),
     82 	PowerDir(0),
     83 	DrainDir(0)
     84 {
     85 }
     86 
     87 
     88 /***********************************************************************************************
     89  * PowerClass::Init_Clear -- Clears all the power bar variables.                               *
     90  *                                                                                             *
     91  *    This routine is called in preparation for the start of a scenario. The power bar is      *
     92  *    initialized into the null state by this routine. As soon as the scenario starts, the     *
     93  *    power bar will rise to reflect the actual power output and drain.                        *
     94  *                                                                                             *
     95  * INPUT:   none                                                                               *
     96  *                                                                                             *
     97  * OUTPUT:  none                                                                               *
     98  *                                                                                             *
     99  * WARNINGS:   none                                                                            *
    100  *                                                                                             *
    101  * HISTORY:                                                                                    *
    102  *   08/07/1995 JLB : Created.                                                                 *
    103  *=============================================================================================*/
    104 void PowerClass::Init_Clear(void)
    105 {
    106 	RadarClass::Init_Clear();
    107 	RecordedDrain = -1;
    108 	RecordedPower = -1;
    109 	DesiredDrainHeight = 0;
    110 	DesiredPowerHeight = 0;
    111 	DrainHeight = 0;
    112 	PowerHeight = 0;
    113 	PowerBounce = 0;
    114 	DrainBounce = 0;
    115 	DrainDir = 0;
    116 	PowerDir = 0;
    117 	FlashTimer = 0;
    118 }
    119 
    120 
    121 /***********************************************************************************************
    122  * PowerClass::One_Time -- One time processing for the power bar.                              *
    123  *                                                                                             *
    124  * This routine is for code that truly only needs to be done once per game run.                *
    125  *                                                                                             *
    126  * INPUT:   none                                                                               *
    127  *                                                                                             *
    128  * OUTPUT:  none                                                                               *
    129  *                                                                                             *
    130  * WARNINGS:   none                                                                            *
    131  *                                                                                             *
    132  * HISTORY:                                                                                    *
    133  *   12/26/1994 JLB : Created.                                                                 *
    134  *=============================================================================================*/
    135 void PowerClass::One_Time(void)
    136 {
    137 	RadarClass::One_Time();
    138 	PowerButton.X = POWER_X * RESFACTOR;
    139 	PowerButton.Y = POWER_Y * RESFACTOR;
    140 	PowerButton.Width = (POWER_WIDTH * RESFACTOR)-1;
    141 	PowerButton.Height = POWER_HEIGHT * RESFACTOR;
    142 	PowerShape = MFCD::Retrieve("POWER.SHP");
    143 	PowerBarShape = MFCD::Retrieve("POWERBAR.SHP");
    144 }
    145 
    146 
    147 /***********************************************************************************************
    148  * PowerClass::Draw_It -- Renders the power bar graphic.                                       *
    149  *                                                                                             *
    150  *    This routine will draw the power bar graphic to the LogicPage.                           *
    151  *                                                                                             *
    152  * INPUT:   complete -- Should the power bar be redrawn even if it isn't specifically flagged  *
    153  *                      to do so?                                                              *
    154  *                                                                                             *
    155  * OUTPUT:  none                                                                               *
    156  *                                                                                             *
    157  * WARNINGS:   none                                                                            *
    158  *                                                                                             *
    159  * HISTORY:                                                                                    *
    160  *   12/20/1994 JLB : Created.                                                                 *
    161  *   12/27/1994 JLB : Changes power bar color depending on amount of power.                    *
    162  *=============================================================================================*/
    163 void PowerClass::Draw_It(bool complete)
    164 {
    165 	static int _modtable[]={
    166 		0, -1, 0, 1, 0, -1, -2, -1, 0, 1, 2, 1 ,0
    167 	};
    168 
    169 	if (complete || IsToRedraw) {
    170 		BStart(BENCH_POWER);
    171 
    172 		if (LogicPage->Lock()) {
    173 			if (Map.IsSidebarActive) {
    174 				IsToRedraw = false;
    175 				ShapeFlags_Type flags = SHAPE_NORMAL;
    176 				void const * remap = NULL;
    177 
    178 				if (FlashTimer > 1 && ((FlashTimer % 3) & 0x01) != 0) {
    179 					flags = flags | SHAPE_FADING;
    180 					remap = Map.FadingRed;
    181 				}
    182 
    183 //				LogicPage->Fill_Rect(POWER_X, POWER_Y, POWER_X+POWER_WIDTH-1, POWER_Y+POWER_HEIGHT-1, LTGREY);
    184 				CC_Draw_Shape(PowerBarShape, 0, 240 * RESFACTOR, 88 * RESFACTOR, WINDOW_MAIN, flags | SHAPE_NORMAL | SHAPE_WIN_REL, remap);
    185 
    186 #ifdef WIN32
    187 				/*
    188 				** Hires power strip is too big to fit into a shape so it is in two parts
    189 				*/
    190 				CC_Draw_Shape(PowerBarShape, 1, 240 * RESFACTOR, (88 * RESFACTOR) + (56*RESFACTOR), WINDOW_MAIN, flags | SHAPE_NORMAL | SHAPE_WIN_REL, remap);
    191 #endif
    192 				/*
    193 				**	Determine how much the power production exceeds or falls short
    194 				**	of power demands.
    195 				*/
    196 				int bottom       = (POWER_Y + POWER_HEIGHT - 1) * RESFACTOR;
    197 				int power_height  = (PowerHeight == DesiredPowerHeight) ? PowerHeight + (_modtable[PowerBounce] * PowerDir) : PowerHeight;
    198 				int drain_height  = (DrainHeight == DesiredDrainHeight) ? DrainHeight + (_modtable[DrainBounce] * DrainDir) : DrainHeight;
    199 				power_height = Bound(power_height, 0, POWER_HEIGHT - 2);
    200 				drain_height = Bound(drain_height, 0, POWER_HEIGHT - 2);
    201 
    202 				/*
    203 				**	Draw the power output graphic on top of the power bar framework.
    204 				*/
    205 				if (power_height) {
    206 					int color1 = 3;
    207 					int color2 = 4;
    208 
    209 					if (PlayerPtr->Drain > PlayerPtr->Power) {
    210 						color1 = 214;
    211 						color2 = 211;
    212 					}
    213 					if (PlayerPtr->Drain > (PlayerPtr->Power * 2)) {
    214 						color1 = 235;
    215 						color2 = 230;
    216 					}
    217 
    218 					/*
    219 					** New power bar is in slightly different place
    220 					**
    221 					** Old power bar was 107 pixels high. New bar is 153 pixels high.
    222 					**
    223 					** ST - 5/2/96 11:23AM
    224 					*/
    225 #ifdef WIN32
    226 					power_height = (power_height*(76*RESFACTOR+1)) / (53*RESFACTOR+1);
    227 					drain_height = (drain_height*(76*RESFACTOR+1)) / (53*RESFACTOR+1);
    228 #endif
    229 					bottom = (175*RESFACTOR)+1;
    230 
    231 					LogicPage->Fill_Rect(245*RESFACTOR, bottom-power_height, 245*RESFACTOR+1, bottom, color2);
    232 					LogicPage->Fill_Rect(246*RESFACTOR, bottom-power_height, 246*RESFACTOR+1, bottom, color1);
    233 				}
    234 
    235 				/*
    236 				**	Draw the power drain threshold marker.
    237 				*/
    238 				CC_Draw_Shape(PowerShape, 0, (POWER_X * RESFACTOR)+RESFACTOR, bottom - (drain_height + (2 * RESFACTOR)), WINDOW_MAIN, flags | SHAPE_NORMAL, remap);
    239 			}
    240 			LogicPage->Unlock();
    241 		}
    242 		BEnd(BENCH_POWER);
    243 	}
    244 	RadarClass::Draw_It(complete);
    245 }
    246 
    247 
    248 /***********************************************************************************************
    249  * PowerClass::AI -- Process the power bar logic.                                              *
    250  *                                                                                             *
    251  *    Use this routine to process the power bar logic. This consists of animation effects.     *
    252  *                                                                                             *
    253  * INPUT:   input -- The player input value to be consumed or ignored as appropriate.          *
    254  *                                                                                             *
    255  *          x,y   -- Mouse coordinate parameters to use.                                       *
    256  *                                                                                             *
    257  * OUTPUT:  none                                                                               *
    258  *                                                                                             *
    259  * WARNINGS:   none                                                                            *
    260  *                                                                                             *
    261  * HISTORY:                                                                                    *
    262  *   12/20/1994 JLB : Created.                                                                 *
    263  *   12/31/1994 JLB : Uses mouse coordinate parameters.                                        *
    264  *=============================================================================================*/
    265 void PowerClass::AI(KeyNumType &input, int x, int y)
    266 {
    267 	if (Map.IsSidebarActive /*IsActive*/) {
    268 		int olddrain = DrainHeight;
    269 		int oldpower  = PowerHeight;
    270 
    271 
    272 		/*
    273 		** If the recorded power value has changed we need to adjust for
    274 		** it.
    275 		*/
    276 		if (PlayerPtr->Power != RecordedPower) {
    277 			DesiredPowerHeight = Power_Height(PlayerPtr->Power);
    278 			RecordedPower		 = PlayerPtr->Power;
    279 			PowerBounce			 = 12;
    280 			if (PowerHeight > DesiredPowerHeight) {
    281 				PowerDir = -1;
    282 			} else if (PowerHeight < DesiredPowerHeight) {
    283 				PowerDir = 1;
    284 			} else {
    285 				PowerBounce = 0;
    286 			}
    287 		}
    288 
    289 		/*
    290 		** If the recorded drain value has changed we need to adjust for
    291 		** it.
    292 		*/
    293 		if (PlayerPtr->Drain != RecordedDrain) {
    294 			DesiredDrainHeight = Power_Height(PlayerPtr->Drain);
    295 			RecordedDrain		 = PlayerPtr->Drain;
    296 			DrainBounce			 = 12;
    297 			if (DrainHeight > DesiredDrainHeight) {
    298 				DrainDir = -1;
    299 			} else if (DrainHeight < DesiredDrainHeight) {
    300 				DrainDir = 1;
    301 			} else {
    302 				DrainBounce = 0;
    303 			}
    304 		}
    305 
    306 		if (DrainBounce && DrainHeight == DesiredDrainHeight) {
    307 			IsToRedraw = true;
    308 			Flag_To_Redraw(false);
    309 			DrainBounce--;
    310 		} else {
    311 			/*
    312 			** If we need to move the drain height then do so.
    313 			*/
    314 			if (DrainHeight != DesiredDrainHeight) {
    315 				DrainHeight += DrainDir;
    316 			}
    317 		}
    318 
    319 		if (PowerBounce && PowerHeight == DesiredPowerHeight) {
    320 			IsToRedraw = true;
    321 			Flag_To_Redraw(false);
    322 			PowerBounce--;
    323 		} else {
    324 			/*
    325 			** If we need to move the power height then do so.
    326 			*/
    327 			if (PowerHeight != DesiredPowerHeight) {
    328 				PowerHeight += PowerDir;
    329 			}
    330 		}
    331 
    332 		if (olddrain != DrainHeight || oldpower != PowerHeight) {
    333 			IsToRedraw = true;
    334 			Flag_To_Redraw(false);
    335 		}
    336 
    337 		/*
    338 		**	Flag to redraw if the power bar flash effect has expired.
    339 		*/
    340 //		if (FlashTimer == 1) {
    341 		if (FlashTimer > 0) {
    342 			IsToRedraw = true;
    343 			Flag_To_Redraw(false);
    344 		}
    345 	}
    346 	RadarClass::AI(input, x, y);
    347 }
    348 
    349 
    350 /***********************************************************************************************
    351  * PowerClass::Refresh_Cells -- Intercepts the redraw logic to see if sidebar to redraw too.   *
    352  *                                                                                             *
    353  *    This routine will examine a refresh list request and determine if the sidebar would be   *
    354  *    affect. If so, it will flag the sidebar to be redrawn.                                   *
    355  *                                                                                             *
    356  * INPUT:   cell  -- The cell that the offset list is base on.                                 *
    357  *                                                                                             *
    358  *          list  -- The list of cell offset used to flag for redraw. If the special sidebar   *
    359  *                   affecting cell magic offset number is detected, the sidebar is flagged    *
    360  *                   for redraw and the magic offset is removed.                               *
    361  *                                                                                             *
    362  * OUTPUT:  none                                                                               *
    363  *                                                                                             *
    364  * WARNINGS:   none                                                                            *
    365  *                                                                                             *
    366  * HISTORY:                                                                                    *
    367  *   06/01/1995 JLB : Created.                                                                 *
    368  *=============================================================================================*/
    369 void PowerClass::Refresh_Cells(CELL cell, short const * list)
    370 {
    371 	if (*list == REFRESH_SIDEBAR) {
    372 		IsToRedraw = true;
    373 		Flag_To_Redraw(false);
    374 	}
    375 	RadarClass::Refresh_Cells(cell, list);
    376 }
    377 
    378 
    379 /***************************************************************************
    380  * PowerClass::Power_Height -- Given a value figure where it falls on bar  *
    381  *                                                                         *
    382  * INPUT:		int value - the value we are testing                        *
    383  *                                                                         *
    384  * OUTPUT:     int the height of the point that this value is on graph     *
    385  *                                                                         *
    386  * WARNINGS:   none                                                        *
    387  *                                                                         *
    388  * HISTORY:                                                                *
    389  *   06/14/1995 PWG : Created.                                             *
    390  *=========================================================================*/
    391 int PowerClass::Power_Height(int value)
    392 {
    393 	int num		= value/ POWER_STEP_LEVEL;		// figure out the initial num of DRAIN_VALUE's
    394 	int retval	= 0;									// currently there is no power
    395 
    396 	/*
    397 	** Loop through the different hundreds figuring out the fractional piece
    398 	** of each.
    399 	*/
    400 	for (int lp = 0; lp < num; lp ++)  {
    401 		retval  = retval + (((POWER_HEIGHT - 2) - retval) / POWER_STEP_FACTOR);
    402 		value  -= POWER_STEP_LEVEL;
    403 	}
    404 
    405 	/*
    406 	** Adjust the retval to factor in the remainder
    407 	*/
    408 	if (value) {
    409 		retval = retval + (((((POWER_HEIGHT - 2) - retval) / POWER_STEP_FACTOR) * value) / POWER_STEP_LEVEL);
    410 	}
    411 
    412 	retval = Bound(retval, 0, POWER_HEIGHT-2);
    413 	return(retval);
    414 }
    415 
    416 
    417 /***********************************************************************************************
    418  * PowerClass::PowerButtonClass::Action -- Handles the mouse over the power bar area.          *
    419  *                                                                                             *
    420  *    This routine handles input on the power bar area. Since no input is used for the power   *
    421  *    bar, this routine just pops up appropriate help text for the power bar.                  *
    422  *                                                                                             *
    423  * INPUT:   flags    -- The event flags that triggered this action call.                       *
    424  *                                                                                             *
    425  *          key      -- The key code (if any) associated with the trigger event.               *
    426  *                                                                                             *
    427  * OUTPUT:  Should further button processing be stopped?                                       *
    428  *                                                                                             *
    429  * WARNINGS:   none                                                                            *
    430  *                                                                                             *
    431  * HISTORY:                                                                                    *
    432  *   08/07/1995 JLB : Created.                                                                 *
    433  *=============================================================================================*/
    434 int PowerClass::PowerButtonClass::Action(unsigned flags, KeyNumType & key)
    435 {
    436 	if (!Map.IsSidebarActive) {
    437 		return(false);
    438 	}
    439 
    440 	/*
    441 	**	Force any help label to disappear when the mouse is held over the
    442 	**	radar map.
    443 	*/
    444 	Map.Override_Mouse_Shape(MOUSE_NORMAL);
    445 	if (PlayerPtr->Power_Fraction() < 1 && PlayerPtr->Power > 0) {
    446 		Map.Help_Text(TXT_POWER_OUTPUT_LOW, -1, -1, GadgetClass::Get_Color_Scheme()->Color);
    447 	} else {
    448 		Map.Help_Text(TXT_POWER_OUTPUT, -1, -1, GadgetClass::Get_Color_Scheme()->Color);
    449 	}
    450 	GadgetClass::Action(flags, key);
    451 	return(true);
    452 }
    453 
    454 
    455 /***********************************************************************************************
    456  * PowerClass::Flash_Power -- Flag the power bar to flash.                                     *
    457  *                                                                                             *
    458  *    This will cause the power bar to display with a flash so as to draw attention to         *
    459  *    itself. Typical use of this effect is when power is low.                                 *
    460  *                                                                                             *
    461  * INPUT:   none                                                                               *
    462  *                                                                                             *
    463  * OUTPUT:  none                                                                               *
    464  *                                                                                             *
    465  * WARNINGS:   none                                                                            *
    466  *                                                                                             *
    467  * HISTORY:                                                                                    *
    468  *   10/14/1996 JLB : Created.                                                                 *
    469  *=============================================================================================*/
    470 void PowerClass::Flash_Power(void)
    471 {
    472 	FlashTimer = TICKS_PER_SECOND;
    473 	IsToRedraw = true;
    474 	Flag_To_Redraw(false);
    475 }