postfx analític: nou shader + estructures chroma_min/max + scan_*

- Substitueix postfx.frag per la versió analítica amb smoothstep
- PostFXUniforms 12→16 floats (64B, 4×vec4): afegeix chroma_min/max,
  scan_dark_ratio, scan_dark_floor, scan_edge_soft
- PostFXParams i PostFXPreset adopten els nous camps amb defaults d'AEE
- MSL extret a source/core/rendering/sdl3gpu/msl/{postfx_vert,postfx_frag,
  crtpi_frag}.msl.h (estil Rendering::Msl::kXxx)
- SPIR-V regenerat (postfx_frag_spv.h: 13648 bytes)
- options.cpp llegeix 'chroma' antic com compat (assigna a min i max);
  escriu els 6 presets per defecte (CRT/NTSC/CURVED/SCANLINES/SUBTLE/CRT LIVE)
  amb els valors d'aee_arcade

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-17 20:32:34 +02:00
parent 743d8c7877
commit 5e6a469d46
26 changed files with 10111 additions and 13608 deletions
-76
View File
@@ -54,81 +54,6 @@ static auto boolToggle(
// ── Command handlers ─────────────────────────────────────────────────────────
// SS [ON|OFF|SIZE|UPSCALE [NEAREST|LINEAR]|DOWNSCALE [BILINEAR|LANCZOS2|LANCZOS3]]
// SS SIZE — dimensions de la textura supersampling activa
static auto cmdSsSize() -> std::string {
if (!Options::video.supersampling.enabled) { return "Supersampling is OFF: no texture"; }
const auto [w, h] = Screen::get()->getSsTextureSize();
if (w == 0) { return "SS texture: not active"; }
return "SS texture: " + std::to_string(w) + "x" + std::to_string(h);
}
// SS UPSCALE [NEAREST|LINEAR] — toggle o estableix mode upscale
static auto cmdSsUpscale(const std::vector<std::string>& args) -> std::string {
if (args.size() == 1) {
Screen::get()->setLinearUpscale(!Options::video.supersampling.linear_upscale);
return std::string("Upscale: ") + (Options::video.supersampling.linear_upscale ? "Linear" : "Nearest");
}
if (args[1] == "NEAREST") {
if (!Options::video.supersampling.linear_upscale) { return "Upscale already Nearest"; }
Screen::get()->setLinearUpscale(false);
return "Upscale: Nearest";
}
if (args[1] == "LINEAR") {
if (Options::video.supersampling.linear_upscale) { return "Upscale already Linear"; }
Screen::get()->setLinearUpscale(true);
return "Upscale: Linear";
}
return "usage: ss upscale [nearest|linear]";
}
// SS DOWNSCALE [BILINEAR|LANCZOS2|LANCZOS3] — consulta o estableix algorisme
static auto cmdSsDownscale(const std::vector<std::string>& args) -> std::string {
static const std::array<std::string_view, 3> DOWNSCALE_NAMES = {"Bilinear", "Lanczos2", "Lanczos3"};
if (args.size() == 1) {
return std::string("Downscale: ") + std::string(DOWNSCALE_NAMES[static_cast<size_t>(Options::video.supersampling.downscale_algo)]);
}
int algo = -1;
if (args[1] == "BILINEAR") { algo = 0; }
if (args[1] == "LANCZOS2") { algo = 1; }
if (args[1] == "LANCZOS3") { algo = 2; }
if (algo == -1) { return "usage: ss downscale [bilinear|lanczos2|lanczos3]"; }
if (Options::video.supersampling.downscale_algo == algo) {
return std::string("Downscale already ") + std::string(DOWNSCALE_NAMES[static_cast<size_t>(algo)]);
}
Screen::get()->setDownscaleAlgo(algo);
return std::string("Downscale: ") + std::string(DOWNSCALE_NAMES[static_cast<size_t>(algo)]);
}
// SS ON — activa supersampling si encara no ho està
static auto cmdSsOn() -> std::string {
if (Options::video.supersampling.enabled) { return "Supersampling already ON"; }
Screen::get()->toggleSupersampling();
return "PostFX Supersampling ON";
}
// SS OFF — desactiva supersampling si encara està actiu
static auto cmdSsOff() -> std::string {
if (!Options::video.supersampling.enabled) { return "Supersampling already OFF"; }
Screen::get()->toggleSupersampling();
return "PostFX Supersampling OFF";
}
// SS — toggle (sense args) o dispatch a subcomandes
static auto cmdSs(const std::vector<std::string>& args) -> std::string {
if (!Screen::get()->isHardwareAccelerated()) { return "No GPU acceleration"; }
if (args.empty()) {
Screen::get()->toggleSupersampling();
return std::string("PostFX Supersampling ") + (Options::video.supersampling.enabled ? "ON" : "OFF");
}
if (args[0] == "SIZE") { return cmdSsSize(); }
if (args[0] == "UPSCALE") { return cmdSsUpscale(args); }
if (args[0] == "DOWNSCALE") { return cmdSsDownscale(args); }
if (args[0] == "ON") { return cmdSsOn(); }
if (args[0] == "OFF") { return cmdSsOff(); }
return "usage: ss [on|off|size|upscale [nearest|linear]|downscale [bilinear|lanczos2|lanczos3]]";
}
// Helper: aplica un preset por dirección (NEXT/PREV) o nombre; devuelve mensaje
static auto applyPreset(const std::vector<std::string>& args) -> std::string {
const bool IS_CRTPI = Options::video.shader.current_shader == Rendering::ShaderType::CRTPI;
@@ -990,7 +915,6 @@ static auto cmdSize(const std::vector<std::string>& /*unused*/) -> std::string {
// ── CommandRegistry ──────────────────────────────────────────────────────────
void CommandRegistry::registerHandlers() {
handlers_["cmd_ss"] = cmdSs;
handlers_["cmd_shader"] = cmdShader;
handlers_["cmd_border"] = cmdBorder;
handlers_["cmd_fullscreen"] = cmdFullscreen;