summaryrefslogtreecommitdiff
path: root/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp')
-rw-r--r--Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp150
1 files changed, 75 insertions, 75 deletions
diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp
index 5416b4fd2f..a09b41e5db 100644
--- a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp
+++ b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp
@@ -10,9 +10,11 @@
#include <QPainter>
#include <QTimer>
+#include "Common/MathUtil.h"
+
#include "InputCommon/ControlReference/ControlReference.h"
#include "InputCommon/ControllerEmu/Control/Control.h"
-#include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h"
+#include "InputCommon/ControllerEmu/ControlGroup/AnalogStick.h"
#include "InputCommon/ControllerEmu/Setting/NumericSetting.h"
#include "InputCommon/ControllerInterface/Device.h"
@@ -28,7 +30,7 @@ MappingIndicator::MappingIndicator(ControllerEmu::ControlGroup* group) : m_group
BindCursorControls(false);
break;
case ControllerEmu::GroupType::Stick:
- BindStickControls();
+ // Nothing needed:
break;
case ControllerEmu::GroupType::Tilt:
BindCursorControls(true);
@@ -68,18 +70,6 @@ void MappingIndicator::BindCursorControls(bool tilt)
}
}
-void MappingIndicator::BindStickControls()
-{
- m_stick_up = m_group->controls[0]->control_ref.get();
- m_stick_down = m_group->controls[1]->control_ref.get();
- m_stick_left = m_group->controls[2]->control_ref.get();
- m_stick_right = m_group->controls[3]->control_ref.get();
- m_stick_modifier = m_group->controls[4]->control_ref.get();
-
- m_stick_radius = m_group->numeric_settings[0].get();
- m_stick_deadzone = m_group->numeric_settings[1].get();
-}
-
void MappingIndicator::BindMixedTriggersControls()
{
m_mixed_triggers_l_button = m_group->controls[0]->control_ref.get();
@@ -144,83 +134,93 @@ void MappingIndicator::DrawCursor(bool tilt)
p.fillRect(curx, cury, 8, 8, Qt::red);
}
-void MappingIndicator::DrawStick()
+// Constructs a polygon by querying a radius at varying angles:
+template <typename F>
+QPolygonF GetPolygonFromRadiusGetter(F&& radius_getter, double scale)
{
- float centerx = width() / 2., centery = height() / 2.;
+ // A multiple of 8 (octagon) and enough points to be visibly pleasing:
+ constexpr int shape_point_count = 32;
+ QPolygonF shape{shape_point_count};
- bool c_stick = m_group->name == "C-Stick";
- bool classic_controller = m_group->name == "Left Stick" || m_group->name == "Right Stick";
+ int p = 0;
+ for (auto& point : shape)
+ {
+ const double angle = MathUtil::TAU * p / shape.size();
+ const double radius = radius_getter(angle) * scale;
- float ratio = 1;
+ point = {std::cos(angle) * radius, std::sin(angle) * radius};
+ ++p;
+ }
- if (c_stick)
- ratio = 1.;
- else if (classic_controller)
- ratio = 0.9f;
+ return shape;
+}
- // Polled values
- float mod = PollControlState(m_stick_modifier) ? 0.5 : 1;
- float radius = m_stick_radius->GetValue();
- float curx = -PollControlState(m_stick_left) + PollControlState(m_stick_right),
- cury = -PollControlState(m_stick_up) + PollControlState(m_stick_down);
- // The maximum deadzone value covers 50% of the stick area
- float deadzone = m_stick_deadzone->GetValue() / 2.;
+void MappingIndicator::DrawStick()
+{
+ // Make the c-stick yellow:
+ const bool is_c_stick = m_group->name == "C-Stick";
+ const QColor gate_brush_color = is_c_stick ? Qt::yellow : Qt::lightGray;
+ const QColor gate_pen_color = gate_brush_color.darker(125);
- // Size parameters
- float max_size = (height() / 2.5) / ratio;
- float stick_size = (height() / 3.) / ratio;
+ auto& stick = *static_cast<ControllerEmu::AnalogStick*>(m_group);
- // Emulated cursor position
- float virt_curx, virt_cury;
+ // TODO: This SetControllerStateNeeded interface leaks input into the game
+ // We should probably hold the mutex for UI updates.
+ Settings::Instance().SetControllerStateNeeded(true);
+ const auto raw_coord = stick.GetState(false);
+ const auto adj_coord = stick.GetState(true);
+ Settings::Instance().SetControllerStateNeeded(false);
- if (std::abs(curx) < deadzone && std::abs(cury) < deadzone)
- {
- virt_curx = virt_cury = 0;
- }
- else
- {
- virt_curx = curx * mod;
- virt_cury = cury * mod;
- }
+ // Bounding box size:
+ const double scale = height() / 2.5;
- // Coordinates for an octagon
- std::array<QPointF, 8> radius_octagon = {{
- QPointF(centerx, centery + stick_size), // Bottom
- QPointF(centerx + stick_size / sqrt(2), centery + stick_size / sqrt(2)), // Bottom Right
- QPointF(centerx + stick_size, centery), // Right
- QPointF(centerx + stick_size / sqrt(2), centery - stick_size / sqrt(2)), // Top Right
- QPointF(centerx, centery - stick_size), // Top
- QPointF(centerx - stick_size / sqrt(2), centery - stick_size / sqrt(2)), // Top Left
- QPointF(centerx - stick_size, centery), // Left
- QPointF(centerx - stick_size / sqrt(2), centery + stick_size / sqrt(2)) // Bottom Left
- }};
+ const float dot_radius = 2;
QPainter p(this);
- p.setRenderHint(QPainter::Antialiasing, true);
- p.setRenderHint(QPainter::SmoothPixmapTransform, true);
+ p.translate(width() / 2, height() / 2);
- // Draw maximum values
+ // Bounding box.
p.setBrush(Qt::white);
- p.setPen(Qt::black);
- p.drawRect(centerx - max_size, centery - max_size, max_size * 2, max_size * 2);
+ p.setPen(Qt::gray);
+ p.drawRect(-scale - 1, -scale - 1, scale * 2 + 1, scale * 2 + 1);
- // Draw radius
- p.setBrush(c_stick ? Qt::yellow : Qt::darkGray);
- p.drawPolygon(radius_octagon.data(), static_cast<int>(radius_octagon.size()));
+ // UI y-axis is opposite that of stick.
+ p.scale(1.0, -1.0);
- // Draw deadzone
- p.setBrush(c_stick ? Qt::darkYellow : Qt::lightGray);
- p.drawEllipse(centerx - deadzone * stick_size, centery - deadzone * stick_size,
- deadzone * stick_size * 2, deadzone * stick_size * 2);
-
- // Draw stick
- p.setBrush(Qt::black);
- p.drawEllipse(centerx - 4 + curx * max_size, centery - 4 + cury * max_size, 8, 8);
+ // Enable AA after drawing bounding box.
+ p.setRenderHint(QPainter::Antialiasing, true);
+ p.setRenderHint(QPainter::SmoothPixmapTransform, true);
- // Draw virtual stick
- p.setBrush(Qt::red);
- p.drawEllipse(centerx - 4 + virt_curx * max_size * radius,
- centery - 4 + virt_cury * max_size * radius, 8, 8);
+ // Input gate. (i.e. the octagon shape)
+ p.setPen(gate_pen_color);
+ p.setBrush(gate_brush_color);
+ p.drawPolygon(GetPolygonFromRadiusGetter(
+ [&stick](double ang) { return stick.GetGateRadiusAtAngle(ang); }, scale));
+
+ // Deadzone.
+ p.setPen(Qt::darkGray);
+ p.setBrush(QBrush(Qt::darkGray, Qt::BDiagPattern));
+ p.drawPolygon(GetPolygonFromRadiusGetter(
+ [&stick](double ang) { return stick.GetDeadzoneRadiusAtAngle(ang); }, scale));
+
+ // Input shape.
+ p.setPen(QPen(Qt::darkGray, 1.0, Qt::DashLine));
+ p.setBrush(Qt::NoBrush);
+ p.drawPolygon(GetPolygonFromRadiusGetter(
+ [&stick](double ang) { return stick.GetInputRadiusAtAngle(ang); }, scale));
+
+ // Raw stick position.
+ p.setPen(Qt::NoPen);
+ p.setBrush(Qt::darkGray);
+ p.drawEllipse(QPointF{raw_coord.x, raw_coord.y} * scale, dot_radius, dot_radius);
+
+ // Adjusted stick position.
+ if (adj_coord.x || adj_coord.y)
+ {
+ p.setPen(Qt::NoPen);
+ p.setBrush(Qt::red);
+ p.drawEllipse(QPointF{adj_coord.x, adj_coord.y} * scale, dot_radius, dot_radius);
+ }
}
void MappingIndicator::DrawMixedTriggers()