From a72cecd235d054d65ff290cd2d4809c50ecc0f7a Mon Sep 17 00:00:00 2001 From: TellowKrinkle Date: Wed, 14 Sep 2022 17:06:23 -0500 Subject: [PATCH] Input: Add FullAxis modifier --- pcsx2-qt/Settings/InputBindingDialog.cpp | 10 ++++----- pcsx2-qt/Settings/InputBindingWidget.cpp | 10 ++++----- pcsx2/Frontend/FullscreenUI.cpp | 2 +- pcsx2/Frontend/InputManager.cpp | 25 +++++++++++++++++------ pcsx2/Frontend/InputManager.h | 13 +++++++++--- pcsx2/Frontend/InputSource.cpp | 23 +++++++++++++++++---- pcsx2/Frontend/SDLInputSource.cpp | 26 +++++++++++++++++++----- pcsx2/Frontend/XInputSource.cpp | 5 +++-- 8 files changed, 83 insertions(+), 31 deletions(-) diff --git a/pcsx2-qt/Settings/InputBindingDialog.cpp b/pcsx2-qt/Settings/InputBindingDialog.cpp index 894f29386b..3a6ebeddda 100644 --- a/pcsx2-qt/Settings/InputBindingDialog.cpp +++ b/pcsx2-qt/Settings/InputBindingDialog.cpp @@ -84,7 +84,7 @@ bool InputBindingDialog::eventFilter(QObject* watched, QEvent* event) if (dx != 0.0f) { InputBindingKey key(InputManager::MakePointerAxisKey(0, InputPointerAxis::WheelX)); - key.negative = (dx < 0.0f); + key.modifier = dx < 0.0f ? InputModifier::Negate : InputModifier::None; m_new_bindings.push_back(key); } @@ -92,7 +92,7 @@ bool InputBindingDialog::eventFilter(QObject* watched, QEvent* event) if (dy != 0.0f) { InputBindingKey key(InputManager::MakePointerAxisKey(0, InputPointerAxis::WheelY)); - key.negative = (dy < 0.0f); + key.modifier = dy < 0.0f ? InputModifier::Negate : InputModifier::None; m_new_bindings.push_back(key); } @@ -115,14 +115,14 @@ bool InputBindingDialog::eventFilter(QObject* watched, QEvent* event) if (std::abs(diff.x()) >= THRESHOLD) { InputBindingKey key(InputManager::MakePointerAxisKey(0, InputPointerAxis::X)); - key.negative = (diff.x() < 0); + key.modifier = diff.x() < 0 ? InputModifier::Negate : InputModifier::None; m_new_bindings.push_back(key); has_one = true; } if (std::abs(diff.y()) >= THRESHOLD) { InputBindingKey key(InputManager::MakePointerAxisKey(0, InputPointerAxis::Y)); - key.negative = (diff.y() < 0); + key.modifier = diff.y() < 0 ? InputModifier::Negate : InputModifier::None; m_new_bindings.push_back(key); has_one = true; } @@ -291,7 +291,7 @@ void InputBindingDialog::inputManagerHookCallback(InputBindingKey key, float val if (abs_value >= 0.5f) { InputBindingKey key_to_add = key; - key_to_add.negative = (value < 0.0f); + key_to_add.modifier = value < 0.0f ? InputModifier::Negate : InputModifier::None; m_new_bindings.push_back(key_to_add); } } diff --git a/pcsx2-qt/Settings/InputBindingWidget.cpp b/pcsx2-qt/Settings/InputBindingWidget.cpp index 65aa976992..eecc820552 100644 --- a/pcsx2-qt/Settings/InputBindingWidget.cpp +++ b/pcsx2-qt/Settings/InputBindingWidget.cpp @@ -138,7 +138,7 @@ bool InputBindingWidget::eventFilter(QObject* watched, QEvent* event) if (dx != 0.0f) { InputBindingKey key(InputManager::MakePointerAxisKey(0, InputPointerAxis::WheelX)); - key.negative = (dx < 0.0f); + key.modifier = dx < 0.0f ? InputModifier::Negate : InputModifier::None; m_new_bindings.push_back(key); } @@ -146,7 +146,7 @@ bool InputBindingWidget::eventFilter(QObject* watched, QEvent* event) if (dy != 0.0f) { InputBindingKey key(InputManager::MakePointerAxisKey(0, InputPointerAxis::WheelY)); - key.negative = (dy < 0.0f); + key.modifier = dy < 0.0f ? InputModifier::Negate : InputModifier::None; m_new_bindings.push_back(key); } @@ -169,14 +169,14 @@ bool InputBindingWidget::eventFilter(QObject* watched, QEvent* event) if (std::abs(diff.x()) >= THRESHOLD) { InputBindingKey key(InputManager::MakePointerAxisKey(0, InputPointerAxis::X)); - key.negative = (diff.x() < 0); + key.modifier = diff.x() < 0 ? InputModifier::Negate : InputModifier::None; m_new_bindings.push_back(key); has_one = true; } if (std::abs(diff.y()) >= THRESHOLD) { InputBindingKey key(InputManager::MakePointerAxisKey(0, InputPointerAxis::Y)); - key.negative = (diff.y() < 0); + key.modifier = diff.y() < 0 ? InputModifier::Negate : InputModifier::None; m_new_bindings.push_back(key); has_one = true; } @@ -357,7 +357,7 @@ void InputBindingWidget::inputManagerHookCallback(InputBindingKey key, float val if (abs_value >= 0.5f) { InputBindingKey key_to_add = key; - key_to_add.negative = (value < 0.0f); + key_to_add.modifier = value < 0.0f ? InputModifier::Negate : InputModifier::None; m_new_bindings.push_back(key_to_add); } } diff --git a/pcsx2/Frontend/FullscreenUI.cpp b/pcsx2/Frontend/FullscreenUI.cpp index 4b93490772..3de29b659d 100644 --- a/pcsx2/Frontend/FullscreenUI.cpp +++ b/pcsx2/Frontend/FullscreenUI.cpp @@ -1319,7 +1319,7 @@ void FullscreenUI::BeginInputBinding(SettingsInterface* bsi, PAD::ControllerBind if (abs_value >= 0.5f) { InputBindingKey key_to_add = key; - key_to_add.negative = (value < 0.0f); + key_to_add.modifier = (value < 0.0f) ? InputModifier::Negate : InputModifier::None; s_input_binding_new_bindings.push_back(key_to_add); } diff --git a/pcsx2/Frontend/InputManager.cpp b/pcsx2/Frontend/InputManager.cpp index aae34b4b4e..651bf17e74 100644 --- a/pcsx2/Frontend/InputManager.cpp +++ b/pcsx2/Frontend/InputManager.cpp @@ -276,7 +276,7 @@ std::string InputManager::ConvertInputBindingKeyToString(InputBindingKey key) } else if (key.source_subtype == InputSubclass::PointerAxis) { - return fmt::format("Pointer-{}/{}{:c}", u32{key.source_index}, s_pointer_axis_names[key.data], key.negative ? '-' : '+'); + return fmt::format("Pointer-{}/{}{:c}", u32{key.source_index}, s_pointer_axis_names[key.data], key.modifier == InputModifier::Negate ? '-' : '+'); } } else if (key.source_type < InputSourceType::Count && s_input_sources[static_cast(key.source_type)]) @@ -497,9 +497,9 @@ std::optional InputManager::ParsePointerKey(const std::string_v const std::string_view dir_part(sub_binding.substr(std::strlen(s_pointer_axis_names[i]))); if (dir_part == "+") - key.negative = false; + key.modifier = InputModifier::None; else if (dir_part == "-") - key.negative = true; + key.modifier = InputModifier::Negate; else return std::nullopt; @@ -677,11 +677,24 @@ bool InputManager::InvokeEvents(InputBindingKey key, float value, GenericInputBi continue; const u8 bit = static_cast(1) << i; - const bool negative = binding->keys[i].negative; + const bool negative = binding->keys[i].modifier == InputModifier::Negate; const bool new_state = (negative ? (value < 0.0f) : (value > 0.0f)); - // invert if we're negative, since the handler expects 0..1 - const float value_to_pass = (negative ? ((value < 0.0f) ? -value : 0.0f) : (value > 0.0f) ? value : 0.0f); + float value_to_pass = 0.0f; + switch (binding->keys[i].modifier) + { + case InputModifier::None: + if (value > 0.0f) + value_to_pass = value; + break; + case InputModifier::Negate: + if (value < 0.0f) + value_to_pass = -value; + break; + case InputModifier::FullAxis: + value_to_pass = value * 0.5f + 0.5f; + break; + } // axes are fired regardless of a state change, unless they're zero // (but going from not-zero to zero will still fire, because of the full state) diff --git a/pcsx2/Frontend/InputManager.h b/pcsx2/Frontend/InputManager.h index 2e738c2d34..1ee7dcc5f5 100644 --- a/pcsx2/Frontend/InputManager.h +++ b/pcsx2/Frontend/InputManager.h @@ -55,6 +55,13 @@ enum class InputSubclass : u32 ControllerHaptic = 3, }; +enum class InputModifier : u32 +{ + None = 0, + Negate, ///< Input * -1, gets the negative side of the axis + FullAxis, ///< (Input * 0.5) + 0.5, uses both the negative and positive side of the axis together +}; + /// A composite type representing a full input key which is part of an event. union InputBindingKey { @@ -63,8 +70,8 @@ union InputBindingKey InputSourceType source_type : 4; u32 source_index : 8; ///< controller number InputSubclass source_subtype : 2; ///< if 1, binding is for an axis and not a button (used for controllers) - u32 negative : 1; ///< if 1, binding is for the negative side of the axis - u32 unused : 17; + InputModifier modifier : 2; + u32 unused : 16; u32 data; }; @@ -79,7 +86,7 @@ union InputBindingKey { InputBindingKey r; r.bits = bits; - r.negative = false; + r.modifier = InputModifier::None; return r; } }; diff --git a/pcsx2/Frontend/InputSource.cpp b/pcsx2/Frontend/InputSource.cpp index 2f6c09387d..6d195e9924 100644 --- a/pcsx2/Frontend/InputSource.cpp +++ b/pcsx2/Frontend/InputSource.cpp @@ -92,12 +92,21 @@ std::optional InputSource::ParseGenericControllerKey( key.data = static_cast(axis_number.value()); if (sub_binding[0] == '+') - key.negative = false; + key.modifier = InputModifier::None; else if (sub_binding[0] == '-') - key.negative = true; + key.modifier = InputModifier::Negate; else return std::nullopt; } + else if (StringUtil::StartsWith(sub_binding, "FullAxis")) + { + const std::optional axis_number = StringUtil::FromChars(sub_binding.substr(8)); + if (!axis_number.has_value() || axis_number.value() < 0) + return std::nullopt; + key.source_subtype = InputSubclass::ControllerAxis; + key.data = static_cast(axis_number.value()); + key.modifier = InputModifier::FullAxis; + } else if (StringUtil::StartsWith(sub_binding, "Button")) { const std::optional button_number = StringUtil::FromChars(sub_binding.substr(6)); @@ -119,8 +128,14 @@ std::string InputSource::ConvertGenericControllerKeyToString(InputBindingKey key { if (key.source_subtype == InputSubclass::ControllerAxis) { - return StringUtil::StdStringFromFormat("%s-%u/%cAxis%u", InputManager::InputSourceToString(key.source_type), - key.source_index, key.negative ? '+' : '-', key.data); + const char* modifier = ""; + switch (key.modifier) { + case InputModifier::None: modifier = "+"; break; + case InputModifier::Negate: modifier = "-"; break; + case InputModifier::FullAxis: modifier = "Full"; break; + } + return StringUtil::StdStringFromFormat("%s-%u/%sAxis%u", InputManager::InputSourceToString(key.source_type), + key.source_index, modifier, key.data); } else if (key.source_subtype == InputSubclass::ControllerButton) { diff --git a/pcsx2/Frontend/SDLInputSource.cpp b/pcsx2/Frontend/SDLInputSource.cpp index 9c9ba25fb3..c77858156b 100644 --- a/pcsx2/Frontend/SDLInputSource.cpp +++ b/pcsx2/Frontend/SDLInputSource.cpp @@ -256,7 +256,7 @@ std::optional SDLInputSource::ParseKeyString( { key.source_subtype = InputSubclass::ControllerAxis; key.data = *value; - key.negative = (binding[0] == '-'); + key.modifier = (binding[0] == '-') ? InputModifier::Negate : InputModifier::None; return key; } } @@ -267,11 +267,21 @@ std::optional SDLInputSource::ParseKeyString( // found an axis! key.source_subtype = InputSubclass::ControllerAxis; key.data = i; - key.negative = (binding[0] == '-'); + key.modifier = (binding[0] == '-') ? InputModifier::Negate : InputModifier::None; return key; } } } + else if (StringUtil::StartsWith(binding, "FullAxis")) + { + if (auto value = StringUtil::FromChars(binding.substr(8))) + { + key.source_subtype = InputSubclass::ControllerAxis; + key.data = *value; + key.modifier = InputModifier::FullAxis; + return key; + } + } else { // must be a button @@ -307,11 +317,17 @@ std::string SDLInputSource::ConvertKeyToString(InputBindingKey key) { if (key.source_subtype == InputSubclass::ControllerAxis) { - char modifier = key.negative ? '-' : '+'; + const char* modifier = key.modifier == InputModifier::Negate ? "-" : "+"; if (key.data < std::size(s_sdl_axis_names)) - ret = StringUtil::StdStringFromFormat("SDL-%u/%c%s", key.source_index, modifier, s_sdl_axis_names[key.data]); + { + ret = StringUtil::StdStringFromFormat("SDL-%u/%s%s", key.source_index, modifier, s_sdl_axis_names[key.data]); + } else - ret = StringUtil::StdStringFromFormat("SDL-%u/%cAxis%u", key.source_index, modifier, key.data); + { + if (key.modifier == InputModifier::FullAxis) + modifier = "Full"; + ret = StringUtil::StdStringFromFormat("SDL-%u/%sAxis%u", key.source_index, modifier, key.data); + } } else if (key.source_subtype == InputSubclass::ControllerButton) { diff --git a/pcsx2/Frontend/XInputSource.cpp b/pcsx2/Frontend/XInputSource.cpp index 7d2819252d..dc6ce7a46a 100644 --- a/pcsx2/Frontend/XInputSource.cpp +++ b/pcsx2/Frontend/XInputSource.cpp @@ -292,7 +292,7 @@ std::optional XInputSource::ParseKeyString( // found an axis! key.source_subtype = InputSubclass::ControllerAxis; key.data = i; - key.negative = (binding[0] == '-'); + key.modifier = binding[0] == '-' ? InputModifier::Negate : InputModifier::None; return key; } } @@ -323,8 +323,9 @@ std::string XInputSource::ConvertKeyToString(InputBindingKey key) { if (key.source_subtype == InputSubclass::ControllerAxis && key.data < std::size(s_axis_names)) { + const char modifier = key.modifier == InputModifier::Negate ? '-' : '+'; ret = StringUtil::StdStringFromFormat( - "XInput-%u/%c%s", key.source_index, key.negative ? '-' : '+', s_axis_names[key.data]); + "XInput-%u/%c%s", key.source_index, modifier, s_axis_names[key.data]); } else if (key.source_subtype == InputSubclass::ControllerButton && key.data < std::size(s_button_names)) {