GAMEDLG.CPP (15906B)
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: /CounterStrike/GAMEDLG.CPP 1 3/03/97 10:24a 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 #define GERMAN_OFFSET_Y 4 //VG 41 42 #ifdef WOLAPI_INTEGRATION 43 #include "WolStrng.h" 44 #include "WolapiOb.h" 45 extern WolapiObject* pWolapi; 46 bool WOL_Options_Dialog( WolapiObject* pWO, bool bCalledFromGame ); 47 #endif 48 49 50 /*********************************************************************************************** 51 * OptionsClass::Process -- Handles all the options graphic interface. * 52 * * 53 * This routine is the main control for the visual representation of the options * 54 * screen. It handles the visual overlay and the player input. * 55 * * 56 * INPUT: none * 57 * OUTPUT: none * 58 * WARNINGS: none * 59 * HISTORY: * 60 * 12/31/1994 MML : Created. * 61 *=============================================================================================*/ 62 void GameControlsClass::Process(void) 63 { 64 /* 65 ** Dialog & button dimensions 66 */ 67 int d_dialog_w = 232 * RESFACTOR; // dialog width 68 int d_dialog_h = 141 * RESFACTOR; // dialog height 69 int d_dialog_x = ((SeenBuff.Get_Width() - d_dialog_w) / 2); // dialog x-coord 70 int d_dialog_y = ((SeenBuff.Get_Height() - d_dialog_h) / 2); // centered y-coord 71 int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // center x-coord 72 int d_top_margin = 25 * RESFACTOR; 73 74 int d_txt6_h = (6 * RESFACTOR) + 1; // ht of 6-pt text 75 int d_margin1 = (5 * RESFACTOR); // large margin 76 int d_margin2 = (2 * RESFACTOR); // small margin 77 78 int d_speed_w = d_dialog_w - (34 * RESFACTOR); 79 int d_speed_h = 6 * RESFACTOR; 80 int d_speed_x = d_dialog_x + (17 * RESFACTOR); 81 #ifdef GERMAN 82 int d_speed_y = d_dialog_y + d_top_margin + d_margin1 + d_txt6_h - GERMAN_OFFSET_Y; 83 #else 84 int d_speed_y = d_dialog_y + d_top_margin + d_margin1 + d_txt6_h; 85 #endif 86 87 int d_scroll_w = d_dialog_w - (34 * RESFACTOR); 88 int d_scroll_h = 6 * RESFACTOR; 89 int d_scroll_x = d_dialog_x + (17 * RESFACTOR); 90 #ifdef GERMAN 91 int d_scroll_y = d_speed_y + d_speed_h + d_txt6_h + (d_margin1 * 2) + d_txt6_h - GERMAN_OFFSET_Y; 92 #else 93 int d_scroll_y = d_speed_y + d_speed_h + d_txt6_h + (d_margin1 * 2) + d_txt6_h; 94 #endif 95 96 int d_visual_w = d_dialog_w - (40 * RESFACTOR); 97 int d_visual_h = 9 * RESFACTOR; 98 int d_visual_x = d_dialog_x + (20 * RESFACTOR); 99 int d_visual_y = d_scroll_y + d_scroll_h + d_txt6_h + (d_margin1 * 2); 100 101 int d_sound_w = d_dialog_w - (40 * RESFACTOR); 102 int d_sound_h = (9 * RESFACTOR); 103 int d_sound_x = d_dialog_x + (20 * RESFACTOR); 104 int d_sound_y = d_visual_y + d_visual_h + d_margin1; 105 106 int d_ok_w = 20 * RESFACTOR; 107 int d_ok_h = 9 * RESFACTOR; 108 int d_ok_x = d_dialog_cx - (d_ok_w / 2); 109 int d_ok_y = d_dialog_y + d_dialog_h - d_ok_h - d_margin1 - (4 * RESFACTOR); 110 111 #ifdef WOLAPI_INTEGRATION 112 int d_wol_x = d_sound_x; 113 int d_wol_y = d_sound_y + d_sound_h + d_margin1; 114 int d_wol_w = d_sound_w; 115 int d_wol_h = d_sound_h; 116 117 bool bShowWolapi = ( pWolapi && !pWolapi->bConnectionDown ); 118 if( bShowWolapi ) 119 { 120 // Enlarge dialog and shift ok button down. 121 d_dialog_h += d_wol_h + d_margin1; 122 d_dialog_y = ((SeenBuff.Get_Height() - d_dialog_h) / 2); // centered y-coord 123 //d_ok_y += d_wol_h + d_margin1; 124 d_ok_y = d_dialog_y + d_dialog_h - d_ok_h - d_margin1 - (4 * RESFACTOR); 125 } 126 #endif 127 128 /* 129 ** Button Enumerations 130 */ 131 #ifdef WOLAPI_INTEGRATION 132 enum { 133 BUTTON_SPEED = 100, 134 BUTTON_SCROLLRATE, 135 BUTTON_VISUAL, 136 BUTTON_SOUND, 137 BUTTON_WOLAPI, 138 BUTTON_OK, 139 BUTTON_COUNT, 140 BUTTON_FIRST = BUTTON_SPEED, 141 }; 142 #else 143 enum { 144 BUTTON_SPEED = 100, 145 BUTTON_SCROLLRATE, 146 BUTTON_VISUAL, 147 BUTTON_SOUND, 148 BUTTON_OK, 149 BUTTON_COUNT, 150 BUTTON_FIRST = BUTTON_SPEED, 151 }; 152 #endif 153 154 /* 155 ** Dialog variables 156 */ 157 KeyNumType input; 158 159 int gamespeed = Options.GameSpeed; 160 int scrollrate = Options.ScrollRate; 161 int selection; 162 bool pressed = false; 163 int curbutton = 0; 164 TextButtonClass *buttons[BUTTON_COUNT - BUTTON_FIRST]; 165 TextPrintType style; 166 167 RemapControlType * scheme = GadgetClass::Get_Color_Scheme(); 168 169 /* 170 ** Buttons 171 */ 172 GadgetClass * commands; // button list 173 174 SliderClass gspeed_btn(BUTTON_SPEED, d_speed_x, d_speed_y, d_speed_w, d_speed_h, true); 175 SliderClass scrate_btn(BUTTON_SCROLLRATE, d_scroll_x, d_scroll_y, d_scroll_w, d_scroll_h, true); 176 TextButtonClass visual_btn(BUTTON_VISUAL, TXT_VISUAL_CONTROLS, TPF_BUTTON, d_visual_x, d_visual_y, d_visual_w, d_visual_h); 177 TextButtonClass sound_btn(BUTTON_SOUND, TXT_SOUND_CONTROLS, TPF_BUTTON, d_sound_x, d_sound_y, d_sound_w, d_sound_h); 178 TextButtonClass okbtn(BUTTON_OK, TXT_OPTIONS_MENU, TPF_BUTTON, d_ok_x, d_ok_y); 179 okbtn.X = (SeenBuff.Get_Width()-okbtn.Width)/2; 180 181 #ifdef WOLAPI_INTEGRATION 182 TextButtonClass wol_btn( BUTTON_WOLAPI, TXT_WOL_OPTTITLE, TPF_BUTTON, d_wol_x, d_wol_y, d_wol_w, d_wol_h ); 183 #endif 184 185 /* 186 ** Various Inits. 187 */ 188 Set_Logic_Page(SeenBuff); 189 190 /* 191 ** Build button list 192 */ 193 commands = &okbtn; 194 gspeed_btn.Add_Tail(*commands); 195 scrate_btn.Add_Tail(*commands); 196 visual_btn.Add_Tail(*commands); 197 sound_btn.Add_Tail(*commands); 198 #ifdef WOLAPI_INTEGRATION 199 if( bShowWolapi ) 200 wol_btn.Add_Tail(*commands); 201 #endif 202 /* 203 ** Init button states 204 ** For sliders, the thumb ranges from 0 - (maxval-1), so to convert the 205 ** thumb value to a real-world value: 206 ** val = (MAX - slider.Get_Value()) - 1; 207 ** and, 208 ** slider.Set_Value(-(val + 1 - MAX)); 209 */ 210 gspeed_btn.Set_Maximum(OptionsClass::MAX_SPEED_SETTING); // varies from 0 - 7 211 gspeed_btn.Set_Thumb_Size(1); 212 gspeed_btn.Set_Value((OptionsClass::MAX_SPEED_SETTING-1) - gamespeed); 213 214 scrate_btn.Set_Maximum(OptionsClass::MAX_SCROLL_SETTING); // varies from 0 - 7 215 scrate_btn.Set_Thumb_Size(1); 216 scrate_btn.Set_Value((OptionsClass::MAX_SCROLL_SETTING-1) - scrollrate); 217 218 /* 219 ** Fill array of button ptrs. 220 */ 221 buttons[0] = NULL; 222 buttons[1] = NULL; 223 buttons[2] = &visual_btn; 224 buttons[3] = &sound_btn; 225 #ifdef WOLAPI_INTEGRATION 226 buttons[4] = &wol_btn; 227 buttons[5] = &okbtn; 228 #else 229 buttons[4] = &okbtn; 230 #endif 231 /* 232 ** Processing loop. 233 */ 234 bool process = true; 235 bool display = true; 236 bool refresh = true; 237 while (process) { 238 239 /* 240 ** Invoke game callback. 241 */ 242 if (Session.Type == GAME_NORMAL || Session.Type == GAME_SKIRMISH) { 243 Call_Back(); 244 } else { 245 if (Main_Loop()) { 246 process = false; 247 } 248 } 249 250 #ifdef WIN32 251 /* 252 ** If we have just received input focus again after running in the background then 253 ** we need to redraw. 254 */ 255 if (AllSurfaces.SurfacesRestored) { 256 AllSurfaces.SurfacesRestored=FALSE; 257 display = true; 258 } 259 #endif 260 /* 261 ** Refresh display if needed. 262 */ 263 if (display) { 264 Hide_Mouse(); 265 266 Map.Flag_To_Redraw(true); 267 Map.Render(); 268 269 Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h); 270 Draw_Caption(TXT_GAME_CONTROLS, d_dialog_x, d_dialog_y, d_dialog_w); 271 Show_Mouse(); 272 display = false; 273 refresh = true; 274 } 275 276 if (refresh) { 277 Hide_Mouse(); 278 279 /* 280 ** Label the game speed slider 281 */ 282 style = TPF_TEXT; 283 if (curbutton == (BUTTON_SPEED - BUTTON_FIRST)) { 284 style = (TextPrintType)(style | TPF_BRIGHT_COLOR); 285 } 286 Fancy_Text_Print(TXT_SPEED, d_speed_x, d_speed_y - d_txt6_h, scheme, TBLACK, style); 287 288 Fancy_Text_Print(TXT_SLOWER, d_speed_x, d_speed_y + d_speed_h + (1 * RESFACTOR), scheme, TBLACK, TPF_TEXT); 289 Fancy_Text_Print(TXT_FASTER, d_speed_x + d_speed_w, d_speed_y + d_speed_h + (1 * RESFACTOR), scheme, TBLACK, TPF_TEXT|TPF_RIGHT); 290 291 /* 292 ** Label the scroll rate slider 293 */ 294 style = TPF_TEXT; 295 if (curbutton == (BUTTON_SCROLLRATE - BUTTON_FIRST)) { 296 style = (TextPrintType)(style | TPF_BRIGHT_COLOR); 297 } 298 Fancy_Text_Print(TXT_SCROLLRATE, d_scroll_x, d_scroll_y - d_txt6_h, scheme, TBLACK, style); 299 300 Fancy_Text_Print (TXT_SLOWER, d_scroll_x, d_scroll_y + d_scroll_h + (1 * RESFACTOR), scheme, TBLACK, TPF_TEXT); 301 Fancy_Text_Print (TXT_FASTER, d_scroll_x + d_scroll_w, d_scroll_y + d_scroll_h + (1 * RESFACTOR), scheme, TBLACK, TPF_TEXT|TPF_RIGHT); 302 303 commands->Draw_All(); 304 305 Show_Mouse(); 306 refresh = false; 307 } 308 309 /* 310 ** Get user input. 311 */ 312 input = commands->Input(); 313 314 /* 315 ** Process input. 316 */ 317 switch (input) { 318 case (BUTTON_SPEED | KN_BUTTON): 319 curbutton = (BUTTON_SPEED - BUTTON_FIRST); 320 refresh = true; 321 break; 322 323 case (BUTTON_SCROLLRATE | KN_BUTTON): 324 curbutton = (BUTTON_SCROLLRATE - BUTTON_FIRST); 325 refresh = true; 326 break; 327 328 case (BUTTON_VISUAL | KN_BUTTON): 329 selection = BUTTON_VISUAL; 330 pressed = true; 331 break; 332 333 case (BUTTON_SOUND | KN_BUTTON): 334 selection = BUTTON_SOUND; 335 pressed = true; 336 break; 337 338 case (BUTTON_OK | KN_BUTTON): 339 selection = BUTTON_OK; 340 pressed = true; 341 break; 342 343 #ifdef WOLAPI_INTEGRATION 344 case (BUTTON_WOLAPI | KN_BUTTON): 345 selection = BUTTON_WOLAPI; 346 pressed = true; 347 break; 348 #endif 349 350 case (KN_ESC): 351 process = false; 352 break; 353 354 case (KN_LEFT): 355 if (curbutton == (BUTTON_SPEED - BUTTON_FIRST) ) { 356 gspeed_btn.Bump(1); 357 } else 358 if (curbutton == (BUTTON_SCROLLRATE - BUTTON_FIRST) ) { 359 scrate_btn.Bump(1); 360 } 361 break; 362 363 case (KN_RIGHT): 364 if (curbutton == (BUTTON_SPEED - BUTTON_FIRST) ) { 365 gspeed_btn.Bump(0); 366 } else 367 if (curbutton == (BUTTON_SCROLLRATE - BUTTON_FIRST) ) { 368 scrate_btn.Bump(0); 369 } 370 break; 371 372 case (KN_UP): 373 if (buttons[curbutton]) { 374 buttons[curbutton]->Turn_Off(); 375 buttons[curbutton]->Flag_To_Redraw(); 376 } 377 378 curbutton--; 379 #ifdef WOLAPI_INTEGRATION 380 if( !bShowWolapi ) 381 { 382 if( curbutton == BUTTON_WOLAPI - BUTTON_FIRST ) 383 curbutton--; // Skip over missing button. 384 } 385 #endif 386 if (curbutton < 0) { 387 curbutton = (BUTTON_COUNT - BUTTON_FIRST - 1); 388 } 389 390 if (buttons[curbutton]) { 391 buttons[curbutton]->Turn_On(); 392 buttons[curbutton]->Flag_To_Redraw(); 393 } 394 refresh = true; 395 break; 396 397 case (KN_DOWN): 398 if (buttons[curbutton]) { 399 buttons[curbutton]->Turn_Off(); 400 buttons[curbutton]->Flag_To_Redraw(); 401 } 402 403 curbutton++; 404 #ifdef WOLAPI_INTEGRATION 405 if( !bShowWolapi ) 406 { 407 if( curbutton == BUTTON_WOLAPI - BUTTON_FIRST ) 408 curbutton++; // Skip over missing button. 409 } 410 #endif 411 if (curbutton > (BUTTON_COUNT - BUTTON_FIRST - 1) ) { 412 curbutton = 0; 413 } 414 415 if (buttons[curbutton]) { 416 buttons[curbutton]->Turn_On(); 417 buttons[curbutton]->Flag_To_Redraw(); 418 } 419 refresh = true; 420 break; 421 422 case (KN_RETURN): 423 selection = curbutton + BUTTON_FIRST; 424 pressed = true; 425 break; 426 427 default: 428 break; 429 } 430 431 /* 432 ** Perform some action. Either to exit the dialog or bring up another. 433 */ 434 if (pressed) { 435 436 /* 437 ** Record the new options slider settings. 438 ** The GameSpeed data member MUST NOT BE SET HERE! It will cause multiplayer 439 ** games to go out of sync. It's set by virtue of the event being executed. 440 */ 441 if (gamespeed != ((OptionsClass::MAX_SPEED_SETTING-1) - gspeed_btn.Get_Value()) ) { 442 gamespeed = (OptionsClass::MAX_SPEED_SETTING-1) - gspeed_btn.Get_Value(); 443 OutList.Add(EventClass(EventClass::GAMESPEED, gamespeed)); 444 } 445 446 if (scrollrate != ((OptionsClass::MAX_SCROLL_SETTING-1) - scrate_btn.Get_Value()) ) { 447 scrollrate = (OptionsClass::MAX_SCROLL_SETTING-1) - scrate_btn.Get_Value(); 448 Options.ScrollRate = scrollrate; 449 } 450 process = false; 451 452 /* 453 ** Save the settings in such a way that the GameSpeed is only set during 454 ** the save process; restore it when we're done, so multiplayer games don't 455 ** go out of sync. 456 */ 457 if (Session.Type == GAME_NORMAL) { 458 Options.GameSpeed = gamespeed; 459 Options.Save_Settings(); // save new value 460 } else { 461 int old = Options.GameSpeed; // save orig value 462 Options.GameSpeed = gamespeed; 463 Options.Save_Settings(); // save new value 464 Options.GameSpeed = old; // restore old value 465 } 466 467 /* 468 ** Possibly launch into another dialog if so directed. 469 */ 470 switch (selection) { 471 case (BUTTON_VISUAL): 472 VisualControlsClass().Process(); 473 process = true; 474 display = true; 475 refresh = true; 476 break; 477 478 case (BUTTON_SOUND): 479 if (!SoundType) { 480 WWMessageBox().Process(Text_String(TXT_NO_SOUND_CARD)); 481 process = true; 482 display = true; 483 refresh = true; 484 } else { 485 SoundControlsClass().Process(); 486 process = true; 487 display = true; 488 refresh = true; 489 } 490 break; 491 492 #ifdef WOLAPI_INTEGRATION 493 case BUTTON_WOLAPI: 494 if( WOL_Options_Dialog( pWolapi, true ) ) 495 { 496 // The game ended while in this dialog. 497 process = false; 498 } 499 else 500 { 501 process = true; 502 display = true; 503 refresh = true; 504 } 505 break; 506 #endif 507 508 case (BUTTON_OK): 509 break; 510 } 511 512 pressed = false; 513 } 514 } 515 } 516 517