HELP.CPP 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  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/HELP.CPP 1 3/03/97 10:24a 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 : HELP.CPP *
  26. * *
  27. * Programmer : Joe L. Bostic *
  28. * *
  29. * Start Date : 11/18/94 *
  30. * *
  31. * Last Update : September 22, 1995 [JLB] *
  32. * *
  33. *---------------------------------------------------------------------------------------------*
  34. * Functions: *
  35. * HelpClass::Draw_Help -- Display the help message (if necessary). *
  36. * HelpClass::HelpClass -- Default constructor for the help processor. *
  37. * HelpClass::Help_AI -- Handles the help text logic. *
  38. * HelpClass::Help_Text -- Assigns text as the current help text. *
  39. * HelpClass::Init_Clear -- Sets help system to a known state. *
  40. * HelpClass::Overlap_List -- Returns with offset list for cells under help text. *
  41. * HelpClass::Scroll_Map -- Makes sure scrolling doesn't leave text shards. *
  42. * HelpClass::Set_Cost -- Initiates the second line of help text showing item cost. *
  43. * HelpClass::Set_Tactical_Position -- Sets the position of the tactical map. *
  44. * HelpClass::Set_Tactical_Position -- Sets the tactical map position. *
  45. * HelpClass::Set_Tactical_Position -- Sets the tactical map position. *
  46. * HelpClass::Set_Text -- Determines the overlap list and draw coordinates. *
  47. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  48. #include "function.h"
  49. /*
  50. ** This is the holding buffer for the text overlap list. This buffer must be in the near
  51. ** data segment. It will be filled in by the Set_Text() function.
  52. */
  53. short const HelpClass::OverlapList[60] = {
  54. REFRESH_EOL
  55. };
  56. char const * HelpClass::HelpText;
  57. /***********************************************************************************************
  58. * HelpClass::HelpClass -- Default constructor for the help processor. *
  59. * *
  60. * The help processor is initialized by this routine. It merely sets up the help engine *
  61. * to the default state. The default state will not display any help text. Call the *
  62. * Help_Text() function to enable help processing. *
  63. * *
  64. * INPUT: none *
  65. * *
  66. * OUTPUT: none *
  67. * *
  68. * WARNINGS: none *
  69. * *
  70. * HISTORY: *
  71. * 11/18/1994 JLB : Created. *
  72. *=============================================================================================*/
  73. HelpClass::HelpClass(void) :
  74. HelpX(0),
  75. HelpY(0),
  76. HelpWidth(0),
  77. IsRight(false),
  78. Cost(0),
  79. X(0),
  80. Y(0),
  81. DrawX(0),
  82. DrawY(0),
  83. Width(0),
  84. Text(TXT_NONE),
  85. Color(LTGREY),
  86. CountDownTimer(0)
  87. {
  88. }
  89. /***********************************************************************************************
  90. * HelpClass::Init_Clear -- Sets help system to a known state. *
  91. * *
  92. * INPUT: none *
  93. * *
  94. * OUTPUT: none *
  95. * *
  96. * WARNINGS: none *
  97. * *
  98. * HISTORY: *
  99. * 12/24/1994 JLB : Created. *
  100. *=============================================================================================*/
  101. void HelpClass::Init_Clear(void)
  102. {
  103. TabClass::Init_Clear();
  104. Set_Text(TXT_NONE);
  105. }
  106. /***********************************************************************************************
  107. * HelpClass::Overlap_List -- Returns with offset list for cells under help text. *
  108. * *
  109. * Use this routine to fetch an offset list for the cells under the text displayed. If *
  110. * there is no text displayed, then the list will consist of just the terminator code. *
  111. * *
  112. * INPUT: none *
  113. * *
  114. * OUTPUT: Returns with a pointer to the offset list for the help text overlap. The offset *
  115. * list is based on the tactical map upper left corner cell. *
  116. * *
  117. * WARNINGS: none *
  118. * *
  119. * HISTORY: *
  120. * 11/18/1994 JLB : Created. *
  121. *=============================================================================================*/
  122. short const * HelpClass::Overlap_List(void) const
  123. {
  124. if (Text == TXT_NONE || CountDownTimer) {
  125. ((short &)(OverlapList[0])) = REFRESH_EOL;
  126. }
  127. return(OverlapList);
  128. }
  129. /***********************************************************************************************
  130. * HelpClass::Help_AI -- Handles the help text logic. *
  131. * *
  132. * This routine handles tracking the mouse position to see if the mouse remains stationary *
  133. * for the required amount of time. If the time requirement has been met, then it flags *
  134. * the help system to display the help text the next time the Draw_Help() function is *
  135. * called. *
  136. * *
  137. * INPUT: key -- Keyboard input code. *
  138. * *
  139. * x,y -- Mouse coordinates. *
  140. * *
  141. * OUTPUT: none *
  142. * *
  143. * WARNINGS: This routine must be called once and only once per game frame (15 times per *
  144. * second). *
  145. * *
  146. * HISTORY: *
  147. * 11/18/1994 JLB : Created. *
  148. * 12/31/1994 JLB : Uses mouse coordinates as passed in. *
  149. *=============================================================================================*/
  150. void HelpClass::AI(KeyNumType &key, int x, int y)
  151. {
  152. if (!CountDownTimer && !IsRight && (x != X || y != Y)) {
  153. Help_Text(TXT_NONE);
  154. }
  155. /*
  156. ** Process the countdown timer only if it hasn't already expired and there is
  157. ** a real help text message to display.
  158. */
  159. if (CountDownTimer && !HelpText && Text != TXT_NONE) {
  160. /*
  161. ** If the mouse has moved, then reset the timer since a moving mouse is not
  162. ** supposed to bring up the help text.
  163. */
  164. if (!IsRight && (X != x || Y != y)) {
  165. X = x;
  166. Y = y;
  167. CountDownTimer = HELP_DELAY;
  168. Help_Text(TXT_NONE);
  169. } else {
  170. /*
  171. ** If the delay has expired, then the text must be drawn. Build the help text
  172. ** overlay list at this time. Better to do it now, when we KNOW it is needed, then
  173. ** to do it earlier when it might not be needed.
  174. */
  175. Set_Text(Text);
  176. }
  177. }
  178. TabClass::AI(key, x, y);
  179. }
  180. /***********************************************************************************************
  181. * HelpClass::Help_Text -- Assigns text as the current help text. *
  182. * *
  183. * Use this routine to change the help text that will pop up if the cursor isn't moved *
  184. * for the help delay duration. Call this routine as often as desired. *
  185. * *
  186. * INPUT: text -- The text number for the help text to use. *
  187. * *
  188. * OUTPUT: none *
  189. * *
  190. * WARNINGS: none *
  191. * *
  192. * HISTORY: *
  193. * 11/18/1994 JLB : Created. *
  194. *=============================================================================================*/
  195. void HelpClass::Help_Text(int text, int x, int y, int color, bool quick)
  196. {
  197. if (text != Text) {
  198. /*
  199. ** If there is an existing text message, then flag the map to redraw the underlying
  200. ** icons so that the text message is erased.
  201. */
  202. if (Text != TXT_NONE) {
  203. Refresh_Cells(Coord_Cell(TacticalCoord), &OverlapList[0]);
  204. }
  205. /*
  206. ** Record the position of the mouse. This recorded position will be used to determine
  207. ** if the mouse has moved. A moving mouse prevents the help text from popping up.
  208. */
  209. X = x;
  210. if (x == -1) X = Get_Mouse_X();
  211. Y = y;
  212. if (y == -1) Y = Get_Mouse_Y();
  213. IsRight = (y != -1) || (x != -1);
  214. if (quick) {
  215. CountDownTimer = 1;
  216. } else {
  217. CountDownTimer = HELP_DELAY;
  218. }
  219. /*
  220. ** All help text prints in the same color for E3
  221. */
  222. //Color = color;
  223. color = color;
  224. Color = HELP_TEXT_COLOR;
  225. Text = text;
  226. Cost = 0;
  227. }
  228. }
  229. /***********************************************************************************************
  230. * HelpClass::Draw_Help -- Display the help message (if necessary). *
  231. * *
  232. * This function will print the help text if it thinks it should. The timer and text *
  233. * message can control whether this occurs. If there is no help text or the countdown timer *
  234. * has not expired, then no text will be printed. *
  235. * *
  236. * INPUT: none *
  237. * *
  238. * OUTPUT: none *
  239. * *
  240. * WARNINGS: none *
  241. * *
  242. * HISTORY: *
  243. * 11/18/1994 JLB : Created. *
  244. *=============================================================================================*/
  245. void HelpClass::Draw_It(bool forced)
  246. {
  247. TabClass::Draw_It(forced);
  248. forced = false; // TCTCTCTC
  249. if (Text != TXT_NONE && (forced || !CountDownTimer)) {
  250. if (LogicPage->Lock()) {
  251. Plain_Text_Print(Text, DrawX, DrawY, Color, BLACK, TPF_MAP|TPF_NOSHADOW);
  252. LogicPage->Draw_Rect(DrawX-1, DrawY-1, DrawX+Width+1, DrawY+FontHeight, Color);
  253. if (Cost) {
  254. char buffer[15];
  255. sprintf(buffer, "$%d", Cost);
  256. int width = String_Pixel_Width(buffer);
  257. Plain_Text_Print(buffer, DrawX, DrawY+FontHeight, Color, BLACK, TPF_MAP|TPF_NOSHADOW);
  258. LogicPage->Draw_Rect(DrawX-1, DrawY+FontHeight, DrawX+width+1, DrawY+FontHeight+FontHeight-1, Color);
  259. LogicPage->Draw_Line(DrawX, DrawY+FontHeight, DrawX+min(width+1, Width)-1, DrawY+FontHeight, BLACK);
  260. }
  261. LogicPage->Unlock();
  262. }
  263. }
  264. }
  265. /***********************************************************************************************
  266. * HelpClass::Set_Text -- Determines the overlap list and draw coordinates. *
  267. * *
  268. * This routine is used to build the overlap list -- used for icon refreshing. It also *
  269. * determines if the text can fit on the screen and makes adjustments so that it will. *
  270. * *
  271. * INPUT: text -- The text number to set the help system to use. *
  272. * *
  273. * OUTPUT: none *
  274. * *
  275. * WARNINGS: none *
  276. * *
  277. * HISTORY: *
  278. * 11/18/1994 JLB : Created. *
  279. * 12/11/1994 JLB : Won't draw past tactical map edges. *
  280. *=============================================================================================*/
  281. void HelpClass::Set_Text(int text)
  282. {
  283. if (text != TXT_NONE) {
  284. Text = text;
  285. Plain_Text_Print(TXT_NONE, 0, 0, 0, 0, TPF_MAP|TPF_NOSHADOW);
  286. Width = String_Pixel_Width(Text_String(Text));
  287. if (IsRight) {
  288. DrawX = X - Width;
  289. DrawY = Y;
  290. } else {
  291. int right = TacPixelX + Lepton_To_Pixel(TacLeptonWidth) - 3*RESFACTOR;
  292. int bottom = TacPixelY + Lepton_To_Pixel(TacLeptonHeight) - 1*RESFACTOR;
  293. DrawX = X+X_OFFSET;
  294. DrawY = Y+Y_OFFSET;
  295. if (DrawX + Width > right) {
  296. DrawX -= (DrawX+Width) - right;
  297. }
  298. if (DrawY + 10*RESFACTOR > bottom) {
  299. DrawY -= (DrawY+10*RESFACTOR) - bottom;
  300. }
  301. if (DrawX < TacPixelX+1) DrawX = TacPixelX+1;
  302. if (DrawY < TacPixelY+1) DrawY = TacPixelY+1;
  303. }
  304. memcpy((void*)OverlapList, Text_Overlap_List(Text_String(Text), DrawX-1, DrawY), sizeof(OverlapList));
  305. *(short *)&OverlapList[ARRAY_SIZE(OverlapList)-1] = REFRESH_EOL;
  306. }
  307. }
  308. /***********************************************************************************************
  309. * HelpClass::Scroll_Map -- Makes sure scrolling doesn't leave text shards. *
  310. * *
  311. * This routine intercepts the map scrolling request and then makes sure that if, in fact, *
  312. * the map is going to scroll, then reset and erase the help text so that it doesn't *
  313. * mess up the display. *
  314. * *
  315. * INPUT: facing -- The direction to scroll (unused by this routine). *
  316. * *
  317. * really -- If the scroll is actually going to occur, rather than just be examined *
  318. * for legality, then this parameter will be true. If this parameter is *
  319. * true, then the help text is reset. *
  320. * *
  321. * OUTPUT: Returns if it can, or did, scroll in the requested direction. *
  322. * *
  323. * WARNINGS: none *
  324. * *
  325. * HISTORY: *
  326. * 12/15/1994 JLB : Created. *
  327. *=============================================================================================*/
  328. bool HelpClass::Scroll_Map(DirType facing, int & distance, bool really)
  329. {
  330. if (really) {
  331. Help_Text(TXT_NONE);
  332. }
  333. return(TabClass::Scroll_Map(facing, distance, really));
  334. }
  335. /***********************************************************************************************
  336. * HelpClass::Set_Cost -- Initiates the second line of help text showing item cost. *
  337. * *
  338. * Use this routine after the Help_Text() function to activate the second line. The second *
  339. * line displays a cost. Typically, this is used by the sidebar to display the cost of the *
  340. * specified item. *
  341. * *
  342. * INPUT: cost -- The cost to associate with this help text. If this value is zero, then *
  343. * no second line is displayed, so don't pass in zero. *
  344. * *
  345. * OUTPUT: none *
  346. * *
  347. * WARNINGS: none *
  348. * *
  349. * HISTORY: *
  350. * 01/09/1995 JLB : Created. *
  351. *=============================================================================================*/
  352. void HelpClass::Set_Cost(int cost)
  353. {
  354. Cost = cost;
  355. }
  356. /***********************************************************************************************
  357. * HelpClass::Set_Tactical_Position -- Sets the position of the tactical map. *
  358. * *
  359. * This routine will set the position of the tactical map. At this class level, it merely *
  360. * makes sure that the help text disappears when this happens. The lower level classes *
  361. * actually change the map's position. *
  362. * *
  363. * INPUT: coord -- The new coordinate to make the upper left corner of the visible display. *
  364. * *
  365. * OUTPUT: none *
  366. * *
  367. * WARNINGS: none *
  368. * *
  369. * HISTORY: *
  370. * 09/22/1995 JLB : Created. *
  371. *=============================================================================================*/
  372. void HelpClass::Set_Tactical_Position(COORDINATE coord)
  373. {
  374. if (TacticalCoord != coord) {
  375. Help_Text(TXT_NONE);
  376. }
  377. TabClass::Set_Tactical_Position(coord);
  378. }