summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon/ControllerEmu/StickGate.cpp
diff options
context:
space:
mode:
authorNick Michael <nickmichael@live.co.uk>2020-10-29 22:11:34 +0000
committerNick Michael <nickmichael@live.co.uk>2020-11-03 22:06:27 +0000
commit55dd3d73376746c4fc46df02d8266269a6e4537e (patch)
tree80d468b458af58fa7597fef1b17f5281ee7edb59 /Source/Core/InputCommon/ControllerEmu/StickGate.cpp
parentab8a128588b61f2651a567b42d298edb3052cefe (diff)
Virtual Notch settings and UI for octagonal stick
Diffstat (limited to 'Source/Core/InputCommon/ControllerEmu/StickGate.cpp')
-rw-r--r--Source/Core/InputCommon/ControllerEmu/StickGate.cpp22
1 files changed, 20 insertions, 2 deletions
diff --git a/Source/Core/InputCommon/ControllerEmu/StickGate.cpp b/Source/Core/InputCommon/ControllerEmu/StickGate.cpp
index 1497471c14..797d19aadf 100644
--- a/Source/Core/InputCommon/ControllerEmu/StickGate.cpp
+++ b/Source/Core/InputCommon/ControllerEmu/StickGate.cpp
@@ -48,6 +48,16 @@ std::optional<double> GetRayLineIntersection(Common::DVec2 ray, Common::DVec2 po
return diff.Cross(-point1) / dot;
}
+double GetNearestNotch(double angle, double virtual_notch_angle)
+{
+ constexpr auto sides = 8;
+ constexpr auto rounding = MathUtil::TAU / sides;
+ const auto closest_notch = std::round(angle / rounding) * rounding;
+ const auto angle_diff =
+ std::fmod(angle - closest_notch + MathUtil::PI, MathUtil::TAU) - MathUtil::PI;
+ return std::abs(angle_diff) < virtual_notch_angle / 2 ? closest_notch : angle;
+}
+
Common::DVec2 GetPointFromAngleAndLength(double angle, double length)
{
return Common::DVec2{std::cos(angle), std::sin(angle)} * length;
@@ -276,16 +286,24 @@ ReshapableInput::ReshapeData ReshapableInput::Reshape(ControlState x, ControlSta
y -= m_center.y;
// TODO: make the AtAngle functions work with negative angles:
- const ControlState angle = std::atan2(y, x) + MathUtil::TAU;
+ ControlState angle = std::atan2(y, x) + MathUtil::TAU;
- const ControlState gate_max_dist = GetGateRadiusAtAngle(angle);
const ControlState input_max_dist = GetInputRadiusAtAngle(angle);
+ ControlState gate_max_dist = GetGateRadiusAtAngle(angle);
// If input radius (from calibration) is zero apply no scaling to prevent division by zero.
const ControlState max_dist = input_max_dist ? input_max_dist : gate_max_dist;
ControlState dist = Common::DVec2{x, y}.Length() / max_dist;
+ const double virtual_notch_size = GetVirtualNotchSize();
+
+ if (virtual_notch_size > 0.0 && dist >= MINIMUM_NOTCH_DISTANCE)
+ {
+ angle = GetNearestNotch(angle, virtual_notch_size);
+ gate_max_dist = GetGateRadiusAtAngle(angle);
+ }
+
// 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%.
if (modifier)