CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

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