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