From f8cca9fe5dc93b051fbb63247edad99533f19bfc Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Mon, 24 Feb 2020 16:55:44 -0600 Subject: [PATCH 1/5] InputCommon: RoundStickGate's ideal sample count can be 1. --- Source/Core/InputCommon/ControllerEmu/StickGate.cpp | 8 +++++++- Source/Core/InputCommon/ControllerEmu/StickGate.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Source/Core/InputCommon/ControllerEmu/StickGate.cpp b/Source/Core/InputCommon/ControllerEmu/StickGate.cpp index 0b16103773..3346b874a2 100644 --- a/Source/Core/InputCommon/ControllerEmu/StickGate.cpp +++ b/Source/Core/InputCommon/ControllerEmu/StickGate.cpp @@ -54,7 +54,7 @@ constexpr int ReshapableInput::CALIBRATION_SAMPLE_COUNT; std::optional StickGate::GetIdealCalibrationSampleCount() const { - return {}; + return std::nullopt; } OctagonStickGate::OctagonStickGate(ControlState radius) : m_radius(radius) @@ -86,6 +86,12 @@ ControlState RoundStickGate::GetRadiusAtAngle(double) const return m_radius; } +std::optional RoundStickGate::GetIdealCalibrationSampleCount() const +{ + // The "radius" is the same at every angle so a single sample is enough. + return 1; +} + SquareStickGate::SquareStickGate(ControlState half_width) : m_half_width(half_width) { } diff --git a/Source/Core/InputCommon/ControllerEmu/StickGate.h b/Source/Core/InputCommon/ControllerEmu/StickGate.h index 217c7f56d7..d044f1932c 100644 --- a/Source/Core/InputCommon/ControllerEmu/StickGate.h +++ b/Source/Core/InputCommon/ControllerEmu/StickGate.h @@ -48,6 +48,7 @@ class RoundStickGate : public StickGate public: explicit RoundStickGate(ControlState radius); ControlState GetRadiusAtAngle(double ang) const override final; + std::optional GetIdealCalibrationSampleCount() const override final; private: const ControlState m_radius; From bd43e084f4e911d5eeec2f237559f382cd89f795 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Mon, 24 Feb 2020 16:58:25 -0600 Subject: [PATCH 2/5] InputCommon: Clamp calibration values within square shape. --- Source/Core/InputCommon/ControllerEmu/StickGate.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Core/InputCommon/ControllerEmu/StickGate.cpp b/Source/Core/InputCommon/ControllerEmu/StickGate.cpp index 3346b874a2..30c9acdcbd 100644 --- a/Source/Core/InputCommon/ControllerEmu/StickGate.cpp +++ b/Source/Core/InputCommon/ControllerEmu/StickGate.cpp @@ -183,7 +183,8 @@ void ReshapableInput::UpdateCalibrationData(CalibrationData& data, Common::DVec2 auto& calibration_sample = data[calibration_index]; // Update closest sample from provided x,y. - calibration_sample = std::max(calibration_sample, point.Length()); + calibration_sample = std::clamp(point.Length(), calibration_sample, + SquareStickGate(1).GetRadiusAtAngle(calibration_angle)); // Here we update all other samples in our calibration vector to maintain // a convex polygon containing our new calibration point. From ed24f32c5bf31bbb249f2748e38d6066bb7f72d1 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Mon, 24 Feb 2020 16:59:23 -0600 Subject: [PATCH 3/5] InputCommon: Specify ini value default when saving calibration "center". --- Source/Core/InputCommon/ControllerEmu/StickGate.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Source/Core/InputCommon/ControllerEmu/StickGate.cpp b/Source/Core/InputCommon/ControllerEmu/StickGate.cpp index 30c9acdcbd..5e2acb3f5b 100644 --- a/Source/Core/InputCommon/ControllerEmu/StickGate.cpp +++ b/Source/Core/InputCommon/ControllerEmu/StickGate.cpp @@ -282,10 +282,11 @@ void ReshapableInput::SaveConfig(IniFile::Section* section, const std::string& d [](ControlState val) { return fmt::format("{:.2f}", val * CALIBRATION_CONFIG_SCALE); }); section->Set(group + CALIBRATION_CONFIG_NAME, JoinStrings(save_data, " "), ""); - const auto center_data = fmt::format("{:.2f} {:.2f}", m_center.x * CENTER_CONFIG_SCALE, + // Save center value. + static constexpr char center_format[] = "{:.2f} {:.2f}"; + const auto center_data = fmt::format(center_format, m_center.x * CENTER_CONFIG_SCALE, m_center.y * CENTER_CONFIG_SCALE); - - section->Set(group + CENTER_CONFIG_NAME, center_data, ""); + section->Set(group + CENTER_CONFIG_NAME, center_data, fmt::format(center_format, 0.0, 0.0)); } ReshapableInput::ReshapeData ReshapableInput::Reshape(ControlState x, ControlState y, From 2c843ae06b61066c597804d35b7f3ba2280e8d0f Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Tue, 25 Feb 2020 17:19:39 -0600 Subject: [PATCH 4/5] DolphinQt: Clean up calibration drawing a bit. --- .../Config/Mapping/MappingIndicator.cpp | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp index f29555c2ef..71782e0f74 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp @@ -149,7 +149,7 @@ constexpr int SPHERE_POINT_COUNT = 200; // Constructs a polygon by querying a radius at varying angles: template -QPolygonF GetPolygonFromRadiusGetter(F&& radius_getter, Common::DVec2 center = {0.0, 0.0}) +QPolygonF GetPolygonFromRadiusGetter(F&& radius_getter) { // A multiple of 8 (octagon) and enough points to be visibly pleasing: constexpr int shape_point_count = 32; @@ -161,7 +161,7 @@ QPolygonF GetPolygonFromRadiusGetter(F&& radius_getter, Common::DVec2 center = { const double angle = MathUtil::TAU * p / shape.size(); const double radius = radius_getter(angle); - point = {std::cos(angle) * radius + center.x, std::sin(angle) * radius + center.y}; + point = {std::cos(angle) * radius, std::sin(angle) * radius}; ++p; } @@ -302,25 +302,30 @@ void ReshapableInputIndicator::DrawReshapableInput( const auto center = stick.GetCenter(); + p.save(); + p.translate(center.x, center.y); + // Deadzone. p.setPen(GetDeadZonePen()); p.setBrush(GetDeadZoneBrush(p)); p.drawPolygon(GetPolygonFromRadiusGetter( - [&stick](double ang) { return stick.GetDeadzoneRadiusAtAngle(ang); }, center)); + [&stick](double ang) { return stick.GetDeadzoneRadiusAtAngle(ang); })); // Input shape. p.setPen(GetInputShapePen()); p.setBrush(Qt::NoBrush); p.drawPolygon(GetPolygonFromRadiusGetter( - [&stick](double ang) { return stick.GetInputRadiusAtAngle(ang); }, center)); + [&stick](double ang) { return stick.GetInputRadiusAtAngle(ang); })); // Center. if (center.x || center.y) { p.setPen(GetInputDotPen(GetCenterColor())); - p.drawPoint(QPointF{center.x, center.y}); + p.drawPoint(QPointF{}); } + p.restore(); + // Raw stick position. p.setPen(GetInputDotPen(GetRawInputColor())); p.drawPoint(QPointF{raw_coord.x, raw_coord.y}); @@ -745,23 +750,26 @@ void GyroMappingIndicator::Draw() void ReshapableInputIndicator::DrawCalibration(QPainter& p, Common::DVec2 point) { - // Bounding box size: const auto center = m_calibration_widget->GetCenter(); + p.save(); + p.translate(center.x, center.y); + // Input shape. p.setPen(GetInputShapePen()); p.setBrush(Qt::NoBrush); p.drawPolygon(GetPolygonFromRadiusGetter( - [this](double angle) { return m_calibration_widget->GetCalibrationRadiusAtAngle(angle); }, - center)); + [this](double angle) { return m_calibration_widget->GetCalibrationRadiusAtAngle(angle); })); // Center. if (center.x || center.y) { p.setPen(GetInputDotPen(GetCenterColor())); - p.drawPoint(QPointF{center.x, center.y}); + p.drawPoint(QPointF{}); } + p.restore(); + // Stick position. p.setPen(GetInputDotPen(GetAdjustedInputColor())); p.drawPoint(QPointF{point.x, point.y}); From 2451a41a48ae283bc66bd85f8a34093233552a53 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Tue, 25 Feb 2020 18:36:56 -0600 Subject: [PATCH 5/5] DolphinQt: Fix calibration cancel behavior. --- .../Config/Mapping/MappingIndicator.cpp | 21 ++++++++----------- .../Config/Mapping/MappingIndicator.h | 4 +--- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp index 71782e0f74..bc27985915 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp @@ -825,11 +825,11 @@ void CalibrationWidget::SetupActions() connect(calibrate_action, &QAction::triggered, [this]() { StartCalibration(); - m_input.SetCenter({0, 0}); + m_new_center = Common::DVec2{}; }); connect(center_action, &QAction::triggered, [this]() { StartCalibration(); - m_is_centering = true; + m_new_center = std::nullopt; }); connect(reset_action, &QAction::triggered, [this]() { m_input.SetCalibrationToDefault(); @@ -846,7 +846,7 @@ void CalibrationWidget::SetupActions() m_completion_action = new QAction(tr("Finish Calibration"), this); connect(m_completion_action, &QAction::triggered, [this]() { - m_input.SetCenter(m_new_center); + m_input.SetCenter(GetCenter()); m_input.SetCalibrationData(std::move(m_calibration_data)); m_informative_timer->stop(); SetupActions(); @@ -857,8 +857,6 @@ void CalibrationWidget::StartCalibration() { m_calibration_data.assign(m_input.CALIBRATION_SAMPLE_COUNT, 0.0); - m_new_center = {0, 0}; - // Cancel calibration. const auto cancel_action = new QAction(tr("Cancel Calibration"), this); connect(cancel_action, &QAction::triggered, [this]() { @@ -883,14 +881,13 @@ void CalibrationWidget::Update(Common::DVec2 point) QFont f = parentWidget()->font(); QPalette p = parentWidget()->palette(); - if (m_is_centering) - { + // Use current point if center is being calibrated. + if (!m_new_center.has_value()) m_new_center = point; - m_is_centering = false; - } - else if (IsCalibrating()) + + if (IsCalibrating()) { - m_input.UpdateCalibrationData(m_calibration_data, point - m_new_center); + m_input.UpdateCalibrationData(m_calibration_data, point - *m_new_center); if (IsCalibrationDataSensible(m_calibration_data)) { @@ -920,5 +917,5 @@ double CalibrationWidget::GetCalibrationRadiusAtAngle(double angle) const Common::DVec2 CalibrationWidget::GetCenter() const { - return m_new_center; + return m_new_center.value_or(Common::DVec2{}); } diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.h b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.h index 7a57af3fb0..763c9e3db7 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.h +++ b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.h @@ -203,7 +203,5 @@ private: QAction* m_completion_action; ControllerEmu::ReshapableInput::CalibrationData m_calibration_data; QTimer* m_informative_timer; - - bool m_is_centering = false; - Common::DVec2 m_new_center; + std::optional m_new_center; };