#include "core/input/global_inputs.hpp" #include #include // Para allocator, operator+, char_traits, string #include // Para vector #include "core/input/input.hpp" // Para Input, InputAction, Input::DO_NOT_ALLOW_REPEAT #include "core/rendering/screen.hpp" // Para Screen #include "game/options.hpp" // Para Options, options, OptionsVideo, Section #include "game/scene_manager.hpp" // Para SceneManager #include "game/ui/notifier.hpp" // Para Notifier, NotificationText #include "utils/utils.hpp" // Para stringInVector #ifdef _DEBUG #include "core/system/debug.hpp" // Para Debug #endif namespace GlobalInputs { // Funciones internas namespace { void handleQuit() { // En la escena GAME el comportamiento es siempre el mismo (con o sin modo kiosko) if (SceneManager::current == SceneManager::Scene::GAME) { const std::string CODE = "PRESS AGAIN TO RETURN TO MENU"; if (stringInVector(Notifier::get()->getCodes(), CODE)) { SceneManager::current = SceneManager::Scene::TITLE; } else { Notifier::get()->show({CODE}, Notifier::Style::DEFAULT, -1, true, CODE); } return; } // En modo kiosko, fuera de GAME: mostrar el texto del kiosko y no salir nunca if (Options::kiosk.enabled) { const std::string KIOSK_CODE = "KIOSK_EXIT"; if (!stringInVector(Notifier::get()->getCodes(), KIOSK_CODE)) { Notifier::get()->show({Options::kiosk.text}, Notifier::Style::DEFAULT, -1, true, KIOSK_CODE); } // Segunda pulsación: notificación ya activa → no hacer nada return; } // Comportamiento normal fuera del modo kiosko const std::string CODE = "PRESS AGAIN TO EXIT"; if (stringInVector(Notifier::get()->getCodes(), CODE)) { SceneManager::current = SceneManager::Scene::QUIT; } else { Notifier::get()->show({CODE}, Notifier::Style::DEFAULT, -1, true, CODE); } } void handleSkipSection() { switch (SceneManager::current) { case SceneManager::Scene::LOGO: case SceneManager::Scene::LOADING_SCREEN: case SceneManager::Scene::CREDITS: case SceneManager::Scene::DEMO: case SceneManager::Scene::GAME_OVER: case SceneManager::Scene::ENDING: case SceneManager::Scene::ENDING2: SceneManager::current = SceneManager::Scene::TITLE; SceneManager::options = SceneManager::Options::NONE; break; default: break; } } void handleToggleBorder() { Screen::get()->toggleBorder(); Notifier::get()->show({"BORDER " + std::string(Options::video.border.enabled ? "ENABLED" : "DISABLED")}); } void handleToggleVideoMode() { Screen::get()->toggleVideoMode(); Notifier::get()->show({"FULLSCREEN " + std::string(static_cast(Options::video.fullscreen) == 0 ? "DISABLED" : "ENABLED")}); } void handleDecWindowZoom() { if (Screen::get()->decWindowZoom()) { Notifier::get()->show({"WINDOW ZOOM x" + std::to_string(Options::window.zoom)}); } } void handleIncWindowZoom() { if (Screen::get()->incWindowZoom()) { Notifier::get()->show({"WINDOW ZOOM x" + std::to_string(Options::window.zoom)}); } } void handleTogglePostFX() { Screen::get()->togglePostFX(); Notifier::get()->show({"POSTFX " + std::string(Options::video.postfx ? "ENABLED" : "DISABLED")}); } void handleNextPostFXPreset() { if (!Options::postfx_presets.empty()) { Options::current_postfx_preset = (Options::current_postfx_preset + 1) % static_cast(Options::postfx_presets.size()); Screen::get()->reloadPostFX(); Notifier::get()->show({"POSTFX " + Options::postfx_presets[static_cast(Options::current_postfx_preset)].name}); } } void handleNextPalette() { Screen::get()->nextPalette(); Notifier::get()->show({"PALETTE " + Options::video.palette}); } void handlePreviousPalette() { Screen::get()->previousPalette(); Notifier::get()->show({"PALETTE " + Options::video.palette}); } void handleToggleIntegerScale() { Screen::get()->toggleIntegerScale(); Screen::get()->setVideoMode(Options::video.fullscreen); Notifier::get()->show({"INTEGER SCALE " + std::string(Options::video.integer_scale ? "ENABLED" : "DISABLED")}); } void handleToggleVSync() { Screen::get()->toggleVSync(); Notifier::get()->show({"V-SYNC " + std::string(Options::video.vertical_sync ? "ENABLED" : "DISABLED")}); } #ifdef _DEBUG void handleShowDebugInfo() { Screen::get()->toggleDebugInfo(); } /* void handleToggleDebug() { Debug::get()->toggleEnabled(); Notifier::get()->show({"DEBUG " + std::string(Debug::get()->isEnabled() ? "ENABLED" : "DISABLED")}, Notifier::TextAlign::CENTER); } */ #endif // Detecta qué acción global ha sido presionada (si alguna) auto getPressedAction() -> InputAction { if (Input::get()->checkAction(InputAction::EXIT, Input::DO_NOT_ALLOW_REPEAT)) { return InputAction::EXIT; } if (Input::get()->checkAction(InputAction::ACCEPT, Input::DO_NOT_ALLOW_REPEAT)) { return InputAction::ACCEPT; } if (Input::get()->checkAction(InputAction::TOGGLE_BORDER, Input::DO_NOT_ALLOW_REPEAT)) { return InputAction::TOGGLE_BORDER; } if (!Options::kiosk.enabled) { if (Input::get()->checkAction(InputAction::TOGGLE_FULLSCREEN, Input::DO_NOT_ALLOW_REPEAT)) { return InputAction::TOGGLE_FULLSCREEN; } if (Input::get()->checkAction(InputAction::WINDOW_DEC_ZOOM, Input::DO_NOT_ALLOW_REPEAT)) { return InputAction::WINDOW_DEC_ZOOM; } if (Input::get()->checkAction(InputAction::WINDOW_INC_ZOOM, Input::DO_NOT_ALLOW_REPEAT)) { return InputAction::WINDOW_INC_ZOOM; } } if (Input::get()->checkAction(InputAction::TOGGLE_POSTFX, Input::DO_NOT_ALLOW_REPEAT)) { if (Options::video.postfx && ((SDL_GetModState() & SDL_KMOD_SHIFT) != 0U)) { return InputAction::NEXT_POSTFX_PRESET; } return InputAction::TOGGLE_POSTFX; } if (Input::get()->checkAction(InputAction::NEXT_PALETTE, Input::DO_NOT_ALLOW_REPEAT)) { return InputAction::NEXT_PALETTE; } if (Input::get()->checkAction(InputAction::PREVIOUS_PALETTE, Input::DO_NOT_ALLOW_REPEAT)) { return InputAction::PREVIOUS_PALETTE; } if (Input::get()->checkAction(InputAction::TOGGLE_INTEGER_SCALE, Input::DO_NOT_ALLOW_REPEAT)) { return InputAction::TOGGLE_INTEGER_SCALE; } if (Input::get()->checkAction(InputAction::TOGGLE_VSYNC, Input::DO_NOT_ALLOW_REPEAT)) { return InputAction::TOGGLE_VSYNC; } if (Input::get()->checkAction(InputAction::TOGGLE_DEBUG, Input::DO_NOT_ALLOW_REPEAT)) { return InputAction::TOGGLE_DEBUG; } if (Input::get()->checkAction(InputAction::SHOW_DEBUG_INFO, Input::DO_NOT_ALLOW_REPEAT)) { return InputAction::SHOW_DEBUG_INFO; } return InputAction::NONE; } } // namespace // Funciones públicas // Comprueba los inputs que se pueden introducir en cualquier sección del juego void handle() { // Salida de administrador en modo kiosko (Ctrl+Shift+Alt+Q) if (Options::kiosk.enabled) { SDL_Keymod mod = SDL_GetModState(); const bool* ks = SDL_GetKeyboardState(nullptr); if (((mod & SDL_KMOD_CTRL) != 0U) && ((mod & SDL_KMOD_SHIFT) != 0U) && ((mod & SDL_KMOD_ALT) != 0U) && ks[SDL_SCANCODE_Q]) { SceneManager::current = SceneManager::Scene::QUIT; return; } } // Detectar qué acción global está siendo presionada InputAction action = getPressedAction(); // Ejecutar el handler correspondiente usando switch statement switch (action) { case InputAction::EXIT: handleQuit(); break; case InputAction::ACCEPT: handleSkipSection(); break; case InputAction::TOGGLE_BORDER: handleToggleBorder(); break; case InputAction::TOGGLE_FULLSCREEN: handleToggleVideoMode(); break; case InputAction::WINDOW_DEC_ZOOM: handleDecWindowZoom(); break; case InputAction::WINDOW_INC_ZOOM: handleIncWindowZoom(); break; case InputAction::TOGGLE_POSTFX: handleTogglePostFX(); break; case InputAction::NEXT_POSTFX_PRESET: handleNextPostFXPreset(); break; case InputAction::NEXT_PALETTE: handleNextPalette(); break; case InputAction::PREVIOUS_PALETTE: handlePreviousPalette(); break; case InputAction::TOGGLE_INTEGER_SCALE: handleToggleIntegerScale(); break; case InputAction::TOGGLE_VSYNC: handleToggleVSync(); break; case InputAction::TOGGLE_DEBUG: // handleToggleDebug(); break; #ifdef _DEBUG case InputAction::SHOW_DEBUG_INFO: handleShowDebugInfo(); break; #endif case InputAction::NONE: default: // No se presionó ninguna acción global break; } } } // namespace GlobalInputs