295 lines
13 KiB
C++
295 lines
13 KiB
C++
#include "core/input/global_inputs.hpp"
|
|
|
|
#include <SDL3/SDL.h>
|
|
|
|
#include <string> // Para allocator, operator+, char_traits, string
|
|
#include <vector> // Para vector
|
|
|
|
#include "core/input/input.hpp" // Para Input, InputAction, Input::DO_NOT_ALLOW_REPEAT
|
|
#include "core/locale/locale.hpp" // Para Locale
|
|
#include "core/rendering/render_info.hpp" // Para RenderInfo
|
|
#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/console.hpp" // Para Console
|
|
#include "game/ui/notifier.hpp" // Para Notifier, NotificationText
|
|
#include "utils/utils.hpp" // Para stringInVector
|
|
|
|
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({Locale::get()->get("ui.press_again_menu")}, Notifier::Style::DEFAULT, -1, true, CODE); // NOLINT(readability-static-accessed-through-instance)
|
|
}
|
|
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({Locale::get()->get("ui.press_again_exit")}, Notifier::Style::DEFAULT, -1, true, CODE); // NOLINT(readability-static-accessed-through-instance)
|
|
}
|
|
}
|
|
|
|
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({Locale::get()->get(Options::video.border.enabled ? "ui.border_enabled" : "ui.border_disabled")}); // NOLINT(readability-static-accessed-through-instance)
|
|
}
|
|
|
|
void handleToggleVideoMode() {
|
|
Screen::get()->toggleVideoMode();
|
|
Notifier::get()->show({Locale::get()->get(static_cast<int>(Options::video.fullscreen) == 0 ? "ui.fullscreen_disabled" : "ui.fullscreen_enabled")}); // NOLINT(readability-static-accessed-through-instance)
|
|
}
|
|
|
|
void handleDecWindowZoom() {
|
|
if (Screen::get()->decWindowZoom()) {
|
|
Notifier::get()->show({Locale::get()->get("ui.window_zoom") + std::to_string(Options::window.zoom)}); // NOLINT(readability-static-accessed-through-instance)
|
|
}
|
|
}
|
|
|
|
void handleIncWindowZoom() {
|
|
if (Screen::get()->incWindowZoom()) {
|
|
Notifier::get()->show({Locale::get()->get("ui.window_zoom") + std::to_string(Options::window.zoom)}); // NOLINT(readability-static-accessed-through-instance)
|
|
}
|
|
}
|
|
|
|
void handleTogglePostFX() {
|
|
Screen::get()->togglePostFX();
|
|
Notifier::get()->show({Locale::get()->get(Options::video.postfx ? "ui.postfx_enabled" : "ui.postfx_disabled")}); // NOLINT(readability-static-accessed-through-instance)
|
|
}
|
|
|
|
void handleToggleSupersampling() {
|
|
Screen::get()->toggleSupersampling();
|
|
Notifier::get()->show({Locale::get()->get(Options::video.supersampling ? "ui.supersampling_enabled" : "ui.supersampling_disabled")}); // NOLINT(readability-static-accessed-through-instance)
|
|
}
|
|
|
|
void handleNextPostFXPreset() {
|
|
if (!Options::postfx_presets.empty()) {
|
|
Options::current_postfx_preset = (Options::current_postfx_preset + 1) % static_cast<int>(Options::postfx_presets.size());
|
|
Screen::get()->reloadPostFX();
|
|
Notifier::get()->show({Locale::get()->get("ui.postfx") + " " + Options::postfx_presets[static_cast<size_t>(Options::current_postfx_preset)].name}); // NOLINT(readability-static-accessed-through-instance)
|
|
}
|
|
}
|
|
|
|
void handleNextPalette() {
|
|
Screen::get()->nextPalette();
|
|
Notifier::get()->show({Locale::get()->get("ui.palette") + " " + Options::video.palette}); // NOLINT(readability-static-accessed-through-instance)
|
|
}
|
|
|
|
void handlePreviousPalette() {
|
|
Screen::get()->previousPalette();
|
|
Notifier::get()->show({Locale::get()->get("ui.palette") + " " + Options::video.palette}); // NOLINT(readability-static-accessed-through-instance)
|
|
}
|
|
|
|
void handleToggleIntegerScale() {
|
|
Screen::get()->toggleIntegerScale();
|
|
Screen::get()->setVideoMode(Options::video.fullscreen);
|
|
Notifier::get()->show({Locale::get()->get(Options::video.integer_scale ? "ui.integer_scale_enabled" : "ui.integer_scale_disabled")}); // NOLINT(readability-static-accessed-through-instance)
|
|
}
|
|
|
|
void handleToggleVSync() {
|
|
Screen::get()->toggleVSync();
|
|
Notifier::get()->show({Locale::get()->get(Options::video.vertical_sync ? "ui.vsync_enabled" : "ui.vsync_disabled")}); // NOLINT(readability-static-accessed-through-instance)
|
|
}
|
|
|
|
// 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 ((SDL_GetModState() & SDL_KMOD_CTRL) != 0U) {
|
|
return InputAction::TOGGLE_SUPERSAMPLING; // Ctrl+F4
|
|
}
|
|
if (Options::video.postfx && ((SDL_GetModState() & SDL_KMOD_SHIFT) != 0U)) {
|
|
return InputAction::NEXT_POSTFX_PRESET; // Shift+F4
|
|
}
|
|
return InputAction::TOGGLE_POSTFX; // F4
|
|
}
|
|
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;
|
|
}
|
|
if (Input::get()->checkAction(InputAction::TOGGLE_CONSOLE, Input::DO_NOT_ALLOW_REPEAT)) {
|
|
return InputAction::TOGGLE_CONSOLE;
|
|
}
|
|
return InputAction::NONE;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
// Funciones públicas
|
|
|
|
// Comprueba los inputs que se pueden introducir en cualquier sección del juego
|
|
void handle() {
|
|
const bool CONSOLE_ACTIVE = Console::get() != nullptr && Console::get()->isActive();
|
|
|
|
if (CONSOLE_ACTIVE) {
|
|
// TAB/ESC cierran la consola en lugar de ejecutar sus acciones normales
|
|
if (Input::get()->checkAction(InputAction::TOGGLE_CONSOLE, Input::DO_NOT_ALLOW_REPEAT) ||
|
|
Input::get()->checkAction(InputAction::EXIT, Input::DO_NOT_ALLOW_REPEAT)) {
|
|
Console::get()->toggle();
|
|
return;
|
|
}
|
|
} else {
|
|
// 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();
|
|
|
|
// Con consola activa, ACCEPT (saltar sección) y EXIT están bloqueados
|
|
if (CONSOLE_ACTIVE && (action == InputAction::ACCEPT || action == InputAction::EXIT)) {
|
|
return;
|
|
}
|
|
|
|
// 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::TOGGLE_SUPERSAMPLING:
|
|
handleToggleSupersampling();
|
|
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_CONSOLE:
|
|
if (Console::get() != nullptr) { Console::get()->toggle(); }
|
|
break;
|
|
|
|
#ifdef _DEBUG
|
|
case InputAction::TOGGLE_DEBUG:
|
|
if (RenderInfo::get() != nullptr) { RenderInfo::get()->toggle(); }
|
|
break;
|
|
|
|
case InputAction::SHOW_DEBUG_INFO:
|
|
break;
|
|
#endif
|
|
|
|
case InputAction::NONE:
|
|
default:
|
|
// No se presionó ninguna acción global
|
|
break;
|
|
}
|
|
}
|
|
} // namespace GlobalInputs
|