DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

MenuScreen_Shell_SystemOptions.cpp (20830B)


      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_SYSTEM_OPTIONS_OPTIONS = 8;
     33 
     34 extern idCVar r_multiSamples;
     35 extern idCVar r_motionBlur;
     36 extern idCVar r_swapInterval;
     37 extern idCVar s_volume_dB;
     38 extern idCVar r_lightScale;
     39 
     40 /*
     41 ========================
     42 idMenuScreen_Shell_SystemOptions::Initialize
     43 ========================
     44 */
     45 void idMenuScreen_Shell_SystemOptions::Initialize( idMenuHandler * data ) {
     46 	idMenuScreen::Initialize( data );
     47 
     48 	if ( data != NULL ) {
     49 		menuGUI = data->GetGUI();
     50 	}
     51 
     52 	SetSpritePath( "menuSystemOptions" );
     53 
     54 	options = new (TAG_SWF) idMenuWidget_DynamicList();
     55 	options->SetNumVisibleOptions( NUM_SYSTEM_OPTIONS_OPTIONS );
     56 	options->SetSpritePath( GetSpritePath(), "info", "options" );
     57 	options->SetWrappingAllowed( true );
     58 	options->SetControlList( true );
     59 	options->Initialize( data );
     60 
     61 	btnBack = new (TAG_SWF) idMenuWidget_Button();
     62 	btnBack->Initialize( data );
     63 	btnBack->SetLabel( "#str_swf_settings" );
     64 	btnBack->SetSpritePath( GetSpritePath(), "info", "btnBack" );
     65 	btnBack->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_GO_BACK );
     66 
     67 	AddChild( options );
     68 	AddChild( btnBack );
     69 
     70 	idMenuWidget_ControlButton * control;
     71 	control = new (TAG_SWF) idMenuWidget_ControlButton();
     72 	control->SetOptionType( OPTION_SLIDER_TEXT );
     73 	control->SetLabel( "#str_02154" );
     74 	control->SetDataSource( &systemData, idMenuDataSource_SystemSettings::SYSTEM_FIELD_FULLSCREEN );
     75 	control->SetupEvents( DEFAULT_REPEAT_TIME, options->GetChildren().Num() );
     76 	control->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, idMenuDataSource_SystemSettings::SYSTEM_FIELD_FULLSCREEN );
     77 	options->AddChild( control );
     78 
     79 	control = new (TAG_SWF) idMenuWidget_ControlButton();
     80 	control->SetOptionType( OPTION_SLIDER_TEXT );
     81 	control->SetLabel( "#str_swf_framerate" );
     82 	control->SetDataSource( &systemData, idMenuDataSource_SystemSettings::SYSTEM_FIELD_FRAMERATE );
     83 	control->SetupEvents( DEFAULT_REPEAT_TIME, options->GetChildren().Num() );
     84 	control->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, idMenuDataSource_SystemSettings::SYSTEM_FIELD_FRAMERATE );
     85 	options->AddChild( control );
     86 
     87 	control = new (TAG_SWF) idMenuWidget_ControlButton();
     88 	control->SetOptionType( OPTION_SLIDER_TEXT );
     89 	control->SetLabel( "#str_04126" );
     90 	control->SetDataSource( &systemData, idMenuDataSource_SystemSettings::SYSTEM_FIELD_VSYNC );
     91 	control->SetupEvents( DEFAULT_REPEAT_TIME, options->GetChildren().Num() );
     92 	control->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, idMenuDataSource_SystemSettings::SYSTEM_FIELD_VSYNC );
     93 	options->AddChild( control );
     94 
     95 	control = new (TAG_SWF) idMenuWidget_ControlButton();
     96 	control->SetOptionType( OPTION_SLIDER_TEXT );
     97 	control->SetLabel( "#str_04128" );
     98 	control->SetDataSource( &systemData, idMenuDataSource_SystemSettings::SYSTEM_FIELD_ANTIALIASING );
     99 	control->SetupEvents( DEFAULT_REPEAT_TIME, options->GetChildren().Num() );
    100 	control->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, idMenuDataSource_SystemSettings::SYSTEM_FIELD_ANTIALIASING );
    101 	options->AddChild( control );
    102 
    103 	control = new (TAG_SWF) idMenuWidget_ControlButton();
    104 	control->SetOptionType( OPTION_SLIDER_TEXT );
    105 	control->SetLabel( "#str_swf_motionblur" );
    106 	control->SetDataSource( &systemData, idMenuDataSource_SystemSettings::SYSTEM_FIELD_MOTIONBLUR );
    107 	control->SetupEvents( DEFAULT_REPEAT_TIME, options->GetChildren().Num() );
    108 	control->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, idMenuDataSource_SystemSettings::SYSTEM_FIELD_MOTIONBLUR );
    109 	options->AddChild( control );
    110 
    111 	control = new (TAG_SWF) idMenuWidget_ControlButton();
    112 	control->SetOptionType( OPTION_SLIDER_BAR );
    113 	control->SetLabel( "#str_swf_lodbias" );
    114 	control->SetDataSource( &systemData, idMenuDataSource_SystemSettings::SYSTEM_FIELD_LODBIAS );
    115 	control->SetupEvents( DEFAULT_REPEAT_TIME, options->GetChildren().Num() );
    116 	control->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, idMenuDataSource_SystemSettings::SYSTEM_FIELD_LODBIAS );
    117 	options->AddChild( control );
    118 
    119 	control = new (TAG_SWF) idMenuWidget_ControlButton();
    120 	control->SetOptionType( OPTION_SLIDER_BAR );
    121 	control->SetLabel( "#str_02155" );	// Brightness
    122 	control->SetDataSource( &systemData, idMenuDataSource_SystemSettings::SYSTEM_FIELD_BRIGHTNESS );
    123 	control->SetupEvents( 2, options->GetChildren().Num() );
    124 	control->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, idMenuDataSource_SystemSettings::SYSTEM_FIELD_BRIGHTNESS );
    125 	options->AddChild( control );
    126 
    127 	control = new (TAG_SWF) idMenuWidget_ControlButton();
    128 	control->SetOptionType( OPTION_SLIDER_BAR );
    129 	control->SetLabel( "#str_02163" );	// Volume
    130 	control->SetDataSource( &systemData, idMenuDataSource_SystemSettings::SYSTEM_FIELD_VOLUME );
    131 	control->SetupEvents( 2, options->GetChildren().Num() );
    132 	control->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, idMenuDataSource_SystemSettings::SYSTEM_FIELD_VOLUME );
    133 	options->AddChild( control );
    134 
    135 	options->AddEventAction( WIDGET_EVENT_SCROLL_DOWN ).Set( new (TAG_SWF) idWidgetActionHandler( options, WIDGET_ACTION_EVENT_SCROLL_DOWN_START_REPEATER, WIDGET_EVENT_SCROLL_DOWN ) );
    136 	options->AddEventAction( WIDGET_EVENT_SCROLL_UP ).Set( new (TAG_SWF) idWidgetActionHandler( options, WIDGET_ACTION_EVENT_SCROLL_UP_START_REPEATER, WIDGET_EVENT_SCROLL_UP ) );
    137 	options->AddEventAction( WIDGET_EVENT_SCROLL_DOWN_RELEASE ).Set( new (TAG_SWF) idWidgetActionHandler( options, WIDGET_ACTION_EVENT_STOP_REPEATER, WIDGET_EVENT_SCROLL_DOWN_RELEASE ) );
    138 	options->AddEventAction( WIDGET_EVENT_SCROLL_UP_RELEASE ).Set( new (TAG_SWF) idWidgetActionHandler( options, WIDGET_ACTION_EVENT_STOP_REPEATER, WIDGET_EVENT_SCROLL_UP_RELEASE ) );
    139 	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 ) );
    140 	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 ) );
    141 	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 ) );
    142 	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 ) );
    143 }
    144 
    145 /*
    146 ========================
    147 idMenuScreen_Shell_SystemOptions::Update
    148 ========================
    149 */
    150 void idMenuScreen_Shell_SystemOptions::Update() {
    151 
    152 	if ( menuData != NULL ) {
    153 		idMenuWidget_CommandBar * cmdBar = menuData->GetCmdBar();
    154 		if ( cmdBar != NULL ) {
    155 			cmdBar->ClearAllButtons();
    156 			idMenuWidget_CommandBar::buttonInfo_t * buttonInfo;			
    157 			buttonInfo = cmdBar->GetButton( idMenuWidget_CommandBar::BUTTON_JOY2 );
    158 			if ( menuData->GetPlatform() != 2 ) {
    159 				buttonInfo->label = "#str_00395";
    160 			}
    161 			buttonInfo->action.Set( WIDGET_ACTION_GO_BACK );
    162 
    163 			buttonInfo = cmdBar->GetButton( idMenuWidget_CommandBar::BUTTON_JOY1 );
    164 			buttonInfo->action.Set( WIDGET_ACTION_PRESS_FOCUSED );
    165 		}		
    166 	}
    167 
    168 	idSWFScriptObject & root = GetSWFObject()->GetRootObject();
    169 	if ( BindSprite( root ) ) {
    170 		idSWFTextInstance * heading = GetSprite()->GetScriptObject()->GetNestedText( "info", "txtHeading" );
    171 		if ( heading != NULL ) {
    172 			heading->SetText( "#str_00183" );	// FULLSCREEN
    173 			heading->SetStrokeInfo( true, 0.75f, 1.75f );
    174 		}
    175 
    176 		idSWFSpriteInstance * gradient = GetSprite()->GetScriptObject()->GetNestedSprite( "info", "gradient" );
    177 		if ( gradient != NULL && heading != NULL ) {
    178 			gradient->SetXPos( heading->GetTextLength() );
    179 		}
    180 	}
    181 
    182 	if ( btnBack != NULL ) {
    183 		btnBack->BindSprite( root );
    184 	}
    185 
    186 	idMenuScreen::Update();
    187 }
    188 
    189 /*
    190 ========================
    191 idMenuScreen_Shell_SystemOptions::ShowScreen
    192 ========================
    193 */
    194 void idMenuScreen_Shell_SystemOptions::ShowScreen( const mainMenuTransition_t transitionType ) {
    195 	
    196 	systemData.LoadData();
    197 	
    198 	idMenuScreen::ShowScreen( transitionType );
    199 }
    200 
    201 /*
    202 ========================
    203 idMenuScreen_Shell_SystemOptions::HideScreen
    204 ========================
    205 */
    206 void idMenuScreen_Shell_SystemOptions::HideScreen( const mainMenuTransition_t transitionType ) {
    207 
    208 	if ( systemData.IsRestartRequired() ) {
    209 		class idSWFScriptFunction_Restart : public idSWFScriptFunction_RefCounted {
    210 		public:
    211 			idSWFScriptFunction_Restart( gameDialogMessages_t _msg, bool _restart ) {
    212 				msg = _msg;
    213 				restart = _restart;
    214 			}
    215 			idSWFScriptVar Call( idSWFScriptObject * thisObject, const idSWFParmList & parms ) {
    216 				common->Dialog().ClearDialog( msg );
    217 				if ( restart ) {
    218 					idStr cmdLine = Sys_GetCmdLine();
    219 					if ( cmdLine.Find( "com_skipIntroVideos" ) < 0 ) {
    220 						cmdLine.Append( " +set com_skipIntroVideos 1" );
    221 					}
    222 					Sys_ReLaunch( (void*)cmdLine.c_str(), cmdLine.Length() );
    223 				}
    224 				return idSWFScriptVar();
    225 			}
    226 		private:
    227 			gameDialogMessages_t msg;
    228 			bool restart;
    229 		};
    230 		idStaticList<idSWFScriptFunction *, 4> callbacks;
    231 		idStaticList<idStrId, 4> optionText;
    232 		callbacks.Append( new idSWFScriptFunction_Restart( GDM_GAME_RESTART_REQUIRED, false ) );
    233 		callbacks.Append( new idSWFScriptFunction_Restart( GDM_GAME_RESTART_REQUIRED, true ) );
    234 		optionText.Append( idStrId( "#str_00100113" ) ); // Continue
    235 		optionText.Append( idStrId( "#str_02487" ) ); // Restart Now
    236 		common->Dialog().AddDynamicDialog( GDM_GAME_RESTART_REQUIRED, callbacks, optionText, true, idStr() );
    237 	}
    238 
    239 	if ( systemData.IsDataChanged() ) {
    240 		systemData.CommitData();
    241 	}
    242 
    243 	idMenuScreen::HideScreen( transitionType );
    244 }
    245 
    246 /*
    247 ========================
    248 idMenuScreen_Shell_SystemOptions::HandleAction h
    249 ========================
    250 */
    251 bool idMenuScreen_Shell_SystemOptions::HandleAction( idWidgetAction & action, const idWidgetEvent & event, idMenuWidget * widget, bool forceHandled ) {
    252 
    253 	if ( menuData == NULL ) {
    254 		return true;
    255 	}
    256 	
    257 	if ( menuData->ActiveScreen() != SHELL_AREA_SYSTEM_OPTIONS ) {
    258 		return false;
    259 	}
    260 
    261 	widgetAction_t actionType = action.GetType();
    262 	const idSWFParmList & parms = action.GetParms();
    263 
    264 	switch ( actionType ) {
    265 		case WIDGET_ACTION_GO_BACK: {
    266 			if ( menuData != NULL ) {
    267 				menuData->SetNextScreen( SHELL_AREA_SETTINGS, MENU_TRANSITION_SIMPLE );
    268 			}
    269 			return true;
    270 		}
    271 		case WIDGET_ACTION_ADJUST_FIELD:
    272 			if ( widget->GetDataSourceFieldIndex() == idMenuDataSource_SystemSettings::SYSTEM_FIELD_FULLSCREEN ) {
    273 				menuData->SetNextScreen( SHELL_AREA_RESOLUTION, MENU_TRANSITION_SIMPLE );
    274 				return true;
    275 			}
    276 			break;
    277 		case WIDGET_ACTION_COMMAND: {
    278 
    279 			if ( options == NULL ) {
    280 				return true;
    281 			}
    282 
    283 			int selectionIndex = options->GetFocusIndex();
    284 			if ( parms.Num() > 0 ) {
    285 				selectionIndex = parms[0].ToInteger();
    286 			}
    287 
    288 			if ( options && selectionIndex != options->GetFocusIndex() ) {
    289 				options->SetViewIndex( options->GetViewOffset() + selectionIndex );
    290 				options->SetFocusIndex( selectionIndex );
    291 			}
    292 
    293 			switch ( parms[0].ToInteger() ) {
    294 				case idMenuDataSource_SystemSettings::SYSTEM_FIELD_FULLSCREEN: {
    295 					menuData->SetNextScreen( SHELL_AREA_RESOLUTION, MENU_TRANSITION_SIMPLE );
    296 					return true;
    297 				}
    298 				default: {
    299 					systemData.AdjustField( parms[0].ToInteger(), 1 );
    300 					options->Update();
    301 				}
    302 			}
    303 
    304 			return true;
    305 		}
    306 		case WIDGET_ACTION_START_REPEATER: {
    307 
    308 			if ( options == NULL ) {
    309 				return true;
    310 			}
    311 
    312 			if ( parms.Num() == 4 ) {
    313 				int selectionIndex = parms[3].ToInteger();
    314 				if ( selectionIndex != options->GetFocusIndex() ) {
    315 					options->SetViewIndex( options->GetViewOffset() + selectionIndex );
    316 					options->SetFocusIndex( selectionIndex );
    317 				}
    318 			}
    319 			break;
    320 		}
    321 	}
    322 
    323 	return idMenuWidget::HandleAction( action, event, widget, forceHandled );
    324 }
    325 
    326 /////////////////////////////////
    327 // SCREEN SETTINGS
    328 /////////////////////////////////
    329 
    330 /*
    331 ========================
    332 idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::idMenuDataSource_SystemSettings
    333 ========================
    334 */
    335 idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::idMenuDataSource_SystemSettings() {
    336 }
    337 
    338 /*
    339 ========================
    340 idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::LoadData
    341 ========================
    342 */
    343 void idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::LoadData() {
    344 	originalFramerate = com_engineHz.GetInteger();
    345 	originalAntialias = r_multiSamples.GetInteger();
    346 	originalMotionBlur = r_motionBlur.GetInteger();
    347 	originalVsync = r_swapInterval.GetInteger();
    348 	originalBrightness = r_lightScale.GetFloat();
    349 	originalVolume = s_volume_dB.GetFloat();
    350 
    351 	const int fullscreen = r_fullscreen.GetInteger();
    352 	if ( fullscreen > 0 ) {
    353 		R_GetModeListForDisplay( fullscreen - 1, modeList );
    354 	} else {
    355 		modeList.Clear();
    356 	}
    357 }
    358 
    359 /*
    360 ========================
    361 idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::IsRestartRequired
    362 ========================
    363 */
    364 bool idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::IsRestartRequired() const {
    365 	if ( originalAntialias != r_multiSamples.GetInteger() ) {
    366 		return true;
    367 	}
    368 	if ( originalFramerate != com_engineHz.GetInteger() ) {
    369 		return true;
    370 	}
    371 	return false;
    372 }
    373 
    374 /*
    375 ========================
    376 idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::CommitData
    377 ========================
    378 */
    379 void idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::CommitData() {
    380 	cvarSystem->SetModifiedFlags( CVAR_ARCHIVE );
    381 }
    382 
    383 /*
    384 ========================
    385 AdjustOption
    386 Given a current value in an array of possible values, returns the next n value
    387 ========================
    388 */
    389 int AdjustOption( int currentValue, const int values[], int numValues, int adjustment ) {
    390 	int index = 0;
    391 	for ( int i = 0; i < numValues; i++ ) {
    392 		if ( currentValue == values[i] ) {
    393 			index = i;
    394 			break;
    395 		}
    396 	}
    397 	index += adjustment;
    398 	while ( index < 0 ) {
    399 		index += numValues;
    400 	}
    401 	index %= numValues;
    402 	return values[index];
    403 }
    404 
    405 /*
    406 ========================
    407 LinearAdjust
    408 Linearly converts a float from one scale to another
    409 ========================
    410 */
    411 float LinearAdjust( float input, float currentMin, float currentMax, float desiredMin, float desiredMax ) {
    412 	return ( ( input - currentMin ) / ( currentMax - currentMin ) ) * ( desiredMax - desiredMin ) + desiredMin;
    413 }
    414 
    415 /*
    416 ========================
    417 idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::AdjustField
    418 ========================
    419 */
    420 void idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::AdjustField( const int fieldIndex, const int adjustAmount ) {
    421 	switch ( fieldIndex ) {
    422 		case SYSTEM_FIELD_FRAMERATE: {
    423 			static const int numValues = 2;
    424 			static const int values[numValues] = { 60, 120 };
    425 			com_engineHz.SetInteger( AdjustOption( com_engineHz.GetInteger(), values, numValues, adjustAmount ) );
    426 			break;
    427 		}
    428 		case SYSTEM_FIELD_VSYNC: {
    429 			static const int numValues = 3;
    430 			static const int values[numValues] = { 0, 1, 2 };
    431 			r_swapInterval.SetInteger( AdjustOption( r_swapInterval.GetInteger(), values, numValues, adjustAmount ) );
    432 			break;
    433 		}
    434 		case SYSTEM_FIELD_ANTIALIASING: {
    435 			static const int numValues = 5;
    436 			static const int values[numValues] = { 0, 2, 4, 8, 16 };
    437 			r_multiSamples.SetInteger( AdjustOption( r_multiSamples.GetInteger(), values, numValues, adjustAmount ) );
    438 			break;
    439 		}
    440 		case SYSTEM_FIELD_MOTIONBLUR: {
    441 			static const int numValues = 5;
    442 			static const int values[numValues] = { 0, 2, 3, 4, 5 };
    443 			r_motionBlur.SetInteger( AdjustOption( r_motionBlur.GetInteger(), values, numValues, adjustAmount ) );
    444 			break;
    445 		}
    446 		case SYSTEM_FIELD_LODBIAS: {
    447 			const float percent = LinearAdjust( r_lodBias.GetFloat(), -1.0f, 1.0f, 0.0f, 100.0f );
    448 			const float adjusted = percent + (float)adjustAmount * 5.0f;
    449 			const float clamped = idMath::ClampFloat( 0.0f, 100.0f, adjusted );
    450 			r_lodBias.SetFloat( LinearAdjust( clamped, 0.0f, 100.0f, -1.0f, 1.0f ) );
    451 			break;
    452 		}
    453 		case SYSTEM_FIELD_BRIGHTNESS: {
    454 			const float percent = LinearAdjust( r_lightScale.GetFloat(), 2.0f, 4.0f, 0.0f, 100.0f );
    455 			const float adjusted = percent + (float)adjustAmount;
    456 			const float clamped = idMath::ClampFloat( 0.0f, 100.0f, adjusted );
    457 			r_lightScale.SetFloat( LinearAdjust( clamped, 0.0f, 100.0f, 2.0f, 4.0f ) );
    458 			break;
    459 		}
    460 		case SYSTEM_FIELD_VOLUME: {
    461 			const float percent = 100.0f * Square( 1.0f - ( s_volume_dB.GetFloat() / DB_SILENCE ) );
    462 			const float adjusted = percent + (float)adjustAmount;
    463 			const float clamped = idMath::ClampFloat( 0.0f, 100.0f, adjusted );
    464 			s_volume_dB.SetFloat( DB_SILENCE - ( idMath::Sqrt( clamped / 100.0f ) * DB_SILENCE ) );
    465 			break;
    466 		}
    467 	}
    468 	cvarSystem->ClearModifiedFlags( CVAR_ARCHIVE );
    469 }
    470 
    471 /*
    472 ========================
    473 idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::GetField	
    474 ========================
    475 */
    476 idSWFScriptVar idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::GetField( const int fieldIndex ) const {
    477 	switch ( fieldIndex ) {
    478 		case SYSTEM_FIELD_FULLSCREEN: {
    479 			const int fullscreen = r_fullscreen.GetInteger();
    480 			const int vidmode = r_vidMode.GetInteger();
    481 			if ( fullscreen == 0 ) {
    482 				return "#str_swf_disabled";
    483 			}
    484 			if ( fullscreen < 0 || vidmode < 0 || vidmode >= modeList.Num() ) {
    485 				return "???";
    486 			}
    487 			if ( modeList[vidmode].displayHz == 60 ) {
    488 				return va( "%4i x %4i", modeList[vidmode].width, modeList[vidmode].height );
    489 			} else {
    490 				return va( "%4i x %4i @ %dhz", modeList[vidmode].width, modeList[vidmode].height, modeList[vidmode].displayHz );
    491 			}
    492 		}
    493 		case SYSTEM_FIELD_FRAMERATE:
    494 			return va( "%d FPS", com_engineHz.GetInteger() );
    495 		case SYSTEM_FIELD_VSYNC:
    496 			if ( r_swapInterval.GetInteger() == 1 ) {
    497 				return "#str_swf_smart";
    498 			} else if ( r_swapInterval.GetInteger() == 2 ) {
    499 				return "#str_swf_enabled";
    500 			} else {
    501 				return "#str_swf_disabled";
    502 			}
    503 		case SYSTEM_FIELD_ANTIALIASING:
    504 			if ( r_multiSamples.GetInteger() == 0 ) {
    505 				return "#str_swf_disabled";
    506 			}
    507 			return va( "%dx", r_multiSamples.GetInteger() );
    508 		case SYSTEM_FIELD_MOTIONBLUR:
    509 			if ( r_motionBlur.GetInteger() == 0 ) {
    510 				return "#str_swf_disabled";
    511 			}
    512 			return va( "%dx", idMath::IPow( 2, r_motionBlur.GetInteger() ) );
    513 		case SYSTEM_FIELD_LODBIAS:
    514 			return LinearAdjust( r_lodBias.GetFloat(), -1.0f, 1.0f, 0.0f, 100.0f );
    515 		case SYSTEM_FIELD_BRIGHTNESS:
    516 			return LinearAdjust( r_lightScale.GetFloat(), 2.0f, 4.0f, 0.0f, 100.0f );
    517 		case SYSTEM_FIELD_VOLUME: {
    518 			return 100.0f * Square( 1.0f - ( s_volume_dB.GetFloat() / DB_SILENCE ) );
    519 		}
    520 	}
    521 	return false;
    522 }
    523 
    524 /*
    525 ========================
    526 idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::IsDataChanged	
    527 ========================
    528 */
    529 bool idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::IsDataChanged() const {
    530 	if ( originalFramerate != com_engineHz.GetInteger() ) {
    531 		return true;
    532 	}
    533 	if ( originalAntialias != r_multiSamples.GetInteger() ) {
    534 		return true;
    535 	}
    536 	if ( originalMotionBlur != r_motionBlur.GetInteger() ) {
    537 		return true;
    538 	}
    539 	if ( originalVsync != r_swapInterval.GetInteger() ) {
    540 		return true;
    541 	}
    542 	if ( originalBrightness != r_lightScale.GetFloat() ) {
    543 		return true;
    544 	}
    545 	if ( originalVolume != s_volume_dB.GetFloat() ) {
    546 		return true;
    547 	}
    548 	return false;
    549 }