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