diff options
-rw-r--r-- | src/yuzu/applets/qt_controller.cpp | 2 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_input.cpp | 2 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_vibration.cpp | 74 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_vibration.h | 18 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_vibration.ui | 7 |
5 files changed, 95 insertions, 8 deletions
diff --git a/src/yuzu/applets/qt_controller.cpp b/src/yuzu/applets/qt_controller.cpp index 4239c17f5..4104928d1 100644 --- a/src/yuzu/applets/qt_controller.cpp +++ b/src/yuzu/applets/qt_controller.cpp @@ -257,7 +257,7 @@ void QtControllerSelectorDialog::LoadConfiguration() { } void QtControllerSelectorDialog::CallConfigureVibrationDialog() { - ConfigureVibration dialog(this); + ConfigureVibration dialog(this, system.HIDCore()); dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint); diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp index d53179dbb..7c5776189 100644 --- a/src/yuzu/configuration/configure_input.cpp +++ b/src/yuzu/configuration/configure_input.cpp @@ -164,7 +164,7 @@ void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem, }); connect(ui->vibrationButton, &QPushButton::clicked, - [this] { CallConfigureDialog<ConfigureVibration>(*this); }); + [this, &hid_core] { CallConfigureDialog<ConfigureVibration>(*this, hid_core); }); connect(ui->motionButton, &QPushButton::clicked, [this, input_subsystem] { CallConfigureDialog<ConfigureMotionTouch>(*this, input_subsystem); diff --git a/src/yuzu/configuration/configure_vibration.cpp b/src/yuzu/configuration/configure_vibration.cpp index adce04b27..779b6401c 100644 --- a/src/yuzu/configuration/configure_vibration.cpp +++ b/src/yuzu/configuration/configure_vibration.cpp @@ -9,11 +9,14 @@ #include "common/param_package.h" #include "common/settings.h" +#include "core/hid/emulated_controller.h" +#include "core/hid/hid_core.h" +#include "core/hid/hid_types.h" #include "ui_configure_vibration.h" #include "yuzu/configuration/configure_vibration.h" -ConfigureVibration::ConfigureVibration(QWidget* parent) - : QDialog(parent), ui(std::make_unique<Ui::ConfigureVibration>()) { +ConfigureVibration::ConfigureVibration(QWidget* parent, Core::HID::HIDCore& hid_core_) + : QDialog(parent), ui(std::make_unique<Ui::ConfigureVibration>()), hid_core{hid_core_} { ui->setupUi(this); vibration_groupboxes = { @@ -31,6 +34,13 @@ ConfigureVibration::ConfigureVibration(QWidget* parent) const auto& players = Settings::values.players.GetValue(); for (std::size_t i = 0; i < NUM_PLAYERS; ++i) { + auto controller = hid_core.GetEmulatedControllerByIndex(i); + Core::HID::ControllerUpdateCallback engine_callback{ + .on_change = [this, + i](Core::HID::ControllerTriggerType type) { VibrateController(type, i); }, + .is_npad_service = false, + }; + controller_callback_key[i] = controller->SetCallback(engine_callback); vibration_groupboxes[i]->setChecked(players[i].vibration_enabled); vibration_spinboxes[i]->setValue(players[i].vibration_strength); } @@ -45,7 +55,14 @@ ConfigureVibration::ConfigureVibration(QWidget* parent) RetranslateUI(); } -ConfigureVibration::~ConfigureVibration() = default; +ConfigureVibration::~ConfigureVibration() { + StopVibrations(); + + for (std::size_t i = 0; i < NUM_PLAYERS; ++i) { + auto controller = hid_core.GetEmulatedControllerByIndex(i); + controller->DeleteCallback(controller_callback_key[i]); + } +}; void ConfigureVibration::ApplyConfiguration() { auto& players = Settings::values.players.GetValue(); @@ -70,3 +87,54 @@ void ConfigureVibration::changeEvent(QEvent* event) { void ConfigureVibration::RetranslateUI() { ui->retranslateUi(this); } + +void ConfigureVibration::VibrateController(Core::HID::ControllerTriggerType type, + std::size_t player_index) { + if (type != Core::HID::ControllerTriggerType::Button) { + return; + } + + auto& player = Settings::values.players.GetValue()[player_index]; + auto controller = hid_core.GetEmulatedControllerByIndex(player_index); + const int vibration_strenght = vibration_spinboxes[player_index]->value(); + const auto& buttons = controller->GetButtonsValues(); + + bool button_is_pressed = false; + for (std::size_t i = 0; i < buttons.size(); ++i) { + if (buttons[i].value) { + button_is_pressed = true; + break; + } + } + + if (!button_is_pressed) { + StopVibrations(); + return; + } + + const int old_vibration_enabled = player.vibration_enabled; + const bool old_vibration_strenght = player.vibration_strength; + player.vibration_enabled = true; + player.vibration_strength = vibration_strenght; + + const Core::HID::VibrationValue vibration{ + .low_amplitude = 1.0f, + .low_frequency = 160.0f, + .high_amplitude = 1.0f, + .high_frequency = 320.0f, + }; + controller->SetVibration(0, vibration); + controller->SetVibration(1, vibration); + + // Restore previous values + player.vibration_enabled = old_vibration_enabled; + player.vibration_strength = old_vibration_strenght; +} + +void ConfigureVibration::StopVibrations() { + for (std::size_t i = 0; i < NUM_PLAYERS; ++i) { + auto controller = hid_core.GetEmulatedControllerByIndex(i); + controller->SetVibration(0, Core::HID::DEFAULT_VIBRATION_VALUE); + controller->SetVibration(1, Core::HID::DEFAULT_VIBRATION_VALUE); + } +} diff --git a/src/yuzu/configuration/configure_vibration.h b/src/yuzu/configuration/configure_vibration.h index 37bbc2653..50b8195fa 100644 --- a/src/yuzu/configuration/configure_vibration.h +++ b/src/yuzu/configuration/configure_vibration.h @@ -15,11 +15,16 @@ namespace Ui { class ConfigureVibration; } +namespace Core::HID { +enum class ControllerTriggerType; +class HIDCore; +} // namespace Core::HID + class ConfigureVibration : public QDialog { Q_OBJECT public: - explicit ConfigureVibration(QWidget* parent); + explicit ConfigureVibration(QWidget* parent, Core::HID::HIDCore& hid_core_); ~ConfigureVibration() override; void ApplyConfiguration(); @@ -27,14 +32,21 @@ public: private: void changeEvent(QEvent* event) override; void RetranslateUI(); + void VibrateController(Core::HID::ControllerTriggerType type, std::size_t player_index); + void StopVibrations(); std::unique_ptr<Ui::ConfigureVibration> ui; static constexpr std::size_t NUM_PLAYERS = 8; - // Groupboxes encapsulating the vibration strength spinbox. + /// Groupboxes encapsulating the vibration strength spinbox. std::array<QGroupBox*, NUM_PLAYERS> vibration_groupboxes; - // Spinboxes representing the vibration strength percentage. + /// Spinboxes representing the vibration strength percentage. std::array<QSpinBox*, NUM_PLAYERS> vibration_spinboxes; + + /// Callback index to stop the controllers events + std::array<int, NUM_PLAYERS> controller_callback_key; + + Core::HID::HIDCore& hid_core; }; diff --git a/src/yuzu/configuration/configure_vibration.ui b/src/yuzu/configuration/configure_vibration.ui index efdf317a9..447a18eb1 100644 --- a/src/yuzu/configuration/configure_vibration.ui +++ b/src/yuzu/configuration/configure_vibration.ui @@ -17,6 +17,13 @@ <string notr="true"/> </property> <layout class="QVBoxLayout"> + <item row="0" column="0" colspan="4"> + <widget class="QLabel" name="label_1"> + <property name="text"> + <string>Press any controller button to vibrate the controller.</string> + </property> + </widget> + </item> <item> <widget class="QGroupBox" name="vibrationStrengthGroup"> <property name="title"> |