aboutsummaryrefslogtreecommitdiff
path: root/src/core/frontend/applets/controller.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/frontend/applets/controller.cpp')
-rw-r--r--src/core/frontend/applets/controller.cpp35
1 files changed, 26 insertions, 9 deletions
diff --git a/src/core/frontend/applets/controller.cpp b/src/core/frontend/applets/controller.cpp
index c4292c5a12..e535866855 100644
--- a/src/core/frontend/applets/controller.cpp
+++ b/src/core/frontend/applets/controller.cpp
@@ -12,6 +12,7 @@
#include "hid_core/frontend/emulated_controller.h"
#include "hid_core/hid_core.h"
#include "hid_core/hid_types.h"
+#include <array>
namespace Core::Frontend {
@@ -29,23 +30,39 @@ void DefaultControllerApplet::ReconfigureControllers(ReconfigureCallback callbac
const std::size_t min_supported_players =
parameters.enable_single_mode ? 1 : parameters.min_players;
-
- // Disconnect Handheld first.
+ using Core::HID::NpadStyleIndex;
+ const std::size_t max_supported_players = parameters.enable_single_mode ? 1 : parameters.max_players;
+ std::size_t num_selected_players = 0;
+ std::array<bool, HID::HIDCore::available_controllers> keep_connected{};
+
+ // reserve existing AND valid players before filling slots. include Handheld, but not other
+ for (std::size_t index = 0; index < hid_core.available_controllers - 1; ++index) {
+ const auto* controller = hid_core.GetEmulatedControllerByIndex(index);
+ if (!parameters.keep_controllers_connected || !controller->IsConnected() || num_selected_players >= max_supported_players) continue;
+
+ const auto style = controller->GetNpadStyleIndex();
+ keep_connected[index] =
+ (style == NpadStyleIndex::Fullkey && parameters.allow_pro_controller) ||
+ (style == NpadStyleIndex::JoyconDual && parameters.allow_dual_joycons) ||
+ (style == NpadStyleIndex::JoyconLeft && parameters.allow_left_joycon) ||
+ (style == NpadStyleIndex::JoyconRight && parameters.allow_right_joycon) ||
+ (style == NpadStyleIndex::Handheld && parameters.enable_single_mode && parameters.allow_handheld && !Settings::IsDockedMode()) ||
+ (style == NpadStyleIndex::GameCube && parameters.allow_gamecube_controller);
+ num_selected_players += keep_connected[index];
+ }
auto* handheld = hid_core.GetEmulatedController(Core::HID::NpadIdType::Handheld);
- handheld->Disconnect();
+ if (!keep_connected[hid_core.available_controllers - 2]) handheld->Disconnect();
// Deduce the best configuration based on the input parameters.
for (std::size_t index = 0; index < hid_core.available_controllers - 2; ++index) {
auto* controller = hid_core.GetEmulatedControllerByIndex(index);
- // First, disconnect all controllers regardless of the value of keep_controllers_connected.
- // This makes it easy to connect the desired controllers.
+ if (keep_connected[index]) continue;
controller->Disconnect();
- // Only connect the minimum number of required players.
- if (index >= min_supported_players) {
- continue;
- }
+ // only add players still needed to reach the minimum
+ if (num_selected_players >= min_supported_players) continue;
+ ++num_selected_players;
// Connect controllers based on the following priority list from highest to lowest priority:
// Pro Controller -> Dual Joycons -> Left Joycon/Right Joycon -> Handheld