Files
jaildoctors_dilemma/source/options.cpp
2025-02-22 23:39:10 +01:00

411 lines
9.7 KiB
C++

#include "options.h"
#include "const.h"
#include "screen.h"
#include <fstream> // Para basic_ofstream, basic_ifstream
#include <iostream> // Para basic_ostream, operator<<, cout
// Variables
options_t options;
bool setOptions(std::string var, std::string value);
void initOptions()
{
// Version del archivo de configuración
options.configVersion = "v1.06.1";
// Opciones de control
options.keys = ctrl_cursor;
// Opciones de video
options.gameWidth = GAMECANVAS_WIDTH;
options.gameHeight = GAMECANVAS_HEIGHT;
options.videoMode = 0;
options.windowSize = 3;
options.filter = FILTER_NEAREST;
options.shaders = false;
options.vSync = true;
options.integerScale = true;
options.keepAspect = true;
options.borderEnabled = true;
options.borderWidth = 32;
options.borderHeight = 24;
options.palette = p_zxspectrum;
#ifdef GAME_CONSOLE
options.windowSize = 2;
#endif
// Estos valores no se guardan en el fichero de configuración
options.console = false;
#ifdef DEBUG
options.console = true;
#endif
options.cheat.infiniteLives = false;
options.cheat.invincible = false;
options.cheat.jailEnabled = false;
options.cheat.altSkin = false;
options.stats.rooms = 0;
options.stats.items = 0;
// Opciones de las notificaciones
options.notifications.posV = pos_top;
options.notifications.posH = pos_left;
options.notifications.sound = true;
options.notifications.color = {48, 48, 48};
#ifdef DEBUG
options.section.name = SECTION_TITLE;
options.section.subsection = SUBSECTION_LOGO_TO_INTRO;
#else
options.section.name = SECTION_LOGO;
options.section.subsection = SUBSECTION_LOGO_TO_INTRO;
#endif
}
bool loadOptionsFromFile(const std::string &file_path)
{
// Indicador de éxito en la carga
bool success = true;
// Versión actual del fichero
const std::string configVersion = options.configVersion;
options.configVersion = "";
// Variables para manejar el fichero
std::string line;
std::ifstream file(file_path);
// Si el fichero se puede abrir
if (file.good())
{
// Procesa el fichero linea a linea
if (options.console)
{
std::cout << "Reading file config.txt\n";
}
while (std::getline(file, line))
{
// Comprueba que la linea no sea un comentario
if (line.substr(0, 1) != "#")
{
// Encuentra la posición del caracter '='
int pos = line.find("=");
// Procesa las dos subcadenas
if (!setOptions(line.substr(0, pos), line.substr(pos + 1, line.length())))
{
if (options.console)
{
std::cout << "Warning: file config.txt\n";
std::cout << "unknown parameter " << line.substr(0, pos).c_str() << std::endl;
}
success = false;
}
}
}
// Cierra el fichero
if (options.console)
{
std::cout << "Closing file config.txt\n\n";
}
file.close();
}
// El fichero no existe
else
{ // Crea el fichero con los valores por defecto
saveOptionsToFile(file_path);
}
// Si la versión de fichero no coincide, crea un fichero nuevo con los valores por defecto
if (configVersion != options.configVersion)
{
initOptions();
saveOptionsToFile(file_path);
}
// Normaliza los valores
const bool a = options.videoMode == 0;
const bool b = options.videoMode == SDL_WINDOW_FULLSCREEN;
const bool c = options.videoMode == SDL_WINDOW_FULLSCREEN_DESKTOP;
if (!(a || b || c))
{
options.videoMode = 0;
}
if (options.windowSize < 1 || options.windowSize > 4)
{
options.windowSize = 3;
}
return success;
}
bool saveOptionsToFile(const std::string &file_path)
{
bool success = true;
// Crea y abre el fichero de texto
std::ofstream file(file_path);
if (file.good())
{
if (options.console)
{
std::cout << file_path << " open for writing" << std::endl;
}
}
else
{
if (options.console)
{
std::cout << file_path << " can't be opened" << std::endl;
}
}
// Escribe en el fichero
file << "## VERSION\n";
file << "configVersion=" + options.configVersion + "\n";
file << "\n## CONTROL OPTIONS\n";
file << "## keys = CURSOR | OPQA | WASD\n";
if (options.keys == ctrl_cursor)
{
file << "keys=CURSOR\n";
}
else if (options.keys == ctrl_opqa)
{
file << "keys=OPQA\n";
}
else if (options.keys == ctrl_wasd)
{
file << "keys=WASD\n";
}
file << "\n## VISUAL OPTIONS\n";
if (options.videoMode == 0)
{
file << "videoMode=0\n";
}
else if (options.videoMode == SDL_WINDOW_FULLSCREEN)
{
file << "videoMode=SDL_WINDOW_FULLSCREEN\n";
}
else if (options.videoMode == SDL_WINDOW_FULLSCREEN_DESKTOP)
{
file << "videoMode=SDL_WINDOW_FULLSCREEN_DESKTOP\n";
}
file << "windowSize=" + std::to_string(options.windowSize) + "\n";
if (options.filter == FILTER_NEAREST)
{
file << "filter=FILTER_NEAREST\n";
}
else
{
file << "filter=FILTER_LINEAR\n";
}
file << "shaders=" + boolToString(options.shaders) + "\n";
file << "vSync=" + boolToString(options.vSync) + "\n";
file << "integerScale=" + boolToString(options.integerScale) + "\n";
file << "keepAspect=" + boolToString(options.keepAspect) + "\n";
file << "borderEnabled=" + boolToString(options.borderEnabled) + "\n";
file << "borderWidth=" + std::to_string(options.borderWidth) + "\n";
file << "borderHeight=" + std::to_string(options.borderHeight) + "\n";
file << "palette=" + std::to_string(options.palette) + "\n";
file << "\n## NOTIFICATION OPTIONS\n";
file << "## notifications.posV = pos_top | pos_bottom\n";
if (options.notifications.posV == pos_top)
{
file << "notifications.posV=pos_top\n";
}
else
{
file << "notifications.posV=pos_bottom\n";
}
file << "## notifications.posH = pos_left | pos_middle | pos_right\n";
if (options.notifications.posH == pos_left)
{
file << "notifications.posH=pos_left\n";
}
else if (options.notifications.posH == pos_middle)
{
file << "notifications.posH=pos_middle\n";
}
else
{
file << "notifications.posH=pos_right\n";
}
file << "notifications.sound=" + boolToString(options.notifications.sound) + "\n";
// Cierra el fichero
file.close();
return success;
}
bool setOptions(std::string var, std::string value)
{
// Indicador de éxito en la asignación
bool success = true;
if (var == "configVersion")
{
options.configVersion = value;
}
else if (var == "keys")
{
if (value == "OPQA")
{
options.keys = ctrl_opqa;
}
else if (value == "WASD")
{
options.keys = ctrl_wasd;
}
else
{
options.keys = ctrl_cursor;
}
}
else if (var == "videoMode")
{
if (value == "SDL_WINDOW_FULLSCREEN_DESKTOP")
{
options.videoMode = SDL_WINDOW_FULLSCREEN_DESKTOP;
}
else if (value == "SDL_WINDOW_FULLSCREEN")
{
options.videoMode = SDL_WINDOW_FULLSCREEN;
}
else
{
options.videoMode = 0;
}
}
else if (var == "windowSize")
{
options.windowSize = std::stoi(value);
if ((options.windowSize < 1) || (options.windowSize > 4))
{
options.windowSize = 3;
}
}
else if (var == "filter")
{
if (value == "FILTER_LINEAR")
{
options.filter = FILTER_LINEAR;
}
else
{
options.filter = FILTER_NEAREST;
}
}
else if (var == "shaders")
{
options.shaders = stringToBool(value);
}
else if (var == "vSync")
{
options.vSync = stringToBool(value);
}
else if (var == "integerScale")
{
options.integerScale = stringToBool(value);
}
else if (var == "keepAspect")
{
options.keepAspect = stringToBool(value);
}
else if (var == "borderEnabled")
{
options.borderEnabled = stringToBool(value);
}
else if (var == "borderWidth")
{
options.borderWidth = std::stoi(value);
}
else if (var == "borderHeight")
{
options.borderHeight = std::stoi(value);
}
else if (var == "palette")
{
const int pal = std::stoi(value);
if (pal == 0)
{
options.palette = p_zxspectrum;
}
else if (pal == 1)
{
options.palette = p_zxarne;
}
}
else if (var == "notifications.posH")
{
if (value == "pos_left")
{
options.notifications.posH = pos_left;
}
else if (value == "pos_middle")
{
options.notifications.posH = pos_middle;
}
else
{
options.notifications.posH = pos_right;
}
}
else if (var == "notifications.posV")
{
if (value == "pos_top")
{
options.notifications.posV = pos_top;
}
else
{
options.notifications.posV = pos_bottom;
}
}
else if (var == "notifications.sound")
{
options.notifications.sound = stringToBool(value);
}
else if (var == "" || var.substr(0, 1) == "#")
{
}
else
{
success = false;
}
return success;
}