//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"; function OptionsMenu::onAdd(%this) { if(!isObject(%this.optionsCategories)) { %this.optionsCategories = new ArrayObject(); } if(!isObject(%this.unappliedChanges)) { %this.unappliedChanges = new ArrayObject(OptionsMenuUnappliedChanges); } %this.currentCategory = ""; addOptionsMenuCategory("Display", "populateDisplaySettingsList();"); addOptionsMenuCategory("Graphics", "populateGraphicsSettingsList();"); addOptionsMenuCategory("Audio", "populateAudioSettingsList();"); addOptionsMenuCategory("Keyboard & Mouse", "populateKeyboardMouseSettingsList();"); addOptionsMenuCategory("Gamepad", "populateGamepadSettingsList();"); callOnModules("populateOptionsMenuCategories", "Game"); } function OptionsMenuSettingsList::onAdd(%this) { } function OptionsMenuSettingsList::getOptionsList(%this, %index) { } function OptionsMenu::onWake(%this) { OptionsMenuCategoryList.clear(); for(%i=0; %i < %this.optionsCategories.count(); %i++) { %catName = %this.optionsCategories.getKey(%i); %callback = %this.optionsCategories.getValue(%i); %newCatButton = new GuiButtonCtrl() { text = %catName; groupNum = "-1"; buttonType = "PushButton"; useMouseEvents = "0"; position = "0 180"; extent = "248 35"; minExtent = "8 2"; horizSizing = "right"; vertSizing = "bottom"; profile = "GuiMenuButtonProfile"; visible = "1"; active = "1"; command = %callback; tooltipProfile = "GuiToolTipProfile"; hovertime = "1000"; isContainer = "0"; canSave = "1"; canSaveDynamicFields = "0"; }; OptionsMenuCategoryList.add(%newCatButton); } %this.unappliedChanges.empty(); MainMenuButtonList.hidden = true; OptionsMenuCategoryList.setAsActiveMenuList(); OptionsButtonHolder.setActive(); OptionsMenuInputHandler.setFirstResponder(); } function OptionsButtonHolder::onWake(%this) { %this-->resetButton.set("btn_back", "R", "Reset", "OptionsMenu.resetToDefaults();"); %this-->selectButton.set("btn_a", "Return", "Select", "OptionsMenu.select();", true); %this-->backButton.set("btn_b", "Escape", "Back", "OptionsMenu.backOut();"); //OptionsMenuCategoryList.getObject(0).performClick(); } function OptionsMenu::select(%this) { if(OptionsMenuCategoryList.isActiveMenuList()) { OptionsMenuSettingsList.setAsActiveMenuList(); %this.updateSelectButton(); } } function OptionsMenu::updateSelectButton(%this) { if(OptionsMenuCategoryList.isActiveMenuList()) { %this-->selectButton.setHidden(false); } else if(OptionsMenuSettingsList.isActiveMenuList()) { %this-->selectButton.setHidden(true); } } 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.humanReadableName $= "" ? %actionMap.getName() : %actionMap.humanReadableName; 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); } } } 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(); //Now we can back out of the options menu OptionsMenu.doOptionsMenuBackOut(); } function OptionsMenu::resetToDefaults(%this) { MessageBoxOKCancel("", "This will set the graphical settings back to the auto-detected defaults. Do you wish to continue?", "AutodetectGraphics();", ""); } function OptionsMenu::refresh(%this) { %cat = %this.currentCategory; if(%this.currentCategory !$= "") { if(!isInt(%this.currentCategory)) { %this.currentCategory = getOptionsCategoryIndexByName(%this.currentCategory); } if(%this.currentCategory == -1) return; %category = %this.optionsCategories.getKey(%this.currentCategory); %command = %this.optionsCategories.getValue(%this.currentCategory); eval(%command); } } function OptionsMenu::getOptionVariableValue(%this, %variableName) { %unappliedPrefIndex = %this.unappliedChanges.getIndexFromKey(%variableName); if(%unappliedPrefIndex != -1) { %value = %this.unappliedChanges.getValue(%unappliedPrefIndex); return strreplace(%value, "\"", ""); } %sanitizedVar = strReplace(%variableName, "[", ""); %sanitizedVar = strReplace(%sanitizedVar, "]", ""); %sanitizedVar = strReplace(%sanitizedVar, ",", "_"); return getVariable(%sanitizedVar); } function OptionsMenuSelectButton::onVisible(%this, %state) { //We're sorta cheating here. //This button should only be displayed when we're in the categories list //so whenever the status changes, such as automatically refreshing due to //navigation events, we'll just do a quick check to ensure we're //in the right visibility mode if(%state && OptionsMenuSettingsList.isActiveMenuList()) { %this.setHidden(true); } } // // // function populateDisplaySettingsList() { OptionsMenuSettingsList.clear(); OptionsMenu.currentCategory = "Display"; OptionName.setText(""); OptionDescription.setText(""); %apiList = ""; %apiCount = GFXInit::getAdapterCount(); %apiIdx = 0; for(%i=0; %i < %apiCount; %i++) { %api = GFXInit::getAdapterType(%i); if(%api !$= "NullDevice") { if(%apiIdx==0) %apiList = %api; else %apiList = %apiList TAB %api; %apiIdx++; } } trim(%apiList); %displayDevice = OptionsMenu.getOptionVariableValue("$pref::Video::displayDevice"); if(%displayDevice $= "") %displayDevice = getDisplayDeviceType(); OptionsMenuSettingsList.addOptionRow("Display API", "$pref::Video::displayDevice", %apiList, false, "", true, "The display API used for rendering.", %displayDevice); %numDevices = Canvas.getMonitorCount(); %devicesList = ""; for(%i = 0; %i < %numDevices; %i++) { %device = (%i+1) @ " - " @ Canvas.getMonitorName(%i); if(%i==0) %devicesList = %device; else %devicesList = %devicesList @ "\t" @ %device; } %selectedDevice = getField(%devicesList, $pref::Video::deviceId); OptionsMenuSettingsList.addOptionRow("Display Device", "$pref::Video::deviceId", %devicesList, false, "", true, "The display devices the window should be on.", %selectedDevice); if (%numDevices > 1) OptionsMenuSettingsList.setRowEnabled(1, true); else OptionsMenuSettingsList.setRowEnabled(1, false); %mode = OptionsMenu.getOptionVariableValue("$pref::Video::deviceMode"); if(isInt(%mode)) %mode = getField($Video::ModeTags, $pref::Video::deviceMode); OptionsMenuSettingsList.addOptionRow("Window Mode", "$pref::Video::deviceMode", $Video::ModeTags, false, "", true, "", %mode); if(%mode !$= "Borderless") { %resolutionList = getScreenResolutionList($pref::Video::deviceId, $pref::Video::deviceMode); %resolution = OptionsMenu.getOptionVariableValue("$pref::Video::Resolution"); if(%resolution $= "") %resolution = $pref::Video::mode; %resolution = _makePrettyResString(%resolution); OptionsMenuSettingsList.addOptionRow("Resolution", "$pref::Video::Resolution", %resolutionList, false, "", true, "Resolution of the game window", %resolution); } OptionsMenuSettingsList.addOptionBoolRow("VSync", "$pref::Video::disableVerticalSync", $yesNoList, false, "", true, ""); %refreshList = getScreenRefreshList($pref::Video::mode); OptionsMenuSettingsList.addOptionRow("Refresh Rate", "$pref::Video::RefreshRate", %refreshList, false, "", true, "", OptionsMenu.getOptionVariableValue("$pref::Video::RefreshRate")); //move to gameplay tab //OptionsMenuSettingsList.addSliderRow("Field of View", "", 75, 5, "65 100", ""); //OptionsMenuSettingsList.addSliderRow("Brightness", "", 0.5, 0.1, "0 1", ""); //OptionsMenuSettingsList.addSliderRow("Contrast", "", 0.5, 0.1, "0 1", ""); } // // // function populateGraphicsSettingsList() { OptionsMenuSettingsList.clear(); OptionsMenu.currentCategory = "Graphics"; OptionName.setText(""); OptionDescription.setText(""); %yesNoList = "No\tYes"; %onOffList = "Off\tOn"; %anisoFilter = "Off\t4\t8\t16"; %aaFilter = "Off\t1\t2\t4"; OptionsMenuSettingsList.addOptionQualityLevelRow("Lighting Quality", "$pref::Graphics::LightingQuality", LightingQualityList, false, "", true, "Amount and drawdistance of local lights"); OptionsMenuSettingsList.addOptionQualityLevelRow("Shadow Quality", "$pref::Graphics::ShadowQuality", ShadowQualityList, false, "", true, "Shadow revolution quality"); %shadowQuality = OptionsMenu.getOptionVariableValue("$pref::Graphics::ShadowQuality"); if(%shadowQuality !$= "None") { OptionsMenuSettingsList.addOptionQualityLevelRow("Soft Shadow Quality", "$pref::Graphics::SoftShadowQuality", SoftShadowList, false, "", true, "Amount of softening applied to shadowmaps"); } OptionsMenuSettingsList.addOptionQualityLevelRow("Mesh Quality", "$pref::Graphics::MeshQuality", MeshQualityGroup, false, "", true, "Fidelity of rendering of mesh objects"); OptionsMenuSettingsList.addOptionQualityLevelRow("Object Draw Distance", "$pref::Graphics::ObjectDrawDistance", MeshDrawDistQualityGroup, false, "", true, "Dictates if and when static objects fade out in the distance"); OptionsMenuSettingsList.addOptionQualityLevelRow("Texture Quality", "$pref::Graphics::TextureQuality", TextureQualityGroup, false, "", true, "Fidelity of textures"); OptionsMenuSettingsList.addOptionQualityLevelRow("Terrain Quality", "$pref::Graphics::TerrainQuality", TerrainQualityGroup, false, "", true, "Quality level of terrain objects"); OptionsMenuSettingsList.addOptionQualityLevelRow("Decal Lifetime", "$pref::Graphics::DecalLifetime", DecalLifetimeGroup, false, "", true, "How long decals are rendered"); OptionsMenuSettingsList.addOptionQualityLevelRow("Ground Cover Density", "$pref::Graphics::GroundCoverDensity", GroundCoverDensityGroup, false, "", true, "Density of ground cover items, such as grass"); OptionsMenuSettingsList.addOptionQualityLevelRow("Shader Quality", "$pref::Graphics::ShaderQuality", ShaderQualityGroup, false, "", true, "Dictates the overall shader quality level, adjusting what features are enabled."); OptionsMenuSettingsList.addOptionRow("Anisotropic Filtering", "$pref::Video::defaultAnisotropy", %anisoFilter, false, "", true, "Amount of Anisotropic Filtering on textures, which dictates their sharpness at a distance"); OptionsMenuSettingsList.addOptionRow("Anti-Aliasing", "$pref::Video::AA", %aaFilter, false, "", true, "Amount of Post-Processing Anti-Aliasing applied to rendering"); OptionsMenuSettingsList.addOptionBoolRow("Parallax", "$pref::Video::disableParallaxMapping", %onOffList, false, "", true, "Whether the surface parallax shader effect is enabled"); OptionsMenuSettingsList.addOptionBoolRow("Water Reflections", "$pref::Water::disableTrueReflections", %onOffList, false, "", true, "Whether water reflections are enabled"); OptionsMenuSettingsList.addOptionBoolRow("SSAO", "$pref::PostFX::EnableSSAO", %onOffList, false, "", true, "Whether Screen-Space Ambient Occlusion is enabled"); OptionsMenuSettingsList.addOptionBoolRow("Depth of Field", "$pref::PostFX::EnableDOF", %onOffList, false, "", true, "Whether the Depth of Field effect is enabled"); OptionsMenuSettingsList.addOptionBoolRow("Vignette", "$pref::PostFX::EnableVignette", %onOffList, false, "", true, "Whether the vignette effect is enabled"); OptionsMenuSettingsList.addOptionBoolRow("Light Rays", "$pref::PostFX::EnableLightRays", %onOffList, false, "", true, "Whether the light rays effect is enabled"); } function updateGraphicsSettings() { if($pref::Graphics::LightingQuality !$= getCurrentQualityLevel(LightingQualityList)) LightingQualityList.applySetting($pref::Graphics::LightingQuality); if($pref::Graphics::ShadowQuality !$= getCurrentQualityLevel(ShadowQualityList)) ShadowQualityList.applySetting($pref::Graphics::ShadowQuality); if($pref::Graphics::SoftShadowQuality !$= getCurrentQualityLevel(SoftShadowList)) SoftShadowList.applySetting($pref::Graphics::SoftShadowQuality); if($pref::Graphics::MeshQuality !$= getCurrentQualityLevel(MeshQualityGroup)) MeshQualityGroup.applySetting($pref::Graphics::MeshQuality); if($pref::Graphics::ObjectDrawDistance !$= getCurrentQualityLevel(MeshDrawDistQualityGroup)) MeshDrawDistQualityGroup.applySetting($pref::Graphics::ObjectDrawDistance); if($pref::Graphics::TextureQuality !$= getCurrentQualityLevel(TextureQualityGroup)) { TextureQualityGroup.applySetting($pref::Graphics::TextureQuality); reloadTextures(); } if($pref::Graphics::TerrainQuality !$= getCurrentQualityLevel(TerrainQualityGroup)) TerrainQualityGroup.applySetting($pref::Graphics::TerrainQuality); if($pref::Graphics::DecalLifetime !$= getCurrentQualityLevel(DecalLifetimeGroup)) DecalLifetimeGroup.applySetting($pref::Graphics::DecalLifetime); if($pref::Graphics::GroundCoverDensity !$= getCurrentQualityLevel(GroundCoverDensityGroup)) GroundCoverDensityGroup.applySetting($pref::Graphics::GroundCoverDensity); } function updateDisplaySettings() { //Update the display settings now %deviceName = getDisplayDeviceName(); %newDeviceID = getWord(%deviceName, 0) - 1; if(!isInt($pref::Video::deviceMode)) { //probably saved out as the mode name, so just translate it back for(%i=0; %i < getFieldCount($Video::ModeTags); %i++) { if(getField($Video::ModeTags, %i) $= $pref::Video::deviceMode) { $pref::Video::deviceMode = %i; break; } } } %deviceModeName = getField($Video::ModeTags, $pref::Video::deviceMode); %newDeviceMode = 0; foreach$(%modeName in $Video::ModeTags) { if (%deviceModeName $= %modeName) break; else %newDeviceMode++; } if($pref::Video::deviceMode == $Video::ModeBorderless) { //if we're changing to borderless, we swap to the full resolution of the desktop $pref::Video::mode = Canvas.getBestCanvasRes($pref::Video::deviceId, $pref::Video::deviceMode); $pref::Video::Resolution = $pref::Video::mode.x SPC $pref::Video::mode.y; } %newRes = $pref::Video::Resolution; %newBpp = 32; // ... its not 1997 anymore. %newFullScreen = %deviceModeName $= "Fullscreen" ? true : false; %newRefresh = $pref::Video::RefreshRate; %newVsync = !$pref::Video::disableVerticalSync; %newFSAA = $pref::Video::AA; // Build the final mode string. %newMode = $pref::Video::Resolution SPC %newFullScreen SPC %newBpp SPC %newRefresh SPC %newFSAA; // Change the video mode. if ( %newMode !$= $pref::Video::mode || %newDeviceID != $pref::Video::deviceId || %newVsync != $pref::Video::disableVerticalSync || %newDeviceMode != $pref::Video::deviceMode) { //****Edge Case Hack // If we're in fullscreen mode and switching to a different monitor at the // same resolution and maintaining fullscreen, GFX...WindowTarget::resetMode() // will early-out because there is no "mode change" and the monitor change // will not get applied. Instead of modifying platform code, we're going to // move onto the new monitor in borderless and immediately switch to FS. if (%newFullScreen && $pref::Video::FullScreen && ($pref::Video::Resolution $= %newRes) && ($pref::Video::deviceId != %newDeviceID)) { $pref::Video::deviceId = %newDeviceID; $pref::Video::deviceMode = $Video::ModeBorderless; %tmpModeStr = Canvas.getMonitorMode(%newDeviceID, 0); Canvas.setVideoMode(%tmpModeStr.x, %tmpModeStr.y, false, 32, getWord(%tmpModeStr, $WORD::REFRESH), %newFSAA); } $pref::Video::mode = %newMode; $pref::Video::disableVerticalSync = %newVsync; $pref::Video::deviceId = %newDeviceID; $pref::Video::deviceMode = %newDeviceMode; $pref::Video::Resolution = %newRes; $pref::Video::FullScreen = %newFullScreen; $pref::Video::RefreshRate = %newRefresh; $pref::Video::AA = %newFSAA; configureCanvas(); } } function updatePostFXSettings() { PostFXManager.settingsEffectSetEnabled(SSAOPostFx, $pref::PostFX::EnableSSAO); PostFXManager.settingsEffectSetEnabled(DepthOfFieldPostFX, $pref::PostFX::EnableDOF); PostFXManager.settingsEffectSetEnabled(LightRayPostFX, $pref::PostFX::EnableLightRays); PostFXManager.settingsEffectSetEnabled(vignettePostFX, $pref::PostFX::EnableVignette); } // // // function populateAudioSettingsList() { OptionsMenuSettingsList.clear(); OptionsMenu.currentCategory = "Audio"; OptionName.setText(""); OptionDescription.setText(""); %buffer = sfxGetAvailableDevices(); %count = getRecordCount( %buffer ); %audioDriverList = ""; %audioProviderList = ""; %audioDeviceList = ""; $currentAudioProvider = $currentAudioProvider $= "" ? $pref::SFX::provider : $currentAudioProvider; for(%i = 0; %i < %count; %i++) { %record = getRecord(%buffer, %i); %provider = getField(%record, 0); %device = getField(%record, 1); //When the client is actually running, we don't care about null audo devices if(%provider $= "null") continue; if(%audioProviderList $= "") %audioProviderList = %provider; else %audioProviderList = %audioProviderList @ "\t" @ %provider; if(%provider $= $currentAudioProvider) { if(%audioDeviceList $= "") %audioDeviceList = %device; else %audioDeviceList = %audioDeviceList @ "\t" @ %device; } } OptionsMenuSettingsList.addOptionRow("Audio Provider", "$pref::SFX::AudioProvider", %audioProviderList, false, "audioProviderChanged", true, ""); OptionsMenuSettingsList.addOptionRow("Audio Device", "$pref::SFX::device", %audioDeviceList, false, "", true); OptionsMenuSettingsList.addSliderRow("Master Volume", "$pref::SFX::masterVolume", 0.1, "0 1", ""); OptionsMenuSettingsList.addSliderRow("GUI Volume", "$pref::SFX::channelVolume[" @ $GuiAudioType @ "]", 0.1, "0 1", ""); OptionsMenuSettingsList.addSliderRow("Effects Volume", "$pref::SFX::channelVolume[" @ $SimAudioType @ "]", 0.1, "0 1", ""); OptionsMenuSettingsList.addSliderRow("Music Volume", "$pref::SFX::channelVolume[" @ $MusicAudioType @ "]", 0.1, "0 1", ""); } function audioProviderChanged() { //Get the option we have set for the provider %provider = OptionsMenuSettingsList.getCurrentOption(0); $currentAudioProvider = %provider; //And now refresh the list to get the correct devices populateAudioSettingsList(); } function updateAudioSettings() { //$pref::SFX::masterVolume = OptionsMenuSettingsList.getValue(2); sfxSetMasterVolume( $pref::SFX::masterVolume ); //$pref::SFX::channelVolume[ $GuiAudioType ] = OptionsMenuSettingsList.getValue(3); //$pref::SFX::channelVolume[ $SimAudioType ] = OptionsMenuSettingsList.getValue(4); //$pref::SFX::channelVolume[ $MusicAudioType ] = OptionsMenuSettingsList.getValue(5); sfxSetChannelVolume( $GuiAudioType, $pref::SFX::channelVolume[ $GuiAudioType ] ); sfxSetChannelVolume( $SimAudioType, $pref::SFX::channelVolume[ $SimAudioType ] ); sfxSetChannelVolume( $MusicAudioType, $pref::SFX::channelVolume[ $MusicAudioType ] ); //$pref::SFX::provider = OptionsMenuSettingsList.getCurrentOption(0); //$pref::SFX::device = OptionsMenuSettingsList.getCurrentOption(1); if ( !sfxCreateDevice( $pref::SFX::provider, $pref::SFX::device, $pref::SFX::useHardware, -1 ) ) error( "Unable to create SFX device: " @ $pref::SFX::provider SPC $pref::SFX::device SPC $pref::SFX::useHardware ); if( !isObject( $AudioTestHandle ) ) { sfxPlay(menuButtonPressed); } } // // // function populateKeyboardMouseSettingsList() { OptionsMenuSettingsList.clear(); OptionsMenu.currentCategory = "Keyboard & Mouse"; OptionName.setText(""); OptionDescription.setText(""); $remapListDevice = "keyboard"; fillRemapList(); //OptionsMenuSettingsList.refresh(); } function populateGamepadSettingsList() { OptionsMenuSettingsList.clear(); OptionsMenu.currentCategory = "Gamepad"; OptionName.setText(""); OptionDescription.setText(""); $remapListDevice = "gamepad"; fillRemapList(); OptionsMenuSettingsList.updateStack(); } // // // function OptionsMenuList::activateRow(%this) { OptionsMenuSettingsList.setFirstResponder(); } function OptionsMenu::backOut(%this) { if(OptionsMenuSettingsList.isActiveMenuList()) { OptionsMenuCategoryList.setAsActiveMenuList(); %this.updateSelectButton(); } else { if(%this.unappliedChanges.count() != 0) { MessageBoxOKCancel("Discard Changes?", "You have unapplied changes to your settings, do you wish to apply or discard them?", "OptionsMenu.apply();", "OptionsMenu.doOptionsMenuBackOut();", "Apply", "Discard"); } else { %this.doOptionsMenuBackOut(); } } } function OptionsMenu::doOptionsMenuBackOut(%this) { //save the settings and then back out if(OptionsMain.hidden == false) { //we're not in a specific menu, so we're actually exiting Canvas.popDialog(OptionsMenu); if(isObject(OptionsMenu.returnGui) && OptionsMenu.returnGui.isMethod("onReturnTo")) OptionsMenu.returnGui.onReturnTo(); } else { OptionsMain.hidden = false; ControlsMenu.hidden = true; GraphicsMenu.hidden = true; CameraMenu.hidden = true; AudioMenu.hidden = true; ScreenBrightnessMenu.hidden = true; } } function OptionsMenuSettingsList::setRowEnabled(%this, %row, %status) { %option = %this.getObject(%row); if(isObject(%option)) { %option.setEnabled(%status); } } function OptionsMenuSettingsList::addOptionRow(%this, %label, %targetPrefVar, %optionsList, %wrapOptions, %callback, %enabled, %description, %defaultValue) { if(%enabled $= "") %enabled = true; %optionsRowSize = 30; %optionColumnWidth = %this.extent.x * 0.3;//todo, calculate off longest option text? %option = new GuiGameSettingsCtrl() { class = "MenuOptionsButton"; profile = "GuiMenuButtonProfile"; horizSizing = "width"; vertSizing = "bottom"; position = "0 0"; extent = %this.extent.x SPC %optionsRowSize; columnSplit = %optionColumnWidth; useMouseEvents = true; previousBitmapAsset = "UI:previousOption_n_image"; nextBitmapAsset = "UI:nextOption_n_image"; }; %option.targetPrefVar = %targetPrefVar; //create a var-option association %option.setListSetting(%label, %optionsList, %wrapOptions, %callback, %enabled, %description, %defaultValue); %this.add(%option); } function OptionsMenuSettingsList::addOptionQualityLevelRow(%this, %label, %targetPrefVar, %qualityLevelList, %wrapOptions, %callback, %enabled, %description, %defaultValue) { if(%defaultValue $= "") { %unappliedPrefIndex = OptionsMenu.unappliedChanges.getIndexFromKey(%targetPrefVar); if(%unappliedPrefIndex != -1) { %value = OptionsMenu.unappliedChanges.getValue(%unappliedPrefIndex); %defaultValue = strreplace(%value, "\"", ""); } if(%defaultValue $= "") { %sanitizedVar = strReplace(%targetPrefVar, "[", ""); %sanitizedVar = strReplace(%sanitizedVar, "]", ""); %sanitizedVar = strReplace(%sanitizedVar, ",", "_"); %defaultValue = getVariable(%sanitizedVar); } if(%defaultValue $= "") %defaultValue = getCurrentQualityLevel(%qualityLevelList); } return %this.addOptionRow(%label, %targetPrefVar, getQualityLevels(%qualityLevelList), %wrapOptions, %callback, %enabled, %description, %defaultValue); } function OptionsMenuSettingsList::addOptionBoolRow(%this, %label, %targetPrefVar, %qualityLevelList, %wrapOptions, %callback, %enabled, %description, %defaultValue) { if(%defaultValue $= "") %defaultValue = OptionsMenu.getOptionVariableValue(%targetPrefVar); if(%qualityLevelList $= $yesNoList && isInt(%defaultValue)) { %defaultValue = convertBoolToYesNo(!%defaultValue); } else if(%qualityLevelList $= $onOffList && isInt(%defaultValue)) { %defaultValue = convertBoolToOnOff(!%defaultValue); } return %this.addOptionRow(%label, %targetPrefVar, %qualityLevelList, %wrapOptions, %callback, %enabled, %description, %defaultValue); } function OptionsMenuSettingsList::addSliderRow(%this, %label, %targetPrefVar, %increment, %range, %callback, %enabled, %description, %defaultValue) { if(%enabled $= "") %enabled = true; %optionsRowSize = 30; %optionColumnWidth = %this.extent.x - 450;//todo, calculate off longest option text? %option = new GuiGameSettingsCtrl() { class = "MenuOptionsButton"; profile = "GuiMenuButtonProfile"; horizSizing = "width"; vertSizing = "bottom"; position = "0 0"; extent = %this.extent.x SPC %optionsRowSize; columnSplit = %optionColumnWidth; useMouseEvents = true; }; %option.targetPrefVar = %targetPrefVar; //create a var-option association if(%defaultValue $= "") %defaultValue = OptionsMenu.getOptionVariableValue(%targetPrefVar); %option.setSliderSetting(%label, %defaultValue, %increment, %range, %callback, %enabled, %description); %this.add(%option); } function OptionsMenuSettingsList::addKeybindRow(%this, %label, %bitmapName, %callback, %enabled, %description) { if(%enabled $= "") %enabled = true; %optionsRowSize = 40; %optionColumnWidth = %this.extent.x - 450; %option = new GuiGameSettingsCtrl() { class = "MenuOptionsButton"; profile = "GuiMenuButtonProfile"; horizSizing = "width"; vertSizing = "bottom"; position = "0 0"; extent = %this.extent.x SPC %optionsRowSize; columnSplit = %optionColumnWidth; useMouseEvents = true; }; %option.setKeybindSetting(%label, %bitmapName, %callback, %enabled, %description); %this.add(%option); } // function OptionsMenuCategoryList::onNavigate(%this, %index) { OptionsMenu.currentCategory = %index; %this.getObject(%index).performClick(); } function convertOptionToBool(%val) { if(%val $= "yes" || %val $= "on") return 1; else return 0; } function convertBoolToYesNo(%val) { if(%val == 1) return "Yes"; else if(%val == 0) return "No"; return %val; } function convertBoolToOnOff(%val) { if(%val == 1) return "On"; else if(%val == 0) return "Off"; return %val; } function getDisplayDeviceName() { %numDevices = Canvas.getMonitorCount(); %devicesList = ""; for(%i = 0; %i < %numDevices; %i++) { %device = (%i+1) @ " - " @ Canvas.getMonitorName(%i); if(%i==0) %devicesList = %device; else %devicesList = %devicesList @ "\t" @ %device; } return getField(%devicesList, $pref::Video::deviceId); } // // // function MenuOptionsButton::onMouseEnter(%this) { OptionName.setText(%this.getLabel()); OptionDescription.setText(%this.getToolTip()); } function MenuOptionsButton::onMouseLeave(%this) { OptionName.setText(""); OptionDescription.setText(""); } function MenuOptionsButton::onChange(%this) { %optionMode = %this.getMode(); %optionName = %this.getLabel(); %tooltipText = %this.getTooltip(); %targetVar = %this.targetPrefVar; OptionName.setText(%optionName); OptionDescription.setText(%tooltipText); if(%optionMode == 0) { %currentValue = %this.getCurrentOption(); if(%currentValue !$= "") { if(%currentValue $= "yes" || %currentValue $= "on") %saveReadyValue = 1; else if(%currentValue $= "no" || %currentValue $= "off") %saveReadyValue = 0; else %saveReadyValue = %currentValue; %prefIndex = OptionsMenu.unappliedChanges.getIndexFromKey(%targetVar); if(%prefIndex == -1) { echo("Setting UnappliedChanges via add: key:" @ %targetVar @", value: " @ %saveReadyValue); OptionsMenu.unappliedChanges.add(%targetVar, "\"" @ %saveReadyValue @ "\"" ); } else OptionsMenu.unappliedChanges.setValue("\"" @ %saveReadyValue @ "\"", %prefIndex); } } else if(%optionMode == 1) { %currentValue = %this.getValue(); %prefIndex = OptionsMenu.unappliedChanges.getIndexFromKey(%targetVar); if(%prefIndex == -1) { echo("Setting UnappliedChanges via add: key:" @ %targetVar @", value: " @ %currentValue); OptionsMenu.unappliedChanges.add(%targetVar, "\"" @ %currentValue @ "\"" ); } else OptionsMenu.unappliedChanges.setValue("\"" @ %currentValue @ "\"", %prefIndex); } //Update the UI in case there's responsive logic OptionsMenu.schedule(32, "refresh"); } function OptionsMenu::onKeybindChanged(%this, %actionMap, %keybind) { %prefIndex = OptionsMenu.unappliedChanges.getIndexFromKey(%actionMap); if(%prefIndex == -1) OptionsMenu.unappliedChanges.add(%actionMap, %keybind); else OptionsMenu.unappliedChanges.setValue(%keybind, %prefIndex); } // // Indicates what category the options item should be added into // function addOptionsMenuCategory(%categoryName, %selectCallback) { //Don't add duplicates! %index = OptionsMenu.optionsCategories.getIndexFromKey(%categoryName); if(%index == -1) OptionsMenu.optionsCategories.add(%categoryName, %selectCallback); } function removeOptionsMenuCategory(%categoryName) { %index = OptionsMenu.optionsCategories.getIndexFromKey(%categoryName); if(%index != -1) OptionsMenu.optionsCategories.erase(%index); } function getOptionsCategoryIndexByName(%categoryName) { for(%i=0; %i < OptionsMenu.optionsCategories.count(); %i++) { if(OptionsMenu.optionsCategories.getKey(%i) $= %categoryName) return %i; } return -1; } function addListOption(%label, %description, %targetPrefVar, %optionsList, %wrapOptions, %callback, %enabled) { if(%wrapOptions $= "") %wrapOptions = false; if(%enabled $= "") %enabled = true; OptionsMenuSettingsList.addOptionRow(%label, %targetPrefVar, %optionsList, %wrapOptions, %callback, %enabled, %description, %targetPrefVar); } function addSliderOption(%label, %description, %targetPrefVar, %defaultValue, %increment, %range, %callback, %enabled) { if(%enabled $= "") %enabled = true; OptionsMenuSettingsList.addSliderRow(%label, %targetPrefVar, %defaultValue, %increment, %range, %callback, %enabled, %description); } function addKeybindOption(%label, %description, %bitmapName, %callback, %enabled) { if(%enabled $= "") %enabled = true; OptionsMenuSettingsList.addSliderRow(%label, %bitmapName, %callback, %enabled, %description); }