#include "define_buttons.h" #include // Para __all_of_fn, all_of #include // Para identity #include // Para allocator, shared_ptr, __shared_ptr_access, operator== #include "input.h" // Para Input #include "input_types.h" // Para InputAction #include "lang.h" // Para getText #include "options.h" // Para Gamepad #include "param.h" // Para Param, param, ParamGame, ParamTitle #include "resource.h" // Para Resource #include "text.h" // Para Text // Constructor DefineButtons::DefineButtons() : input_(Input::get()), x_(param.game.width / 2), y_(param.title.press_start_position) { clearButtons(); auto gamepads = input_->getGamepads(); for (auto gamepad : gamepads) { controller_names_.emplace_back(Input::getControllerName(gamepad)); } } // Dibuja el objeto en pantalla 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(static_cast(options_gamepad_->player_id))); text_->writeCentered(x_, y_, options_gamepad_->name); 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) { auto gamepad = input_->getGamepad(event.which); // Asegúrate de que el gamepad sea válido y sea el que corresponde if (!gamepad || gamepad != options_gamepad_->instance) { return; } const auto BUTTON = static_cast(event.button); if (checkButtonNotInUse(BUTTON)) { buttons_.at(index_button_).button = BUTTON; incIndexButton(); } } // Asigna los botones definidos al input_ void DefineButtons::bindButtons(Options::Gamepad *options_gamepad) { for (const auto &button : buttons_) { Input::bindGameControllerButton(options_gamepad->instance, button.action, button.button); } // Remapea los inputs a inputs Input::bindGameControllerButton(options_gamepad->instance, Input::Action::SM_SELECT, Input::Action::FIRE_LEFT); Input::bindGameControllerButton(options_gamepad->instance, Input::Action::SM_BACK, Input::Action::FIRE_CENTER); } // Comprueba los eventos void DefineButtons::checkEvents(const SDL_Event &event) { if (enabled_) { switch (event.type) { case SDL_EVENT_GAMEPAD_BUTTON_DOWN: doControllerButtonDown(event.gbutton); break; case SDL_EVENT_GAMEPAD_BUTTON_UP: checkEnd(); break; default: break; } } } // Habilita el objeto auto DefineButtons::enable(Options::Gamepad *options_gamepad) -> bool { if (options_gamepad != nullptr) { options_gamepad_ = options_gamepad; enabled_ = true; finished_ = false; index_button_ = 0; clearButtons(); return true; } return false; } // Incrementa el indice de los botones void DefineButtons::incIndexButton() { if (index_button_ < buttons_.size() - 1) { ++index_button_; } else { finished_ = true; } } // Comprueba que un botón no esté ya asignado auto DefineButtons::checkButtonNotInUse(SDL_GamepadButton button) -> bool { return std::ranges::all_of(buttons_, [button](const auto &b) { return b.button != button; }); } // Limpia la asignación de botones void DefineButtons::clearButtons() { buttons_.clear(); buttons_.emplace_back(Lang::getText("[DEFINE_BUTTONS] FIRE_LEFT"), Input::Action::FIRE_LEFT, SDL_GAMEPAD_BUTTON_INVALID); buttons_.emplace_back(Lang::getText("[DEFINE_BUTTONS] FIRE_UP"), Input::Action::FIRE_CENTER, SDL_GAMEPAD_BUTTON_INVALID); buttons_.emplace_back(Lang::getText("[DEFINE_BUTTONS] FIRE_RIGHT"), Input::Action::FIRE_RIGHT, SDL_GAMEPAD_BUTTON_INVALID); buttons_.emplace_back(Lang::getText("[DEFINE_BUTTONS] START"), Input::Action::START, SDL_GAMEPAD_BUTTON_INVALID); buttons_.emplace_back(Lang::getText("[DEFINE_BUTTONS] SERVICE_MENU"), Input::Action::SERVICE, SDL_GAMEPAD_BUTTON_INVALID); } // Comprueba si ha finalizado void DefineButtons::checkEnd() { if (finished_) { bindButtons(options_gamepad_); // Asigna los botones definidos al input_ input_->saveGamepadConfigFromGamepad(options_gamepad_->instance); // Guarda los cambios input_->resetInputStates(); // Reinicia los estados de las pulsaciones de los botones enabled_ = false; // Deshabilita } }