configure_vibration.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // Copyright 2020 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <algorithm>
  5. #include <unordered_map>
  6. #include <fmt/format.h>
  7. #include "common/param_package.h"
  8. #include "common/settings.h"
  9. #include "ui_configure_vibration.h"
  10. #include "yuzu/configuration/configure_vibration.h"
  11. ConfigureVibration::ConfigureVibration(QWidget* parent)
  12. : QDialog(parent), ui(std::make_unique<Ui::ConfigureVibration>()) {
  13. ui->setupUi(this);
  14. vibration_groupboxes = {
  15. ui->vibrationGroupPlayer1, ui->vibrationGroupPlayer2, ui->vibrationGroupPlayer3,
  16. ui->vibrationGroupPlayer4, ui->vibrationGroupPlayer5, ui->vibrationGroupPlayer6,
  17. ui->vibrationGroupPlayer7, ui->vibrationGroupPlayer8,
  18. };
  19. vibration_spinboxes = {
  20. ui->vibrationSpinPlayer1, ui->vibrationSpinPlayer2, ui->vibrationSpinPlayer3,
  21. ui->vibrationSpinPlayer4, ui->vibrationSpinPlayer5, ui->vibrationSpinPlayer6,
  22. ui->vibrationSpinPlayer7, ui->vibrationSpinPlayer8,
  23. };
  24. const auto& players = Settings::values.players.GetValue();
  25. for (std::size_t i = 0; i < NUM_PLAYERS; ++i) {
  26. vibration_groupboxes[i]->setChecked(players[i].vibration_enabled);
  27. vibration_spinboxes[i]->setValue(players[i].vibration_strength);
  28. }
  29. ui->checkBoxAccurateVibration->setChecked(
  30. Settings::values.enable_accurate_vibrations.GetValue());
  31. if (!Settings::IsConfiguringGlobal()) {
  32. ui->checkBoxAccurateVibration->setDisabled(true);
  33. }
  34. RetranslateUI();
  35. }
  36. ConfigureVibration::~ConfigureVibration() = default;
  37. void ConfigureVibration::ApplyConfiguration() {
  38. auto& players = Settings::values.players.GetValue();
  39. for (std::size_t i = 0; i < NUM_PLAYERS; ++i) {
  40. players[i].vibration_enabled = vibration_groupboxes[i]->isChecked();
  41. players[i].vibration_strength = vibration_spinboxes[i]->value();
  42. }
  43. Settings::values.enable_accurate_vibrations.SetValue(
  44. ui->checkBoxAccurateVibration->isChecked());
  45. }
  46. void ConfigureVibration::SetVibrationDevices(std::size_t player_index) {
  47. using namespace Settings::NativeButton;
  48. static constexpr std::array<std::array<Settings::NativeButton::Values, 6>, 2> buttons{{
  49. {DLeft, DUp, DRight, DDown, L, ZL}, // Left Buttons
  50. {A, B, X, Y, R, ZR}, // Right Buttons
  51. }};
  52. auto& player = Settings::values.players.GetValue()[player_index];
  53. for (std::size_t device_idx = 0; device_idx < buttons.size(); ++device_idx) {
  54. std::unordered_map<std::string, int> params_count;
  55. for (const auto button_index : buttons[device_idx]) {
  56. const auto& player_button = player.buttons[button_index];
  57. if (params_count.find(player_button) != params_count.end()) {
  58. ++params_count[player_button];
  59. continue;
  60. }
  61. params_count.insert_or_assign(player_button, 1);
  62. }
  63. const auto it = std::max_element(
  64. params_count.begin(), params_count.end(),
  65. [](const auto& lhs, const auto& rhs) { return lhs.second < rhs.second; });
  66. auto& vibration_param_str = player.vibrations[device_idx];
  67. vibration_param_str.clear();
  68. if (it->first.empty()) {
  69. continue;
  70. }
  71. const auto param = Common::ParamPackage(it->first);
  72. const auto engine = param.Get("engine", "");
  73. const auto guid = param.Get("guid", "");
  74. const auto port = param.Get("port", 0);
  75. if (engine.empty() || engine == "keyboard" || engine == "mouse" || engine == "tas") {
  76. continue;
  77. }
  78. vibration_param_str += fmt::format("engine:{}", engine);
  79. if (port != 0) {
  80. vibration_param_str += fmt::format(",port:{}", port);
  81. }
  82. if (!guid.empty()) {
  83. vibration_param_str += fmt::format(",guid:{}", guid);
  84. }
  85. }
  86. if (player.vibrations[0] != player.vibrations[1]) {
  87. return;
  88. }
  89. if (!player.vibrations[0].empty() &&
  90. player.controller_type != Settings::ControllerType::RightJoycon) {
  91. player.vibrations[1].clear();
  92. } else if (!player.vibrations[1].empty() &&
  93. player.controller_type == Settings::ControllerType::RightJoycon) {
  94. player.vibrations[0].clear();
  95. }
  96. }
  97. void ConfigureVibration::SetAllVibrationDevices() {
  98. // Set vibration devices for all player indices including handheld
  99. for (std::size_t player_idx = 0; player_idx < NUM_PLAYERS + 1; ++player_idx) {
  100. SetVibrationDevices(player_idx);
  101. }
  102. }
  103. void ConfigureVibration::changeEvent(QEvent* event) {
  104. if (event->type() == QEvent::LanguageChange) {
  105. RetranslateUI();
  106. }
  107. QDialog::changeEvent(event);
  108. }
  109. void ConfigureVibration::RetranslateUI() {
  110. ui->retranslateUi(this);
  111. }