#pragma once #include #include // for uint8_t #include // for string, basic_string #include // for vector // Valores de repetición constexpr bool REPEAT_TRUE = true; constexpr bool REPEAT_FALSE = false; // Métodos de entrada constexpr int INPUT_USE_KEYBOARD = 0; constexpr int INPUT_USE_GAMECONTROLLER = 1; constexpr int INPUT_USE_ANY = 2; enum InputAction : std::uint8_t { // Inputs obligatorios input_null, input_up, input_down, input_left, input_right, input_pause, input_exit, input_accept, input_cancel, // Inputs personalizados input_fire_left, input_fire_center, input_fire_right, input_window_fullscreen, input_window_inc_size, input_window_dec_size, // GPU / shaders (hotkeys provisionales hasta que haya menú de opciones) input_next_preset, input_toggle_shader, input_toggle_shader_type, // Input obligatorio input_number_of_inputs }; enum InputDisable : std::uint8_t { d_notDisabled, d_forever, d_keyPressed }; class Input { 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 connectedControllers; // Vector con todos los mandos conectados std::vector connectedControllerIds; // Instance IDs paralelos para mapear eventos // Variables std::vector keyBindings; // Vector con las teclas asociadas a los inputs predefinidos std::vector gameControllerBindings; // Vector con las teclas asociadas a los inputs predefinidos std::vector controllerNames; // Vector con los nombres de los mandos int numGamepads{0}; // Numero de mandos conectados std::string dbPath; // Ruta al archivo gamecontrollerdb.txt bool verbose{true}; // Indica si ha de mostrar mensajes InputDisable disabledUntil{d_notDisabled}; // Tiempo que esta deshabilitado bool enabled{true}; // Indica si está habilitado // Construye el nombre visible de un mando (name truncado + sufijo #N) static auto buildControllerName(SDL_Gamepad *pad, int padIndex) -> std::string; // Constructor privado (usar Input::init) explicit Input(std::string file); // Instancia única static Input *instance; public: // Singleton API static void init(const std::string &gameControllerDbPath); // Crea la instancia static void destroy(); // Libera la instancia static auto get() -> Input *; // Obtiene el puntero a la instancia // Destructor ~Input(); // Actualiza el estado del objeto void update(); // Asigna inputs a teclas void bindKey(Uint8 input, SDL_Scancode code); // Asigna inputs a botones del mando void bindGameControllerButton(Uint8 input, SDL_GamepadButton button); // Comprueba si un input esta activo auto checkInput(Uint8 input, bool repeat = true, int device = INPUT_USE_ANY, int index = 0) -> bool; // Comprueba si hay almenos un input activo auto checkAnyInput(int device = INPUT_USE_ANY, int index = 0) -> bool; // Busca si hay un mando conectado auto discoverGameController() -> bool; // 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 &outName) -> 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 &outName) -> bool; // Comprueba si hay algun mando conectado [[nodiscard]] auto gameControllerFound() const -> bool; // Obten el numero de mandos conectados [[nodiscard]] auto getNumControllers() const -> int; // Obten el nombre de un mando de juego auto getControllerName(int index) -> std::string; // Establece si ha de mostrar mensajes void setVerbose(bool value); // Deshabilita las entradas durante un periodo de tiempo void disableUntil(InputDisable value); // Hablita las entradas void enable(); };