diff --git a/source/game/ui/console.cpp b/source/game/ui/console.cpp index c3fb4d2..3e2715e 100644 --- a/source/game/ui/console.cpp +++ b/source/game/ui/console.cpp @@ -41,30 +41,146 @@ static auto parseTokens(const std::string& input) -> std::vector { return tokens; } +// Macro para comando de toggle booleano (evita repetición en ON/OFF) +#define BOOL_TOGGLE_CMD(label, getter, toggle_fn) \ + [](const std::vector& args) -> std::string { \ + if (args.empty()) { \ + (toggle_fn); \ + return label " " + std::string((getter) ? "ON" : "OFF"); \ + } \ + if (args[0] == "ON") { \ + if (getter) { return label " already ON"; } \ + (toggle_fn); return label " ON"; \ + } \ + if (args[0] == "OFF") { \ + if (!(getter)) { return label " already OFF"; } \ + (toggle_fn); return label " OFF"; \ + } \ + return "Usage: " label " [ON|OFF]"; \ + } + +// Texto de ayuda común para HELP y ? +static void printHelp() { + SDL_Log("=== JDD CONSOLE COMMANDS ==="); + SDL_Log(" SS [ON|OFF] Supersampling (Ctrl+F4)"); + SDL_Log(" POSTFX [ON|OFF|NEXT] Post-FX effects / next preset (F4/Shift+F4)"); + SDL_Log(" BORDER [ON|OFF] Decorative border (B)"); + SDL_Log(" FULLSCREEN [ON|OFF] Fullscreen mode (F3)"); + SDL_Log(" ZOOM [UP|DOWN] Window zoom (F1/F2)"); + SDL_Log(" INTSCALE [ON|OFF] Integer scaling (F7)"); + SDL_Log(" VSYNC [ON|OFF] Vertical sync"); + SDL_Log(" PALETTE [NEXT|PREV] Color palette (F5/F6)"); +#ifdef _DEBUG + SDL_Log(" DEBUG Toggle debug overlay (F12)"); +#endif + SDL_Log(" HELP/? Show this help in terminal"); +} + // Tabla de comandos disponibles static const std::vector COMMANDS = { - {"SS", [](const std::vector& args) -> std::string { + // SS [ON|OFF] — Supersampling (Ctrl+F4) + {.keyword = "SS", .execute = BOOL_TOGGLE_CMD("Supersampling", + Options::video.supersampling, + Screen::get()->toggleSupersampling())}, + + // POSTFX [ON|OFF|NEXT] — PostFX y presets (F4 / Shift+F4) + {.keyword = "POSTFX", .execute = [](const std::vector& args) -> std::string { if (args.empty()) { - Screen::get()->toggleSupersampling(); - return std::string("Supersampling ") + (Options::video.supersampling ? "ON" : "OFF"); + Screen::get()->togglePostFX(); + return std::string("PostFX ") + (Options::video.postfx ? "ON" : "OFF"); } if (args[0] == "ON") { - if (Options::video.supersampling) { return "Supersampling already ON"; } - Screen::get()->toggleSupersampling(); - return "Supersampling ON"; + if (Options::video.postfx) { return "PostFX already ON"; } + Screen::get()->togglePostFX(); return "PostFX ON"; } if (args[0] == "OFF") { - if (!Options::video.supersampling) { return "Supersampling already OFF"; } - Screen::get()->toggleSupersampling(); - return "Supersampling OFF"; + if (!Options::video.postfx) { return "PostFX already OFF"; } + Screen::get()->togglePostFX(); return "PostFX OFF"; } - return "Usage: SS [ON|OFF]"; + if (args[0] == "NEXT") { + if (Options::postfx_presets.empty()) { return "No presets available"; } + Options::current_postfx_preset = + (Options::current_postfx_preset + 1) % + static_cast(Options::postfx_presets.size()); + Screen::get()->reloadPostFX(); + return "PostFX preset: " + + Options::postfx_presets[static_cast(Options::current_postfx_preset)].name; + } + return "Usage: POSTFX [ON|OFF|NEXT]"; }}, - {"HELP", [](const std::vector&) -> std::string { - return "Commands: SS [ON|OFF]"; + + // BORDER [ON|OFF] — Borde decorativo (B) + {.keyword = "BORDER", .execute = BOOL_TOGGLE_CMD("Border", + Options::video.border.enabled, + Screen::get()->toggleBorder())}, + + // FULLSCREEN [ON|OFF] — Pantalla completa (F3) + {.keyword = "FULLSCREEN", .execute = BOOL_TOGGLE_CMD("Fullscreen", + Options::video.fullscreen, + Screen::get()->toggleVideoMode())}, + + // ZOOM UP/DOWN — Zoom de ventana (F1/F2) + {.keyword = "ZOOM", .execute = [](const std::vector& args) -> std::string { + if (args.empty()) { return "Usage: ZOOM [UP|DOWN]"; } + if (args[0] == "UP") { + if (!Screen::get()->incWindowZoom()) { return "Max zoom reached"; } + return "Zoom " + std::to_string(Options::window.zoom); + } + if (args[0] == "DOWN") { + if (!Screen::get()->decWindowZoom()) { return "Min zoom reached"; } + return "Zoom " + std::to_string(Options::window.zoom); + } + return "Usage: ZOOM [UP|DOWN]"; }}, - {"?", [](const std::vector&) -> std::string { - return "Commands: SS [ON|OFF]"; + + // INTSCALE [ON|OFF] — Escalado entero (F7) + {.keyword = "INTSCALE", .execute = [](const std::vector& args) -> std::string { + const bool ON = args.empty() ? !Options::video.integer_scale + : (args[0] == "ON"); + if (!args.empty() && args[0] != "ON" && args[0] != "OFF") { + return "Usage: INTSCALE [ON|OFF]"; + } + if (ON == Options::video.integer_scale) { + return std::string("IntScale already ") + (ON ? "ON" : "OFF"); + } + Screen::get()->toggleIntegerScale(); + Screen::get()->setVideoMode(Options::video.fullscreen); + return std::string("IntScale ") + (Options::video.integer_scale ? "ON" : "OFF"); + }}, + + // VSYNC [ON|OFF] — Sincronización vertical + {.keyword = "VSYNC", .execute = BOOL_TOGGLE_CMD("VSync", + Options::video.vertical_sync, + Screen::get()->toggleVSync())}, + + // PALETTE NEXT/PREV — Paleta de colores (F5/F6) + {.keyword = "PALETTE", .execute = [](const std::vector& args) -> std::string { + if (args.empty()) { return "Usage: PALETTE [NEXT|PREV]"; } + if (args[0] == "NEXT") { + Screen::get()->nextPalette(); + return "Palette: " + Options::video.palette; + } + if (args[0] == "PREV") { + Screen::get()->previousPalette(); + return "Palette: " + Options::video.palette; + } + return "Usage: PALETTE [NEXT|PREV]"; + }}, + +#ifdef _DEBUG + // DEBUG — Toggle overlay de debug (F12, solo en builds debug) + {.keyword = "DEBUG", .execute = [](const std::vector&) -> std::string { + Screen::get()->toggleFPS(); + return "Debug overlay toggled"; + }}, +#endif + + // HELP / ? — Muestra ayuda en la terminal del sistema + {.keyword = "HELP", .execute = [](const std::vector&) -> std::string { + printHelp(); return "Help printed to terminal"; + }}, + {.keyword = "?", .execute = [](const std::vector&) -> std::string { + printHelp(); return "Help printed to terminal"; }}, }; @@ -97,6 +213,8 @@ Console::Console(const std::string& font_name) height_ = static_cast((TEXT_SIZE * 2) + (PADDING_IN_V * 2)); y_ = -height_; + msg_line_ = std::string(CONSOLE_NAME) + " " + std::string(CONSOLE_VERSION); + buildSurface(); } @@ -133,7 +251,7 @@ void Console::redrawText() { text_->writeColored(PADDING_IN_H, PADDING_IN_V, msg_line_, MSG_COLOR); // Línea 2: prompt + input + cursor - const bool SHOW_CURSOR = cursor_visible_ && (static_cast(input_line_.size()) < MAX_INPUT_CHARS); + const bool SHOW_CURSOR = cursor_visible_ && (static_cast(input_line_.size()) < MAX_LINE_CHARS); const std::string INPUT_STR = "> " + input_line_ + (SHOW_CURSOR ? "_" : ""); text_->writeColored(PADDING_IN_H, PADDING_IN_V + TEXT_SIZE, INPUT_STR, BORDER_COLOR); @@ -203,7 +321,8 @@ void Console::toggle() { SDL_StartTextInput(SDL_GetKeyboardFocus()); break; case Status::ACTIVE: - status_ = Status::VANISHING; + status_ = Status::VANISHING; + msg_line_ = std::string(CONSOLE_NAME) + " " + std::string(CONSOLE_VERSION); SDL_StopTextInput(SDL_GetKeyboardFocus()); break; default: @@ -217,7 +336,7 @@ void Console::handleEvent(const SDL_Event& event) { if (status_ != Status::ACTIVE) { return; } if (event.type == SDL_EVENT_TEXT_INPUT) { - if (static_cast(input_line_.size()) < MAX_INPUT_CHARS) { + if (static_cast(input_line_.size()) < MAX_LINE_CHARS) { input_line_ += event.text.text; } return; @@ -251,6 +370,9 @@ void Console::processCommand() { if (!found) { msg_line_ = "Unknown: " + cmd; } + if (static_cast(msg_line_.size()) > MAX_LINE_CHARS) { + msg_line_.resize(MAX_LINE_CHARS); + } } } input_line_.clear(); diff --git a/source/game/ui/console.hpp b/source/game/ui/console.hpp index 89c92a3..d196df1 100644 --- a/source/game/ui/console.hpp +++ b/source/game/ui/console.hpp @@ -40,8 +40,10 @@ class Console { static constexpr Uint8 MSG_COLOR = 8; // PaletteColor::GREEN static constexpr float SLIDE_SPEED = 120.0F; - // Constantes de entrada - static constexpr int MAX_INPUT_CHARS = 28; + // Constantes de consola + static constexpr std::string_view CONSOLE_NAME = "JDD Console"; + static constexpr std::string_view CONSOLE_VERSION = "v1.0"; + static constexpr int MAX_LINE_CHARS = 28; static constexpr float CURSOR_ON_TIME = 0.5F; static constexpr float CURSOR_OFF_TIME = 0.3F; @@ -68,7 +70,7 @@ class Console { float height_{0.0F}; // Altura del panel // Estado de la entrada de texto - std::string msg_line_{"JDD CONSOLE V1.0"}; + std::string msg_line_; // inicializado en constructor con CONSOLE_NAME + CONSOLE_VERSION std::string input_line_; float cursor_timer_{0.0F}; bool cursor_visible_{true};