GSCREEN.CPP 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  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: /CounterStrike/GSCREEN.CPP 1 3/03/97 10:24a 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 : GSCREEN.CPP *
  22. * *
  23. * Programmer : Joe L. Bostic *
  24. * *
  25. * Start Date : 12/15/94 *
  26. * *
  27. * Last Update : January 19, 1995 [JLB] *
  28. * *
  29. *---------------------------------------------------------------------------------------------*
  30. * Functions: *
  31. * GScreenClass::Add_A_Button -- Add a gadget to the game input system. *
  32. * GScreenClass::Blit_Display -- Redraw the display from the hidpage to the seenpage. *
  33. * GScreenClass::Flag_To_Redraw -- Flags the display to be redrawn. *
  34. * GScreenClass::GScreenClass -- Default constructor for GScreenClass. *
  35. * GScreenClass::Init -- Init's the entire display hierarchy by calling all Init routines. *
  36. * GScreenClass::Init_Clear -- Sets the map to a known state. *
  37. * GScreenClass::Init_IO -- Initializes the Button list ('Buttons'). *
  38. * GScreenClass::Init_Theater -- Performs theater-specific initializations. *
  39. * GScreenClass::Input -- Fetches input and processes gadgets. *
  40. * GScreenClass::One_Time -- Handles one time class setups. *
  41. * GScreenClass::Remove_A_Button -- Removes a gadget from the game input system. *
  42. * GScreenClass::Render -- General drawing dispatcher an display update function. *
  43. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  44. #include "function.h"
  45. GadgetClass * GScreenClass::Buttons = 0;
  46. GraphicBufferClass * GScreenClass::ShadowPage = 0;
  47. /***********************************************************************************************
  48. * GScreenClass::GScreenClass -- Default constructor for GScreenClass. *
  49. * *
  50. * This constructor merely sets the display system, so that it will redraw the first time *
  51. * the render function is called. *
  52. * *
  53. * INPUT: none *
  54. * *
  55. * OUTPUT: none *
  56. * *
  57. * WARNINGS: none *
  58. * *
  59. * HISTORY: *
  60. * 12/15/1994 JLB : Created. *
  61. *=============================================================================================*/
  62. GScreenClass::GScreenClass(void)
  63. {
  64. IsToUpdate = true;
  65. IsToRedraw = true;
  66. }
  67. /***********************************************************************************************
  68. * GScreenClass::One_Time -- Handles one time class setups. *
  69. * *
  70. * This routine (and all those that overload it) must perform truly one-time initialization. *
  71. * Such init's would normally be done in the constructor, but other aspects of the game may *
  72. * not have been initialized at the time the constructors are called (such as the file system, *
  73. * the display, or other WWLIB subsystems), so many initializations should be deferred to the *
  74. * One_Time init's. *
  75. * *
  76. * Any variables set in this routine should be declared as static, so they won't be modified *
  77. * by the load/save process. Non-static variables will be over-written by a loaded game. *
  78. * *
  79. * This function allocates the shadow buffer that is used for quick screen updates. If *
  80. * there were any data files to load, they would be loaded at this time as well. *
  81. * *
  82. * INPUT: none *
  83. * *
  84. * OUTPUT: none *
  85. * *
  86. * WARNINGS: Call this routine only ONCE at the beginning of the game. *
  87. * *
  88. * HISTORY: *
  89. * 12/15/1994 JLB : Created. *
  90. *=============================================================================================*/
  91. void GScreenClass::One_Time(void)
  92. {
  93. /*
  94. ** Allocate the screen shadow page. This page is used to reduce access to the
  95. ** actual screen memory. It contains a duplicate of what the SEENPAGE is.
  96. */
  97. Buttons = 0;
  98. ShadowPage = new GraphicBufferClass(320, 200);
  99. if (ShadowPage) {
  100. ShadowPage->Clear();
  101. HidPage.Clear();
  102. }
  103. }
  104. /***********************************************************************************************
  105. * GScreenClass::Init -- Init's the entire display hierarchy by calling all Init routines. *
  106. * *
  107. * This routine shouldn't be overloaded. It's the main map initialization routine, and will *
  108. * perform a complete map initialization, from mixfiles to clearing the buffers. Calling this *
  109. * routine results in calling every initialization routine in the entire map hierarchy. *
  110. * *
  111. * INPUT: *
  112. * theater theater to initialize to *
  113. * *
  114. * OUTPUT: *
  115. * none. *
  116. * *
  117. * WARNINGS: *
  118. * none. *
  119. * *
  120. * HISTORY: *
  121. * 12/28/1994 BR : Created. *
  122. *=============================================================================================*/
  123. void GScreenClass::Init(TheaterType theater)
  124. {
  125. Init_Clear();
  126. Init_IO();
  127. Init_Theater(theater);
  128. }
  129. /***********************************************************************************************
  130. * GScreenClass::Init_Clear -- Sets the map to a known state. *
  131. * *
  132. * This routine (and those that overload it) clears any buffers and variables to a known *
  133. * state. It assumes that all buffers are allocated & valid. The map should be displayable *
  134. * after calling this function, and should draw basically an empty display. *
  135. * *
  136. * INPUT: *
  137. * none. *
  138. * *
  139. * OUTPUT: *
  140. * none. *
  141. * *
  142. * WARNINGS: *
  143. * none. *
  144. * *
  145. * HISTORY: *
  146. * 12/28/1994 BR : Created. *
  147. *=============================================================================================*/
  148. void GScreenClass::Init_Clear(void)
  149. {
  150. /*
  151. ** Clear the ShadowPage & HidPage to force a complete shadow blit.
  152. */
  153. if (ShadowPage) {
  154. ShadowPage->Clear();
  155. HidPage.Clear();
  156. }
  157. IsToRedraw = true;
  158. }
  159. /***********************************************************************************************
  160. * GScreenClass::Init_Theater -- Performs theater-specific initializations. *
  161. * *
  162. * This routine (and those that overload it) performs any theater-specific initializations *
  163. * needed. This will include setting the palette, setting up remap tables, etc. This routine *
  164. * only needs to be called when the theater has changed. *
  165. * *
  166. * INPUT: *
  167. * none. *
  168. * *
  169. * OUTPUT: *
  170. * none. *
  171. * *
  172. * WARNINGS: *
  173. * none. *
  174. * *
  175. * HISTORY: *
  176. * 12/28/1994 BR : Created. *
  177. *=============================================================================================*/
  178. void GScreenClass::Init_Theater(TheaterType )
  179. {
  180. }
  181. /***********************************************************************************************
  182. * GScreenClass::Init_IO -- Initializes the Button list ('Buttons'). *
  183. * *
  184. * INPUT: *
  185. * none. *
  186. * *
  187. * OUTPUT: *
  188. * none. *
  189. * *
  190. * WARNINGS: *
  191. * none. *
  192. * *
  193. * HISTORY: *
  194. * 12/28/1994 BR : Created. *
  195. *=============================================================================================*/
  196. void GScreenClass::Init_IO(void)
  197. {
  198. /*
  199. ** Reset the button list. This means that any other elements of the map that need
  200. ** buttons must attach them after this routine is called!
  201. */
  202. Buttons = 0;
  203. }
  204. /***********************************************************************************************
  205. * GScreenClass::Flag_To_Redraw -- Flags the display to be redrawn. *
  206. * *
  207. * This function is used to flag the display system whether any rendering is needed. The *
  208. * parameter tells the system either to redraw EVERYTHING, or just that something somewhere *
  209. * has changed and the individual Draw_It functions must be called. When a sub system *
  210. * determines that it needs to render something local to itself, it would call this routine *
  211. * with a false parameter. If the entire screen gets trashed or needs to be rebuilt, then *
  212. * this routine will be called with a true parameter. *
  213. * *
  214. * INPUT: complete -- bool; Should the ENTIRE screen be redrawn? *
  215. * *
  216. * OUTPUT: none *
  217. * *
  218. * WARNINGS: This doesn't actually draw the screen, it merely sets flags so that when the *
  219. * Render() function is called, the appropriate drawing steps will be performed. *
  220. * *
  221. * HISTORY: *
  222. * 12/15/1994 JLB : Created. *
  223. *=============================================================================================*/
  224. void GScreenClass::Flag_To_Redraw(bool complete)
  225. {
  226. IsToUpdate = true;
  227. if (complete) {
  228. IsToRedraw = true;
  229. }
  230. }
  231. /***********************************************************************************************
  232. * GScreenClass::Input -- Fetches input and processes gadgets. *
  233. * *
  234. * This routine will fetch the keyboard/mouse input and dispatch this through the gadget *
  235. * system. *
  236. * *
  237. * INPUT: key -- Reference to the key code (for future examination). *
  238. * *
  239. * x,y -- Reference to mouse coordinates (for future examination). *
  240. * *
  241. * OUTPUT: none *
  242. * *
  243. * WARNINGS: none *
  244. * *
  245. * HISTORY: *
  246. * 01/19/1995 JLB : Created. *
  247. *=============================================================================================*/
  248. void GScreenClass::Input(KeyNumType & key, int & x, int & y)
  249. {
  250. key = Keyboard->Check();
  251. x = Keyboard->Mouse_X();
  252. y = Keyboard->Mouse_Y();
  253. if (Buttons != NULL) {
  254. /*
  255. ** If any buttons need redrawing, they will do so in the Input routine, and
  256. ** they should draw themselves to the HidPage. So, flag ourselves for a Blit
  257. ** to show the newly drawn buttons.
  258. */
  259. if (Buttons->Is_List_To_Redraw()) {
  260. Flag_To_Redraw(false);
  261. }
  262. #ifdef WIN32
  263. GraphicViewPortClass * oldpage= Set_Logic_Page(HidPage);
  264. #else
  265. GraphicBufferClass * oldpage= Set_Logic_Page(HidPage);
  266. #endif
  267. key = Buttons->Input();
  268. Set_Logic_Page(oldpage);
  269. } else {
  270. if (key != 0) {
  271. key = Keyboard->Get();
  272. }
  273. }
  274. AI(key, x, y);
  275. }
  276. /***********************************************************************************************
  277. * GScreenClass::Add_A_Button -- Add a gadget to the game input system. *
  278. * *
  279. * This will add a gadget to the game input system. The gadget will be processed in *
  280. * subsequent calls to the GScreenClass::Input() function. *
  281. * *
  282. * INPUT: gadget -- Reference to the gadget that will be added to the input system. *
  283. * *
  284. * OUTPUT: none *
  285. * *
  286. * WARNINGS: none *
  287. * *
  288. * HISTORY: *
  289. * 01/19/1995 JLB : Created. *
  290. *=============================================================================================*/
  291. void GScreenClass::Add_A_Button(GadgetClass & gadget)
  292. {
  293. /*
  294. ** If this gadget is already in the list, remove it before adding it in:
  295. ** - If 1st gadget in list, use Remove_A_Button to remove it, to reset the
  296. ** value of 'Buttons' appropriately
  297. ** - Otherwise, just call the Remove function for that gadget to remove it
  298. ** from any list it may be in
  299. */
  300. if (Buttons == &gadget) {
  301. Remove_A_Button(gadget);
  302. } else {
  303. gadget.Remove();
  304. }
  305. /*
  306. ** Now add the gadget to our list:
  307. ** - If there are not buttons, start the list with this one
  308. ** - Otherwise, add it to the tail of the existing list
  309. */
  310. if (Buttons) {
  311. gadget.Add_Tail(*Buttons);
  312. } else {
  313. Buttons = &gadget;
  314. }
  315. }
  316. /***********************************************************************************************
  317. * GScreenClass::Remove_A_Button -- Removes a gadget from the game input system. *
  318. * *
  319. * INPUT: gadget -- Reference to the gadget that will be removed from the input system. *
  320. * *
  321. * OUTPUT: none *
  322. * *
  323. * WARNINGS: 'gadget' MUST be already a part of 'Buttons', or the new value of 'Buttons' *
  324. * will be invalid! *
  325. * *
  326. * HISTORY: *
  327. * 01/19/1995 JLB : Created. *
  328. *=============================================================================================*/
  329. void GScreenClass::Remove_A_Button(GadgetClass & gadget)
  330. {
  331. Buttons = gadget.Remove();
  332. }
  333. /***********************************************************************************************
  334. * GScreenClass::Render -- General drawing dispatcher an display update function. *
  335. * *
  336. * This routine should be called in the main game loop (once every game frame). It will *
  337. * call the Draw_It() function if necessary. All rendering is performed to the LogicPage *
  338. * which is set to the HIDPAGE. After rendering has been performed, the HIDPAGE is *
  339. * copied to the visible page. *
  340. * *
  341. * INPUT: none *
  342. * *
  343. * OUTPUT: none *
  344. * *
  345. * WARNINGS: This actually updates the graphic display. As a result it can take quite a *
  346. * while to perform. *
  347. * *
  348. * HISTORY: *
  349. * 12/15/1994 JLB : Created. *
  350. *=============================================================================================*/
  351. void GScreenClass::Render(void)
  352. {
  353. //This is unnessasary surely? ST - 10/16/96 2:30PM
  354. //if (Buttons && Buttons->Is_List_To_Redraw()) {
  355. // IsToRedraw = true;
  356. //}
  357. if (IsToUpdate || IsToRedraw) {
  358. BStart(BENCH_GSCREEN_RENDER);
  359. #ifdef WIN32
  360. GraphicViewPortClass * oldpage= Set_Logic_Page(HidPage);
  361. #else
  362. GraphicBufferClass * oldpage= Set_Logic_Page(HidPage);
  363. if (IsToRedraw) {
  364. Hide_Mouse();
  365. SeenPage.To_Buffer(0, 0, 320, 200, ShadowPage);
  366. Show_Mouse();
  367. }
  368. #endif
  369. Draw_It(IsToRedraw);
  370. if (Buttons) Buttons->Draw_All(false);
  371. #ifdef SCENARIO_EDITOR
  372. /*
  373. ** Draw the Editor's buttons
  374. */
  375. if (Debug_Map) {
  376. if (Buttons) {
  377. Buttons->Draw_All();
  378. }
  379. }
  380. #endif
  381. /*
  382. ** Draw the multiplayer message system to the Hidpage at this point.
  383. ** This way, they'll Blit along with the rest of the map.
  384. */
  385. if (Session.Messages.Num_Messages() > 0) {
  386. Session.Messages.Set_Width(
  387. Lepton_To_Cell(Map.TacLeptonWidth) * ICON_PIXEL_W);
  388. }
  389. Session.Messages.Draw();
  390. //Blit_Display(); // 5/19/20 SKY - Skip copying to scene page, we can get the data directly from hidden page
  391. IsToUpdate = false;
  392. IsToRedraw = false;
  393. BEnd(BENCH_GSCREEN_RENDER);
  394. Set_Logic_Page(oldpage);
  395. }
  396. }
  397. /***********************************************************************************************
  398. * GScreenClass::Blit_Display -- Redraw the display from the hidpage to the seenpage. *
  399. * *
  400. * This routine is used to copy the correct display from the HIDPAGE *
  401. * to the SEENPAGE. *
  402. * *
  403. * INPUT: none *
  404. * *
  405. * OUTPUT: none *
  406. * *
  407. * WARNINGS: none *
  408. * *
  409. * HISTORY: *
  410. * 02/14/1994 JLB : Created. *
  411. * 05/01/1994 JLB : Converted to member function. *
  412. *=============================================================================================*/
  413. extern "C" {
  414. void ModeX_Blit (GraphicBufferClass * source);
  415. }
  416. void GScreenClass::Blit_Display(void)
  417. {
  418. BStart(BENCH_BLIT_DISPLAY);
  419. #ifdef WIN32
  420. if (SeenBuff.Get_Width()!=320) {
  421. WWMouse->Draw_Mouse(&HidPage);
  422. HidPage.Blit(SeenBuff , 0 , 0 , 0 , 0 , HidPage.Get_Width() , HidPage.Get_Height() , (BOOL) FALSE );
  423. WWMouse->Erase_Mouse(&HidPage, FALSE);
  424. } else {
  425. //PG ModeX_Blit(&HiddenPage);
  426. }
  427. #else
  428. Shadow_Blit(0, 0, 320, 200, HidPage, SeenPage, ShadowPage->Get_Buffer());
  429. #endif
  430. BEnd(BENCH_BLIT_DISPLAY);
  431. }