CnC_Remastered_Collection

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

MOUSE.CPP (19697B)


      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\mouse.cpv   2.18   16 Oct 1995 16:49: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 : MOUSE.CPP                                                    *
     24  *                                                                                             *
     25  *                   Programmer : Joe L. Bostic                                                *
     26  *                                                                                             *
     27  *                   Start Date : 12/15/94                                                     *
     28  *                                                                                             *
     29  *                  Last Update : June 30, 1995 [JLB]                                          *
     30  *                                                                                             *
     31  *---------------------------------------------------------------------------------------------*
     32  * Functions:                                                                                  *
     33  *   MouseClass::AI -- Process player input as it relates to the mouse                         *
     34  *   MouseClass::Override_Mouse_Shape -- Alters the shape of the mouse.                        *
     35  *   MouseClass::Init_Clear -- Sets the mouse system to a known state                          *
     36  *   MouseClass::MouseClass -- Default constructor for the mouse handler class.                *
     37  *   MouseClass::One_Time -- Performs the one time initialization of the mouse system.         *
     38  *   MouseClass::Set_Default_Mouse -- Sets the mouse to match the shape specified.             *
     39  *   MouseClass::Revert_Mouse_Shape -- Reverts the mouse shape to the non overridden shape.    *
     40  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     41 
     42 #include	"function.h"
     43 
     44 
     45 /*
     46 **	This points to the loaded mouse shapes.
     47 */
     48 void const * MouseClass::MouseShapes;
     49 
     50 /*
     51 **	This is the timer that controls the mouse animation. It is always at a fixed
     52 **	rate so it uses the constant system timer.
     53 */
     54 CountDownTimerClass MouseClass::Timer;
     55 
     56 /*
     57 ** This contains the value of the Virtual Function Table Pointer
     58 */
     59 void * MouseClass::VTable;
     60 
     61 
     62 /***********************************************************************************************
     63  * MouseClass::Set_Default_Mouse -- Sets the mouse to match the shape specified.               *
     64  *                                                                                             *
     65  *    This routine is used to inform the display system as to which mouse shape is desired.    *
     66  *                                                                                             *
     67  * INPUT:   mouse -- The mouse shape number to set the mouse to.                               *
     68  *                                                                                             *
     69  * OUTPUT:  none                                                                               *
     70  *                                                                                             *
     71  * WARNINGS:   none                                                                            *
     72  *                                                                                             *
     73  * HISTORY:                                                                                    *
     74  *   09/19/1994 JLB : Created.                                                                 *
     75  *=============================================================================================*/
     76 void MouseClass::Set_Default_Mouse(MouseType mouse, bool size)
     77 {
     78 	NormalMouseShape = mouse;
     79 	Override_Mouse_Shape(mouse, size);
     80 }
     81 
     82 
     83 /***********************************************************************************************
     84  * MouseClass::Revert_Mouse_Shape -- Reverts the mouse shape to the non overridden shape.      *
     85  *                                                                                             *
     86  *    Use this routine to cancel the effects of Override_Mouse_Shape(). It will revert the     *
     87  *    mouse back to the original shape.                                                        *
     88  *                                                                                             *
     89  * INPUT:   none                                                                               *
     90  *                                                                                             *
     91  * OUTPUT:  none                                                                               *
     92  *                                                                                             *
     93  * WARNINGS:   none                                                                            *
     94  *                                                                                             *
     95  * HISTORY:                                                                                    *
     96  *   03/27/1995 JLB : Created.                                                                 *
     97  *=============================================================================================*/
     98 void MouseClass::Revert_Mouse_Shape(void)
     99 {
    100 	Override_Mouse_Shape(NormalMouseShape, false);
    101 }
    102 
    103 
    104 void MouseClass::Mouse_Small(bool wwsmall)
    105 {
    106 	MouseStruct const * control = &MouseControl[CurrentMouseShape];
    107 
    108 	if (IsSmall == wwsmall) {
    109 		return;
    110 	}
    111 
    112 	IsSmall	= wwsmall;
    113 
    114 	if (wwsmall) {
    115 		if (control->SmallFrame != -1) {
    116 			Set_Mouse_Cursor(control->X, control->Y, Extract_Shape(MouseShapes, control->SmallFrame + Frame/4));
    117 		} else {
    118 			Set_Mouse_Cursor(MouseControl[MOUSE_NORMAL].X, MouseControl[MOUSE_NORMAL].Y, Extract_Shape(MouseShapes, MOUSE_NORMAL));
    119 		}
    120 	} else {
    121 		Set_Mouse_Cursor(control->X, control->Y, Extract_Shape(MouseShapes, control->StartFrame + Frame/4));
    122 	}
    123 }
    124 
    125 
    126 /***********************************************************************************************
    127  * MouseClass::Override_Mouse_Shape -- Alters the shape of the mouse.                          *
    128  *                                                                                             *
    129  *    This routine is used to alter the shape of the mouse as needed.                          *
    130  *    Typical mouse shape change occurs when scrolling the map or                              *
    131  *    selecting targets.                                                                       *
    132  *                                                                                             *
    133  * INPUT:   mouse -- The mouse shape number to use.                                            *
    134  *                                                                                             *
    135  * OUTPUT:  bool; Was the mouse shape changed?                                                 *
    136  *                                                                                             *
    137  * WARNINGS:   This is not intended to be used as a means to hide the                          *
    138  *             mouse. Nor will it work correctly if the mouse shape                            *
    139  *             file hasn't been loaded.                                                        *
    140  *                                                                                             *
    141  * HISTORY:                                                                                    *
    142  *   03/10/1994 JLB : Created.                                                                 *
    143  *   06/03/1994 JLB : Made into member function.                                               *
    144  *   12/24/1994 JLB : Added small control parameter.                                           *
    145  *=============================================================================================*/
    146 bool MouseClass::Override_Mouse_Shape(MouseType mouse, bool wwsmall)
    147 {
    148 	MouseStruct const * control = &MouseControl[mouse];
    149 	static bool startup = false;
    150 	int baseshp;
    151 
    152 	/*
    153 	**	Only certain mouse shapes have a small counterpart. If the requested mouse
    154 	**	shape is not one of these, then force the small size override flag to false.
    155 	*/
    156 	if (control->SmallFrame == -1) {
    157 		wwsmall = false;
    158 	}
    159 
    160 	/*
    161 	**	If the mouse shape is going to change, then inform the mouse driver of the
    162 	**	change.
    163 	*/
    164 	if (!startup || (MouseShapes && ((mouse != CurrentMouseShape) || (wwsmall != IsSmall)))) {
    165 		startup = true;
    166 
    167 		Timer.Set(control->FrameRate);
    168 		Frame = 0;
    169 
    170 #ifdef OBSOLETE
    171 		Control.Set_Stage(0);
    172 		int rate = Options.Normalize_Delay(control->FrameRate);
    173 		Control.Set_Rate(MAX(rate, 1));
    174 #endif
    175 		baseshp = (wwsmall) ? control->SmallFrame : control->StartFrame;
    176 
    177 		Set_Mouse_Cursor(control->X, control->Y, Extract_Shape(MouseShapes, baseshp + Frame/4));
    178 		CurrentMouseShape = mouse;
    179 		IsSmall = wwsmall;
    180 		return(true);
    181 	}
    182 	return(false);
    183 }
    184 
    185 
    186 /***********************************************************************************************
    187  * MouseClass::AI -- Process player input as it relates to the mouse                           *
    188  *                                                                                             *
    189  *    This routine will is to be called once per game tick and is passed the player keyboard   *
    190  *    or mouse input code. It processes this code and updates the mouse shape as appropriate.  *
    191  *                                                                                             *
    192  * INPUT:   input -- The player input code as returned from Keyboard::Get().                   *
    193  *                                                                                             *
    194  *          x,y   -- The mouse coordinate values to use.                                       *
    195  *                                                                                             *
    196  * OUTPUT:  none                                                                               *
    197  *                                                                                             *
    198  * WARNINGS:   none                                                                            *
    199  *                                                                                             *
    200  * HISTORY:                                                                                    *
    201  *   12/24/1994 JLB : Created.                                                                 *
    202  *   12/31/1994 JLB : Uses mouse coordinate parameters.                                        *
    203  *   03/27/1995 JLB : New animation control.                                                   *
    204  *   05/28/1995 JLB : Moderates animation so is more steady regardless of speed.               *
    205  *   06/30/1995 JLB : Uses constant timer system.                                              *
    206  *=============================================================================================*/
    207 void MouseClass::AI(KeyNumType &input, int x, int y)
    208 {
    209 //	bool doit = false;
    210 	void *mouse_shape_ptr;
    211 	MouseStruct const * control = &MouseControl[CurrentMouseShape];
    212 
    213 	if (control->FrameRate && Timer.Time() == 0) {
    214 
    215 		Frame++;
    216 		Frame %= control->FrameCount;
    217 		Timer.Set(control->FrameRate);
    218 
    219 #ifdef OBSOLETE
    220 		Control.Set_Stage(Control.Fetch_Stage() % control->FrameCount);
    221 #endif
    222 
    223 		if (!IsSmall || control->SmallFrame != -1) {
    224 			int baseframe = (IsSmall) ? control->SmallFrame : control->StartFrame;
    225 			mouse_shape_ptr = Extract_Shape(MouseShapes, baseframe + Frame);
    226 			if (mouse_shape_ptr){
    227 				Set_Mouse_Cursor(control->X, control->Y, mouse_shape_ptr);
    228 			}
    229 		}
    230 	}
    231 
    232 	ScrollClass::AI(input, x, y);
    233 }
    234 
    235 
    236 /***********************************************************************************************
    237  * MouseClass::MouseClass -- Default constructor for the mouse handler class.                  *
    238  *                                                                                             *
    239  *    This is the default constructor for the mouse handling class. It merely sets up the      *
    240  *    mouse system to its default state.                                                       *
    241  *                                                                                             *
    242  * INPUT:   none                                                                               *
    243  *                                                                                             *
    244  * OUTPUT:  none                                                                               *
    245  *                                                                                             *
    246  * WARNINGS:   none                                                                            *
    247  *                                                                                             *
    248  * HISTORY:                                                                                    *
    249  *   12/24/1994 JLB : Created.                                                                 *
    250  *=============================================================================================*/
    251 MouseClass::MouseClass(void)
    252 {
    253 	CurrentMouseShape = MOUSE_NORMAL;
    254 	NormalMouseShape = MOUSE_NORMAL;
    255 	Timer.Start();
    256 }
    257 
    258 
    259 /***********************************************************************************************
    260  * MouseClass::One_Time -- Performs the one time initialization of the mouse system.           *
    261  *                                                                                             *
    262  *    Use this routine to load the mouse data file and perform any other necessary one time    *
    263  *    preparations for the game.                                                               *
    264  *                                                                                             *
    265  * INPUT:   none                                                                               *
    266  *                                                                                             *
    267  * OUTPUT:  none                                                                               *
    268  *                                                                                             *
    269  * WARNINGS:   Only call this routine ONCE.                                                    *
    270  *                                                                                             *
    271  * HISTORY:                                                                                    *
    272  *   12/24/1994 JLB : Created.                                                                 *
    273  *=============================================================================================*/
    274 void MouseClass::One_Time(void)
    275 {
    276 	ScrollClass::One_Time();
    277 
    278 	/*
    279 	**	Override the mouse shape file with the one in the current directory, but only if there
    280 	**	is an override file available.
    281 	*/
    282 	RawFileClass file("MOUSE.SHP");
    283 	if (file.Is_Available()) {
    284 		MouseShapes = Load_Alloc_Data(file);
    285 	} else {
    286 		MouseShapes = MixFileClass::Retrieve("MOUSE.SHP");
    287 	}
    288 
    289 	VTable = ((void **)(((char *)this) + sizeof(VectorClass<CellClass>) - 4))[0];
    290 }
    291 
    292 
    293 /***********************************************************************************************
    294  * MouseClass::Init_Clear -- Sets the mouse system to a known state                            *
    295  *                                                                                             *
    296  *    This routine will reset the mouse handling system. Typically, this routine is called     *
    297  *    when preparing for the beginning of a new scenario.                                      *
    298  *                                                                                             *
    299  * INPUT:   theater  -- The theater that the scenario will take place.                         *
    300  *                                                                                             *
    301  * OUTPUT:  none                                                                               *
    302  *                                                                                             *
    303  * WARNINGS:   none                                                                            *
    304  *                                                                                             *
    305  * HISTORY:                                                                                    *
    306  *   12/24/1994 JLB : Created.                                                                 *
    307  *=============================================================================================*/
    308 void MouseClass::Init_Clear(void)
    309 {
    310 	ScrollClass::Init_Clear();
    311 	IsSmall = false;
    312 	NormalMouseShape = MOUSE_NORMAL;
    313 }
    314 
    315 
    316 /*
    317 **	This array of structures is used to control the mouse animation
    318 **	sequences.
    319 */
    320 MouseClass::MouseStruct MouseClass::MouseControl[MOUSE_COUNT] = {
    321 	{0, 	1,		0,		86,	 0,	0},	//	MOUSE_NORMAL
    322 	{1, 	1,		0,		-1,	15,	0},	//	MOUSE_N
    323 	{2, 	1,		0,		-1,	29,	0},	//	MOUSE_NE
    324 	{3, 	1,		0,		-1,	29,	12},	//	MOUSE_E
    325 	{4,	1,		0,		-1,	29,	23},	//	MOUSE_SE
    326 	{5,	1,		0,		-1,	15,	23},	//	MOUSE_S
    327 	{6,	1,		0,		-1,	0, 	23},	//	MOUSE_SW
    328 	{7,	1,		0,		-1,	0, 	13},	//	MOUSE_W
    329 	{8,	1,		0,		-1,	0, 	0},	//	MOUSE_NW
    330 
    331 	{130, 1,		0,		-1,	15,	0},	//	MOUSE_NO_N
    332 	{131, 1,		0,		-1,	29,	0},	//	MOUSE_NO_NE
    333 	{132, 1,		0,		-1,	29,	12},	//	MOUSE_NO_E
    334 	{133,	1,		0,		-1,	29,	23},	//	MOUSE_NO_SE
    335 	{134,	1,		0,		-1,	15,	23},	//	MOUSE_NO_S
    336 	{135,	1,		0,		-1,	0, 	23},	//	MOUSE_NO_SW
    337 	{136,	1,		0,		-1,	0, 	13},	//	MOUSE_NO_W
    338 	{137,	1,		0,		-1,	0, 	0},	//	MOUSE_NO_NW
    339 
    340 	{11,	1,		0,		27,	15,	12},	//	MOUSE_NO_MOVE
    341 	{10,	1,		0,		26,	15,	12},	//	MOUSE_CAN_MOVE
    342 	{119,	3,		4,		148,	15,	12},	//	MOUSE_ENTER
    343 	{53,	9,		4,		-1,	15,	12},	//	MOUSE_DEPLOY
    344 	{12,	6,		4,		-1,	15,	12},	//	MOUSE_CAN_SELECT
    345 	{18,	8,		4,		140,	15,	12},	//	MOUSE_CAN_ATTACK
    346 	{62,	24,	2,		-1,	15,	12},	//	MOUSE_SELL_BACK
    347 	{154,	24,	2,		-1,	15,	12},	//	MOUSE_SELL_UNIT
    348 	{29,	24,	2,		-1,	15,	12},	//	MOUSE_REPAIR
    349 	{126,	1,		0,		-1,	15,	12},	//	MOUSE_NO_REPAIR
    350 	{125,	1,		0,		-1,	15,	12},	//	MOUSE_NO_SELL_BACK
    351 	{87,	1,		0,		151,	0, 	0},	//	MOUSE_RADAR_CURSOR
    352 	{103,	16,	2,		-1,	15,	12},	//	MOUSE_ION_CANNON
    353 	{96,	7,		4,		-1,	15,	12},	//	MOUSE_NUCLEAR_BOMB
    354 	{88,	8,		2,		-1,	15,	12},	//	MOUSE_AIR_STRIKE
    355 	{122,	3,		4,		127,	15,	12},	//	MOUSE_DEMOLITIONS
    356 	{153,	1,		0,		152,	15,	12},	//	MOUSE_AREA_GUARD
    357 };