DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

MenuScreen_Shell_Controls.cpp (14475B)


      1 /*
      2 ===========================================================================
      3 
      4 Doom 3 BFG Edition GPL Source Code
      5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 
      6 
      7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").  
      8 
      9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
     10 it under the terms of the GNU General Public License as published by
     11 the Free Software Foundation, either version 3 of the License, or
     12 (at your option) any later version.
     13 
     14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
     15 but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17 GNU General Public License for more details.
     18 
     19 You should have received a copy of the GNU General Public License
     20 along with Doom 3 BFG Edition Source Code.  If not, see <http://www.gnu.org/licenses/>.
     21 
     22 In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code.  If not, please request a copy in writing from id Software at the address below.
     23 
     24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
     25 
     26 ===========================================================================
     27 */
     28 #pragma hdrstop
     29 #include "../../idLib/precompiled.h"
     30 #include "../Game_local.h"
     31 
     32 const static int NUM_CONTROLS_OPTIONS = 8;
     33 
     34 enum contorlsMenuCmds_t {
     35 	CONTROLS_CMD_BINDINGS,
     36 	CONTROLS_CMD_GAMEPAD,
     37 	CONTROLS_CMD_GAMEPAD_ENABLED,
     38 	CONTROLS_CMD_INVERT,
     39 	CONTROLS_CMD_MOUSE_SENS
     40 };
     41 
     42 /*
     43 ========================
     44 idMenuScreen_Shell_Controls::Initialize
     45 ========================
     46 */
     47 void idMenuScreen_Shell_Controls::Initialize( idMenuHandler * data ) {
     48 	idMenuScreen::Initialize( data );
     49 
     50 	if ( data != NULL ) {
     51 		menuGUI = data->GetGUI();
     52 	}
     53 
     54 	SetSpritePath( "menuControls" );
     55 
     56 	options = new (TAG_SWF) idMenuWidget_DynamicList();
     57 	options->SetNumVisibleOptions( NUM_CONTROLS_OPTIONS );
     58 	options->SetSpritePath( GetSpritePath(), "info", "options" );
     59 	options->SetWrappingAllowed( true );
     60 	options->SetControlList( true );
     61 	options->Initialize( data );
     62 	AddChild( options );
     63 
     64 	idMenuWidget_Help * const helpWidget = new ( TAG_SWF ) idMenuWidget_Help();
     65 	helpWidget->SetSpritePath( GetSpritePath(), "info", "helpTooltip" );
     66 	AddChild( helpWidget );
     67 
     68 	btnBack = new (TAG_SWF) idMenuWidget_Button();
     69 	btnBack->Initialize( data );
     70 	btnBack->SetLabel( "#str_swf_settings" );
     71 	btnBack->SetSpritePath( GetSpritePath(), "info", "btnBack" );
     72 	btnBack->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_GO_BACK );
     73 	AddChild( btnBack );
     74 
     75 	idMenuWidget_ControlButton * control;
     76 	control = new (TAG_SWF) idMenuWidget_ControlButton();
     77 	control->SetOptionType( OPTION_BUTTON_TEXT );
     78 	control->SetLabel( "#str_swf_keyboard" );	// KEY BINDINGS
     79 	control->SetDescription( "#str_swf_binding_desc" );
     80 	control->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, CONTROLS_CMD_BINDINGS );
     81 	control->RegisterEventObserver( helpWidget );
     82 	options->AddChild( control );
     83 
     84 	control = new (TAG_SWF) idMenuWidget_ControlButton();
     85 	control->SetOptionType( OPTION_BUTTON_TEXT );
     86 	control->SetLabel( "#str_swf_gamepad" );	// Gamepad
     87 	control->SetDescription( "#str_swf_gamepad_desc" );
     88 	control->RegisterEventObserver( helpWidget );
     89 	control->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, CONTROLS_CMD_GAMEPAD );
     90 	options->AddChild( control );
     91 
     92 	control = new (TAG_SWF) idMenuWidget_ControlButton();
     93 	control->SetOptionType( OPTION_SLIDER_TOGGLE );
     94 	control->SetLabel( "#str_swf_gamepad_enabled" );	// Gamepad Enabled
     95 	control->SetDataSource( &controlData, idMenuDataSource_ControlSettings::CONTROLS_FIELD_GAMEPAD_ENABLED );
     96 	control->SetupEvents( DEFAULT_REPEAT_TIME, options->GetChildren().Num() );
     97 	control->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, CONTROLS_CMD_GAMEPAD_ENABLED );
     98 	control->RegisterEventObserver( helpWidget );
     99 	options->AddChild( control );
    100 
    101 	control = new (TAG_SWF) idMenuWidget_ControlButton();
    102 	control->SetOptionType( OPTION_SLIDER_TOGGLE );
    103 	control->SetLabel( "#str_swf_invert_mouse" );	// Invert Mouse
    104 	control->SetDataSource( &controlData, idMenuDataSource_ControlSettings::CONTROLS_FIELD_INVERT_MOUSE );
    105 	control->SetupEvents( DEFAULT_REPEAT_TIME, options->GetChildren().Num() );
    106 	control->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, CONTROLS_CMD_INVERT );
    107 	control->RegisterEventObserver( helpWidget );
    108 	options->AddChild( control );
    109 
    110 	control = new (TAG_SWF) idMenuWidget_ControlButton();
    111 	control->SetOptionType( OPTION_SLIDER_BAR );
    112 	control->SetLabel( "#str_swf_mouse_sens" );	// Mouse Sensitivity
    113 	control->SetDataSource( &controlData, idMenuDataSource_ControlSettings::CONTROLS_FIELD_MOUSE_SENS );
    114 	control->SetupEvents( 2, options->GetChildren().Num() );
    115 	control->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, CONTROLS_CMD_MOUSE_SENS );
    116 	control->RegisterEventObserver( helpWidget );
    117 	options->AddChild( control );
    118 
    119 	options->AddEventAction( WIDGET_EVENT_SCROLL_DOWN ).Set( new (TAG_SWF) idWidgetActionHandler( options, WIDGET_ACTION_EVENT_SCROLL_DOWN_START_REPEATER, WIDGET_EVENT_SCROLL_DOWN ) );
    120 	options->AddEventAction( WIDGET_EVENT_SCROLL_UP ).Set( new (TAG_SWF) idWidgetActionHandler( options, WIDGET_ACTION_EVENT_SCROLL_UP_START_REPEATER, WIDGET_EVENT_SCROLL_UP ) );
    121 	options->AddEventAction( WIDGET_EVENT_SCROLL_DOWN_RELEASE ).Set( new (TAG_SWF) idWidgetActionHandler( options, WIDGET_ACTION_EVENT_STOP_REPEATER, WIDGET_EVENT_SCROLL_DOWN_RELEASE ) );
    122 	options->AddEventAction( WIDGET_EVENT_SCROLL_UP_RELEASE ).Set( new (TAG_SWF) idWidgetActionHandler( options, WIDGET_ACTION_EVENT_STOP_REPEATER, WIDGET_EVENT_SCROLL_UP_RELEASE ) );
    123 	options->AddEventAction( WIDGET_EVENT_SCROLL_DOWN_LSTICK ).Set( new (TAG_SWF) idWidgetActionHandler( options, WIDGET_ACTION_EVENT_SCROLL_DOWN_START_REPEATER, WIDGET_EVENT_SCROLL_DOWN_LSTICK ) );
    124 	options->AddEventAction( WIDGET_EVENT_SCROLL_UP_LSTICK ).Set( new (TAG_SWF) idWidgetActionHandler( options, WIDGET_ACTION_EVENT_SCROLL_UP_START_REPEATER, WIDGET_EVENT_SCROLL_UP_LSTICK ) );
    125 	options->AddEventAction( WIDGET_EVENT_SCROLL_DOWN_LSTICK_RELEASE ).Set( new (TAG_SWF) idWidgetActionHandler( options, WIDGET_ACTION_EVENT_STOP_REPEATER, WIDGET_EVENT_SCROLL_DOWN_LSTICK_RELEASE ) );
    126 	options->AddEventAction( WIDGET_EVENT_SCROLL_UP_LSTICK_RELEASE ).Set( new (TAG_SWF) idWidgetActionHandler( options, WIDGET_ACTION_EVENT_STOP_REPEATER, WIDGET_EVENT_SCROLL_UP_LSTICK_RELEASE ) );
    127 }
    128 
    129 /*
    130 ========================
    131 idMenuScreen_Shell_Controls::Update
    132 ========================
    133 */
    134 void idMenuScreen_Shell_Controls::Update() {
    135 
    136 	if ( menuData != NULL ) {
    137 		idMenuWidget_CommandBar * cmdBar = menuData->GetCmdBar();
    138 		if ( cmdBar != NULL ) {
    139 			cmdBar->ClearAllButtons();
    140 			idMenuWidget_CommandBar::buttonInfo_t * buttonInfo;			
    141 			buttonInfo = cmdBar->GetButton( idMenuWidget_CommandBar::BUTTON_JOY2 );
    142 			if ( menuData->GetPlatform() != 2 ) {
    143 				buttonInfo->label = "#str_00395";
    144 			}
    145 			buttonInfo->action.Set( WIDGET_ACTION_GO_BACK );
    146 
    147 			buttonInfo = cmdBar->GetButton( idMenuWidget_CommandBar::BUTTON_JOY1 );
    148 			if ( menuData->GetPlatform() != 2 ) {
    149 				buttonInfo->label = "#str_SWF_SELECT";
    150 			}
    151 			buttonInfo->action.Set( WIDGET_ACTION_PRESS_FOCUSED );
    152 		}		
    153 	}
    154 
    155 	idSWFScriptObject & root = GetSWFObject()->GetRootObject();
    156 	if ( BindSprite( root ) ) {
    157 		idSWFTextInstance * heading = GetSprite()->GetScriptObject()->GetNestedText( "info", "txtHeading" );
    158 		if ( heading != NULL ) {
    159 			idStr controls( idLocalization::GetString( "#str_04158" ) );
    160 			controls.ToUpper();
    161 			heading->SetText( controls );	// CONTROLS
    162 			heading->SetStrokeInfo( true, 0.75f, 1.75f );
    163 		}
    164 
    165 		idSWFSpriteInstance * gradient = GetSprite()->GetScriptObject()->GetNestedSprite( "info", "gradient" );
    166 		if ( gradient != NULL && heading != NULL ) {
    167 			gradient->SetXPos( heading->GetTextLength() );
    168 		}
    169 	}
    170 
    171 	if ( btnBack != NULL ) {
    172 		btnBack->BindSprite( root );
    173 	}
    174 
    175 	idMenuScreen::Update();
    176 }
    177 
    178 /*
    179 ========================
    180 idMenuScreen_Shell_Controls::ShowScreen
    181 ========================
    182 */
    183 void idMenuScreen_Shell_Controls::ShowScreen( const mainMenuTransition_t transitionType ) {
    184 	controlData.LoadData();
    185 	idMenuScreen::ShowScreen( transitionType );
    186 }
    187 
    188 /*
    189 ========================
    190 idMenuScreen_Shell_Controls::HideScreen
    191 ========================
    192 */
    193 void idMenuScreen_Shell_Controls::HideScreen( const mainMenuTransition_t transitionType ) {
    194 	
    195 	if ( controlData.IsDataChanged() ) {
    196 		controlData.CommitData();
    197 	}
    198 	
    199 	if ( menuData != NULL ) {
    200 		idMenuHandler_Shell * handler = dynamic_cast< idMenuHandler_Shell * >( menuData );
    201 		if ( handler != NULL ) {
    202 			handler->SetupPCOptions();
    203 		}
    204 	}
    205 
    206 	idMenuScreen::HideScreen( transitionType );
    207 }
    208 
    209 /*
    210 ========================
    211 idMenuScreen_Shell_Controls::HandleAction
    212 ========================
    213 */
    214 bool idMenuScreen_Shell_Controls::HandleAction( idWidgetAction & action, const idWidgetEvent & event, idMenuWidget * widget, bool forceHandled ) {
    215 
    216 	if ( menuData == NULL ) {
    217 		return true;
    218 	}
    219 
    220 	if ( menuData->ActiveScreen() != SHELL_AREA_CONTROLS ) {
    221 		return false;
    222 	}
    223 	
    224 	widgetAction_t actionType = action.GetType();
    225 	const idSWFParmList & parms = action.GetParms();
    226 
    227 	switch ( actionType ) {
    228 		case WIDGET_ACTION_GO_BACK: {
    229 			menuData->SetNextScreen( SHELL_AREA_SETTINGS, MENU_TRANSITION_SIMPLE );
    230 			return true;
    231 		}
    232 
    233 		case WIDGET_ACTION_COMMAND: {
    234 
    235 			if ( options == NULL ) {
    236 				return true;
    237 			}
    238 
    239 			int selectionIndex = options->GetFocusIndex();
    240 			if ( parms.Num() > 0 ) {
    241 				selectionIndex = parms[0].ToInteger();
    242 			}
    243 
    244 			if ( selectionIndex != options->GetFocusIndex() ) {
    245 				options->SetViewIndex( options->GetViewOffset() + selectionIndex );
    246 				options->SetFocusIndex( selectionIndex );
    247 			}
    248 
    249 			switch ( parms[0].ToInteger() ) {
    250 				case CONTROLS_CMD_BINDINGS: {
    251 					menuData->SetNextScreen( SHELL_AREA_KEYBOARD, MENU_TRANSITION_SIMPLE );
    252 					break;
    253 				}
    254 				case CONTROLS_CMD_GAMEPAD: {
    255 					menuData->SetNextScreen( SHELL_AREA_GAMEPAD, MENU_TRANSITION_SIMPLE );
    256 					break;
    257 				}
    258 				case CONTROLS_CMD_INVERT: {
    259 					controlData.AdjustField( idMenuDataSource_ControlSettings::CONTROLS_FIELD_INVERT_MOUSE, 1 );
    260 					if ( options != NULL ) {
    261 						options->Update();
    262 					}
    263 					break;
    264 				}
    265 				case CONTROLS_CMD_MOUSE_SENS: {
    266 					controlData.AdjustField( idMenuDataSource_ControlSettings::CONTROLS_FIELD_MOUSE_SENS, 1 );
    267 					if ( options != NULL ) {
    268 						options->Update();
    269 					}
    270 					break;
    271 				}
    272 				case CONTROLS_CMD_GAMEPAD_ENABLED: {
    273 					controlData.AdjustField( idMenuDataSource_ControlSettings::CONTROLS_FIELD_GAMEPAD_ENABLED, 1 );
    274 					if ( options != NULL ) {
    275 						options->Update();
    276 					}
    277 					break;
    278 				}
    279 			}
    280 
    281 			return true;
    282 		}
    283 		case WIDGET_ACTION_START_REPEATER: {
    284 
    285 			if ( options == NULL ) {
    286 				return true;
    287 			}
    288 
    289 			if ( parms.Num() == 4 ) {
    290 				int selectionIndex = parms[3].ToInteger();
    291 				if ( selectionIndex != options->GetFocusIndex() ) {
    292 					options->SetViewIndex( options->GetViewOffset() + selectionIndex );
    293 					options->SetFocusIndex( selectionIndex );
    294 				}
    295 			}
    296 			break;
    297 		}
    298 	}
    299 
    300 	return idMenuWidget::HandleAction( action, event, widget, forceHandled );
    301 }
    302 
    303 /////////////////////////////////
    304 // SCREEN SETTINGS
    305 /////////////////////////////////
    306 
    307 extern idCVar in_mouseInvertLook;
    308 extern idCVar in_mouseSpeed;
    309 extern idCVar in_useJoystick;
    310 
    311 /*
    312 ========================
    313 idMenuScreen_Shell_Controls::idMenuDataSource_AudioSettings::idMenuDataSource_AudioSettings
    314 ========================
    315 */
    316 idMenuScreen_Shell_Controls::idMenuDataSource_ControlSettings::idMenuDataSource_ControlSettings() {
    317 	fields.SetNum( MAX_CONTROL_FIELDS );
    318 	originalFields.SetNum( MAX_CONTROL_FIELDS );
    319 }
    320 
    321 /*
    322 ========================
    323 idMenuScreen_Shell_Controls::idMenuDataSource_AudioSettings::LoadData
    324 ========================
    325 */
    326 void idMenuScreen_Shell_Controls::idMenuDataSource_ControlSettings::LoadData() {	
    327 	fields[ CONTROLS_FIELD_INVERT_MOUSE ].SetBool( in_mouseInvertLook.GetBool() );
    328 	float mouseSpeed = ( ( in_mouseSpeed.GetFloat() - 0.25f ) / ( 4.0f - 0.25 ) ) * 100.0f;
    329 	fields[ CONTROLS_FIELD_MOUSE_SENS ].SetFloat( mouseSpeed );
    330 	fields[ CONTROLS_FIELD_GAMEPAD_ENABLED ].SetBool( in_useJoystick.GetBool() );
    331 
    332 	originalFields = fields;
    333 }
    334 
    335 /*
    336 ========================
    337 idMenuScreen_Shell_Controls::idMenuDataSource_AudioSettings::CommitData
    338 ========================
    339 */
    340 void idMenuScreen_Shell_Controls::idMenuDataSource_ControlSettings::CommitData() {
    341 
    342 	in_mouseInvertLook.SetBool( fields[ CONTROLS_FIELD_INVERT_MOUSE ].ToBool() );		
    343 	float mouseSpeed = 0.25f + ( ( 4.0f - 0.25 ) * ( fields[ CONTROLS_FIELD_MOUSE_SENS ].ToFloat() / 100.0f ) );
    344 	in_mouseSpeed.SetFloat( mouseSpeed );
    345 	in_useJoystick.SetBool( fields[ CONTROLS_FIELD_GAMEPAD_ENABLED ].ToBool() );
    346 
    347 	cvarSystem->SetModifiedFlags( CVAR_ARCHIVE );
    348 
    349 	// make the committed fields into the backup fields
    350 	originalFields = fields;
    351 }
    352 
    353 /*
    354 ========================
    355 idMenuScreen_Shell_Controls::idMenuDataSource_AudioSettings::AdjustField
    356 ========================
    357 */
    358 void idMenuScreen_Shell_Controls::idMenuDataSource_ControlSettings::AdjustField( const int fieldIndex, const int adjustAmount ) {
    359 	if ( fieldIndex == CONTROLS_FIELD_INVERT_MOUSE || fieldIndex == CONTROLS_FIELD_GAMEPAD_ENABLED ) {
    360 		fields[ fieldIndex ].SetBool( !fields[ fieldIndex ].ToBool() );
    361 	} else if ( fieldIndex == CONTROLS_FIELD_MOUSE_SENS ) {
    362 		float newValue = idMath::ClampFloat( 0.0f, 100.0f, fields[ fieldIndex ].ToFloat() + adjustAmount );
    363 		fields[ fieldIndex ].SetFloat( newValue );
    364 	}
    365 }
    366 
    367 /*
    368 ========================
    369 idMenuScreen_Shell_Controls::idMenuDataSource_AudioSettings::IsDataChanged
    370 ========================
    371 */
    372 bool idMenuScreen_Shell_Controls::idMenuDataSource_ControlSettings::IsDataChanged() const {
    373 	
    374 	if ( fields[ CONTROLS_FIELD_INVERT_MOUSE ].ToBool() != originalFields[ CONTROLS_FIELD_INVERT_MOUSE ].ToBool() ) {
    375 		return true;
    376 	}
    377 
    378 	if ( fields[ CONTROLS_FIELD_MOUSE_SENS ].ToFloat() != originalFields[ CONTROLS_FIELD_MOUSE_SENS ].ToFloat() ) {
    379 		return true;
    380 	}
    381 
    382 	if ( fields[ CONTROLS_FIELD_GAMEPAD_ENABLED ].ToFloat() != originalFields[ CONTROLS_FIELD_GAMEPAD_ENABLED ].ToFloat() ) {
    383 		return true;
    384 	}
    385 
    386 	return false;
    387 }