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 };