Files
jaildoctors_dilemma/source/game/options.hpp
2025-10-27 18:35:53 +01:00

276 lines
10 KiB
C++

#pragma once
#include <SDL3/SDL.h>
#include <algorithm>
#include <string> // Para string, basic_string
#include <utility>
#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 auto convertVolume(int volume_percent) -> int {
return (volume_percent * 128) / 100;
}
} // namespace VolumeHelpers
// 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/defaults.hpp"
namespace Options {
// Estructura para las opciones de las notificaciones
struct Notification {
bool sound; // Indica si las notificaciones suenan
Uint8 color; // Color de las notificaciones
// Constructor por defecto
Notification()
: sound(GameDefaults::NOTIFICATION_SOUND),
color(GameDefaults::NOTIFICATION_COLOR) {}
// Constructor
Notification(bool s, Uint8 c)
: sound(s),
color(c) {}
};
// 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
[[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; // 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) {}
// Constructor
Stats(int room_count, int item_count, std::string worst_nightmare_room)
: rooms(room_count),
items(item_count),
worst_nightmare(std::move(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),
palette(GameDefaults::PALETTE_NAME) {}
// Constructor
Video(bool is_fullscreen, ScreenFilter screen_filter, bool vsync, bool use_shaders, bool int_scale, bool keep_aspect_ratio, Border video_border, 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(std::move(palette_name)) {}
};
// 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()
: 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 globales (inline C++17+) ---
inline std::string version{}; // Versión del fichero de configuración. Sirve para saber si las opciones son compatibles
inline bool console{false}; // Indica si ha de mostrar información por la consola de texto
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 Notification notifications{}; // Opciones relativas a las notificaciones;
inline Window window{}; // Opciones relativas a la ventana
inline Audio audio{}; // Opciones relativas al audio
inline ControlScheme keys{GameDefaults::CONTROL_SCHEME}; // Teclas usadas para jugar
// --- Funciones ---
void init(); // Crea e inicializa las opciones del programa
auto loadFromFile(const std::string& file_path) -> bool; // Carga las opciones desde un fichero
auto saveToFile(const std::string& file_path) -> bool; // Guarda las opciones a un fichero
} // namespace Options