From 1817d00881b4efa606bbaa8ef2eac72c77d0d502 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Mon, 30 Mar 2026 23:03:21 +0200 Subject: [PATCH] screen torna llista de paletes i permet canviar a una paleta pel nom console 2.1 por canviar de paleta pel nom --- source/core/rendering/screen.cpp | 27 +++++++++++ source/core/rendering/screen.hpp | 24 +++++----- source/game/ui/console.cpp | 82 +++++++++++++++++++------------- source/utils/defines.hpp | 2 +- 4 files changed, 90 insertions(+), 45 deletions(-) diff --git a/source/core/rendering/screen.cpp b/source/core/rendering/screen.cpp index 5cf2b10..fe59e40 100644 --- a/source/core/rendering/screen.cpp +++ b/source/core/rendering/screen.cpp @@ -482,6 +482,33 @@ auto Screen::findPalette(const std::string& name) -> size_t { // NOLINT(readabi return static_cast(0); } +// Cambia a una paleta por nombre (case-insensitive); devuelve false si no existe +bool Screen::setPaletteByName(const std::string& name) { + const std::string upper_name = toUpper(name + ".pal"); + for (size_t i = 0; i < palettes_.size(); ++i) { + if (toUpper(getFileName(palettes_[i])) == upper_name) { + current_palette_ = static_cast(i); + setPalete(); + return true; + } + } + return false; +} + +// Devuelve los nombres de paletas disponibles (mayúsculas, sin extensión .pal) +auto Screen::getPaletteNames() const -> std::vector { + std::vector names; + names.reserve(palettes_.size()); + for (const auto& p : palettes_) { + std::string name = p; + const size_t pos = name.find(".pal"); + if (pos != std::string::npos) { name.erase(pos, 4); } + std::ranges::transform(name, name.begin(), ::toupper); + names.push_back(std::move(name)); + } + return names; +} + // Limpia la game_surface_ void Screen::clearSurface(Uint8 index) { game_surface_->clear(index); } diff --git a/source/core/rendering/screen.hpp b/source/core/rendering/screen.hpp index 4379b6c..fd30de9 100644 --- a/source/core/rendering/screen.hpp +++ b/source/core/rendering/screen.hpp @@ -52,17 +52,19 @@ class Screen { void toggleBorder(); // Cambia entre borde visible y no visible // Paletas y PostFX - void nextPalette(); // Cambia a la siguiente paleta - void previousPalette(); // Cambia a la paleta anterior - void setPalete(); // Establece la paleta actual - void toggleShaders(); // Activa/desactiva todos los shaders respetando current_shader - void toggleSupersampling(); // Activa/desactiva el supersampling global - void reloadPostFX(); // Recarga el shader del preset actual sin toggle - void reloadCrtPi(); // Recarga el shader CrtPi del preset actual sin toggle - void setLinearUpscale(bool linear); // Upscale NEAREST (false) o LINEAR (true) en el paso SS - void setDownscaleAlgo(int algo); // 0=bilinear legacy, 1=Lanczos2, 2=Lanczos3 - void setActiveShader(Rendering::ShaderType type); // Cambia el shader de post-procesado activo - void nextShader(); // Cicla al siguiente shader disponible (para futura UI) + void nextPalette(); // Cambia a la siguiente paleta + void previousPalette(); // Cambia a la paleta anterior + void setPalete(); // Establece la paleta actual + bool setPaletteByName(const std::string& name); // Cambia a paleta por nombre; false si no existe + [[nodiscard]] auto getPaletteNames() const -> std::vector; // Nombres disponibles (mayúsculas, sin .pal) + void toggleShaders(); // Activa/desactiva todos los shaders respetando current_shader + void toggleSupersampling(); // Activa/desactiva el supersampling global + void reloadPostFX(); // Recarga el shader del preset actual sin toggle + void reloadCrtPi(); // Recarga el shader CrtPi del preset actual sin toggle + void setLinearUpscale(bool linear); // Upscale NEAREST (false) o LINEAR (true) en el paso SS + void setDownscaleAlgo(int algo); // 0=bilinear legacy, 1=Lanczos2, 2=Lanczos3 + void setActiveShader(Rendering::ShaderType type); // Cambia el shader de post-procesado activo + void nextShader(); // Cicla al siguiente shader disponible (para futura UI) // Surfaces y notificaciones void setRendererSurface(const std::shared_ptr& surface = nullptr); // Establece el renderizador para las surfaces diff --git a/source/game/ui/console.cpp b/source/game/ui/console.cpp index c71feed..7351ba8 100644 --- a/source/game/ui/console.cpp +++ b/source/game/ui/console.cpp @@ -369,9 +369,9 @@ static const std::vector COMMANDS = { return "Driver: " + driver_lower + " (restart)"; }}, - // PALETTE NEXT/PREV — Paleta de colores (F5/F6) + // PALETTE NEXT/PREV/ — Paleta de colores (F5/F6 o por nombre) {.keyword = "PALETTE", .execute = [](const std::vector& args) -> std::string { - if (args.empty()) { return "usage: palette [next|prev]"; } + if (args.empty()) { return "usage: palette [next|prev|]"; } if (args[0] == "NEXT") { Screen::get()->nextPalette(); return "Palette: " + Options::video.palette; @@ -380,7 +380,10 @@ static const std::vector COMMANDS = { Screen::get()->previousPalette(); return "Palette: " + Options::video.palette; } - return "usage: palette [next|prev]"; + if (!Screen::get()->setPaletteByName(args[0])) { + return "Unknown palette: " + args[0]; + } + return "Palette: " + Options::video.palette; }}, #ifdef _DEBUG @@ -1150,44 +1153,57 @@ void Console::handleEvent(const SDL_Event& event) { } else { // Modo sub-argumento: completar primer arg del comando base using SubArgs = std::vector; - using Entry = std::pair; + using Entry = std::pair; static const std::vector SUB_ARGS = { - {"SS", {"ON", "OFF", "SIZE", "UPSCALE", "DOWNSCALE"}}, - {"SHADER", {"ON", "OFF", "NEXT", "POSTFX", "CRTPI"}}, - {"BORDER", {"ON", "OFF"}}, + {"SS", {"ON", "OFF", "SIZE", "UPSCALE", "DOWNSCALE"}}, + {"SHADER", {"ON", "OFF", "NEXT", "POSTFX", "CRTPI"}}, + {"BORDER", {"ON", "OFF"}}, {"FULLSCREEN", {"ON", "OFF"}}, - {"ZOOM", {"UP", "DOWN"}}, - {"INTSCALE", {"ON", "OFF"}}, - {"VSYNC", {"ON", "OFF"}}, - {"DRIVER", {"LIST", "AUTO", "NONE"}}, - {"PALETTE", {"NEXT", "PREV"}}, - {"AUDIO", {"ON", "OFF", "VOL"}}, - {"MUSIC", {"ON", "OFF", "VOL"}}, - {"SOUND", {"ON", "OFF", "VOL"}}, + {"ZOOM", {"UP", "DOWN"}}, + {"INTSCALE", {"ON", "OFF"}}, + {"VSYNC", {"ON", "OFF"}}, + {"DRIVER", {"LIST", "AUTO", "NONE"}}, + {"AUDIO", {"ON", "OFF", "VOL"}}, + {"MUSIC", {"ON", "OFF", "VOL"}}, + {"SOUND", {"ON", "OFF", "VOL"}}, #ifdef _DEBUG - {"SHOW", {"INFO", "NOTIFICATION", "CHEEVO"}}, - {"SET", {"PLAYER", "INITIAL", "ITEMS"}}, - {"DEBUG", {"ON", "OFF"}}, - {"ROOM", {"NEXT", "PREV"}}, - {"SCENE", {"LOGO", "LOADING", "TITLE", "CREDITS", "GAME", "ENDING", "ENDING2", "RESTART"}}, + {"SHOW", {"INFO", "NOTIFICATION", "CHEEVO"}}, + {"SET", {"PLAYER", "INITIAL", "ITEMS"}}, + {"DEBUG", {"ON", "OFF"}}, + {"ROOM", {"NEXT", "PREV"}}, + {"SCENE", {"LOGO", "LOADING", "TITLE", "CREDITS", "GAME", "ENDING", "ENDING2", "RESTART"}}, #else - {"SHOW", {"INFO"}}, - {"SET", {"PLAYER"}}, + {"SHOW", {"INFO"}}, + {"SET", {"PLAYER"}}, #endif - {"HIDE", {"INFO"}}, - {"KIOSK", {"ON"}}, - {"CHEAT", {"INFINITE", "INVINCIBILITY", "OPEN", "CLOSE"}}, + {"HIDE", {"INFO"}}, + {"KIOSK", {"ON"}}, + {"CHEAT", {"INFINITE", "INVINCIBILITY", "OPEN", "CLOSE"}}, }; - const std::string base_cmd = upper.substr(0, space_pos); + const std::string base_cmd = upper.substr(0, space_pos); const std::string sub_prefix = upper.substr(space_pos + 1); - for (const auto& [keyword, args] : SUB_ARGS) { - if (keyword == base_cmd) { - for (const auto& arg : args) { - if (sub_prefix.empty() || std::string_view{arg}.starts_with(sub_prefix)) { - tab_matches_.emplace_back(std::string(base_cmd) + " " + std::string(arg)); - } + if (base_cmd == "PALETTE" && Screen::get() != nullptr) { + // NEXT/PREV primero, luego todos los nombres de paleta disponibles + for (const auto sv : {"NEXT", "PREV"}) { + if (sub_prefix.empty() || std::string_view{sv}.starts_with(sub_prefix)) { + tab_matches_.emplace_back("PALETTE " + std::string(sv)); + } + } + for (const auto& name : Screen::get()->getPaletteNames()) { + if (sub_prefix.empty() || std::string_view{name}.starts_with(sub_prefix)) { + tab_matches_.emplace_back("PALETTE " + name); + } + } + } else { + for (const auto& [keyword, args] : SUB_ARGS) { + if (keyword == base_cmd) { + for (const auto& arg : args) { + if (sub_prefix.empty() || std::string_view{arg}.starts_with(sub_prefix)) { + tab_matches_.emplace_back(std::string(base_cmd) + " " + std::string(arg)); + } + } + break; } - break; } } } diff --git a/source/utils/defines.hpp b/source/utils/defines.hpp index a419165..624cd6e 100644 --- a/source/utils/defines.hpp +++ b/source/utils/defines.hpp @@ -6,7 +6,7 @@ namespace Texts { constexpr const char* WINDOW_CAPTION = "© 2022 JailDoctor's Dilemma — JailDesigner"; constexpr const char* COPYRIGHT = "@2022 JailDesigner"; - constexpr const char* VERSION = "1.10"; // Versión por defecto + constexpr const char* VERSION = "1.11"; // Versión por defecto } // namespace Texts // Tamaño de bloque