From fd6ebe28952fd99e319c6d06fb5c855bb17a742d Mon Sep 17 00:00:00 2001 From: Megamouse Date: Fri, 16 Aug 2024 21:15:19 +0200 Subject: [PATCH] Qt/input: Don't report two direction trigger values unless actually requested Fixes a bug where you could map LT- even if you weren't pressing ALT before. --- rpcs3/Emu/Io/PadHandler.h | 11 ++++++-- rpcs3/Input/xinput_pad_handler.cpp | 38 ++++++++++++++++----------- rpcs3/Input/xinput_pad_handler.h | 4 +-- rpcs3/rpcs3qt/pad_settings_dialog.cpp | 2 +- 4 files changed, 34 insertions(+), 21 deletions(-) diff --git a/rpcs3/Emu/Io/PadHandler.h b/rpcs3/Emu/Io/PadHandler.h index 978ed00bde..8c6010cc62 100644 --- a/rpcs3/Emu/Io/PadHandler.h +++ b/rpcs3/Emu/Io/PadHandler.h @@ -70,6 +70,13 @@ public: disconnected }; + enum class trigger_recognition_mode + { + any, // Add all trigger modes to the button map + one_directional, // Treat trigger axis as one-directional only + two_directional // Treat trigger axis as two-directional only (similar to sticks) + }; + protected: enum button { @@ -124,7 +131,7 @@ protected: usz m_max_devices = 0; u32 m_trigger_threshold = 0; u32 m_thumb_threshold = 0; - bool m_triggers_as_sticks_only = false; + trigger_recognition_mode m_trigger_recognition_mode = trigger_recognition_mode::any; bool b_has_led = false; bool b_has_rgb = false; @@ -285,7 +292,7 @@ public: u16 NormalizeStickInput(u16 raw_value, s32 threshold, s32 multiplier, bool ignore_threshold = false) const; void convert_stick_values(u16& x_out, u16& y_out, s32 x_in, s32 y_in, u32 deadzone, u32 anti_deadzone, u32 padsquircling) const; - void set_triggers_as_sticks_only(bool enabled) { m_triggers_as_sticks_only = enabled; } + void set_trigger_recognition_mode(trigger_recognition_mode mode) { m_trigger_recognition_mode = mode; } virtual bool Init() { return true; } PadHandlerBase(pad_handler type = pad_handler::null); diff --git a/rpcs3/Input/xinput_pad_handler.cpp b/rpcs3/Input/xinput_pad_handler.cpp index 4088a08f90..5ee7c4fe23 100644 --- a/rpcs3/Input/xinput_pad_handler.cpp +++ b/rpcs3/Input/xinput_pad_handler.cpp @@ -212,31 +212,34 @@ std::unordered_map xinput_pad_handler::get_button_values(const std::sh // Try SCP first, if it fails for that pad then try normal XInput if (dev->is_scp_device) { - return get_button_values_scp(dev->state_scp, m_triggers_as_sticks_only); + return get_button_values_scp(dev->state_scp, m_trigger_recognition_mode); } - return get_button_values_base(dev->state_base, m_triggers_as_sticks_only); + return get_button_values_base(dev->state_base, m_trigger_recognition_mode); } -xinput_pad_handler::PadButtonValues xinput_pad_handler::get_button_values_base(const XINPUT_STATE& state, bool triggers_as_sticks_only) +xinput_pad_handler::PadButtonValues xinput_pad_handler::get_button_values_base(const XINPUT_STATE& state, trigger_recognition_mode trigger_mode) { PadButtonValues values; // Triggers - if (!triggers_as_sticks_only) + if (trigger_mode == trigger_recognition_mode::any || trigger_mode == trigger_recognition_mode::one_directional) { values[XInputKeyCodes::LT] = state.Gamepad.bLeftTrigger; values[XInputKeyCodes::RT] = state.Gamepad.bRightTrigger; } - const float lTrigger = state.Gamepad.bLeftTrigger / 255.0f; - const float rTrigger = state.Gamepad.bRightTrigger / 255.0f; + if (trigger_mode == trigger_recognition_mode::any || trigger_mode == trigger_recognition_mode::two_directional) + { + const float lTrigger = state.Gamepad.bLeftTrigger / 255.0f; + const float rTrigger = state.Gamepad.bRightTrigger / 255.0f; - values[XInputKeyCodes::LT_Pos] = static_cast(lTrigger > 0.5f ? std::clamp((lTrigger - 0.5f) * 2.0f * 255.0f, 0.0f, 255.0f) : 0.0f); - values[XInputKeyCodes::LT_Neg] = static_cast(lTrigger < 0.5f ? std::clamp((0.5f - lTrigger) * 2.0f * 255.0f, 0.0f, 255.0f) : 0.0f); + values[XInputKeyCodes::LT_Pos] = static_cast(lTrigger > 0.5f ? std::clamp((lTrigger - 0.5f) * 2.0f * 255.0f, 0.0f, 255.0f) : 0.0f); + values[XInputKeyCodes::LT_Neg] = static_cast(lTrigger < 0.5f ? std::clamp((0.5f - lTrigger) * 2.0f * 255.0f, 0.0f, 255.0f) : 0.0f); - values[XInputKeyCodes::RT_Pos] = static_cast(rTrigger > 0.5f ? std::clamp((rTrigger - 0.5f) * 2.0f * 255.0f, 0.0f, 255.0f) : 0.0f); - values[XInputKeyCodes::RT_Neg] = static_cast(rTrigger < 0.5f ? std::clamp((0.5f - rTrigger) * 2.0f * 255.0f, 0.0f, 255.0f) : 0.0f); + values[XInputKeyCodes::RT_Pos] = static_cast(rTrigger > 0.5f ? std::clamp((rTrigger - 0.5f) * 2.0f * 255.0f, 0.0f, 255.0f) : 0.0f); + values[XInputKeyCodes::RT_Neg] = static_cast(rTrigger < 0.5f ? std::clamp((0.5f - rTrigger) * 2.0f * 255.0f, 0.0f, 255.0f) : 0.0f); + } // Sticks const int lx = state.Gamepad.sThumbLX; @@ -289,22 +292,25 @@ xinput_pad_handler::PadButtonValues xinput_pad_handler::get_button_values_base(c return values; } -xinput_pad_handler::PadButtonValues xinput_pad_handler::get_button_values_scp(const SCP_EXTN& state, bool triggers_as_sticks_only) +xinput_pad_handler::PadButtonValues xinput_pad_handler::get_button_values_scp(const SCP_EXTN& state, trigger_recognition_mode trigger_mode) { PadButtonValues values; // Triggers - if (!triggers_as_sticks_only) + if (trigger_mode == trigger_recognition_mode::any || trigger_mode == trigger_recognition_mode::one_directional) { values[xinput_pad_handler::XInputKeyCodes::LT] = static_cast(state.SCP_L2 * 255.0f); values[xinput_pad_handler::XInputKeyCodes::RT] = static_cast(state.SCP_R2 * 255.0f); } - values[XInputKeyCodes::LT_Pos] = static_cast(state.SCP_L2 > 0.5f ? std::clamp((state.SCP_L2 - 0.5f) * 2.0f * 255.0f, 0.0f, 255.0f) : 0.0f); - values[XInputKeyCodes::LT_Neg] = static_cast(state.SCP_L2 < 0.5f ? std::clamp((0.5f - state.SCP_L2) * 2.0f * 255.0f, 0.0f, 255.0f) : 0.0f); + if (trigger_mode == trigger_recognition_mode::any || trigger_mode == trigger_recognition_mode::two_directional) + { + values[XInputKeyCodes::LT_Pos] = static_cast(state.SCP_L2 > 0.5f ? std::clamp((state.SCP_L2 - 0.5f) * 2.0f * 255.0f, 0.0f, 255.0f) : 0.0f); + values[XInputKeyCodes::LT_Neg] = static_cast(state.SCP_L2 < 0.5f ? std::clamp((0.5f - state.SCP_L2) * 2.0f * 255.0f, 0.0f, 255.0f) : 0.0f); - values[XInputKeyCodes::RT_Pos] = static_cast(state.SCP_R2 > 0.5f ? std::clamp((state.SCP_R2 - 0.5f) * 2.0f * 255.0f, 0.0f, 255.0f) : 0.0f); - values[XInputKeyCodes::RT_Neg] = static_cast(state.SCP_R2 < 0.5f ? std::clamp((0.5f - state.SCP_R2) * 2.0f * 255.0f, 0.0f, 255.0f) : 0.0f); + values[XInputKeyCodes::RT_Pos] = static_cast(state.SCP_R2 > 0.5f ? std::clamp((state.SCP_R2 - 0.5f) * 2.0f * 255.0f, 0.0f, 255.0f) : 0.0f); + values[XInputKeyCodes::RT_Neg] = static_cast(state.SCP_R2 < 0.5f ? std::clamp((0.5f - state.SCP_R2) * 2.0f * 255.0f, 0.0f, 255.0f) : 0.0f); + } // Sticks const float lx = state.SCP_LX; diff --git a/rpcs3/Input/xinput_pad_handler.h b/rpcs3/Input/xinput_pad_handler.h index 7c4d7a814e..2ca25bd336 100644 --- a/rpcs3/Input/xinput_pad_handler.h +++ b/rpcs3/Input/xinput_pad_handler.h @@ -123,8 +123,8 @@ private: typedef DWORD (WINAPI * PFN_XINPUTGETBATTERYINFORMATION)(DWORD, BYTE, XINPUT_BATTERY_INFORMATION *); int GetDeviceNumber(const std::string& padId); - static PadButtonValues get_button_values_base(const XINPUT_STATE& state, bool triggers_as_sticks_only); - static PadButtonValues get_button_values_scp(const SCP_EXTN& state, bool triggers_as_sticks_only); + static PadButtonValues get_button_values_base(const XINPUT_STATE& state, trigger_recognition_mode trigger_mode); + static PadButtonValues get_button_values_scp(const SCP_EXTN& state, trigger_recognition_mode trigger_mode); HMODULE library{ nullptr }; PFN_XINPUTGETEXTENDED xinputGetExtended{ nullptr }; diff --git a/rpcs3/rpcs3qt/pad_settings_dialog.cpp b/rpcs3/rpcs3qt/pad_settings_dialog.cpp index 4b3834a4f2..1d3b09eac7 100644 --- a/rpcs3/rpcs3qt/pad_settings_dialog.cpp +++ b/rpcs3/rpcs3qt/pad_settings_dialog.cpp @@ -1312,7 +1312,7 @@ void pad_settings_dialog::OnPadButtonClicked(int id) } // On alt+click or alt+space allow to handle triggers as the entire stick axis - m_handler->set_triggers_as_sticks_only(QApplication::keyboardModifiers() & Qt::KeyboardModifier::AltModifier); + m_handler->set_trigger_recognition_mode((QApplication::keyboardModifiers() & Qt::KeyboardModifier::AltModifier) ? PadHandlerBase::trigger_recognition_mode::two_directional : PadHandlerBase::trigger_recognition_mode::one_directional); for (auto but : m_pad_buttons->buttons()) {