summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorJordan Woyak <jordan.woyak@gmail.com>2018-12-21 16:11:00 -0600
committerJordan Woyak <jordan.woyak@gmail.com>2018-12-27 18:31:46 -0600
commitda9bcf83efeb1ede43e1c2ac08e6869ce8a2c15a (patch)
tree9418d35e0e0233bf26f91871002888dd9570bf79 /Source/Core
parentceb28a2302e23b2484bca63626605d3fd56a1f11 (diff)
InputCommon: Simplified StickGate interface and moved class into its own file. Changed default input radius to perform no resizing. Tweaked the indicator colors a bit to improve visibility. Cleaned up some math and code.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp7
-rw-r--r--Source/Core/InputCommon/CMakeLists.txt1
-rw-r--r--Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp60
-rw-r--r--Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.h45
-rw-r--r--Source/Core/InputCommon/ControllerEmu/StickGate.cpp47
-rw-r--r--Source/Core/InputCommon/ControllerEmu/StickGate.h55
-rw-r--r--Source/Core/InputCommon/InputCommon.vcxproj4
-rw-r--r--Source/Core/InputCommon/InputCommon.vcxproj.filters6
8 files changed, 125 insertions, 100 deletions
diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp
index 538e67bc5c..e6e8c72875 100644
--- a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp
+++ b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp
@@ -159,7 +159,8 @@ void MappingIndicator::DrawStick()
{
// Make the c-stick yellow:
const bool is_c_stick = m_group->name == "C-Stick";
- const QColor gate_color = is_c_stick ? Qt::yellow : Qt::lightGray;
+ const QColor gate_brush_color = is_c_stick ? Qt::yellow : Qt::lightGray;
+ const QColor gate_pen_color = gate_brush_color.darker(125);
auto& stick = *static_cast<ControllerEmu::AnalogStick*>(m_group);
@@ -191,8 +192,8 @@ void MappingIndicator::DrawStick()
p.setRenderHint(QPainter::SmoothPixmapTransform, true);
// Input gate. (i.e. the octagon shape)
- p.setPen(Qt::darkGray);
- p.setBrush(gate_color);
+ p.setPen(gate_pen_color);
+ p.setBrush(gate_brush_color);
p.drawPolygon(GetPolygonFromRadiusGetter(
[&stick](double ang) { return stick.GetGateRadiusAtAngle(ang); }, scale));
diff --git a/Source/Core/InputCommon/CMakeLists.txt b/Source/Core/InputCommon/CMakeLists.txt
index a3ef2722d8..ece9bbbde8 100644
--- a/Source/Core/InputCommon/CMakeLists.txt
+++ b/Source/Core/InputCommon/CMakeLists.txt
@@ -2,6 +2,7 @@ add_library(inputcommon
InputConfig.cpp
InputProfile.cpp
ControllerEmu/ControllerEmu.cpp
+ ControllerEmu/StickGate.cpp
ControllerEmu/Control/Control.cpp
ControllerEmu/Control/Input.cpp
ControllerEmu/Control/Output.cpp
diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp b/Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp
index 5368c6b7ba..3f766d5e45 100644
--- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp
+++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp
@@ -4,9 +4,7 @@
#include "InputCommon/ControllerEmu/ControlGroup/AnalogStick.h"
-#include <algorithm>
#include <cmath>
-#include <memory>
#include "Common/Common.h"
#include "Common/MathUtil.h"
@@ -33,8 +31,10 @@ AnalogStick::AnalogStick(const char* const name_, const char* const ui_name_,
controls.emplace_back(std::make_unique<Input>(Translate, _trans("Modifier")));
+ // Set default input radius to that of the gate radius (no resizing)
numeric_settings.emplace_back(
- std::make_unique<NumericSetting>(_trans("Input Radius"), 1.0, 0, 100));
+ std::make_unique<NumericSetting>(_trans("Input Radius"), GetGateRadiusAtAngle(0.0), 0, 100));
+ // 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));
@@ -50,9 +50,7 @@ AnalogStick::StateData AnalogStick::GetState(bool adjusted)
return {x, y};
// TODO: make the AtAngle functions work with negative angles:
- const ControlState ang = atan2(y, x) + MathUtil::TAU;
- const ControlState ang_sin = sin(ang);
- const ControlState ang_cos = cos(ang);
+ const ControlState ang = std::atan2(y, x) + MathUtil::TAU;
const ControlState gate_max_dist = GetGateRadiusAtAngle(ang);
const ControlState input_max_dist = GetInputRadiusAtAngle(ang);
@@ -82,9 +80,8 @@ AnalogStick::StateData AnalogStick::GetState(bool adjusted)
// Scale to the gate shape/radius:
dist = dist *= gate_max_dist;
- y = std::max(-1.0, std::min(1.0, ang_sin * dist));
- x = std::max(-1.0, std::min(1.0, ang_cos * 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};
}
@@ -111,57 +108,16 @@ ControlState AnalogStick::CalculateInputShapeRadiusAtAngle(double ang) const
{
// Between 0 and 25 return a shape between octagon and circle
const auto amt = shape;
- return OctagonStickGate::ComputeRadiusAtAngle(ang) * (1 - amt) + amt;
+ 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::ComputeRadiusAtAngle(ang) * amt;
+ return (1 - amt) + SquareStickGate(1).GetRadiusAtAngle(ang) * amt;
}
}
-OctagonStickGate::OctagonStickGate(ControlState radius) : m_radius(radius)
-{
-}
-
-ControlState OctagonStickGate::GetRadiusAtAngle(double ang) const
-{
- return ComputeRadiusAtAngle(ang) * m_radius;
-}
-
-ControlState OctagonStickGate::ComputeRadiusAtAngle(double ang)
-{
- // Ratio of octagon circumcircle to incircle:
- const double incircle_radius = 0.923879532511287;
- const double section_ang = MathUtil::TAU / 8;
- return incircle_radius / std::cos(std::fmod(ang, section_ang) - section_ang / 2);
-}
-
-RoundStickGate::RoundStickGate(ControlState radius) : m_radius(radius)
-{
-}
-
-ControlState RoundStickGate::GetRadiusAtAngle(double) const
-{
- return m_radius;
-}
-
-SquareStickGate::SquareStickGate(ControlState half_width) : m_half_width(half_width)
-{
-}
-
-ControlState SquareStickGate::GetRadiusAtAngle(double ang) const
-{
- return ComputeRadiusAtAngle(ang) * m_half_width;
-}
-
-ControlState SquareStickGate::ComputeRadiusAtAngle(double ang)
-{
- const double section_ang = MathUtil::TAU / 4;
- return 1 / std::cos(std::fmod(ang + section_ang / 2, section_ang) - section_ang / 2);
-}
-
OctagonAnalogStick::OctagonAnalogStick(const char* name, ControlState gate_radius)
: OctagonAnalogStick(name, name, gate_radius)
{
diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.h b/Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.h
index 336669124a..2351189f74 100644
--- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.h
+++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.h
@@ -5,54 +5,11 @@
#pragma once
#include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h"
+#include "InputCommon/ControllerEmu/StickGate.h"
#include "InputCommon/ControllerInterface/Device.h"
namespace ControllerEmu
{
-// An abstract class representing the plastic shell that limits an analog stick's movement.
-class StickGate
-{
-public:
- // Angle is in radians and should be non-negative
- virtual ControlState GetRadiusAtAngle(double ang) const = 0;
-};
-
-// An octagon-shaped stick gate is found on most Nintendo GC/Wii analog sticks.
-class OctagonStickGate : public StickGate
-{
-public:
- explicit OctagonStickGate(ControlState radius);
- ControlState GetRadiusAtAngle(double ang) const override;
-
- static ControlState ComputeRadiusAtAngle(double ang);
-
- const ControlState m_radius;
-};
-
-// A round-shaped stick gate. Possibly found on 3rd-party accessories.
-class RoundStickGate : public StickGate
-{
-public:
- explicit RoundStickGate(ControlState radius);
- ControlState GetRadiusAtAngle(double ang) const override;
-
-private:
- const ControlState m_radius;
-};
-
-// A square-shaped stick gate. e.g. keyboard input.
-class SquareStickGate : public StickGate
-{
-public:
- explicit SquareStickGate(ControlState half_width);
- ControlState GetRadiusAtAngle(double ang) const override;
-
- static ControlState ComputeRadiusAtAngle(double ang);
-
-private:
- const ControlState m_half_width;
-};
-
class AnalogStick : public ControlGroup
{
public:
diff --git a/Source/Core/InputCommon/ControllerEmu/StickGate.cpp b/Source/Core/InputCommon/ControllerEmu/StickGate.cpp
new file mode 100644
index 0000000000..c0c2a668a3
--- /dev/null
+++ b/Source/Core/InputCommon/ControllerEmu/StickGate.cpp
@@ -0,0 +1,47 @@
+// Copyright 2018 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "InputCommon/ControllerEmu/StickGate.h"
+
+#include <cmath>
+
+#include "Common/MathUtil.h"
+
+namespace ControllerEmu
+{
+OctagonStickGate::OctagonStickGate(ControlState radius) : m_radius(radius)
+{
+}
+
+ControlState OctagonStickGate::GetRadiusAtAngle(double ang) const
+{
+ constexpr int sides = 8;
+ constexpr double sum_int_angles = (sides - 2) * MathUtil::PI;
+ constexpr double half_int_angle = sum_int_angles / sides / 2;
+
+ ang = std::fmod(ang, MathUtil::TAU / sides);
+ // Solve ASA triangle using The Law of Sines:
+ return m_radius / std::sin(MathUtil::PI - ang - half_int_angle) * std::sin(half_int_angle);
+}
+
+RoundStickGate::RoundStickGate(ControlState radius) : m_radius(radius)
+{
+}
+
+ControlState RoundStickGate::GetRadiusAtAngle(double) const
+{
+ return m_radius;
+}
+
+SquareStickGate::SquareStickGate(ControlState half_width) : m_half_width(half_width)
+{
+}
+
+ControlState SquareStickGate::GetRadiusAtAngle(double ang) const
+{
+ constexpr double section_ang = MathUtil::TAU / 4;
+ return m_half_width / std::cos(std::fmod(ang + section_ang / 2, section_ang) - section_ang / 2);
+}
+
+} // namespace ControllerEmu
diff --git a/Source/Core/InputCommon/ControllerEmu/StickGate.h b/Source/Core/InputCommon/ControllerEmu/StickGate.h
new file mode 100644
index 0000000000..decb15d234
--- /dev/null
+++ b/Source/Core/InputCommon/ControllerEmu/StickGate.h
@@ -0,0 +1,55 @@
+// Copyright 2018 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "InputCommon/ControlReference/ControlReference.h"
+
+namespace ControllerEmu
+{
+// An abstract class representing the plastic shell that limits an analog stick's movement.
+class StickGate
+{
+public:
+ // Angle is in radians and should be non-negative
+ virtual ControlState GetRadiusAtAngle(double ang) const = 0;
+
+ virtual ~StickGate() = default;
+};
+
+// An octagon-shaped stick gate is found on most Nintendo GC/Wii analog sticks.
+class OctagonStickGate : public StickGate
+{
+public:
+ // Radius of circumscribed circle
+ explicit OctagonStickGate(ControlState radius);
+ ControlState GetRadiusAtAngle(double ang) const override final;
+
+private:
+ const ControlState m_radius;
+};
+
+// A round-shaped stick gate. Possibly found on 3rd-party accessories.
+class RoundStickGate : public StickGate
+{
+public:
+ explicit RoundStickGate(ControlState radius);
+ ControlState GetRadiusAtAngle(double ang) const override final;
+
+private:
+ const ControlState m_radius;
+};
+
+// A square-shaped stick gate. e.g. keyboard input.
+class SquareStickGate : public StickGate
+{
+public:
+ explicit SquareStickGate(ControlState half_width);
+ ControlState GetRadiusAtAngle(double ang) const override final;
+
+private:
+ const ControlState m_half_width;
+};
+
+} // namespace ControllerEmu
diff --git a/Source/Core/InputCommon/InputCommon.vcxproj b/Source/Core/InputCommon/InputCommon.vcxproj
index 0b5dc08018..2bef816726 100644
--- a/Source/Core/InputCommon/InputCommon.vcxproj
+++ b/Source/Core/InputCommon/InputCommon.vcxproj
@@ -37,6 +37,7 @@
<PropertyGroup Label="UserMacros" />
<ItemGroup>
<ClCompile Include="ControllerEmu\ControllerEmu.cpp" />
+ <ClCompile Include="ControllerEmu\StickGate.cpp" />
<ClCompile Include="ControllerEmu\Control\Control.cpp" />
<ClCompile Include="ControllerEmu\Control\Input.cpp" />
<ClCompile Include="ControllerEmu\Control\Output.cpp" />
@@ -75,6 +76,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="ControllerEmu\ControllerEmu.h" />
+ <ClInclude Include="ControllerEmu\StickGate.h" />
<ClInclude Include="ControllerEmu\Control\Control.h" />
<ClInclude Include="ControllerEmu\Control\Input.h" />
<ClInclude Include="ControllerEmu\Control\Output.h" />
@@ -119,4 +121,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
-</Project> \ No newline at end of file
+</Project>
diff --git a/Source/Core/InputCommon/InputCommon.vcxproj.filters b/Source/Core/InputCommon/InputCommon.vcxproj.filters
index c67333497c..01c5c371b6 100644
--- a/Source/Core/InputCommon/InputCommon.vcxproj.filters
+++ b/Source/Core/InputCommon/InputCommon.vcxproj.filters
@@ -32,6 +32,9 @@
<ClCompile Include="ControllerEmu\ControllerEmu.cpp">
<Filter>ControllerEmu</Filter>
</ClCompile>
+ <ClCompile Include="ControllerEmu\StickGate.cpp">
+ <Filter>ControllerEmu</Filter>
+ </ClCompile>
<ClCompile Include="ControllerEmu\Control\Control.cpp">
<Filter>ControllerEmu\Control</Filter>
</ClCompile>
@@ -119,6 +122,9 @@
<ClInclude Include="ControllerEmu\ControllerEmu.h">
<Filter>ControllerEmu</Filter>
</ClInclude>
+ <ClInclude Include="ControllerEmu\StickGate.h">
+ <Filter>ControllerEmu</Filter>
+ </ClInclude>
<ClInclude Include="ControllerEmu\Control\Control.h">
<Filter>ControllerEmu\Control</Filter>
</ClInclude>