MOUSE.CPP 19 KB

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