84 lines
3.9 KiB
C++
84 lines
3.9 KiB
C++
#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
|