summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp
diff options
context:
space:
mode:
authorJMC47 <JMC4789@gmail.com>2019-01-10 19:04:27 -0500
committerGitHub <noreply@github.com>2019-01-10 19:04:27 -0500
commit012338288e30e765e2ef8ec284cdbaceb42ba5ea (patch)
tree2874ac5d304b6e881673cc7b5e256bc85d1df4d4 /Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp
parentc2afcb0f6bba761c248031ee715a1db3fd4dbe05 (diff)
parent7efa96eda979f5e717813e7c76cefb0720bc239a (diff)
Merge pull request #7662 from jordan-woyak/mapping-indicators-make-pretty
ControllerEmu: Make mapping indicators pretty
Diffstat (limited to 'Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp')
-rw-r--r--Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp88
1 files changed, 13 insertions, 75 deletions
diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp b/Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp
index 9db29909fd..0cd5da6ba0 100644
--- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp
+++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp
@@ -24,103 +24,41 @@ AnalogStick::AnalogStick(const char* const name_, std::unique_ptr<StickGate>&& s
AnalogStick::AnalogStick(const char* const name_, const char* const ui_name_,
std::unique_ptr<StickGate>&& stick_gate)
- : ControlGroup(name_, ui_name_, GroupType::Stick), m_stick_gate(std::move(stick_gate))
+ : ReshapableInput(name_, ui_name_, GroupType::Stick), m_stick_gate(std::move(stick_gate))
{
for (auto& named_direction : named_directions)
controls.emplace_back(std::make_unique<Input>(Translate, named_direction));
controls.emplace_back(std::make_unique<Input>(Translate, _trans("Modifier")));
- // Set default input radius to that of the gate radius (no resizing)
- // Allow radius greater than 1.0 for definitions of rounded squares
- // This is ideal for Xbox controllers (and probably others)
- numeric_settings.emplace_back(
- std::make_unique<NumericSetting>(_trans("Input Radius"), GetGateRadiusAtAngle(0.0), 0, 140));
- // Set default input shape to an octagon (no reshaping)
- numeric_settings.emplace_back(
- std::make_unique<NumericSetting>(_trans("Input Shape"), 0.0, 0, 50));
- numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Dead Zone"), 0, 0, 50));
+ // Default input radius to that of the gate radius (no resizing)
+ // Default input shape to an octagon (no reshaping)
+ // Max deadzone to 50%
+ AddReshapingSettings(GetGateRadiusAtAngle(0.0), 0.0, 50);
}
-AnalogStick::StateData AnalogStick::GetState(bool adjusted)
+AnalogStick::ReshapeData AnalogStick::GetReshapableState(bool adjusted)
{
- ControlState y = controls[0]->control_ref->State() - controls[1]->control_ref->State();
- ControlState x = controls[3]->control_ref->State() - controls[2]->control_ref->State();
+ const ControlState y = controls[0]->control_ref->State() - controls[1]->control_ref->State();
+ const ControlState x = controls[3]->control_ref->State() - controls[2]->control_ref->State();
// Return raw values. (used in UI)
if (!adjusted)
return {x, y};
- // TODO: make the AtAngle functions work with negative angles:
- const ControlState ang = std::atan2(y, x) + MathUtil::TAU;
-
- const ControlState gate_max_dist = GetGateRadiusAtAngle(ang);
- const ControlState input_max_dist = GetInputRadiusAtAngle(ang);
-
- // If input radius is zero we apply no scaling.
- // This is useful when mapping native controllers without knowing intimate radius details.
- const ControlState max_dist = input_max_dist ? input_max_dist : gate_max_dist;
-
- ControlState dist = std::sqrt(x * x + y * y) / max_dist;
-
- // If the modifier is pressed, scale the distance by the modifier's value.
- // This is affected by the modifier's "range" setting which defaults to 50%.
const ControlState modifier = controls[4]->control_ref->State();
- if (modifier)
- {
- // TODO: Modifier's range setting gets reset to 100% when the clear button is clicked.
- // This causes the modifier to not behave how a user might suspect.
- // Retaining the old scale-by-50% behavior until range is fixed to clear to 50%.
- dist *= 0.5;
- // dist *= modifier;
- }
-
- // Apply deadzone as a percentage of the user-defined radius/shape:
- const ControlState deadzone = GetDeadzoneRadiusAtAngle(ang);
- dist = std::max(0.0, dist - deadzone) / (1.0 - deadzone);
-
- // Scale to the gate shape/radius:
- dist = dist *= gate_max_dist;
-
- x = MathUtil::Clamp(std::cos(ang) * dist, -1.0, 1.0);
- y = MathUtil::Clamp(std::sin(ang) * dist, -1.0, 1.0);
- return {x, y};
-}
-ControlState AnalogStick::GetGateRadiusAtAngle(double ang) const
-{
- return m_stick_gate->GetRadiusAtAngle(ang);
-}
-
-ControlState AnalogStick::GetDeadzoneRadiusAtAngle(double ang) const
-{
- return CalculateInputShapeRadiusAtAngle(ang) * numeric_settings[SETTING_DEADZONE]->GetValue();
+ return Reshape(x, y, modifier);
}
-ControlState AnalogStick::GetInputRadiusAtAngle(double ang) const
+AnalogStick::StateData AnalogStick::GetState()
{
- const ControlState radius =
- CalculateInputShapeRadiusAtAngle(ang) * numeric_settings[SETTING_INPUT_RADIUS]->GetValue();
- // Clamp within the -1 to +1 square as input radius may be greater than 1.0:
- return std::min(radius, SquareStickGate(1).GetRadiusAtAngle(ang));
+ return GetReshapableState(true);
}
-ControlState AnalogStick::CalculateInputShapeRadiusAtAngle(double ang) const
+ControlState AnalogStick::GetGateRadiusAtAngle(double ang) const
{
- const auto shape = numeric_settings[SETTING_INPUT_SHAPE]->GetValue() * 4.0;
-
- if (shape < 1.0)
- {
- // Between 0 and 25 return a shape between octagon and circle
- const auto amt = shape;
- return OctagonStickGate(1).GetRadiusAtAngle(ang) * (1 - amt) + amt;
- }
- else
- {
- // Between 25 and 50 return a shape between circle and square
- const auto amt = shape - 1.0;
- return (1 - amt) + SquareStickGate(1).GetRadiusAtAngle(ang) * amt;
- }
+ return m_stick_gate->GetRadiusAtAngle(ang);
}
OctagonAnalogStick::OctagonAnalogStick(const char* name, ControlState gate_radius)