Files
jaildoctors_dilemma/source/core/input/input.hpp
2025-10-27 18:35:53 +01:00

138 lines
5.1 KiB
C++

#pragma once
#include <SDL3/SDL.h>
#include <string> // Para string, basic_string
#include <vector> // Para vector
// Definiciones de repetición
constexpr bool INPUT_ALLOW_REPEAT = true;
constexpr bool INPUT_DO_NOT_ALLOW_REPEAT = false;
// Tipos de entrada
enum class InputDeviceToUse : int {
KEYBOARD = 0,
CONTROLLER = 1,
ANY = 2,
};
enum class InputAction {
// Inputs obligatorios
UP,
DOWN,
LEFT,
RIGHT,
PAUSE,
EXIT,
ACCEPT,
CANCEL,
// Inputs personalizados
JUMP,
WINDOW_INC_ZOOM,
WINDOW_DEC_ZOOM,
TOGGLE_VIDEOMODE,
TOGGLE_INTEGER_SCALE,
TOGGLE_BORDER,
TOGGLE_MUSIC,
NEXT_PALETTE,
PREVIOUS_PALETTE,
TOGGLE_SHADERS,
SHOW_DEBUG_INFO,
// Input obligatorio
NONE,
SIZE
};
class Input {
private:
// [SINGLETON] Objeto privado
static Input* input;
struct KeyBindings {
Uint8 scancode; // Scancode asociado
bool active; // Indica si está activo
// Constructor
explicit KeyBindings(Uint8 sc = 0, bool act = false)
: scancode(sc),
active(act) {}
};
struct ControllerBindings {
SDL_GamepadButton button; // GameControllerButton asociado
bool active; // Indica si está activo
bool axis_active; // Estado del eje
// Constructor
explicit ControllerBindings(SDL_GamepadButton btn = SDL_GAMEPAD_BUTTON_INVALID, bool act = false, bool axis_act = false)
: button(btn),
active(act),
axis_active(axis_act) {}
};
// Variables
std::vector<SDL_Gamepad*> connected_controllers_; // Vector con todos los mandos conectados
std::vector<SDL_Joystick*> joysticks_; // Vector con todos los joysticks conectados
std::vector<KeyBindings> key_bindings_; // Vector con las teclas asociadas a los inputs predefinidos
std::vector<std::vector<ControllerBindings>> controller_bindings_; // Vector con los botones asociadas a los inputs predefinidos para cada mando
std::vector<std::string> controller_names_; // Vector con los nombres de los mandos
std::vector<InputAction> button_inputs_; // Inputs asignados al jugador y a botones, excluyendo direcciones
int num_joysticks_ = 0; // Número de joysticks conectados
int num_gamepads_ = 0; // Número de mandos conectados
std::string game_controller_db_path_; // Ruta al archivo gamecontrollerdb.txt
// Comprueba el eje del mando
auto checkAxisInput(InputAction input, int controller_index, bool repeat) -> bool;
// Constructor
explicit Input(const std::string& game_controller_db_path);
// Destructor
~Input() = default;
public:
// [SINGLETON] Crearemos el objeto con esta función estática
static void init(const std::string& game_controller_db_path);
// [SINGLETON] Destruiremos el objeto con esta función estática
static void destroy();
// [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él
static auto get() -> Input*;
// Asigna inputs a teclas
void bindKey(InputAction input, SDL_Scancode code);
// Asigna inputs a botones del mando
void bindGameControllerButton(int controller_index, InputAction input, SDL_GamepadButton button);
void bindGameControllerButton(int controller_index, InputAction input_target, InputAction input_source);
// Comprueba si un input esta activo
auto checkInput(InputAction input, bool repeat = true, InputDeviceToUse device = InputDeviceToUse::ANY, int controller_index = 0) -> bool;
// Comprueba si hay almenos un input activo
auto checkAnyInput(InputDeviceToUse device = InputDeviceToUse::ANY, int controller_index = 0) -> bool;
// Busca si hay mandos conectados
auto discoverGameControllers() -> bool;
// Comprueba si hay algun mando conectado
[[nodiscard]] auto gameControllerFound() const -> bool;
// Obten el número de mandos conectados
[[nodiscard]] auto getNumControllers() const -> int;
// Obten el nombre de un mando de juego
[[nodiscard]] auto getControllerName(int controller_index) const -> std::string;
// Obtiene el indice del controlador a partir de un event.id
[[nodiscard]] auto getJoyIndex(SDL_JoystickID id) const -> int;
// Obtiene el SDL_GamepadButton asignado a un input
[[nodiscard]] auto getControllerBinding(int controller_index, InputAction input) const -> SDL_GamepadButton;
// Obtiene el indice a partir del nombre del mando
[[nodiscard]] auto getIndexByName(const std::string& name) const -> int;
};