CnC_Remastered_Collection

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

GAUGE.CPP (26712B)


      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\gauge.cpv   2.19   16 Oct 1995 16:50:56   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 : GAUGE.CPP                                                    *
     24  *                                                                                             *
     25  *                   Programmer : Joe L. Bostic, Maria del Mar McCready Legg                   *
     26  *                                                                                             *
     27  *                   Start Date : 01/15/95                                                     *
     28  *                                                                                             *
     29  *                  Last Update : January 16, 1995 [JLB]                                       *
     30  *                                                                                             *
     31  *---------------------------------------------------------------------------------------------*
     32  * Functions:                                                                                  *
     33  *   GaugeClass::Action -- Handles input events for the gauge.                                 *
     34  *   GaugeClass::Draw_Me -- Draws the body of the gauge.                                       *
     35  *   GaugeClass::Value_To_Pixel -- Convert gauge value to pixel offset.                        *
     36  *   GaugeClass::Pixel_To_Value -- Convert a pixel offset into a gauge value.                  *
     37  *   GaugeClass::Set_Value -- Set the value of the gauge.                                      *
     38  *   GaugeClass::Set_Maximum -- Sets the maximum value for the gauge.                          *
     39  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     40 
     41 #include	"function.h"
     42 
     43 
     44 /***************************************************************************
     45  * GAUGECLASS::GAUGECLASS -- class constructor                             *
     46  *                                                                         *
     47  * INPUT:    id                     -- button ID                           *
     48  *                                                                         *
     49  *             x,y                     -- upper-left corner, in pixels     *
     50  *                                                                         *
     51  *             w,h                     -- width, height, in pixels         *
     52  *                                                                         *
     53  * OUTPUT:   none.                                                         *
     54  *                                                                         *
     55  * WARNINGS: none.                                                         *
     56  *                                                                         *
     57  * HISTORY:  01/05/1995 MML : Created.                                     *
     58  *=========================================================================*/
     59 GaugeClass::GaugeClass(unsigned id, int x, int y, int w, int h)
     60 	: ControlClass(id, x, y, w, h, LEFTHELD|LEFTPRESS|LEFTRELEASE, true)
     61 {
     62 	Set_Maximum(255);
     63 	Set_Value(0);
     64 
     65 	HasThumb = true;
     66 	IsHorizontal = (w > h);
     67 	IsColorized = true;
     68 
     69 	ClickDiff = 0;
     70 }
     71 
     72 
     73 /***********************************************************************************************
     74  * GaugeClass::Set_Maximum -- Sets the maximum value for the gauge.                            *
     75  *                                                                                             *
     76  *    This routine will set the maximum value for the gauge. This is the largest value that    *
     77  *    the current setting may reach. The ability to change this allows the guage to use and    *
     78  *    return values that are convenient for the programmer's current needs.                    *
     79  *                                                                                             *
     80  * INPUT:   value -- The value to use as the gauge maximum.                                    *
     81  *                                                                                             *
     82  * OUTPUT:  bool; Was the gauge maximum changed? A false indicates that the specified value    *
     83  *                already matches the current maximum.                                         *
     84  *                                                                                             *
     85  * WARNINGS:   none                                                                            *
     86  *                                                                                             *
     87  * HISTORY:                                                                                    *
     88  *   01/16/1995 JLB : Created.                                                                 *
     89  *=============================================================================================*/
     90 int GaugeClass::Set_Maximum(int value)
     91 {
     92 	if (value != MaxValue) {
     93 	   MaxValue = value;
     94 		Flag_To_Redraw();
     95 		return(true);
     96 	}
     97 	return(false);
     98 }
     99 
    100 
    101 /***********************************************************************************************
    102  * GaugeClass::Set_Value -- Set the value of the gauge.                                        *
    103  *                                                                                             *
    104  *    This routine will set the current value for the gauge. This value is clipped to the      *
    105  *    limits of the gauge maximum.                                                             *
    106  *                                                                                             *
    107  * INPUT:   value -- The value to set at the new current value.                                *
    108  *                                                                                             *
    109  * OUTPUT:  bool; Was the current setting changed? A false indicates that the setting          *
    110  *                specified is the same as what was already there.                             *
    111  *                                                                                             *
    112  * WARNINGS:   none                                                                            *
    113  *                                                                                             *
    114  * HISTORY:                                                                                    *
    115  *   01/16/1995 JLB : Created.                                                                 *
    116  *=============================================================================================*/
    117 int GaugeClass::Set_Value(int value)
    118 {
    119 	value = Bound(value, 0, MaxValue);
    120 //	value = MIN(value, MaxValue);
    121 //	value = MAX(value, 0);
    122 	if (value != CurValue) {
    123 		CurValue = value;
    124 		Flag_To_Redraw();
    125 		return(true);
    126 	}
    127 	return(false);
    128 }
    129 
    130 
    131 /***********************************************************************************************
    132  * GaugeClass::Pixel_To_Value -- Convert a pixel offset into a gauge value.                    *
    133  *                                                                                             *
    134  *    Use this routine to conver the specified pixel offset into a gauge value. This is used   *
    135  *    in translating mouse clicks into a cooresponding setting for the guage.                  *
    136  *                                                                                             *
    137  * INPUT:   pixel -- The pixel offset form the start of the gauge.                             *
    138  *                                                                                             *
    139  * OUTPUT:  Returns with the setting value in guage coordinates.                               *
    140  *                                                                                             *
    141  * WARNINGS:   none                                                                            *
    142  *                                                                                             *
    143  * HISTORY:                                                                                    *
    144  *   01/16/1995 JLB : Created.                                                                 *
    145  *=============================================================================================*/
    146 int GaugeClass::Pixel_To_Value(int pixel)
    147 {
    148 	int maximum;
    149 
    150 	if (IsHorizontal) {
    151 		pixel -= X+1;
    152 		maximum = Width;
    153 	} else {
    154 		pixel -= Y+1;
    155 		maximum = Height;
    156 	}
    157 	maximum -= 2;
    158 	pixel = Bound(pixel, 0, maximum);
    159 //	pixel = MIN(pixel, maximum);
    160 //	pixel = MAX(pixel, 0);
    161 	return(Fixed_To_Cardinal(MaxValue, Cardinal_To_Fixed(maximum, pixel)));
    162 }
    163 
    164 
    165 /***********************************************************************************************
    166  * GaugeClass::Value_To_Pixel -- Convert gauge value to pixel offset.                          *
    167  *                                                                                             *
    168  *    Use this routine to convert the specified gauge value into a pixel offset from the       *
    169  *    star of the gauge. This is used for thumb positioning.                                   *
    170  *                                                                                             *
    171  * INPUT:   value -- The value to convert to a pixel offset.                                   *
    172  *                                                                                             *
    173  * OUTPUT:  Returns with the pixel offset of the specified value from the start of the         *
    174  *          guage.                                                                             *
    175  *                                                                                             *
    176  * WARNINGS:   none                                                                            *
    177  *                                                                                             *
    178  * HISTORY:                                                                                    *
    179  *   01/16/1995 JLB : Created.                                                                 *
    180  *=============================================================================================*/
    181 int GaugeClass::Value_To_Pixel(int value)
    182 {
    183 	int maximum;
    184 	int start;
    185 	if (IsHorizontal) {
    186 		maximum = Width;
    187 		start = X;
    188 	} else {
    189 		maximum = Height;
    190 		start = Y;
    191 	}
    192 	maximum -= 2;
    193 	return(start + Fixed_To_Cardinal(maximum, Cardinal_To_Fixed(MaxValue, value)));
    194 }
    195 
    196 
    197 /***********************************************************************************************
    198  * GaugeClass::Draw_Me -- Draws the body of the gauge.                                         *
    199  *                                                                                             *
    200  *    This routine will draw the body of the gauge if necessary.                               *
    201  *                                                                                             *
    202  * INPUT:      forced   -- Should the gauge be redrawn regardless of the current redraw flag?  *
    203  *                                                                                             *
    204  * OUTPUT:     bool; Was the gauge redrawn?                                                    *
    205  *                                                                                             *
    206  * WARNINGS:   none                                                                            *
    207  *                                                                                             *
    208  * HISTORY:    01/16/1995 JLB : Created.                                                       *
    209  *=============================================================================================*/
    210 int GaugeClass::Draw_Me(int forced)
    211 {
    212 	if (ControlClass::Draw_Me(forced)) {
    213 
    214 		/*
    215 		===================== Hide the mouse =====================
    216 		*/
    217 		if (LogicPage == &SeenBuff) {
    218 			Conditional_Hide_Mouse(X, Y, X+Width, Y+Height);
    219 		}
    220 
    221 		/*
    222 		=========== Draw the body & set text color ===============
    223 		*/
    224 		Draw_Box (X, Y, Width, Height, BOXSTYLE_GREEN_DOWN, true);
    225 
    226 		/*
    227 		**	Colorize the inside of the gauge if indicated.
    228 		*/
    229 		if (IsColorized) {
    230 			int middle = Value_To_Pixel(CurValue);
    231 			int color = CC_BRIGHT_GREEN;
    232 			if (IsHorizontal) {
    233 				if (middle >= (X + 1))
    234 					LogicPage->Fill_Rect(X+1, Y+1, middle, Y+Height-2, color);
    235 			} else {
    236 				if (middle >= (Y + 1))
    237 					LogicPage->Fill_Rect(X+1, Y+1, X+Width-2, middle, color);
    238 			}
    239 		}
    240 
    241 		if (HasThumb)
    242 			Draw_Thumb();
    243 
    244 		/*
    245 		=================== Display the mouse ===================
    246 		*/
    247 		if (LogicPage == &SeenBuff) {
    248 			Conditional_Show_Mouse();
    249 		}
    250 		return(true);
    251 	}
    252 	return(false);
    253 }
    254 
    255 
    256 /***********************************************************************************************
    257  * GaugeClass::Action -- Handles input events for the gauge.                                   *
    258  *                                                                                             *
    259  *    This routine will handle input event processing for the gauge. It will adjust the        *
    260  *    current setting of the gauge according to the mouse position.                            *
    261  *                                                                                             *
    262  * INPUT:   flags -- The input event that is the reason for this function call.                *
    263  *          key   -- The key code that caused the event.                                       *
    264  *                                                                                             *
    265  * OUTPUT:  bool; Was the even recognized, processed, and no further gadget scanning is        *
    266  *                desird (for this pass).                                                      *
    267  *                                                                                             *
    268  * WARNINGS:   none                                                                            *
    269  * HISTORY:                                                                                    *
    270  *   01/16/1995 JLB : Created.                                                                 *
    271  *=============================================================================================*/
    272 int GaugeClass::Action(unsigned flags, KeyNumType &key)
    273 {
    274 	/*
    275 	** If there's no thumb on this gauge, it's a display-only device; ignore
    276 	** any input.
    277 	*/
    278 	if (!HasThumb) {
    279 		key = KN_NONE;
    280 		return(true);
    281 	}
    282 
    283 	/*
    284 	**	We might end up clearing the event bits. Make sure that the sticky
    285 	**	process is properly updated anyway.
    286 	*/
    287 	Sticky_Process(flags);
    288 
    289 	/*
    290 	**	If the thumb is currently being "dragged around", then update the slider
    291 	**	position according to the mouse position. In all other cases, ignore the
    292 	**	button being held down.
    293 	*/
    294 	if ((flags & LEFTPRESS) || ((flags & LEFTHELD) && StuckOn == this)) {
    295 
    296 		/*
    297 		** Compute the difference between where we clicked, and the edge of
    298 		** the thumb (only if we clicked on the thumb.)
    299 		*/
    300 		if (flags & LEFTPRESS) {
    301 			int curpix = Value_To_Pixel(CurValue);
    302 			int clickpix = (IsHorizontal ? Get_Mouse_X() : Get_Mouse_Y());
    303 
    304 			if ( (clickpix > curpix) && (clickpix - curpix) < Thumb_Pixels()) {
    305 				ClickDiff = (clickpix - curpix);
    306 			} else {
    307 				ClickDiff = 0;
    308 			}
    309 
    310 			int testval = Pixel_To_Value(IsHorizontal ?
    311 				Get_Mouse_X() - ClickDiff : Get_Mouse_Y() - ClickDiff);
    312 
    313 			/*
    314 			** Correct for round-down errors in Pixel_To_Value() and
    315 			** Value_To_Pixe(); make ClickDiff exactly right so that
    316 			** at this point, Get_Mouse_n() - ClickDiff converts to
    317 			** CurValue.
    318 			*/
    319 			while (testval < CurValue && ClickDiff > 0) {
    320 				ClickDiff--;
    321 				testval = Pixel_To_Value(IsHorizontal ?
    322 				Get_Mouse_X() - ClickDiff : Get_Mouse_Y() - ClickDiff);
    323 			}
    324 		}
    325 
    326 		/*
    327 		**	If no change occurred in the gauge, just call Control's Action routine,
    328 		** but turn off the flags so it won't fill in 'key' with the button ID.
    329 		** Thus, no button ID will be returned by Input.
    330 		*/
    331 		if (!Set_Value(Pixel_To_Value(IsHorizontal ?
    332 			Get_Mouse_X() - ClickDiff : Get_Mouse_Y() - ClickDiff))) {
    333 
    334 			flags &= ~(LEFTHELD|LEFTRELEASE|LEFTPRESS);
    335 			ControlClass::Action(0,key);
    336 			key = KN_NONE;
    337 			return(true);
    338 		}
    339 
    340 	} else {
    341 
    342 		/*
    343 		**	Ingore the left mouse button being held down if this gauge is not
    344 		**	currently in "sticky" mode. This allows processing of the LEFTPRESS
    345 		**	by any derived classes such that this guage can be more closely
    346 		**	controlled.
    347 		*/
    348 		flags &= ~LEFTHELD;
    349 	}
    350 	return(ControlClass::Action(flags, key));
    351 }
    352 
    353 
    354 /***********************************************************************************************
    355  * GaugeClass::Draw_Thumb -- Draws the body of the gauge.                                      *
    356  *                                                                                             *
    357  *    This routine will draw the body of the gauge if necessary.                               *
    358  *                                                                                             *
    359  * INPUT:      none.                                                                           *
    360  *                                                                                             *
    361  * OUTPUT:     none.                                                                           *
    362  *                                                                                             *
    363  * WARNINGS:   none.                                                                           *
    364  *                                                                                             *
    365  * HISTORY:    01/16/1995 MML : Created.                                                       *
    366  *=============================================================================================*/
    367 void GaugeClass::Draw_Thumb(void)
    368 {
    369 	int x = Value_To_Pixel(CurValue);
    370 
    371 //	if ((x + 8) > Value_To_Pixel(MaxValue)) {
    372 	if ((x + 4) > Value_To_Pixel(MaxValue)) {
    373 		x = Value_To_Pixel(MaxValue) - 2;
    374 	}
    375 
    376 	if (IsHorizontal) {
    377 		Draw_Box(x, Y, 4, Height, BOXSTYLE_GREEN_RAISED, true);
    378 		//Draw_Box(x, Y, 8, Height, BOXSTYLE_GREEN_RAISED, true);
    379 	} else {
    380 		Draw_Box(X, x, Width, 4,  BOXSTYLE_GREEN_RAISED, true);
    381 		//Draw_Box(X, x, Width, 8,  BOXSTYLE_GREEN_RAISED, true);
    382 	}
    383 }
    384 
    385 
    386 /***********************************************************************************************
    387  * TriColorGaugeClass::TriColorGaugeClass -- Constructor for 3 color (red\yellow\green) gauge. *
    388  *                                                                                             *
    389  *    This routine will draw the body of the gauge if necessary.                               *
    390  *                                                                                             *
    391  * INPUT:      See below.                                                                      *
    392  *                                                                                             *
    393  * OUTPUT:     none.                                                                           *
    394  *                                                                                             *
    395  * WARNINGS:   none.                                                                           *
    396  *                                                                                             *
    397  * HISTORY:    01/16/1995 MML : Created.                                                       *
    398  *=============================================================================================*/
    399 TriColorGaugeClass::TriColorGaugeClass(unsigned id, int x, int y, int w, int h)
    400 	: GaugeClass(id, x, y, w, h)
    401 {
    402 	RedLimit = 0;				// maximum value for red
    403 	YellowLimit = 0;			// maximum value for yellow
    404 }
    405 
    406 
    407 /***********************************************************************************************
    408  * TriColorGaugeClass::Set_Red_Limit -- Set the value for the red area of gauge.               *
    409  *                                                                                             *
    410  * INPUT:      int value.                                                                      *
    411  *                                                                                             *
    412  * OUTPUT:     bool true of false.                                                             *
    413  *                                                                                             *
    414  * WARNINGS:   none.                                                                           *
    415  *                                                                                             *
    416  * HISTORY:    01/16/1995 MML : Created.                                                       *
    417  *=============================================================================================*/
    418 int TriColorGaugeClass::Set_Red_Limit(int value)
    419 {
    420 	if (value >= 0 && value < MaxValue) {
    421 
    422 //		if (value > YellowLimit) {
    423 //			RedLimit = YellowLimit;
    424 //			YellowLimit = value;
    425 //		} else {
    426 			RedLimit = value;
    427 //		}
    428 		Flag_To_Redraw();
    429 		return(true);
    430 	}
    431 	return(false);
    432 }
    433 
    434 
    435 /***********************************************************************************************
    436  * TriColorGaugeClass::Set_Yellow_Limit -- Set the value for the yellow area of gauge.         *
    437  *                                                                                             *
    438  * INPUT:      int value.                                                                      *
    439  *                                                                                             *
    440  * OUTPUT:     bool true of false.                                                             *
    441  *                                                                                             *
    442  * WARNINGS:   none.                                                                           *
    443  *                                                                                             *
    444  * HISTORY:    01/16/1995 MML : Created.                                                       *
    445  *=============================================================================================*/
    446 int TriColorGaugeClass::Set_Yellow_Limit(int value)
    447 {
    448 	if (value >= 0 && value < MaxValue) {
    449 
    450 //		if (value < RedLimit) {
    451 //			YellowLimit = RedLimit;
    452 //			RedLimit = value;
    453 //		} else {
    454 			YellowLimit = value;
    455 //		}
    456 		Flag_To_Redraw();
    457 		return(true);
    458 	}
    459 	return(false);
    460 }
    461 
    462 
    463 /***********************************************************************************************
    464  * TriColorGaugeClass::Draw_Me -- Draw the tri color gauge.                                    *
    465  *                                                                                             *
    466  * INPUT:      int forced -- draw or not?                                                      *
    467  *                                                                                             *
    468  * OUTPUT:     bool true of false.                                                             *
    469  *                                                                                             *
    470  * WARNINGS:   none.                                                                           *
    471  *                                                                                             *
    472  * HISTORY:    01/16/1995 MML : Created.                                                       *
    473  *=============================================================================================*/
    474 int TriColorGaugeClass::Draw_Me(int forced)
    475 {
    476 	if (ControlClass::Draw_Me(forced)) {
    477 
    478 		/*
    479 		===================== Hide the mouse =====================
    480 		*/
    481 		if (LogicPage == &SeenBuff) {
    482 			Conditional_Hide_Mouse(X, Y, X+Width, Y+Height);
    483 		}
    484 		/*
    485 		=========== Draw the body & set text color ===============
    486 		*/
    487 		Draw_Box (X, Y, Width, Height, (IsDisabled ? BOXSTYLE_GREEN_RAISED : BOXSTYLE_GREEN_DOWN), true);
    488 
    489 		/*
    490 		**	Colorize the inside of the gauge if indicated.
    491 		*/
    492 		int red    = Value_To_Pixel(RedLimit);
    493 		int yellow = Value_To_Pixel(YellowLimit);
    494 		int middle = Value_To_Pixel(CurValue);
    495 
    496 		if (CurValue <= RedLimit) {
    497 			if (IsHorizontal) {
    498 				LogicPage->Fill_Rect(X+1, Y+1, middle, Y+Height-2, PINK);
    499 			} else {
    500 				LogicPage->Fill_Rect(X+1, Y+1, X+Width-2, middle, PINK);
    501 			}
    502 		} else if (CurValue > RedLimit && CurValue <= YellowLimit) {
    503 			if (IsHorizontal) {
    504 				LogicPage->Fill_Rect(X+1, Y+1, red,    Y+Height-2, PINK);
    505 				LogicPage->Fill_Rect(red, Y+1, middle, Y+Height-2, YELLOW);
    506 			} else {
    507 				LogicPage->Fill_Rect(X+1, Y+1, X+Width-2, red,    PINK);
    508 				LogicPage->Fill_Rect(X+1, red, X+Width-2, middle, YELLOW);
    509 			}
    510 		} else if (CurValue > YellowLimit && CurValue <= MaxValue) {
    511 
    512 			if (IsHorizontal) {
    513 				LogicPage->Fill_Rect(X+1,    Y+1, red,    Y+Height-2, PINK);
    514 				LogicPage->Fill_Rect(red,    Y+1, yellow, Y+Height-2, YELLOW);
    515 				LogicPage->Fill_Rect(yellow, Y+1, middle, Y+Height-2, GREEN);
    516 			} else {
    517 				LogicPage->Fill_Rect(X+1, Y+1,    X+Width-2, red,    PINK);
    518 				LogicPage->Fill_Rect(X+1, red,    X+Width-2, yellow, YELLOW);
    519 				LogicPage->Fill_Rect(X+1, yellow, X+Width-2, middle, GREEN);
    520 			}
    521 		}
    522 
    523 		if (HasThumb)
    524 			Draw_Thumb();
    525 
    526 		/*
    527 		=================== Display the mouse ===================
    528 		*/
    529 		if (LogicPage == &SeenBuff) {
    530 			Conditional_Show_Mouse();
    531 		}
    532 		return(true);
    533 	}
    534 	return(false);
    535 }
    536