fix: shaders on i off no afectaven a crtpi

This commit is contained in:
2026-04-16 19:26:45 +02:00
parent 52431adb0e
commit a36662ac6e
3 changed files with 62 additions and 32 deletions

View File

@@ -78,8 +78,9 @@ namespace GlobalInputs {
// F6 — Toggle supersampling // F6 — Toggle supersampling
bool ss = JI_KeyPressed(KeyConfig::scancode("toggle_supersampling")); bool ss = JI_KeyPressed(KeyConfig::scancode("toggle_supersampling"));
if (ss && !ss_prev) { if (ss && !ss_prev) {
Screen::get()->toggleSupersampling(); if (Screen::get()->toggleSupersampling()) {
Overlay::showNotification(Options::video.supersampling ? Locale::get("notifications.ss_on") : Locale::get("notifications.ss_off")); Overlay::showNotification(Options::video.supersampling ? Locale::get("notifications.ss_on") : Locale::get("notifications.ss_off"));
}
} }
if (ss) consumed = true; if (ss) consumed = true;
ss_prev = ss; ss_prev = ss;
@@ -87,10 +88,11 @@ namespace GlobalInputs {
// F7 — Canviar tipus de shader (PostFX ↔ CrtPi) // F7 — Canviar tipus de shader (PostFX ↔ CrtPi)
bool next_shader = JI_KeyPressed(KeyConfig::scancode("next_shader")); bool next_shader = JI_KeyPressed(KeyConfig::scancode("next_shader"));
if (next_shader && !next_shader_prev) { if (next_shader && !next_shader_prev) {
Screen::get()->nextShaderType(); if (Screen::get()->nextShaderType()) {
char msg[64]; char msg[64];
snprintf(msg, sizeof(msg), "%s: %s", Screen::get()->getActiveShaderName(), Screen::get()->getCurrentPresetName()); snprintf(msg, sizeof(msg), "%s: %s", Screen::get()->getActiveShaderName(), Screen::get()->getCurrentPresetName());
Overlay::showNotification(msg); Overlay::showNotification(msg);
}
} }
if (next_shader) consumed = true; if (next_shader) consumed = true;
next_shader_prev = next_shader; next_shader_prev = next_shader;
@@ -98,10 +100,11 @@ namespace GlobalInputs {
// F8 — Pròxim preset del shader actiu // F8 — Pròxim preset del shader actiu
bool next_preset = JI_KeyPressed(KeyConfig::scancode("next_shader_preset")); bool next_preset = JI_KeyPressed(KeyConfig::scancode("next_shader_preset"));
if (next_preset && !next_preset_prev) { if (next_preset && !next_preset_prev) {
Screen::get()->nextPreset(); if (Screen::get()->nextPreset()) {
char msg[64]; char msg[64];
snprintf(msg, sizeof(msg), Locale::get("notifications.preset_fmt"), Screen::get()->getCurrentPresetName()); snprintf(msg, sizeof(msg), Locale::get("notifications.preset_fmt"), Screen::get()->getCurrentPresetName());
Overlay::showNotification(msg); Overlay::showNotification(msg);
}
} }
if (next_preset) consumed = true; if (next_preset) consumed = true;
next_preset_prev = next_preset; next_preset_prev = next_preset;

View File

@@ -145,11 +145,22 @@ void Screen::present(Uint32* pixel_data) {
shader_backend_->uploadPixels(pixel_data, GAME_WIDTH, GAME_HEIGHT); shader_backend_->uploadPixels(pixel_data, GAME_WIDTH, GAME_HEIGHT);
shader_backend_->render(); shader_backend_->render();
} else if (shader_backend_ && shader_backend_->isHardwareAccelerated()) { } 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{}; Rendering::PostFXParams clean{};
shader_backend_->setPostFXParams(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_->uploadPixels(pixel_data, GAME_WIDTH, GAME_HEIGHT);
shader_backend_->render(); shader_backend_->render();
if (prev_shader != Rendering::ShaderType::POSTFX) {
shader_backend_->setActiveShader(prev_shader);
}
} else { } else {
// Fallback SDL_Renderer // Fallback SDL_Renderer
SDL_UpdateTexture(texture_, nullptr, pixel_data, GAME_WIDTH * sizeof(Uint32)); SDL_UpdateTexture(texture_, nullptr, pixel_data, GAME_WIDTH * sizeof(Uint32));
@@ -192,10 +203,16 @@ void Screen::toggleShaders() {
} }
} }
void Screen::toggleSupersampling() { auto Screen::toggleSupersampling() -> bool {
if (!shader_backend_ || !shader_backend_->isHardwareAccelerated()) return; // 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; Options::video.supersampling = !Options::video.supersampling;
shader_backend_->setOversample(Options::video.supersampling ? 3 : 1); shader_backend_->setOversample(Options::video.supersampling ? 3 : 1);
return true;
} }
void Screen::toggleAspectRatio() { void Screen::toggleAspectRatio() {
@@ -244,8 +261,9 @@ void Screen::cycleTextureFilter(int dir) {
} }
} }
void Screen::nextShaderType() { auto Screen::nextShaderType() -> bool {
if (!shader_backend_ || !shader_backend_->isHardwareAccelerated()) return; if (!shader_backend_ || !shader_backend_->isHardwareAccelerated()) return false;
if (!Options::video.shader_enabled) return false;
if (shader_backend_->getActiveShader() == Rendering::ShaderType::POSTFX) { if (shader_backend_->getActiveShader() == Rendering::ShaderType::POSTFX) {
shader_backend_->setActiveShader(Rendering::ShaderType::CRTPI); shader_backend_->setActiveShader(Rendering::ShaderType::CRTPI);
@@ -256,45 +274,50 @@ void Screen::nextShaderType() {
Options::video.current_shader = "postfx"; Options::video.current_shader = "postfx";
applyCurrentPostFXPreset(); applyCurrentPostFXPreset();
} }
return true;
} }
void Screen::nextPreset() { auto Screen::nextPreset() -> bool {
if (!shader_backend_ || !shader_backend_->isHardwareAccelerated()) return; if (!shader_backend_ || !shader_backend_->isHardwareAccelerated()) return false;
if (!Options::video.shader_enabled) return false;
if (shader_backend_->getActiveShader() == Rendering::ShaderType::POSTFX) { 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<int>(Options::postfx_presets.size()); Options::current_postfx_preset = (Options::current_postfx_preset + 1) % static_cast<int>(Options::postfx_presets.size());
Options::video.current_postfx_preset = Options::postfx_presets[Options::current_postfx_preset].name; Options::video.current_postfx_preset = Options::postfx_presets[Options::current_postfx_preset].name;
applyCurrentPostFXPreset(); applyCurrentPostFXPreset();
} else { } 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<int>(Options::crtpi_presets.size()); Options::current_crtpi_preset = (Options::current_crtpi_preset + 1) % static_cast<int>(Options::crtpi_presets.size());
Options::video.current_crtpi_preset = Options::crtpi_presets[Options::current_crtpi_preset].name; Options::video.current_crtpi_preset = Options::crtpi_presets[Options::current_crtpi_preset].name;
applyCurrentCrtPiPreset(); applyCurrentCrtPiPreset();
} }
return true;
} }
void Screen::prevShaderType() { auto Screen::prevShaderType() -> bool {
// Només dues opcions — prev == next // Només dues opcions — prev == next
nextShaderType(); return nextShaderType();
} }
void Screen::prevPreset() { auto Screen::prevPreset() -> bool {
if (!shader_backend_ || !shader_backend_->isHardwareAccelerated()) return; if (!shader_backend_ || !shader_backend_->isHardwareAccelerated()) return false;
if (!Options::video.shader_enabled) return false;
if (shader_backend_->getActiveShader() == Rendering::ShaderType::POSTFX) { if (shader_backend_->getActiveShader() == Rendering::ShaderType::POSTFX) {
if (Options::postfx_presets.empty()) return; if (Options::postfx_presets.empty()) return false;
int n = static_cast<int>(Options::postfx_presets.size()); int n = static_cast<int>(Options::postfx_presets.size());
Options::current_postfx_preset = (Options::current_postfx_preset - 1 + n) % n; Options::current_postfx_preset = (Options::current_postfx_preset - 1 + n) % n;
Options::video.current_postfx_preset = Options::postfx_presets[Options::current_postfx_preset].name; Options::video.current_postfx_preset = Options::postfx_presets[Options::current_postfx_preset].name;
applyCurrentPostFXPreset(); applyCurrentPostFXPreset();
} else { } else {
if (Options::crtpi_presets.empty()) return; if (Options::crtpi_presets.empty()) return false;
int n = static_cast<int>(Options::crtpi_presets.size()); int n = static_cast<int>(Options::crtpi_presets.size());
Options::current_crtpi_preset = (Options::current_crtpi_preset - 1 + n) % n; Options::current_crtpi_preset = (Options::current_crtpi_preset - 1 + n) % n;
Options::video.current_crtpi_preset = Options::crtpi_presets[Options::current_crtpi_preset].name; Options::video.current_crtpi_preset = Options::crtpi_presets[Options::current_crtpi_preset].name;
applyCurrentCrtPiPreset(); applyCurrentCrtPiPreset();
} }
return true;
} }
auto Screen::getCurrentPresetName() const -> const char* { auto Screen::getCurrentPresetName() const -> const char* {

View File

@@ -23,16 +23,20 @@ class Screen {
void setZoom(int zoom); void setZoom(int zoom);
// Shaders i vídeo // 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 toggleShaders();
void toggleSupersampling(); auto toggleSupersampling() -> bool; // false si GPU off / shaders off / actiu != POSTFX
void toggleAspectRatio(); 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 toggleVSync();
void cycleTextureFilter(int dir); // Cicla NEAREST/LINEAR void cycleTextureFilter(int dir); // Cicla NEAREST/LINEAR
void nextShaderType(); // Cicla PostFX ↔ CrtPi (F7) auto nextShaderType() -> bool; // false si GPU off / shaders off
void prevShaderType(); // Cicla al revés auto prevShaderType() -> bool; // idem
void nextPreset(); // Cicla presets del shader actiu (F8) auto nextPreset() -> bool; // false si GPU off / shaders off
void prevPreset(); // Cicla presets al revés auto prevPreset() -> bool; // idem
[[nodiscard]] auto getCurrentPresetName() const -> const char*; [[nodiscard]] auto getCurrentPresetName() const -> const char*;
void setActiveShader(Rendering::ShaderType type); void setActiveShader(Rendering::ShaderType type);
void applyCurrentPostFXPreset(); void applyCurrentPostFXPreset();