From 79033346c0ac35a5eebda2db0b2b59cc07db432f Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Thu, 2 Oct 2025 16:35:11 +0200 Subject: [PATCH] migrat fitxer de config a v2 --- config/assets.txt | 2 +- source/director.cpp | 2 +- source/options.cpp | 91 ++++++++++++++++++++++++++++----------------- source/options.h | 9 +++-- 4 files changed, 63 insertions(+), 41 deletions(-) diff --git a/config/assets.txt b/config/assets.txt index 5d8d0d3..f159b1c 100644 --- a/config/assets.txt +++ b/config/assets.txt @@ -4,7 +4,7 @@ # Variables: ${PREFIX}, ${SYSTEM_FOLDER} # Archivos de configuración del sistema (absolutos y opcionales) -DATA|${SYSTEM_FOLDER}/config.txt|optional,absolute +DATA|${SYSTEM_FOLDER}/config_v2.txt|optional,absolute DATA|${SYSTEM_FOLDER}/controllers.json|optional,absolute DATA|${SYSTEM_FOLDER}/score.bin|optional,absolute diff --git a/source/director.cpp b/source/director.cpp index 9fdca43..c55c51f 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -86,7 +86,7 @@ void Director::init() { #endif loadAssets(); // Crea el índice de archivos Input::init(Asset::get()->get("gamecontrollerdb.txt"), Asset::get()->get("controllers.json")); // Carga configuración de controles - Options::setConfigFile(Asset::get()->get("config.txt")); // Establece el fichero de configuración + Options::setConfigFile(Asset::get()->get("config_v2.txt")); // Establece el fichero de configuración Options::setControllersFile(Asset::get()->get("controllers.json")); // Establece el fichero de configuración de mandos Options::loadFromFile(); // Carga el archivo de configuración loadParams(); // Carga los parámetros del programa diff --git a/source/options.cpp b/source/options.cpp index 28e566d..8bf39f5 100644 --- a/source/options.cpp +++ b/source/options.cpp @@ -6,6 +6,7 @@ #include // Para size_t #include // Para basic_ostream, operator<<, basic_ostream::operator<<, basic_ofstream, basic_istream, basic_ifstream, ifstream, ofstream #include // Para function +#include // Para istringstream #include // Para map, operator==, _Rb_tree_const_iterator #include // Para std::ranges::any_of #include // Para invalid_argument, out_of_range @@ -64,11 +65,27 @@ auto loadFromFile() -> bool { // --- CASO: EL FICHERO EXISTE --- SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\nReading file: %s", getFileName(settings.config_file).c_str()); std::string line; + std::string param_name; + std::string param_value; + while (std::getline(file, line)) { - if (line.substr(0, 1) != "#") { - int pos = line.find('='); - if (!set(line.substr(0, pos), line.substr(pos + 1, line.length()))) { - SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Unknown parameter: %s", line.substr(0, pos).c_str()); + // Elimina comentarios + auto comment_pos = line.find('#'); + if (comment_pos != std::string::npos) { + line.resize(comment_pos); + } + + // Si la línea contiene '=', lo reemplazamos por un espacio para compatibilidad + auto equals_pos = line.find('='); + if (equals_pos != std::string::npos) { + line[equals_pos] = ' '; + } + + // Usa un stream para separar palabras (elimina automáticamente espacios extra) + std::istringstream iss(line); + if (iss >> param_name >> param_value) { + if (!set(param_name, param_value)) { + SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Unknown parameter: %s", param_name.c_str()); } } } @@ -100,49 +117,51 @@ auto saveToFile() -> bool { applyPendingChanges(); + // Versión del archivo + file << "# Coffee Crisis Arcade Edition - Configuration File\n"; + file << "# Format: key value\n"; + file << "config.version " << settings.config_version << "\n"; + // Opciones de ventana - file << "## WINDOW\n"; - file << "window.zoom=" << window.zoom << "\n"; + file << "\n# WINDOW\n"; + file << "window.zoom " << window.zoom << "\n"; // Opciones de video - file << "\n## VIDEO\n"; - file << "## video.scale_mode [" << static_cast(SDL_ScaleMode::SDL_SCALEMODE_NEAREST) << ": nearest, " << static_cast(SDL_ScaleMode::SDL_SCALEMODE_LINEAR) << ": lineal]\n"; - - file << "video.fullscreen=" << boolToString(video.fullscreen) << "\n"; - file << "video.scale_mode=" << static_cast(video.scale_mode) << "\n"; - file << "video.vsync=" << boolToString(video.vsync) << "\n"; - file << "video.integer_scale=" << boolToString(video.integer_scale) << "\n"; - file << "video.shaders=" << boolToString(video.shaders) << "\n"; + file << "\n# VIDEO\n"; + file << "# video.scale_mode [" << static_cast(SDL_ScaleMode::SDL_SCALEMODE_NEAREST) << ": nearest, " << static_cast(SDL_ScaleMode::SDL_SCALEMODE_LINEAR) << ": linear]\n"; + file << "video.fullscreen " << boolToString(video.fullscreen) << "\n"; + file << "video.scale_mode " << static_cast(video.scale_mode) << "\n"; + file << "video.vsync " << boolToString(video.vsync) << "\n"; + file << "video.integer_scale " << boolToString(video.integer_scale) << "\n"; + file << "video.shaders " << boolToString(video.shaders) << "\n"; // Opciones de audio - file << "\n## AUDIO\n"; - file << "## volume [0 .. 100]\n"; - - file << "audio.enabled=" << boolToString(audio.enabled) << "\n"; - file << "audio.volume=" << audio.volume << "\n"; - file << "audio.music.enabled=" << boolToString(audio.music.enabled) << "\n"; - file << "audio.music.volume=" << audio.music.volume << "\n"; - file << "audio.sound.enabled=" << boolToString(audio.sound.enabled) << "\n"; - file << "audio.sound.volume=" << audio.sound.volume << "\n"; + file << "\n# AUDIO\n"; + file << "# volume range: [0 .. 100]\n"; + file << "audio.enabled " << boolToString(audio.enabled) << "\n"; + file << "audio.volume " << audio.volume << "\n"; + file << "audio.music.enabled " << boolToString(audio.music.enabled) << "\n"; + file << "audio.music.volume " << audio.music.volume << "\n"; + file << "audio.sound.enabled " << boolToString(audio.sound.enabled) << "\n"; + file << "audio.sound.volume " << audio.sound.volume << "\n"; // Opciones del juego - file << "\n## GAME\n"; - file << "## game.language [0: spanish, 1: valencian, 2: english]\n"; - file << "## game.difficulty [" << static_cast(Difficulty::Code::EASY) << ": easy, " << static_cast(Difficulty::Code::NORMAL) << ": normal, " << static_cast(Difficulty::Code::HARD) << ": hard]\n"; - - file << "game.language=" << static_cast(settings.language) << "\n"; - file << "game.difficulty=" << static_cast(settings.difficulty) << "\n"; - file << "game.autofire=" << boolToString(settings.autofire) << "\n"; - file << "game.shutdown_enabled=" << boolToString(settings.shutdown_enabled) << "\n"; - file << "game.params_file=" << settings.params_file << "\n"; + file << "\n# GAME\n"; + file << "# game.language [0: spanish, 1: valencian, 2: english]\n"; + file << "# game.difficulty [" << static_cast(Difficulty::Code::EASY) << ": easy, " << static_cast(Difficulty::Code::NORMAL) << ": normal, " << static_cast(Difficulty::Code::HARD) << ": hard]\n"; + file << "game.language " << static_cast(settings.language) << "\n"; + file << "game.difficulty " << static_cast(settings.difficulty) << "\n"; + file << "game.autofire " << boolToString(settings.autofire) << "\n"; + file << "game.shutdown_enabled " << boolToString(settings.shutdown_enabled) << "\n"; + file << "game.params_file " << settings.params_file << "\n"; // Opciones de mandos - file << "\n## CONTROLLERS\n"; + file << "\n# CONTROLLERS\n"; gamepad_manager.saveToFile(file); // Opciones de teclado - file << "\n## KEYBOARD\n"; - file << "keyboard.player=" << static_cast(keyboard.player_id) << "\n"; + file << "\n# KEYBOARD\n"; + file << "keyboard.player " << static_cast(keyboard.player_id) << "\n"; // Cierra el fichero file.close(); @@ -177,6 +196,8 @@ auto set(const std::string& var, const std::string& value) -> bool { // Un mapa estático asegura que se inicializa solo una vez static const std::map> SETTINGS_MAP = { + // Configuración + {"config.version", [](const auto& val) { settings.config_version = std::stoi(val); }}, // Ventana {"window.zoom", [](const auto& val) { window.zoom = std::stoi(val); }}, // Vídeo diff --git a/source/options.h b/source/options.h index 587506f..4920a42 100644 --- a/source/options.h +++ b/source/options.h @@ -58,6 +58,7 @@ struct Audio { }; struct Settings { + int config_version = 2; // Versión del archivo de configuración Difficulty::Code difficulty = Difficulty::Code::NORMAL; // Dificultad del juego Lang::Code language = Lang::Code::VALENCIAN; // Idioma usado en el juego bool autofire = GameDefaults::Options::SETTINGS_AUTOFIRE; // Indicador de autofire @@ -158,12 +159,12 @@ class GamepadManager { const auto& gamepad = gamepads_[i]; // Guardar el nombre solo si hay path (mando real asignado) if (!gamepad.path.empty()) { - file << "controller." << i << ".name=" << gamepad.name << "\n"; + file << "controller." << i << ".name " << gamepad.name << "\n"; } else { - file << "controller." << i << ".name=\n"; // vacío + file << "controller." << i << ".name \n"; // vacío } - file << "controller." << i << ".path=" << gamepad.path << "\n"; - file << "controller." << i << ".player=" << static_cast(gamepad.player_id) << "\n"; + file << "controller." << i << ".path " << gamepad.path << "\n"; + file << "controller." << i << ".player " << static_cast(gamepad.player_id) << "\n"; } }