#include "options.h" #include "const.h" #include "screen.h" #include // Para basic_ofstream, basic_ifstream #include // Para basic_ostream, operator<<, cout // Variables Options options; bool setOptions(const std::string &var, const std::string &value); // Crea e inicializa las opciones del programa void initOptions() { options = Options(); #ifdef DEBUG options.section = SectionState(Section::TITLE, Subsection::NONE); options.console = true; #else options.section = SectionState(Section::LOGO, Subsection::LOGO_TO_INTRO); options.console = false; #endif } // Carga las opciones desde un fichero 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.version; options.version = ""; // 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.version) { initOptions(); saveOptionsToFile(file_path); } // Normaliza los valores if (options.video.mode != 0 && options.video.mode != SDL_WINDOW_FULLSCREEN && options.video.mode != SDL_WINDOW_FULLSCREEN_DESKTOP) { options.video.mode = 0; } return success; } // Guarda las opciones en un fichero bool saveOptionsToFile(const std::string &file_path) { // Crea y abre el fichero de texto std::ofstream file(file_path); bool success = file.is_open(); // Verifica si el archivo se abrió correctamente if (!success) // Si no se pudo abrir el archivo, muestra un mensaje de error y devuelve false { if (options.console) { std::cerr << "Error: Unable to open file " << file_path << " for writing." << std::endl; } return false; } if (options.console) { std::cout << file_path << " open for writing" << std::endl; } // Escribe en el fichero file << "## VERSION\n"; file << "version=" << options.version << "\n"; file << "\n## CONTROL\n"; file << "## keys = CURSOR | OPQA | WASD\n"; file << "keys=" << static_cast(options.keys) << "\n"; file << "\n## VIDEO\n"; file << "video.mode=" << options.video.mode << "\n"; file << "window.zoom=" << options.window.zoom << "\n"; file << "video.filter=" << static_cast(options.video.filter) << "\n"; file << "video.shaders=" << boolToString(options.video.shaders) << "\n"; file << "video.vertical_sync=" << boolToString(options.video.vertical_sync) << "\n"; file << "video.integer_scale=" << boolToString(options.video.integer_scale) << "\n"; file << "video.keep_aspect=" << boolToString(options.video.keep_aspect) << "\n"; file << "video.border.enabled=" << boolToString(options.video.border.enabled) << "\n"; file << "video.border.width=" << options.video.border.width << "\n"; file << "video.border.height=" << options.video.border.height << "\n"; file << "video.palette=" << static_cast(options.video.palette) << "\n"; // Cierra el fichero file.close(); return success; } // Establece las opciones bool setOptions(const std::string &var, const std::string &value) { static const std::unordered_map> optionHandlers = { {"version", [](std::string v) { options.version = v; }}, {"keys", [](std::string v) { options.keys = static_cast(safeStoi(v, static_cast(ControlScheme::CURSOR))); }}, {"video.mode", [](std::string v) { options.video.mode = safeStoi(v, 0); }}, {"window.zoom", [](std::string v) { options.window.zoom = safeStoi(v, 1); }}, {"video.shaders", [](std::string v) { options.video.shaders = stringToBool(v); }}, {"video.vertical_sync", [](std::string v) { options.video.vertical_sync = stringToBool(v); }}, {"video.integer_scale", [](std::string v) { options.video.integer_scale = stringToBool(v); }}, {"video.keep_aspect", [](std::string v) { options.video.keep_aspect = stringToBool(v); }}, {"video.border.enabled", [](std::string v) { options.video.border.enabled = stringToBool(v); }}, {"video.border.width", [](std::string v) { options.video.border.width = safeStoi(v, 32); }}, {"video.border.height", [](std::string v) { options.video.border.height = safeStoi(v, 24); }}, {"video.palette", [](std::string v) { options.video.palette = static_cast(safeStoi(v, static_cast(DEFAULT_PALETTE))); }} }; auto it = optionHandlers.find(var); if (it != optionHandlers.end()) { it->second(value); return true; } return false; }