Input: mogudes structs, enums i consts a la part publica

This commit is contained in:
2025-07-30 08:53:57 +02:00
parent 677feb3afe
commit 989f081a25
14 changed files with 302 additions and 275 deletions

View File

@@ -27,39 +27,39 @@ Input::Input(std::string game_controller_db_path)
initSDLGamePad();
// Inicializa los vectores
key_bindings_.resize(static_cast<int>(InputAction::SIZE), KeyBindings());
controller_bindings_.resize(num_gamepads_, std::vector<ControllerBindings>(static_cast<int>(InputAction::SIZE), ControllerBindings()));
key_bindings_.resize(static_cast<int>(Action::SIZE), KeyBindings());
controller_bindings_.resize(num_gamepads_, std::vector<ControllerBindings>(static_cast<int>(Action::SIZE), ControllerBindings()));
// Listado de los inputs para jugar que utilizan botones, ni palancas ni crucetas
button_inputs_ = {InputAction::FIRE_LEFT, InputAction::FIRE_CENTER, InputAction::FIRE_RIGHT, InputAction::START};
button_inputs_ = {Action::FIRE_LEFT, Action::FIRE_CENTER, Action::FIRE_RIGHT, Action::START};
}
// Asigna inputs a teclas
void Input::bindKey(InputAction input, SDL_Scancode code) {
void Input::bindKey(Action input, SDL_Scancode code) {
key_bindings_.at(static_cast<int>(input)).scancode = code;
}
// Asigna inputs a botones del mando
void Input::bindGameControllerButton(int controller_index, InputAction input, SDL_GamepadButton button) {
void Input::bindGameControllerButton(int controller_index, Action input, SDL_GamepadButton button) {
if (controller_index < num_gamepads_) {
controller_bindings_.at(controller_index).at(static_cast<int>(input)).button = button;
}
}
// Asigna inputs a botones del mando
void Input::bindGameControllerButton(int controller_index, InputAction input_target, InputAction input_source) {
void Input::bindGameControllerButton(int controller_index, Action input_target, Action input_source) {
if (controller_index < num_gamepads_) {
controller_bindings_.at(controller_index).at(static_cast<int>(input_target)).button = controller_bindings_.at(controller_index).at(static_cast<int>(input_source)).button;
}
}
// Comprueba si un input esta activo
auto Input::checkInput(InputAction input, bool repeat, InputDevice device, int controller_index) -> bool {
auto Input::checkInput(Action input, bool repeat, Device device, int controller_index) -> bool {
bool success_keyboard = false;
bool success_controller = false;
const int INPUT_INDEX = static_cast<int>(input);
if (device == InputDevice::KEYBOARD || device == InputDevice::ANY) {
if (device == Device::KEYBOARD || device == Device::ANY) {
if (repeat) { // El usuario quiere saber si está pulsada (estado mantenido)
success_keyboard = key_bindings_[INPUT_INDEX].is_held;
} else { // El usuario quiere saber si ACABA de ser pulsada (evento de un solo fotograma)
@@ -68,7 +68,7 @@ auto Input::checkInput(InputAction input, bool repeat, InputDevice device, int c
}
if (gameControllerFound() && controller_index >= 0 && controller_index < num_gamepads_) {
if ((device == InputDevice::CONTROLLER) || (device == InputDevice::ANY)) {
if ((device == Device::CONTROLLER) || (device == Device::ANY)) {
success_controller = checkAxisInput(input, controller_index, repeat);
if (!success_controller) {
@@ -85,12 +85,12 @@ auto Input::checkInput(InputAction input, bool repeat, InputDevice device, int c
}
// Comprueba si hay almenos un input activo
auto Input::checkAnyInput(InputDevice device, int controller_index) -> bool {
auto Input::checkAnyInput(Device device, int controller_index) -> bool {
// Obtenemos el número total de acciones posibles para iterar sobre ellas.
const int NUM_ACTIONS = static_cast<int>(InputAction::SIZE);
const int NUM_ACTIONS = static_cast<int>(Action::SIZE);
// --- Comprobación del Teclado ---
if (device == InputDevice::KEYBOARD || device == InputDevice::ANY) {
if (device == Device::KEYBOARD || device == Device::ANY) {
for (int i = 0; i < NUM_ACTIONS; ++i) {
// Simplemente leemos el estado pre-calculado por Input::update().
// Ya no se llama a SDL_GetKeyboardState ni se modifica el estado '.active'.
@@ -103,7 +103,7 @@ auto Input::checkAnyInput(InputDevice device, int controller_index) -> bool {
// --- Comprobación del Mando ---
// Comprobamos si hay mandos y si el índice solicitado es válido.
if (gameControllerFound() && controller_index >= 0 && controller_index < num_gamepads_) {
if (device == InputDevice::CONTROLLER || device == InputDevice::ANY) {
if (device == Device::CONTROLLER || device == Device::ANY) {
// Bucle CORREGIDO: Iteramos sobre todas las acciones, no sobre el número de mandos.
for (int i = 0; i < NUM_ACTIONS; ++i) {
// Leemos el estado pre-calculado para el mando y la acción específicos.
@@ -123,13 +123,13 @@ auto Input::checkAnyButton(bool repeat) -> int {
// Solo comprueba los botones definidos previamente
for (auto bi : button_inputs_) {
// Comprueba el teclado
if (checkInput(bi, repeat, InputDevice::KEYBOARD)) {
if (checkInput(bi, repeat, Device::KEYBOARD)) {
return 1;
}
// Comprueba los mandos
for (int i = 0; i < num_gamepads_; ++i) {
if (checkInput(bi, repeat, InputDevice::CONTROLLER, i)) {
if (checkInput(bi, repeat, Device::CONTROLLER, i)) {
return i + 1;
}
}
@@ -226,12 +226,12 @@ auto Input::getJoyIndex(SDL_JoystickID id) const -> int {
}
// Muestra por consola los controles asignados
void Input::printBindings(InputDevice device, int controller_index) const {
if (device == InputDevice::ANY || device == InputDevice::KEYBOARD) {
void Input::printBindings(Device device, int controller_index) const {
if (device == Device::ANY || device == Device::KEYBOARD) {
return;
}
if (device == InputDevice::CONTROLLER) {
if (device == Device::CONTROLLER) {
if (controller_index >= num_gamepads_) {
return;
}
@@ -247,7 +247,7 @@ void Input::printBindings(InputDevice device, int controller_index) const {
}
// Obtiene el SDL_GamepadButton asignado a un input
auto Input::getControllerBinding(int controller_index, InputAction input) const -> SDL_GamepadButton {
auto Input::getControllerBinding(int controller_index, Action input) const -> SDL_GamepadButton {
return controller_bindings_[controller_index][static_cast<int>(input)].button;
}
@@ -258,17 +258,17 @@ auto Input::getIndexByName(const std::string &name) const -> int {
}
// Convierte un InputAction a std::string
auto Input::inputToString(InputAction input) -> std::string {
auto Input::inputToString(Action input) -> std::string {
switch (input) {
case InputAction::FIRE_LEFT:
case Action::FIRE_LEFT:
return "input_fire_left";
case InputAction::FIRE_CENTER:
case Action::FIRE_CENTER:
return "input_fire_center";
case InputAction::FIRE_RIGHT:
case Action::FIRE_RIGHT:
return "input_fire_right";
case InputAction::START:
case Action::START:
return "input_start";
case InputAction::SERVICE:
case Action::SERVICE:
return "input_service";
default:
return "";
@@ -276,34 +276,34 @@ auto Input::inputToString(InputAction input) -> std::string {
}
// Convierte un std::string a InputAction
auto Input::stringToInput(const std::string &name) -> InputAction {
static const std::unordered_map<std::string, InputAction> INPUT_MAP = {
{"input_fire_left", InputAction::FIRE_LEFT},
{"input_fire_center", InputAction::FIRE_CENTER},
{"input_fire_right", InputAction::FIRE_RIGHT},
{"input_start", InputAction::START},
{"input_service", InputAction::SERVICE}};
auto Input::stringToInput(const std::string &name) -> Action {
static const std::unordered_map<std::string, Action> INPUT_MAP = {
{"input_fire_left", Action::FIRE_LEFT},
{"input_fire_center", Action::FIRE_CENTER},
{"input_fire_right", Action::FIRE_RIGHT},
{"input_start", Action::START},
{"input_service", Action::SERVICE}};
auto it = INPUT_MAP.find(name);
return it != INPUT_MAP.end() ? it->second : InputAction::NONE;
return it != INPUT_MAP.end() ? it->second : Action::NONE;
}
// Comprueba el eje del mando
auto Input::checkAxisInput(InputAction input, int controller_index, bool repeat) -> bool {
auto Input::checkAxisInput(Action input, int controller_index, bool repeat) -> bool {
// Umbral para considerar el eje como activo
bool axis_active_now = false;
switch (input) {
case InputAction::LEFT:
case Action::LEFT:
axis_active_now = SDL_GetGamepadAxis(connected_controllers_[controller_index], SDL_GAMEPAD_AXIS_LEFTX) < -AXIS_THRESHOLD;
break;
case InputAction::RIGHT:
case Action::RIGHT:
axis_active_now = SDL_GetGamepadAxis(connected_controllers_[controller_index], SDL_GAMEPAD_AXIS_LEFTX) > AXIS_THRESHOLD;
break;
case InputAction::UP:
case Action::UP:
axis_active_now = SDL_GetGamepadAxis(connected_controllers_[controller_index], SDL_GAMEPAD_AXIS_LEFTY) < -AXIS_THRESHOLD;
break;
case InputAction::DOWN:
case Action::DOWN:
axis_active_now = SDL_GetGamepadAxis(connected_controllers_[controller_index], SDL_GAMEPAD_AXIS_LEFTY) > AXIS_THRESHOLD;
break;
default:
@@ -379,4 +379,25 @@ void Input::update() {
controller_bindings_[c][i].is_held = button_is_down_now;
}
}
}
void Input::handleEvent(const SDL_Event &event) {
switch (event.type) {
case SDL_EVENT_GAMEPAD_ADDED: {
printf("¡Mando conectado! ID: %d\n", event.gdevice.which);
SDL_Gamepad *gamepad = SDL_OpenGamepad(event.gdevice.which);
if (gamepad) {
printf("Gamepad abierto correctamente.\n");
} else {
printf("Error al abrir el gamepad: %s\n", SDL_GetError());
}
break;
}
case SDL_EVENT_GAMEPAD_REMOVED: {
printf("¡Mando desconectado! Instance ID: %d\n", event.gdevice.which);
// Aquí puedes cerrar el gamepad si lo tenías abierto
// SDL_CloseGamepad(gamepad); ← si tienes el puntero guardado
break;
}
}
}