133 lines
5.2 KiB
C++
133 lines
5.2 KiB
C++
#pragma once
|
|
|
|
#include <SDL3/SDL.h>
|
|
|
|
#include <cstdint> // for uint8_t
|
|
#include <string> // for string, basic_string
|
|
#include <vector> // for vector
|
|
|
|
class Input {
|
|
public:
|
|
enum class Repeat : std::uint8_t {
|
|
OFF,
|
|
ON
|
|
};
|
|
|
|
enum class Device : std::uint8_t {
|
|
KEYBOARD,
|
|
GAMECONTROLLER,
|
|
ANY
|
|
};
|
|
|
|
enum class Disable : std::uint8_t {
|
|
NOT_DISABLED,
|
|
FOREVER,
|
|
KEY_PRESSED
|
|
};
|
|
|
|
enum class Action : std::uint8_t {
|
|
// Inputs obligatorios
|
|
INVALID,
|
|
UP,
|
|
DOWN,
|
|
LEFT,
|
|
RIGHT,
|
|
PAUSE,
|
|
EXIT,
|
|
ACCEPT,
|
|
CANCEL,
|
|
|
|
// Inputs personalizados
|
|
FIRE_LEFT,
|
|
FIRE_CENTER,
|
|
FIRE_RIGHT,
|
|
WINDOW_FULLSCREEN,
|
|
WINDOW_INC_ZOOM,
|
|
WINDOW_DEC_ZOOM,
|
|
|
|
// GPU / shaders (hotkeys provisionales hasta que haya menú de opciones)
|
|
NEXT_SHADER_PRESET,
|
|
TOGGLE_SHADER,
|
|
TOGGLE_SHADER_TYPE,
|
|
|
|
// Diagnostic
|
|
SHOW_VERSION,
|
|
|
|
// Centinela final (usar para sizing)
|
|
NUMBER_OF_INPUTS
|
|
};
|
|
|
|
// Singleton API
|
|
static void init(const std::string &game_controller_db_path); // Crea la instancia
|
|
static void destroy(); // Libera la instancia
|
|
static auto get() -> Input *; // Obtiene el puntero a la instancia
|
|
|
|
~Input(); // Destructor
|
|
|
|
void update(); // Actualiza el estado del objeto
|
|
void bindKey(Action input, SDL_Scancode code); // Asigna inputs a teclas
|
|
void bindGameControllerButton(Action input, SDL_GamepadButton button); // Asigna inputs a botones del mando
|
|
|
|
auto checkInput(Action input, Repeat repeat = Repeat::ON, Device device = Device::ANY, int index = 0) -> bool; // Comprueba si un input esta activo
|
|
auto checkAnyInput(Device device = Device::ANY, int index = 0) -> bool; // Comprueba si hay almenos un input activo
|
|
|
|
auto discoverGameController() -> bool; // Busca si hay un mando conectado
|
|
|
|
// Procesa un evento SDL_EVENT_GAMEPAD_ADDED. Devuelve true si el mando se ha añadido
|
|
// (no estaba ya registrado) y escribe el nombre visible en outName.
|
|
auto handleGamepadAdded(SDL_JoystickID jid, std::string &out_name) -> bool;
|
|
|
|
// Procesa un evento SDL_EVENT_GAMEPAD_REMOVED. Devuelve true si se ha encontrado y
|
|
// eliminado, y escribe el nombre visible en outName.
|
|
auto handleGamepadRemoved(SDL_JoystickID jid, std::string &out_name) -> bool;
|
|
|
|
[[nodiscard]] auto gameControllerFound() const -> bool; // Comprueba si hay algun mando conectado
|
|
[[nodiscard]] auto getNumControllers() const -> int; // Obten el numero de mandos conectados
|
|
auto getControllerName(int index) -> std::string; // Obten el nombre de un mando de juego
|
|
|
|
void setVerbose(bool value); // Establece si ha de mostrar mensajes
|
|
void disableUntil(Disable value); // Deshabilita las entradas durante un periodo de tiempo
|
|
void enable(); // Hablita las entradas
|
|
|
|
private:
|
|
struct KeyBindings {
|
|
Uint8 scancode; // Scancode asociado
|
|
bool active; // Indica si está activo
|
|
};
|
|
|
|
struct GameControllerBindings {
|
|
SDL_GamepadButton button; // GameControllerButton asociado
|
|
bool active; // Indica si está activo
|
|
};
|
|
|
|
// Objetos y punteros
|
|
std::vector<SDL_Gamepad *> connected_controllers_; // Vector con todos los mandos conectados
|
|
std::vector<SDL_JoystickID> connected_controller_ids_; // Instance IDs paralelos para mapear eventos
|
|
|
|
// Variables
|
|
std::vector<KeyBindings> key_bindings_; // Vector con las teclas asociadas a los inputs predefinidos
|
|
std::vector<GameControllerBindings> game_controller_bindings_; // Vector con las teclas asociadas a los inputs predefinidos
|
|
std::vector<std::string> controller_names_; // Vector con los nombres de los mandos
|
|
int num_gamepads_{0}; // Numero de mandos conectados
|
|
std::string db_path_; // Ruta al archivo gamecontrollerdb.txt
|
|
bool verbose_{true}; // Indica si ha de mostrar mensajes
|
|
Disable disabled_until_{Disable::NOT_DISABLED}; // Tiempo que esta deshabilitado
|
|
bool enabled_{true}; // Indica si está habilitado
|
|
|
|
static Input *instance; // Instancia única
|
|
|
|
explicit Input(std::string file); // Constructor privado (usar Input::init)
|
|
|
|
// Construye el nombre visible de un mando (name truncado + sufijo #N)
|
|
static auto buildControllerName(SDL_Gamepad *pad, int pad_index) -> std::string;
|
|
|
|
// Helpers de checkInput
|
|
auto checkKeyboardInput(Action input, Repeat repeat) -> bool;
|
|
auto checkGameControllerInput(Action input, Repeat repeat, int index) -> bool;
|
|
|
|
// Helpers de discoverGameController
|
|
void resetGameControllerState();
|
|
void ensureGamepadSubsystem();
|
|
auto openGamepad(SDL_JoystickID joystick_id, int pad_index) -> bool;
|
|
};
|