diff --git a/Source/Core/DolphinQt/Config/Mapping/IOWindow.cpp b/Source/Core/DolphinQt/Config/Mapping/IOWindow.cpp index b4dd1aa54a..aa0f1efa0d 100644 --- a/Source/Core/DolphinQt/Config/Mapping/IOWindow.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/IOWindow.cpp @@ -544,7 +544,7 @@ void InputStateDelegate::paint(QPainter* painter, const QStyleOptionViewItem& op rect.setWidth(rect.width() * std::clamp(state, 0.0, 1.0)); // Create a temporary indicator object to retreive color constants. - MappingIndicator indicator(nullptr); + MappingIndicator indicator; painter->save(); diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp index e6549e48d6..413038b452 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp @@ -105,14 +105,16 @@ void MappingIndicator::AdjustGateColor(QColor* color) color->setHsvF(color->hueF(), color->saturationF(), 1 - color->valueF()); } -MappingIndicator::MappingIndicator(ControllerEmu::ControlGroup* group) : m_group(group) +MappingIndicator::MappingIndicator() { // TODO: Make these magic numbers less ugly. - int required_height = 106; - - if (group && ControllerEmu::GroupType::MixedTriggers == group->type) - required_height = 64 + 1; + const int required_height = 106; + setFixedHeight(required_height); +} +MixedTriggersIndicator::MixedTriggersIndicator(ControllerEmu::MixedTriggers& group) : m_group(group) +{ + const int required_height = 64 + 1; setFixedHeight(required_height); } @@ -209,8 +211,16 @@ void GenerateFibonacciSphere(int point_count, F&& callback) } // namespace -void MappingIndicator::DrawCursor(ControllerEmu::Cursor& cursor) +void MappingIndicator::paintEvent(QPaintEvent*) { + const auto lock = ControllerEmu::EmulatedController::GetStateLock(); + Draw(); +} + +void CursorIndicator::Draw() +{ + auto& cursor = m_cursor_group; + const auto center = cursor.GetCenter(); QColor tv_brush_color = CURSOR_TV_COLOR; @@ -291,21 +301,12 @@ void MappingIndicator::DrawCursor(ControllerEmu::Cursor& cursor) } } -void MappingIndicator::DrawReshapableInput(ControllerEmu::ReshapableInput& stick) +void ReshapableInputIndicator::DrawReshapableInput( + ControllerEmu::ReshapableInput& stick, + const ControllerEmu::ReshapableInput::ReshapeData& adj_coord, QColor gate_brush_color) { - // Some hacks for pretty colors: - const bool is_c_stick = m_group->name == "C-Stick"; - const bool is_tilt = m_group->name == "Tilt"; - const auto center = stick.GetCenter(); - QColor gate_brush_color = STICK_GATE_COLOR; - - if (is_c_stick) - gate_brush_color = C_STICK_GATE_COLOR; - else if (is_tilt) - gate_brush_color = TILT_GATE_COLOR; - QColor gate_pen_color = gate_brush_color.darker(125); AdjustGateColor(&gate_brush_color); @@ -313,18 +314,6 @@ void MappingIndicator::DrawReshapableInput(ControllerEmu::ReshapableInput& stick const auto raw_coord = stick.GetReshapableState(false); - Common::DVec2 adj_coord; - if (is_tilt) - { - WiimoteEmu::EmulateTilt(&m_motion_state, static_cast(&stick), - 1.f / INDICATOR_UPDATE_FREQ); - adj_coord = Common::DVec2{-m_motion_state.angle.y, m_motion_state.angle.x} / MathUtil::PI; - } - else - { - adj_coord = stick.GetReshapableState(true); - } - UpdateCalibrationWidget(raw_coord); // Bounding box size: @@ -391,12 +380,33 @@ void MappingIndicator::DrawReshapableInput(ControllerEmu::ReshapableInput& stick } } -void MappingIndicator::DrawMixedTriggers() +void AnalogStickIndicator::Draw() +{ + // Some hacks for pretty colors: + const bool is_c_stick = m_group.name == "C-Stick"; + + const auto gate_brush_color = is_c_stick ? C_STICK_GATE_COLOR : STICK_GATE_COLOR; + + const auto adj_coord = m_group.GetReshapableState(true); + + DrawReshapableInput(m_group, adj_coord, gate_brush_color); +} + +void TiltIndicator::Draw() +{ + WiimoteEmu::EmulateTilt(&m_motion_state, &m_group, 1.f / INDICATOR_UPDATE_FREQ); + const auto adj_coord = + Common::DVec2{-m_motion_state.angle.y, m_motion_state.angle.x} / MathUtil::PI; + + DrawReshapableInput(m_group, adj_coord, TILT_GATE_COLOR); +} + +void MixedTriggersIndicator::Draw() { QPainter p(this); p.setRenderHint(QPainter::TextAntialiasing, true); - const auto& triggers = *static_cast(m_group); + const auto& triggers = m_group; const ControlState threshold = triggers.GetThreshold(); const ControlState deadzone = triggers.GetDeadzone(); @@ -486,8 +496,10 @@ void MappingIndicator::DrawMixedTriggers() } } -void MappingIndicator::DrawForce(ControllerEmu::Force& force) +void SwingIndicator::Draw() { + auto& force = m_swing_group; + const auto center = force.GetCenter(); QColor gate_brush_color = SWING_GATE_COLOR; @@ -597,39 +609,7 @@ void MappingIndicator::DrawForce(ControllerEmu::Force& force) } } -void MappingIndicator::paintEvent(QPaintEvent*) -{ - switch (m_group->type) - { - case ControllerEmu::GroupType::Cursor: - DrawCursor(*static_cast(m_group)); - break; - case ControllerEmu::GroupType::Stick: - case ControllerEmu::GroupType::Tilt: - DrawReshapableInput(*static_cast(m_group)); - break; - case ControllerEmu::GroupType::MixedTriggers: - DrawMixedTriggers(); - break; - case ControllerEmu::GroupType::Force: - DrawForce(*static_cast(m_group)); - break; - default: - break; - } -} - -ShakeMappingIndicator::ShakeMappingIndicator(ControllerEmu::Shake* group) - : MappingIndicator(group), m_shake_group(*group) -{ -} - -void ShakeMappingIndicator::paintEvent(QPaintEvent*) -{ - DrawShake(); -} - -void ShakeMappingIndicator::DrawShake() +void ShakeMappingIndicator::Draw() { constexpr std::size_t HISTORY_COUNT = INDICATOR_UPDATE_FREQ; @@ -706,12 +686,7 @@ void ShakeMappingIndicator::DrawShake() } } -AccelerometerMappingIndicator::AccelerometerMappingIndicator(ControllerEmu::IMUAccelerometer* group) - : MappingIndicator(group), m_accel_group(*group) -{ -} - -void AccelerometerMappingIndicator::paintEvent(QPaintEvent*) +void AccelerometerMappingIndicator::Draw() { const auto accel_state = m_accel_group.GetState(); const auto state = accel_state.value_or(Common::Vec3{}); @@ -793,12 +768,7 @@ void AccelerometerMappingIndicator::paintEvent(QPaintEvent*) fmt::format("{:.2f} g", state.Length() / WiimoteEmu::GRAVITY_ACCELERATION))); } -GyroMappingIndicator::GyroMappingIndicator(ControllerEmu::IMUGyroscope* group) - : MappingIndicator(group), m_gyro_group(*group), m_state(Common::Matrix33::Identity()) -{ -} - -void GyroMappingIndicator::paintEvent(QPaintEvent*) +void GyroMappingIndicator::Draw() { const auto gyro_state = m_gyro_group.GetState(); const auto raw_gyro_state = m_gyro_group.GetRawState(); @@ -915,7 +885,7 @@ void GyroMappingIndicator::paintEvent(QPaintEvent*) p.drawEllipse(QPointF{}, INPUT_DOT_RADIUS, INPUT_DOT_RADIUS); } -void MappingIndicator::DrawCalibration(QPainter& p, Common::DVec2 point) +void ReshapableInputIndicator::DrawCalibration(QPainter& p, Common::DVec2 point) { // Bounding box size: const double scale = GetScale(); @@ -942,24 +912,24 @@ void MappingIndicator::DrawCalibration(QPainter& p, Common::DVec2 point) p.drawEllipse(QPointF{point.x, point.y} * scale, INPUT_DOT_RADIUS, INPUT_DOT_RADIUS); } -void MappingIndicator::UpdateCalibrationWidget(Common::DVec2 point) +void ReshapableInputIndicator::UpdateCalibrationWidget(Common::DVec2 point) { if (m_calibration_widget) m_calibration_widget->Update(point); } -bool MappingIndicator::IsCalibrating() const +bool ReshapableInputIndicator::IsCalibrating() const { return m_calibration_widget && m_calibration_widget->IsCalibrating(); } -void MappingIndicator::SetCalibrationWidget(CalibrationWidget* widget) +void ReshapableInputIndicator::SetCalibrationWidget(CalibrationWidget* widget) { m_calibration_widget = widget; } CalibrationWidget::CalibrationWidget(ControllerEmu::ReshapableInput& input, - MappingIndicator& indicator) + ReshapableInputIndicator& indicator) : m_input(input), m_indicator(indicator), m_completion_action{} { m_indicator.SetCalibrationWidget(this); diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.h b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.h index 2405ebcc0c..279b84d6dd 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.h +++ b/Source/Core/DolphinQt/Config/Mapping/MappingIndicator.h @@ -18,6 +18,7 @@ class Control; class ControlGroup; class Cursor; class Force; +class MixedTriggers; } // namespace ControllerEmu class QPainter; @@ -29,9 +30,7 @@ class CalibrationWidget; class MappingIndicator : public QWidget { public: - explicit MappingIndicator(ControllerEmu::ControlGroup* group); - - void SetCalibrationWidget(CalibrationWidget* widget); + MappingIndicator(); QPen GetBBoxPen() const; QBrush GetBBoxBrush() const; @@ -49,58 +48,126 @@ public: protected: double GetScale() const; - WiimoteEmu::MotionState m_motion_state{}; + virtual void Draw() {} private: - void DrawCursor(ControllerEmu::Cursor& cursor); - void DrawReshapableInput(ControllerEmu::ReshapableInput& stick); - void DrawMixedTriggers(); - void DrawForce(ControllerEmu::Force&); - void DrawCalibration(QPainter& p, Common::DVec2 point); - void paintEvent(QPaintEvent*) override; +}; + +class ReshapableInputIndicator : public MappingIndicator +{ +public: + void SetCalibrationWidget(CalibrationWidget* widget); + +protected: + void DrawReshapableInput(ControllerEmu::ReshapableInput& group, + const ControllerEmu::ReshapableInput::ReshapeData& adj_coord, + QColor gate_color); bool IsCalibrating() const; + + void DrawCalibration(QPainter& p, Common::DVec2 point); void UpdateCalibrationWidget(Common::DVec2 point); - ControllerEmu::ControlGroup* const m_group; +private: CalibrationWidget* m_calibration_widget{}; }; +class AnalogStickIndicator : public ReshapableInputIndicator +{ +public: + explicit AnalogStickIndicator(ControllerEmu::ReshapableInput& stick) : m_group(stick) {} + +private: + void Draw() override; + + ControllerEmu::ReshapableInput& m_group; +}; + +class TiltIndicator : public ReshapableInputIndicator +{ +public: + explicit TiltIndicator(ControllerEmu::Tilt& tilt) : m_group(tilt) {} + +private: + void Draw() override; + + ControllerEmu::Tilt& m_group; + WiimoteEmu::MotionState m_motion_state{}; +}; + +class CursorIndicator : public ReshapableInputIndicator +{ +public: + explicit CursorIndicator(ControllerEmu::Cursor& cursor) : m_cursor_group(cursor) {} + +private: + void Draw() override; + + ControllerEmu::Cursor& m_cursor_group; +}; + +class MixedTriggersIndicator : public MappingIndicator +{ +public: + explicit MixedTriggersIndicator(ControllerEmu::MixedTriggers& triggers); + +private: + void Draw() override; + + ControllerEmu::MixedTriggers& m_group; +}; + +class SwingIndicator : public ReshapableInputIndicator +{ +public: + explicit SwingIndicator(ControllerEmu::Force& swing) : m_swing_group(swing) {} + +private: + void Draw() override; + + ControllerEmu::Force& m_swing_group; + WiimoteEmu::MotionState m_motion_state{}; +}; + class ShakeMappingIndicator : public MappingIndicator { public: - explicit ShakeMappingIndicator(ControllerEmu::Shake* group); - - void DrawShake(); - void paintEvent(QPaintEvent*) override; + explicit ShakeMappingIndicator(ControllerEmu::Shake& shake) : m_shake_group(shake) {} private: - std::deque m_position_samples; - int m_grid_line_position = 0; + void Draw() override; ControllerEmu::Shake& m_shake_group; + WiimoteEmu::MotionState m_motion_state{}; + std::deque m_position_samples; + int m_grid_line_position = 0; }; class AccelerometerMappingIndicator : public MappingIndicator { public: - explicit AccelerometerMappingIndicator(ControllerEmu::IMUAccelerometer* group); - void paintEvent(QPaintEvent*) override; + explicit AccelerometerMappingIndicator(ControllerEmu::IMUAccelerometer& accel) + : m_accel_group(accel) + { + } private: + void Draw() override; + ControllerEmu::IMUAccelerometer& m_accel_group; }; class GyroMappingIndicator : public MappingIndicator { public: - explicit GyroMappingIndicator(ControllerEmu::IMUGyroscope* group); - void paintEvent(QPaintEvent*) override; + explicit GyroMappingIndicator(ControllerEmu::IMUGyroscope& gyro) : m_gyro_group(gyro) {} private: + void Draw() override; + ControllerEmu::IMUGyroscope& m_gyro_group; - Common::Matrix33 m_state; + Common::Matrix33 m_state = Common::Matrix33::Identity(); Common::Vec3 m_previous_velocity = {}; u32 m_stable_steps = 0; }; @@ -108,7 +175,7 @@ private: class CalibrationWidget : public QToolButton { public: - CalibrationWidget(ControllerEmu::ReshapableInput& input, MappingIndicator& indicator); + CalibrationWidget(ControllerEmu::ReshapableInput& input, ReshapableInputIndicator& indicator); void Update(Common::DVec2 point); @@ -123,7 +190,7 @@ private: void SetupActions(); ControllerEmu::ReshapableInput& m_input; - MappingIndicator& m_indicator; + ReshapableInputIndicator& m_indicator; QAction* m_completion_action; ControllerEmu::ReshapableInput::CalibrationData m_calibration_data; QTimer* m_informative_timer; diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp index eb39bac64f..160c914a63 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp @@ -19,6 +19,7 @@ #include "InputCommon/ControlReference/ControlReference.h" #include "InputCommon/ControllerEmu/Control/Control.h" #include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" +#include "InputCommon/ControllerEmu/ControlGroup/MixedTriggers.h" #include "InputCommon/ControllerEmu/ControllerEmu.h" #include "InputCommon/ControllerEmu/Setting/NumericSetting.h" #include "InputCommon/ControllerEmu/StickGate.h" @@ -52,52 +53,63 @@ QGroupBox* MappingWidget::CreateGroupBox(const QString& name, ControllerEmu::Con group_box->setLayout(form_layout); - const bool need_indicator = group->type == ControllerEmu::GroupType::Cursor || - group->type == ControllerEmu::GroupType::Stick || - group->type == ControllerEmu::GroupType::Tilt || - group->type == ControllerEmu::GroupType::MixedTriggers || - group->type == ControllerEmu::GroupType::Force || - group->type == ControllerEmu::GroupType::IMUAccelerometer || - group->type == ControllerEmu::GroupType::IMUGyroscope || - group->type == ControllerEmu::GroupType::Shake; + MappingIndicator* indicator = nullptr; - const bool need_calibration = group->type == ControllerEmu::GroupType::Cursor || - group->type == ControllerEmu::GroupType::Stick || - group->type == ControllerEmu::GroupType::Tilt || - group->type == ControllerEmu::GroupType::Force; - - if (need_indicator) + switch (group->type) { - MappingIndicator* indicator; + case ControllerEmu::GroupType::Shake: + indicator = new ShakeMappingIndicator(*static_cast(group)); + break; - switch (group->type) - { - case ControllerEmu::GroupType::Shake: - indicator = new ShakeMappingIndicator(static_cast(group)); - break; + case ControllerEmu::GroupType::MixedTriggers: + indicator = new MixedTriggersIndicator(*static_cast(group)); + break; - case ControllerEmu::GroupType::IMUAccelerometer: - indicator = - new AccelerometerMappingIndicator(static_cast(group)); - break; + case ControllerEmu::GroupType::Tilt: + indicator = new TiltIndicator(*static_cast(group)); + break; - case ControllerEmu::GroupType::IMUGyroscope: - indicator = new GyroMappingIndicator(static_cast(group)); - break; + case ControllerEmu::GroupType::Cursor: + indicator = new CursorIndicator(*static_cast(group)); + break; - default: - indicator = new MappingIndicator(group); - break; - } + case ControllerEmu::GroupType::Force: + indicator = new SwingIndicator(*static_cast(group)); + break; + case ControllerEmu::GroupType::IMUAccelerometer: + indicator = + new AccelerometerMappingIndicator(*static_cast(group)); + break; + + case ControllerEmu::GroupType::IMUGyroscope: + indicator = new GyroMappingIndicator(*static_cast(group)); + break; + + case ControllerEmu::GroupType::Stick: + indicator = new AnalogStickIndicator(*static_cast(group)); + break; + + default: + break; + } + + if (indicator) + { form_layout->addRow(indicator); connect(this, &MappingWidget::Update, indicator, QOverload<>::of(&MappingIndicator::update)); + const bool need_calibration = group->type == ControllerEmu::GroupType::Cursor || + group->type == ControllerEmu::GroupType::Stick || + group->type == ControllerEmu::GroupType::Tilt || + group->type == ControllerEmu::GroupType::Force; + if (need_calibration) { const auto calibrate = - new CalibrationWidget(*static_cast(group), *indicator); + new CalibrationWidget(*static_cast(group), + *static_cast(indicator)); form_layout->addRow(calibrate); } @@ -105,7 +117,7 @@ QGroupBox* MappingWidget::CreateGroupBox(const QString& name, ControllerEmu::Con for (auto& control : group->controls) { - auto* button = new MappingButton(this, control->control_ref.get(), !need_indicator); + auto* button = new MappingButton(this, control->control_ref.get(), !indicator); button->setMinimumWidth(100); button->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);