From 6b7c068f8325d77802c9970f6d254e0768046c33 Mon Sep 17 00:00:00 2001 From: Albert Liu <45282415+ggrtk@users.noreply.github.com> Date: Sat, 6 Jun 2020 18:49:25 -0700 Subject: [PATCH 1/2] ControllerInterface: Implement axis scaling for axis-to-axis mappings This feature allows us to work around analog stick range issues at the intercardinal directions in certain titles (e.g. Rockman DASH 2) caused by modern controllers having a tighter logical range of reporting than PS1 analog controllers. --- src/frontend-common/common_host_interface.cpp | 3 +++ src/frontend-common/controller_interface.h | 3 +++ src/frontend-common/sdl_controller_interface.cpp | 14 +++++++++++++- src/frontend-common/sdl_controller_interface.h | 6 ++++++ 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/frontend-common/common_host_interface.cpp b/src/frontend-common/common_host_interface.cpp index e627cf209..dd3db4507 100644 --- a/src/frontend-common/common_host_interface.cpp +++ b/src/frontend-common/common_host_interface.cpp @@ -1030,6 +1030,9 @@ void CommonHostInterface::UpdateControllerInputMap(SettingsInterface& si) for (const std::string& binding : bindings) AddRumbleToInputMap(binding, controller_index, num_motors); } + + const float axis_scale = si.GetFloatValue(category, "AxisScale", 1.00f); + m_controller_interface->SetControllerAxisScale(controller_index, axis_scale); } } diff --git a/src/frontend-common/controller_interface.h b/src/frontend-common/controller_interface.h index ed35e6108..c8f3f14de 100644 --- a/src/frontend-common/controller_interface.h +++ b/src/frontend-common/controller_interface.h @@ -43,6 +43,9 @@ public: virtual u32 GetControllerRumbleMotorCount(int controller_index) = 0; virtual void SetControllerRumbleStrength(int controller_index, const float* strengths, u32 num_motors) = 0; + // Set scaling that will be applied on axis-to-axis mappings + virtual bool SetControllerAxisScale(int controller_index, float scale) = 0; + // Input monitoring for external access. struct Hook { diff --git a/src/frontend-common/sdl_controller_interface.cpp b/src/frontend-common/sdl_controller_interface.cpp index 53af1b297..098f74cf1 100644 --- a/src/frontend-common/sdl_controller_interface.cpp +++ b/src/frontend-common/sdl_controller_interface.cpp @@ -289,7 +289,8 @@ bool SDLControllerInterface::HandleControllerAxisEvent(const SDL_Event* ev) const AxisCallback& cb = it->axis_mapping[ev->caxis.axis]; if (cb) { - cb(value); + // Apply axis scaling only when controller axis is mapped to an axis + cb(std::clamp(it->axis_scale * value, -1.0f, 1.0f)); return true; } @@ -386,3 +387,14 @@ void SDLControllerInterface::SetControllerRumbleStrength(int controller_index, c SDL_HapticRumbleStop(haptic); } } + +bool SDLControllerInterface::SetControllerAxisScale(int controller_index, float scale /* = 1.00f */) +{ + auto it = GetControllerDataForPlayerId(controller_index); + if (it == m_controllers.end()) + return false; + + it->axis_scale = std::clamp(std::abs(scale), 0.01f, 1.50f); + Log_InfoPrintf("Controller %d axis scale set to %f", controller_index, it->axis_scale); + return true; +} diff --git a/src/frontend-common/sdl_controller_interface.h b/src/frontend-common/sdl_controller_interface.h index 6293b7268..69e8270c5 100644 --- a/src/frontend-common/sdl_controller_interface.h +++ b/src/frontend-common/sdl_controller_interface.h @@ -29,6 +29,9 @@ public: u32 GetControllerRumbleMotorCount(int controller_index) override; void SetControllerRumbleStrength(int controller_index, const float* strengths, u32 num_motors) override; + // Set scaling that will be applied on axis-to-axis mappings + bool SetControllerAxisScale(int controller_index, float scale = 1.00f) override; + void PollEvents() override; bool ProcessSDLEvent(const SDL_Event* event); @@ -42,6 +45,9 @@ private: int joystick_id; int player_id; + // Scaling value of 1.30f to 1.40f recommended when using recent controllers + float axis_scale = 1.00f; + std::array axis_mapping; std::array button_mapping; std::array, MAX_NUM_AXISES> axis_button_mapping; From 293c2f50cdab738025f6342aaf12d3946138155b Mon Sep 17 00:00:00 2001 From: Albert Liu <45282415+ggrtk@users.noreply.github.com> Date: Mon, 22 Jun 2020 19:30:19 -0700 Subject: [PATCH 2/2] ControllerInterface: Make axis-to-button deadzone customizable --- src/frontend-common/common_host_interface.cpp | 3 +++ src/frontend-common/controller_interface.h | 3 +++ src/frontend-common/sdl_controller_interface.cpp | 16 ++++++++++++---- src/frontend-common/sdl_controller_interface.h | 4 ++++ 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/frontend-common/common_host_interface.cpp b/src/frontend-common/common_host_interface.cpp index dd3db4507..fce0a44ef 100644 --- a/src/frontend-common/common_host_interface.cpp +++ b/src/frontend-common/common_host_interface.cpp @@ -1033,6 +1033,9 @@ void CommonHostInterface::UpdateControllerInputMap(SettingsInterface& si) const float axis_scale = si.GetFloatValue(category, "AxisScale", 1.00f); m_controller_interface->SetControllerAxisScale(controller_index, axis_scale); + + const float deadzone_size = si.GetFloatValue(category, "Deadzone", 0.25f); + m_controller_interface->SetControllerDeadzone(controller_index, deadzone_size); } } diff --git a/src/frontend-common/controller_interface.h b/src/frontend-common/controller_interface.h index c8f3f14de..906a27d56 100644 --- a/src/frontend-common/controller_interface.h +++ b/src/frontend-common/controller_interface.h @@ -46,6 +46,9 @@ public: // Set scaling that will be applied on axis-to-axis mappings virtual bool SetControllerAxisScale(int controller_index, float scale) = 0; + // Set deadzone that will be applied on axis-to-button mappings + virtual bool SetControllerDeadzone(int controller_index, float size) = 0; + // Input monitoring for external access. struct Hook { diff --git a/src/frontend-common/sdl_controller_interface.cpp b/src/frontend-common/sdl_controller_interface.cpp index 098f74cf1..a2c54ed52 100644 --- a/src/frontend-common/sdl_controller_interface.cpp +++ b/src/frontend-common/sdl_controller_interface.cpp @@ -273,9 +273,6 @@ bool SDLControllerInterface::BindControllerAxisToButton(int controller_index, in bool SDLControllerInterface::HandleControllerAxisEvent(const SDL_Event* ev) { - // TODO: Make deadzone customizable. - static constexpr float deadzone = 8192.0f / 32768.0f; - const float value = static_cast(ev->caxis.value) / (ev->caxis.value < 0 ? 32768.0f : 32767.0f); Log_DebugPrintf("controller %d axis %d %d %f", ev->caxis.which, ev->caxis.axis, ev->caxis.value, value); @@ -295,7 +292,7 @@ bool SDLControllerInterface::HandleControllerAxisEvent(const SDL_Event* ev) } // set the other direction to false so large movements don't leave the opposite on - const bool outside_deadzone = (std::abs(value) >= deadzone); + const bool outside_deadzone = (std::abs(value) >= it->deadzone); const bool positive = (value >= 0.0f); const ButtonCallback& other_button_cb = it->axis_button_mapping[ev->caxis.axis][BoolToUInt8(!positive)]; const ButtonCallback& button_cb = it->axis_button_mapping[ev->caxis.axis][BoolToUInt8(positive)]; @@ -398,3 +395,14 @@ bool SDLControllerInterface::SetControllerAxisScale(int controller_index, float Log_InfoPrintf("Controller %d axis scale set to %f", controller_index, it->axis_scale); return true; } + +bool SDLControllerInterface::SetControllerDeadzone(int controller_index, float size /* = 0.25f */) +{ + auto it = GetControllerDataForPlayerId(controller_index); + if (it == m_controllers.end()) + return false; + + it->deadzone = std::clamp(std::abs(size), 0.01f, 0.99f); + Log_InfoPrintf("Controller %d deadzone size set to %f", controller_index, it->deadzone); + return true; +} diff --git a/src/frontend-common/sdl_controller_interface.h b/src/frontend-common/sdl_controller_interface.h index 69e8270c5..1aacab523 100644 --- a/src/frontend-common/sdl_controller_interface.h +++ b/src/frontend-common/sdl_controller_interface.h @@ -32,6 +32,9 @@ public: // Set scaling that will be applied on axis-to-axis mappings bool SetControllerAxisScale(int controller_index, float scale = 1.00f) override; + // Set deadzone that will be applied on axis-to-button mappings + bool SetControllerDeadzone(int controller_index, float size = 0.25f) override; + void PollEvents() override; bool ProcessSDLEvent(const SDL_Event* event); @@ -47,6 +50,7 @@ private: // Scaling value of 1.30f to 1.40f recommended when using recent controllers float axis_scale = 1.00f; + float deadzone = 0.25f; std::array axis_mapping; std::array button_mapping;