presentation: bool integer_scale -> enum PresentationMode (integer_scale|letterbox|stretched|overscan) amb migracio de configs antics

This commit is contained in:
2026-05-19 20:29:22 +02:00
parent ac997c185d
commit 20325ddd5a
8 changed files with 214 additions and 69 deletions
+2 -1
View File
@@ -19,7 +19,8 @@ namespace Defaults::Video {
constexpr SDL_ScaleMode SCALE_MODE = SDL_ScaleMode::SDL_SCALEMODE_NEAREST;
constexpr bool FULLSCREEN = false;
constexpr bool VSYNC = true;
constexpr bool INTEGER_SCALE = true;
// INTEGER_SCALE eliminat: ara es part de PresentationMode (a options.hpp).
// El default es defineix literal alli: PresentationMode::INTEGER_SCALE.
constexpr bool GPU_ACCELERATION = true;
constexpr const char *GPU_PREFERRED_DRIVER = "";
constexpr bool SHADER_ENABLED = false;
+49 -3
View File
@@ -31,6 +31,42 @@ namespace Options {
std::string crtpi_file_path;
int current_crtpi_preset = 0;
// Conversions PresentationMode <-> string per a config.yaml i UI
auto presentationModeToString(PresentationMode m) -> const char * {
switch (m) {
case PresentationMode::INTEGER_SCALE:
return "integer_scale";
case PresentationMode::LETTERBOX:
return "letterbox";
case PresentationMode::STRETCHED:
return "stretched";
case PresentationMode::OVERSCAN:
return "overscan";
}
return "integer_scale";
}
auto presentationModeFromString(const std::string &s) -> PresentationMode {
if (s == "letterbox") { return PresentationMode::LETTERBOX; }
if (s == "stretched") { return PresentationMode::STRETCHED; }
if (s == "overscan") { return PresentationMode::OVERSCAN; }
return PresentationMode::INTEGER_SCALE;
}
auto nextPresentationMode(PresentationMode m) -> PresentationMode {
switch (m) {
case PresentationMode::INTEGER_SCALE:
return PresentationMode::LETTERBOX;
case PresentationMode::LETTERBOX:
return PresentationMode::STRETCHED;
case PresentationMode::STRETCHED:
return PresentationMode::OVERSCAN;
case PresentationMode::OVERSCAN:
return PresentationMode::INTEGER_SCALE;
}
return PresentationMode::INTEGER_SCALE;
}
// Lectura tolerant d'un camp YAML: assigna a `target` el valor del camp
// si existeix i el tipus encaixa. Si la clau no hi és o el tipus YAML
// no és compatible amb T, conserva el valor previ de `target` (default).
@@ -82,7 +118,16 @@ namespace Options {
parseBoolField(vid, "fullscreen", video.fullscreen);
parseBoolField(vid, "vsync", video.vsync);
parseBoolField(vid, "integer_scale", video.integer_scale);
// presentation_mode (nou): prefereix string explicit; cau a integer_scale legacy (bool) si no.
std::string pm_str;
if (tryGet<std::string>(vid, "presentation_mode", pm_str)) {
video.presentation_mode = presentationModeFromString(pm_str);
} else {
bool legacy_integer_scale = true;
if (tryGet<bool>(vid, "integer_scale", legacy_integer_scale)) {
video.presentation_mode = legacy_integer_scale ? PresentationMode::INTEGER_SCALE : PresentationMode::LETTERBOX;
}
}
int scale_mode_int = static_cast<int>(video.scale_mode);
if (tryGet<int>(vid, "scale_mode", scale_mode_int)) {
video.scale_mode = static_cast<SDL_ScaleMode>(scale_mode_int);
@@ -197,7 +242,7 @@ namespace Options {
// En Emscripten la ventana la gestiona el navegador
window.zoom = 4;
video.fullscreen = false;
video.integer_scale = true;
video.presentation_mode = PresentationMode::INTEGER_SCALE;
#endif
// Dispositius d'entrada per defecte
@@ -283,7 +328,8 @@ namespace Options {
file << "video:\n";
file << " fullscreen: " << boolToString(video.fullscreen) << "\n";
file << " vsync: " << boolToString(video.vsync) << "\n";
file << " integer_scale: " << boolToString(video.integer_scale) << "\n";
file << " presentation_mode: " << presentationModeToString(video.presentation_mode)
<< " # integer_scale | letterbox | stretched | overscan\n";
file << " scale_mode: " << static_cast<int>(video.scale_mode)
<< " # " << static_cast<int>(SDL_SCALEMODE_NEAREST) << ": nearest, "
<< static_cast<int>(SDL_SCALEMODE_LINEAR) << ": linear\n";
+16 -1
View File
@@ -18,6 +18,16 @@
namespace Options {
// Modes de presentacio del canvas virtual a la finestra. Tot fullscreen i
// windowed amb zoom no-fit el respecta; en windowed amb zoom exacte (1x/2x/3x)
// l'efecte es null perque el canvas ja encaixa amb la finestra.
enum class PresentationMode : std::uint8_t {
INTEGER_SCALE, // Multiple enter (1x, 2x, 3x...), centrat, amb barres
LETTERBOX, // Mante aspect ratio, centrat, amb barres
STRETCHED, // Omple tota la finestra, deforma l'aspect ratio
OVERSCAN // Mante aspect ratio i omple la finestra retallant el contingut fora
};
struct Window {
std::string caption = Defaults::Window::CAPTION;
int zoom = Defaults::Window::ZOOM;
@@ -42,11 +52,16 @@ namespace Options {
SDL_ScaleMode scale_mode = Defaults::Video::SCALE_MODE;
bool fullscreen = Defaults::Video::FULLSCREEN;
bool vsync = Defaults::Video::VSYNC;
bool integer_scale = Defaults::Video::INTEGER_SCALE;
PresentationMode presentation_mode = PresentationMode::INTEGER_SCALE;
GPU gpu;
ShaderConfig shader;
};
// Conversions string <-> PresentationMode per a config.yaml i notificacions
auto presentationModeToString(PresentationMode m) -> const char *;
auto presentationModeFromString(const std::string &s) -> PresentationMode;
auto nextPresentationMode(PresentationMode m) -> PresentationMode;
struct Music {
bool enabled = Defaults::Music::ENABLED;
float volume = Defaults::Music::VOLUME;