summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon/ControllerEmu/ControlGroup/Tilt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/InputCommon/ControllerEmu/ControlGroup/Tilt.cpp')
-rw-r--r--Source/Core/InputCommon/ControllerEmu/ControlGroup/Tilt.cpp99
1 files changed, 99 insertions, 0 deletions
diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Tilt.cpp b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Tilt.cpp
new file mode 100644
index 0000000000..5481d92606
--- /dev/null
+++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Tilt.cpp
@@ -0,0 +1,99 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "InputCommon/ControllerEmu/ControlGroup/Tilt.h"
+
+#include <algorithm>
+#include <cmath>
+#include <cstring>
+#include <memory>
+#include <string>
+
+#include "Common/Common.h"
+#include "InputCommon/ControlReference/ControlReference.h"
+#include "InputCommon/ControllerEmu/Control/Control.h"
+#include "InputCommon/ControllerEmu/Control/Input.h"
+
+namespace ControllerEmu
+{
+Tilt::Tilt(const std::string& name_) : ControlGroup(name_, GROUP_TYPE_TILT)
+{
+ memset(m_tilt, 0, sizeof(m_tilt));
+
+ controls.emplace_back(std::make_unique<Input>("Forward"));
+ controls.emplace_back(std::make_unique<Input>("Backward"));
+ controls.emplace_back(std::make_unique<Input>("Left"));
+ controls.emplace_back(std::make_unique<Input>("Right"));
+
+ controls.emplace_back(std::make_unique<Input>(_trans("Modifier")));
+
+ numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Dead Zone"), 0, 0, 50));
+ numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Circle Stick"), 0));
+ numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Angle"), 0.9, 0, 180));
+}
+
+void Tilt::GetState(ControlState* const x, ControlState* const y, const bool step)
+{
+ // this is all a mess
+
+ ControlState yy = controls[0]->control_ref->State() - controls[1]->control_ref->State();
+ ControlState xx = controls[3]->control_ref->State() - controls[2]->control_ref->State();
+
+ ControlState deadzone = numeric_settings[0]->GetValue();
+ ControlState circle = numeric_settings[1]->GetValue();
+ auto const angle = numeric_settings[2]->GetValue() / 1.8;
+ ControlState m = controls[4]->control_ref->State();
+
+ // deadzone / circle stick code
+ // this section might be all wrong, but its working good enough, I think
+
+ ControlState ang = atan2(yy, xx);
+ ControlState ang_sin = sin(ang);
+ ControlState ang_cos = cos(ang);
+
+ // the amt a full square stick would have at current angle
+ ControlState square_full =
+ std::min(ang_sin ? 1 / fabs(ang_sin) : 2, ang_cos ? 1 / fabs(ang_cos) : 2);
+
+ // the amt a full stick would have that was (user setting circular) at current angle
+ // I think this is more like a pointed circle rather than a rounded square like it should be
+ ControlState stick_full = (square_full * (1 - circle)) + (circle);
+
+ ControlState dist = sqrt(xx * xx + yy * yy);
+
+ // dead zone code
+ dist = std::max(0.0, dist - deadzone * stick_full);
+ dist /= (1 - deadzone);
+
+ // circle stick code
+ ControlState amt = dist / stick_full;
+ dist += (square_full - 1) * amt * circle;
+
+ if (m)
+ dist *= 0.5;
+
+ yy = std::max(-1.0, std::min(1.0, ang_sin * dist));
+ xx = std::max(-1.0, std::min(1.0, ang_cos * dist));
+
+ // this is kinda silly here
+ // gui being open will make this happen 2x as fast, o well
+
+ // silly
+ if (step)
+ {
+ if (xx > m_tilt[0])
+ m_tilt[0] = std::min(m_tilt[0] + 0.1, xx);
+ else if (xx < m_tilt[0])
+ m_tilt[0] = std::max(m_tilt[0] - 0.1, xx);
+
+ if (yy > m_tilt[1])
+ m_tilt[1] = std::min(m_tilt[1] + 0.1, yy);
+ else if (yy < m_tilt[1])
+ m_tilt[1] = std::max(m_tilt[1] - 0.1, yy);
+ }
+
+ *y = m_tilt[1] * angle;
+ *x = m_tilt[0] * angle;
+}
+} // namespace ControllerEmu