diff --git a/source/define_buttons.cpp b/source/define_buttons.cpp index e9235a1..81291f9 100644 --- a/source/define_buttons.cpp +++ b/source/define_buttons.cpp @@ -20,7 +20,7 @@ DefineButtons::DefineButtons() clearButtons(); for (int i = 0; i < input_->getNumControllers(); ++i) { - controller_names_.emplace_back(input_->getControllerName(i)); + // controller_names_.emplace_back(input_->getControllerName(i)); } } @@ -28,18 +28,18 @@ DefineButtons::DefineButtons() void DefineButtons::render() { static auto text = Resource::get()->getText("8bithud"); if (enabled_) { - text->writeCentered(x_, y_ - 10, Lang::getText("[DEFINE_BUTTONS] PLAYER") + std::to_string(Options::controllers.at(index_controller_).player_id)); - text->writeCentered(x_, y_, controller_names_.at(index_controller_)); - text->writeCentered(x_, y_ + 10, buttons_.at(index_button_).label); + // text->writeCentered(x_, y_ - 10, Lang::getText("[DEFINE_BUTTONS] PLAYER") + std::to_string(Options::controllers.at(index_controller_).player_id)); + // text->writeCentered(x_, y_, controller_names_.at(index_controller_)); + // text->writeCentered(x_, y_ + 10, buttons_.at(index_button_).label); } } // Comprueba el botón que se ha pulsado void DefineButtons::doControllerButtonDown(const SDL_GamepadButtonEvent &event) { // Solo pilla botones del mando que toca - if (input_->getJoyIndex(event.which) != static_cast(index_controller_)) { - return; - } + // if (input_->getJoyIndex(event.which) != static_cast(index_controller_)) { + // return; + //} const auto BUTTON = static_cast(event.button); if (checkButtonNotInUse(BUTTON)) { @@ -99,11 +99,11 @@ void DefineButtons::incIndexButton() { // Guarda los cambios en las opciones void DefineButtons::saveBindingsToOptions() { - auto &controller = Options::controllers.at(index_controller_); - controller.name = input_->getControllerName(index_controller_); - for (size_t j = 0; j < controller.inputs.size(); ++j) { - controller.buttons.at(j) = input_->getControllerBinding(index_controller_, controller.inputs.at(j)); - } + // auto &controller = Options::controllers.at(index_controller_); + // controller.name = input_->getControllerName(index_controller_); + // for (size_t j = 0; j < controller.inputs.size(); ++j) { + // controller.buttons.at(j) = input_->getControllerBinding(index_controller_, controller.inputs.at(j)); + // } } // Comprueba que un botón no esté ya asignado @@ -126,7 +126,7 @@ void DefineButtons::clearButtons() { // Comprueba si ha finalizado void DefineButtons::checkEnd() { if (finished_) { - bindButtons(); // Asigna los botones definidos al input_ + // bindButtons(); // Asigna los botones definidos al input_ saveBindingsToOptions(); // Guarda los cambios en las opciones input_->resetInputStates(); // Reinicia los estados de las pulsaciones de los botones enabled_ = false; // Deshabilita diff --git a/source/director.cpp b/source/director.cpp index 53f0b14..1d946a8 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -150,7 +150,7 @@ void Director::loadScoreFile() { // Asigna los botones y teclas al objeto Input void Director::bindInputs() { - static auto input = Input::get(); + /*static auto input = Input::get(); // Teclado - Movimiento del jugador input->bindKey(Input::Action::UP, SDL_SCANCODE_UP); @@ -243,7 +243,7 @@ void Director::bindInputs() { // Asegura que algún jugador tenga el teclado asignado if (Options::getPlayerWhoUsesKeyboard() == 0) { Options::setKeyboardToPlayer(1); - } + }*/ } // Crea el indice de ficheros diff --git a/source/gamepad_config_manager.h b/source/gamepad_config_manager.h index d5b3159..801402a 100644 --- a/source/gamepad_config_manager.h +++ b/source/gamepad_config_manager.h @@ -1,5 +1,5 @@ -#include #pragma once +#include #include #include diff --git a/source/global_inputs.cpp b/source/global_inputs.cpp index fa8afb2..bc4a1c7 100644 --- a/source/global_inputs.cpp +++ b/source/global_inputs.cpp @@ -170,8 +170,9 @@ auto checkServiceButton() -> bool { // Mandos { - for (int i = 0; i < Input::get()->getNumControllers(); ++i) { - if (Input::get()->checkAction(Input::Action::SERVICE, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, i)) { + auto gamepads = Input::get()->getGamepads(); + for (auto gamepad : gamepads) { + if (Input::get()->checkAction(Input::Action::SERVICE, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, gamepad)) { toggleServiceMenu(); return true; } @@ -227,39 +228,40 @@ auto checkServiceInputs() -> bool { // Mandos { - for (int i = 0; i < Input::get()->getNumControllers(); ++i) { + auto gamepads = Input::get()->getGamepads(); + for (auto gamepad : gamepads) { // Arriba - if (Input::get()->checkAction(Input::Action::UP, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, i)) { + if (Input::get()->checkAction(Input::Action::UP, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, gamepad)) { ServiceMenu::get()->setSelectorUp(); return true; } // Abajo - if (Input::get()->checkAction(Input::Action::DOWN, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, i)) { + if (Input::get()->checkAction(Input::Action::DOWN, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, gamepad)) { ServiceMenu::get()->setSelectorDown(); return true; } // Derecha - if (Input::get()->checkAction(Input::Action::RIGHT, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, i)) { + if (Input::get()->checkAction(Input::Action::RIGHT, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, gamepad)) { ServiceMenu::get()->adjustOption(true); return true; } // Izquierda - if (Input::get()->checkAction(Input::Action::LEFT, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, i)) { + if (Input::get()->checkAction(Input::Action::LEFT, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, gamepad)) { ServiceMenu::get()->adjustOption(false); return true; } // Aceptar - if (Input::get()->checkAction(Input::Action::SM_SELECT, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, i)) { + if (Input::get()->checkAction(Input::Action::SM_SELECT, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, gamepad)) { ServiceMenu::get()->selectOption(); return true; } // Atras - if (Input::get()->checkAction(Input::Action::SM_BACK, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, i)) { + if (Input::get()->checkAction(Input::Action::SM_BACK, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, gamepad)) { ServiceMenu::get()->moveBack(); return true; } diff --git a/source/input.cpp b/source/input.cpp index d92065c..5de2059 100644 --- a/source/input.cpp +++ b/source/input.cpp @@ -27,56 +27,51 @@ Input::Input(std::string game_controller_db_path) // Inicializa el subsistema SDL_INIT_GAMEPAD initSDLGamePad(); - // Inicializa los vectores - // key_bindings_.resize(static_cast(Action::SIZE), KeyBindings()); - // controller_bindings_.resize(gamepads.size(), std::vector(static_cast(Action::SIZE), ControllerBindings())); - // Listado de los inputs para jugar que utilizan botones, ni palancas ni crucetas button_inputs_ = {Action::FIRE_LEFT, Action::FIRE_CENTER, Action::FIRE_RIGHT, Action::START}; } // Asigna inputs a teclas -void Input::bindKey(Action input, SDL_Scancode code) { - key_bindings_.at(static_cast(input)).scancode = code; +void Input::bindKey(Action action, SDL_Scancode code) { + keyboard_.bindings[action].scancode = code; } // Asigna inputs a botones del mando -void Input::bindGameControllerButton(std::shared_ptr gamepad, Action input, SDL_GamepadButton button) { +void Input::bindGameControllerButton(std::shared_ptr gamepad, Action action, SDL_GamepadButton button) { if (gamepad != nullptr) { - gamepad->button_states.at(static_cast(input)).button = button; + gamepad->bindings[action].button = button; } } // Asigna inputs a botones del mando void Input::bindGameControllerButton(std::shared_ptr gamepad, Action input_target, Action input_source) { if (gamepad != nullptr) { - gamepad->button_states.at(static_cast(input_target)).button = gamepad->button_states.at(static_cast(input_source)).button; + gamepad->bindings[input_target].button = gamepad->bindings[input_source].button; } } // Comprueba si un input esta activo -auto Input::checkAction(Action input, bool repeat, Device device, std::shared_ptr gamepad) -> bool { +auto Input::checkAction(Action action, bool repeat, Device device, std::shared_ptr gamepad) -> bool { bool success_keyboard = false; bool success_controller = false; - const int INPUT_INDEX = static_cast(input); 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; + success_keyboard = keyboard_.bindings[action].is_held; } else { // El usuario quiere saber si ACABA de ser pulsada (evento de un solo fotograma) - success_keyboard = key_bindings_[INPUT_INDEX].just_pressed; + success_keyboard = keyboard_.bindings[action].just_pressed; } } if (gamepad != nullptr) { if ((device == Device::CONTROLLER) || (device == Device::ANY)) { - success_controller = checkAxisInput(input, gamepad, repeat); + success_controller = checkAxisInput(action, gamepad, repeat); if (!success_controller) { if (repeat) { // El usuario quiere saber si está pulsada (estado mantenido) - success_controller = gamepad->button_states.at(INPUT_INDEX).is_held; + success_controller = gamepad->bindings[action].is_held; } else { // El usuario quiere saber si ACABA de ser pulsada (evento de un solo fotograma) - success_controller = gamepad->button_states.at(INPUT_INDEX).just_pressed; + success_controller = gamepad->bindings[action].just_pressed; } } } @@ -88,14 +83,13 @@ auto Input::checkAction(Action input, bool repeat, Device device, std::shared_pt // Comprueba si hay almenos un input activo auto Input::checkAnyInput(Device device, std::shared_ptr gamepad) -> bool { // Obtenemos el número total de acciones posibles para iterar sobre ellas. - const int NUM_ACTIONS = static_cast(Action::SIZE); // --- Comprobación del Teclado --- if (device == Device::KEYBOARD || device == Device::ANY) { - for (int i = 0; i < NUM_ACTIONS; ++i) { + for (const auto &pair : keyboard_.bindings) { // Simplemente leemos el estado pre-calculado por Input::update(). // Ya no se llama a SDL_GetKeyboardState ni se modifica el estado '.active'. - if (key_bindings_.at(i).just_pressed) { + if (pair.second.just_pressed) { return true; // Se encontró una acción recién pulsada. } } @@ -106,9 +100,9 @@ auto Input::checkAnyInput(Device device, std::shared_ptr gamepad) -> bo if (gamepad != nullptr) { if (device == Device::CONTROLLER || device == Device::ANY) { // Iteramos sobre todas las acciones, no sobre el número de mandos. - for (int i = 0; i < NUM_ACTIONS; ++i) { + for (const auto &pair : gamepad->bindings) { // Leemos el estado pre-calculado para el mando y la acción específicos. - if (gamepad->button_states.at(i).just_pressed) { + if (pair.second.just_pressed) { return true; // Se encontró una acción recién pulsada en el mando. } } @@ -150,17 +144,17 @@ auto Input::getNumControllers() const -> int { return gamepads_.size(); } // Obtiene el indice del controlador a partir de un event.id auto Input::getJoyIndex(SDL_JoystickID id) const -> int { - for (int i = 0; i < num_joysticks_; ++i) { - if (SDL_GetJoystickID(joysticks_[i]) == id) { - return i; - } - } + // for (int i = 0; i < num_joysticks_; ++i) { + // if (SDL_GetJoystickID(joysticks_[i]) == id) { + // return i; + // } + // } return -1; } // Obtiene el SDL_GamepadButton asignado a un input auto Input::getControllerBinding(std::shared_ptr gamepad, Action input) const -> SDL_GamepadButton { - return gamepad->button_states.at(static_cast(input)).button; + return gamepad->bindings[input].button; } // Convierte un InputAction a std::string @@ -217,7 +211,7 @@ auto Input::checkAxisInput(Action input, std::shared_ptr gamepad, bool } // Referencia al binding correspondiente - auto &binding = gamepad->button_states.at(static_cast(input)); + auto &binding = gamepad->bindings[input]; if (repeat) { // Si se permite repetir, simplemente devolvemos el estado actual @@ -252,15 +246,15 @@ void Input::initSDLGamePad() { void Input::resetInputStates() { // Resetear todos los KeyBindings.active a false - for (auto &key : key_bindings_) { - key.is_held = false; - key.just_pressed = false; + for (auto &key : keyboard_.bindings) { + key.second.is_held = false; + key.second.just_pressed = false; } // Resetear todos los ControllerBindings.active a false for (auto &gamepad : gamepads_) { - for (auto &binding : gamepad->button_states) { - binding.is_held = false; - binding.just_pressed = false; + for (auto &binding : gamepad->bindings) { + binding.second.is_held = false; + binding.second.just_pressed = false; } } } @@ -269,22 +263,22 @@ void Input::update() { // --- TECLADO --- const bool *key_states = SDL_GetKeyboardState(nullptr); - for (auto &key_binding : key_bindings_) { - bool key_is_down_now = key_states[key_binding.scancode]; + for (auto &binding : keyboard_.bindings) { + bool key_is_down_now = key_states[binding.second.scancode]; // El estado .is_held del fotograma anterior nos sirve para saber si es un pulso nuevo - key_binding.just_pressed = key_is_down_now && !key_binding.is_held; - key_binding.is_held = key_is_down_now; + binding.second.just_pressed = key_is_down_now && !binding.second.is_held; + binding.second.is_held = key_is_down_now; } // --- MANDOS --- for (auto gamepad : gamepads_) { - for (auto &binding : gamepad->button_states) { - bool button_is_down_now = static_cast(SDL_GetGamepadButton(gamepad->pad, binding.button)) != 0; + for (auto &binding : gamepad->bindings) { + bool button_is_down_now = static_cast(SDL_GetGamepadButton(gamepad->pad, binding.second.button)) != 0; // El estado .is_held del fotograma anterior nos sirve para saber si es un pulso nuevo - binding.just_pressed = button_is_down_now && !binding.is_held; - binding.is_held = button_is_down_now; + binding.second.just_pressed = button_is_down_now && !binding.second.is_held; + binding.second.is_held = button_is_down_now; } } } diff --git a/source/input.h b/source/input.h index 120c49a..d9af02b 100644 --- a/source/input.h +++ b/source/input.h @@ -5,6 +5,7 @@ #include #include // Para std::unique_ptr #include // Para basic_string, string +#include #include // Para vector /* @@ -92,21 +93,58 @@ class Input { : button(btn), is_held(is_held), just_pressed(just_pressed), axis_active(axis_act) {} }; + struct Keyboard { + std::unordered_map bindings; + + Keyboard() + : bindings{ + {Input::Action::UP, KeyState(SDL_SCANCODE_UP)}, + {Input::Action::DOWN, KeyState(SDL_SCANCODE_DOWN)}, + {Input::Action::LEFT, KeyState(SDL_SCANCODE_LEFT)}, + {Input::Action::RIGHT, KeyState(SDL_SCANCODE_RIGHT)}, + {Input::Action::FIRE_LEFT, KeyState(SDL_SCANCODE_Q)}, + {Input::Action::FIRE_CENTER, KeyState(SDL_SCANCODE_W)}, + {Input::Action::FIRE_RIGHT, KeyState(SDL_SCANCODE_E)}, + {Input::Action::START, KeyState(SDL_SCANCODE_RETURN)}, + {Input::Action::SERVICE, KeyState(SDL_SCANCODE_0)}, + {Input::Action::SM_SELECT, KeyState(SDL_SCANCODE_RETURN)}, + {Input::Action::SM_BACK, KeyState(SDL_SCANCODE_BACKSPACE)}, + {Input::Action::EXIT, KeyState(SDL_SCANCODE_ESCAPE)}, + {Input::Action::PAUSE, KeyState(SDL_SCANCODE_P)}, + {Input::Action::BACK, KeyState(SDL_SCANCODE_BACKSPACE)}, + {Input::Action::WINDOW_DEC_SIZE, KeyState(SDL_SCANCODE_F1)}, + {Input::Action::WINDOW_INC_SIZE, KeyState(SDL_SCANCODE_F2)}, + {Input::Action::WINDOW_FULLSCREEN, KeyState(SDL_SCANCODE_F3)}, + {Input::Action::TOGGLE_VIDEO_SHADERS, KeyState(SDL_SCANCODE_F4)}, + {Input::Action::TOGGLE_VIDEO_INTEGER_SCALE, KeyState(SDL_SCANCODE_F5)}, + {Input::Action::TOGGLE_VIDEO_VSYNC, KeyState(SDL_SCANCODE_F6)}, + {Input::Action::TOGGLE_AUDIO, KeyState(SDL_SCANCODE_F7)}, + {Input::Action::TOGGLE_AUTO_FIRE, KeyState(SDL_SCANCODE_F8)}, + {Input::Action::CHANGE_LANG, KeyState(SDL_SCANCODE_F9)}, + {Input::Action::RESET, KeyState(SDL_SCANCODE_F10)}, + {Input::Action::SHOW_INFO, KeyState(SDL_SCANCODE_F12)}} {} + }; + struct Gamepad { SDL_Gamepad *pad; SDL_JoystickID instance_id; std::string name; - std::vector button_states; + std::unordered_map bindings; Gamepad(SDL_Gamepad *gamepad) : pad(gamepad), instance_id(SDL_GetJoystickID(SDL_GetGamepadJoystick(gamepad))), - name(std::string(SDL_GetGamepadName(gamepad)) + " #" + std::to_string(instance_id)) {} + name(std::string(SDL_GetGamepadName(gamepad)) + " #" + std::to_string(instance_id)), + bindings{ + {Input::Action::FIRE_LEFT, ButtonState(SDL_GAMEPAD_BUTTON_WEST)}, + {Input::Action::FIRE_CENTER, ButtonState(SDL_GAMEPAD_BUTTON_NORTH)}, + {Input::Action::FIRE_RIGHT, ButtonState(SDL_GAMEPAD_BUTTON_EAST)}, + {Input::Action::START, ButtonState(SDL_GAMEPAD_BUTTON_START)}, + {Input::Action::SERVICE, ButtonState(SDL_GAMEPAD_BUTTON_BACK)}} {} ~Gamepad() { if (pad) { SDL_CloseGamepad(pad); - // std::cout << "Gamepad cerrado (ID " << instance_id << ")\n"; } } }; @@ -154,7 +192,7 @@ class Input { // --- Variables internas --- std::vector> gamepads_; // Mandos conectados - std::vector key_bindings_; // Vector con las teclas asociadas a los inputs predefinidos + Keyboard keyboard_; // Estructura con las asociaciones de teclas a acciones std::vector button_inputs_; // Inputs asignados al jugador y a botones, excluyendo direcciones std::string game_controller_db_path_; // Ruta al archivo gamecontrollerdb.txt diff --git a/source/options.cpp b/source/options.cpp index d67bf72..a9fc4d7 100644 --- a/source/options.cpp +++ b/source/options.cpp @@ -25,7 +25,7 @@ VideoOptions video; // Opciones de vídeo AudioOptions audio; // Opciones de audio std::vector controllers; // Opciones de mando para cada jugador PendingChanges pending_changes; // Opciones que se aplican al cerrar -std::vector gamepad_configs; // Lista con las configuraciones registradas para cada mando +//std::vector gamepad_configs; // Lista con las configuraciones registradas para cada mando // Declaraciones auto set(const std::string& var, const std::string& value) -> bool; @@ -160,11 +160,6 @@ auto saveToFile() -> bool { file << "controller." << controller_index << ".name=" << controller.name << "\n"; file << "controller." << controller_index << ".player=" << controller.player_id << "\n"; file << "controller." << controller_index << ".type=" << static_cast(controller.type) << "\n"; - file << "controller." << controller_index << ".button.fire_left=" << controller.buttons.at(0) << "\n"; - file << "controller." << controller_index << ".button.fire_center=" << controller.buttons.at(1) << "\n"; - file << "controller." << controller_index << ".button.fire_right=" << controller.buttons.at(2) << "\n"; - file << "controller." << controller_index << ".button.start=" << controller.buttons.at(3) << "\n"; - file << "controller." << controller_index << ".button.service=" << controller.buttons.at(4) << "\n"; // Incrementa el índice ++controller_index; @@ -193,16 +188,6 @@ void parseAndSetController(const std::string& var, const std::string& value) { controller.player_id = std::clamp(std::stoi(value), 1, 2); } else if (setting_key == "type") { controller.type = static_cast(std::stoi(value)); - } else if (setting_key == "button.fire_left") { - controller.buttons.at(0) = static_cast(std::stoi(value)); - } else if (setting_key == "button.fire_center") { - controller.buttons.at(1) = static_cast(std::stoi(value)); - } else if (setting_key == "button.fire_right") { - controller.buttons.at(2) = static_cast(std::stoi(value)); - } else if (setting_key == "button.start") { - controller.buttons.at(3) = static_cast(std::stoi(value)); - } else if (setting_key == "button.service") { - controller.buttons.at(4) = static_cast(std::stoi(value)); } } diff --git a/source/options.h b/source/options.h index fe06bff..6386b18 100644 --- a/source/options.h +++ b/source/options.h @@ -9,7 +9,7 @@ #include // Para vector #include "difficulty.h" // Para Code -#include "gamepad_config_manager.h" +// #include "gamepad_config_manager.h" #include "input.h" // Para InputAction, InputDevice #include "lang.h" // Para Code #include "manage_hiscore_table.h" // Para HiScoreEntry @@ -93,10 +93,10 @@ struct SettingsOptions { }; struct GamepadOptions { - Input::Gamepad gamepad = nullptr; // Mando - int player_id; // Jugador asociado al mando - Input::Device type = Input::Device::CONTROLLER; // Tipo de dispositivo - GamepadConfig config; + std::shared_ptr gamepad = nullptr; // Referencia al mando + std::string name; // Nombre del mando + int player_id; // Jugador asociado al mando + Input::Device type = Input::Device::CONTROLLER; // Tipo de dispositivo GamepadOptions(int custom_player_id = INVALID_INDEX) : player_id(custom_player_id) {} @@ -113,13 +113,12 @@ struct PendingChanges { }; // --- Variables globales --- -extern WindowOptions window; // Opciones de la ventana -extern SettingsOptions settings; // Opciones del juego -extern VideoOptions video; // Opciones de vídeo -extern AudioOptions audio; // Opciones de audio -extern std::vector controllers; // Opciones de mando para cada jugador -extern PendingChanges pending_changes; // Opciones que se aplican al cerrar -extern std::vector gamepad_configs; // Lista con las configuraciones registradas para cada mando +extern WindowOptions window; // Opciones de la ventana +extern SettingsOptions settings; // Opciones del juego +extern VideoOptions video; // Opciones de vídeo +extern AudioOptions audio; // Opciones de audio +extern std::vector controllers; // Opciones de mando para cada jugador +extern PendingChanges pending_changes; // Opciones que se aplican al cerrar // --- Funciones de configuración --- void init(); // Inicializa las opciones del programa diff --git a/source/player.cpp b/source/player.cpp index 124e092..503041c 100644 --- a/source/player.cpp +++ b/source/player.cpp @@ -17,8 +17,8 @@ // Constructor Player::Player(int id, float x, int y, bool demo, SDL_FRect &play_area, std::vector> texture, const std::vector> &animations) - : player_sprite_(std::make_unique(texture[0], animations[0])), - power_sprite_(std::make_unique(texture[1], animations[1])), + : player_sprite_(std::make_unique(texture.at(0), animations.at(0))), + power_sprite_(std::make_unique(texture.at(1), animations.at(1))), enter_name_(std::make_unique()), id_(id), play_area_(play_area), diff --git a/source/player.h b/source/player.h index c11c1fe..73745bb 100644 --- a/source/player.h +++ b/source/player.h @@ -6,8 +6,9 @@ #include // Para string #include // Para vector -#include "animated_sprite.h" // Para AnimatedSprite -#include "enter_name.h" // Para EnterName +#include "animated_sprite.h" // Para AnimatedSprite +#include "enter_name.h" // Para EnterName +#include "input.h" #include "manage_hiscore_table.h" // Para HiScoreEntry #include "options.h" // Para SettingsOptions, settings #include "scoreboard.h" // Para Scoreboard @@ -219,6 +220,10 @@ class Player { int credits_used_ = 0; // Indica el número de veces que ha continuado std::string last_enter_name_; // Último nombre introducido en la tabla de puntuaciones int waiting_counter_ = 0; // Contador para el estado de espera + std::shared_ptr gamepad_ = nullptr; // Dispositivo asociado + // Setter y getter para gamepad_ + void setGamepad(std::shared_ptr gamepad) { gamepad_ = gamepad; } + [[nodiscard]] std::shared_ptr getGamepad() const { return gamepad_; } // --- Métodos internos --- void shiftColliders(); // Actualiza el círculo de colisión a la posición del jugador diff --git a/source/sections/game.cpp b/source/sections/game.cpp index d6ce89a..284020b 100644 --- a/source/sections/game.cpp +++ b/source/sections/game.cpp @@ -125,6 +125,7 @@ Game::~Game() { void Game::setResources() { // Texturas - Game_text { + game_text_textures_.clear(); game_text_textures_.emplace_back(Resource::get()->getTexture("game_text_1000_points")); game_text_textures_.emplace_back(Resource::get()->getTexture("game_text_2500_points")); game_text_textures_.emplace_back(Resource::get()->getTexture("game_text_5000_points")); @@ -136,6 +137,7 @@ void Game::setResources() { // Texturas - Items { + item_textures_.clear(); item_textures_.emplace_back(Resource::get()->getTexture("item_points1_disk.png")); item_textures_.emplace_back(Resource::get()->getTexture("item_points2_gavina.png")); item_textures_.emplace_back(Resource::get()->getTexture("item_points3_pacmar.png")); @@ -145,6 +147,7 @@ void Game::setResources() { item_textures_.emplace_back(Resource::get()->getTexture("item_coffee_machine.png")); } + player_textures_.clear(); // Texturas - Player1 { std::vector> player_texture; @@ -163,12 +166,14 @@ void Game::setResources() { // Animaciones -- Jugador { + player_animations_.clear(); player_animations_.emplace_back(Resource::get()->getAnimation("player.ani")); player_animations_.emplace_back(Resource::get()->getAnimation("player_power.ani")); } // Animaciones -- Items { + item_animations_.clear(); item_animations_.emplace_back(Resource::get()->getAnimation("item_points1_disk.ani")); item_animations_.emplace_back(Resource::get()->getAnimation("item_points2_gavina.ani")); item_animations_.emplace_back(Resource::get()->getAnimation("item_points3_pacmar.ani")); @@ -1243,8 +1248,9 @@ void Game::checkInput() { // Verifica si alguno de los controladores ha solicitado una pausa y actualiza el estado de pausa del juego. void Game::checkPauseInput() { // Comprueba los mandos - for (int i = 0; i < input_->getNumControllers(); ++i) { - if (input_->checkAction(Input::Action::PAUSE, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, i)) { + auto gamepads = input_->getGamepads(); + for (auto gamepad : gamepads) { + if (input_->checkAction(Input::Action::PAUSE, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, gamepad)) { pause(!paused_); return; } @@ -1360,14 +1366,14 @@ void Game::handlePlayersInput() { // Maneja las entradas de movimiento y disparo para un jugador en modo normal. void Game::handleNormalPlayerInput(const std::shared_ptr &player) { - const auto &controller = Options::controllers.at(player->getController()); + const auto &controller = Options::controllers.at(0); - if (input_->checkAction(Input::Action::LEFT, Input::ALLOW_REPEAT, controller.type, controller.index)) { + if (input_->checkAction(Input::Action::LEFT, Input::ALLOW_REPEAT, controller.type, controller.gamepad)) { player->setInput(Input::Action::LEFT); #ifdef RECORDING demo_.keys.left = 1; #endif - } else if (input_->checkAction(Input::Action::RIGHT, Input::ALLOW_REPEAT, controller.type, controller.index)) { + } else if (input_->checkAction(Input::Action::RIGHT, Input::ALLOW_REPEAT, controller.type, controller.gamepad)) { player->setInput(Input::Action::RIGHT); #ifdef RECORDING demo_.keys.right = 1; @@ -1380,23 +1386,23 @@ void Game::handleNormalPlayerInput(const std::shared_ptr &player) { } const bool AUTOFIRE = player->isPowerUp() || Options::settings.autofire; - handleFireInputs(player, AUTOFIRE, player->getController()); // Verifica y maneja todas las posibles entradas de disparo. + handleFireInputs(player, AUTOFIRE); // Verifica y maneja todas las posibles entradas de disparo. } // Procesa las entradas de disparo del jugador, permitiendo disparos automáticos si está habilitado. -void Game::handleFireInputs(const std::shared_ptr &player, bool autofire, int controller_index) { - const auto CONTROLLER = Options::controllers.at(player->getController()); - if (input_->checkAction(Input::Action::FIRE_CENTER, autofire, CONTROLLER.type, CONTROLLER.index)) { +void Game::handleFireInputs(const std::shared_ptr &player, bool autofire) { + const auto CONTROLLER = Options::controllers.at(0); + if (input_->checkAction(Input::Action::FIRE_CENTER, autofire, CONTROLLER.type, CONTROLLER.gamepad)) { handleFireInput(player, BulletType::UP); #ifdef RECORDING demo_.keys.fire = 1; #endif - } else if (input_->checkAction(Input::Action::FIRE_LEFT, autofire, CONTROLLER.type, CONTROLLER.index)) { + } else if (input_->checkAction(Input::Action::FIRE_LEFT, autofire, CONTROLLER.type, CONTROLLER.gamepad)) { handleFireInput(player, BulletType::LEFT); #ifdef RECORDING demo_.keys.fire_left = 1; #endif - } else if (input_->checkAction(Input::Action::FIRE_RIGHT, autofire, CONTROLLER.type, CONTROLLER.index)) { + } else if (input_->checkAction(Input::Action::FIRE_RIGHT, autofire, CONTROLLER.type, CONTROLLER.gamepad)) { handleFireInput(player, BulletType::RIGHT); #ifdef RECORDING demo_.keys.fire_right = 1; @@ -1406,17 +1412,17 @@ void Game::handleFireInputs(const std::shared_ptr &player, bool autofire // Maneja la continuación del jugador cuando no está jugando, permitiendo que continúe si se pulsa el botón de inicio. void Game::handlePlayerContinueInput(const std::shared_ptr &player) { - const auto CONTROLLER = Options::controllers.at(player->getController()); - if (input_->checkAction(Input::Action::START, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) { + const auto CONTROLLER = Options::controllers.at(0); + if (input_->checkAction(Input::Action::START, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.gamepad)) { player->setPlayingState(Player::State::RESPAWNING); player->addCredit(); sendPlayerToTheFront(player); } // Disminuye el contador de continuación si se presiona cualquier botón de disparo. - if (input_->checkAction(Input::Action::FIRE_LEFT, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index) || - input_->checkAction(Input::Action::FIRE_CENTER, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index) || - input_->checkAction(Input::Action::FIRE_RIGHT, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) { + if (input_->checkAction(Input::Action::FIRE_LEFT, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.gamepad) || + input_->checkAction(Input::Action::FIRE_CENTER, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.gamepad) || + input_->checkAction(Input::Action::FIRE_RIGHT, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.gamepad)) { if (player->getContinueCounter() < param.scoreboard.skip_countdown_value) { player->decContinueCounter(); } @@ -1425,8 +1431,8 @@ void Game::handlePlayerContinueInput(const std::shared_ptr &player) { // Maneja la continuación del jugador cuando no está jugando, permitiendo que continúe si se pulsa el botón de inicio. void Game::handlePlayerWaitingInput(const std::shared_ptr &player) { - const auto CONTROLLER = Options::controllers.at(player->getController()); - if (input_->checkAction(Input::Action::START, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) { + const auto CONTROLLER = Options::controllers.at(0); + if (input_->checkAction(Input::Action::START, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.gamepad)) { player->setPlayingState(Player::State::ENTERING_SCREEN); player->addCredit(); sendPlayerToTheFront(player); @@ -1435,8 +1441,8 @@ void Game::handlePlayerWaitingInput(const std::shared_ptr &player) { // Procesa las entradas para la introducción del nombre del jugador. void Game::handleNameInput(const std::shared_ptr &player) { - const auto CONTROLLER = Options::controllers.at(player->getController()); - if (input_->checkAction(Input::Action::FIRE_LEFT, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) { + const auto CONTROLLER = Options::controllers.at(0); + if (input_->checkAction(Input::Action::FIRE_LEFT, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.gamepad)) { if (player->isShowingName()) { player->setPlayingState(Player::State::CONTINUE); } else if (player->getEnterNamePositionOverflow()) { @@ -1446,18 +1452,18 @@ void Game::handleNameInput(const std::shared_ptr &player) { } else { player->setInput(Input::Action::RIGHT); } - } else if (input_->checkAction(Input::Action::FIRE_CENTER, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index) || - input_->checkAction(Input::Action::FIRE_RIGHT, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) { + } else if (input_->checkAction(Input::Action::FIRE_CENTER, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.gamepad) || + input_->checkAction(Input::Action::FIRE_RIGHT, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.gamepad)) { if (player->isShowingName()) { player->setPlayingState(Player::State::CONTINUE); } else { player->setInput(Input::Action::LEFT); } - } else if (input_->checkAction(Input::Action::UP, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) { + } else if (input_->checkAction(Input::Action::UP, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.gamepad)) { player->setInput(Input::Action::UP); - } else if (input_->checkAction(Input::Action::DOWN, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) { + } else if (input_->checkAction(Input::Action::DOWN, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.gamepad)) { player->setInput(Input::Action::DOWN); - } else if (input_->checkAction(Input::Action::START, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) { + } else if (input_->checkAction(Input::Action::START, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.gamepad)) { if (player->isShowingName()) { player->setPlayingState(Player::State::CONTINUE); } else { diff --git a/source/sections/game.h b/source/sections/game.h index ce53a8c..cccdc01 100644 --- a/source/sections/game.h +++ b/source/sections/game.h @@ -198,13 +198,13 @@ class Game { void checkPauseInput(); // Verifica solicitudes de pausa de controladores // --- Entrada de jugadores normales --- - void handlePlayersInput(); // Gestiona entrada de todos los jugadores - void handleNormalPlayerInput(const std::shared_ptr &player); // Procesa entrada de un jugador específico - void handleFireInput(const std::shared_ptr &player, BulletType bullet_type); // Gestiona disparo de jugador - void handleFireInputs(const std::shared_ptr &player, bool autofire, int controller_index); // Procesa disparos automáticos - void handlePlayerContinueInput(const std::shared_ptr &player); // Permite continuar al jugador - void handlePlayerWaitingInput(const std::shared_ptr &player); // Permite (re)entrar al jugador - void handleNameInput(const std::shared_ptr &player); // Gestiona entrada de nombre del jugador + void handlePlayersInput(); // Gestiona entrada de todos los jugadores + void handleNormalPlayerInput(const std::shared_ptr &player); // Procesa entrada de un jugador específico + void handleFireInput(const std::shared_ptr &player, BulletType bullet_type); // Gestiona disparo de jugador + void handleFireInputs(const std::shared_ptr &player, bool autofire); // Procesa disparos automáticos + void handlePlayerContinueInput(const std::shared_ptr &player); // Permite continuar al jugador + void handlePlayerWaitingInput(const std::shared_ptr &player); // Permite (re)entrar al jugador + void handleNameInput(const std::shared_ptr &player); // Gestiona entrada de nombre del jugador // --- Entrada en modo demo --- void demoHandleInput(); // Gestiona entrada durante el modo demostración diff --git a/source/sections/title.cpp b/source/sections/title.cpp index 49e8db2..3673536 100644 --- a/source/sections/title.cpp +++ b/source/sections/title.cpp @@ -274,7 +274,7 @@ auto Title::isStartButtonPressed(const Options::GamepadOptions& controller) -> b Input::Action::START, Input::DO_NOT_ALLOW_REPEAT, controller.type, - controller.index); + controller.gamepad); } void Title::handleStartButtonPress(const Options::GamepadOptions& controller) { @@ -357,12 +357,12 @@ void Title::showControllers() { } // Genera el texto correspondiente - for (size_t i = 0; i < NUM_CONTROLLERS; ++i) { - const size_t INDEX = player_controller_index.at(i); - if (Options::controllers.at(INDEX).plugged) { - text.at(i) = Lang::getText("[DEFINE_BUTTONS] PLAYER") + std::to_string(i + 1) + ": " + Options::controllers.at(INDEX).name; - } - } + //for (size_t i = 0; i < NUM_CONTROLLERS; ++i) { + // const size_t INDEX = player_controller_index.at(i); + // if (Options::controllers.at(INDEX).plugged) { + // text.at(i) = Lang::getText("[DEFINE_BUTTONS] PLAYER") + std::to_string(i + 1) + ": " + Options::controllers.at(INDEX).name; + // } + //} // Muestra la notificación Notifier::get()->show({text.at(0), text.at(1)});