MOUSE.CPP 19 KB

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