reestructurat el apartat de video de config.yaml

This commit is contained in:
2026-04-01 18:57:32 +02:00
parent a804ad1368
commit f9c1c4843d
8 changed files with 256 additions and 182 deletions

View File

@@ -92,21 +92,21 @@ namespace GlobalInputs {
void handleToggleShaders() { void handleToggleShaders() {
Screen::get()->toggleShaders(); Screen::get()->toggleShaders();
Notifier::get()->show({Locale::get()->get(Options::video.postfx ? "ui.shaders_enabled" : "ui.shaders_disabled")}); // NOLINT(readability-static-accessed-through-instance) Notifier::get()->show({Locale::get()->get(Options::video.shader.enabled ? "ui.shaders_enabled" : "ui.shaders_disabled")}); // NOLINT(readability-static-accessed-through-instance)
} }
void handleNextShaderPreset() { void handleNextShaderPreset() {
if (Options::current_shader == Rendering::ShaderType::CRTPI) { if (Options::video.shader.current_shader == Rendering::ShaderType::CRTPI) {
if (!Options::crtpi_presets.empty()) { if (!Options::crtpi_presets.empty()) {
Options::current_crtpi_preset = (Options::current_crtpi_preset + 1) % static_cast<int>(Options::crtpi_presets.size()); Options::video.shader.current_crtpi_preset = (Options::video.shader.current_crtpi_preset + 1) % static_cast<int>(Options::crtpi_presets.size());
Screen::get()->reloadCrtPi(); Screen::get()->reloadCrtPi();
Notifier::get()->show({Locale::get()->get("ui.crtpi") + " " + Options::crtpi_presets[static_cast<size_t>(Options::current_crtpi_preset)].name}); // NOLINT(readability-static-accessed-through-instance) Notifier::get()->show({Locale::get()->get("ui.crtpi") + " " + Options::crtpi_presets[static_cast<size_t>(Options::video.shader.current_crtpi_preset)].name}); // NOLINT(readability-static-accessed-through-instance)
} }
} else { } else {
if (!Options::postfx_presets.empty()) { if (!Options::postfx_presets.empty()) {
Options::current_postfx_preset = (Options::current_postfx_preset + 1) % static_cast<int>(Options::postfx_presets.size()); Options::video.shader.current_postfx_preset = (Options::video.shader.current_postfx_preset + 1) % static_cast<int>(Options::postfx_presets.size());
Screen::get()->reloadPostFX(); Screen::get()->reloadPostFX();
Notifier::get()->show({Locale::get()->get("ui.postfx") + " " + Options::postfx_presets[static_cast<size_t>(Options::current_postfx_preset)].name}); // NOLINT(readability-static-accessed-through-instance) Notifier::get()->show({Locale::get()->get("ui.postfx") + " " + Options::postfx_presets[static_cast<size_t>(Options::video.shader.current_postfx_preset)].name}); // NOLINT(readability-static-accessed-through-instance)
} }
} }
} }
@@ -114,7 +114,7 @@ namespace GlobalInputs {
void handleNextShader() { void handleNextShader() {
Screen::get()->nextShader(); Screen::get()->nextShader();
Notifier::get()->show({Locale::get()->get("ui.shader") + " " + // NOLINT(readability-static-accessed-through-instance) Notifier::get()->show({Locale::get()->get("ui.shader") + " " + // NOLINT(readability-static-accessed-through-instance)
(Options::current_shader == Rendering::ShaderType::CRTPI ? "CRTPI" : "POSTFX")}); (Options::video.shader.current_shader == Rendering::ShaderType::CRTPI ? "CRTPI" : "POSTFX")});
} }
void handleNextPalette() { void handleNextPalette() {
@@ -165,7 +165,7 @@ namespace GlobalInputs {
if ((SDL_GetModState() & SDL_KMOD_CTRL) != 0U) { if ((SDL_GetModState() & SDL_KMOD_CTRL) != 0U) {
return InputAction::TOGGLE_SUPERSAMPLING; // Ctrl+F4 return InputAction::TOGGLE_SUPERSAMPLING; // Ctrl+F4
} }
if (Options::video.postfx && ((SDL_GetModState() & SDL_KMOD_SHIFT) != 0U)) { if (Options::video.shader.enabled && ((SDL_GetModState() & SDL_KMOD_SHIFT) != 0U)) {
return InputAction::NEXT_SHADER_PRESET; // Shift+F4 return InputAction::NEXT_SHADER_PRESET; // Shift+F4
} }
return InputAction::TOGGLE_SHADER; // F4 return InputAction::TOGGLE_SHADER; // F4

View File

@@ -89,20 +89,20 @@ void RenderInfo::render() const {
line += " | " + zoom_str + "x"; line += " | " + zoom_str + "x";
// PostFX: muestra shader + preset y supersampling, o nada si está desactivado // PostFX: muestra shader + preset y supersampling, o nada si está desactivado
if (Options::video.postfx) { if (Options::video.shader.enabled) {
const bool IS_CRTPI = (Options::current_shader == Rendering::ShaderType::CRTPI); const bool IS_CRTPI = (Options::video.shader.current_shader == Rendering::ShaderType::CRTPI);
const std::string SHADER_NAME = IS_CRTPI ? "crtpi" : "postfx"; const std::string SHADER_NAME = IS_CRTPI ? "crtpi" : "postfx";
std::string preset_name = "-"; std::string preset_name = "-";
if (IS_CRTPI) { if (IS_CRTPI) {
if (!Options::crtpi_presets.empty()) { if (!Options::crtpi_presets.empty()) {
preset_name = Options::crtpi_presets[static_cast<size_t>(Options::current_crtpi_preset)].name; preset_name = Options::crtpi_presets[static_cast<size_t>(Options::video.shader.current_crtpi_preset)].name;
} }
} else { } else {
if (!Options::postfx_presets.empty()) { if (!Options::postfx_presets.empty()) {
preset_name = Options::postfx_presets[static_cast<size_t>(Options::current_postfx_preset)].name; preset_name = Options::postfx_presets[static_cast<size_t>(Options::video.shader.current_postfx_preset)].name;
} }
} }
const bool SHOW_SS = Options::video.supersampling && !IS_CRTPI; const bool SHOW_SS = Options::video.supersampling.enabled && !IS_CRTPI;
line += " | " + SHADER_NAME + " " + preset_name + (SHOW_SS ? " (ss)" : ""); line += " | " + SHADER_NAME + " " + preset_name + (SHOW_SS ? " (ss)" : "");
} }

View File

@@ -239,11 +239,11 @@ void Screen::renderNotifications() const {
// Activa/desactiva todos los shaders respetando el shader actualmente seleccionado // Activa/desactiva todos los shaders respetando el shader actualmente seleccionado
void Screen::toggleShaders() { void Screen::toggleShaders() {
Options::video.postfx = !Options::video.postfx; Options::video.shader.enabled = !Options::video.shader.enabled;
if (shader_backend_ && shader_backend_->isHardwareAccelerated()) { if (shader_backend_ && shader_backend_->isHardwareAccelerated()) {
if (Options::video.postfx) { if (Options::video.shader.enabled) {
// Activar: usar el shader actualmente seleccionado // Activar: usar el shader actualmente seleccionado
if (Options::current_shader == Rendering::ShaderType::CRTPI) { if (Options::video.shader.current_shader == Rendering::ShaderType::CRTPI) {
shader_backend_->setActiveShader(Rendering::ShaderType::CRTPI); shader_backend_->setActiveShader(Rendering::ShaderType::CRTPI);
applyCurrentCrtPiPreset(); applyCurrentCrtPiPreset();
} else { } else {
@@ -262,10 +262,10 @@ void Screen::toggleShaders() {
// Recarga el shader del preset actual sin toggle // Recarga el shader del preset actual sin toggle
void Screen::reloadPostFX() { void Screen::reloadPostFX() {
if (Options::video.postfx && shader_backend_ && shader_backend_->isHardwareAccelerated()) { if (Options::video.shader.enabled && shader_backend_ && shader_backend_->isHardwareAccelerated()) {
// El backend ya está activo: solo actualizar uniforms, sin recrear el pipeline // El backend ya está activo: solo actualizar uniforms, sin recrear el pipeline
applyCurrentPostFXPreset(); applyCurrentPostFXPreset();
} else if (Options::video.postfx) { } else if (Options::video.shader.enabled) {
initShaders(); initShaders();
} }
} }
@@ -505,14 +505,14 @@ auto loadData(const std::string& filepath) -> std::vector<uint8_t> {
} }
void Screen::setLinearUpscale(bool linear) { void Screen::setLinearUpscale(bool linear) {
Options::video.linear_upscale = linear; Options::video.supersampling.linear_upscale = linear;
if (shader_backend_ && shader_backend_->isHardwareAccelerated()) { if (shader_backend_ && shader_backend_->isHardwareAccelerated()) {
shader_backend_->setLinearUpscale(linear); shader_backend_->setLinearUpscale(linear);
} }
} }
void Screen::setDownscaleAlgo(int algo) { void Screen::setDownscaleAlgo(int algo) {
Options::video.downscale_algo = algo; Options::video.supersampling.downscale_algo = algo;
if (shader_backend_ && shader_backend_->isHardwareAccelerated()) { if (shader_backend_ && shader_backend_->isHardwareAccelerated()) {
shader_backend_->setDownscaleAlgo(algo); shader_backend_->setDownscaleAlgo(algo);
} }
@@ -525,8 +525,8 @@ auto Screen::getSsTextureSize() const -> std::pair<int, int> {
// Activa/desactiva el supersampling global (Ctrl+F4) // Activa/desactiva el supersampling global (Ctrl+F4)
void Screen::toggleSupersampling() { void Screen::toggleSupersampling() {
Options::video.supersampling = !Options::video.supersampling; Options::video.supersampling.enabled = !Options::video.supersampling.enabled;
if (Options::video.postfx && shader_backend_ && shader_backend_->isHardwareAccelerated()) { if (Options::video.shader.enabled && shader_backend_ && shader_backend_->isHardwareAccelerated()) {
applyCurrentPostFXPreset(); applyCurrentPostFXPreset();
} }
} }
@@ -534,11 +534,11 @@ void Screen::toggleSupersampling() {
// Aplica los parámetros del preset actual al backend de shaders // Aplica los parámetros del preset actual al backend de shaders
void Screen::applyCurrentPostFXPreset() { // NOLINT(readability-convert-member-functions-to-static) void Screen::applyCurrentPostFXPreset() { // NOLINT(readability-convert-member-functions-to-static)
if (shader_backend_ && !Options::postfx_presets.empty()) { if (shader_backend_ && !Options::postfx_presets.empty()) {
const auto& p = Options::postfx_presets[static_cast<size_t>(Options::current_postfx_preset)]; const auto& p = Options::postfx_presets[static_cast<size_t>(Options::video.shader.current_postfx_preset)];
// Supersampling es un toggle global (Options::video.supersampling), no por preset. // Supersampling es un toggle global (Options::video.supersampling.enabled), no por preset.
// setOversample primero: puede recrear texturas antes de que setPostFXParams // setOversample primero: puede recrear texturas antes de que setPostFXParams
// decida si hornear scanlines en CPU o aplicarlas en GPU. // decida si hornear scanlines en CPU o aplicarlas en GPU.
shader_backend_->setOversample(Options::video.supersampling ? 3 : 1); shader_backend_->setOversample(Options::video.supersampling.enabled ? 3 : 1);
Rendering::PostFXParams params{.vignette = p.vignette, .scanlines = p.scanlines, .chroma = p.chroma, .mask = p.mask, .gamma = p.gamma, .curvature = p.curvature, .bleeding = p.bleeding, .flicker = p.flicker}; Rendering::PostFXParams params{.vignette = p.vignette, .scanlines = p.scanlines, .chroma = p.chroma, .mask = p.mask, .gamma = p.gamma, .curvature = p.curvature, .bleeding = p.bleeding, .flicker = p.flicker};
shader_backend_->setPostFXParams(params); shader_backend_->setPostFXParams(params);
} }
@@ -547,7 +547,7 @@ void Screen::applyCurrentPostFXPreset() { // NOLINT(readability-convert-member-
// Aplica los parámetros del preset CrtPi actual al backend de shaders // Aplica los parámetros del preset CrtPi actual al backend de shaders
void Screen::applyCurrentCrtPiPreset() { // NOLINT(readability-convert-member-functions-to-static) void Screen::applyCurrentCrtPiPreset() { // NOLINT(readability-convert-member-functions-to-static)
if (shader_backend_ && !Options::crtpi_presets.empty()) { if (shader_backend_ && !Options::crtpi_presets.empty()) {
const auto& p = Options::crtpi_presets[static_cast<size_t>(Options::current_crtpi_preset)]; const auto& p = Options::crtpi_presets[static_cast<size_t>(Options::video.shader.current_crtpi_preset)];
Rendering::CrtPiParams params{ Rendering::CrtPiParams params{
.scanline_weight = p.scanline_weight, .scanline_weight = p.scanline_weight,
.scanline_gap_brightness = p.scanline_gap_brightness, .scanline_gap_brightness = p.scanline_gap_brightness,
@@ -570,9 +570,9 @@ void Screen::applyCurrentCrtPiPreset() { // NOLINT(readability-convert-member-f
// Cambia el shader de post-procesado activo y aplica el preset correspondiente // Cambia el shader de post-procesado activo y aplica el preset correspondiente
void Screen::setActiveShader(Rendering::ShaderType type) { void Screen::setActiveShader(Rendering::ShaderType type) {
Options::current_shader = type; Options::video.shader.current_shader = type;
if (!shader_backend_) { return; } if (!shader_backend_) { return; }
if (!Options::video.postfx) { if (!Options::video.shader.enabled) {
// Shaders desactivados: guardar preferencia pero mantener pass-through // Shaders desactivados: guardar preferencia pero mantener pass-through
shader_backend_->setActiveShader(Rendering::ShaderType::POSTFX); shader_backend_->setActiveShader(Rendering::ShaderType::POSTFX);
shader_backend_->setPostFXParams(Rendering::PostFXParams{}); shader_backend_->setPostFXParams(Rendering::PostFXParams{});
@@ -588,7 +588,7 @@ void Screen::setActiveShader(Rendering::ShaderType type) {
// Cicla al siguiente shader disponible (preparado para futura UI) // Cicla al siguiente shader disponible (preparado para futura UI)
void Screen::nextShader() { void Screen::nextShader() {
const Rendering::ShaderType NEXT = (Options::current_shader == Rendering::ShaderType::POSTFX) const Rendering::ShaderType NEXT = (Options::video.shader.current_shader == Rendering::ShaderType::POSTFX)
? Rendering::ShaderType::CRTPI ? Rendering::ShaderType::CRTPI
: Rendering::ShaderType::POSTFX; : Rendering::ShaderType::POSTFX;
setActiveShader(NEXT); setActiveShader(NEXT);
@@ -603,7 +603,7 @@ void Screen::initShaders() {
if (!shader_backend_) { if (!shader_backend_) {
shader_backend_ = std::make_unique<Rendering::SDL3GPUShader>(); shader_backend_ = std::make_unique<Rendering::SDL3GPUShader>();
const std::string fallback_driver = "none"; const std::string fallback_driver = "none";
shader_backend_->setPreferredDriver(Options::video.gpu_acceleration ? Options::video.gpu_preferred_driver : fallback_driver); shader_backend_->setPreferredDriver(Options::video.gpu.acceleration ? Options::video.gpu.preferred_driver : fallback_driver);
} }
shader_backend_->init(window_, tex, "", ""); shader_backend_->init(window_, tex, "", "");
gpu_driver_ = shader_backend_->getDriverName(); gpu_driver_ = shader_backend_->getDriverName();
@@ -611,10 +611,10 @@ void Screen::initShaders() {
// Propagar flags de vsync, integer scale, upscale y downscale al backend GPU // Propagar flags de vsync, integer scale, upscale y downscale al backend GPU
shader_backend_->setVSync(Options::video.vertical_sync); shader_backend_->setVSync(Options::video.vertical_sync);
shader_backend_->setScaleMode(Options::video.integer_scale); shader_backend_->setScaleMode(Options::video.integer_scale);
shader_backend_->setLinearUpscale(Options::video.linear_upscale); shader_backend_->setLinearUpscale(Options::video.supersampling.linear_upscale);
shader_backend_->setDownscaleAlgo(Options::video.downscale_algo); shader_backend_->setDownscaleAlgo(Options::video.supersampling.downscale_algo);
if (Options::video.postfx) { if (Options::video.shader.enabled) {
applyCurrentPostFXPreset(); applyCurrentPostFXPreset();
} else { } else {
// Pass-through: todos los efectos a 0, el shader solo copia la textura // Pass-through: todos los efectos a 0, el shader solo copia la textura
@@ -622,8 +622,8 @@ void Screen::initShaders() {
} }
// Restaurar el shader activo guardado en config (y sus parámetros CrtPi si aplica) // Restaurar el shader activo guardado en config (y sus parámetros CrtPi si aplica)
shader_backend_->setActiveShader(Options::current_shader); shader_backend_->setActiveShader(Options::video.shader.current_shader);
if (Options::current_shader == Rendering::ShaderType::CRTPI) { if (Options::video.shader.current_shader == Rendering::ShaderType::CRTPI) {
applyCurrentCrtPiPreset(); applyCurrentCrtPiPreset();
} }
} }

View File

@@ -25,7 +25,7 @@ namespace Defaults::Video {
constexpr bool FULLSCREEN = false; // Modo de pantalla completa por defecto (false = ventana) constexpr bool FULLSCREEN = false; // Modo de pantalla completa por defecto (false = ventana)
constexpr Screen::Filter FILTER = Screen::Filter::NEAREST; // Filtro por defecto constexpr Screen::Filter FILTER = Screen::Filter::NEAREST; // Filtro por defecto
constexpr bool VERTICAL_SYNC = true; // Vsync activado por defecto constexpr bool VERTICAL_SYNC = true; // Vsync activado por defecto
constexpr bool POSTFX = false; // PostFX desactivado por defecto constexpr bool SHADER_ENABLED = false; // Shaders de post-procesado desactivados por defecto
constexpr bool SUPERSAMPLING = false; // Supersampling desactivado por defecto constexpr bool SUPERSAMPLING = false; // Supersampling desactivado por defecto
constexpr bool INTEGER_SCALE = true; // Escalado entero activado por defecto constexpr bool INTEGER_SCALE = true; // Escalado entero activado por defecto
constexpr bool KEEP_ASPECT = true; // Mantener aspecto activado por defecto constexpr bool KEEP_ASPECT = true; // Mantener aspecto activado por defecto

View File

@@ -297,9 +297,80 @@ namespace Options {
} }
} }
// Carga los campos básicos de configuración de video // Helper: carga la sección gpu desde YAML
void loadGPUConfigFromYaml(const fkyaml::node& gpu_node) {
if (gpu_node.contains("acceleration")) {
try {
video.gpu.acceleration = gpu_node["acceleration"].get_value<bool>();
} catch (...) {
video.gpu.acceleration = Defaults::Video::GPU_ACCELERATION;
}
}
if (gpu_node.contains("preferred_driver")) {
try {
video.gpu.preferred_driver = gpu_node["preferred_driver"].get_value<std::string>();
} catch (...) {
video.gpu.preferred_driver = "";
}
}
}
// Helper: carga la sección supersampling desde YAML
void loadSupersamplingConfigFromYaml(const fkyaml::node& ss_node) {
if (ss_node.contains("enabled")) {
try {
video.supersampling.enabled = ss_node["enabled"].get_value<bool>();
} catch (...) {
video.supersampling.enabled = Defaults::Video::SUPERSAMPLING;
}
}
if (ss_node.contains("linear_upscale")) {
try {
video.supersampling.linear_upscale = ss_node["linear_upscale"].get_value<bool>();
} catch (...) {
video.supersampling.linear_upscale = Defaults::Video::LINEAR_UPSCALE;
}
}
if (ss_node.contains("downscale_algo")) {
try {
video.supersampling.downscale_algo = ss_node["downscale_algo"].get_value<int>();
} catch (...) {
video.supersampling.downscale_algo = Defaults::Video::DOWNSCALE_ALGO;
}
}
}
// Helper: carga la sección shader desde YAML
void loadShaderConfigFromYaml(const fkyaml::node& sh_node) {
if (sh_node.contains("enabled")) {
try {
video.shader.enabled = sh_node["enabled"].get_value<bool>();
} catch (...) {
video.shader.enabled = Defaults::Video::SHADER_ENABLED;
}
}
if (sh_node.contains("current_shader")) {
try {
const std::string s = sh_node["current_shader"].get_value<std::string>();
video.shader.current_shader = (s == "crtpi") ? Rendering::ShaderType::CRTPI : Rendering::ShaderType::POSTFX;
} catch (...) {
video.shader.current_shader = Rendering::ShaderType::POSTFX;
}
}
if (sh_node.contains("current_postfx_preset")) {
try {
video.shader.current_postfx_preset_name = sh_node["current_postfx_preset"].get_value<std::string>();
} catch (...) {}
}
if (sh_node.contains("current_crtpi_preset")) {
try {
video.shader.current_crtpi_preset_name = sh_node["current_crtpi_preset"].get_value<std::string>();
} catch (...) {}
}
}
// Carga los campos básicos de configuración de video (nivel video:)
void loadBasicVideoFieldsFromYaml(const fkyaml::node& vid) { void loadBasicVideoFieldsFromYaml(const fkyaml::node& vid) {
// fullscreen (antes era "mode")
if (vid.contains("fullscreen")) { if (vid.contains("fullscreen")) {
try { try {
video.fullscreen = vid["fullscreen"].get_value<bool>(); video.fullscreen = vid["fullscreen"].get_value<bool>();
@@ -308,7 +379,6 @@ namespace Options {
} }
} }
// filter (ahora es string)
if (vid.contains("filter")) { if (vid.contains("filter")) {
try { try {
auto filter_str = vid["filter"].get_value<std::string>(); auto filter_str = vid["filter"].get_value<std::string>();
@@ -318,47 +388,6 @@ namespace Options {
} }
} }
if (vid.contains("postfx")) {
try {
video.postfx = vid["postfx"].get_value<bool>();
} catch (...) {
video.postfx = Defaults::Video::POSTFX;
}
}
if (vid.contains("supersampling")) {
try {
video.supersampling = vid["supersampling"].get_value<bool>();
} catch (...) {
video.supersampling = Defaults::Video::SUPERSAMPLING;
}
}
if (vid.contains("current_postfx_preset")) {
try {
current_postfx_preset = vid["current_postfx_preset"].get_value<int>();
} catch (...) {
current_postfx_preset = 0;
}
}
if (vid.contains("current_crtpi_preset")) {
try {
current_crtpi_preset = vid["current_crtpi_preset"].get_value<int>();
} catch (...) {
current_crtpi_preset = 0;
}
}
if (vid.contains("current_shader")) {
try {
const std::string s = vid["current_shader"].get_value<std::string>();
current_shader = (s == "crtpi") ? Rendering::ShaderType::CRTPI : Rendering::ShaderType::POSTFX;
} catch (...) {
current_shader = Rendering::ShaderType::POSTFX;
}
}
if (vid.contains("vertical_sync")) { if (vid.contains("vertical_sync")) {
try { try {
video.vertical_sync = vid["vertical_sync"].get_value<bool>(); video.vertical_sync = vid["vertical_sync"].get_value<bool>();
@@ -383,38 +412,6 @@ namespace Options {
} }
} }
if (vid.contains("linear_upscale")) {
try {
video.linear_upscale = vid["linear_upscale"].get_value<bool>();
} catch (...) {
video.linear_upscale = Defaults::Video::LINEAR_UPSCALE;
}
}
if (vid.contains("downscale_algo")) {
try {
video.downscale_algo = vid["downscale_algo"].get_value<int>();
} catch (...) {
video.downscale_algo = Defaults::Video::DOWNSCALE_ALGO;
}
}
if (vid.contains("gpu_acceleration")) {
try {
video.gpu_acceleration = vid["gpu_acceleration"].get_value<bool>();
} catch (...) {
video.gpu_acceleration = Defaults::Video::GPU_ACCELERATION;
}
}
if (vid.contains("gpu_preferred_driver")) {
try {
video.gpu_preferred_driver = vid["gpu_preferred_driver"].get_value<std::string>();
} catch (...) {
video.gpu_preferred_driver = "";
}
}
loadPaletteFromYaml(vid); loadPaletteFromYaml(vid);
} }
@@ -424,10 +421,18 @@ namespace Options {
const auto& vid = yaml["video"]; const auto& vid = yaml["video"];
loadBasicVideoFieldsFromYaml(vid); loadBasicVideoFieldsFromYaml(vid);
// Lee border
if (vid.contains("border")) { if (vid.contains("border")) {
loadBorderConfigFromYaml(vid["border"]); loadBorderConfigFromYaml(vid["border"]);
} }
if (vid.contains("gpu")) {
loadGPUConfigFromYaml(vid["gpu"]);
}
if (vid.contains("supersampling")) {
loadSupersamplingConfigFromYaml(vid["supersampling"]);
}
if (vid.contains("shader")) {
loadShaderConfigFromYaml(vid["shader"]);
}
} }
} }
@@ -666,6 +671,25 @@ namespace Options {
} }
} }
// Helper: retorna el nombre del preset PostFX actual (para guardar en config)
auto currentPostFXPresetName() -> std::string {
const auto idx = static_cast<size_t>(video.shader.current_postfx_preset);
if (idx < postfx_presets.size()) {
return postfx_presets[idx].name;
}
// Presets no cargados aún: devolver el nombre almacenado del config
return video.shader.current_postfx_preset_name;
}
// Helper: retorna el nombre del preset CrtPi actual (para guardar en config)
auto currentCrtPiPresetName() -> std::string {
const auto idx = static_cast<size_t>(video.shader.current_crtpi_preset);
if (idx < crtpi_presets.size()) {
return crtpi_presets[idx].name;
}
return video.shader.current_crtpi_preset_name;
}
// Guarda las opciones al fichero configurado // Guarda las opciones al fichero configurado
auto saveToFile() -> bool { auto saveToFile() -> bool {
// Abre el fichero para escritura // Abre el fichero para escritura
@@ -712,24 +736,27 @@ namespace Options {
file << "# VIDEO \n"; file << "# VIDEO \n";
file << "video:\n"; file << "video:\n";
file << " fullscreen: " << (video.fullscreen ? "true" : "false") << "\n"; file << " fullscreen: " << (video.fullscreen ? "true" : "false") << "\n";
file << " filter: " << filterToString(video.filter) << " # filter: nearest (pixel perfect) | linear (smooth)\n";
file << " postfx: " << (video.postfx ? "true" : "false") << "\n";
file << " supersampling: " << (video.supersampling ? "true" : "false") << "\n";
file << " current_postfx_preset: " << current_postfx_preset << "\n";
file << " current_crtpi_preset: " << current_crtpi_preset << "\n";
file << " current_shader: " << (current_shader == Rendering::ShaderType::CRTPI ? "crtpi" : "postfx") << "\n";
file << " vertical_sync: " << (video.vertical_sync ? "true" : "false") << "\n"; file << " vertical_sync: " << (video.vertical_sync ? "true" : "false") << "\n";
file << " integer_scale: " << (video.integer_scale ? "true" : "false") << "\n"; file << " integer_scale: " << (video.integer_scale ? "true" : "false") << "\n";
file << " keep_aspect: " << (video.keep_aspect ? "true" : "false") << "\n"; file << " keep_aspect: " << (video.keep_aspect ? "true" : "false") << "\n";
file << " linear_upscale: " << (video.linear_upscale ? "true" : "false") << "\n"; file << " filter: " << filterToString(video.filter) << " # filter: nearest (pixel perfect) | linear (smooth)\n";
file << " downscale_algo: " << video.downscale_algo << " # 0=bilinear, 1=Lanczos2, 2=Lanczos3\n";
file << " gpu_acceleration: " << (video.gpu_acceleration ? "true" : "false") << " # Usar aceleración hardware GPU (false = SDL fallback)\n";
file << " gpu_preferred_driver: \"" << video.gpu_preferred_driver << "\" # Driver GPU específico (empty = auto, aplica solo si gpu_acceleration: true)\n";
file << " palette: " << video.palette << "\n"; file << " palette: " << video.palette << "\n";
file << " border:\n"; file << " border:\n";
file << " enabled: " << (video.border.enabled ? "true" : "false") << "\n"; file << " enabled: " << (video.border.enabled ? "true" : "false") << "\n";
file << " width: " << video.border.width << "\n"; file << " width: " << video.border.width << "\n";
file << " height: " << video.border.height << "\n"; file << " height: " << video.border.height << "\n";
file << " gpu:\n";
file << " acceleration: " << (video.gpu.acceleration ? "true" : "false") << " # Usar aceleración hardware GPU (false = SDL fallback)\n";
file << " preferred_driver: \"" << video.gpu.preferred_driver << "\" # Driver GPU específico (empty = auto, aplica solo si gpu_acceleration: true)\n";
file << " supersampling:\n";
file << " enabled: " << (video.supersampling.enabled ? "true" : "false") << "\n";
file << " linear_upscale: " << (video.supersampling.linear_upscale ? "true" : "false") << "\n";
file << " downscale_algo: " << video.supersampling.downscale_algo << " # 0=bilinear, 1=Lanczos2, 2=Lanczos3\n";
file << " shader:\n";
file << " enabled: " << (video.shader.enabled ? "true" : "false") << "\n";
file << " current_shader: " << (video.shader.current_shader == Rendering::ShaderType::CRTPI ? "crtpi" : "postfx") << "\n";
file << " current_postfx_preset: " << currentPostFXPresetName() << "\n";
file << " current_crtpi_preset: " << currentCrtPiPresetName() << "\n";
file << "\n"; file << "\n";
// KEYBOARD CONTROLS // KEYBOARD CONTROLS
@@ -773,6 +800,40 @@ namespace Options {
return true; return true;
} }
// Resuelve el nombre del preset PostFX a índice dentro del vector de presets
void resolvePostFXPresetName() {
const auto& name = video.shader.current_postfx_preset_name;
if (name.empty()) {
video.shader.current_postfx_preset = 0;
return;
}
for (int i = 0; i < static_cast<int>(postfx_presets.size()); ++i) {
if (postfx_presets[static_cast<size_t>(i)].name == name) {
video.shader.current_postfx_preset = i;
return;
}
}
std::cout << "PostFX preset '" << name << "' not found, defaulting to first preset\n";
video.shader.current_postfx_preset = 0;
}
// Resuelve el nombre del preset CrtPi a índice dentro del vector de presets
void resolveCrtPiPresetName() {
const auto& name = video.shader.current_crtpi_preset_name;
if (name.empty()) {
video.shader.current_crtpi_preset = 0;
return;
}
for (int i = 0; i < static_cast<int>(crtpi_presets.size()); ++i) {
if (crtpi_presets[static_cast<size_t>(i)].name == name) {
video.shader.current_crtpi_preset = i;
return;
}
}
std::cout << "CrtPi preset '" << name << "' not found, defaulting to first preset\n";
video.shader.current_crtpi_preset = 0;
}
// Establece la ruta del fichero de PostFX // Establece la ruta del fichero de PostFX
void setPostFXFile(const std::string& path) { void setPostFXFile(const std::string& path) {
postfx_file_path = path; postfx_file_path = path;
@@ -824,14 +885,11 @@ namespace Options {
} }
} }
// Preservar el índice cargado desde config.yaml; clampar al rango válido. // Resolver el nombre del preset a índice
if (!postfx_presets.empty()) { if (!postfx_presets.empty()) {
current_postfx_preset = std::clamp( resolvePostFXPresetName();
current_postfx_preset,
0,
static_cast<int>(postfx_presets.size()) - 1);
} else { } else {
current_postfx_preset = 0; video.shader.current_postfx_preset = 0;
} }
std::cout << "PostFX file loaded: " << postfx_presets.size() << " preset(s)\n"; std::cout << "PostFX file loaded: " << postfx_presets.size() << " preset(s)\n";
@@ -936,7 +994,7 @@ namespace Options {
postfx_presets.push_back({"SCANLINES", 0.0F, 0.8F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F}); postfx_presets.push_back({"SCANLINES", 0.0F, 0.8F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F});
postfx_presets.push_back({"SUBTLE", 0.3F, 0.4F, 0.05F, 0.0F, 0.3F, 0.0F, 0.0F, 0.0F}); postfx_presets.push_back({"SUBTLE", 0.3F, 0.4F, 0.05F, 0.0F, 0.3F, 0.0F, 0.0F, 0.0F});
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({"CRT LIVE", 0.5F, 0.6F, 0.3F, 0.3F, 0.4F, 0.3F, 0.4F, 0.8F});
current_postfx_preset = 0; video.shader.current_postfx_preset = 0;
return true; return true;
} }
@@ -967,7 +1025,7 @@ namespace Options {
crtpi_presets.push_back({"CURVED", 6.0F, 0.12F, 3.5F, 2.4F, 2.2F, 0.80F, 0.05F, 0.10F, 2, true, true, true, true, false}); crtpi_presets.push_back({"CURVED", 6.0F, 0.12F, 3.5F, 2.4F, 2.2F, 0.80F, 0.05F, 0.10F, 2, true, true, true, true, false});
crtpi_presets.push_back({"SHARP", 6.0F, 0.12F, 3.5F, 2.4F, 2.2F, 0.80F, 0.05F, 0.10F, 2, true, false, true, false, true}); crtpi_presets.push_back({"SHARP", 6.0F, 0.12F, 3.5F, 2.4F, 2.2F, 0.80F, 0.05F, 0.10F, 2, true, false, true, false, true});
crtpi_presets.push_back({"MINIMAL", 8.0F, 0.05F, 2.0F, 2.4F, 2.2F, 1.00F, 0.0F, 0.0F, 0, true, false, false, false, false}); crtpi_presets.push_back({"MINIMAL", 8.0F, 0.05F, 2.0F, 2.4F, 2.2F, 1.00F, 0.0F, 0.0F, 0, true, false, false, false, false});
current_crtpi_preset = 0; video.shader.current_crtpi_preset = 0;
return true; return true;
} }
out << "# JailDoctor's Dilemma - CrtPi Shader Presets\n"; out << "# JailDoctor's Dilemma - CrtPi Shader Presets\n";
@@ -1048,7 +1106,7 @@ namespace Options {
crtpi_presets.push_back({"CURVED", 6.0F, 0.12F, 3.5F, 2.4F, 2.2F, 0.80F, 0.05F, 0.10F, 2, true, true, true, true, false}); crtpi_presets.push_back({"CURVED", 6.0F, 0.12F, 3.5F, 2.4F, 2.2F, 0.80F, 0.05F, 0.10F, 2, true, true, true, true, false});
crtpi_presets.push_back({"SHARP", 6.0F, 0.12F, 3.5F, 2.4F, 2.2F, 0.80F, 0.05F, 0.10F, 2, true, false, true, false, true}); crtpi_presets.push_back({"SHARP", 6.0F, 0.12F, 3.5F, 2.4F, 2.2F, 0.80F, 0.05F, 0.10F, 2, true, false, true, false, true});
crtpi_presets.push_back({"MINIMAL", 8.0F, 0.05F, 2.0F, 2.4F, 2.2F, 1.00F, 0.0F, 0.0F, 0, true, false, false, false, false}); crtpi_presets.push_back({"MINIMAL", 8.0F, 0.05F, 2.0F, 2.4F, 2.2F, 1.00F, 0.0F, 0.0F, 0, true, false, false, false, false});
current_crtpi_preset = 0; video.shader.current_crtpi_preset = 0;
return true; return true;
} }
@@ -1107,13 +1165,11 @@ namespace Options {
} }
} }
// Resolver el nombre del preset a índice
if (!crtpi_presets.empty()) { if (!crtpi_presets.empty()) {
current_crtpi_preset = std::clamp( resolveCrtPiPresetName();
current_crtpi_preset,
0,
static_cast<int>(crtpi_presets.size()) - 1);
} else { } else {
current_crtpi_preset = 0; video.shader.current_crtpi_preset = 0;
} }
std::cout << "CrtPi file loaded: " << crtpi_presets.size() << " preset(s)\n"; std::cout << "CrtPi file loaded: " << crtpi_presets.size() << " preset(s)\n";
@@ -1124,7 +1180,7 @@ namespace Options {
// Cargar defaults en memoria en caso de error // Cargar defaults en memoria en caso de error
crtpi_presets.clear(); crtpi_presets.clear();
crtpi_presets.push_back({"DEFAULT", 6.0F, 0.12F, 3.5F, 2.4F, 2.2F, 0.80F, 0.05F, 0.10F, 2, true, true, true, false, false}); crtpi_presets.push_back({"DEFAULT", 6.0F, 0.12F, 3.5F, 2.4F, 2.2F, 0.80F, 0.05F, 0.10F, 2, true, true, true, false, false});
current_crtpi_preset = 0; video.shader.current_crtpi_preset = 0;
return false; return false;
} }
} }

View File

@@ -75,22 +75,42 @@ namespace Options {
float height{Defaults::Border::HEIGHT}; // Alto del borde float height{Defaults::Border::HEIGHT}; // Alto del borde
}; };
// Estructura para las opciones de GPU
struct GPU {
bool acceleration{Defaults::Video::GPU_ACCELERATION}; // Usar aceleración GPU; false = path SDL fallback directo
std::string preferred_driver; // Driver GPU preferido; vacío = auto. Aplica en el próximo arranque.
};
// Estructura para las opciones de supersampling
struct Supersampling {
bool enabled{Defaults::Video::SUPERSAMPLING}; // Indica si el supersampling 3× está activo
bool linear_upscale{Defaults::Video::LINEAR_UPSCALE}; // Upscale LINEAR (true) o NEAREST (false)
int downscale_algo{Defaults::Video::DOWNSCALE_ALGO}; // 0=bilinear, 1=Lanczos2, 2=Lanczos3
};
// Estructura para las opciones de shader (dentro de Video)
struct ShaderConfig {
bool enabled{Defaults::Video::SHADER_ENABLED}; // Indica si se usan shaders de post-procesado
Rendering::ShaderType current_shader{Rendering::ShaderType::POSTFX}; // Shader de post-procesado activo
std::string current_postfx_preset_name; // Nombre del preset PostFX leído del config
std::string current_crtpi_preset_name; // Nombre del preset CrtPi leído del config
int current_postfx_preset{0}; // Índice resuelto del preset PostFX
int current_crtpi_preset{0}; // Índice resuelto del preset CrtPi
};
// Estructura para las opciones de video // Estructura para las opciones de video
struct Video { struct Video {
bool fullscreen{Defaults::Video::FULLSCREEN}; // Contiene el valor del modo de pantalla completa bool fullscreen{Defaults::Video::FULLSCREEN}; // Contiene el valor del modo de pantalla completa
Screen::Filter filter{Defaults::Video::FILTER}; // Filtro usado para el escalado de la imagen Screen::Filter filter{Defaults::Video::FILTER}; // Filtro usado para el escalado de la imagen
bool vertical_sync{Defaults::Video::VERTICAL_SYNC}; // Indica si se quiere usar vsync o no bool vertical_sync{Defaults::Video::VERTICAL_SYNC}; // Indica si se quiere usar vsync o no
bool postfx{Defaults::Video::POSTFX}; // Indica si se van a usar efectos PostFX o no bool integer_scale{Defaults::Video::INTEGER_SCALE}; // Indica si el escalado de la imagen ha de ser entero en el modo a pantalla completa
bool supersampling{Defaults::Video::SUPERSAMPLING}; // Indica si el supersampling 3× está activo bool keep_aspect{Defaults::Video::KEEP_ASPECT}; // Indica si se ha de mantener la relación de aspecto al poner el modo a pantalla completa
bool integer_scale{Defaults::Video::INTEGER_SCALE}; // Indica si el escalado de la imagen ha de ser entero en el modo a pantalla completa std::string palette{Defaults::Video::PALETTE_NAME}; // Paleta de colores a usar en el juego
bool keep_aspect{Defaults::Video::KEEP_ASPECT}; // Indica si se ha de mantener la relación de aspecto al poner el modo a pantalla completa std::string info; // Información sobre el modo de vídeo
bool linear_upscale{Defaults::Video::LINEAR_UPSCALE}; // Upscale LINEAR (true) o NEAREST (false) Border border{}; // Borde de la pantalla
int downscale_algo{Defaults::Video::DOWNSCALE_ALGO}; // 0=bilinear, 1=Lanczos2, 2=Lanczos3 GPU gpu{}; // Opciones de aceleración GPU
Border border{}; // Borde de la pantalla Supersampling supersampling{}; // Opciones de supersampling
std::string palette{Defaults::Video::PALETTE_NAME}; // Paleta de colores a usar en el juego ShaderConfig shader{}; // Opciones de shader post-procesado
std::string info; // Información sobre el modo de vídeo
bool gpu_acceleration{Defaults::Video::GPU_ACCELERATION}; // Usar aceleración GPU; false = path SDL fallback directo
std::string gpu_preferred_driver; // Driver GPU preferido; vacío = auto. Aplica en el próximo arranque.
}; };
// Estructura para las opciones de musica // Estructura para las opciones de musica
@@ -172,17 +192,12 @@ namespace Options {
// --- Variables PostFX --- // --- Variables PostFX ---
inline std::vector<PostFXPreset> postfx_presets{}; // Lista de presets de PostFX inline std::vector<PostFXPreset> postfx_presets{}; // Lista de presets de PostFX
inline int current_postfx_preset{0}; // Índice del preset de PostFX actual
inline std::string postfx_file_path{}; // Ruta del fichero postfx.yaml inline std::string postfx_file_path{}; // Ruta del fichero postfx.yaml
// --- Variables CrtPi --- // --- Variables CrtPi ---
inline std::vector<CrtPiPreset> crtpi_presets{}; // Lista de presets del shader CRT-Pi inline std::vector<CrtPiPreset> crtpi_presets{}; // Lista de presets del shader CRT-Pi
inline int current_crtpi_preset{0}; // Índice del preset CRT-Pi actual
inline std::string crtpi_file_path{}; // Ruta del fichero crtpi.yaml inline std::string crtpi_file_path{}; // Ruta del fichero crtpi.yaml
// --- Shader activo ---
inline Rendering::ShaderType current_shader{Rendering::ShaderType::POSTFX}; // Shader de post-procesado activo
// --- Funciones públicas --- // --- Funciones públicas ---
void setConfigFile(const std::string& path); // Establece la ruta del fichero de configuración void setConfigFile(const std::string& path); // Establece la ruta del fichero de configuración
auto loadFromFile() -> bool; // Carga las opciones desde el fichero configurado auto loadFromFile() -> bool; // Carga las opciones desde el fichero configurado
@@ -193,4 +208,7 @@ namespace Options {
void setCrtPiFile(const std::string& path); // Establece la ruta del fichero de CrtPi void setCrtPiFile(const std::string& path); // Establece la ruta del fichero de CrtPi
auto loadCrtPiFromFile() -> bool; // Carga los presets de CrtPi desde el fichero (crea defaults si no existe) auto loadCrtPiFromFile() -> bool; // Carga los presets de CrtPi desde el fichero (crea defaults si no existe)
void resolvePostFXPresetName(); // Resuelve el nombre del preset PostFX a índice
void resolveCrtPiPresetName(); // Resuelve el nombre del preset CrtPi a índice
} // namespace Options } // namespace Options

View File

@@ -150,23 +150,23 @@ static const std::vector<ConsoleCommand> COMMANDS = {
if (!Screen::get()->isHardwareAccelerated()) { return "No GPU acceleration"; } if (!Screen::get()->isHardwareAccelerated()) { return "No GPU acceleration"; }
static const std::array<std::string_view, 3> DOWNSCALE_NAMES = {"Bilinear", "Lanczos2", "Lanczos3"}; static const std::array<std::string_view, 3> DOWNSCALE_NAMES = {"Bilinear", "Lanczos2", "Lanczos3"};
if (!args.empty() && args[0] == "SIZE") { if (!args.empty() && args[0] == "SIZE") {
if (!Options::video.supersampling) { return "Supersampling is OFF: no texture"; } if (!Options::video.supersampling.enabled) { return "Supersampling is OFF: no texture"; }
const auto [w, h] = Screen::get()->getSsTextureSize(); const auto [w, h] = Screen::get()->getSsTextureSize();
if (w == 0) { return "SS texture: not active"; } if (w == 0) { return "SS texture: not active"; }
return "SS texture: " + std::to_string(w) + "x" + std::to_string(h); return "SS texture: " + std::to_string(w) + "x" + std::to_string(h);
} }
if (!args.empty() && args[0] == "UPSCALE") { if (!args.empty() && args[0] == "UPSCALE") {
if (args.size() == 1) { if (args.size() == 1) {
Screen::get()->setLinearUpscale(!Options::video.linear_upscale); Screen::get()->setLinearUpscale(!Options::video.supersampling.linear_upscale);
return std::string("Upscale: ") + (Options::video.linear_upscale ? "Linear" : "Nearest"); return std::string("Upscale: ") + (Options::video.supersampling.linear_upscale ? "Linear" : "Nearest");
} }
if (args[1] == "NEAREST") { if (args[1] == "NEAREST") {
if (!Options::video.linear_upscale) { return "Upscale already Nearest"; } if (!Options::video.supersampling.linear_upscale) { return "Upscale already Nearest"; }
Screen::get()->setLinearUpscale(false); Screen::get()->setLinearUpscale(false);
return "Upscale: Nearest"; return "Upscale: Nearest";
} }
if (args[1] == "LINEAR") { if (args[1] == "LINEAR") {
if (Options::video.linear_upscale) { return "Upscale already Linear"; } if (Options::video.supersampling.linear_upscale) { return "Upscale already Linear"; }
Screen::get()->setLinearUpscale(true); Screen::get()->setLinearUpscale(true);
return "Upscale: Linear"; return "Upscale: Linear";
} }
@@ -174,14 +174,14 @@ static const std::vector<ConsoleCommand> COMMANDS = {
} }
if (!args.empty() && args[0] == "DOWNSCALE") { if (!args.empty() && args[0] == "DOWNSCALE") {
if (args.size() == 1) { if (args.size() == 1) {
return std::string("Downscale: ") + std::string(DOWNSCALE_NAMES[static_cast<size_t>(Options::video.downscale_algo)]); return std::string("Downscale: ") + std::string(DOWNSCALE_NAMES[static_cast<size_t>(Options::video.supersampling.downscale_algo)]);
} }
int algo = -1; int algo = -1;
if (args[1] == "BILINEAR") { algo = 0; } if (args[1] == "BILINEAR") { algo = 0; }
if (args[1] == "LANCZOS2") { algo = 1; } if (args[1] == "LANCZOS2") { algo = 1; }
if (args[1] == "LANCZOS3") { algo = 2; } if (args[1] == "LANCZOS3") { algo = 2; }
if (algo == -1) { return "usage: ss downscale [bilinear|lanczos2|lanczos3]"; } if (algo == -1) { return "usage: ss downscale [bilinear|lanczos2|lanczos3]"; }
if (Options::video.downscale_algo == algo) { if (Options::video.supersampling.downscale_algo == algo) {
return std::string("Downscale already ") + std::string(DOWNSCALE_NAMES[static_cast<size_t>(algo)]); return std::string("Downscale already ") + std::string(DOWNSCALE_NAMES[static_cast<size_t>(algo)]);
} }
Screen::get()->setDownscaleAlgo(algo); Screen::get()->setDownscaleAlgo(algo);
@@ -189,15 +189,15 @@ static const std::vector<ConsoleCommand> COMMANDS = {
} }
if (args.empty()) { if (args.empty()) {
Screen::get()->toggleSupersampling(); Screen::get()->toggleSupersampling();
return std::string("PostFX Supersampling ") + (Options::video.supersampling ? "ON" : "OFF"); return std::string("PostFX Supersampling ") + (Options::video.supersampling.enabled ? "ON" : "OFF");
} }
if (args[0] == "ON") { if (args[0] == "ON") {
if (Options::video.supersampling) { return "Supersampling already ON"; } if (Options::video.supersampling.enabled) { return "Supersampling already ON"; }
Screen::get()->toggleSupersampling(); Screen::get()->toggleSupersampling();
return "PostFX Supersampling ON"; return "PostFX Supersampling ON";
} }
if (args[0] == "OFF") { if (args[0] == "OFF") {
if (!Options::video.supersampling) { return "Supersampling already OFF"; } if (!Options::video.supersampling.enabled) { return "Supersampling already OFF"; }
Screen::get()->toggleSupersampling(); Screen::get()->toggleSupersampling();
return "PostFX Supersampling OFF"; return "PostFX Supersampling OFF";
} }
@@ -214,15 +214,15 @@ static const std::vector<ConsoleCommand> COMMANDS = {
if (!Screen::get()->isHardwareAccelerated()) { return "No GPU acceleration"; } if (!Screen::get()->isHardwareAccelerated()) { return "No GPU acceleration"; }
if (args.empty()) { if (args.empty()) {
Screen::get()->toggleShaders(); Screen::get()->toggleShaders();
return std::string("Shader ") + (Options::video.postfx ? "ON" : "OFF"); return std::string("Shader ") + (Options::video.shader.enabled ? "ON" : "OFF");
} }
if (args[0] == "ON") { if (args[0] == "ON") {
if (Options::video.postfx) { return "Shader already ON"; } if (Options::video.shader.enabled) { return "Shader already ON"; }
Screen::get()->toggleShaders(); Screen::get()->toggleShaders();
return "Shader ON"; return "Shader ON";
} }
if (args[0] == "OFF") { if (args[0] == "OFF") {
if (!Options::video.postfx) { return "Shader already OFF"; } if (!Options::video.shader.enabled) { return "Shader already OFF"; }
Screen::get()->toggleShaders(); Screen::get()->toggleShaders();
return "Shader OFF"; return "Shader OFF";
} }
@@ -237,27 +237,27 @@ static const std::vector<ConsoleCommand> COMMANDS = {
if (args[0] == "NEXT") { if (args[0] == "NEXT") {
// SHADER NEXT PRESET → cicla presets del shader activo // SHADER NEXT PRESET → cicla presets del shader activo
if (args.size() >= 2 && args[1] == "PRESET") { if (args.size() >= 2 && args[1] == "PRESET") {
if (Options::current_shader == Rendering::ShaderType::CRTPI) { if (Options::video.shader.current_shader == Rendering::ShaderType::CRTPI) {
if (Options::crtpi_presets.empty()) { return "No CrtPi presets available"; } if (Options::crtpi_presets.empty()) { return "No CrtPi presets available"; }
Options::current_crtpi_preset = Options::video.shader.current_crtpi_preset =
(Options::current_crtpi_preset + 1) % (Options::video.shader.current_crtpi_preset + 1) %
static_cast<int>(Options::crtpi_presets.size()); static_cast<int>(Options::crtpi_presets.size());
Screen::get()->reloadCrtPi(); Screen::get()->reloadCrtPi();
return "CrtPi preset: " + return "CrtPi preset: " +
Options::crtpi_presets[static_cast<size_t>(Options::current_crtpi_preset)].name; Options::crtpi_presets[static_cast<size_t>(Options::video.shader.current_crtpi_preset)].name;
} }
if (Options::postfx_presets.empty()) { return "No PostFX presets available"; } if (Options::postfx_presets.empty()) { return "No PostFX presets available"; }
Options::current_postfx_preset = Options::video.shader.current_postfx_preset =
(Options::current_postfx_preset + 1) % (Options::video.shader.current_postfx_preset + 1) %
static_cast<int>(Options::postfx_presets.size()); static_cast<int>(Options::postfx_presets.size());
Screen::get()->reloadPostFX(); Screen::get()->reloadPostFX();
return "PostFX preset: " + return "PostFX preset: " +
Options::postfx_presets[static_cast<size_t>(Options::current_postfx_preset)].name; Options::postfx_presets[static_cast<size_t>(Options::video.shader.current_postfx_preset)].name;
} }
// SHADER NEXT → cicla entre tipos de shader (PostFX ↔ CrtPi) // SHADER NEXT → cicla entre tipos de shader (PostFX ↔ CrtPi)
Screen::get()->nextShader(); Screen::get()->nextShader();
return std::string("Shader: ") + return std::string("Shader: ") +
(Options::current_shader == Rendering::ShaderType::CRTPI ? "CrtPi" : "PostFX"); (Options::video.shader.current_shader == Rendering::ShaderType::CRTPI ? "CrtPi" : "PostFX");
} }
return "usage: shader [on|off|next [preset]|postfx|crtpi]"; return "usage: shader [on|off|next [preset]|postfx|crtpi]";
}, },
@@ -373,12 +373,12 @@ static const std::vector<ConsoleCommand> COMMANDS = {
return "Not allowed in kiosk mode"; return "Not allowed in kiosk mode";
} }
if (args[0] == "AUTO") { if (args[0] == "AUTO") {
Options::video.gpu_preferred_driver.clear(); Options::video.gpu.preferred_driver.clear();
Options::saveToFile(); Options::saveToFile();
return "Driver: auto (restart)"; return "Driver: auto (restart)";
} }
if (args[0] == "NONE") { if (args[0] == "NONE") {
Options::video.gpu_preferred_driver = "none"; Options::video.gpu.preferred_driver = "none";
Options::saveToFile(); Options::saveToFile();
return "Driver: none (SDL fallback, restart)"; return "Driver: none (SDL fallback, restart)";
} }
@@ -394,7 +394,7 @@ static const std::vector<ConsoleCommand> COMMANDS = {
if (!found) { if (!found) {
return "Unknown driver: " + driver_lower + ". Use DRIVER LIST or NONE"; return "Unknown driver: " + driver_lower + ". Use DRIVER LIST or NONE";
} }
Options::video.gpu_preferred_driver = driver_lower; Options::video.gpu.preferred_driver = driver_lower;
Options::saveToFile(); Options::saveToFile();
return "Driver: " + driver_lower + " (restart)"; return "Driver: " + driver_lower + " (restart)";
}, },

View File

@@ -6,7 +6,7 @@
namespace Texts { namespace Texts {
constexpr const char* WINDOW_CAPTION = "© 2022 JailDoctor's Dilemma — JailDesigner"; constexpr const char* WINDOW_CAPTION = "© 2022 JailDoctor's Dilemma — JailDesigner";
constexpr const char* COPYRIGHT = "@2022 JailDesigner"; constexpr const char* COPYRIGHT = "@2022 JailDesigner";
constexpr const char* VERSION = "1.11"; // Versión por defecto constexpr const char* VERSION = "1.12"; // Versión por defecto
} // namespace Texts } // namespace Texts
// Tamaño de bloque // Tamaño de bloque