MOUSE.CPP 21 KB

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