diff --git a/apps/openmw/mwinput/controllermanager.cpp b/apps/openmw/mwinput/controllermanager.cpp index 554a323331..d921376f9c 100644 --- a/apps/openmw/mwinput/controllermanager.cpp +++ b/apps/openmw/mwinput/controllermanager.cpp @@ -33,6 +33,8 @@ namespace MWInput , mGuiCursorEnabled(true) , mJoystickLastUsed(false) , mGamepadMousePressed(false) + , mLeftTriggerGuiPressed(false) + , mRightTriggerGuiPressed(false) { if (!controllerBindingsFile.empty()) { @@ -340,6 +342,22 @@ namespace MWInput bool ControllerManager::gamepadToGuiControl(const SDL_ControllerAxisEvent& arg) { + const int triggerPressThreshold = Settings::gui().mControllerTriggerPressThreshold; + const int rawTriggerReleaseThreshold = Settings::gui().mControllerTriggerReleaseThreshold; + const int triggerReleaseThreshold = std::clamp(rawTriggerReleaseThreshold, 0, triggerPressThreshold - 1); + + auto handleTriggerPress = [&](Sint16 value, bool& triggerGuiPressed, const auto& onPress) { + if (value >= triggerPressThreshold && !triggerGuiPressed) + { + onPress(); + triggerGuiPressed = true; + } + else if (value <= triggerReleaseThreshold) + { + triggerGuiPressed = false; + } + }; + MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager(); if (Settings::gui().mControllerMenus) @@ -347,14 +365,14 @@ namespace MWInput // Left and right triggers toggle through open GUI windows. if (arg.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT) { - if (arg.value == 32767) // Treat like a button. - winMgr->cycleActiveControllerWindow(true); + handleTriggerPress( + arg.value, mRightTriggerGuiPressed, [&] { winMgr->cycleActiveControllerWindow(true); }); return true; } else if (arg.axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT) { - if (arg.value == 32767) // Treat like a button. - winMgr->cycleActiveControllerWindow(false); + handleTriggerPress( + arg.value, mLeftTriggerGuiPressed, [&] { winMgr->cycleActiveControllerWindow(false); }); return true; } @@ -402,12 +420,12 @@ namespace MWInput switch (arg.axis) { case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: - if (arg.value == 32767) // Treat like a button. - winMgr->injectKeyPress(MyGUI::KeyCode::Minus, 0, false); + handleTriggerPress(arg.value, mRightTriggerGuiPressed, + [&] { winMgr->injectKeyPress(MyGUI::KeyCode::Minus, 0, false); }); break; case SDL_CONTROLLER_AXIS_TRIGGERLEFT: - if (arg.value == 32767) // Treat like a button. - winMgr->injectKeyPress(MyGUI::KeyCode::Equals, 0, false); + handleTriggerPress(arg.value, mLeftTriggerGuiPressed, + [&] { winMgr->injectKeyPress(MyGUI::KeyCode::Equals, 0, false); }); break; case SDL_CONTROLLER_AXIS_LEFTX: case SDL_CONTROLLER_AXIS_LEFTY: diff --git a/apps/openmw/mwinput/controllermanager.hpp b/apps/openmw/mwinput/controllermanager.hpp index 535ee85fd5..e5c1a935c4 100644 --- a/apps/openmw/mwinput/controllermanager.hpp +++ b/apps/openmw/mwinput/controllermanager.hpp @@ -68,6 +68,8 @@ namespace MWInput bool mGuiCursorEnabled; bool mJoystickLastUsed; bool mGamepadMousePressed; + bool mLeftTriggerGuiPressed; + bool mRightTriggerGuiPressed; }; } #endif diff --git a/components/settings/categories/gui.hpp b/components/settings/categories/gui.hpp index 06f32640fd..7061fd25a1 100644 --- a/components/settings/categories/gui.hpp +++ b/components/settings/categories/gui.hpp @@ -24,6 +24,10 @@ namespace Settings SettingValue mTooltipDelay{ mIndex, "GUI", "tooltip delay", makeMaxSanitizerFloat(0) }; SettingValue mStretchMenuBackground{ mIndex, "GUI", "stretch menu background" }; SettingValue mControllerMenus{ mIndex, "GUI", "controller menus" }; + SettingValue mControllerTriggerPressThreshold{ mIndex, "GUI", "controller trigger press", + makeClampSanitizerInt(1, 32767) }; + SettingValue mControllerTriggerReleaseThreshold{ mIndex, "GUI", "controller trigger release", + makeClampSanitizerInt(0, 32766) }; SettingValue mControllerTooltips{ mIndex, "GUI", "controller tooltips" }; SettingValue mSubtitles{ mIndex, "GUI", "subtitles" }; SettingValue mHitFader{ mIndex, "GUI", "hit fader" }; diff --git a/docs/source/reference/modding/settings/GUI.rst b/docs/source/reference/modding/settings/GUI.rst index f5afb3a017..b085cae83a 100644 --- a/docs/source/reference/modding/settings/GUI.rst +++ b/docs/source/reference/modding/settings/GUI.rst @@ -81,6 +81,28 @@ GUI Settings tooltips, similar to Oblivion Remastered. Mouse input remains fully supported. If false, the controller works as a GUI mouse. +.. omw-setting:: + :title: controller trigger press + :type: int + :range: 1, 32767 + :default: 30720 + + Sets how far the triggers (L2/R2) must be pulled before controller menus + recognize them as a button press. + The default value is 15/16ths depressed. + +.. omw-setting:: + :title: controller trigger release + :type: int + :range: 0, 32766 + :default: 26624 + + Sets how far the triggers (L2/R2) must be released before their latch + is reset and it can be pressed again in controller menus. + This value must be less than controller trigger press. + If it is not, it will be clamped to controller trigger press - 1. + The default value is 13/16ths depressed. + .. omw-setting:: :title: controller tooltips :type: boolean diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 618d2584cb..72010831a9 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -204,6 +204,13 @@ stretch menu background = false # Make menus easier to navigate with a controller. controller menus = false +# Trigger axis value required to count as pressed for controller menu actions. Value from 1-32767. +controller trigger press = 30720 + +# Trigger axis value below which the trigger is considered released again. Value from 0-32766. +# This value must be less than the value of trigger press. If not, it will be clamped to trigger press - 1. +controller trigger release = 26624 + # When true, you do not need to press R3 to show tooltips. controller tooltips = false