fix(input): dedup de mandos, auto-assign per ordre i cycles sense col·lisió
This commit is contained in:
1 parent
e5b8d7731b
commit
996ff0053e
4 files changed
+111
-20
No files matched your search
@@ -79,6 +79,17 @@ auto GamepadManager::uniqueName(const std::string& base) const -> std::string {
|
||||
}
|
||||
|
||||
void GamepadManager::addGamepad(SDL_JoystickID jid, bool notify) {
|
||||
// Dedup per `instance_id`: SDL encua un SDL_EVENT_GAMEPAD_ADDED per
|
||||
// cada mando ja connectat quan s'inicialitza el subsistema, a més
|
||||
// dels que ja hem obert a `init()`. Sense aquesta guarda, el mateix
|
||||
// mando s'afegiria dues vegades (silenciós + notificat amb sufix
|
||||
// "#2") i qualsevol referència via `getPrimary`/`entries_` seria
|
||||
// ambigua.
|
||||
const bool ALREADY_KNOWN = std::ranges::any_of(
|
||||
entries_,
|
||||
[jid](const Entry& e) { return e.instance_id == jid; });
|
||||
if (ALREADY_KNOWN) { return; }
|
||||
|
||||
installWebStandardMapping(jid);
|
||||
if (!SDL_IsGamepad(jid)) { return; }
|
||||
SDL_Gamepad* pad = SDL_OpenGamepad(jid);
|
||||
@@ -257,3 +268,28 @@ void GamepadManager::unassignFromPlayer(int player_id) {
|
||||
if (player_id < 0 || player_id >= MAX_PLAYERS) { return; }
|
||||
assignments_[static_cast<std::size_t>(player_id)] = Assignment{};
|
||||
}
|
||||
|
||||
auto GamepadManager::autoAssignFreeSlots() -> std::vector<AutoAssigned> {
|
||||
std::vector<AutoAssigned> assigned;
|
||||
for (int pid = 0; pid < MAX_PLAYERS; ++pid) {
|
||||
auto& slot = assignments_[static_cast<std::size_t>(pid)];
|
||||
if (slot.pad != nullptr) { continue; }
|
||||
// Primer mando que cap altre slot no haja reclamat. Així respectem
|
||||
// qualsevol assignació persistida que ja haja vinculat un pad
|
||||
// concret i no el reassignem a un jugador diferent.
|
||||
for (const auto& e : entries_) {
|
||||
const bool TAKEN = std::ranges::any_of(
|
||||
assignments_,
|
||||
[&](const Assignment& other) { return other.pad == e.pad; });
|
||||
if (TAKEN) { continue; }
|
||||
slot.pad = e.pad;
|
||||
slot.name = e.pretty_name;
|
||||
slot.path = e.path;
|
||||
assigned.push_back(AutoAssigned{.player_id = pid, .name = e.pretty_name, .path = e.path});
|
||||
std::cout << "GamepadManager: auto-assigned " << e.pretty_name
|
||||
<< " → P" << (pid + 1) << '\n';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return assigned;
|
||||
}
|
||||
Reference in new issue
Block a user