feat(controls): redefinició de tecles i botons del mando des del menú de servei
This commit is contained in:
1 parent
4739354875
commit
37fdcb4751
15 files changed
+1169
-80
No files matched your search
@@ -0,0 +1,91 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
// Vinculacions remapeables d'accions del joc a botons d'un mando concret,
|
||||
// indexades per `(name, path)` del mando — replica el patró
|
||||
// `GamepadConfig` + `GamepadConfigManager` de coffee_crisis_arcade_edition.
|
||||
//
|
||||
// Persisteix en un YAML aïllat al system folder (no a `config.yaml`) perquè
|
||||
// és per dispositiu, no per usuari/perfil: dos mandos diferents poden
|
||||
// tenir mappings diferents i cap d'ells va lligat a un slot de jugador.
|
||||
//
|
||||
// El layer runtime (consultat per Player/Director cada frame) és
|
||||
// directament aquesta classe; no hi ha caché a `GamepadManager::Entry`. El
|
||||
// nombre d'entries persistides és típicament <10, i les accions són 3
|
||||
// (JUMP/ATTACK/SERVICE), així que les consultes són trivialment ràpides.
|
||||
class GamepadBindings {
|
||||
public:
|
||||
enum class Action : std::uint8_t {
|
||||
JUMP,
|
||||
ATTACK,
|
||||
SERVICE,
|
||||
};
|
||||
|
||||
// Triggers L2/R2 representats com a "botons virtuals" — replica la
|
||||
// convenció de coffee_crisis_arcade_edition (`TRIGGER_L2_AS_BUTTON`,
|
||||
// `TRIGGER_R2_AS_BUTTON`). El threshold viu a `isPressed`.
|
||||
static constexpr int TRIGGER_L2_AS_BUTTON = 100;
|
||||
static constexpr int TRIGGER_R2_AS_BUTTON = 101;
|
||||
|
||||
static auto get() -> GamepadBindings&;
|
||||
|
||||
GamepadBindings(const GamepadBindings&) = delete;
|
||||
GamepadBindings(GamepadBindings&&) = delete;
|
||||
auto operator=(const GamepadBindings&) -> GamepadBindings& = delete;
|
||||
auto operator=(GamepadBindings&&) -> GamepadBindings& = delete;
|
||||
|
||||
// Fixa la ruta del fitxer persistent + el carrega. Si no existix
|
||||
// encara, l'estat queda buit (les consultes retornaran defaults) i
|
||||
// `save()` el crearà al primer `setBindings`.
|
||||
void load(const std::string& file_path);
|
||||
|
||||
// Persistix l'estat actual (totes les Config conegudes). Cridat
|
||||
// automàticament dins de `setBindings` — no cal cridar-la a mà.
|
||||
auto save() -> bool;
|
||||
|
||||
// Retorna el botó (o trigger virtual 100/101) lligat a `action` per al
|
||||
// mando identificat per (name, path). Si no hi ha entrada per aquest
|
||||
// mando, retorna el default global. La cerca és primer per `path`
|
||||
// (re-vincular el mateix mando al mateix port és prioritari) i, si no
|
||||
// troba, fallback per `name` (mando connectat a un altre port USB).
|
||||
[[nodiscard]] auto getButton(const std::string& name, const std::string& path, Action action) const -> int;
|
||||
|
||||
// Reescriu totes les vinculacions del mando (name, path). Si no hi
|
||||
// havia config per aquest dispositiu, en crea una nova. Persisteix a
|
||||
// disc immediatament. Replicació de `Input::saveGamepadConfigFromGamepad`.
|
||||
void setBindings(const std::string& name,
|
||||
const std::string& path,
|
||||
const std::unordered_map<Action, int>& bindings);
|
||||
|
||||
// Wrapper de polling: torna `true` si el "botó" (o trigger virtual)
|
||||
// està premut ara mateix al mando `pad`. Encapsula el threshold per
|
||||
// a L2/R2 (~50% del rang).
|
||||
[[nodiscard]] static auto isPressed(SDL_Gamepad* pad, int button) -> bool;
|
||||
|
||||
// Default de fàbrica per a una acció — usat tant pel fallback de
|
||||
// `getButton` com per inicialitzar la seqüència del DefineButtons.
|
||||
[[nodiscard]] static auto defaultButton(Action action) -> int;
|
||||
|
||||
private:
|
||||
struct Config {
|
||||
std::string name;
|
||||
std::string path;
|
||||
std::unordered_map<Action, int> bindings;
|
||||
};
|
||||
|
||||
GamepadBindings() = default;
|
||||
~GamepadBindings() = default;
|
||||
|
||||
// Localitza la Config que coincideix amb (name, path); retorna -1 si
|
||||
// no la troba. Match prioritari per path, fallback per nom.
|
||||
[[nodiscard]] auto findConfig(const std::string& name, const std::string& path) const -> int;
|
||||
|
||||
std::vector<Config> configs_;
|
||||
std::string file_path_;
|
||||
};
|
||||
Reference in new issue
Block a user