[applet] ReconfigureControllers fallback unconditional disconnect fix (#4420)

- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.

-------------------

So, about Absolum's no overlay applet P2 issue:

The fallback controller applet ignored keep_controllers_connected, according comment: "This makes it easy to connect the desired controllers". Unfortunately it was not good enough. It disconnected every controller, then reconnected only the minimum player count. That disconnect interacts with some guests (absolum in this case) causing undesired behaviors.

The fix is entwined to original routine but it is a lot simple tho: preserves compatible connected controllers within the requested player range, while the existing routine configures only the remaining slots.

This may fix some games, and should not harm others. Let us give it a go.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4420
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
This commit is contained in:
xbzk
2026-09-15 21:53:07 +02:00
committed by crueter
parent defddec47f
commit b77308ced6
+25 -8
View File
@@ -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;
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{};
// Disconnect Handheld first.
// 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