feat(input): assignació mando↔jugador persistida a config.yaml
This commit is contained in:
1 parent
4e9d5df872
commit
a725b76684
5 files changed
+226
-13
No files matched your search
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -41,22 +42,70 @@ class GamepadManager {
|
||||
void handleEvent(const SDL_Event& ev);
|
||||
|
||||
// Primary = primer gamepad al vector. `nullptr` si no n'hi ha cap.
|
||||
// Ús típic: Player 1 i navegació del ServiceMenu.
|
||||
// Ús típic: navegació del ServiceMenu. Per al gameplay els jugadors
|
||||
// usen `getForPlayer(id)`.
|
||||
[[nodiscard]] auto getPrimary() const -> SDL_Gamepad*;
|
||||
|
||||
[[nodiscard]] auto getCount() const -> std::size_t;
|
||||
|
||||
// Retorna el mand del jugador `idx`-èsim (0-indexed) o `nullptr` si
|
||||
// encara no hi ha prou mandos connectats. Reservat per a multi-jugador.
|
||||
// Retorna el mand del jugador `idx`-èsim (0-indexed) en l'ordre de
|
||||
// connexió. Per al gameplay, `getForPlayer` fa servir l'assignació
|
||||
// persistida, no l'ordre de connexió.
|
||||
[[nodiscard]] auto getByPlayerIndex(std::size_t idx) const -> SDL_Gamepad*;
|
||||
|
||||
// Informació exposada al menú de servei (llista de mandos
|
||||
// disponibles). `path` pot estar buit si SDL no l'exposa (p. ex. a
|
||||
// alguns backends web).
|
||||
struct Info {
|
||||
SDL_Gamepad* pad{nullptr};
|
||||
std::string name;
|
||||
std::string path;
|
||||
};
|
||||
[[nodiscard]] auto getAll() const -> std::vector<Info>;
|
||||
|
||||
// Retorna el mand assignat al jugador `player_id` (0 = P1, 1 = P2)
|
||||
// o `nullptr` si no n'hi ha cap. L'assignació la fixa
|
||||
// `assignToPlayer` (cridat per Options en carregar `config.yaml` o
|
||||
// des del ServiceMenu quan l'usuari tria un mando).
|
||||
[[nodiscard]] auto getForPlayer(int player_id) const -> SDL_Gamepad*;
|
||||
|
||||
// Assigna un mando per nom + ruta física. Si ja hi ha un mando
|
||||
// connectat que coincideix per ruta (o per nom com a fallback), el
|
||||
// vincula immediatament; si no, l'assignació queda pendent i
|
||||
// s'aplicarà si el mando es connecta més tard (hot-plug).
|
||||
// Política last-wins: si l'altre jugador tenia el mateix mando
|
||||
// vinculat, se'l desvincula silenciosament.
|
||||
void assignToPlayer(int player_id, const std::string& name, const std::string& path);
|
||||
|
||||
// Esborra l'assignació (per si l'usuari trie "Cap" al menú).
|
||||
void unassignFromPlayer(int player_id);
|
||||
|
||||
private:
|
||||
struct Entry {
|
||||
SDL_Gamepad* pad{nullptr};
|
||||
SDL_JoystickID instance_id{0};
|
||||
std::string pretty_name;
|
||||
std::string path;
|
||||
};
|
||||
|
||||
// Assignació persistent per jugador. `name` i `path` venen d'Options
|
||||
// (o del menú de servei) i poden referenciar un mando encara no
|
||||
// connectat; en aquest cas `pad` és `nullptr` i el hot-plug el
|
||||
// vincularà quan aparegui.
|
||||
struct Assignment {
|
||||
std::string name;
|
||||
std::string path;
|
||||
SDL_Gamepad* pad{nullptr};
|
||||
};
|
||||
static constexpr int MAX_PLAYERS = 2;
|
||||
std::array<Assignment, MAX_PLAYERS> assignments_{};
|
||||
|
||||
// Busca a `entries_` el millor match per a una assignació (primer
|
||||
// per path, després per nom). Retorna l'iterador o `entries_.end()`.
|
||||
// També accepta assignar `path` nou si ha coincidit per nom
|
||||
// (cas mando reenchufat a un altre port USB).
|
||||
void rebindAssignment(Assignment& a);
|
||||
|
||||
GamepadManager() = default;
|
||||
~GamepadManager() = default;
|
||||
|
||||
|
||||
Reference in new issue
Block a user