summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/yuzu/applets/qt_controller.cpp52
-rw-r--r--src/yuzu/applets/qt_controller.h4
-rw-r--r--src/yuzu/configuration/configure_input.cpp59
-rw-r--r--src/yuzu/configuration/configure_input.h7
-rw-r--r--src/yuzu/configuration/configure_input_player.h5
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
680void 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
671void QtControllerSelectorDialog::DisableUnsupportedPlayers() { 703void 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
178void ConfigureInput::propagateMouseClickOnPlayers(size_t player_index, bool checked, bool origin) { 192void 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
202QList<QWidget*> ConfigureInput::GetSubTabs() const { 213QList<QWidget*> ConfigureInput::GetSubTabs() const {
@@ -249,17 +260,17 @@ void ConfigureInput::LoadConfiguration() {
249} 260}
250 261
251void ConfigureInput::LoadPlayerControllerIndices() { 262void 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
77signals: 77signals:
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