mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-15 08:49:20 +01:00
Merge pull request #8647 from jordan-woyak/minor-input-cleanups
InputCommon: Minor ReshapableInput related cleanups.
This commit is contained in:
commit
4944e4b429
@ -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{});
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
};
|
};
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user