#include "core/input/global_inputs.hpp" #include #include "core/input/input.h" #include "core/locale/lang.h" #include "core/rendering/screen.h" #include "core/resources/resource.h" #include "core/resources/skin_manager.hpp" #include "game/options.hpp" #include "utils/utils.h" namespace GlobalInputs { namespace { // Índexs de Lang per a les notificacions de hotkey constexpr int LANG_ZOOM = 96; constexpr int LANG_FULLSCREEN = 97; constexpr int LANG_WINDOW = 98; constexpr int LANG_SHADER = 99; constexpr int LANG_PRESET = 100; constexpr int LANG_EXIT_CONFIRM = 101; constexpr int LANG_SKIN = 102; constexpr Uint32 NOTIFY_MS = 1500; constexpr Uint32 EXIT_CONFIRM_MS = 2000; const Color BLACK = {0x00, 0x00, 0x00}; const Color CYAN = {0x00, 0xFF, 0xFF}; const Color YELLOW = {0xFF, 0xE0, 0x40}; const Color MAGENTA = {0xFF, 0x00, 0xFF}; const Color GREEN = {0x00, 0xFF, 0x80}; const Color RED = {0xFF, 0x40, 0x40}; // Patró de doble pulsació: la primera pulsació d'EXIT mostra una // notificació en vermell i obre una finestra de confirmació; una // segona pulsació dins la finestra activa `quit_requested`. La // finestra coincideix amb la durada del missatge perquè usuari i // sistema sempre estiguin sincronitzats. Uint32 exit_window_until_ticks = 0; bool quit_requested = false; void notifyZoom() { const std::string MSG = Lang::get()->getText(LANG_ZOOM) + " " + std::to_string(Options::window.zoom) + "x"; Screen::get()->notify(MSG, YELLOW, BLACK, NOTIFY_MS); } void notifyFullscreen() { const int IDX = Options::video.fullscreen ? LANG_FULLSCREEN : LANG_WINDOW; Screen::get()->notify(Lang::get()->getText(IDX), YELLOW, BLACK, NOTIFY_MS); } void notifyShaderEnabled() { const std::string STATE = Screen::isShaderEnabled() ? "ON" : "OFF"; const std::string MSG = Lang::get()->getText(LANG_SHADER) + " " + STATE; Screen::get()->notify(MSG, CYAN, BLACK, NOTIFY_MS); } void notifyShaderType() { const bool IS_CRTPI = Options::video.shader.current_shader == Rendering::ShaderType::CRTPI; const std::string MSG = Lang::get()->getText(LANG_SHADER) + " " + (IS_CRTPI ? "CRTPI" : "POSTFX"); Screen::get()->notify(MSG, MAGENTA, BLACK, NOTIFY_MS); } void notifyPreset() { const std::string MSG = Lang::get()->getText(LANG_PRESET) + " " + Screen::get()->getCurrentPresetName(); Screen::get()->notify(MSG, GREEN, BLACK, NOTIFY_MS); } void notifySkin() { const std::string MSG = Lang::get()->getText(LANG_SKIN) + " " + SkinManager::get()->currentDisplayName(); Screen::get()->notify(MSG, CYAN, BLACK, NOTIFY_MS); } void onExit() { const Uint32 NOW = SDL_GetTicks(); if (NOW < exit_window_until_ticks) { quit_requested = true; return; } exit_window_until_ticks = NOW + EXIT_CONFIRM_MS; Screen::get()->notify(Lang::get()->getText(LANG_EXIT_CONFIRM), RED, BLACK, EXIT_CONFIRM_MS); } } // namespace auto handle() -> bool { if (Screen::get() == nullptr || Input::get() == nullptr) { return false; } if (Input::get()->checkInput(Input::Action::EXIT, Input::Repeat::OFF)) { onExit(); return true; } if (Input::get()->checkInput(Input::Action::WINDOW_FULLSCREEN, Input::Repeat::OFF)) { Screen::get()->toggleVideoMode(); notifyFullscreen(); return true; } if (Input::get()->checkInput(Input::Action::WINDOW_DEC_ZOOM, Input::Repeat::OFF)) { if (Screen::get()->decWindowZoom()) { notifyZoom(); } return true; } if (Input::get()->checkInput(Input::Action::WINDOW_INC_ZOOM, Input::Repeat::OFF)) { if (Screen::get()->incWindowZoom()) { notifyZoom(); } return true; } if (Input::get()->checkInput(Input::Action::TOGGLE_SHADER, Input::Repeat::OFF)) { Screen::get()->toggleShaderEnabled(); notifyShaderEnabled(); return true; } // F5/F6 només actuen quan el post-procesado està actiu. if (Screen::isShaderEnabled()) { if (Input::get()->checkInput(Input::Action::TOGGLE_SHADER_TYPE, Input::Repeat::OFF)) { Screen::get()->toggleActiveShader(); notifyShaderType(); return true; } if (Input::get()->checkInput(Input::Action::NEXT_SHADER_PRESET, Input::Repeat::OFF)) { if (Screen::get()->nextPreset()) { notifyPreset(); } return true; } } if (Input::get()->checkInput(Input::Action::NEXT_SKIN, Input::Repeat::OFF)) { const std::string NEXT_ID = SkinManager::get()->nextSkinId(); if (NEXT_ID != SkinManager::get()->current()) { Resource::get()->reloadForSkin(NEXT_ID); } notifySkin(); return true; } return false; } auto wantsQuit() -> bool { return quit_requested; } } // namespace GlobalInputs