#include "options.h" #include "const.h" #include "screen.h" #include // Para basic_ofstream, basic_ifstream #include // 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; }