5e6a469d46
- Substitueix postfx.frag per la versió analítica amb smoothstep
- PostFXUniforms 12→16 floats (64B, 4×vec4): afegeix chroma_min/max,
scan_dark_ratio, scan_dark_floor, scan_edge_soft
- PostFXParams i PostFXPreset adopten els nous camps amb defaults d'AEE
- MSL extret a source/core/rendering/sdl3gpu/msl/{postfx_vert,postfx_frag,
crtpi_frag}.msl.h (estil Rendering::Msl::kXxx)
- SPIR-V regenerat (postfx_frag_spv.h: 13648 bytes)
- options.cpp llegeix 'chroma' antic com compat (assigna a min i max);
escriu els 6 presets per defecte (CRT/NTSC/CURVED/SCANLINES/SUBTLE/CRT LIVE)
amb els valors d'aee_arcade
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
221 lines
13 KiB
C++
221 lines
13 KiB
C++
#pragma once
|
|
|
|
#include <SDL3/SDL.h>
|
|
|
|
#include <algorithm>
|
|
#include <string> // Para string, basic_string
|
|
#include <utility>
|
|
#include <vector> // Para vector
|
|
|
|
#include "core/rendering/screen.hpp" // Para Screen::Filter
|
|
#include "core/rendering/shader_backend.hpp" // Para Rendering::ShaderType
|
|
#include "game/defaults.hpp"
|
|
#include "utils/defines.hpp" // Para WINDOW_CAPTION
|
|
#include "utils/utils.hpp" // Para Color, Palette
|
|
|
|
// --- Namespace Options: gestión de configuración y opciones del juego ---
|
|
namespace Options {
|
|
|
|
// Estructura para las opciones de control de teclado
|
|
struct KeyboardControls {
|
|
SDL_Scancode key_left{Defaults::Controls::KEY_LEFT}; // Tecla para mover a la izquierda
|
|
SDL_Scancode key_right{Defaults::Controls::KEY_RIGHT}; // Tecla para mover a la derecha
|
|
SDL_Scancode key_jump{Defaults::Controls::KEY_JUMP}; // Tecla para saltar
|
|
};
|
|
|
|
// Estructura para las opciones de control del gamepad/joystick
|
|
struct GamepadControls {
|
|
int button_left{Defaults::Controls::GAMEPAD_BUTTON_LEFT}; // Botón para mover a la izquierda (por defecto: DPAD_LEFT)
|
|
int button_right{Defaults::Controls::GAMEPAD_BUTTON_RIGHT}; // Botón para mover a la derecha (por defecto: DPAD_RIGHT)
|
|
int button_jump{Defaults::Controls::GAMEPAD_BUTTON_JUMP}; // Botón para saltar (por defecto: WEST/X button)
|
|
};
|
|
|
|
// Estructura para albergar trucos
|
|
struct Cheat {
|
|
enum class State : bool {
|
|
DISABLED = false,
|
|
ENABLED = true
|
|
};
|
|
|
|
State infinite_lives{Defaults::Cheat::INFINITE_LIVES ? State::ENABLED : State::DISABLED}; // Indica si el jugador dispone de vidas infinitas
|
|
State invincible{Defaults::Cheat::INVINCIBLE ? State::ENABLED : State::DISABLED}; // Indica si el jugador puede morir
|
|
State jail_is_open{Defaults::Cheat::JAIL_IS_OPEN ? State::ENABLED : State::DISABLED}; // Indica si la Jail está abierta
|
|
|
|
// Método para comprobar si alguno de los tres primeros trucos está activo
|
|
[[nodiscard]] auto enabled() const -> bool {
|
|
return infinite_lives == State::ENABLED || invincible == State::ENABLED || jail_is_open == State::ENABLED;
|
|
}
|
|
};
|
|
|
|
// Estructura para almacenar estadísticas
|
|
struct Stats {
|
|
int rooms{Defaults::Stats::ROOMS}; // Cantidad de habitaciones visitadas
|
|
int items{Defaults::Stats::ITEMS}; // Cantidad de items obtenidos
|
|
std::string worst_nightmare{Defaults::Stats::WORST_NIGHTMARE}; // Habitación con más muertes acumuladas
|
|
};
|
|
|
|
// Estructura para el modo kiosko
|
|
struct Kiosk {
|
|
bool enabled{Defaults::Kiosk::ENABLED}; // Indica si el modo kiosko está activo
|
|
std::string text{Defaults::Kiosk::TEXT}; // Texto a mostrar en el modo kiosko
|
|
bool infinite_lives{Defaults::Kiosk::INFINITE_LIVES}; // Indica si el jugador tiene vidas infinitas en modo kiosko
|
|
};
|
|
|
|
// Estructura con opciones de la ventana
|
|
struct Window {
|
|
std::string caption{Texts::WINDOW_CAPTION}; // Texto que aparece en la barra de título de la ventana
|
|
int zoom{Defaults::Window::ZOOM}; // Zoom de la ventana
|
|
int max_zoom{Defaults::Window::ZOOM}; // Máximo tamaño de zoom para la ventana
|
|
};
|
|
|
|
// Estructura para gestionar el borde de la pantalla
|
|
struct Border {
|
|
bool enabled{Defaults::Border::ENABLED}; // Indica si se ha de mostrar el borde
|
|
float width{Defaults::Border::WIDTH}; // Ancho 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 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
|
|
struct Video {
|
|
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
|
|
bool vertical_sync{Defaults::Video::VERTICAL_SYNC}; // Indica si se quiere usar vsync 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 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 palette{Defaults::Video::PALETTE_NAME}; // Paleta de colores a usar en el juego
|
|
std::string palette_sort{Defaults::Video::PALETTE_SORT}; // Modo de ordenación de la paleta (original/luminance/spectrum)
|
|
std::string info; // Información sobre el modo de vídeo
|
|
Border border{}; // Borde de la pantalla
|
|
GPU gpu{}; // Opciones de aceleración GPU
|
|
ShaderConfig shader{}; // Opciones de shader post-procesado
|
|
};
|
|
|
|
// Estructura para las opciones de musica
|
|
struct Music {
|
|
bool enabled{Defaults::Music::ENABLED}; // Indica si la música suena o no
|
|
float volume{Defaults::Music::VOLUME}; // Volumen al que suena la música
|
|
};
|
|
|
|
// Estructura para las opciones de sonido
|
|
struct Sound {
|
|
bool enabled{Defaults::Sound::ENABLED}; // Indica si los sonidos suenan o no
|
|
float volume{Defaults::Sound::VOLUME}; // Volumen al que suenan los sonidos (0 a 128 internamente)
|
|
};
|
|
|
|
// Estructura para las opciones de audio
|
|
struct Audio {
|
|
Music music{}; // Opciones para la música
|
|
Sound sound{}; // Opciones para los efectos de sonido
|
|
bool enabled{Defaults::Audio::ENABLED}; // Indica si el audio está activo o no
|
|
float volume{Defaults::Audio::VOLUME}; // Volumen al que suenan el audio (0-128 internamente)
|
|
};
|
|
|
|
// Estructura para las opciones de la pantalla de carga
|
|
struct Loading {
|
|
bool show{Defaults::Loading::SHOW}; // Muestra la pantalla de carga (si no, pantalla en negro)
|
|
bool show_resource_name{Defaults::Loading::SHOW_RESOURCE_NAME}; // Muestra el nombre del recurso sobre la barra de progreso
|
|
bool wait_for_input{Defaults::Loading::WAIT_FOR_INPUT}; // Al terminar la carga, espera tecla antes de continuar (solo si show=true)
|
|
};
|
|
|
|
// Estructura para las opciones de juego
|
|
struct Game {
|
|
float width{Defaults::Canvas::WIDTH}; // Ancho de la resolucion del juego
|
|
float height{Defaults::Canvas::HEIGHT}; // Alto de la resolucion del juego
|
|
std::string player_skin{Defaults::Game::Player::SKIN}; // Skin del jugador ("default" o nombre de enemigo)
|
|
int player_color{Defaults::Game::Player::COLOR}; // Color del jugador (-1 = automático, 0-15 = color fijo)
|
|
};
|
|
|
|
// Estructura para un preset de PostFX
|
|
struct PostFXPreset {
|
|
std::string name; // Nombre del preset
|
|
float vignette{0.6F}; // Intensidad de la viñeta (0.0 = ninguna, 1.0 = máxima)
|
|
float scanlines{0.7F}; // Intensidad de las scanlines
|
|
float chroma_min{0.15F}; // Aberració cromàtica mínima (sempre present)
|
|
float chroma_max{0.15F}; // Si != chroma_min → pulsa sinusoidalment
|
|
float mask{0.0F}; // Máscara de fósforo RGB
|
|
float gamma{0.0F}; // Corrección gamma (0=off, 1=full)
|
|
float curvature{0.0F}; // Distorsión barrel CRT
|
|
float bleeding{0.0F}; // Sangrado de color NTSC
|
|
float flicker{0.0F}; // Parpadeo de fósforo ~50 Hz
|
|
// 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};
|
|
};
|
|
|
|
// Estructura para un preset del shader CRT-Pi
|
|
struct CrtPiPreset {
|
|
std::string name;
|
|
float scanline_weight{6.0F}; // Ajuste gaussiano (mayor = scanlines más estrechas)
|
|
float scanline_gap_brightness{0.12F}; // Brillo mínimo en las ranuras entre scanlines
|
|
float bloom_factor{3.5F}; // Factor de brillo para zonas iluminadas
|
|
float input_gamma{2.4F}; // Gamma de entrada (linealización)
|
|
float output_gamma{2.2F}; // Gamma de salida (codificación)
|
|
float mask_brightness{0.80F}; // Brillo sub-píxeles en la máscara de fósforo
|
|
float curvature_x{0.05F}; // Distorsión barrel eje X
|
|
float curvature_y{0.10F}; // Distorsión barrel eje Y
|
|
int mask_type{2}; // 0=ninguna, 1=verde/magenta, 2=RGB fósforo
|
|
bool enable_scanlines{true}; // Activar efecto de scanlines
|
|
bool enable_multisample{true}; // Antialiasing analítico de scanlines
|
|
bool enable_gamma{true}; // Corrección gamma
|
|
bool enable_curvature{false}; // Distorsión barrel CRT
|
|
bool enable_sharper{false}; // Submuestreo más nítido (modo SHARPER)
|
|
};
|
|
|
|
// --- Variables globales ---
|
|
inline std::string version{}; // Versión del fichero de configuración. Sirve para saber si las opciones son compatibles
|
|
inline Cheat cheats{}; // Contiene trucos y ventajas para el juego
|
|
inline Game game{}; // Opciones de juego
|
|
inline Video video{}; // Opciones de video
|
|
inline Stats stats{}; // Datos con las estadisticas de juego
|
|
inline Window window{}; // Opciones relativas a la ventana
|
|
inline Audio audio{}; // Opciones relativas al audio
|
|
inline Loading loading{}; // Opciones de la pantalla de carga
|
|
inline KeyboardControls keyboard_controls{}; // Teclas usadas para jugar
|
|
inline GamepadControls gamepad_controls{}; // Botones del gamepad usados para jugar
|
|
inline Kiosk kiosk{}; // Opciones del modo kiosko
|
|
|
|
// Idioma del juego (establecido al inicio, sin cambio en caliente)
|
|
inline std::string language{Defaults::Localization::LANGUAGE};
|
|
|
|
// Ruta completa del fichero de configuración (establecida mediante setConfigFile)
|
|
inline std::string config_file_path{};
|
|
|
|
// --- Variables PostFX ---
|
|
inline std::vector<PostFXPreset> postfx_presets{}; // Lista de presets de PostFX
|
|
inline std::string postfx_file_path{}; // Ruta del fichero postfx.yaml
|
|
|
|
// --- Variables CrtPi ---
|
|
inline std::vector<CrtPiPreset> crtpi_presets{}; // Lista de presets del shader CRT-Pi
|
|
inline std::string crtpi_file_path{}; // Ruta del fichero crtpi.yaml
|
|
|
|
// --- Funciones públicas ---
|
|
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 saveToFile() -> bool; // Guarda las opciones al fichero configurado
|
|
void setPostFXFile(const std::string& path); // Establece la ruta del fichero de PostFX
|
|
auto loadPostFXFromFile() -> bool; // Carga los presets de PostFX desde el fichero
|
|
auto savePostFXToFile() -> bool; // Guarda los presets de PostFX por defecto
|
|
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)
|
|
|
|
void resolvePostFXPresetName(); // Resuelve el nombre del preset PostFX a índice
|
|
void resolveCrtPiPresetName(); // Resuelve el nombre del preset CrtPi a índice
|
|
|
|
} // namespace Options
|