feat(service_menu): picker de mando per llista i fix SENSE MANDO

El cycle anterior fallava al desasignar perque Input::resolvePlayerGamepad
tenia un fallback per slot que reasignava gamepads_[player_index] quan
name+path eren buits. Això el contradeia el slot "SENSE MANDO" del cycle:
el YAML quedava buit pero el runtime seguia lligant el mando. Treure el
fallback i moure l'autoassignacio inicial al boot (nomes si tots dos
jugadors venen buits) restaura la semàntica: buit vol dir buit.

Sobre el fix, redissenyem la UX dels items MANDO P1/P2: ja no son CYCLE
sino SUBMENU que obrin una pàgina-llista (estil RESOLUCIÓ) amb tots els
mandos detectats. Cada item porta sufix (P1)/(P2) nomes si el mando el
te l'altre jugador, perque sapigues que assignar-lo li'l "robarà".
L'ultim item es "SENSE MANDO" per a desassignar explícitament. La
lògica de swap automatic en conflicte queda extreta a assignPadToPlayer
i es reutilitza des de la picker.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-24 22:12:53 +02:00
parent 99d0f62ab5
commit 3dcf5c3a99
5 changed files with 132 additions and 59 deletions
+5 -1
View File
@@ -107,7 +107,11 @@ namespace System {
[[nodiscard]] static auto buildAudioPage() -> Page;
[[nodiscard]] auto buildOptionsPage() const -> Page;
[[nodiscard]] auto buildSystemPage() -> Page;
[[nodiscard]] static auto buildControlsPage() -> Page;
[[nodiscard]] auto buildControlsPage() -> Page;
// Llista de mandos detectats per a un jugador. Cada item assigna el
// pad triat (amb swap automatic si l'altre jugador ja el tenia).
// L'ultim item es "SENSE MANDO" per a desasignar.
[[nodiscard]] static auto buildPadPickerPage(int player_index) -> Page;
// Pagina de confirmacio "ESTAS SEGUR? NO/SI". on_yes s'executa si
// l'usuari selecciona SI; el cursor per defecte apunta a NO.
void pushConfirmPage(const std::string& title_key, std::function<void()> on_yes);