Merge pull request #8647 from jordan-woyak/minor-input-cleanups

InputCommon: Minor ReshapableInput related cleanups.
This commit is contained in:
Léo Lam 2020-03-15 15:06:54 +01:00 committed by GitHub
commit 4944e4b429
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 29 deletions

View File

@ -149,7 +149,7 @@ constexpr int SPHERE_POINT_COUNT = 200;
// Constructs a polygon by querying a radius at varying angles: // Constructs a polygon by querying a radius at varying angles:
template <typename F> template <typename F>
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: // A multiple of 8 (octagon) and enough points to be visibly pleasing:
constexpr int shape_point_count = 32; 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 angle = MathUtil::TAU * p / shape.size();
const double radius = radius_getter(angle); 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; ++p;
} }
@ -302,25 +302,30 @@ void ReshapableInputIndicator::DrawReshapableInput(
const auto center = stick.GetCenter(); const auto center = stick.GetCenter();
p.save();
p.translate(center.x, center.y);
// Deadzone. // Deadzone.
p.setPen(GetDeadZonePen()); p.setPen(GetDeadZonePen());
p.setBrush(GetDeadZoneBrush(p)); p.setBrush(GetDeadZoneBrush(p));
p.drawPolygon(GetPolygonFromRadiusGetter( p.drawPolygon(GetPolygonFromRadiusGetter(
[&stick](double ang) { return stick.GetDeadzoneRadiusAtAngle(ang); }, center)); [&stick](double ang) { return stick.GetDeadzoneRadiusAtAngle(ang); }));
// Input shape. // Input shape.
p.setPen(GetInputShapePen()); p.setPen(GetInputShapePen());
p.setBrush(Qt::NoBrush); p.setBrush(Qt::NoBrush);
p.drawPolygon(GetPolygonFromRadiusGetter( p.drawPolygon(GetPolygonFromRadiusGetter(
[&stick](double ang) { return stick.GetInputRadiusAtAngle(ang); }, center)); [&stick](double ang) { return stick.GetInputRadiusAtAngle(ang); }));
// Center. // Center.
if (center.x || center.y) if (center.x || center.y)
{ {
p.setPen(GetInputDotPen(GetCenterColor())); p.setPen(GetInputDotPen(GetCenterColor()));
p.drawPoint(QPointF{center.x, center.y}); p.drawPoint(QPointF{});
} }
p.restore();
// Raw stick position. // Raw stick position.
p.setPen(GetInputDotPen(GetRawInputColor())); p.setPen(GetInputDotPen(GetRawInputColor()));
p.drawPoint(QPointF{raw_coord.x, raw_coord.y}); p.drawPoint(QPointF{raw_coord.x, raw_coord.y});
@ -745,23 +750,26 @@ void GyroMappingIndicator::Draw()
void ReshapableInputIndicator::DrawCalibration(QPainter& p, Common::DVec2 point) void ReshapableInputIndicator::DrawCalibration(QPainter& p, Common::DVec2 point)
{ {
// Bounding box size:
const auto center = m_calibration_widget->GetCenter(); const auto center = m_calibration_widget->GetCenter();
p.save();
p.translate(center.x, center.y);
// Input shape. // Input shape.
p.setPen(GetInputShapePen()); p.setPen(GetInputShapePen());
p.setBrush(Qt::NoBrush); p.setBrush(Qt::NoBrush);
p.drawPolygon(GetPolygonFromRadiusGetter( p.drawPolygon(GetPolygonFromRadiusGetter(
[this](double angle) { return m_calibration_widget->GetCalibrationRadiusAtAngle(angle); }, [this](double angle) { return m_calibration_widget->GetCalibrationRadiusAtAngle(angle); }));
center));
// Center. // Center.
if (center.x || center.y) if (center.x || center.y)
{ {
p.setPen(GetInputDotPen(GetCenterColor())); p.setPen(GetInputDotPen(GetCenterColor()));
p.drawPoint(QPointF{center.x, center.y}); p.drawPoint(QPointF{});
} }
p.restore();
// Stick position. // Stick position.
p.setPen(GetInputDotPen(GetAdjustedInputColor())); p.setPen(GetInputDotPen(GetAdjustedInputColor()));
p.drawPoint(QPointF{point.x, point.y}); p.drawPoint(QPointF{point.x, point.y});
@ -817,11 +825,11 @@ void CalibrationWidget::SetupActions()
connect(calibrate_action, &QAction::triggered, [this]() { connect(calibrate_action, &QAction::triggered, [this]() {
StartCalibration(); StartCalibration();
m_input.SetCenter({0, 0}); m_new_center = Common::DVec2{};
}); });
connect(center_action, &QAction::triggered, [this]() { connect(center_action, &QAction::triggered, [this]() {
StartCalibration(); StartCalibration();
m_is_centering = true; m_new_center = std::nullopt;
}); });
connect(reset_action, &QAction::triggered, [this]() { connect(reset_action, &QAction::triggered, [this]() {
m_input.SetCalibrationToDefault(); m_input.SetCalibrationToDefault();
@ -838,7 +846,7 @@ void CalibrationWidget::SetupActions()
m_completion_action = new QAction(tr("Finish Calibration"), this); m_completion_action = new QAction(tr("Finish Calibration"), this);
connect(m_completion_action, &QAction::triggered, [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_input.SetCalibrationData(std::move(m_calibration_data));
m_informative_timer->stop(); m_informative_timer->stop();
SetupActions(); SetupActions();
@ -849,8 +857,6 @@ void CalibrationWidget::StartCalibration()
{ {
m_calibration_data.assign(m_input.CALIBRATION_SAMPLE_COUNT, 0.0); m_calibration_data.assign(m_input.CALIBRATION_SAMPLE_COUNT, 0.0);
m_new_center = {0, 0};
// Cancel calibration. // Cancel calibration.
const auto cancel_action = new QAction(tr("Cancel Calibration"), this); const auto cancel_action = new QAction(tr("Cancel Calibration"), this);
connect(cancel_action, &QAction::triggered, [this]() { connect(cancel_action, &QAction::triggered, [this]() {
@ -875,14 +881,13 @@ void CalibrationWidget::Update(Common::DVec2 point)
QFont f = parentWidget()->font(); QFont f = parentWidget()->font();
QPalette p = parentWidget()->palette(); 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_new_center = point;
m_is_centering = false;
} if (IsCalibrating())
else 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)) if (IsCalibrationDataSensible(m_calibration_data))
{ {
@ -912,5 +917,5 @@ double CalibrationWidget::GetCalibrationRadiusAtAngle(double angle) const
Common::DVec2 CalibrationWidget::GetCenter() const Common::DVec2 CalibrationWidget::GetCenter() const
{ {
return m_new_center; return m_new_center.value_or(Common::DVec2{});
} }

View File

@ -203,7 +203,5 @@ private:
QAction* m_completion_action; QAction* m_completion_action;
ControllerEmu::ReshapableInput::CalibrationData m_calibration_data; ControllerEmu::ReshapableInput::CalibrationData m_calibration_data;
QTimer* m_informative_timer; QTimer* m_informative_timer;
std::optional<Common::DVec2> m_new_center;
bool m_is_centering = false;
Common::DVec2 m_new_center;
}; };

View File

@ -54,7 +54,7 @@ constexpr int ReshapableInput::CALIBRATION_SAMPLE_COUNT;
std::optional<u32> StickGate::GetIdealCalibrationSampleCount() const std::optional<u32> StickGate::GetIdealCalibrationSampleCount() const
{ {
return {}; return std::nullopt;
} }
OctagonStickGate::OctagonStickGate(ControlState radius) : m_radius(radius) OctagonStickGate::OctagonStickGate(ControlState radius) : m_radius(radius)
@ -86,6 +86,12 @@ ControlState RoundStickGate::GetRadiusAtAngle(double) const
return m_radius; return m_radius;
} }
std::optional<u32> 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) SquareStickGate::SquareStickGate(ControlState half_width) : m_half_width(half_width)
{ {
} }
@ -177,7 +183,8 @@ void ReshapableInput::UpdateCalibrationData(CalibrationData& data, Common::DVec2
auto& calibration_sample = data[calibration_index]; auto& calibration_sample = data[calibration_index];
// Update closest sample from provided x,y. // 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 // Here we update all other samples in our calibration vector to maintain
// a convex polygon containing our new calibration point. // a convex polygon containing our new calibration point.
@ -275,10 +282,11 @@ void ReshapableInput::SaveConfig(IniFile::Section* section, const std::string& d
[](ControlState val) { return fmt::format("{:.2f}", val * CALIBRATION_CONFIG_SCALE); }); [](ControlState val) { return fmt::format("{:.2f}", val * CALIBRATION_CONFIG_SCALE); });
section->Set(group + CALIBRATION_CONFIG_NAME, JoinStrings(save_data, " "), ""); 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); m_center.y * CENTER_CONFIG_SCALE);
section->Set(group + CENTER_CONFIG_NAME, center_data, fmt::format(center_format, 0.0, 0.0));
section->Set(group + CENTER_CONFIG_NAME, center_data, "");
} }
ReshapableInput::ReshapeData ReshapableInput::Reshape(ControlState x, ControlState y, ReshapableInput::ReshapeData ReshapableInput::Reshape(ControlState x, ControlState y,

View File

@ -48,6 +48,7 @@ class RoundStickGate : public StickGate
public: public:
explicit RoundStickGate(ControlState radius); explicit RoundStickGate(ControlState radius);
ControlState GetRadiusAtAngle(double ang) const override final; ControlState GetRadiusAtAngle(double ang) const override final;
std::optional<u32> GetIdealCalibrationSampleCount() const override final;
private: private:
const ControlState m_radius; const ControlState m_radius;