diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/yuzu/applets/qt_controller.cpp | 52 | ||||
| -rw-r--r-- | src/yuzu/applets/qt_controller.h | 4 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_input.cpp | 59 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_input.h | 7 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_input_player.h | 5 |
5 files changed, 87 insertions, 40 deletions
diff --git a/src/yuzu/applets/qt_controller.cpp b/src/yuzu/applets/qt_controller.cpp index ca0e14fad..515cb7ce6 100644 --- a/src/yuzu/applets/qt_controller.cpp +++ b/src/yuzu/applets/qt_controller.cpp | |||
| @@ -155,18 +155,27 @@ QtControllerSelectorDialog::QtControllerSelectorDialog( | |||
| 155 | UpdateBorderColor(i); | 155 | UpdateBorderColor(i); |
| 156 | 156 | ||
| 157 | connect(player_groupboxes[i], &QGroupBox::toggled, [this, i](bool checked) { | 157 | connect(player_groupboxes[i], &QGroupBox::toggled, [this, i](bool checked) { |
| 158 | if (checked) { | 158 | // Reconnect current controller if it was the last one checked |
| 159 | // Hide eventual error message about number of controllers | 159 | // (player number was reduced by more than one) |
| 160 | ui->labelError->setVisible(false); | 160 | const bool reconnect_first = !checked && i < player_groupboxes.size() - 1 && |
| 161 | for (std::size_t index = 0; index <= i; ++index) { | 161 | player_groupboxes[i + 1]->isChecked(); |
| 162 | connected_controller_checkboxes[index]->setChecked(checked); | 162 | |
| 163 | } | 163 | // Ensures that connecting a controller changes the number of players |
| 164 | } else { | 164 | if (connected_controller_checkboxes[i]->isChecked() != checked) { |
| 165 | for (std::size_t index = i; index < NUM_PLAYERS; ++index) { | 165 | // Ensures that the players are always connected in sequential order |
| 166 | connected_controller_checkboxes[index]->setChecked(checked); | 166 | PropagatePlayerNumberChanged(i, checked, reconnect_first); |
| 167 | } | ||
| 168 | } | 167 | } |
| 169 | }); | 168 | }); |
| 169 | connect(connected_controller_checkboxes[i], &QCheckBox::clicked, [this, i](bool checked) { | ||
| 170 | // Reconnect current controller if it was the last one checked | ||
| 171 | // (player number was reduced by more than one) | ||
| 172 | const bool reconnect_first = !checked && | ||
| 173 | i < connected_controller_checkboxes.size() - 1 && | ||
| 174 | connected_controller_checkboxes[i + 1]->isChecked(); | ||
| 175 | |||
| 176 | // Ensures that the players are always connected in sequential order | ||
| 177 | PropagatePlayerNumberChanged(i, checked, reconnect_first); | ||
| 178 | }); | ||
| 170 | 179 | ||
| 171 | connect(emulated_controllers[i], qOverload<int>(&QComboBox::currentIndexChanged), | 180 | connect(emulated_controllers[i], qOverload<int>(&QComboBox::currentIndexChanged), |
| 172 | [this, i](int) { | 181 | [this, i](int) { |
| @@ -668,6 +677,29 @@ void QtControllerSelectorDialog::UpdateDockedState(bool is_handheld) { | |||
| 668 | } | 677 | } |
| 669 | } | 678 | } |
| 670 | 679 | ||
| 680 | void QtControllerSelectorDialog::PropagatePlayerNumberChanged(size_t player_index, bool checked, | ||
| 681 | bool reconnect_current) { | ||
| 682 | connected_controller_checkboxes[player_index]->setChecked(checked); | ||
| 683 | // Hide eventual error message about number of controllers | ||
| 684 | ui->labelError->setVisible(false); | ||
| 685 | |||
| 686 | if (checked) { | ||
| 687 | // Check all previous buttons when checked | ||
| 688 | if (player_index > 0) { | ||
| 689 | PropagatePlayerNumberChanged(player_index - 1, checked); | ||
| 690 | } | ||
| 691 | } else { | ||
| 692 | // Unchecked all following buttons when unchecked | ||
| 693 | if (player_index < connected_controller_checkboxes.size() - 1) { | ||
| 694 | PropagatePlayerNumberChanged(player_index + 1, checked); | ||
| 695 | } | ||
| 696 | } | ||
| 697 | |||
| 698 | if (reconnect_current) { | ||
| 699 | connected_controller_checkboxes[player_index]->setCheckState(Qt::Checked); | ||
| 700 | } | ||
| 701 | } | ||
| 702 | |||
| 671 | void QtControllerSelectorDialog::DisableUnsupportedPlayers() { | 703 | void QtControllerSelectorDialog::DisableUnsupportedPlayers() { |
| 672 | const auto max_supported_players = parameters.enable_single_mode ? 1 : parameters.max_players; | 704 | const auto max_supported_players = parameters.enable_single_mode ? 1 : parameters.max_players; |
| 673 | 705 | ||
diff --git a/src/yuzu/applets/qt_controller.h b/src/yuzu/applets/qt_controller.h index 7f0673d06..e5372495d 100644 --- a/src/yuzu/applets/qt_controller.h +++ b/src/yuzu/applets/qt_controller.h | |||
| @@ -100,6 +100,10 @@ private: | |||
| 100 | // Updates the console mode. | 100 | // Updates the console mode. |
| 101 | void UpdateDockedState(bool is_handheld); | 101 | void UpdateDockedState(bool is_handheld); |
| 102 | 102 | ||
| 103 | // Enable preceding controllers or disable following ones | ||
| 104 | void PropagatePlayerNumberChanged(size_t player_index, bool checked, | ||
| 105 | bool reconnect_current = false); | ||
| 106 | |||
| 103 | // Disables and disconnects unsupported players based on the given parameters. | 107 | // Disables and disconnects unsupported players based on the given parameters. |
| 104 | void DisableUnsupportedPlayers(); | 108 | void DisableUnsupportedPlayers(); |
| 105 | 109 | ||
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp index 5a48e388b..3dcad2701 100644 --- a/src/yuzu/configuration/configure_input.cpp +++ b/src/yuzu/configuration/configure_input.cpp | |||
| @@ -101,13 +101,13 @@ void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem, | |||
| 101 | ui->tabPlayer5, ui->tabPlayer6, ui->tabPlayer7, ui->tabPlayer8, | 101 | ui->tabPlayer5, ui->tabPlayer6, ui->tabPlayer7, ui->tabPlayer8, |
| 102 | }; | 102 | }; |
| 103 | 103 | ||
| 104 | player_connected = { | 104 | connected_controller_checkboxes = { |
| 105 | ui->checkboxPlayer1Connected, ui->checkboxPlayer2Connected, ui->checkboxPlayer3Connected, | 105 | ui->checkboxPlayer1Connected, ui->checkboxPlayer2Connected, ui->checkboxPlayer3Connected, |
| 106 | ui->checkboxPlayer4Connected, ui->checkboxPlayer5Connected, ui->checkboxPlayer6Connected, | 106 | ui->checkboxPlayer4Connected, ui->checkboxPlayer5Connected, ui->checkboxPlayer6Connected, |
| 107 | ui->checkboxPlayer7Connected, ui->checkboxPlayer8Connected, | 107 | ui->checkboxPlayer7Connected, ui->checkboxPlayer8Connected, |
| 108 | }; | 108 | }; |
| 109 | 109 | ||
| 110 | std::array<QLabel*, 8> player_connected_labels = { | 110 | std::array<QLabel*, 8> connected_controller_labels = { |
| 111 | ui->label, ui->label_3, ui->label_4, ui->label_5, | 111 | ui->label, ui->label_3, ui->label_4, ui->label_5, |
| 112 | ui->label_6, ui->label_7, ui->label_8, ui->label_9, | 112 | ui->label_6, ui->label_7, ui->label_8, ui->label_9, |
| 113 | }; | 113 | }; |
| @@ -115,23 +115,37 @@ void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem, | |||
| 115 | for (std::size_t i = 0; i < player_tabs.size(); ++i) { | 115 | for (std::size_t i = 0; i < player_tabs.size(); ++i) { |
| 116 | player_tabs[i]->setLayout(new QHBoxLayout(player_tabs[i])); | 116 | player_tabs[i]->setLayout(new QHBoxLayout(player_tabs[i])); |
| 117 | player_tabs[i]->layout()->addWidget(player_controllers[i]); | 117 | player_tabs[i]->layout()->addWidget(player_controllers[i]); |
| 118 | connect(player_connected[i], &QCheckBox::clicked, [this, i](int checked) { | 118 | connect(player_controllers[i], &ConfigureInputPlayer::Connected, [this, i](bool checked) { |
| 119 | // Ensures that the controllers are always connected in sequential order | 119 | // Ensures that connecting a controller changes the number of players |
| 120 | this->propagateMouseClickOnPlayers(i, checked, true); | 120 | if (connected_controller_checkboxes[i]->isChecked() != checked) { |
| 121 | // Ensures that the players are always connected in sequential order | ||
| 122 | PropagatePlayerNumberChanged(i, checked); | ||
| 123 | } | ||
| 124 | }); | ||
| 125 | connect(connected_controller_checkboxes[i], &QCheckBox::clicked, [this, i](bool checked) { | ||
| 126 | // Reconnect current controller if it was the last one checked | ||
| 127 | // (player number was reduced by more than one) | ||
| 128 | const bool reconnect_first = !checked && | ||
| 129 | i < connected_controller_checkboxes.size() - 1 && | ||
| 130 | connected_controller_checkboxes[i + 1]->isChecked(); | ||
| 131 | |||
| 132 | // Ensures that the players are always connected in sequential order | ||
| 133 | PropagatePlayerNumberChanged(i, checked, reconnect_first); | ||
| 121 | }); | 134 | }); |
| 122 | connect(player_controllers[i], &ConfigureInputPlayer::RefreshInputDevices, this, | 135 | connect(player_controllers[i], &ConfigureInputPlayer::RefreshInputDevices, this, |
| 123 | &ConfigureInput::UpdateAllInputDevices); | 136 | &ConfigureInput::UpdateAllInputDevices); |
| 124 | connect(player_controllers[i], &ConfigureInputPlayer::RefreshInputProfiles, this, | 137 | connect(player_controllers[i], &ConfigureInputPlayer::RefreshInputProfiles, this, |
| 125 | &ConfigureInput::UpdateAllInputProfiles, Qt::QueuedConnection); | 138 | &ConfigureInput::UpdateAllInputProfiles, Qt::QueuedConnection); |
| 126 | connect(player_connected[i], &QCheckBox::stateChanged, [this, i](int state) { | 139 | connect(connected_controller_checkboxes[i], &QCheckBox::stateChanged, [this, i](int state) { |
| 140 | // Keep activated controllers synced with the "Connected Controllers" checkboxes | ||
| 127 | player_controllers[i]->ConnectPlayer(state == Qt::Checked); | 141 | player_controllers[i]->ConnectPlayer(state == Qt::Checked); |
| 128 | }); | 142 | }); |
| 129 | 143 | ||
| 130 | // Remove/hide all the elements that exceed max_players, if applicable. | 144 | // Remove/hide all the elements that exceed max_players, if applicable. |
| 131 | if (i >= max_players) { | 145 | if (i >= max_players) { |
| 132 | ui->tabWidget->removeTab(static_cast<int>(max_players)); | 146 | ui->tabWidget->removeTab(static_cast<int>(max_players)); |
| 133 | player_connected[i]->hide(); | 147 | connected_controller_checkboxes[i]->hide(); |
| 134 | player_connected_labels[i]->hide(); | 148 | connected_controller_labels[i]->hide(); |
| 135 | } | 149 | } |
| 136 | } | 150 | } |
| 137 | // Only the first player can choose handheld mode so connect the signal just to player 1 | 151 | // Only the first player can choose handheld mode so connect the signal just to player 1 |
| @@ -175,28 +189,25 @@ void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem, | |||
| 175 | LoadConfiguration(); | 189 | LoadConfiguration(); |
| 176 | } | 190 | } |
| 177 | 191 | ||
| 178 | void ConfigureInput::propagateMouseClickOnPlayers(size_t player_index, bool checked, bool origin) { | 192 | void ConfigureInput::PropagatePlayerNumberChanged(size_t player_index, bool checked, |
| 179 | // Origin has already been toggled | 193 | bool reconnect_current) { |
| 180 | if (!origin) { | 194 | connected_controller_checkboxes[player_index]->setChecked(checked); |
| 181 | player_connected[player_index]->setChecked(checked); | ||
| 182 | } | ||
| 183 | 195 | ||
| 184 | if (checked) { | 196 | if (checked) { |
| 185 | // Check all previous buttons when checked | 197 | // Check all previous buttons when checked |
| 186 | if (player_index > 0) { | 198 | if (player_index > 0) { |
| 187 | propagateMouseClickOnPlayers(player_index - 1, checked, false); | 199 | PropagatePlayerNumberChanged(player_index - 1, checked); |
| 188 | } | 200 | } |
| 189 | } else { | 201 | } else { |
| 190 | // Unchecked all following buttons when unchecked | 202 | // Unchecked all following buttons when unchecked |
| 191 | if (player_index < player_tabs.size() - 1) { | 203 | if (player_index < connected_controller_checkboxes.size() - 1) { |
| 192 | // Reconnect current player if it was the last one checked | 204 | PropagatePlayerNumberChanged(player_index + 1, checked); |
| 193 | // (player number was reduced by more than one) | ||
| 194 | if (origin && player_connected[player_index + 1]->checkState() == Qt::Checked) { | ||
| 195 | player_connected[player_index]->setCheckState(Qt::Checked); | ||
| 196 | } | ||
| 197 | propagateMouseClickOnPlayers(player_index + 1, checked, false); | ||
| 198 | } | 205 | } |
| 199 | } | 206 | } |
| 207 | |||
| 208 | if (reconnect_current) { | ||
| 209 | connected_controller_checkboxes[player_index]->setCheckState(Qt::Checked); | ||
| 210 | } | ||
| 200 | } | 211 | } |
| 201 | 212 | ||
| 202 | QList<QWidget*> ConfigureInput::GetSubTabs() const { | 213 | QList<QWidget*> ConfigureInput::GetSubTabs() const { |
| @@ -249,17 +260,17 @@ void ConfigureInput::LoadConfiguration() { | |||
| 249 | } | 260 | } |
| 250 | 261 | ||
| 251 | void ConfigureInput::LoadPlayerControllerIndices() { | 262 | void ConfigureInput::LoadPlayerControllerIndices() { |
| 252 | for (std::size_t i = 0; i < player_connected.size(); ++i) { | 263 | for (std::size_t i = 0; i < connected_controller_checkboxes.size(); ++i) { |
| 253 | if (i == 0) { | 264 | if (i == 0) { |
| 254 | auto* handheld = | 265 | auto* handheld = |
| 255 | system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld); | 266 | system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld); |
| 256 | if (handheld->IsConnected()) { | 267 | if (handheld->IsConnected()) { |
| 257 | player_connected[i]->setChecked(true); | 268 | connected_controller_checkboxes[i]->setChecked(true); |
| 258 | continue; | 269 | continue; |
| 259 | } | 270 | } |
| 260 | } | 271 | } |
| 261 | const auto* controller = system.HIDCore().GetEmulatedControllerByIndex(i); | 272 | const auto* controller = system.HIDCore().GetEmulatedControllerByIndex(i); |
| 262 | player_connected[i]->setChecked(controller->IsConnected()); | 273 | connected_controller_checkboxes[i]->setChecked(controller->IsConnected()); |
| 263 | } | 274 | } |
| 264 | } | 275 | } |
| 265 | 276 | ||
diff --git a/src/yuzu/configuration/configure_input.h b/src/yuzu/configuration/configure_input.h index abb7f7089..136cd3a0a 100644 --- a/src/yuzu/configuration/configure_input.h +++ b/src/yuzu/configuration/configure_input.h | |||
| @@ -56,7 +56,9 @@ private: | |||
| 56 | void UpdateDockedState(bool is_handheld); | 56 | void UpdateDockedState(bool is_handheld); |
| 57 | void UpdateAllInputDevices(); | 57 | void UpdateAllInputDevices(); |
| 58 | void UpdateAllInputProfiles(std::size_t player_index); | 58 | void UpdateAllInputProfiles(std::size_t player_index); |
| 59 | void propagateMouseClickOnPlayers(size_t player_index, bool origin, bool checked); | 59 | // Enable preceding controllers or disable following ones |
| 60 | void PropagatePlayerNumberChanged(size_t player_index, bool checked, | ||
| 61 | bool reconnect_current = false); | ||
| 60 | 62 | ||
| 61 | /// Load configuration settings. | 63 | /// Load configuration settings. |
| 62 | void LoadConfiguration(); | 64 | void LoadConfiguration(); |
| @@ -71,7 +73,8 @@ private: | |||
| 71 | 73 | ||
| 72 | std::array<ConfigureInputPlayer*, 8> player_controllers; | 74 | std::array<ConfigureInputPlayer*, 8> player_controllers; |
| 73 | std::array<QWidget*, 8> player_tabs; | 75 | std::array<QWidget*, 8> player_tabs; |
| 74 | std::array<QCheckBox*, 8> player_connected; | 76 | // Checkboxes representing the "Connected Controllers". |
| 77 | std::array<QCheckBox*, 8> connected_controller_checkboxes; | ||
| 75 | ConfigureInputAdvanced* advanced; | 78 | ConfigureInputAdvanced* advanced; |
| 76 | 79 | ||
| 77 | Core::System& system; | 80 | Core::System& system; |
diff --git a/src/yuzu/configuration/configure_input_player.h b/src/yuzu/configuration/configure_input_player.h index d4df43d73..d3255d2b4 100644 --- a/src/yuzu/configuration/configure_input_player.h +++ b/src/yuzu/configuration/configure_input_player.h | |||
| @@ -75,7 +75,7 @@ public: | |||
| 75 | void ClearAll(); | 75 | void ClearAll(); |
| 76 | 76 | ||
| 77 | signals: | 77 | signals: |
| 78 | /// Emitted when this controller is connected by the user. | 78 | /// Emitted when this controller is (dis)connected by the user. |
| 79 | void Connected(bool connected); | 79 | void Connected(bool connected); |
| 80 | /// Emitted when the Handheld mode is selected (undocked with dual joycons attached). | 80 | /// Emitted when the Handheld mode is selected (undocked with dual joycons attached). |
| 81 | void HandheldStateChanged(bool is_handheld); | 81 | void HandheldStateChanged(bool is_handheld); |
| @@ -183,9 +183,6 @@ private: | |||
| 183 | /// Stores a pair of "Connected Controllers" combobox index and Controller Type enum. | 183 | /// Stores a pair of "Connected Controllers" combobox index and Controller Type enum. |
| 184 | std::vector<std::pair<int, Core::HID::NpadStyleIndex>> index_controller_type_pairs; | 184 | std::vector<std::pair<int, Core::HID::NpadStyleIndex>> index_controller_type_pairs; |
| 185 | 185 | ||
| 186 | static constexpr int PLAYER_COUNT = 8; | ||
| 187 | std::array<QCheckBox*, PLAYER_COUNT> player_connected_checkbox; | ||
| 188 | |||
| 189 | /// This will be the the setting function when an input is awaiting configuration. | 186 | /// This will be the the setting function when an input is awaiting configuration. |
| 190 | std::optional<std::function<void(const Common::ParamPackage&)>> input_setter; | 187 | std::optional<std::function<void(const Common::ParamPackage&)>> input_setter; |
| 191 | 188 | ||