CnC_Remastered_Collection

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

POWER.CPP (22270B)


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