From cf1f97a84fc71918a061d71c97b6b4aa7ed614a0 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Fri, 3 Apr 2026 16:30:38 +0200 Subject: [PATCH] Afegides les opcions a Service Menu --- data/lang/ba_BA.json | 5 +- data/lang/en_UK.json | 5 +- data/lang/es_ES.json | 5 +- source/screen.cpp | 18 +++++--- source/ui/menu_option.hpp | 22 +++++++++ source/ui/service_menu.cpp | 94 +++++++++++++++++++++++++++++++++----- 6 files changed, 126 insertions(+), 23 deletions(-) diff --git a/data/lang/ba_BA.json b/data/lang/ba_BA.json index 5387d43..f71d1ea 100644 --- a/data/lang/ba_BA.json +++ b/data/lang/ba_BA.json @@ -79,8 +79,9 @@ "[SERVICE_MENU] SHUTDOWN": "Apagar el sistema", "[SERVICE_MENU] FULLSCREEN": "Pantalla completa", "[SERVICE_MENU] WINDOW_SIZE": "Tamany de la finestra", - "[SERVICE_MENU] POSTFX": "PostFX", - "[SERVICE_MENU] POSTFX_PRESET": "Preset PostFX", + "[SERVICE_MENU] SHADER": "Shader", + "[SERVICE_MENU] SHADER_DISABLED": "Desactivat", + "[SERVICE_MENU] SHADER_PRESET": "Preset", "[SERVICE_MENU] SUPERSAMPLING": "Supermostreig", "[SERVICE_MENU] VSYNC": "Sincronisme vertical", "[SERVICE_MENU] INTEGER_SCALE": "Escalat sencer", diff --git a/data/lang/en_UK.json b/data/lang/en_UK.json index 9d2d655..da5be5e 100644 --- a/data/lang/en_UK.json +++ b/data/lang/en_UK.json @@ -78,8 +78,9 @@ "[SERVICE_MENU] SHUTDOWN": "Shutdown System", "[SERVICE_MENU] FULLSCREEN": "Fullscreen", "[SERVICE_MENU] WINDOW_SIZE": "Window Zoom", - "[SERVICE_MENU] POSTFX": "PostFX", - "[SERVICE_MENU] POSTFX_PRESET": "PostFX Preset", + "[SERVICE_MENU] SHADER": "Shader", + "[SERVICE_MENU] SHADER_DISABLED": "Disabled", + "[SERVICE_MENU] SHADER_PRESET": "Preset", "[SERVICE_MENU] SUPERSAMPLING": "Supersampling", "[SERVICE_MENU] VSYNC": "V-Sync", "[SERVICE_MENU] INTEGER_SCALE": "Integer Scale", diff --git a/data/lang/es_ES.json b/data/lang/es_ES.json index 650ad45..eeb2fd8 100644 --- a/data/lang/es_ES.json +++ b/data/lang/es_ES.json @@ -78,8 +78,9 @@ "[SERVICE_MENU] SHUTDOWN": "Apagar el sistema", "[SERVICE_MENU] FULLSCREEN": "Pantalla completa", "[SERVICE_MENU] WINDOW_SIZE": "Zoom de ventana", - "[SERVICE_MENU] POSTFX": "PostFX", - "[SERVICE_MENU] POSTFX_PRESET": "Preset PostFX", + "[SERVICE_MENU] SHADER": "Shader", + "[SERVICE_MENU] SHADER_DISABLED": "Desactivado", + "[SERVICE_MENU] SHADER_PRESET": "Preset", "[SERVICE_MENU] SUPERSAMPLING": "Supersampling", "[SERVICE_MENU] VSYNC": "Sincronismo vertical", "[SERVICE_MENU] INTEGER_SCALE": "Escalado proporcional", diff --git a/source/screen.cpp b/source/screen.cpp index 2053d08..a439472 100644 --- a/source/screen.cpp +++ b/source/screen.cpp @@ -275,12 +275,18 @@ void Screen::initShaders() { self->shader_backend_->setLinearUpscale(Options::video.supersampling.linear_upscale); self->shader_backend_->setDownscaleAlgo(Options::video.supersampling.downscale_algo); self->shader_backend_->setOversample(Options::video.supersampling.enabled ? 3 : 1); - self->shader_backend_->setActiveShader(Options::video.shader.current_shader); - } - if (Options::video.shader.current_shader == Rendering::ShaderType::CRTPI) { - self->applyCurrentCrtPiPreset(); - } else { - self->applyCurrentPostFXPreset(); + + if (!Options::video.shader.enabled) { + // Passthrough: POSTFX con parámetros a cero + self->shader_backend_->setActiveShader(Rendering::ShaderType::POSTFX); + self->shader_backend_->setPostFXParams(Rendering::PostFXParams{}); + } else if (Options::video.shader.current_shader == Rendering::ShaderType::CRTPI) { + self->shader_backend_->setActiveShader(Rendering::ShaderType::CRTPI); + self->applyCurrentCrtPiPreset(); + } else { + self->shader_backend_->setActiveShader(Rendering::ShaderType::POSTFX); + self->applyCurrentPostFXPreset(); + } } #endif } diff --git a/source/ui/menu_option.hpp b/source/ui/menu_option.hpp index c34e2d1..c78a46c 100644 --- a/source/ui/menu_option.hpp +++ b/source/ui/menu_option.hpp @@ -216,4 +216,26 @@ class ActionListOption : public MenuOption { void updateCurrentIndex(); [[nodiscard]] auto findCurrentIndex() const -> size_t; +}; + +// Opción genérica con callbacks: getter para mostrar, adjuster(bool up) para cambiar valor +class CallbackOption : public MenuOption { + public: + CallbackOption(const std::string& cap, ServiceMenu::SettingsGroup grp, std::function getter, std::function adjuster, std::function max_width_fn = nullptr) + : MenuOption(cap, grp), + getter_(std::move(getter)), + adjuster_(std::move(adjuster)), + max_width_fn_(std::move(max_width_fn)) {} + + [[nodiscard]] auto getBehavior() const -> Behavior override { return Behavior::ADJUST; } + [[nodiscard]] auto getValueAsString() const -> std::string override { return getter_(); } + void adjustValue(bool adjust_up) override { adjuster_(adjust_up); } + auto getMaxValueWidth(Text* text_renderer) const -> int override { + return max_width_fn_ ? max_width_fn_(text_renderer) : 0; + } + + private: + std::function getter_; + std::function adjuster_; + std::function max_width_fn_; }; \ No newline at end of file diff --git a/source/ui/service_menu.cpp b/source/ui/service_menu.cpp index 706eb04..c1d3c68 100644 --- a/source/ui/service_menu.cpp +++ b/source/ui/service_menu.cpp @@ -363,18 +363,76 @@ void ServiceMenu::initializeOptions() { Options::window.max_zoom, 1)); - options_.push_back(std::make_unique( - Lang::getText("[SERVICE_MENU] POSTFX"), - SettingsGroup::VIDEO, - &Options::video.shader.enabled)); + // Shader: Desactivat / PostFX / CrtPi + { + const std::string DISABLED_TEXT = Lang::getText("[SERVICE_MENU] SHADER_DISABLED"); + std::vector shader_values = {DISABLED_TEXT, "PostFX", "CrtPi"}; + auto shader_getter = [DISABLED_TEXT]() -> std::string { + if (!Options::video.shader.enabled) { return DISABLED_TEXT; } + return (Options::video.shader.current_shader == Rendering::ShaderType::CRTPI) ? "CrtPi" : "PostFX"; + }; + auto shader_setter = [DISABLED_TEXT](const std::string& val) { + if (val == DISABLED_TEXT) { + Options::video.shader.enabled = false; + } else { + Options::video.shader.enabled = true; + const auto TYPE = (val == "CrtPi") ? Rendering::ShaderType::CRTPI : Rendering::ShaderType::POSTFX; + Options::video.shader.current_shader = TYPE; + auto* screen = Screen::get(); + if (screen != nullptr) { + screen->applySettings(); + } + } + Screen::initShaders(); + }; + options_.push_back(std::make_unique( + Lang::getText("[SERVICE_MENU] SHADER"), + SettingsGroup::VIDEO, + shader_values, + shader_getter, + shader_setter)); + } - options_.push_back(std::make_unique( - Lang::getText("[SERVICE_MENU] POSTFX_PRESET"), - SettingsGroup::VIDEO, - &Options::video.shader.current_postfx_preset, - 0, - static_cast(Options::postfx_presets.size()) - 1, - 1)); + // Preset: muestra nombre, cicla circularmente entre presets del shader activo + { + auto preset_getter = []() -> std::string { + if (Options::video.shader.current_shader == Rendering::ShaderType::CRTPI) { + if (Options::crtpi_presets.empty()) { return ""; } + return Options::crtpi_presets.at(static_cast(Options::video.shader.current_crtpi_preset)).name; + } + if (Options::postfx_presets.empty()) { return ""; } + return Options::postfx_presets.at(static_cast(Options::video.shader.current_postfx_preset)).name; + }; + auto preset_adjuster = [](bool up) { + if (Options::video.shader.current_shader == Rendering::ShaderType::CRTPI) { + if (Options::crtpi_presets.empty()) { return; } + const int SIZE = static_cast(Options::crtpi_presets.size()); + Options::video.shader.current_crtpi_preset = up + ? (Options::video.shader.current_crtpi_preset + 1) % SIZE + : (Options::video.shader.current_crtpi_preset + SIZE - 1) % SIZE; + } else { + if (Options::postfx_presets.empty()) { return; } + const int SIZE = static_cast(Options::postfx_presets.size()); + Options::video.shader.current_postfx_preset = up + ? (Options::video.shader.current_postfx_preset + 1) % SIZE + : (Options::video.shader.current_postfx_preset + SIZE - 1) % SIZE; + } + Screen::initShaders(); + }; + auto preset_max_width = [](Text* text) -> int { + int max_w = 0; + for (const auto& p : Options::postfx_presets) { max_w = std::max(max_w, text->length(p.name, -2)); } + for (const auto& p : Options::crtpi_presets) { max_w = std::max(max_w, text->length(p.name, -2)); } + return max_w; + }; + + options_.push_back(std::make_unique( + Lang::getText("[SERVICE_MENU] SHADER_PRESET"), + SettingsGroup::VIDEO, + preset_getter, + preset_adjuster, + preset_max_width)); + } options_.push_back(std::make_unique( Lang::getText("[SERVICE_MENU] SUPERSAMPLING"), @@ -569,6 +627,20 @@ void ServiceMenu::setHiddenOptions() { } } + { + auto* option = getOptionByCaption(Lang::getText("[SERVICE_MENU] SHADER_PRESET")); + if (option != nullptr) { + option->setHidden(!Options::video.shader.enabled); + } + } + + { + auto* option = getOptionByCaption(Lang::getText("[SERVICE_MENU] SUPERSAMPLING")); + if (option != nullptr) { + option->setHidden(!Options::video.shader.enabled || Options::video.shader.current_shader != Rendering::ShaderType::POSTFX); + } + } + updateMenu(); // El menú debe refrescarse si algo se oculta }