primera implementacio de sdl3gpu

This commit is contained in:
2026-04-04 19:49:58 +02:00
parent 2c7b70911e
commit 2a774f777f
10 changed files with 103 additions and 29 deletions

View File

@@ -18,6 +18,7 @@ namespace GlobalInputs {
static bool ss_prev = false; static bool ss_prev = false;
static bool next_shader_prev = false; static bool next_shader_prev = false;
static bool next_preset_prev = false; static bool next_preset_prev = false;
static bool stretch_filter_prev = false;
auto handle() -> bool { auto handle() -> bool {
bool consumed = false; bool consumed = false;
@@ -84,7 +85,9 @@ namespace GlobalInputs {
bool next_shader = JI_KeyPressed(Options::keys_gui.next_shader); bool next_shader = JI_KeyPressed(Options::keys_gui.next_shader);
if (next_shader && !next_shader_prev) { if (next_shader && !next_shader_prev) {
Screen::get()->nextShaderPreset(); Screen::get()->nextShaderPreset();
Overlay::showNotification(Screen::get()->isHardwareAccelerated() ? "POSTFX / CRT-PI" : "SENSE GPU"); char msg[32];
snprintf(msg, sizeof(msg), "SHADER: %s", Screen::get()->getActiveShaderName());
Overlay::showNotification(msg);
} }
if (next_shader) consumed = true; if (next_shader) consumed = true;
next_shader_prev = next_shader; next_shader_prev = next_shader;
@@ -98,6 +101,15 @@ namespace GlobalInputs {
if (next_preset) consumed = true; if (next_preset) consumed = true;
next_preset_prev = next_preset; next_preset_prev = next_preset;
// F9 — Toggle filtre d'estirament 4:3 (NEAREST ↔ LINEAR)
bool stretch_filter = JI_KeyPressed(Options::keys_gui.toggle_stretch_filter);
if (stretch_filter && !stretch_filter_prev) {
Screen::get()->toggleStretchFilter();
Overlay::showNotification(Options::video.stretch_filter_linear ? "FILTRE: LINEAR" : "FILTRE: NEAREST");
}
if (stretch_filter) consumed = true;
stretch_filter_prev = stretch_filter;
return consumed; return consumed;
} }

View File

@@ -21,7 +21,8 @@ static bool isGuiKey(SDL_Scancode sc) {
sc == Options::keys_gui.toggle_aspect_ratio || sc == Options::keys_gui.toggle_aspect_ratio ||
sc == Options::keys_gui.toggle_supersampling || sc == Options::keys_gui.toggle_supersampling ||
sc == Options::keys_gui.next_shader || sc == Options::keys_gui.next_shader ||
sc == Options::keys_gui.next_shader_preset; sc == Options::keys_gui.next_shader_preset ||
sc == Options::keys_gui.toggle_stretch_filter;
} }
void JI_DisableKeyboard(Uint32 time) { void JI_DisableKeyboard(Uint32 time) {

View File

@@ -88,6 +88,7 @@ void Screen::initShaders() {
// Aplica opcions de vídeo // Aplica opcions de vídeo
shader_backend_->setScaleMode(Options::video.integer_scale); shader_backend_->setScaleMode(Options::video.integer_scale);
shader_backend_->setStretchFilter(Options::video.stretch_filter_linear);
shader_backend_->setStretch4_3(Options::video.aspect_ratio_4_3); shader_backend_->setStretch4_3(Options::video.aspect_ratio_4_3);
shader_backend_->setLinearUpscale(Options::video.linear_upscale); shader_backend_->setLinearUpscale(Options::video.linear_upscale);
shader_backend_->setDownscaleAlgo(Options::video.downscale_algo); shader_backend_->setDownscaleAlgo(Options::video.downscale_algo);
@@ -179,6 +180,13 @@ void Screen::toggleIntegerScale() {
} }
} }
void Screen::toggleStretchFilter() {
Options::video.stretch_filter_linear = !Options::video.stretch_filter_linear;
if (shader_backend_) {
shader_backend_->setStretchFilter(Options::video.stretch_filter_linear);
}
}
void Screen::nextShaderPreset() { void Screen::nextShaderPreset() {
if (!shader_backend_ || !shader_backend_->isHardwareAccelerated()) return; if (!shader_backend_ || !shader_backend_->isHardwareAccelerated()) return;
@@ -224,6 +232,11 @@ auto Screen::isHardwareAccelerated() const -> bool {
return shader_backend_ && shader_backend_->isHardwareAccelerated(); return shader_backend_ && shader_backend_->isHardwareAccelerated();
} }
auto Screen::getActiveShaderName() const -> const char* {
if (!shader_backend_ || !shader_backend_->isHardwareAccelerated()) return "SENSE GPU";
return shader_backend_->getActiveShader() == Rendering::ShaderType::POSTFX ? "POSTFX" : "CRT-PI";
}
void Screen::adjustWindowSize() { void Screen::adjustWindowSize() {
int w = GAME_WIDTH * zoom_; int w = GAME_WIDTH * zoom_;
// Si 4:3 actiu, l'alçada visual és 240 per zoom (200 * 1.2) // Si 4:3 actiu, l'alçada visual és 240 per zoom (200 * 1.2)

View File

@@ -27,7 +27,8 @@ class Screen {
void toggleSupersampling(); void toggleSupersampling();
void toggleAspectRatio(); void toggleAspectRatio();
void toggleIntegerScale(); void toggleIntegerScale();
void nextShaderPreset(); // Futur: ciclar presets void toggleStretchFilter();
void nextShaderPreset();
void setActiveShader(Rendering::ShaderType type); void setActiveShader(Rendering::ShaderType type);
void applyCurrentPostFXPreset(); void applyCurrentPostFXPreset();
void applyCurrentCrtPiPreset(); void applyCurrentCrtPiPreset();
@@ -36,6 +37,7 @@ class Screen {
[[nodiscard]] auto isFullscreen() const -> bool { return fullscreen_; } [[nodiscard]] auto isFullscreen() const -> bool { return fullscreen_; }
[[nodiscard]] auto getZoom() const -> int { return zoom_; } [[nodiscard]] auto getZoom() const -> int { return zoom_; }
[[nodiscard]] auto isHardwareAccelerated() const -> bool; [[nodiscard]] auto isHardwareAccelerated() const -> bool;
[[nodiscard]] auto getActiveShaderName() const -> const char*;
[[nodiscard]] auto getWindow() -> SDL_Window* { return window_; } [[nodiscard]] auto getWindow() -> SDL_Window* { return window_; }
[[nodiscard]] auto getRenderer() -> SDL_Renderer* { return renderer_; } [[nodiscard]] auto getRenderer() -> SDL_Renderer* { return renderer_; }

View File

@@ -812,23 +812,40 @@ namespace Rendering {
SDL_EndGPUCopyPass(copy); SDL_EndGPUCopyPass(copy);
} }
// ---- Upscale pass: scene_texture_ → scaled_texture_ (NEAREST o LINEAR según linear_upscale_) ---- // ---- Upscale pass: scene_texture_ → scaled_texture_ ----
// Si 4:3 actiu, l'estirament s'aplica ací directament (320x200 → W*factor × H*factor*1.2)
// El filtre per al 4:3 és configurable (stretch_filter_linear_).
// L'effective_scene/height reflecteix la textura real que veuen els shaders.
// Sense SS ni stretch: scene_texture_ a game_height_.
// Amb SS o stretch: scaled_texture_ a l'alçada escalada (amb o sense 4:3).
SDL_GPUTexture* effective_scene = scene_texture_;
int effective_height = game_height_;
if (oversample_ > 1 && scaled_texture_ != nullptr && upscale_pipeline_ != nullptr) { if (oversample_ > 1 && scaled_texture_ != nullptr && upscale_pipeline_ != nullptr) {
SDL_GPUColorTargetInfo upscale_target = {}; SDL_GPUColorTargetInfo upscale_target = {};
upscale_target.texture = scaled_texture_; upscale_target.texture = scaled_texture_;
upscale_target.load_op = SDL_GPU_LOADOP_DONT_CARE; upscale_target.load_op = SDL_GPU_LOADOP_DONT_CARE;
upscale_target.store_op = SDL_GPU_STOREOP_STORE; upscale_target.store_op = SDL_GPU_STOREOP_STORE;
// Triar filtre: si 4:3 actiu, usar el filtre configurable per a l'estirament.
// Si no, usar el filtre d'upscale normal (linear_upscale_).
bool use_linear = stretch_4_3_ ? stretch_filter_linear_ : linear_upscale_;
SDL_GPURenderPass* upass = SDL_BeginGPURenderPass(cmd, &upscale_target, 1, nullptr); SDL_GPURenderPass* upass = SDL_BeginGPURenderPass(cmd, &upscale_target, 1, nullptr);
if (upass != nullptr) { if (upass != nullptr) {
SDL_BindGPUGraphicsPipeline(upass, upscale_pipeline_); SDL_BindGPUGraphicsPipeline(upass, upscale_pipeline_);
SDL_GPUTextureSamplerBinding ubinding = {}; SDL_GPUTextureSamplerBinding ubinding = {};
ubinding.texture = scene_texture_; ubinding.texture = scene_texture_;
ubinding.sampler = (linear_upscale_ && linear_sampler_ != nullptr) ? linear_sampler_ : sampler_; ubinding.sampler = (use_linear && linear_sampler_ != nullptr) ? linear_sampler_ : sampler_;
SDL_BindGPUFragmentSamplers(upass, 0, &ubinding, 1); SDL_BindGPUFragmentSamplers(upass, 0, &ubinding, 1);
SDL_DrawGPUPrimitives(upass, 3, 1, 0, 0); SDL_DrawGPUPrimitives(upass, 3, 1, 0, 0);
SDL_EndGPURenderPass(upass); SDL_EndGPURenderPass(upass);
} }
effective_scene = scaled_texture_;
effective_height = stretch_4_3_ ? static_cast<int>(static_cast<float>(game_height_) * 1.2F) : game_height_;
} else if (stretch_4_3_) {
// Sense SS: el viewport s'encarrega de l'estirament geomètric
effective_height = static_cast<int>(static_cast<float>(game_height_) * 1.2F);
} }
// ---- Acquire swapchain texture ---- // ---- Acquire swapchain texture ----
@@ -846,10 +863,10 @@ namespace Rendering {
return; return;
} }
// ---- Calcular viewport (dimensions lògiques del canvas, no de textura GPU) ---- // ---- Calcular viewport (dimensions lògiques del canvas) ----
// Si stretch_4_3_ actiu, l'alçada lògica es multiplica per 1.2 (200→240) per simular 4:3 CRT // Si 4:3 actiu, effective_height ja és 240 (la textura estirada)
const float logical_w = static_cast<float>(game_width_); const float logical_w = static_cast<float>(game_width_);
const float logical_h = stretch_4_3_ ? static_cast<float>(game_height_) * 1.2F : static_cast<float>(game_height_); const float logical_h = static_cast<float>(effective_height);
float vx = 0.0F; float vx = 0.0F;
float vy = 0.0F; float vy = 0.0F;
@@ -869,14 +886,15 @@ namespace Rendering {
vx = std::floor((static_cast<float>(sw) - vw) * 0.5F); vx = std::floor((static_cast<float>(sw) - vw) * 0.5F);
vy = std::floor((static_cast<float>(sh) - vh) * 0.5F); vy = std::floor((static_cast<float>(sh) - vh) * 0.5F);
// pixel_scale: subpíxeles por pixel lógico. // pixel_scale: subpíxels per píxel lògic.
// Sin SS: vh/game_height (zoom de ventana). // Sense SS: vh/effective_height (zoom de finestra).
// Con SS: ss_factor_ exacto (3, 6, 9...). // Amb SS: ss_factor_ exacte (3, 6, 9...).
if (oversample_ > 1 && ss_factor_ > 0) { if (oversample_ > 1 && ss_factor_ > 0) {
uniforms_.pixel_scale = static_cast<float>(ss_factor_); uniforms_.pixel_scale = static_cast<float>(ss_factor_);
} else { } else {
uniforms_.pixel_scale = (game_height_ > 0) ? (vh / static_cast<float>(game_height_)) : 1.0F; uniforms_.pixel_scale = (effective_height > 0) ? (vh / static_cast<float>(effective_height)) : 1.0F;
} }
uniforms_.screen_height = static_cast<float>(effective_height);
uniforms_.time = static_cast<float>(SDL_GetTicks()) / 1000.0F; uniforms_.time = static_cast<float>(SDL_GetTicks()) / 1000.0F;
uniforms_.oversample = (oversample_ > 1 && ss_factor_ > 0) uniforms_.oversample = (oversample_ > 1 && ss_factor_ > 0)
? static_cast<float>(ss_factor_) ? static_cast<float>(ss_factor_)
@@ -897,13 +915,13 @@ namespace Rendering {
SDL_SetGPUViewport(pass, &vp); SDL_SetGPUViewport(pass, &vp);
SDL_GPUTextureSamplerBinding binding = {}; SDL_GPUTextureSamplerBinding binding = {};
binding.texture = scene_texture_; binding.texture = effective_scene;
binding.sampler = sampler_; // NEAREST: el shader CrtPi hace su propio filtrado analítico binding.sampler = sampler_; // NEAREST: el shader CrtPi fa el seu propi filtrat analític
SDL_BindGPUFragmentSamplers(pass, 0, &binding, 1); SDL_BindGPUFragmentSamplers(pass, 0, &binding, 1);
// Inyectar texture_width/height antes del push // Injectar texture_width/height abans del push
crtpi_uniforms_.texture_width = static_cast<float>(game_width_); crtpi_uniforms_.texture_width = static_cast<float>(game_width_);
crtpi_uniforms_.texture_height = static_cast<float>(game_height_); crtpi_uniforms_.texture_height = static_cast<float>(effective_height);
SDL_PushGPUFragmentUniformData(cmd, 0, &crtpi_uniforms_, sizeof(CrtPiUniforms)); SDL_PushGPUFragmentUniformData(cmd, 0, &crtpi_uniforms_, sizeof(CrtPiUniforms));
SDL_DrawGPUPrimitives(pass, 3, 1, 0, 0); SDL_DrawGPUPrimitives(pass, 3, 1, 0, 0);
@@ -973,10 +991,10 @@ namespace Rendering {
SDL_GPUViewport vp = {.x = vx, .y = vy, .w = vw, .h = vh, .min_depth = 0.0F, .max_depth = 1.0F}; SDL_GPUViewport vp = {.x = vx, .y = vy, .w = vw, .h = vh, .min_depth = 0.0F, .max_depth = 1.0F};
SDL_SetGPUViewport(pass, &vp); SDL_SetGPUViewport(pass, &vp);
// Con SS: leer de scaled_texture_ con LINEAR; sin SS: scene_texture_ con NEAREST. // Amb SS: llegir de scaled_texture_ amb LINEAR; sense SS: effective_scene amb NEAREST.
SDL_GPUTexture* input_texture = (oversample_ > 1 && scaled_texture_ != nullptr) SDL_GPUTexture* input_texture = (oversample_ > 1 && scaled_texture_ != nullptr)
? scaled_texture_ ? scaled_texture_
: scene_texture_; : effective_scene;
SDL_GPUSampler* active_sampler = (oversample_ > 1 && linear_sampler_ != nullptr) SDL_GPUSampler* active_sampler = (oversample_ > 1 && linear_sampler_ != nullptr)
? linear_sampler_ ? linear_sampler_
: sampler_; : sampler_;
@@ -1179,6 +1197,17 @@ namespace Rendering {
integer_scale_ = integer_scale; integer_scale_ = integer_scale;
} }
void SDL3GPUShader::setStretch4_3(bool enabled) {
stretch_4_3_ = enabled;
if (!is_initialized_ || device_ == nullptr) return;
// Recrear scaled_texture_ perquè tinga les dimensions correctes (amb o sense 4:3)
if (oversample_ > 1 && ss_factor_ > 0) {
SDL_WaitForGPUIdle(device_);
recreateScaledTexture(ss_factor_);
}
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// setOversample — cambia el factor SS; recrea texturas si ya está inicializado // setOversample — cambia el factor SS; recrea texturas si ya está inicializado
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@@ -1292,7 +1321,10 @@ namespace Rendering {
ss_factor_ = 0; ss_factor_ = 0;
const int W = game_width_ * factor; const int W = game_width_ * factor;
const int H = game_height_ * factor; // Si 4:3 actiu, l'alçada inclou l'estirament (200 * factor * 1.2)
const int H = stretch_4_3_
? static_cast<int>(static_cast<float>(game_height_) * 1.2F * static_cast<float>(factor))
: game_height_ * factor;
SDL_GPUTextureCreateInfo info = {}; SDL_GPUTextureCreateInfo info = {};
info.type = SDL_GPU_TEXTURETYPE_2D; info.type = SDL_GPU_TEXTURETYPE_2D;

View File

@@ -120,9 +120,10 @@ namespace Rendering {
// Devuelve el shader activo // Devuelve el shader activo
[[nodiscard]] auto getActiveShader() const -> ShaderType override { return active_shader_; } [[nodiscard]] auto getActiveShader() const -> ShaderType override { return active_shader_; }
// Estirament vertical 4:3 (320x200 → 320x240 visual al viewport) // Estirament vertical 4:3 (fusionat amb l'upscale pass)
void setStretch4_3(bool enabled) override { stretch_4_3_ = enabled; } void setStretch4_3(bool enabled) override;
[[nodiscard]] auto isStretch4_3() const -> bool override { return stretch_4_3_; } [[nodiscard]] auto isStretch4_3() const -> bool override { return stretch_4_3_; }
void setStretchFilter(bool linear) override { stretch_filter_linear_ = linear; }
private: private:
static auto createShaderMSL(SDL_GPUDevice* device, static auto createShaderMSL(SDL_GPUDevice* device,
@@ -155,9 +156,9 @@ namespace Rendering {
SDL_GPUGraphicsPipeline* postfx_offscreen_pipeline_ = nullptr; // PostFX → postfx_texture_ (B8G8R8A8, solo con Lanczos) 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* upscale_pipeline_ = nullptr; // Upscale pass (solo con SS)
SDL_GPUGraphicsPipeline* downscale_pipeline_ = nullptr; // Lanczos downscale (solo con SS + algo > 0) SDL_GPUGraphicsPipeline* downscale_pipeline_ = nullptr; // Lanczos downscale (solo con SS + algo > 0)
SDL_GPUTexture* scene_texture_ = nullptr; // Canvas del juego (game_width_ × game_height_) SDL_GPUTexture* scene_texture_ = nullptr; // Canvas del joc (game_width_ × game_height_)
SDL_GPUTexture* scaled_texture_ = nullptr; // Upscale target (game×factor), solo con SS SDL_GPUTexture* scaled_texture_ = nullptr; // Upscale target (game×factor, amb 4:3 si actiu)
SDL_GPUTexture* postfx_texture_ = nullptr; // PostFX output a resolución escalada, solo con Lanczos SDL_GPUTexture* postfx_texture_ = nullptr; // PostFX output a resolució escalada, sols amb Lanczos
SDL_GPUTransferBuffer* upload_buffer_ = nullptr; SDL_GPUTransferBuffer* upload_buffer_ = nullptr;
SDL_GPUSampler* sampler_ = nullptr; // NEAREST SDL_GPUSampler* sampler_ = nullptr; // NEAREST
SDL_GPUSampler* linear_sampler_ = nullptr; // LINEAR SDL_GPUSampler* linear_sampler_ = nullptr; // LINEAR
@@ -166,7 +167,7 @@ namespace Rendering {
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}; 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 ShaderType active_shader_ = ShaderType::POSTFX; // Shader de post-procesado activo
int game_width_ = 0; // Dimensiones originales del canvas int game_width_ = 0; // Dimensions originals del canvas
int game_height_ = 0; int game_height_ = 0;
int ss_factor_ = 0; // Factor SS activo (3, 6, 9...) o 0 si SS desactivado 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 oversample_ = 1; // SS on/off (1 = off, >1 = on)
@@ -176,8 +177,9 @@ namespace Rendering {
bool is_initialized_ = false; bool is_initialized_ = false;
bool vsync_ = true; bool vsync_ = true;
bool integer_scale_ = false; bool integer_scale_ = false;
bool linear_upscale_ = false; // Upscale NEAREST (false) o LINEAR (true) bool linear_upscale_ = false; // Upscale NEAREST (false) o LINEAR (true)
bool stretch_4_3_ = false; // Estirament vertical 4:3 al viewport bool stretch_4_3_ = false; // Estirament vertical 4:3
bool stretch_filter_linear_ = false; // Filtre per a l'estirament 4:3 (false=NEAREST, true=LINEAR)
}; };
} // namespace Rendering } // namespace Rendering

View File

@@ -177,6 +177,11 @@ namespace Rendering {
*/ */
virtual void setStretch4_3(bool /*enabled*/) {} virtual void setStretch4_3(bool /*enabled*/) {}
[[nodiscard]] virtual auto isStretch4_3() const -> bool { return false; } [[nodiscard]] virtual auto isStretch4_3() const -> bool { return false; }
/**
* @brief Filtre per a l'estirament 4:3 (false=NEAREST, true=LINEAR).
*/
virtual void setStretchFilter(bool /*linear*/) {}
}; };
} // namespace Rendering } // namespace Rendering

View File

@@ -12,6 +12,7 @@ namespace Defaults::KeysGUI {
constexpr SDL_Scancode TOGGLE_SUPERSAMPLING = SDL_SCANCODE_F6; constexpr SDL_Scancode TOGGLE_SUPERSAMPLING = SDL_SCANCODE_F6;
constexpr SDL_Scancode NEXT_SHADER = SDL_SCANCODE_F7; constexpr SDL_Scancode NEXT_SHADER = SDL_SCANCODE_F7;
constexpr SDL_Scancode NEXT_SHADER_PRESET = SDL_SCANCODE_F8; constexpr SDL_Scancode NEXT_SHADER_PRESET = SDL_SCANCODE_F8;
constexpr SDL_Scancode TOGGLE_STRETCH_FILTER = SDL_SCANCODE_F9;
} // namespace Defaults::KeysGUI } // namespace Defaults::KeysGUI
// Tecles de joc (moviment del personatge, accions) // Tecles de joc (moviment del personatge, accions)
@@ -28,8 +29,9 @@ namespace Defaults::Video {
constexpr bool SHADER_ENABLED = false; constexpr bool SHADER_ENABLED = false;
constexpr bool SUPERSAMPLING = false; constexpr bool SUPERSAMPLING = false;
constexpr bool INTEGER_SCALE = true; constexpr bool INTEGER_SCALE = true;
constexpr bool ASPECT_RATIO_4_3 = true; // CRT original estira 200→240 constexpr bool ASPECT_RATIO_4_3 = true; // CRT original estira 200→240
constexpr int DOWNSCALE_ALGO = 1; // 0=bilinear, 1=Lanczos2, 2=Lanczos3 constexpr bool STRETCH_FILTER_LINEAR = false; // Filtre per a l'estirament 4:3 (false=NEAREST)
constexpr int DOWNSCALE_ALGO = 1; // 0=bilinear, 1=Lanczos2, 2=Lanczos3
constexpr bool LINEAR_UPSCALE = false; constexpr bool LINEAR_UPSCALE = false;
} // namespace Defaults::Video } // namespace Defaults::Video

View File

@@ -55,6 +55,8 @@ namespace Options {
video.integer_scale = node["integer_scale"].get_value<bool>(); video.integer_scale = node["integer_scale"].get_value<bool>();
if (node.contains("aspect_ratio_4_3")) if (node.contains("aspect_ratio_4_3"))
video.aspect_ratio_4_3 = node["aspect_ratio_4_3"].get_value<bool>(); video.aspect_ratio_4_3 = node["aspect_ratio_4_3"].get_value<bool>();
if (node.contains("stretch_filter_linear"))
video.stretch_filter_linear = node["stretch_filter_linear"].get_value<bool>();
if (node.contains("downscale_algo")) if (node.contains("downscale_algo"))
video.downscale_algo = node["downscale_algo"].get_value<int>(); video.downscale_algo = node["downscale_algo"].get_value<int>();
if (node.contains("linear_upscale")) if (node.contains("linear_upscale"))
@@ -158,6 +160,7 @@ namespace Options {
file << " supersampling: " << (video.supersampling ? "true" : "false") << "\n"; file << " supersampling: " << (video.supersampling ? "true" : "false") << "\n";
file << " integer_scale: " << (video.integer_scale ? "true" : "false") << "\n"; file << " integer_scale: " << (video.integer_scale ? "true" : "false") << "\n";
file << " aspect_ratio_4_3: " << (video.aspect_ratio_4_3 ? "true" : "false") << "\n"; file << " aspect_ratio_4_3: " << (video.aspect_ratio_4_3 ? "true" : "false") << "\n";
file << " stretch_filter_linear: " << (video.stretch_filter_linear ? "true" : "false") << " # filtre 4:3: false=nearest, true=linear\n";
file << " downscale_algo: " << video.downscale_algo << " # 0=bilinear, 1=Lanczos2, 2=Lanczos3\n"; file << " downscale_algo: " << video.downscale_algo << " # 0=bilinear, 1=Lanczos2, 2=Lanczos3\n";
file << " linear_upscale: " << (video.linear_upscale ? "true" : "false") << "\n"; file << " linear_upscale: " << (video.linear_upscale ? "true" : "false") << "\n";
file << "\n"; file << "\n";

View File

@@ -17,6 +17,7 @@ namespace Options {
SDL_Scancode toggle_supersampling{Defaults::KeysGUI::TOGGLE_SUPERSAMPLING}; SDL_Scancode toggle_supersampling{Defaults::KeysGUI::TOGGLE_SUPERSAMPLING};
SDL_Scancode next_shader{Defaults::KeysGUI::NEXT_SHADER}; SDL_Scancode next_shader{Defaults::KeysGUI::NEXT_SHADER};
SDL_Scancode next_shader_preset{Defaults::KeysGUI::NEXT_SHADER_PRESET}; SDL_Scancode next_shader_preset{Defaults::KeysGUI::NEXT_SHADER_PRESET};
SDL_Scancode toggle_stretch_filter{Defaults::KeysGUI::TOGGLE_STRETCH_FILTER};
}; };
// Tecles de joc (moviment, accions) // Tecles de joc (moviment, accions)
@@ -35,6 +36,7 @@ namespace Options {
bool supersampling{Defaults::Video::SUPERSAMPLING}; bool supersampling{Defaults::Video::SUPERSAMPLING};
bool integer_scale{Defaults::Video::INTEGER_SCALE}; bool integer_scale{Defaults::Video::INTEGER_SCALE};
bool aspect_ratio_4_3{Defaults::Video::ASPECT_RATIO_4_3}; bool aspect_ratio_4_3{Defaults::Video::ASPECT_RATIO_4_3};
bool stretch_filter_linear{Defaults::Video::STRETCH_FILTER_LINEAR};
int downscale_algo{Defaults::Video::DOWNSCALE_ALGO}; int downscale_algo{Defaults::Video::DOWNSCALE_ALGO};
bool linear_upscale{Defaults::Video::LINEAR_UPSCALE}; bool linear_upscale{Defaults::Video::LINEAR_UPSCALE};
}; };