GAMEDLG.CPP 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  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: F:\projects\c&c\vcs\code\gamedlg.cpv 2.17 16 Oct 1995 16:52:02 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 : GAMEDLG.CPP *
  22. * *
  23. * Programmer : Maria del Mar McCready Legg, Joe L. Bostic *
  24. * *
  25. * Start Date : Jan 8, 1995 *
  26. * *
  27. * Last Update : Jan 18, 1995 [MML] *
  28. * *
  29. *---------------------------------------------------------------------------------------------*
  30. * Functions: *
  31. * OptionsClass::Process -- Handles all the options graphic interface. *
  32. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  33. #include "function.h"
  34. #include "gamedlg.h"
  35. #include "sounddlg.h"
  36. #include "visudlg.h"
  37. /***********************************************************************************************
  38. * OptionsClass::Process -- Handles all the options graphic interface. *
  39. * *
  40. * This routine is the main control for the visual representation of the options *
  41. * screen. It handles the visual overlay and the player input. *
  42. * *
  43. * INPUT: none *
  44. * OUTPUT: none *
  45. * WARNINGS: none *
  46. * HISTORY: *
  47. * 12/31/1994 MML : Created. *
  48. *=============================================================================================*/
  49. void GameControlsClass::Process(void)
  50. {
  51. int factor = (SeenBuff.Get_Width() == 320) ? 1 : 2;
  52. /*
  53. ** Dialog & button dimensions
  54. */
  55. int d_dialog_w = 232 * factor; // dialog width
  56. int d_dialog_h = 141 * factor; // dialog height
  57. int d_dialog_x = ((SeenBuff.Get_Width()- d_dialog_w) / 2); // dialog x-coord
  58. int d_dialog_y = ((SeenBuff.Get_Height() - d_dialog_h) / 2); // centered y-coord
  59. int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // center x-coord
  60. int d_top_margin= 30 * factor;
  61. int d_txt6_h = 7 * factor; // ht of 6-pt text
  62. int d_margin1 = 5 * factor; // large margin
  63. int d_margin2 = 2 * factor; // small margin
  64. int d_speed_w = d_dialog_w - (20 * factor);
  65. int d_speed_h = 6 * factor;
  66. int d_speed_x = d_dialog_x + (10 * factor);
  67. int d_speed_y = d_dialog_y + d_top_margin + d_margin1 + d_txt6_h;
  68. int d_scroll_w = d_dialog_w - (20 * factor);
  69. int d_scroll_h = 6 * factor;
  70. int d_scroll_x = d_dialog_x + (10 * factor);
  71. int d_scroll_y = d_speed_y + d_speed_h + d_txt6_h + (d_margin1 * 2) + d_txt6_h;
  72. int d_visual_w = d_dialog_w - (40 * factor);
  73. int d_visual_h = 9 * factor;
  74. int d_visual_x = d_dialog_x + (20 * factor);
  75. int d_visual_y = d_scroll_y + d_scroll_h + d_txt6_h + (d_margin1 * 2);
  76. int d_sound_w = d_dialog_w - (40 * factor);
  77. int d_sound_h = 9 * factor;
  78. int d_sound_x = d_dialog_x + (20 * factor);
  79. int d_sound_y = d_visual_y + d_visual_h + d_margin1;
  80. int d_ok_w = 20 * factor;
  81. int d_ok_h = 9 * factor;
  82. int d_ok_x = d_dialog_cx - (d_ok_w / 2);
  83. int d_ok_y = d_dialog_y + d_dialog_h - d_ok_h - d_margin1;
  84. /*
  85. ** Button Enumerations
  86. */
  87. enum {
  88. BUTTON_SPEED = 100,
  89. BUTTON_SCROLLRATE,
  90. BUTTON_VISUAL,
  91. BUTTON_SOUND,
  92. BUTTON_OK,
  93. BUTTON_COUNT,
  94. BUTTON_FIRST = BUTTON_SPEED,
  95. };
  96. /*
  97. ** Dialog variables
  98. */
  99. KeyNumType input;
  100. int gamespeed = Options.GameSpeed;
  101. int scrollrate = Options.ScrollRate;
  102. int selection;
  103. bool pressed = false;
  104. int curbutton = 0;
  105. TextButtonClass *buttons[BUTTON_COUNT - BUTTON_FIRST];
  106. TextPrintType style;
  107. /*
  108. ** Buttons
  109. */
  110. GadgetClass *commands; // button list
  111. SliderClass gspeed_btn(BUTTON_SPEED, d_speed_x, d_speed_y, d_speed_w, d_speed_h);
  112. SliderClass scrate_btn(BUTTON_SCROLLRATE, d_scroll_x, d_scroll_y, d_scroll_w, d_scroll_h);
  113. TextButtonClass visual_btn(BUTTON_VISUAL, TXT_VISUAL_CONTROLS,
  114. TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
  115. d_visual_x, d_visual_y, d_visual_w, d_visual_h);
  116. TextButtonClass sound_btn(BUTTON_SOUND, TXT_SOUND_CONTROLS,
  117. TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
  118. d_sound_x, d_sound_y, d_sound_w, d_sound_h);
  119. TextButtonClass okbtn(BUTTON_OK, TXT_OPTIONS_MENU,
  120. TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
  121. d_ok_x, d_ok_y);
  122. okbtn.X = (SeenBuff.Get_Width()-okbtn.Width)/2;
  123. /*
  124. ** Various Inits.
  125. */
  126. Set_Logic_Page(SeenBuff);
  127. /*
  128. ** Build button list
  129. */
  130. commands = &okbtn;
  131. gspeed_btn.Add_Tail(*commands);
  132. scrate_btn.Add_Tail(*commands);
  133. visual_btn.Add_Tail(*commands);
  134. sound_btn.Add_Tail(*commands);
  135. /*
  136. ** Init button states
  137. ** For sliders, the thumb ranges from 0 - (maxval-1), so to convert the
  138. ** thumb value to a real-world value:
  139. ** val = (MAX - slider.Get_Value()) - 1;
  140. ** and,
  141. ** slider.Set_Value(-(val + 1 - MAX));
  142. */
  143. gspeed_btn.Set_Maximum(OptionsClass::MAX_SPEED_SETTING); // varies from 0 - 7
  144. gspeed_btn.Set_Thumb_Size(1);
  145. gspeed_btn.Set_Value((OptionsClass::MAX_SPEED_SETTING-1) - gamespeed);
  146. scrate_btn.Set_Maximum(OptionsClass::MAX_SCROLL_SETTING); // varies from 0 - 7
  147. scrate_btn.Set_Thumb_Size(1);
  148. scrate_btn.Set_Value((OptionsClass::MAX_SCROLL_SETTING-1) - scrollrate);
  149. /*
  150. ** Fill array of button ptrs.
  151. */
  152. buttons[0] = NULL;
  153. buttons[1] = NULL;
  154. buttons[2] = &visual_btn;
  155. buttons[3] = &sound_btn;
  156. buttons[4] = &okbtn;
  157. /*
  158. ** Processing loop.
  159. */
  160. bool process = true;
  161. bool display = true;
  162. bool refresh = true;
  163. while (process) {
  164. /*
  165. ** Invoke game callback.
  166. */
  167. if (GameToPlay == GAME_NORMAL) {
  168. Call_Back();
  169. } else {
  170. if (Main_Loop()) {
  171. process = false;
  172. }
  173. }
  174. /*
  175. ** If we have just received input focus again after running in the background then
  176. ** we need to redraw.
  177. */
  178. if (AllSurfaces.SurfacesRestored){
  179. AllSurfaces.SurfacesRestored=FALSE;
  180. display=TRUE;
  181. }
  182. /*
  183. ** Refresh display if needed.
  184. */
  185. if (display) {
  186. Hide_Mouse();
  187. Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h);
  188. Draw_Caption(TXT_GAME_CONTROLS, d_dialog_x, d_dialog_y, d_dialog_w);
  189. Show_Mouse();
  190. display = false;
  191. refresh = true;
  192. }
  193. if (refresh) {
  194. Hide_Mouse();
  195. /*
  196. ** Label the game speed slider
  197. */
  198. style = TPF_6PT_GRAD | TPF_NOSHADOW | TPF_USE_GRAD_PAL;
  199. if (curbutton == (BUTTON_SPEED - BUTTON_FIRST)) {
  200. style = (TextPrintType)(style | TPF_BRIGHT_COLOR);
  201. }
  202. Fancy_Text_Print(TXT_SPEED, d_speed_x, d_speed_y - d_txt6_h, CC_GREEN, TBLACK, style);
  203. Fancy_Text_Print(TXT_SLOWER, d_speed_x, d_speed_y + d_speed_h + 1, CC_GREEN, TBLACK, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW);
  204. Fancy_Text_Print(TXT_FASTER, d_speed_x + d_speed_w, d_speed_y + d_speed_h + 1, CC_GREEN, TBLACK, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW|TPF_RIGHT);
  205. /*
  206. ** Label the scroll rate slider
  207. */
  208. style = TPF_6PT_GRAD | TPF_NOSHADOW | TPF_USE_GRAD_PAL;
  209. if (curbutton == (BUTTON_SCROLLRATE - BUTTON_FIRST)) {
  210. style = (TextPrintType)(style | TPF_BRIGHT_COLOR);
  211. }
  212. Fancy_Text_Print(TXT_SCROLLRATE, d_scroll_x, d_scroll_y - d_txt6_h, CC_GREEN, TBLACK, style);
  213. Fancy_Text_Print (TXT_SLOWER, d_scroll_x, d_scroll_y + d_scroll_h + 1, CC_GREEN, TBLACK, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW);
  214. Fancy_Text_Print (TXT_FASTER, d_scroll_x + d_scroll_w, d_scroll_y + d_scroll_h + 1, CC_GREEN, TBLACK, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_NOSHADOW|TPF_RIGHT);
  215. commands->Draw_All();
  216. Show_Mouse();
  217. refresh = false;
  218. }
  219. /*
  220. ** Get user input.
  221. */
  222. input = commands->Input();
  223. /*
  224. ** Process input.
  225. */
  226. switch (input) {
  227. case (BUTTON_SPEED | KN_BUTTON):
  228. curbutton = (BUTTON_SPEED - BUTTON_FIRST);
  229. refresh = true;
  230. break;
  231. case (BUTTON_SCROLLRATE | KN_BUTTON):
  232. curbutton = (BUTTON_SCROLLRATE - BUTTON_FIRST);
  233. refresh = true;
  234. break;
  235. case (BUTTON_VISUAL | KN_BUTTON):
  236. selection = BUTTON_VISUAL;
  237. pressed = true;
  238. break;
  239. case (BUTTON_SOUND | KN_BUTTON):
  240. selection = BUTTON_SOUND;
  241. pressed = true;
  242. break;
  243. case (BUTTON_OK | KN_BUTTON):
  244. selection = BUTTON_OK;
  245. pressed = true;
  246. break;
  247. case (KN_ESC):
  248. process = false;
  249. break;
  250. case (KN_LEFT):
  251. if (curbutton == (BUTTON_SPEED - BUTTON_FIRST) ) {
  252. gspeed_btn.Bump(1);
  253. } else
  254. if (curbutton == (BUTTON_SCROLLRATE - BUTTON_FIRST) ) {
  255. scrate_btn.Bump(1);
  256. }
  257. break;
  258. case (KN_RIGHT):
  259. if (curbutton == (BUTTON_SPEED - BUTTON_FIRST) ) {
  260. gspeed_btn.Bump(0);
  261. } else
  262. if (curbutton == (BUTTON_SCROLLRATE - BUTTON_FIRST) ) {
  263. scrate_btn.Bump(0);
  264. }
  265. break;
  266. case (KN_UP):
  267. if (buttons[curbutton]) {
  268. buttons[curbutton]->Turn_Off();
  269. buttons[curbutton]->Flag_To_Redraw();
  270. }
  271. curbutton--;
  272. if (curbutton < 0) {
  273. curbutton = (BUTTON_COUNT - BUTTON_FIRST - 1);
  274. }
  275. if (buttons[curbutton]) {
  276. buttons[curbutton]->Turn_On();
  277. buttons[curbutton]->Flag_To_Redraw();
  278. }
  279. refresh = true;
  280. break;
  281. case (KN_DOWN):
  282. if (buttons[curbutton]) {
  283. buttons[curbutton]->Turn_Off();
  284. buttons[curbutton]->Flag_To_Redraw();
  285. }
  286. curbutton++;
  287. if (curbutton > (BUTTON_COUNT - BUTTON_FIRST - 1) ) {
  288. curbutton = 0;
  289. }
  290. if (buttons[curbutton]) {
  291. buttons[curbutton]->Turn_On();
  292. buttons[curbutton]->Flag_To_Redraw();
  293. }
  294. refresh = true;
  295. break;
  296. case (KN_RETURN):
  297. selection = curbutton + BUTTON_FIRST;
  298. pressed = true;
  299. break;
  300. default:
  301. break;
  302. }
  303. /*
  304. ** Perform some action. Either to exit the dialog or bring up another.
  305. */
  306. if (pressed) {
  307. /*
  308. ** Record the new options slider settings.
  309. ** The GameSpeed data member MUST NOT BE SET HERE!!! It will cause multiplayer
  310. ** games to go out of sync. It's set by virtue of the event being executed.
  311. */
  312. if (gamespeed != ((OptionsClass::MAX_SPEED_SETTING-1) - gspeed_btn.Get_Value()) ) {
  313. gamespeed = (OptionsClass::MAX_SPEED_SETTING-1) - gspeed_btn.Get_Value();
  314. OutList.Add(EventClass(EventClass::GAMESPEED, gamespeed));
  315. }
  316. if (scrollrate != ((OptionsClass::MAX_SCROLL_SETTING-1) - scrate_btn.Get_Value()) ) {
  317. scrollrate = (OptionsClass::MAX_SCROLL_SETTING-1) - scrate_btn.Get_Value();
  318. Options.ScrollRate = scrollrate;
  319. }
  320. process = false;
  321. /*
  322. ** Save the settings in such a way that the GameSpeed is only set during
  323. ** the save process; restore it when we're done, so multiplayer games don't
  324. ** go out of sync.
  325. */
  326. int old = Options.GameSpeed; // save orig value
  327. Options.GameSpeed = gamespeed;
  328. Options.Save_Settings(); // save new value
  329. Options.GameSpeed = old; // restore old value
  330. /*
  331. ** Possibly launch into another dialog if so directed.
  332. */
  333. switch (selection) {
  334. case (BUTTON_VISUAL):
  335. VisualControlsClass().Process();
  336. process = true;
  337. display = true;
  338. refresh = true;
  339. break;
  340. case (BUTTON_SOUND):
  341. if (!SoundType) {
  342. CCMessageBox().Process(Text_String(TXT_NO_SOUND_CARD));
  343. process = true;
  344. display = true;
  345. refresh = true;
  346. } else {
  347. SoundControlsClass().Process();
  348. }
  349. break;
  350. case (BUTTON_OK):
  351. break;
  352. }
  353. pressed = false;
  354. }
  355. }
  356. }