Merge pull request #566 from ggrtk/analog-controller

ControllerInterface: Customizable axis scaling and deadzone size
This commit is contained in:
Connor McLaughlin 2020-06-24 01:33:26 +10:00 committed by GitHub
commit f32028a736
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 47 additions and 5 deletions

View File

@ -1030,6 +1030,12 @@ void CommonHostInterface::UpdateControllerInputMap(SettingsInterface& si)
for (const std::string& binding : bindings) for (const std::string& binding : bindings)
AddRumbleToInputMap(binding, controller_index, num_motors); AddRumbleToInputMap(binding, controller_index, num_motors);
} }
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);
} }
} }

View File

@ -43,6 +43,12 @@ public:
virtual u32 GetControllerRumbleMotorCount(int controller_index) = 0; virtual u32 GetControllerRumbleMotorCount(int controller_index) = 0;
virtual void SetControllerRumbleStrength(int controller_index, const float* strengths, u32 num_motors) = 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;
// 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. // Input monitoring for external access.
struct Hook struct Hook
{ {

View File

@ -273,9 +273,6 @@ bool SDLControllerInterface::BindControllerAxisToButton(int controller_index, in
bool SDLControllerInterface::HandleControllerAxisEvent(const SDL_Event* ev) bool SDLControllerInterface::HandleControllerAxisEvent(const SDL_Event* ev)
{ {
// TODO: Make deadzone customizable.
static constexpr float deadzone = 8192.0f / 32768.0f;
const float value = static_cast<float>(ev->caxis.value) / (ev->caxis.value < 0 ? 32768.0f : 32767.0f); const float value = static_cast<float>(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); Log_DebugPrintf("controller %d axis %d %d %f", ev->caxis.which, ev->caxis.axis, ev->caxis.value, value);
@ -289,12 +286,13 @@ bool SDLControllerInterface::HandleControllerAxisEvent(const SDL_Event* ev)
const AxisCallback& cb = it->axis_mapping[ev->caxis.axis]; const AxisCallback& cb = it->axis_mapping[ev->caxis.axis];
if (cb) 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; return true;
} }
// set the other direction to false so large movements don't leave the opposite on // 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 bool positive = (value >= 0.0f);
const ButtonCallback& other_button_cb = it->axis_button_mapping[ev->caxis.axis][BoolToUInt8(!positive)]; 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)]; const ButtonCallback& button_cb = it->axis_button_mapping[ev->caxis.axis][BoolToUInt8(positive)];
@ -386,3 +384,25 @@ void SDLControllerInterface::SetControllerRumbleStrength(int controller_index, c
SDL_HapticRumbleStop(haptic); 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;
}
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;
}

View File

@ -29,6 +29,12 @@ public:
u32 GetControllerRumbleMotorCount(int controller_index) override; u32 GetControllerRumbleMotorCount(int controller_index) override;
void SetControllerRumbleStrength(int controller_index, const float* strengths, u32 num_motors) 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;
// Set deadzone that will be applied on axis-to-button mappings
bool SetControllerDeadzone(int controller_index, float size = 0.25f) override;
void PollEvents() override; void PollEvents() override;
bool ProcessSDLEvent(const SDL_Event* event); bool ProcessSDLEvent(const SDL_Event* event);
@ -42,6 +48,10 @@ private:
int joystick_id; int joystick_id;
int player_id; int player_id;
// Scaling value of 1.30f to 1.40f recommended when using recent controllers
float axis_scale = 1.00f;
float deadzone = 0.25f;
std::array<AxisCallback, MAX_NUM_AXISES> axis_mapping; std::array<AxisCallback, MAX_NUM_AXISES> axis_mapping;
std::array<ButtonCallback, MAX_NUM_BUTTONS> button_mapping; std::array<ButtonCallback, MAX_NUM_BUTTONS> button_mapping;
std::array<std::array<ButtonCallback, 2>, MAX_NUM_AXISES> axis_button_mapping; std::array<std::array<ButtonCallback, 2>, MAX_NUM_AXISES> axis_button_mapping;