mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-15 00:24:40 +00:00
Update optionsMenu.tscript
Fixed problems mapping mouse to keyboard and vice versa, added saving of custom keybinds, added mouse sensitivity slider, changed organization of file, added some commenting
This commit is contained in:
parent
a032b9e2a9
commit
04af5aafcc
1 changed files with 580 additions and 400 deletions
|
|
@ -1,4 +1,3 @@
|
||||||
$reportKeymapping = false;
|
|
||||||
$optionsEntryPad = 10;
|
$optionsEntryPad = 10;
|
||||||
|
|
||||||
$OptionsMenuCategories[0] = "Video";
|
$OptionsMenuCategories[0] = "Video";
|
||||||
|
|
@ -6,6 +5,11 @@ $OptionsMenuCategories[1] = "Audio";
|
||||||
$OptionsMenuCategories[2] = "KBM";
|
$OptionsMenuCategories[2] = "KBM";
|
||||||
$OptionsMenuCategories[3] = "Controller";
|
$OptionsMenuCategories[3] = "Controller";
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
//
|
||||||
|
// OptionsMenu General Functions
|
||||||
|
//
|
||||||
|
//==============================================================================
|
||||||
function OptionsMenu::onAdd(%this)
|
function OptionsMenu::onAdd(%this)
|
||||||
{
|
{
|
||||||
if(!isObject(%this.optionsCategories))
|
if(!isObject(%this.optionsCategories))
|
||||||
|
|
@ -465,240 +469,6 @@ function OptionsMenuActivateOption(%val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
// This function utilizes the VideoSettingsGroup SimGroup to populate options.
|
|
||||||
// The object is defined in core/rendering/scripts/graphicsOptions.tscript
|
|
||||||
// A majority of the options are statically defined, but some are dynamically populated
|
|
||||||
// on refresh, like the display device or available resolution options.
|
|
||||||
// Once populated, we loop over the simgroup structure to populate our option entry
|
|
||||||
// rows in the options menu itself.
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
// This function utilizes the AudioSettingsGroup SimGroup to populate options.
|
|
||||||
// The object is defined in core/sfx/scripts/audioOptions.tscript
|
|
||||||
// Similar to the video options, it can be a mix of static and dynamically populated
|
|
||||||
// option entries, which we then iterate over and populate the entry rows for the menu
|
|
||||||
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"));
|
|
||||||
|
|
||||||
//Now we'll populate the sliders for the audio channels.
|
|
||||||
//The defaults of these are defined in core/sfx/scripts/audio.tscript
|
|
||||||
//These define the MasterVolume channel, as well as several other common defualt ones
|
|
||||||
//Because it's a variable list, this can be expanded by modules by just upping $AudioChannelCount
|
|
||||||
//and then defining the $AudioChannelName[x] with the displayed name and
|
|
||||||
//and the $AudioChannels[x] variable with the SFXSource object defined to it for the given channel
|
|
||||||
AudioSettingsList.add(addOptionSlider("Master Volume", "", "$pref::SFX::masterVolume", 0, 1, 10));
|
|
||||||
|
|
||||||
//We init to 1, because 0 is the reserved for the masterVolume in practice
|
|
||||||
for(%i=1; %i < $AudioChannelCount; %i++)
|
|
||||||
{
|
|
||||||
AudioSettingsList.add(addOptionSlider($AudioChannelsName[%i] @ " Volume", "", "$pref::SFX::channelVolume" @ %i, 0, 1, 10));
|
|
||||||
}
|
|
||||||
|
|
||||||
//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)
|
|
||||||
{
|
|
||||||
%this.populateKeybinds("keyboard" TAB "mouse", KBMControlsList);
|
|
||||||
|
|
||||||
%this.syncGui();
|
|
||||||
|
|
||||||
KBMControlsList.syncGui();
|
|
||||||
}
|
|
||||||
|
|
||||||
function OptionsMenu::populateGamepadControls(%this)
|
|
||||||
{
|
|
||||||
%this.populateKeybinds("gamepad", GamepadControlsList);
|
|
||||||
|
|
||||||
%this.syncGui();
|
|
||||||
|
|
||||||
GamepadControlsList.syncGui();
|
|
||||||
}
|
|
||||||
|
|
||||||
function OptionsMenu::populateKeybinds(%this, %devices, %controlsList)
|
|
||||||
{
|
|
||||||
%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);
|
|
||||||
|
|
||||||
echo("============================================");
|
|
||||||
|
|
||||||
for(%am = 0; %am < getFieldCount(%actionMapList); %am++)
|
|
||||||
{
|
|
||||||
%currentActionMap = getField(%actionMapList, %am);
|
|
||||||
|
|
||||||
//only add the group if we've got more than one group, otherwise it's obviously
|
|
||||||
//part of the single grouping
|
|
||||||
if(getFieldCount(%actionMapList) > 1)
|
|
||||||
{
|
|
||||||
%actionMapGroupEntry = addOptionGroup(%currentActionMap);
|
|
||||||
%controlsList.add(%actionMapGroupEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( %i = 0; %i < $RemapCount; %i++ )
|
|
||||||
{
|
|
||||||
%entryDevice = "";
|
|
||||||
//Check each field of %devices for device matching the remappable action
|
|
||||||
foreach$(%d in %devices){
|
|
||||||
if(%d $= $RemapDevice[%i]) {
|
|
||||||
%entryDevice = %d;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//If there was no match go to the next remappable action
|
|
||||||
if(%entryDevice $= "")
|
|
||||||
continue;
|
|
||||||
|
|
||||||
%actionMapName = $RemapActionMap[%i].humanReadableName $= "" ? $RemapActionMap[%i].getName() : $RemapActionMap[%i].humanReadableName;
|
|
||||||
|
|
||||||
if(%currentActionMap !$= %actionMapName)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
%keyMap = buildFullMapString( %i, $RemapActionMap[%i], %entryDevice );
|
|
||||||
|
|
||||||
%description = $RemapDescription[%i];
|
|
||||||
|
|
||||||
echo("Added ActionMap Entry: " @ %actionMapName @ " | " @ %entryDevice @ " | " @ %keymap @ " | " @ %description);
|
|
||||||
|
|
||||||
%remapEntry = addActionMapEntry(%actionMapName, %entryDevice, %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)
|
function tryCloseOptionsMenu(%val)
|
||||||
{
|
{
|
||||||
if(!%val)
|
if(!%val)
|
||||||
|
|
@ -723,8 +493,8 @@ function tryCloseOptionsMenu(%val)
|
||||||
if(%unappliedVideoChanges || %unappliedAudioChanges)
|
if(%unappliedVideoChanges || %unappliedAudioChanges)
|
||||||
{
|
{
|
||||||
MessageBoxOKCancel("Discard Changes?", "You have unapplied changes to your settings, do you wish to apply or discard them?",
|
MessageBoxOKCancel("Discard Changes?", "You have unapplied changes to your settings, do you wish to apply or discard them?",
|
||||||
"OptionsMenu.applyChangedOptions(); BaseUIBackOut(1);", "BaseUIBackOut(1);",
|
"OptionsMenu.applyChangedOptions(); BaseUIBackOut(1);", "BaseUIBackOut(1);",
|
||||||
"Apply", "Discard");
|
"Apply", "Discard");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -750,6 +520,7 @@ function OptionsMenu::applyChangedOptions(%this)
|
||||||
{
|
{
|
||||||
VideoSettingsList.applyChanges();
|
VideoSettingsList.applyChanges();
|
||||||
AudioSettingsList.applyChanges();
|
AudioSettingsList.applyChanges();
|
||||||
|
KBMControlsList.applyChanges(); //Saves settings and binds from GamepadControlsList as well -Skurps
|
||||||
|
|
||||||
//Process the audio channel tempvars to get their values
|
//Process the audio channel tempvars to get their values
|
||||||
//and then apply them to the actual pref variable, as well as the SFXChannelVolume
|
//and then apply them to the actual pref variable, as well as the SFXChannelVolume
|
||||||
|
|
@ -772,23 +543,6 @@ function OptionsMenu::applyChangedOptions(%this)
|
||||||
MessageBoxOK("Restart Required", "Some of your changes require the game to be restarted.");
|
MessageBoxOK("Restart Required", "Some of your changes require the game to be restarted.");
|
||||||
}
|
}
|
||||||
|
|
||||||
function doKeyRemap( %optionEntry )
|
|
||||||
{
|
|
||||||
%name = getField(%optionEntry.keymap,0);
|
|
||||||
|
|
||||||
RemapDlg-->OptRemapText.text = "Re-bind \"" @ %name @ "\" to..." ;
|
|
||||||
OptRemapInputCtrl.index = %optionEntry.remapIndex;
|
|
||||||
|
|
||||||
$remapListDevice = %optionEntry.device;
|
|
||||||
|
|
||||||
Canvas.pushDialog( RemapDlg );
|
|
||||||
}
|
|
||||||
|
|
||||||
function OptionsMenu::resetSettings(%this)
|
|
||||||
{
|
|
||||||
MessageBoxOKCancel("", "This will set the graphical settings back to the auto-detected defaults. Do you wish to continue?", "AutodetectGraphics();", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
// Option types
|
// Option types
|
||||||
function addOptionGroup(%displayName)
|
function addOptionGroup(%displayName)
|
||||||
|
|
@ -1028,12 +782,419 @@ function OptionsSliderEntrySlider::updateSliderValue(%this)
|
||||||
//update settings value here
|
//update settings value here
|
||||||
}
|
}
|
||||||
|
|
||||||
function OptionsMenuActionMapButton::onHighlighted(%this, %highlighted)
|
//==============================================================================
|
||||||
|
//
|
||||||
|
// Video List Functions
|
||||||
|
//
|
||||||
|
//==============================================================================
|
||||||
|
//==============================================================================
|
||||||
|
// This function utilizes the VideoSettingsGroup SimGroup to populate options.
|
||||||
|
// The object is defined in core/rendering/scripts/graphicsOptions.tscript
|
||||||
|
// A majority of the options are statically defined, but some are dynamically populated
|
||||||
|
// on refresh, like the display device or available resolution options.
|
||||||
|
// Once populated, we loop over the simgroup structure to populate our option entry
|
||||||
|
// rows in the options menu itself.
|
||||||
|
function OptionsMenu::populateVideoSettings(%this)
|
||||||
{
|
{
|
||||||
%container = %this.getParent();
|
VideoSettingsList.clear();
|
||||||
%container-->actionName.profile = %highlighted ? MenuSubHeaderTextHighlighted : MenuSubHeaderText;
|
|
||||||
|
|
||||||
OptionsMenuSettingsScroll.scrollToObject(%container);
|
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::resetSettings(%this)
|
||||||
|
{
|
||||||
|
MessageBoxOKCancel("", "This will set the graphical settings back to the auto-detected defaults. Do you wish to continue?", "AutodetectGraphics();", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
//
|
||||||
|
// Audio List Functions
|
||||||
|
//
|
||||||
|
//==============================================================================
|
||||||
|
//==============================================================================
|
||||||
|
// This function utilizes the AudioSettingsGroup SimGroup to populate options.
|
||||||
|
// The object is defined in core/sfx/scripts/audioOptions.tscript
|
||||||
|
// Similar to the video options, it can be a mix of static and dynamically populated
|
||||||
|
// option entries, which we then iterate over and populate the entry rows for the menu
|
||||||
|
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"));
|
||||||
|
|
||||||
|
//Now we'll populate the sliders for the audio channels.
|
||||||
|
//The defaults of these are defined in core/sfx/scripts/audio.tscript
|
||||||
|
//These define the MasterVolume channel, as well as several other common defualt ones
|
||||||
|
//Because it's a variable list, this can be expanded by modules by just upping $AudioChannelCount
|
||||||
|
//and then defining the $AudioChannelName[x] with the displayed name and
|
||||||
|
//and the $AudioChannels[x] variable with the SFXSource object defined to it for the given channel
|
||||||
|
AudioSettingsList.add(addOptionSlider("Master Volume", "", "$pref::SFX::masterVolume", 0, 1, 10));
|
||||||
|
|
||||||
|
//We init to 1, because 0 is the reserved for the masterVolume in practice
|
||||||
|
for(%i=1; %i < $AudioChannelCount; %i++)
|
||||||
|
{
|
||||||
|
AudioSettingsList.add(addOptionSlider($AudioChannelsName[%i] @ " Volume", "", "$pref::SFX::channelVolume" @ %i, 0, 1, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
//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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
//
|
||||||
|
// Keyboard & Mouse, Controller List Functions
|
||||||
|
//
|
||||||
|
//==============================================================================
|
||||||
|
function KBMControlsList::applyChanges(%this){ //Skurps
|
||||||
|
|
||||||
|
//Save mouse sensitivity
|
||||||
|
$pref::Input::LinkMouseSensitivity = $pref::Input::LinkMouseSensitivity_tempVar;
|
||||||
|
|
||||||
|
if(!$RemapDirty)
|
||||||
|
return;
|
||||||
|
|
||||||
|
%prefPath = getPrefpath();
|
||||||
|
%filePath = (%prefPath @ "/keybinds." @ $TorqueScriptFileExtension);
|
||||||
|
%fileWrite = new fileObject(){};
|
||||||
|
|
||||||
|
// Delete the file first if it exists
|
||||||
|
if (isFile(%filePath))
|
||||||
|
fileDelete( %filepath );
|
||||||
|
|
||||||
|
// Open / create the custom binds file
|
||||||
|
%fileWrite.openForWrite(%filePath);
|
||||||
|
|
||||||
|
// Iterate through the remapabble bindings and write them to the keyBinds file
|
||||||
|
for(%i = 0; %i < $RemapCount; %i++){
|
||||||
|
%actionMap = $RemapActionMap[%i];
|
||||||
|
%cmd = $RemapCmd[%i];
|
||||||
|
%binding = %actionMap.getBinding(%cmd);
|
||||||
|
|
||||||
|
%device = getField(%binding, 0);
|
||||||
|
%action = getField(%binding, 1);
|
||||||
|
|
||||||
|
// saves a restoreRemap call to each line of keyBinds file instead of the bind command in order to leverage functions for
|
||||||
|
// removing conflicts and duplicates
|
||||||
|
if (%device !$= "" && %action !$= ""){
|
||||||
|
%line = "restoreRemap(" @ %device @ ", " @ %actionMap @ ", \"" @ %action @ "\", \"" @ %cmd @ "\");";
|
||||||
|
%fileWrite.writeLine(%line);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
%fileWrite.close();
|
||||||
|
%fileWrite.delete();
|
||||||
|
$RemapDirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// restoreRemap() is called from user custom keybinds file which is generated by KBMControlsList::applyChanges() -Skurps
|
||||||
|
function restoreRemap(%device, %actionMap, %action, %cmd){
|
||||||
|
// Make sure no other "action" (key / button press) is bound to this command on this actionMap (from remapDlg.tscript)
|
||||||
|
unbindExtraActions( %cmd, %actionMap, %device, 0 );
|
||||||
|
unbindExtraActions( %cmd, %actionMap, %device, 1 );
|
||||||
|
%actionMap.bind( %device, %action, %cmd );
|
||||||
|
}
|
||||||
|
|
||||||
|
function OptionsMenu::populateKBMControls(%this){
|
||||||
|
|
||||||
|
%this.populateKeybinds("keyboard", KBMControlsList); // includes remappable actions declared with "mouse" as the device as well
|
||||||
|
%this.syncGui();
|
||||||
|
|
||||||
|
KBMControlsList.syncGui();
|
||||||
|
}
|
||||||
|
|
||||||
|
function OptionsMenu::populateGamepadControls(%this){
|
||||||
|
%this.populateKeybinds("gamepad", GamepadControlsList);
|
||||||
|
|
||||||
|
%this.syncGui();
|
||||||
|
|
||||||
|
GamepadControlsList.syncGui();
|
||||||
|
}
|
||||||
|
|
||||||
|
function OptionsMenu::populateKeybinds(%this,%device, %controlsList) {
|
||||||
|
%controlsList.clear();
|
||||||
|
|
||||||
|
if (%device $= "keyboard") {
|
||||||
|
%controlsList.add(addOptionGroup("Mouse Options")); //Skurps
|
||||||
|
%controlsList.add(addOptionSlider("Mouse Sensitivity", "", "$pref::Input::LinkMouseSensitivity", 0, 1, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
//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);
|
||||||
|
|
||||||
|
echo("============================================");
|
||||||
|
|
||||||
|
for(%am = 0; %am < getFieldCount(%actionMapList); %am++)
|
||||||
|
{
|
||||||
|
%currentActionMap = getField(%actionMapList, %am);
|
||||||
|
|
||||||
|
//only add the group if we've got more than one group, otherwise it's obviously
|
||||||
|
//part of the single grouping
|
||||||
|
if(getFieldCount(%actionMapList) > 1)
|
||||||
|
{
|
||||||
|
%actionMapGroupEntry = addOptionGroup(%currentActionMap);
|
||||||
|
%controlsList.add(%actionMapGroupEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( %i = 0; %i < $RemapCount; %i++ )
|
||||||
|
{
|
||||||
|
//If there was no match go to the next remappable action
|
||||||
|
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];
|
||||||
|
|
||||||
|
echo("Added ActionMap Entry: " @ %actionMapName @ " | " @ %device @ " | " @ %keymap @ " | " @ %description);
|
||||||
|
|
||||||
|
%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 buildFullMapString( %index, %actionMap, %deviceType )
|
||||||
|
{
|
||||||
|
%name = $RemapName[%index];
|
||||||
|
%cmd = $RemapCmd[%index];
|
||||||
|
|
||||||
|
%temp = %actionMap.getBinding( %cmd );
|
||||||
|
if ( %temp $= "" )
|
||||||
|
return %name TAB "";
|
||||||
|
|
||||||
|
%mapString = "";
|
||||||
|
|
||||||
|
%count = getFieldCount( %temp );
|
||||||
|
for ( %i = 0; %i < %count; %i += 2 )
|
||||||
|
{
|
||||||
|
if ( %mapString !$= "" )
|
||||||
|
continue;
|
||||||
|
//%mapString = %mapString @ ", ";
|
||||||
|
|
||||||
|
%device = getField( %temp, %i + 0 );
|
||||||
|
%object = getField( %temp, %i + 1 );
|
||||||
|
|
||||||
|
if (startsWith(%device,"mouse"))
|
||||||
|
%deviceType = "mouse";
|
||||||
|
|
||||||
|
if(%deviceType !$= "" && !startsWith(%device, %deviceType))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
%mapString = %mapString @ getMapDisplayName( %device, %object );
|
||||||
|
}
|
||||||
|
|
||||||
|
return %name TAB %mapString;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also used by remapDlg.tscript
|
||||||
|
function getMapDisplayName( %device, %action )
|
||||||
|
{
|
||||||
|
if ( %device $= "keyboard" )
|
||||||
|
return( %action );
|
||||||
|
else if ( strstr( %device, "mouse" ) != -1 )
|
||||||
|
{
|
||||||
|
// Substitute "mouse" for "button" in the action string:
|
||||||
|
%pos = strstr( %action, "button" );
|
||||||
|
if ( %pos != -1 )
|
||||||
|
{
|
||||||
|
%mods = getSubStr( %action, 0, %pos );
|
||||||
|
%object = getSubStr( %action, %pos, 1000 );
|
||||||
|
%instance = getSubStr( %object, strlen( "button" ), 1000 );
|
||||||
|
return( %mods @ "mouse" @ ( %instance + 1 ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error( "Mouse input object other than button passed to getDisplayMapName!" );
|
||||||
|
}
|
||||||
|
else if ( strstr( %device, "joystick" ) != -1 )
|
||||||
|
{
|
||||||
|
// Substitute "joystick" for "button" in the action string:
|
||||||
|
%pos = strstr( %action, "button" );
|
||||||
|
if ( %pos != -1 )
|
||||||
|
{
|
||||||
|
%mods = getSubStr( %action, 0, %pos );
|
||||||
|
%object = getSubStr( %action, %pos, 1000 );
|
||||||
|
%instance = getSubStr( %object, strlen( "button" ), 1000 );
|
||||||
|
return( %mods @ "joystick" @ ( %instance + 1 ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
%pos = strstr( %action, "pov" );
|
||||||
|
if ( %pos != -1 )
|
||||||
|
{
|
||||||
|
%wordCount = getWordCount( %action );
|
||||||
|
%mods = %wordCount > 1 ? getWords( %action, 0, %wordCount - 2 ) @ " " : "";
|
||||||
|
%object = getWord( %action, %wordCount - 1 );
|
||||||
|
switch$ ( %object )
|
||||||
|
{
|
||||||
|
case "upov": %object = "POV1 up";
|
||||||
|
case "dpov": %object = "POV1 down";
|
||||||
|
case "lpov": %object = "POV1 left";
|
||||||
|
case "rpov": %object = "POV1 right";
|
||||||
|
case "upov2": %object = "POV2 up";
|
||||||
|
case "dpov2": %object = "POV2 down";
|
||||||
|
case "lpov2": %object = "POV2 left";
|
||||||
|
case "rpov2": %object = "POV2 right";
|
||||||
|
default: %object = "";
|
||||||
|
}
|
||||||
|
return( %mods @ %object );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error( "Unsupported Joystick input object passed to getDisplayMapName!" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( strstr( %device, "gamepad" ) != -1 )
|
||||||
|
{
|
||||||
|
return %action;
|
||||||
|
|
||||||
|
%pos = strstr( %action, "button" );
|
||||||
|
if ( %pos != -1 )
|
||||||
|
{
|
||||||
|
%mods = getSubStr( %action, 0, %pos );
|
||||||
|
%object = getSubStr( %action, %pos, 1000 );
|
||||||
|
%instance = getSubStr( %object, strlen( "button" ), 1000 );
|
||||||
|
return( %mods @ "joystick" @ ( %instance + 1 ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
%pos = strstr( %action, "thumb" );
|
||||||
|
if ( %pos != -1 )
|
||||||
|
{
|
||||||
|
//%instance = getSubStr( %action, strlen( "thumb" ), 1000 );
|
||||||
|
//return( "thumb" @ ( %instance + 1 ) );
|
||||||
|
return %action;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error( "Unsupported gamepad input object passed to getDisplayMapName!" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return( "" );
|
||||||
}
|
}
|
||||||
|
|
||||||
function addActionMapEntry(%actionMap, %device, %keyMap, %index, %description)
|
function addActionMapEntry(%actionMap, %device, %keyMap, %index, %description)
|
||||||
|
|
@ -1084,8 +1245,7 @@ function addActionMapEntry(%actionMap, %device, %keyMap, %index, %description)
|
||||||
};
|
};
|
||||||
|
|
||||||
%buttonContainer = %entry.findObjectByInternalName("valuesContainer");
|
%buttonContainer = %entry.findObjectByInternalName("valuesContainer");
|
||||||
if ($reportKeymapping)
|
echo("Keymap: " @ %keymap @ " | Keymap word count: " @ getWordCount(getField(%keyMap, 1)));
|
||||||
echo("Keymap: " @ %keymap @ " | Keymap word count: " @ getWordCount(getField(%keyMap, 1)));
|
|
||||||
if(getWordCount(getField(%keyMap, 1)) == 2)
|
if(getWordCount(getField(%keyMap, 1)) == 2)
|
||||||
{
|
{
|
||||||
%modifierBtn = new GuiIconButtonCtrl() {
|
%modifierBtn = new GuiIconButtonCtrl() {
|
||||||
|
|
@ -1142,3 +1302,23 @@ function addActionMapEntry(%actionMap, %device, %keyMap, %index, %description)
|
||||||
|
|
||||||
return %entry;
|
return %entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function OptionsMenuActionMapButton::onHighlighted(%this, %highlighted)
|
||||||
|
{
|
||||||
|
%container = %this.getParent();
|
||||||
|
%container-->actionName.profile = %highlighted ? MenuSubHeaderTextHighlighted : MenuSubHeaderText;
|
||||||
|
|
||||||
|
OptionsMenuSettingsScroll.scrollToObject(%container);
|
||||||
|
}
|
||||||
|
|
||||||
|
function doKeyRemap( %optionEntry )
|
||||||
|
{
|
||||||
|
%name = getField(%optionEntry.keymap,0);
|
||||||
|
|
||||||
|
RemapDlg-->OptRemapText.text = "Re-bind \"" @ %name @ "\" to..." ;
|
||||||
|
OptRemapInputCtrl.index = %optionEntry.remapIndex;
|
||||||
|
|
||||||
|
$remapListDevice = %optionEntry.device;
|
||||||
|
|
||||||
|
Canvas.pushDialog( RemapDlg );
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue