PostFXParams/Preset amb chroma_min/max + scan_*; presets AEE migrats
This commit is contained in:
@@ -179,12 +179,6 @@ void Screen::initShaders() {
|
||||
shader_backend_->setVSync(Options::video.vsync);
|
||||
shader_backend_->setTextureFilter(Options::video.texture_filter);
|
||||
shader_backend_->setStretch43(Options::video.aspect_ratio_4_3);
|
||||
shader_backend_->setDownscaleAlgo(Options::video.downscale_algo);
|
||||
|
||||
if (Options::video.supersampling) {
|
||||
shader_backend_->setOversample(3);
|
||||
}
|
||||
|
||||
shader_backend_->setInternalResolution(Options::video.internal_resolution);
|
||||
|
||||
// Resol el shader actiu des del config
|
||||
@@ -325,24 +319,6 @@ void Screen::toggleShaders() {
|
||||
}
|
||||
}
|
||||
|
||||
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() {
|
||||
Options::video.aspect_ratio_4_3 = !Options::video.aspect_ratio_4_3;
|
||||
if (shader_backend_) {
|
||||
@@ -516,12 +492,16 @@ void Screen::applyCurrentPostFXPreset() {
|
||||
Rendering::PostFXParams p;
|
||||
p.vignette = preset.vignette;
|
||||
p.scanlines = preset.scanlines;
|
||||
p.chroma = preset.chroma;
|
||||
p.chroma_min = preset.chroma_min;
|
||||
p.chroma_max = preset.chroma_max;
|
||||
p.mask = preset.mask;
|
||||
p.gamma = preset.gamma;
|
||||
p.curvature = preset.curvature;
|
||||
p.bleeding = preset.bleeding;
|
||||
p.flicker = preset.flicker;
|
||||
p.scan_dark_ratio = preset.scan_dark_ratio;
|
||||
p.scan_dark_floor = preset.scan_dark_floor;
|
||||
p.scan_edge_soft = preset.scan_edge_soft;
|
||||
shader_backend_->setPostFXParams(p);
|
||||
}
|
||||
|
||||
@@ -572,10 +552,7 @@ void Screen::updateRenderInfo() {
|
||||
shader_seg = " - " + toLower(getActiveShaderName()) + " " + toLower(getCurrentPresetName());
|
||||
}
|
||||
|
||||
// Segment 2: supersampling indicator
|
||||
const char* ss_seg = (Options::video.shader_enabled && Options::video.supersampling) ? " (ss)" : nullptr;
|
||||
|
||||
// Segment 3: hora (només si show_time)
|
||||
// Segment 2: hora (només si show_time)
|
||||
char time_buf[32] = {0};
|
||||
if (Options::render_info.show_time) {
|
||||
Uint32 elapsed = SDL_GetTicks() - START_TICKS;
|
||||
@@ -585,14 +562,14 @@ void Screen::updateRenderInfo() {
|
||||
snprintf(time_buf, sizeof(time_buf), " - %d:%02d.%02d", minutes, seconds, centis);
|
||||
}
|
||||
|
||||
// Dígits en mono a FPS (segment 0) i TEMPS (segment 3): els dígits canvien
|
||||
// Dígits en mono a FPS (segment 0) i TEMPS (segment 2): els dígits canvien
|
||||
// contínuament mentre els símbols del voltant ("fps", ":", ".", " - ") no
|
||||
Overlay::setRenderInfoSegments(
|
||||
fps_driver.c_str(),
|
||||
shader_seg.empty() ? nullptr : shader_seg.c_str(),
|
||||
ss_seg,
|
||||
(time_buf[0] != 0) ? time_buf : nullptr,
|
||||
0b1001);
|
||||
nullptr,
|
||||
0b0101);
|
||||
}
|
||||
|
||||
void Screen::applyFallbackPresentation() {
|
||||
|
||||
@@ -7,20 +7,28 @@
|
||||
|
||||
// PostFX uniforms pushed to fragment stage each frame.
|
||||
// Must match the MSL struct and GLSL uniform block layout.
|
||||
// 12 floats = 48 bytes — meets Metal/Vulkan 16-byte alignment requirement.
|
||||
// 16 floats = 64 bytes (4 × vec4) — meets Metal/Vulkan 16-byte alignment.
|
||||
struct PostFXUniforms {
|
||||
// vec4 #0
|
||||
float vignette_strength; // 0 = none, ~0.8 = subtle
|
||||
float chroma_strength; // 0 = off, ~0.2 = subtle chromatic aberration
|
||||
float chroma_min; // aberració cromàtica mínima (sempre present)
|
||||
float scanline_strength; // 0 = off, 1 = full
|
||||
float screen_height; // logical height in pixels (used by bleeding effect)
|
||||
float mask_strength; // 0 = off, 1 = full phosphor dot mask
|
||||
float gamma_strength; // 0 = off, 1 = full gamma 2.4/2.2 correction
|
||||
float curvature; // 0 = flat, 1 = max barrel distortion
|
||||
float bleeding; // 0 = off, 1 = max NTSC chrominance bleeding
|
||||
float pixel_scale; // physical pixels per logical pixel (vh / tex_height_)
|
||||
float time; // seconds since SDL init (SDL_GetTicks() / 1000.0f)
|
||||
float oversample; // supersampling factor (1.0 = off, 3.0 = 3×SS)
|
||||
float flicker; // 0 = off, 1 = phosphor flicker ~50 Hz — keep struct at 48 bytes (3 × 16)
|
||||
// vec4 #1
|
||||
float mask_strength; // 0 = off, 1 = full phosphor dot mask
|
||||
float gamma_strength; // 0 = off, 1 = full gamma 2.4/2.2 correction
|
||||
float curvature; // 0 = flat, 1 = max barrel distortion
|
||||
float bleeding; // 0 = off, 1 = max NTSC chrominance bleeding
|
||||
// vec4 #2
|
||||
float pixel_scale; // physical pixels per logical pixel (vh / tex_height_)
|
||||
float time; // seconds since SDL init (SDL_GetTicks() / 1000.0f)
|
||||
float flicker; // 0 = off, 1 = phosphor flicker ~50 Hz
|
||||
float chroma_max; // si == chroma_min queda estàtic; si != pulsa sinusoidalment
|
||||
// vec4 #3 — paràmetres de forma de les scanlines (exposats per preset)
|
||||
float scan_dark_ratio; // fracció de subfila fosca (1/3 = 0.333 per defecte)
|
||||
float scan_dark_floor; // brillantor de la subfila fosca (0.42 per defecte)
|
||||
float scan_edge_soft; // suavitzat de la transició (0 = step dur, 1 = 1px físic)
|
||||
float pad3;
|
||||
};
|
||||
|
||||
// CrtPi uniforms pushed to fragment stage each frame.
|
||||
@@ -49,15 +57,6 @@ struct CrtPiUniforms {
|
||||
float texture_height; // Alto del canvas en píxeles (inyectado en render)
|
||||
};
|
||||
|
||||
// Downscale uniforms pushed to the Lanczos downscale fragment stage.
|
||||
// 1 int + 3 floats = 16 bytes — meets Metal/Vulkan alignment.
|
||||
struct DownscaleUniforms {
|
||||
int algorithm; // 0 = Lanczos2 (ventana 2), 1 = Lanczos3 (ventana 3)
|
||||
float pad0;
|
||||
float pad1;
|
||||
float pad2;
|
||||
};
|
||||
|
||||
namespace Rendering {
|
||||
|
||||
/**
|
||||
@@ -99,15 +98,6 @@ namespace Rendering {
|
||||
// Selecciona el mode de presentació lògica (DISABLED/STRETCH/LETTERBOX/OVERSCAN/INTEGER)
|
||||
void setScalingMode(Options::ScalingMode mode) override;
|
||||
|
||||
// Establece factor de supersampling (1 = off, 3 = 3×SS)
|
||||
void setOversample(int factor) override;
|
||||
|
||||
// Selecciona algoritmo de downscale: 0=bilinear legacy, 1=Lanczos2, 2=Lanczos3
|
||||
void setDownscaleAlgo(int algo) override;
|
||||
|
||||
// Devuelve las dimensiones de la textura de supersampling (0,0 si SS desactivado)
|
||||
[[nodiscard]] auto getSsTextureSize() const -> std::pair<int, int> override;
|
||||
|
||||
// Selecciona el shader de post-procesado activo (POSTFX o CRTPI)
|
||||
void setActiveShader(ShaderType type) override;
|
||||
|
||||
@@ -146,39 +136,30 @@ namespace Rendering {
|
||||
Uint32 num_uniform_buffers) -> SDL_GPUShader*;
|
||||
|
||||
auto createPipeline() -> bool;
|
||||
auto createCrtPiPipeline() -> bool; // Pipeline dedicado para el shader CrtPi
|
||||
auto reinitTexturesAndBuffer() -> bool; // Recrea scene_texture_ y upload_buffer_
|
||||
auto recreateScaledTexture(int factor) -> bool; // Recrea scaled_texture_ para factor dado
|
||||
auto recreateInternalTexture() -> bool; // Recrea internal_texture_ (res interna × N)
|
||||
static auto calcSsFactor(float zoom) -> int; // Primer múltiplo de 3 >= zoom (mín 3)
|
||||
auto createCrtPiPipeline() -> bool; // Pipeline dedicado para el shader CrtPi
|
||||
auto reinitTexturesAndBuffer() -> bool; // Recrea scene_texture_ y upload_buffer_
|
||||
auto recreateInternalTexture() -> bool; // Recrea internal_texture_ (res interna × N)
|
||||
// Devuelve el mejor present mode disponible: IMMEDIATE > MAILBOX > VSYNC
|
||||
[[nodiscard]] auto bestPresentMode(bool vsync) const -> SDL_GPUPresentMode;
|
||||
|
||||
SDL_Window* window_ = nullptr;
|
||||
SDL_GPUDevice* device_ = nullptr;
|
||||
SDL_GPUGraphicsPipeline* pipeline_ = nullptr; // PostFX pass (→ swapchain o → postfx_texture_)
|
||||
SDL_GPUGraphicsPipeline* crtpi_pipeline_ = nullptr; // CrtPi pass (→ swapchain directo, sin SS)
|
||||
SDL_GPUGraphicsPipeline* postfx_offscreen_pipeline_ = nullptr; // PostFX → postfx_texture_ (B8G8R8A8, solo con Lanczos)
|
||||
SDL_GPUGraphicsPipeline* upscale_pipeline_ = nullptr; // Upscale pass (solo con SS)
|
||||
SDL_GPUGraphicsPipeline* downscale_pipeline_ = nullptr; // Lanczos downscale (solo con SS + algo > 0)
|
||||
SDL_GPUTexture* scene_texture_ = nullptr; // Canvas del joc (game_width_ × game_height_)
|
||||
SDL_GPUTexture* internal_texture_ = nullptr; // Resolució interna ampliada (game·N × game·N), si N>1
|
||||
SDL_GPUTexture* scaled_texture_ = nullptr; // Upscale target (game×factor, amb 4:3 si actiu)
|
||||
SDL_GPUTexture* postfx_texture_ = nullptr; // PostFX output a resolució escalada, sols amb Lanczos
|
||||
SDL_GPUGraphicsPipeline* pipeline_ = nullptr; // PostFX pass → swapchain
|
||||
SDL_GPUGraphicsPipeline* crtpi_pipeline_ = nullptr; // CrtPi pass → swapchain
|
||||
SDL_GPUGraphicsPipeline* upscale_pipeline_ = nullptr; // Upscale per al pas de resolució interna
|
||||
SDL_GPUTexture* scene_texture_ = nullptr; // Canvas del joc (game_width_ × game_height_)
|
||||
SDL_GPUTexture* internal_texture_ = nullptr; // Resolució interna ampliada (game·N × game·N), si N>1
|
||||
SDL_GPUTransferBuffer* upload_buffer_ = nullptr;
|
||||
SDL_GPUSampler* sampler_ = nullptr; // NEAREST
|
||||
SDL_GPUSampler* linear_sampler_ = nullptr; // LINEAR
|
||||
SDL_GPUSampler* linear_sampler_ = nullptr; // LINEAR (per texture_filter_linear_)
|
||||
|
||||
PostFXUniforms uniforms_{.vignette_strength = 0.6F, .chroma_strength = 0.15F, .scanline_strength = 0.7F, .screen_height = 200.0F, .pixel_scale = 1.0F, .oversample = 1.0F};
|
||||
PostFXUniforms uniforms_{.vignette_strength = 0.6F, .chroma_min = 0.15F, .scanline_strength = 0.7F, .screen_height = 200.0F, .pixel_scale = 1.0F, .chroma_max = 0.15F, .scan_dark_ratio = 0.333F, .scan_dark_floor = 0.42F, .scan_edge_soft = 1.0F};
|
||||
CrtPiUniforms crtpi_uniforms_{.scanline_weight = 6.0F, .scanline_gap_brightness = 0.12F, .bloom_factor = 3.5F, .input_gamma = 2.4F, .output_gamma = 2.2F, .mask_brightness = 0.80F, .curvature_x = 0.05F, .curvature_y = 0.10F, .mask_type = 2, .enable_scanlines = 1, .enable_multisample = 1, .enable_gamma = 1};
|
||||
ShaderType active_shader_ = ShaderType::POSTFX; // Shader de post-procesado activo
|
||||
|
||||
int game_width_ = 0; // Dimensions originals del canvas
|
||||
int game_height_ = 0;
|
||||
int ss_factor_ = 0; // Factor SS activo (3, 6, 9...) o 0 si SS desactivado
|
||||
int oversample_ = 1; // SS on/off (1 = off, >1 = on)
|
||||
int downscale_algo_ = 1; // 0 = bilinear legacy, 1 = Lanczos2, 2 = Lanczos3
|
||||
int internal_res_ = 1; // Multiplicador de resolució interna (1 = off)
|
||||
int internal_res_ = 1; // Multiplicador de resolució interna (1 = off)
|
||||
std::string driver_name_;
|
||||
std::string preferred_driver_; // Driver preferido; vacío = auto (SDL elige)
|
||||
bool is_initialized_ = false;
|
||||
|
||||
@@ -21,12 +21,19 @@ namespace Rendering {
|
||||
struct PostFXParams {
|
||||
float vignette = 0.0F; // Intensidad de la viñeta
|
||||
float scanlines = 0.0F; // Intensidad de las scanlines
|
||||
float chroma = 0.0F; // Aberración cromática
|
||||
// Aberració cromàtica — varia entre min i max via sinusoidal; si coincideixen
|
||||
// queda estàtica. min > 0 garanteix que la imatge mai sigui lliure de chroma.
|
||||
float chroma_min = 0.0F;
|
||||
float chroma_max = 0.0F;
|
||||
float mask = 0.0F; // Máscara de fósforo RGB
|
||||
float gamma = 0.0F; // Corrección gamma (blend 0=off, 1=full)
|
||||
float curvature = 0.0F; // Curvatura barrel CRT
|
||||
float bleeding = 0.0F; // Sangrado de color NTSC
|
||||
float flicker = 0.0F; // Parpadeo de fósforo CRT ~50 Hz
|
||||
// Forma de les scanlines — 3 subpíxels per fila lògica per defecte.
|
||||
float scan_dark_ratio = 0.333F; // fracció obscura (1/3)
|
||||
float scan_dark_floor = 0.42F; // brillantor subfila fosca
|
||||
float scan_edge_soft = 1.0F; // 0 = step dur; 1 = suavitzat 1 px físic
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -112,27 +119,6 @@ namespace Rendering {
|
||||
*/
|
||||
virtual void setScalingMode(Options::ScalingMode /*mode*/) {}
|
||||
|
||||
/**
|
||||
* @brief Establece el factor de supersampling (1 = off, 3 = 3× SS)
|
||||
* Con factor > 1, la textura GPU se crea a game×factor resolución y
|
||||
* las scanlines se hornean en CPU (uploadPixels). El sampler usa LINEAR.
|
||||
*/
|
||||
virtual void setOversample(int /*factor*/) {}
|
||||
|
||||
/**
|
||||
* @brief Selecciona el algoritmo de downscale tras el PostFX (SS activo).
|
||||
* 0 = bilinear legacy (comportamiento actual, sin textura intermedia),
|
||||
* 1 = Lanczos2 (ventana 2, ~25 muestras), 2 = Lanczos3 (ventana 3, ~49 muestras).
|
||||
*/
|
||||
virtual void setDownscaleAlgo(int /*algo*/) {}
|
||||
[[nodiscard]] virtual auto getDownscaleAlgo() const -> int { return 0; }
|
||||
|
||||
/**
|
||||
* @brief Devuelve las dimensiones de la textura de supersampling.
|
||||
* @return Par (ancho, alto) en píxeles; (0, 0) si SS está desactivado.
|
||||
*/
|
||||
[[nodiscard]] virtual auto getSsTextureSize() const -> std::pair<int, int> { return {0, 0}; }
|
||||
|
||||
/**
|
||||
* @brief Verifica si el backend está usando aceleración por hardware
|
||||
* @return true si usa aceleración (OpenGL/Metal/Vulkan)
|
||||
|
||||
+21
-23
@@ -145,9 +145,6 @@ namespace Options {
|
||||
if (node.contains("shader_enabled")) {
|
||||
video.shader_enabled = node["shader_enabled"].get_value<bool>();
|
||||
}
|
||||
if (node.contains("supersampling")) {
|
||||
video.supersampling = node["supersampling"].get_value<bool>();
|
||||
}
|
||||
if (node.contains("scaling_mode")) {
|
||||
auto s = node["scaling_mode"].get_value<std::string>();
|
||||
if (s == "disabled") {
|
||||
@@ -172,9 +169,6 @@ namespace Options {
|
||||
auto s = node["texture_filter"].get_value<std::string>();
|
||||
video.texture_filter = (s == "linear") ? TextureFilter::LINEAR : TextureFilter::NEAREST;
|
||||
}
|
||||
if (node.contains("downscale_algo")) {
|
||||
video.downscale_algo = node["downscale_algo"].get_value<int>();
|
||||
}
|
||||
if (node.contains("internal_resolution")) {
|
||||
video.internal_resolution = node["internal_resolution"].get_value<int>();
|
||||
video.internal_resolution = std::max(video.internal_resolution, 1);
|
||||
@@ -344,7 +338,6 @@ namespace Options {
|
||||
file << "video:\n";
|
||||
file << " gpu_acceleration: " << (video.gpu_acceleration ? "true" : "false") << "\n";
|
||||
file << " shader_enabled: " << (video.shader_enabled ? "true" : "false") << "\n";
|
||||
file << " supersampling: " << (video.supersampling ? "true" : "false") << "\n";
|
||||
{
|
||||
const char* m = nullptr;
|
||||
switch (video.scaling_mode) {
|
||||
@@ -370,7 +363,6 @@ namespace Options {
|
||||
file << " vsync: " << (video.vsync ? "true" : "false") << "\n";
|
||||
file << " aspect_ratio_4_3: " << (video.aspect_ratio_4_3 ? "true" : "false") << "\n";
|
||||
file << " texture_filter: " << (video.texture_filter == TextureFilter::LINEAR ? "linear" : "nearest") << " # nearest|linear\n";
|
||||
file << " downscale_algo: " << video.downscale_algo << " # 0=bilinear, 1=Lanczos2, 2=Lanczos3\n";
|
||||
file << " internal_resolution: " << video.internal_resolution << " # multiplicador enter font, clampat a max_zoom\n";
|
||||
file << " current_shader: " << video.current_shader << "\n";
|
||||
file << " current_postfx_preset: " << video.current_postfx_preset << "\n";
|
||||
@@ -481,22 +473,24 @@ namespace Options {
|
||||
// Escriure defaults
|
||||
std::ofstream out(postfx_file_path);
|
||||
if (out.is_open()) {
|
||||
out << "# Aventures En Egipte - PostFX Shader Presets\n\n";
|
||||
out << "# Aventures En Egipte - PostFX Shader Presets\n";
|
||||
out << "# chroma_min/max: min == max → estàtic; min != max → pulsa sinusoïdalment.\n";
|
||||
out << "# scan_dark_ratio/floor/edge_soft: forma analítica de les scanlines.\n\n";
|
||||
out << "presets:\n";
|
||||
out << " - name: \"CRT\"\n vignette: 0.6\n scanlines: 0.7\n chroma: 0.15\n mask: 0.6\n gamma: 0.8\n";
|
||||
out << " - name: \"NTSC\"\n vignette: 0.4\n scanlines: 0.5\n chroma: 0.2\n mask: 0.4\n gamma: 0.5\n bleeding: 0.6\n";
|
||||
out << " - name: \"CURVED\"\n vignette: 0.5\n scanlines: 0.6\n chroma: 0.1\n mask: 0.5\n gamma: 0.7\n curvature: 0.8\n";
|
||||
out << " - name: \"SCANLINES\"\n scanlines: 0.8\n vignette: 0.0\n chroma: 0.0\n";
|
||||
out << " - name: \"SUBTLE\"\n vignette: 0.3\n scanlines: 0.4\n chroma: 0.05\n gamma: 0.3\n";
|
||||
out << " - name: \"CRT LIVE\"\n vignette: 0.5\n scanlines: 0.6\n chroma: 0.3\n mask: 0.3\n gamma: 0.4\n curvature: 0.3\n bleeding: 0.4\n flicker: 0.8\n";
|
||||
out << " - name: \"CRT\"\n vignette: 0.6\n scanlines: 0.7\n chroma_min: 0.15\n chroma_max: 0.15\n mask: 0.6\n gamma: 0.8\n";
|
||||
out << " - name: \"NTSC\"\n vignette: 0.4\n scanlines: 0.5\n chroma_min: 0.2\n chroma_max: 0.2\n mask: 0.4\n gamma: 0.5\n bleeding: 0.6\n";
|
||||
out << " - name: \"CURVED\"\n vignette: 0.5\n scanlines: 0.6\n chroma_min: 0.1\n chroma_max: 0.1\n mask: 0.5\n gamma: 0.7\n curvature: 0.8\n";
|
||||
out << " - name: \"SCANLINES\"\n scanlines: 0.8\n vignette: 0.0\n chroma_min: 0.0\n chroma_max: 0.0\n";
|
||||
out << " - name: \"SUBTLE\"\n vignette: 0.3\n scanlines: 0.4\n chroma_min: 0.05\n chroma_max: 0.05\n gamma: 0.3\n";
|
||||
out << " - name: \"CRT LIVE\"\n vignette: 0.5\n scanlines: 0.6\n chroma_min: 0.3\n chroma_max: 0.3\n mask: 0.3\n gamma: 0.4\n curvature: 0.3\n bleeding: 0.4\n flicker: 0.8\n";
|
||||
out.close();
|
||||
}
|
||||
postfx_presets.push_back({"CRT", 0.6F, 0.7F, 0.15F, 0.6F, 0.8F});
|
||||
postfx_presets.push_back({"NTSC", 0.4F, 0.5F, 0.2F, 0.4F, 0.5F, 0.0F, 0.6F});
|
||||
postfx_presets.push_back({"CURVED", 0.5F, 0.6F, 0.1F, 0.5F, 0.7F, 0.8F});
|
||||
postfx_presets.push_back({"SCANLINES", 0.0F, 0.8F});
|
||||
postfx_presets.push_back({"SUBTLE", 0.3F, 0.4F, 0.05F, 0.0F, 0.3F});
|
||||
postfx_presets.push_back({"CRT LIVE", 0.5F, 0.6F, 0.3F, 0.3F, 0.4F, 0.3F, 0.4F, 0.8F});
|
||||
postfx_presets.push_back({.name = "CRT", .vignette = 0.6F, .scanlines = 0.7F, .chroma_min = 0.15F, .chroma_max = 0.15F, .mask = 0.6F, .gamma = 0.8F});
|
||||
postfx_presets.push_back({.name = "NTSC", .vignette = 0.4F, .scanlines = 0.5F, .chroma_min = 0.2F, .chroma_max = 0.2F, .mask = 0.4F, .gamma = 0.5F, .bleeding = 0.6F});
|
||||
postfx_presets.push_back({.name = "CURVED", .vignette = 0.5F, .scanlines = 0.6F, .chroma_min = 0.1F, .chroma_max = 0.1F, .mask = 0.5F, .gamma = 0.7F, .curvature = 0.8F});
|
||||
postfx_presets.push_back({.name = "SCANLINES", .vignette = 0.0F, .scanlines = 0.8F, .chroma_min = 0.0F, .chroma_max = 0.0F});
|
||||
postfx_presets.push_back({.name = "SUBTLE", .vignette = 0.3F, .scanlines = 0.4F, .chroma_min = 0.05F, .chroma_max = 0.05F, .gamma = 0.3F});
|
||||
postfx_presets.push_back({.name = "CRT LIVE", .vignette = 0.5F, .scanlines = 0.6F, .chroma_min = 0.3F, .chroma_max = 0.3F, .mask = 0.3F, .gamma = 0.4F, .curvature = 0.3F, .bleeding = 0.4F, .flicker = 0.8F});
|
||||
current_postfx_preset = 0;
|
||||
return true;
|
||||
}
|
||||
@@ -514,12 +508,16 @@ namespace Options {
|
||||
}
|
||||
parseFloatField(p, "vignette", preset.vignette);
|
||||
parseFloatField(p, "scanlines", preset.scanlines);
|
||||
parseFloatField(p, "chroma", preset.chroma);
|
||||
parseFloatField(p, "chroma_min", preset.chroma_min);
|
||||
parseFloatField(p, "chroma_max", preset.chroma_max);
|
||||
parseFloatField(p, "mask", preset.mask);
|
||||
parseFloatField(p, "gamma", preset.gamma);
|
||||
parseFloatField(p, "curvature", preset.curvature);
|
||||
parseFloatField(p, "bleeding", preset.bleeding);
|
||||
parseFloatField(p, "flicker", preset.flicker);
|
||||
parseFloatField(p, "scan_dark_ratio", preset.scan_dark_ratio);
|
||||
parseFloatField(p, "scan_dark_floor", preset.scan_dark_floor);
|
||||
parseFloatField(p, "scan_edge_soft", preset.scan_edge_soft);
|
||||
postfx_presets.push_back(preset);
|
||||
}
|
||||
}
|
||||
@@ -528,7 +526,7 @@ namespace Options {
|
||||
return true;
|
||||
} catch (const fkyaml::exception& e) {
|
||||
std::cerr << "Error parsing PostFX YAML: " << e.what() << '\n';
|
||||
postfx_presets.push_back({"CRT", 0.6F, 0.7F, 0.15F, 0.6F, 0.8F});
|
||||
postfx_presets.push_back({.name = "CRT", .vignette = 0.6F, .scanlines = 0.7F, .chroma_min = 0.15F, .chroma_max = 0.15F, .mask = 0.6F, .gamma = 0.8F});
|
||||
current_postfx_preset = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -40,12 +40,10 @@ namespace Options {
|
||||
struct Video {
|
||||
bool gpu_acceleration{Defaults::Video::GPU_ACCELERATION};
|
||||
bool shader_enabled{Defaults::Video::SHADER_ENABLED};
|
||||
bool supersampling{Defaults::Video::SUPERSAMPLING};
|
||||
ScalingMode scaling_mode{ScalingMode::INTEGER};
|
||||
bool vsync{Defaults::Video::VSYNC};
|
||||
bool aspect_ratio_4_3{Defaults::Video::ASPECT_RATIO_4_3};
|
||||
TextureFilter texture_filter{TextureFilter::NEAREST};
|
||||
int downscale_algo{Defaults::Video::DOWNSCALE_ALGO};
|
||||
int internal_resolution{Defaults::Video::INTERNAL_RESOLUTION}; // Multiplicador enter ≥ 1, clampat a max_zoom
|
||||
std::string current_shader{"postfx"}; // "postfx" o "crtpi"
|
||||
std::string current_postfx_preset{"CRT"}; // Nom del preset PostFX actiu
|
||||
@@ -99,12 +97,18 @@ namespace Options {
|
||||
std::string name;
|
||||
float vignette{0.6F};
|
||||
float scanlines{0.7F};
|
||||
float chroma{0.15F};
|
||||
// Aberració cromàtica: min == max → estàtic; min != max → pulsa sinusoïdalment.
|
||||
float chroma_min{0.15F};
|
||||
float chroma_max{0.15F};
|
||||
float mask{0.0F};
|
||||
float gamma{0.0F};
|
||||
float curvature{0.0F};
|
||||
float bleeding{0.0F};
|
||||
float flicker{0.0F};
|
||||
// Forma de les scanlines — 3 subpíxels per fila lògica per defecte.
|
||||
float scan_dark_ratio{0.333F};
|
||||
float scan_dark_floor{0.42F};
|
||||
float scan_edge_soft{1.0F};
|
||||
};
|
||||
|
||||
// Preset CrtPi
|
||||
|
||||
Reference in New Issue
Block a user