#pragma once #include #include #include // Para string, basic_string #include "core/rendering/screen.hpp" // Para ScreenFilter #include "utils/utils.hpp" // Para Color, Palette // --- Namespace Options: gestión de configuración y opciones del juego --- namespace Options { // ============================================================================= // VOLUME HELPERS - Conversión de volumen 0-100 a 0-128 // ============================================================================= namespace VolumeHelpers { constexpr int convertVolume(int volume_percent) { return (volume_percent * 128) / 100; } } // namespace VolumeHelpers // Posiciones de las notificaciones enum class NotificationPosition { UPPER_LEFT, UPPER_CENTER, UPPER_RIGHT, BOTTOM_LEFT, BOTTOM_CENTER, BOTTOM_RIGHT, TOP, BOTTOM, LEFT, RIGHT, CENTER, UNKNOWN, }; // Tipos de control de teclado enum class ControlScheme { CURSOR, OPQA, WASD }; } // namespace Options // Incluir constantes por defecto después de declarar los enums #include "game/gameplay/defaults.hpp" namespace Options { // Estructura para las opciones de las notificaciones struct Notification { NotificationPosition pos; // Ubicación de las notificaciones en pantalla bool sound; // Indica si las notificaciones suenan Uint8 color; // Color de las notificaciones // Constructor por defecto Notification() : pos(GameDefaults::NOTIFICATION_POSITION), sound(GameDefaults::NOTIFICATION_SOUND), color(GameDefaults::NOTIFICATION_COLOR) {} // Constructor Notification(NotificationPosition p, bool s, Uint8 c) : pos(p), sound(s), color(c) {} // Método que devuelve la posición horizontal NotificationPosition getHorizontalPosition() const { switch (pos) { case NotificationPosition::UPPER_LEFT: case NotificationPosition::BOTTOM_LEFT: return NotificationPosition::LEFT; case NotificationPosition::UPPER_CENTER: case NotificationPosition::BOTTOM_CENTER: return NotificationPosition::CENTER; case NotificationPosition::UPPER_RIGHT: case NotificationPosition::BOTTOM_RIGHT: return NotificationPosition::RIGHT; default: return NotificationPosition::UNKNOWN; } } // Método que devuelve la posición vertical NotificationPosition getVerticalPosition() const { switch (pos) { case NotificationPosition::UPPER_LEFT: case NotificationPosition::UPPER_CENTER: case NotificationPosition::UPPER_RIGHT: return NotificationPosition::TOP; case NotificationPosition::BOTTOM_LEFT: case NotificationPosition::BOTTOM_CENTER: case NotificationPosition::BOTTOM_RIGHT: return NotificationPosition::BOTTOM; default: return NotificationPosition::UNKNOWN; } } }; // Estructura para albergar trucos struct Cheat { enum class State : bool { DISABLED = false, ENABLED = true }; State infinite_lives; // Indica si el jugador dispone de vidas infinitas State invincible; // Indica si el jugador puede morir State jail_is_open; // Indica si la Jail está abierta State alternate_skin; // Indica si se usa una skin diferente para el jugador // Constructor por defecto Cheat() : infinite_lives(State::DISABLED), invincible(State::DISABLED), jail_is_open(State::DISABLED), alternate_skin(State::DISABLED) {} // Constructor Cheat(State inf_lives, State is_invincible, State jail_enabled, State alt_skin) : infinite_lives(inf_lives), invincible(is_invincible), jail_is_open(jail_enabled), alternate_skin(alt_skin) {} // Método para comprobar si alguno de los tres primeros trucos está activo bool enabled() const { return infinite_lives == State::ENABLED || invincible == State::ENABLED || jail_is_open == State::ENABLED; } }; // Estructura para almacenar estadísticas struct Stats { int rooms; // Cantidad de habitaciones visitadas int items; // Cantidad de items obtenidos std::string worst_nightmare; // Habitación con más muertes acumuladas // Constructor por defecto Stats() : rooms(0), items(0), worst_nightmare("") {} // Constructor Stats(int room_count, int item_count, const std::string& worst_nightmare_room) : rooms(room_count), items(item_count), worst_nightmare(worst_nightmare_room) {} }; // Estructura con opciones de la ventana struct Window { std::string caption; // Texto que aparece en la barra de título de la ventana int zoom; // Zoom de la ventana int max_zoom; // Máximo tamaño de zoom para la ventana // Constructor por defecto Window() : caption("JailDoctor's Dilemma"), zoom(GameDefaults::WINDOW_ZOOM), max_zoom(GameDefaults::WINDOW_ZOOM) {} // Constructor Window(int window_zoom, int maximum_zoom) : caption("JailDoctor's Dilemma"), zoom(window_zoom), max_zoom(maximum_zoom) {} }; // Estructura para gestionar el borde de la pantalla struct Border { bool enabled; // Indica si se ha de mostrar el borde float width; // Ancho del borde float height; // Alto del borde // Constructor por defecto Border() : enabled(GameDefaults::BORDER_ENABLED), width(GameDefaults::BORDER_WIDTH), height(GameDefaults::BORDER_HEIGHT) {} // Constructor Border(bool is_enabled, float border_width, float border_height) : enabled(is_enabled), width(border_width), height(border_height) {} }; // Estructura para las opciones de video struct Video { bool fullscreen; // Contiene el valor del modo de pantalla completa ScreenFilter filter; // Filtro usado para el escalado de la imagen bool vertical_sync; // Indica si se quiere usar vsync o no bool shaders; // Indica si se van a usar shaders o no bool integer_scale; // Indica si el escalado de la imagen ha de ser entero en el modo a pantalla completa bool keep_aspect; // Indica si se ha de mantener la relación de aspecto al poner el modo a pantalla completa Border border; // Borde de la pantalla std::string palette; // Paleta de colores a usar en el juego std::string info; // Información sobre el modo de vídeo // Constructor por defecto Video() : fullscreen(GameDefaults::VIDEO_MODE), filter(GameDefaults::VIDEO_FILTER), vertical_sync(GameDefaults::VIDEO_VERTICAL_SYNC), shaders(GameDefaults::VIDEO_SHADERS), integer_scale(GameDefaults::VIDEO_INTEGER_SCALE), keep_aspect(GameDefaults::VIDEO_KEEP_ASPECT), border(Border()), palette(GameDefaults::PALETTE_NAME), info("") {} // Constructor Video(bool is_fullscreen, ScreenFilter screen_filter, bool vsync, bool use_shaders, bool int_scale, bool keep_aspect_ratio, Border video_border, const std::string& palette_name) : fullscreen(is_fullscreen), filter(screen_filter), vertical_sync(vsync), shaders(use_shaders), integer_scale(int_scale), keep_aspect(keep_aspect_ratio), border(video_border), palette(palette_name), info("") {} }; // Estructura para las opciones de musica struct Music { bool enabled; // Indica si la música suena o no int volume; // Volumen al que suena la música (0 a 128 internamente) // Constructor por defecto Music() : enabled(GameDefaults::MUSIC_ENABLED), volume(VolumeHelpers::convertVolume(GameDefaults::MUSIC_VOLUME)) {} // Constructor con parámetros Music(bool is_enabled, int volume_percent) : enabled(is_enabled), volume(VolumeHelpers::convertVolume(volume_percent)) {} // Método para establecer el volumen void setVolume(int volume_percent) { volume_percent = std::clamp(volume_percent, 0, 100); volume = VolumeHelpers::convertVolume(volume_percent); } }; // Estructura para las opciones de sonido struct Sound { bool enabled; // Indica si los sonidos suenan o no int volume; // Volumen al que suenan los sonidos (0 a 128 internamente) // Constructor por defecto Sound() : enabled(GameDefaults::SOUND_ENABLED), volume(VolumeHelpers::convertVolume(GameDefaults::SOUND_VOLUME)) {} // Constructor con parámetros Sound(bool is_enabled, int volume_percent) : enabled(is_enabled), volume(VolumeHelpers::convertVolume(volume_percent)) {} // Método para establecer el volumen void setVolume(int volume_percent) { volume_percent = std::clamp(volume_percent, 0, 100); volume = VolumeHelpers::convertVolume(volume_percent); } }; // 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; // Indica si el audio está activo o no int volume; // Volumen al que suenan el audio (0-128 internamente) // Constructor por defecto Audio() : music(Music()), sound(Sound()), enabled(GameDefaults::AUDIO_ENABLED), volume(VolumeHelpers::convertVolume(GameDefaults::AUDIO_VOLUME)) {} // Constructor Audio(Music audio_music, Sound audio_sound, bool is_enabled, int volume_percent) : music(audio_music), sound(audio_sound), enabled(is_enabled), volume(VolumeHelpers::convertVolume(volume_percent)) {} }; // Estructura para las opciones de juego struct Game { float width; // Ancho de la resolucion del juego float height; // Alto de la resolucion del juego // Constructor por defecto Game() : width(GameDefaults::GAME_WIDTH), height(GameDefaults::GAME_HEIGHT) {} // Constructor Game(float game_width, float game_height) : width(game_width), height(game_height) {} }; // --- Variables --- extern std::string version; // Versión del fichero de configuración. Sirve para saber si las opciones son compatibles extern bool console; // Indica si ha de mostrar información por la consola de texto extern Cheat cheats; // Contiene trucos y ventajas para el juego extern Game game; // Opciones de juego extern Video video; // Opciones de video extern Stats stats; // Datos con las estadisticas de juego extern Notification notifications; // Opciones relativas a las notificaciones; extern Window window; // Opciones relativas a la ventana extern Audio audio; // Opciones relativas al audio extern ControlScheme keys; // Teclas usadas para jugar // --- Funciones --- void init(); // Crea e inicializa las opciones del programa bool loadFromFile(const std::string& file_path); // Carga las opciones desde un fichero bool saveToFile(const std::string& file_path); // Guarda las opciones a un fichero } // namespace Options