configure_vibration.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "common/settings.h"
  4. #include "hid_core/frontend/emulated_controller.h"
  5. #include "hid_core/hid_core.h"
  6. #include "hid_core/hid_types.h"
  7. #include "ui_configure_vibration.h"
  8. #include "yuzu/configuration/configure_vibration.h"
  9. ConfigureVibration::ConfigureVibration(QWidget* parent, Core::HID::HIDCore& hid_core_)
  10. : QDialog(parent), ui(std::make_unique<Ui::ConfigureVibration>()), hid_core{hid_core_} {
  11. ui->setupUi(this);
  12. vibration_groupboxes = {
  13. ui->vibrationGroupPlayer1, ui->vibrationGroupPlayer2, ui->vibrationGroupPlayer3,
  14. ui->vibrationGroupPlayer4, ui->vibrationGroupPlayer5, ui->vibrationGroupPlayer6,
  15. ui->vibrationGroupPlayer7, ui->vibrationGroupPlayer8,
  16. };
  17. vibration_spinboxes = {
  18. ui->vibrationSpinPlayer1, ui->vibrationSpinPlayer2, ui->vibrationSpinPlayer3,
  19. ui->vibrationSpinPlayer4, ui->vibrationSpinPlayer5, ui->vibrationSpinPlayer6,
  20. ui->vibrationSpinPlayer7, ui->vibrationSpinPlayer8,
  21. };
  22. const auto& players = Settings::values.players.GetValue();
  23. for (std::size_t i = 0; i < NUM_PLAYERS; ++i) {
  24. auto controller = hid_core.GetEmulatedControllerByIndex(i);
  25. Core::HID::ControllerUpdateCallback engine_callback{
  26. .on_change = [this,
  27. i](Core::HID::ControllerTriggerType type) { VibrateController(type, i); },
  28. .is_npad_service = false,
  29. };
  30. controller_callback_key[i] = controller->SetCallback(engine_callback);
  31. vibration_groupboxes[i]->setChecked(players[i].vibration_enabled);
  32. vibration_spinboxes[i]->setValue(players[i].vibration_strength);
  33. }
  34. ui->checkBoxAccurateVibration->setChecked(
  35. Settings::values.enable_accurate_vibrations.GetValue());
  36. if (!Settings::IsConfiguringGlobal()) {
  37. ui->checkBoxAccurateVibration->setDisabled(true);
  38. }
  39. RetranslateUI();
  40. }
  41. ConfigureVibration::~ConfigureVibration() {
  42. StopVibrations();
  43. for (std::size_t i = 0; i < NUM_PLAYERS; ++i) {
  44. auto controller = hid_core.GetEmulatedControllerByIndex(i);
  45. controller->DeleteCallback(controller_callback_key[i]);
  46. }
  47. };
  48. void ConfigureVibration::ApplyConfiguration() {
  49. auto& players = Settings::values.players.GetValue();
  50. for (std::size_t i = 0; i < NUM_PLAYERS; ++i) {
  51. players[i].vibration_enabled = vibration_groupboxes[i]->isChecked();
  52. players[i].vibration_strength = vibration_spinboxes[i]->value();
  53. }
  54. Settings::values.enable_accurate_vibrations.SetValue(
  55. ui->checkBoxAccurateVibration->isChecked());
  56. }
  57. void ConfigureVibration::changeEvent(QEvent* event) {
  58. if (event->type() == QEvent::LanguageChange) {
  59. RetranslateUI();
  60. }
  61. QDialog::changeEvent(event);
  62. }
  63. void ConfigureVibration::RetranslateUI() {
  64. ui->retranslateUi(this);
  65. }
  66. void ConfigureVibration::VibrateController(Core::HID::ControllerTriggerType type,
  67. std::size_t player_index) {
  68. if (type != Core::HID::ControllerTriggerType::Button) {
  69. return;
  70. }
  71. auto& player = Settings::values.players.GetValue()[player_index];
  72. auto controller = hid_core.GetEmulatedControllerByIndex(player_index);
  73. const int vibration_strength = vibration_spinboxes[player_index]->value();
  74. const auto& buttons = controller->GetButtonsValues();
  75. bool button_is_pressed = false;
  76. for (std::size_t i = 0; i < buttons.size(); ++i) {
  77. if (buttons[i].value) {
  78. button_is_pressed = true;
  79. break;
  80. }
  81. }
  82. if (!button_is_pressed) {
  83. StopVibrations();
  84. return;
  85. }
  86. const bool old_vibration_enabled = player.vibration_enabled;
  87. const int old_vibration_strength = player.vibration_strength;
  88. player.vibration_enabled = true;
  89. player.vibration_strength = vibration_strength;
  90. const Core::HID::VibrationValue vibration{
  91. .low_amplitude = 1.0f,
  92. .low_frequency = 160.0f,
  93. .high_amplitude = 1.0f,
  94. .high_frequency = 320.0f,
  95. };
  96. controller->SetVibration(Core::HID::DeviceIndex::Left, vibration);
  97. controller->SetVibration(Core::HID::DeviceIndex::Right, vibration);
  98. // Restore previous values
  99. player.vibration_enabled = old_vibration_enabled;
  100. player.vibration_strength = old_vibration_strength;
  101. }
  102. void ConfigureVibration::StopVibrations() {
  103. for (std::size_t i = 0; i < NUM_PLAYERS; ++i) {
  104. auto controller = hid_core.GetEmulatedControllerByIndex(i);
  105. controller->SetVibration(Core::HID::DeviceIndex::Left, Core::HID::DEFAULT_VIBRATION_VALUE);
  106. controller->SetVibration(Core::HID::DeviceIndex::Right, Core::HID::DEFAULT_VIBRATION_VALUE);
  107. }
  108. }