#include "core/system/global_events.hpp" #include "core/input/input.hpp" // Para Input (gamepad add/remove) #include "core/input/mouse.hpp" #include "core/locale/locale.hpp" // Para Locale #include "core/rendering/screen.hpp" // Para Screen::handleWindowResized #include "game/options.hpp" // Para Options, options, OptionsGame, OptionsAudio #include "game/scene_manager.hpp" // Para SceneManager::current (filtrar BACK a GAME) #include "game/ui/console.hpp" // Para Console #include "game/ui/notifier.hpp" // Para Notifier namespace GlobalEvents { namespace { // Flag per saber si en aquest frame s'ha rebut un button down del gamepad. // El consumeix GlobalInputs perquè un botó del comandament salti escenes. bool gamepad_button_pressed_ = false; } // namespace // Comprueba los eventos que se pueden producir en cualquier sección del juego. // Nota: SDL_EVENT_QUIT el gestiona Director::handleEvent() directament. void handle(const SDL_Event& event) { if (event.type == SDL_EVENT_RENDER_DEVICE_RESET || event.type == SDL_EVENT_RENDER_TARGETS_RESET) { // reLoadTextures(); } // Canvi de mida de la finestra (fullscreen toggle extern, rotació del dispositiu, // resize manual...). Re-sincronitzem el logical size del renderer i el zoom factor // per evitar que la textura quedi estirada o desalineada amb el nou viewport. if (event.type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED && Screen::get() != nullptr) { Screen::get()->handleWindowResized(); } // Connexió/desconnexió de gamepads: cal enrutar-los a Input perquè // afegisca el dispositiu a gamepads_. Sense això, en wasm els gamepads // mai es detecten (la Gamepad API del navegador només els exposa // després que l'usuari els active, més tard que el discoverGamepads // inicial). En desktop també arregla la connexió en calent. if (event.type == SDL_EVENT_GAMEPAD_ADDED || event.type == SDL_EVENT_GAMEPAD_REMOVED) { if (Input::get() != nullptr) { std::string name = Input::get()->handleEvent(event); if (!name.empty() && Notifier::get() != nullptr && Locale::get() != nullptr) { const std::string KEY = (event.type == SDL_EVENT_GAMEPAD_ADDED) ? "ui.gamepad_connected" : "ui.gamepad_disconnected"; Notifier::get()->show({name + " " + Locale::get()->get(KEY)}); } } } // Marcar polsació de qualsevol botó del comandament (els consumirà GlobalInputs // per saltar escenes d'attract mode). El botó BACK queda exclòs perquè es // reserva per a l'acció EXIT. A emscripten només l'excloem a l'escena GAME // (tornar al menú); a la resta d'escenes web BACK actua com a botó genèric, // ja que no pot activar el procés de tancament del joc. if (event.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN) { const bool IS_BACK = (event.gbutton.button == SDL_GAMEPAD_BUTTON_BACK); #ifdef __EMSCRIPTEN__ const bool RESERVE_BACK = IS_BACK && SceneManager::current == SceneManager::Scene::GAME; #else const bool RESERVE_BACK = IS_BACK; #endif if (!RESERVE_BACK) { gamepad_button_pressed_ = true; } } // Enrutar eventos de texto a la consola cuando está activa if (Console::get() != nullptr && Console::get()->isActive()) { if (event.type == SDL_EVENT_TEXT_INPUT || event.type == SDL_EVENT_KEY_DOWN) { Console::get()->handleEvent(event); return; } } Mouse::handleEvent(event); } auto consumeGamepadButtonPressed() -> bool { const bool RESULT = gamepad_button_pressed_; gamepad_button_pressed_ = false; return RESULT; } } // namespace GlobalEvents