From a36662ac6ed184ecfdeaf4439c4f68f7ce9dddcb Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Thu, 16 Apr 2026 19:26:45 +0200 Subject: [PATCH] fix: shaders on i off no afectaven a crtpi --- source/core/input/global_inputs.cpp | 23 +++++++------ source/core/rendering/screen.cpp | 53 +++++++++++++++++++++-------- source/core/rendering/screen.hpp | 18 ++++++---- 3 files changed, 62 insertions(+), 32 deletions(-) diff --git a/source/core/input/global_inputs.cpp b/source/core/input/global_inputs.cpp index a8083a1..faa779e 100644 --- a/source/core/input/global_inputs.cpp +++ b/source/core/input/global_inputs.cpp @@ -78,8 +78,9 @@ namespace GlobalInputs { // F6 — Toggle supersampling bool ss = JI_KeyPressed(KeyConfig::scancode("toggle_supersampling")); if (ss && !ss_prev) { - Screen::get()->toggleSupersampling(); - Overlay::showNotification(Options::video.supersampling ? Locale::get("notifications.ss_on") : Locale::get("notifications.ss_off")); + if (Screen::get()->toggleSupersampling()) { + Overlay::showNotification(Options::video.supersampling ? Locale::get("notifications.ss_on") : Locale::get("notifications.ss_off")); + } } if (ss) consumed = true; ss_prev = ss; @@ -87,10 +88,11 @@ namespace GlobalInputs { // F7 — Canviar tipus de shader (PostFX ↔ CrtPi) bool next_shader = JI_KeyPressed(KeyConfig::scancode("next_shader")); if (next_shader && !next_shader_prev) { - Screen::get()->nextShaderType(); - char msg[64]; - snprintf(msg, sizeof(msg), "%s: %s", Screen::get()->getActiveShaderName(), Screen::get()->getCurrentPresetName()); - Overlay::showNotification(msg); + if (Screen::get()->nextShaderType()) { + char msg[64]; + snprintf(msg, sizeof(msg), "%s: %s", Screen::get()->getActiveShaderName(), Screen::get()->getCurrentPresetName()); + Overlay::showNotification(msg); + } } if (next_shader) consumed = true; next_shader_prev = next_shader; @@ -98,10 +100,11 @@ namespace GlobalInputs { // F8 — Pròxim preset del shader actiu bool next_preset = JI_KeyPressed(KeyConfig::scancode("next_shader_preset")); if (next_preset && !next_preset_prev) { - Screen::get()->nextPreset(); - char msg[64]; - snprintf(msg, sizeof(msg), Locale::get("notifications.preset_fmt"), Screen::get()->getCurrentPresetName()); - Overlay::showNotification(msg); + if (Screen::get()->nextPreset()) { + char msg[64]; + snprintf(msg, sizeof(msg), Locale::get("notifications.preset_fmt"), Screen::get()->getCurrentPresetName()); + Overlay::showNotification(msg); + } } if (next_preset) consumed = true; next_preset_prev = next_preset; diff --git a/source/core/rendering/screen.cpp b/source/core/rendering/screen.cpp index 88a2d3a..8e9096e 100644 --- a/source/core/rendering/screen.cpp +++ b/source/core/rendering/screen.cpp @@ -145,11 +145,22 @@ void Screen::present(Uint32* pixel_data) { shader_backend_->uploadPixels(pixel_data, GAME_WIDTH, GAME_HEIGHT); shader_backend_->render(); } else if (shader_backend_ && shader_backend_->isHardwareAccelerated()) { - // GPU activa però shaders desactivats: renderitza net (sense efectes) + // GPU activa però shaders desactivats: renderitza net (sense efectes). + // Força POSTFX amb params zerats — altrament, si l'actiu és CRTPI, + // els seus efectes (scanlines, curvatura) seguirien aplicant-se encara + // que shader_enabled sigui false. Restaurem l'actiu al final per a + // no trencar la selecció de l'usuari. Rendering::PostFXParams clean{}; shader_backend_->setPostFXParams(clean); + const auto prev_shader = shader_backend_->getActiveShader(); + if (prev_shader != Rendering::ShaderType::POSTFX) { + shader_backend_->setActiveShader(Rendering::ShaderType::POSTFX); + } shader_backend_->uploadPixels(pixel_data, GAME_WIDTH, GAME_HEIGHT); shader_backend_->render(); + if (prev_shader != Rendering::ShaderType::POSTFX) { + shader_backend_->setActiveShader(prev_shader); + } } else { // Fallback SDL_Renderer SDL_UpdateTexture(texture_, nullptr, pixel_data, GAME_WIDTH * sizeof(Uint32)); @@ -192,10 +203,16 @@ void Screen::toggleShaders() { } } -void Screen::toggleSupersampling() { - if (!shader_backend_ || !shader_backend_->isHardwareAccelerated()) return; +auto Screen::toggleSupersampling() -> bool { + // SS només té sentit amb shaders on i pipeline PostFX (el Lanczos downscale + // i el camí SS s'apliquen al pas de PostFX; CRTPI fa el seu propi + // submostreig intern i no usa aquesta via). + if (!shader_backend_ || !shader_backend_->isHardwareAccelerated()) return false; + if (!Options::video.shader_enabled) return false; + if (shader_backend_->getActiveShader() != Rendering::ShaderType::POSTFX) return false; Options::video.supersampling = !Options::video.supersampling; shader_backend_->setOversample(Options::video.supersampling ? 3 : 1); + return true; } void Screen::toggleAspectRatio() { @@ -244,8 +261,9 @@ void Screen::cycleTextureFilter(int dir) { } } -void Screen::nextShaderType() { - if (!shader_backend_ || !shader_backend_->isHardwareAccelerated()) return; +auto Screen::nextShaderType() -> bool { + if (!shader_backend_ || !shader_backend_->isHardwareAccelerated()) return false; + if (!Options::video.shader_enabled) return false; if (shader_backend_->getActiveShader() == Rendering::ShaderType::POSTFX) { shader_backend_->setActiveShader(Rendering::ShaderType::CRTPI); @@ -256,45 +274,50 @@ void Screen::nextShaderType() { Options::video.current_shader = "postfx"; applyCurrentPostFXPreset(); } + return true; } -void Screen::nextPreset() { - if (!shader_backend_ || !shader_backend_->isHardwareAccelerated()) return; +auto Screen::nextPreset() -> bool { + if (!shader_backend_ || !shader_backend_->isHardwareAccelerated()) return false; + if (!Options::video.shader_enabled) return false; if (shader_backend_->getActiveShader() == Rendering::ShaderType::POSTFX) { - if (Options::postfx_presets.empty()) return; + if (Options::postfx_presets.empty()) return false; Options::current_postfx_preset = (Options::current_postfx_preset + 1) % static_cast(Options::postfx_presets.size()); Options::video.current_postfx_preset = Options::postfx_presets[Options::current_postfx_preset].name; applyCurrentPostFXPreset(); } else { - if (Options::crtpi_presets.empty()) return; + if (Options::crtpi_presets.empty()) return false; Options::current_crtpi_preset = (Options::current_crtpi_preset + 1) % static_cast(Options::crtpi_presets.size()); Options::video.current_crtpi_preset = Options::crtpi_presets[Options::current_crtpi_preset].name; applyCurrentCrtPiPreset(); } + return true; } -void Screen::prevShaderType() { +auto Screen::prevShaderType() -> bool { // Només dues opcions — prev == next - nextShaderType(); + return nextShaderType(); } -void Screen::prevPreset() { - if (!shader_backend_ || !shader_backend_->isHardwareAccelerated()) return; +auto Screen::prevPreset() -> bool { + if (!shader_backend_ || !shader_backend_->isHardwareAccelerated()) return false; + if (!Options::video.shader_enabled) return false; if (shader_backend_->getActiveShader() == Rendering::ShaderType::POSTFX) { - if (Options::postfx_presets.empty()) return; + if (Options::postfx_presets.empty()) return false; int n = static_cast(Options::postfx_presets.size()); Options::current_postfx_preset = (Options::current_postfx_preset - 1 + n) % n; Options::video.current_postfx_preset = Options::postfx_presets[Options::current_postfx_preset].name; applyCurrentPostFXPreset(); } else { - if (Options::crtpi_presets.empty()) return; + if (Options::crtpi_presets.empty()) return false; int n = static_cast(Options::crtpi_presets.size()); Options::current_crtpi_preset = (Options::current_crtpi_preset - 1 + n) % n; Options::video.current_crtpi_preset = Options::crtpi_presets[Options::current_crtpi_preset].name; applyCurrentCrtPiPreset(); } + return true; } auto Screen::getCurrentPresetName() const -> const char* { diff --git a/source/core/rendering/screen.hpp b/source/core/rendering/screen.hpp index e472ec3..40cd48c 100644 --- a/source/core/rendering/screen.hpp +++ b/source/core/rendering/screen.hpp @@ -23,16 +23,20 @@ class Screen { void setZoom(int zoom); // Shaders i vídeo + // Mètodes que depenen d'una precondició (GPU present, shaders on, etc.) + // retornen `bool`: true si l'acció s'ha aplicat, false si la precondició + // no es complia. Els callers (F-keys, menú) poden suprimir notificacions + // o feedback quan la crida no ha tingut efecte. void toggleShaders(); - void toggleSupersampling(); + auto toggleSupersampling() -> bool; // false si GPU off / shaders off / actiu != POSTFX void toggleAspectRatio(); - void cycleScalingMode(int dir); // Cicla DISABLED/STRETCH/LETTERBOX/OVERSCAN/INTEGER + void cycleScalingMode(int dir); // Cicla DISABLED/STRETCH/LETTERBOX/OVERSCAN/INTEGER void toggleVSync(); - void cycleTextureFilter(int dir); // Cicla NEAREST/LINEAR - void nextShaderType(); // Cicla PostFX ↔ CrtPi (F7) - void prevShaderType(); // Cicla al revés - void nextPreset(); // Cicla presets del shader actiu (F8) - void prevPreset(); // Cicla presets al revés + void cycleTextureFilter(int dir); // Cicla NEAREST/LINEAR + auto nextShaderType() -> bool; // false si GPU off / shaders off + auto prevShaderType() -> bool; // idem + auto nextPreset() -> bool; // false si GPU off / shaders off + auto prevPreset() -> bool; // idem [[nodiscard]] auto getCurrentPresetName() const -> const char*; void setActiveShader(Rendering::ShaderType type); void applyCurrentPostFXPreset();