mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-03-05 21:40:31 +00:00
Updated autodetect graphics to complete to new apply changes rules Made it so gamepad can activate key rebinds
1137 lines
No EOL
34 KiB
Text
1137 lines
No EOL
34 KiB
Text
//options settings
|
|
|
|
//Screen and Display menu
|
|
//Renderer Mode
|
|
//Screen resolution
|
|
//Windowed/fullscreen(borderless?)
|
|
//VSync
|
|
|
|
//Screen brightness
|
|
//screen brightness
|
|
//screen gamma
|
|
|
|
//Lighting Menu
|
|
//Shadow Distance(Distance shadows are drawn to. Also affects shadowmap slices)
|
|
//Shadow Quality(Resolution of shadows rendered, setting to none disables dynamic shadows)
|
|
//Soft Shadows(Whether shadow softening is used)
|
|
//Shadow caching(If the lights enable it, shadow caching is activated)
|
|
//Light Draw Distance(How far away lights are still drawn. Doesn't impact vector lights like the sun)
|
|
|
|
//Mesh and Textures Menu
|
|
//Draw distance(Overall draw distance) -slider
|
|
//Object draw distance(Draw distance from small/unimportant objects) -slider
|
|
//Mesh quality
|
|
//Texture quality
|
|
//Foliage draw distance
|
|
//Terrain Quality
|
|
//Decal Quality
|
|
|
|
//Effects Menu
|
|
//Parallax
|
|
//HDR
|
|
//Light shafts
|
|
//Motion Blur
|
|
//Depth of Field
|
|
//SSAO
|
|
//AA(ModelXAmount)[defualt is FXAA]
|
|
//Anisotropic filtering
|
|
|
|
//Keybinds
|
|
|
|
//Camera
|
|
//horizontal mouse sensitivity
|
|
//vert mouse sensitivity
|
|
//invert vertical
|
|
//zoom mouse sensitivities(both horz/vert)
|
|
//headbob
|
|
//FOV
|
|
|
|
$yesNoList = "No\tYes";
|
|
$onOffList = "Off\tOn";
|
|
$optionsEntryPad = 10;
|
|
|
|
$OptionsMenuCategories[0] = "Video";
|
|
$OptionsMenuCategories[1] = "Audio";
|
|
$OptionsMenuCategories[2] = "KBM";
|
|
$OptionsMenuCategories[3] = "Controller";
|
|
|
|
function OptionsMenu::onAdd(%this)
|
|
{
|
|
if(!isObject(%this.optionsCategories))
|
|
{
|
|
%this.optionsCategories = new ArrayObject();
|
|
}
|
|
|
|
if(!isObject(%this.unappliedChanges))
|
|
{
|
|
%this.unappliedChanges = new ArrayObject(OptionsMenuUnappliedChanges);
|
|
}
|
|
|
|
%this.currentCategory = "";
|
|
|
|
callOnModules("populateOptionsMenuCategories", "Game");
|
|
}
|
|
|
|
function OptionsMenu::onWake(%this)
|
|
{
|
|
%this.unappliedChanges.empty();
|
|
|
|
%this.populateVideoSettings();
|
|
|
|
%this.populateAudioSettings();
|
|
|
|
%this.populateKBMControls();
|
|
|
|
%this.populateGamepadControls();
|
|
//establish the cached prefs values here
|
|
|
|
%this.openOptionsCategory("Video");
|
|
}
|
|
|
|
if(!isObject( OptionsMenuActionMap ) )
|
|
{
|
|
new ActionMap(OptionsMenuActionMap){};
|
|
|
|
OptionsMenuActionMap.bind( keyboard, Escape, tryCloseOptionsMenu);
|
|
OptionsMenuActionMap.bind( gamepad, btn_b, tryCloseOptionsMenu);
|
|
|
|
OptionsMenuActionMap.bind( keyboard, w, OptionMenuNavigatePrev );
|
|
OptionsMenuActionMap.bind( keyboard, s, OptionMenuNavigateNext );
|
|
OptionsMenuActionMap.bind( gamepad, yaxis, "D", "-0.23 0.23", OptionMenuStickNavigate );
|
|
OptionsMenuActionMap.bind( gamepad, upov, OptionMenuNavigatePrev );
|
|
OptionsMenuActionMap.bind( gamepad, dpov, OptionMenuNavigateNext );
|
|
|
|
OptionsMenuActionMap.bind( keyboard, a, OptionMenuPrevSetting );
|
|
OptionsMenuActionMap.bind( keyboard, d, OptionMenuNextSetting );
|
|
OptionsMenuActionMap.bind( gamepad, xaxis, "D", "-0.23 0.23", OptionMenuStickChangeSetting );
|
|
OptionsMenuActionMap.bind( gamepad, lpov, OptionMenuPrevSetting );
|
|
OptionsMenuActionMap.bind( gamepad, lpov, OptionMenuNextSetting );
|
|
|
|
OptionsMenuActionMap.bind( keyboard, q, OptionsMenuPrevCategory );
|
|
OptionsMenuActionMap.bind( gamepad, btn_l, OptionsMenuPrevCategory );
|
|
|
|
OptionsMenuActionMap.bind( keyboard, e, OptionsMenuNextCategory );
|
|
OptionsMenuActionMap.bind( gamepad, btn_r, OptionsMenuNextCategory );
|
|
|
|
OptionsMenuActionMap.bind( keyboard, R, OptionsMenuReset );
|
|
OptionsMenuActionMap.bind( gamepad, btn_x, OptionsMenuReset );
|
|
|
|
OptionsMenuActionMap.bind( keyboard, Enter, OptionsMenuActivateOption );
|
|
OptionsMenuActionMap.bind( gamepad, btn_a, OptionsMenuActivateOption );
|
|
}
|
|
|
|
function OptionsMenuList::syncGui(%this)
|
|
{
|
|
%this.callOnChildren("setHighlighted", false);
|
|
|
|
%btn = %this.getObject(%this.listPosition);
|
|
if(%btn.class $= "OptionsListEntry" ||
|
|
%btn.class $= "OptionsListSliderEntry" ||
|
|
%btn.class $= "OptionsKeybindEntry")
|
|
%btn-->button.setHighlighted(true);
|
|
|
|
//iterate over the items and ensure that they are formatted well based on the settings selected
|
|
foreach(%option in %this)
|
|
{
|
|
%container = %option-->valuesContainer;
|
|
|
|
if(%option.class $= "OptionsListEntry")
|
|
{
|
|
%hasLevels = %option.optionsObject.getCount() <= 1;
|
|
|
|
%optionObject = %option.optionsObject;
|
|
|
|
//If it's out of range of the options, it's probably a custom value
|
|
if(%option.currentOptionIndex < %optionObject.getCount() && %option.currentOptionIndex >= 0)
|
|
{
|
|
%currentOptionLevel = %optionObject.getObject(%option.currentOptionIndex);
|
|
%currentOptionLevelTxt = %currentOptionLevel.displayName;
|
|
}
|
|
else
|
|
{
|
|
%currentOptionLevelTxt = "Custom";
|
|
}
|
|
|
|
%optionValTextWidth = %option-->optionValue.profile.getStringWidth(%currentOptionLevelTxt);
|
|
|
|
%option-->optionValue.resize(%container.extent.x - %container-->prevValButton.extent.x - %optionValTextWidth - 20, 0,
|
|
%optionValTextWidth + 20, %container.extent.y);
|
|
|
|
%option-->optionValue.text = %currentOptionLevelTxt;
|
|
|
|
%container-->prevValButton.position.x = %option-->optionValue.position.x - 20;
|
|
%container-->nextValButton.position.x = %container.extent.x - %container-->prevValButton.extent.x;
|
|
|
|
//if there's no alternatives, disable the left/right buttons
|
|
%container-->prevValButton.setHidden(%hasLevels);
|
|
%container-->nextValButton.setHidden(%hasLevels);
|
|
}
|
|
else if(%option.class $= "OptionsListSliderEntry")
|
|
{
|
|
}
|
|
else if(%option.class $= "OptionsKeybindEntry")
|
|
{
|
|
%bindImgAsset = getButtonBitmap(%option.device, getField(%option.keymap, 1));
|
|
|
|
if(%bindImgAsset $= "UI:Keyboard_Black_Blank_image")
|
|
%bindImgAsset = "";
|
|
|
|
%container-->bindButton.setBitmap(%bindImgAsset);
|
|
}
|
|
}
|
|
}
|
|
|
|
function OptionsMenuList::checkForUnappliedChanges(%this)
|
|
{
|
|
%unappliedChanges = false;
|
|
|
|
foreach(%option in %this)
|
|
{
|
|
if(%option.class $= "OptionsListEntry")
|
|
{
|
|
if(%option.currentOptionIndex >= 0 && %option.currentOptionIndex < %option.optionsObject.getCount())
|
|
{
|
|
%targetOptionLevel = %option.optionsObject.getObject(%option.currentOptionIndex);
|
|
|
|
if(!%targetOptionLevel.isCurrent())
|
|
%unappliedChanges = true;
|
|
|
|
if(%option.optionsObject.requiresRestart)
|
|
$optionsChangeRequiresRestart = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return %unappliedChanges;
|
|
}
|
|
|
|
function OptionsMenuList::applyChanges(%this)
|
|
{
|
|
foreach(%option in %this)
|
|
{
|
|
if(%option.class $= "OptionsListEntry")
|
|
{
|
|
//If it's custom or nonsensical index, there's some kind of external factor going on, so we're
|
|
//just going to skip applying it because we don't know what we'd be applying
|
|
if(%option.currentOptionIndex >= 0 && %option.currentOptionIndex < %option.optionsObject.getCount())
|
|
{
|
|
%targetOptionLevel = %option.optionsObject.getObject(%option.currentOptionIndex);
|
|
|
|
if(!%targetOptionLevel.isCurrent())
|
|
%targetOptionLevel.apply();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function OptionsMenu::openOptionsCategory(%this, %categoryName)
|
|
{
|
|
VideoSettingsList.setVisible(%categoryName $= "Video");
|
|
AudioSettingsList.setVisible(%categoryName $= "Audio");
|
|
KBMControlsList.setVisible(%categoryName $= "KBM");
|
|
GamepadControlsList.setVisible(%categoryName $= "Controller");
|
|
|
|
if(%categoryName $= "Video")
|
|
{
|
|
$MenuList = VideoSettingsList;
|
|
//Find our first non-group entry
|
|
while($MenuList.getObject($MenuList.listPosition).class !$= OptionsListEntry && $MenuList.listPosition < $MenuList.getCount())
|
|
{
|
|
$MenuList.listPosition += 1;
|
|
}
|
|
|
|
%this.currentCatgeoryIdx = 0;
|
|
}
|
|
else if(%categoryName $= "Audio")
|
|
{
|
|
$MenuList = AudioSettingsList;
|
|
|
|
%this.currentCatgeoryIdx = 1;
|
|
}
|
|
else if(%categoryName $= "KBM")
|
|
{
|
|
$MenuList = KBMControlsList;
|
|
|
|
%this.currentCatgeoryIdx = 2;
|
|
}
|
|
else if(%categoryName $= "Controller")
|
|
{
|
|
$MenuList = GamepadControlsList;
|
|
|
|
%this.currentCatgeoryIdx = 3;
|
|
}
|
|
|
|
$MenuList.syncGui();
|
|
%this.syncGui();
|
|
}
|
|
|
|
function OptionsMenu::syncGui(%this)
|
|
{
|
|
OptionsMenuCategoryList.callOnChildren("setHighlighted", false);
|
|
|
|
%btn = OptionsMenuCategoryList.getObject(%this.currentCatgeoryIdx);
|
|
%btn.setHighlighted(true);
|
|
|
|
%buttonPosX = %btn.position.x + OptionsMenuCategoryList.position.x;
|
|
|
|
OptionsMenuPrevNavIcon.position.x = %buttonPosX - 5;
|
|
OptionsMenuNextNavIcon.position.x = %buttonPosX + %btn.extent.x - 35;
|
|
|
|
//Update the button imagery to comply to the last input device we'd used
|
|
%device = Canvas.getLastInputDevice();
|
|
if(%device $= "mouse")
|
|
%device = "keyboard";
|
|
|
|
OptionsMenuBackBtn.setBitmap(BaseUIActionMap.getCommandButtonBitmap(%device, "BaseUIBackOut"));
|
|
OptionsMenuResetBtn.setBitmap(OptionsMenuActionMap.getCommandButtonBitmap(%device, "OptionsMenuReset"));
|
|
|
|
OptionsMenuPrevNavIcon.setBitmap(OptionsMenuActionMap.getCommandButtonBitmap(%device, "OptionsMenuPrevCategory"));
|
|
OptionsMenuNextNavIcon.setBitmap(OptionsMenuActionMap.getCommandButtonBitmap(%device, "OptionsMenuNextCategory"));
|
|
}
|
|
|
|
function OptionsMenuPrevCategory(%val)
|
|
{
|
|
if(%val)
|
|
{
|
|
%currentIdx = OptionsMenu.currentMenuIdx;
|
|
OptionsMenu.currentMenuIdx -= 1;
|
|
|
|
OptionsMenu.currentMenuIdx = mClamp(OptionsMenu.currentMenuIdx, 0, 3);
|
|
|
|
if(%currentIdx == OptionsMenu.currentMenuIdx)
|
|
return;
|
|
|
|
%newCategory = $OptionsMenuCategories[OptionsMenu.currentMenuIdx];
|
|
OptionsMenu.openOptionsCategory(%newCategory);
|
|
}
|
|
}
|
|
|
|
function OptionsMenuNextCategory(%val)
|
|
{
|
|
if(%val)
|
|
{
|
|
%currentIdx = OptionsMenu.currentMenuIdx;
|
|
OptionsMenu.currentMenuIdx += 1;
|
|
|
|
OptionsMenu.currentMenuIdx = mClamp(OptionsMenu.currentMenuIdx, 0, 3);
|
|
|
|
if(%currentIdx == OptionsMenu.currentMenuIdx)
|
|
return;
|
|
|
|
%newCategory = $OptionsMenuCategories[OptionsMenu.currentMenuIdx];
|
|
OptionsMenu.openOptionsCategory(%newCategory);
|
|
}
|
|
}
|
|
|
|
//
|
|
function OptionMenuNavigatePrev(%val)
|
|
{
|
|
if(%val)
|
|
{
|
|
$MenuList.listPosition -= 1;
|
|
while( $MenuList.listPosition >= 0 && ($MenuList.getObject($MenuList.listPosition).class !$= "OptionsListEntry" &&
|
|
$MenuList.getObject($MenuList.listPosition).class !$= "OptionsListSliderEntry" &&
|
|
$MenuList.getObject($MenuList.listPosition).class !$= "OptionsKeybindEntry"))
|
|
{
|
|
$MenuList.listPosition -= 1;
|
|
}
|
|
|
|
if($MenuList.listPosition < 0)
|
|
$MenuList.listPosition = 0;
|
|
|
|
$MenuList.syncGUI();
|
|
}
|
|
}
|
|
|
|
function OptionMenuNavigateNext(%val)
|
|
{
|
|
if(%val)
|
|
{
|
|
$MenuList.listPosition += 1;
|
|
while($MenuList.listPosition < $MenuList.getCount() && ($MenuList.getObject($MenuList.listPosition).class !$= "OptionsListEntry" &&
|
|
$MenuList.getObject($MenuList.listPosition).class !$= "OptionsListSliderEntry" &&
|
|
$MenuList.getObject($MenuList.listPosition).class !$= "OptionsKeybindEntry"))
|
|
{
|
|
$MenuList.listPosition += 1;
|
|
}
|
|
|
|
if($MenuList.listPosition >= $MenuList.getCount())
|
|
$MenuList.listPosition = $MenuList.getCount()-1;
|
|
|
|
$MenuList.syncGUI();
|
|
}
|
|
}
|
|
|
|
function OptionMenuStickNavigate(%val)
|
|
{
|
|
if(%val == -1)
|
|
BaseUINavigateNext(1);
|
|
else if(%val == 1)
|
|
mainMenuNavigateDown(1);
|
|
}
|
|
|
|
function OptionMenuPrevSetting(%val)
|
|
{
|
|
if(!%val)
|
|
return;
|
|
|
|
%option = $MenuList.getObject($MenuList.listPosition);
|
|
|
|
if(!isObject(%option))
|
|
return;
|
|
|
|
if(%option.class $= "OptionsListEntry")
|
|
{
|
|
%optionObject = %option.optionsObject;
|
|
%currentOptionLevel = %optionObject.getObject(%option.currentOptionIndex);
|
|
|
|
%option.currentOptionIndex = mClamp(%option.currentOptionIndex-1, 0, %optionObject.getCount()-1);
|
|
|
|
%newOptionLevel = %optionObject.getObject(%option.currentOptionIndex);
|
|
|
|
//echo("Changed option: " @ %optionObject.optionName @ " from level: " @ %currentOptionLevel.displayName @ " to level: " @ %newOptionLevel.displayName);
|
|
}
|
|
|
|
$MenuList.syncGUI();
|
|
}
|
|
|
|
function OptionMenuNextSetting(%val)
|
|
{
|
|
if(!%val)
|
|
return;
|
|
|
|
%option = $MenuList.getObject($MenuList.listPosition);
|
|
|
|
if(!isObject(%option) )
|
|
return;
|
|
|
|
if(%option.class $= "OptionsListEntry")
|
|
{
|
|
%optionObject = %option.optionsObject;
|
|
%currentOptionLevel = %optionObject.getObject(%option.currentOptionIndex);
|
|
|
|
%option.currentOptionIndex = mClamp(%option.currentOptionIndex+1, 0, %optionObject.getCount()-1);
|
|
|
|
%newOptionLevel = %optionObject.getObject(%option.currentOptionIndex);
|
|
|
|
//echo("Changed option: " @ %optionObject.optionName @ " from level: " @ %currentOptionLevel.displayName @ " to level: " @ %newOptionLevel.displayName);
|
|
}
|
|
|
|
$MenuList.syncGUI();
|
|
}
|
|
|
|
function OptionMenuStickChangeSetting(%val)
|
|
{
|
|
|
|
}
|
|
|
|
function OptionsMenuActivateOption(%val)
|
|
{
|
|
if(!%val)
|
|
return;
|
|
|
|
%option = $MenuList.getObject($MenuList.listPosition);
|
|
|
|
if(!isObject(%option))
|
|
return;
|
|
|
|
echo(%option.class);
|
|
|
|
if(%option.class $= "OptionsKeybindEntry")
|
|
{
|
|
eval(%option-->button.altCommand);
|
|
}
|
|
}
|
|
//
|
|
//
|
|
//
|
|
function OptionsMenu::populateVideoSettings(%this)
|
|
{
|
|
VideoSettingsList.clear();
|
|
|
|
VideoSettingsGroup::populateDisplaySettings();
|
|
|
|
for(%i=0; %i < VideoSettingsGroup.getCount(); %i++)
|
|
{
|
|
%setting = VideoSettingsGroup.getObject(%i);
|
|
|
|
if(%setting.class $= "SubOptionsGroup")
|
|
{
|
|
%entry = addOptionGroup(%setting.displayName);
|
|
|
|
if(isObject(%entry))
|
|
VideoSettingsList.add(%entry);
|
|
|
|
for(%s=0; %s < %setting.getCount(); %s++)
|
|
{
|
|
%option = %setting.getObject(%s);
|
|
|
|
%optionsEntry = addOptionEntry(%option);
|
|
|
|
if(isObject(%optionsEntry))
|
|
VideoSettingsList.add(%optionsEntry);
|
|
}
|
|
}
|
|
else if(%setting.class $= "OptionsSettings")
|
|
{
|
|
%optionsEntry = addOptionEntry(%setting);
|
|
|
|
if(isObject(%optionsEntry))
|
|
VideoSettingsList.add(%optionsEntry);
|
|
}
|
|
}
|
|
|
|
//Ensure our newly templated options listings are sized right
|
|
for(%i=0; %i < VideoSettingsList.getCount(); %i++)
|
|
{
|
|
%entry = VideoSettingsList.getObject(%i);
|
|
%entry.resize(0, 0, VideoSettingsList.extent.x - 15, %entry.extent.y); //-10 for the scroll wheel pad
|
|
}
|
|
}
|
|
|
|
function OptionsMenu::populateAudioSettings(%this)
|
|
{
|
|
AudioSettingsList.clear();
|
|
AudioSettingsGroup.populateSettings();
|
|
|
|
//Process the lists
|
|
for(%i=0; %i < AudioSettingsGroup.getCount(); %i++)
|
|
{
|
|
%setting = AudioSettingsGroup.getObject(%i);
|
|
|
|
if(%setting.class $= "SubOptionsGroup")
|
|
{
|
|
%entry = addOptionGroup(%setting.displayName);
|
|
|
|
if(isObject(%entry))
|
|
AudioSettingsList.add(%entry);
|
|
|
|
for(%s=0; %s < %setting.getCount(); %s++)
|
|
{
|
|
%option = %setting.getObject(%s);
|
|
|
|
%optionsEntry = addOptionEntry(%option);
|
|
|
|
if(isObject(%optionsEntry))
|
|
AudioSettingsList.add(%optionsEntry);
|
|
}
|
|
}
|
|
else if(%setting.class $= "AudioOptionsSettings")
|
|
{
|
|
%optionsEntry = addOptionEntry(%setting);
|
|
|
|
if(isObject(%optionsEntry))
|
|
AudioSettingsList.add(%optionsEntry);
|
|
}
|
|
}
|
|
|
|
AudioSettingsList.add(addOptionGroup("Channel Volume"));
|
|
|
|
AudioSettingsList.add(addOptionSlider("Master Volume", "", "$pref::SFX::masterVolume", 0, 1, 0.1));
|
|
AudioSettingsList.add(addOptionSlider("GUI Volume", "", "$pref::SFX::channelVolume[" @ $GuiAudioType @ "]", 0, 1, 0.1));
|
|
AudioSettingsList.add(addOptionSlider("Effects Volume", "", "$pref::SFX::channelVolume[" @ $SimAudioType @ "]", 0, 1, 0.1));
|
|
AudioSettingsList.add(addOptionSlider("Music Volume", "", "$pref::SFX::channelVolume[" @ $MusicAudioType @ "]", 0, 1, 0.1));
|
|
|
|
//Ensure our newly templated options listings are sized right
|
|
for(%i=0; %i < AudioSettingsList.getCount(); %i++)
|
|
{
|
|
%entry = AudioSettingsList.getObject(%i);
|
|
%entry.resize(0, 0, AudioSettingsList.extent.x - 15, %entry.extent.y); //-10 for the scroll wheel pad
|
|
}
|
|
}
|
|
|
|
function OptionsMenu::populateKBMControls(%this)
|
|
{
|
|
//$remapListDevice = "keyboard";
|
|
%this.populateKeybinds("keyboard", KBMControlsList);
|
|
|
|
%this.syncGui();
|
|
}
|
|
|
|
function OptionsMenu::populateGamepadControls(%this)
|
|
{
|
|
//$remapListDevice = ;
|
|
%this.populateKeybinds("gamepad", GamepadControlsList);
|
|
|
|
%this.syncGui();
|
|
}
|
|
|
|
function OptionsMenu::populateKeybinds(%this, %device, %controlsList)
|
|
{
|
|
//%device = $remapListDevice;
|
|
|
|
%controlsList.clear();
|
|
|
|
//build out our list of action maps
|
|
%actionMapCount = ActionMapGroup.getCount();
|
|
|
|
%actionMapList = "";
|
|
for(%i=0; %i < %actionMapCount; %i++)
|
|
{
|
|
%actionMap = ActionMapGroup.getObject(%i);
|
|
|
|
if(%actionMap == GlobalActionMap.getId())
|
|
continue;
|
|
|
|
%actionMapName = %actionMap.humanReadableName $= "" ? %actionMap.getName() : %actionMap.humanReadableName;
|
|
|
|
//see if we have any actual listed remappable keys for this movemap. if so, drop it from the listing
|
|
%hasRemaps = false;
|
|
for ( %r = 0; %r < $RemapCount; %r++ )
|
|
{
|
|
%testMapName = $RemapActionMap[%r].humanReadableName $= "" ? $RemapActionMap[%r].getName() : $RemapActionMap[%r].humanReadableName;
|
|
|
|
if(%actionMapName $= %testMapName)
|
|
{
|
|
//got a match to at least one, so we're ok to continue
|
|
%hasRemaps = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(!%hasRemaps)
|
|
continue;
|
|
|
|
if(%actionMapList $= "")
|
|
%actionMapList = %actionMapName;
|
|
else
|
|
%actionMapList = %actionMapList TAB %actionMapName;
|
|
}
|
|
|
|
//If we didn't find any valid actionMaps, then just exit out
|
|
if(%actionMapList $= "")
|
|
return;
|
|
|
|
if($activeRemapControlSet $= "")
|
|
$activeRemapControlSet = getField(%actionMapList, 0);
|
|
|
|
if(getFieldCount(%actionMapList) > 1)
|
|
{
|
|
for(%am = 0; %am < getFieldCount(%actionMapList); %am++)
|
|
{
|
|
%currentActionMap = getField(%actionMapList, %am);
|
|
|
|
%actionMapGroupEntry = addOptionGroup(%currentActionMap);
|
|
%controlsList.add(%actionMapGroupEntry);
|
|
|
|
for ( %i = 0; %i < $RemapCount; %i++ )
|
|
{
|
|
if(%device !$= "" && %device !$= $RemapDevice[%i])
|
|
continue;
|
|
|
|
%actionMapName = $RemapActionMap[%i].humanReadableName $= "" ? $RemapActionMap[%i].getName() : $RemapActionMap[%i].humanReadableName;
|
|
|
|
if(%currentActionMap !$= %actionMapName)
|
|
continue;
|
|
|
|
%keyMap = buildFullMapString( %i, $RemapActionMap[%i], %device );
|
|
|
|
%description = $RemapDescription[%i];
|
|
|
|
%remapEntry = addActionMapEntry(%actionMapName, %device, %keyMap, %i, %description);
|
|
%controlsList.add(%remapEntry);
|
|
}
|
|
}
|
|
}
|
|
|
|
//Ensure our newly templated options listings are sized right
|
|
for(%i=0; %i < %controlsList.getCount(); %i++)
|
|
{
|
|
%entry = %controlsList.getObject(%i);
|
|
%entry.resize(0, 0, %controlsList.extent.x - 15, %entry.extent.y); //-10 for the scroll wheel pad
|
|
}
|
|
}
|
|
|
|
function tryCloseOptionsMenu(%val)
|
|
{
|
|
if(!%val)
|
|
return;
|
|
|
|
$optionsChangeRequiresRestart = false;
|
|
|
|
%unappliedVideoChanges = VideoSettingsList.checkForUnappliedChanges();
|
|
%unappliedAudioChanges = AudioSettingsList.checkForUnappliedChanges();
|
|
|
|
if(%unappliedVideoChanges || %unappliedAudioChanges)
|
|
{
|
|
MessageBoxOKCancel("Discard Changes?", "You have unapplied changes to your settings, do you wish to apply or discard them?",
|
|
"OptionsMenu.applyChangedOptions();", "Canvas.popDialog(OptionsMenu);",
|
|
"Apply", "Discard");
|
|
}
|
|
else
|
|
{
|
|
Canvas.popDialog(OptionsMenu);
|
|
}
|
|
}
|
|
|
|
function OptionsMenu::applyChangedOptions(%this)
|
|
{
|
|
VideoSettingsList.applyChanges();
|
|
AudioSettingsList.applyChanges();
|
|
|
|
//$pref::SFX::masterVolume = OptionsMenuSettingsList.getValue(2);
|
|
sfxSetMasterVolume( $pref::SFX::masterVolume );
|
|
sfxSetChannelVolume( $GuiAudioType, $pref::SFX::channelVolume[ $GuiAudioType ] );
|
|
sfxSetChannelVolume( $SimAudioType, $pref::SFX::channelVolume[ $SimAudioType ] );
|
|
sfxSetChannelVolume( $MusicAudioType, $pref::SFX::channelVolume[ $MusicAudioType ] );
|
|
|
|
//Finally, write our prefs to file
|
|
%prefPath = getPrefpath();
|
|
export("$pref::*", %prefPath @ "/clientPrefs." @ $TorqueScriptFileExtension, false);
|
|
|
|
Canvas.popDialog(OptionsMenu);
|
|
|
|
if($optionsChangeRequiresRestart)
|
|
MessageBoxOK("Restart Required", "Some of your changes require the game to be restarted.");
|
|
}
|
|
|
|
function doKeyRemap( %optionEntry )
|
|
{
|
|
//%rowIndex = %row.remapIndex;
|
|
//%name = $RemapName[%rowIndex];
|
|
|
|
%name = getField(%optionEntry.keymap,0);
|
|
|
|
RemapDlg-->OptRemapText.text = "Re-bind \"" @ %name @ "\" to..." ;
|
|
OptRemapInputCtrl.index = %optionEntry.remapIndex;
|
|
|
|
Canvas.pushDialog( RemapDlg );
|
|
}
|
|
|
|
function OptionsMenu::apply(%this)
|
|
{
|
|
//Now we run through our list of unapplied changes and... apply them.
|
|
%hasKeybindChanges = false;
|
|
%hasVideoChanges = false;
|
|
%hasPostFXChanges = false;
|
|
%hasAudioChanges = false;
|
|
%hasGraphicsChanges = false;
|
|
for(%i=0; %i < %this.unappliedChanges.count(); %i++)
|
|
{
|
|
%targetVar = %this.unappliedChanges.getKey(%i);
|
|
%newValue = strReplace(%this.unappliedChanges.getValue(%i), "\"", "");
|
|
|
|
//First, lets just check through our action map names, see if any match
|
|
%wasKeybind = false;
|
|
for(%am=0; %am < ActionMapGroup.getCount(); %am++)
|
|
{
|
|
%actionMap = ActionMapGroup.getObject(%am);
|
|
|
|
if(%actionMap == GlobalActionMap.getId())
|
|
continue;
|
|
|
|
%actionMapName = %actionMap.getName();
|
|
if(%actionMapName $= %targetVar)
|
|
{
|
|
%hasKeybindChanges = true;
|
|
%wasKeybind = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(!%wasKeybind)
|
|
{
|
|
%sanitizedVar = strReplace(%targetVar, "[", "");
|
|
%sanitizedVar = strReplace(%sanitizedVar, "]", "");
|
|
%sanitizedVar = strReplace(%sanitizedVar, ",", "_");
|
|
%currentValue = getVariable(%sanitizedVar);
|
|
if(%currentValue !$= %newValue)
|
|
{
|
|
setVariable(%targetVar, %newValue);
|
|
|
|
//now, lets check for special cases that need additional handling
|
|
//for updates
|
|
if ( %targetVar $= "$pref::Video::displayDevice" )
|
|
{
|
|
schedule(32, 0, "MessageBoxOK", "Change requires restart", "Please restart the game for a display device change to take effect.");
|
|
}
|
|
else if(startsWith(%targetVar, "$pref::PostFX::"))
|
|
{
|
|
%hasPostFXChanges = true;
|
|
}
|
|
else if(startsWith(%targetVar, "$pref::Video::"))
|
|
{
|
|
%hasVideoChanges = true;
|
|
|
|
//if it's the resolution, it's possible we got the human-friendly
|
|
//version stored off. if so, reprocess into the usable state
|
|
if(%targetVar $= "$pref::Video::Resolution")
|
|
{
|
|
if(strpos(%newValue, " x ") != -1)
|
|
{
|
|
%newValue = strreplace(%newValue, " x ", " ");
|
|
setVariable(%targetVar, %newValue);
|
|
}
|
|
}
|
|
//This is a bit of hackery to have an intermediate variable because we display in text
|
|
//but save by index, so we take the applied name and get the index of the deviceId
|
|
else if(%targetVar $= "$pref::Video::displayDeviceId")
|
|
{
|
|
%deviceId = getDisplayDeviceId($pref::Video::displayDeviceId);
|
|
if(%deviceId == -1)
|
|
%deviceId = 0;
|
|
|
|
$pref::Video::deviceId = %deviceId;
|
|
$pref::Video::displayDeviceId = "";
|
|
}
|
|
}
|
|
else if(startsWith(%targetVar, "$pref::SFX::"))
|
|
{
|
|
%hasAudioChanges = true;
|
|
}
|
|
else if(startsWith(%targetVar, "$pref::Graphics::"))
|
|
{
|
|
%hasGraphicsChanges = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//If we had keybind changes, go ahead and save those out
|
|
if(%hasKeybindChanges)
|
|
{
|
|
%prefPath = getPrefpath();
|
|
|
|
%actionMapCount = ActionMapGroup.getCount();
|
|
|
|
%actionMapList = "";
|
|
%append = false;
|
|
for(%i=0; %i < %actionMapCount; %i++)
|
|
{
|
|
%actionMap = ActionMapGroup.getObject(%i);
|
|
|
|
if(%actionMap == GlobalActionMap.getId())
|
|
continue;
|
|
|
|
%actionMap.save( %prefPath @ "/keybinds." @ $TorqueScriptFileExtension, %append );
|
|
|
|
if(%append != true)
|
|
%append = true;
|
|
}
|
|
}
|
|
|
|
if(%hasPostFXChanges)
|
|
{
|
|
updatePostFXSettings();
|
|
}
|
|
|
|
if(%hasVideoChanges)
|
|
{
|
|
updateDisplaySettings();
|
|
}
|
|
|
|
if(%hasAudioChanges)
|
|
{
|
|
updateAudioSettings();
|
|
}
|
|
|
|
if(%hasGraphicsChanges)
|
|
{
|
|
updateGraphicsSettings();
|
|
}
|
|
|
|
//Finally, write our prefs to file
|
|
%prefPath = getPrefpath();
|
|
export("$pref::*", %prefPath @ "/clientPrefs." @ $TorqueScriptFileExtension, false);
|
|
|
|
OptionsMenu.unappliedChanges.empty();
|
|
}
|
|
|
|
function OptionsMenu::resetSettings(%this)
|
|
{
|
|
MessageBoxOKCancel("", "This will set the graphical settings back to the auto-detected defaults. Do you wish to continue?", "AutodetectGraphics();", "");
|
|
}
|
|
|
|
function addOptionGroup(%displayName)
|
|
{
|
|
%group = new GuiTextCtrl() {
|
|
text = %displayName;
|
|
position = "0 0";
|
|
extent = "500 45";
|
|
profile = "MenuHeaderText";
|
|
tooltipProfile = "GuiToolTipProfile";
|
|
};
|
|
|
|
return %group;
|
|
}
|
|
|
|
function optionsMenuButton::onHighlighted(%this, %highlighted)
|
|
{
|
|
%container = %this.getParent();
|
|
|
|
%container-->optionName.profile = %highlighted ? MenuSubHeaderTextHighlighted : MenuSubHeaderText;
|
|
%container-->optionDescription.profile = %highlighted ? GuiMLTextProfileHighlighted : GuiMLTextProfile;
|
|
|
|
%valuesContainer = %container-->valuesContainer;
|
|
%valuesContainer-->optionValue.profile = %highlighted ? GuiMenuTextProfileHL : GuiMenuTextProfile;
|
|
|
|
OptionsMenuSettingsScroll.scrollToObject(%container);
|
|
}
|
|
|
|
function addOptionEntry(%optionObj)
|
|
{
|
|
if(!isObject(%optionObj) || (%optionObj.class !$= "OptionsSettings" && %optionObj.class !$= "AudioOptionsSettings"))
|
|
{
|
|
error("addOptionsEntry() - attempting to create a new options entry, but was provided an invalid options object");
|
|
return 0;
|
|
}
|
|
|
|
%qualityLevel = getCurrentQualityLevel(%optionObj);
|
|
|
|
if(isObject(%qualityLevel))
|
|
{
|
|
%qualityLevelText = %qualityLevel.displayName;
|
|
%qualityLevelIndex = %optionObj.getObjectIndex(%qualityLevel);
|
|
}
|
|
else
|
|
{
|
|
%qualityLevelText = %qualityLevel;
|
|
%qualityLevelIndex = %optionObj.getCount();
|
|
}
|
|
|
|
%optionNameHeight = 20;
|
|
if(%optionObj.Description $= "")
|
|
%optionNameHeight = 40;
|
|
|
|
%entry = new GuiContainer() {
|
|
position = "0 0";
|
|
extent = "800 40";
|
|
profile = GuiMenuDefaultProfile;
|
|
tooltipProfile = "GuiToolTipProfile";
|
|
horizSizing = "width";
|
|
vertSizing = "bottom";
|
|
class = "OptionsListEntry";
|
|
optionsObject = %optionObj;
|
|
currentOptionIndex = %qualityLevelIndex;
|
|
canSave = "0";
|
|
|
|
new GuiButtonCtrl() {
|
|
profile = GuiMenuButtonProfile;
|
|
position = "0 0";
|
|
extent = "800 40";
|
|
horizSizing = "width";
|
|
vertSizing = "height";
|
|
internalName = "button";
|
|
class = "optionsMenuButton";
|
|
};
|
|
|
|
new GuiTextCtrl() {
|
|
text = %optionObj.OptionName;
|
|
position = $optionsEntryPad SPC -1;
|
|
extent = 400 SPC %optionNameHeight;
|
|
profile = "MenuSubHeaderText";
|
|
tooltipProfile = "GuiToolTipProfile";
|
|
internalName = "optionName";
|
|
};
|
|
new GuiTextCtrl() {
|
|
text = %optionObj.Description;
|
|
position = $optionsEntryPad SPC 17;
|
|
extent = "400 18";
|
|
profile = "GuiMLTextProfile";
|
|
tooltipProfile = "GuiToolTipProfile";
|
|
internalName = "optionDescription";
|
|
};
|
|
|
|
new GuiContainer() {
|
|
position = "400 0";
|
|
extent = "400 40";
|
|
profile = GuiModelessDialogProfile;
|
|
tooltipProfile = "GuiToolTipProfile";
|
|
horizSizing = "left";
|
|
vertSizing = "height";
|
|
internalName = "valuesContainer";
|
|
|
|
new GuiButtonCtrl() {
|
|
position = "310 0";
|
|
extent = "20 40";
|
|
text = "<";
|
|
profile = GuiMenuButtonProfile;
|
|
internalName = "prevValButton";
|
|
};
|
|
|
|
new GuiTextCtrl() {
|
|
text = %qualityLevelText;
|
|
position = "330 0";
|
|
extent = "50 40";
|
|
profile = "GuiMenuTextProfile";
|
|
tooltipProfile = "GuiToolTipProfile";
|
|
horizSizing = "right";
|
|
vertSizing = "center";
|
|
internalName = "optionValue";
|
|
};
|
|
|
|
new GuiButtonCtrl() {
|
|
position = "380 0";
|
|
extent = "20 40";
|
|
text = ">";
|
|
profile = GuiMenuButtonProfile;
|
|
internalName = "nextValButton";
|
|
};
|
|
};
|
|
};
|
|
|
|
return %entry;
|
|
}
|
|
|
|
function addOptionSlider(%optionName, %optionDesc, %prefName, %sliderMin, %sliderMax, %sliderTicks)
|
|
{
|
|
%currentVal = getVariable(%prefName);
|
|
|
|
if(%currentVal $= "")
|
|
%currentVal = %sliderMin;
|
|
|
|
%optionNameHeight = 20;
|
|
if(%optionDesc $= "")
|
|
%optionNameHeight = 40;
|
|
|
|
%entry = new GuiContainer() {
|
|
position = "0 0";
|
|
extent = "800 40";
|
|
profile = GuiMenuDefaultProfile;
|
|
tooltipProfile = "GuiToolTipProfile";
|
|
horizSizing = "width";
|
|
vertSizing = "bottom";
|
|
class = "OptionsListSliderEntry";
|
|
canSave = "0";
|
|
|
|
new GuiButtonCtrl() {
|
|
profile = GuiMenuButtonProfile;
|
|
position = "0 0";
|
|
extent = "800 40";
|
|
horizSizing = "width";
|
|
vertSizing = "height";
|
|
internalName = "button";
|
|
class = "optionsMenuButton";
|
|
};
|
|
|
|
new GuiTextCtrl() {
|
|
text = %optionName;
|
|
position = $optionsEntryPad SPC -1;
|
|
extent = 400 SPC %optionNameHeight;
|
|
profile = "MenuSubHeaderText";
|
|
tooltipProfile = "GuiToolTipProfile";
|
|
internalName = "optionName";
|
|
};
|
|
|
|
new GuiTextCtrl() {
|
|
text = %optionDesc;
|
|
position = $optionsEntryPad SPC 17;
|
|
extent = "400 18";
|
|
profile = "GuiMLTextProfile";
|
|
tooltipProfile = "GuiToolTipProfile";
|
|
internalName = "optionDescription";
|
|
};
|
|
|
|
new GuiContainer() {
|
|
position = "400 0";
|
|
extent = "400 40";
|
|
profile = GuiModelessDialogProfile;
|
|
tooltipProfile = "GuiToolTipProfile";
|
|
horizSizing = "left";
|
|
vertSizing = "height";
|
|
internalName = "valuesContainer";
|
|
|
|
new GuiSliderCtrl() {
|
|
range = %sliderMin SPC %sliderMax;
|
|
ticks = %sliderTicks;
|
|
snap = "1";
|
|
value = %currentVal;
|
|
useFillBar = "1";
|
|
fillBarColor = $TextMediumEmphasisColor;
|
|
renderTicks = "0";
|
|
position = "0 10";
|
|
extent = "300 20";
|
|
minExtent = "8 2";
|
|
horizSizing = "right";
|
|
vertSizing = "center";
|
|
profile = GuiMenuButtonProfile;
|
|
visible = "1";
|
|
active = "1";
|
|
command = "$thisControl.updateSliderValue();";
|
|
tooltipProfile = "GuiToolTipProfile";
|
|
hovertime = "1000";
|
|
isContainer = "0";
|
|
canSave = "1";
|
|
canSaveDynamicFields = "0";
|
|
class = "OptionsSliderEntrySlider";
|
|
};
|
|
};
|
|
};
|
|
|
|
return %entry;
|
|
}
|
|
|
|
function OptionsSliderEntrySlider::updateSliderValue(%this)
|
|
{
|
|
//update settings value here
|
|
}
|
|
|
|
function OptionsMenuActionMapButton::onHighlighted(%this, %highlighted)
|
|
{
|
|
%container = %this.getParent();
|
|
%container-->actionName.profile = %highlighted ? MenuSubHeaderTextHighlighted : MenuSubHeaderText;
|
|
|
|
OptionsMenuSettingsScroll.scrollToObject(%container);
|
|
}
|
|
|
|
function addActionMapEntry(%actionMap, %device, %keyMap, %index, %description)
|
|
{
|
|
%entry = new GuiContainer() {
|
|
position = "0 0";
|
|
extent = "800 40";
|
|
profile = GuiMenuDefaultProfile;
|
|
tooltipProfile = "GuiToolTipProfile";
|
|
horizSizing = "width";
|
|
vertSizing = "bottom";
|
|
class = "OptionsKeybindEntry";
|
|
canSave = "0";
|
|
actionMap = %actionMap;
|
|
device = %device;
|
|
keymap = %keyMap;
|
|
remapIndex = %index;
|
|
|
|
new GuiButtonCtrl() {
|
|
profile = GuiMenuButtonProfile;
|
|
position = "0 0";
|
|
extent = "800 40";
|
|
horizSizing = "width";
|
|
vertSizing = "height";
|
|
internalName = "button";
|
|
class = "OptionsMenuActionMapButton";
|
|
altCommand = "doKeyRemap($thisControl.getParent());";
|
|
};
|
|
|
|
new GuiTextCtrl() {
|
|
text = getField(%keyMap, 0);
|
|
position = $optionsEntryPad SPC -1;
|
|
extent = "400 40";
|
|
profile = "MenuSubHeaderText";
|
|
tooltipProfile = "GuiToolTipProfile";
|
|
internalName = "actionName";
|
|
};
|
|
|
|
new GuiContainer() {
|
|
position = "400 3";
|
|
extent = "400 34";
|
|
profile = GuiModelessDialogProfile;
|
|
tooltipProfile = "GuiToolTipProfile";
|
|
horizSizing = "left";
|
|
vertSizing = "height";
|
|
internalName = "valuesContainer";
|
|
|
|
new GuiIconButtonCtrl() {
|
|
position = "300 -10";
|
|
extent = "98 45";
|
|
BitmapAsset = "";
|
|
profile = GuiRemapActionMapButtonProfile;
|
|
sizeIconToButton = true;
|
|
makeIconSquare = true;
|
|
iconLocation = "center";
|
|
internalName = "bindButton";
|
|
active = false;
|
|
};
|
|
};
|
|
};
|
|
|
|
return %entry;
|
|
} |