mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-19 20:24:49 +00:00
Updated autodetect graphics to complete to new apply changes rules Made it so gamepad can activate key rebinds
1137 lines
34 KiB
Plaintext
1137 lines
34 KiB
Plaintext
//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;
|
|
} |