void ScoreFile::save() { // Score files are dependent of the level name. std::string score_file = (ScoreFile::directory + this->level_name + "." + ScoreFile::extension); // Will fall back to default high score file // if no level was specified if (this->level_name.empty()) score_file = Globals::Config::scoresFile; // Tries to create file if it doesn't exist. // If we can't create it at all let's just give up. if (! Utils::File::exists(score_file)) { Utils::File::create(score_file); if (! Utils::File::exists(score_file)) throw ScoreFileException("Could not create file '" + score_file + "'"); } // We'll recreate the whole score file from scratch INI::Parser ini; ini.create(); ini.top().addKey("version", std::string(VERSION)); // Adding each score entry on the file for (size_t i = 0; i < (this->entries.size()); i++) { std::string score_name = "score" + Utils::String::toString(i); ini.top().addGroup(score_name); ini(score_name).addKey("level", this->entries[i].level); ini(score_name).addKey("points", Utils::String::toString(this->entries[i].points)); ini(score_name).addKey("speed", Utils::String::toString(this->entries[i].speed)); ini(score_name).addKey("fruits", Utils::String::toString(this->entries[i].fruits)); ini(score_name).addKey("random_walls", Utils::String::toString(this->entries[i].random_walls)); ini(score_name).addKey("teleport", Utils::String::toString(this->entries[i].teleport)); int board_size = Globals::Game::boardSizeToInt(this->entries[i].board_size); ini(score_name).addKey("board_size", Utils::String::toString(board_size)); ini(score_name).addKey("board_scroll_delay", Utils::String::toString(this->entries[i].board_scroll_delay)); ini(score_name).addKey("board_scroll_left", Utils::String::toString(this->entries[i].board_scroll_left)); ini(score_name).addKey("board_scroll_right", Utils::String::toString(this->entries[i].board_scroll_right)); ini(score_name).addKey("board_scroll_up", Utils::String::toString(this->entries[i].board_scroll_up)); ini(score_name).addKey("board_scroll_down", Utils::String::toString(this->entries[i].board_scroll_down)); } std::stringstream contents; ini.dump(contents); std::ofstream file; file.open(score_file.c_str()); file << Utils::Base64::encode(contents.str()); file.close(); }
void Profile::saveSettings() { // Even if the file doesn't exist, we'll create it. INI::Parser* ini; try { ini = new INI::Parser(this->fileSettings); } catch(std::runtime_error& e) { ini = new INI::Parser(); ini->create(); } std::string buffer; // Other macro to avoid typing, similar to the one // at loadFile() #define INI_SET(out, in, var) \ { \ buffer = Utils::String::toString(var); \ ini->top().addGroup(out); \ (* ini)(out).addKey(in, buffer); \ } INI_SET("screen", "center_horizontal", settings.screen.center_horizontally); INI_SET("screen", "center_vertical", settings.screen.center_vertically); INI_SET("screen", "borders", settings.screen.show_borders); INI_SET("screen", "fancy_borders", settings.screen.fancy_borders); INI_SET("screen", "outer_border", settings.screen.outer_border); INI_SET("screen", "colors", settings.screen.use_colors); INI_SET("screen", "statistics", settings.screen.show_statistics); INI_SET("screen", "animation_menu", settings.screen.animation_menu); INI_SET("screen", "animation_game", settings.screen.animation_game); // Game INI_SET("game", "next_pieces", settings.game.next_pieces); INI_SET("game", "ghost", settings.game.has_ghost); INI_SET("game", "hold", settings.game.can_hold); INI_SET("game", "game_over_animation", settings.game.has_game_over_animation); INI_SET("game", "line_clear_delay", settings.game.line_clear_delay); // Input Keys std::string key; key = InputManager::keyToString(InputManager::getBind("left")); INI_SET("input", "left", key); key = InputManager::keyToString(InputManager::getBind("right")); INI_SET("input", "right", key); key = InputManager::keyToString(InputManager::getBind("down")); INI_SET("input", "down", key); key = InputManager::keyToString(InputManager::getBind("drop")); INI_SET("input", "drop", key); key = InputManager::keyToString(InputManager::getBind("rotate_clockwise")); INI_SET("input", "rotate_clockwise", key); key = InputManager::keyToString(InputManager::getBind("rotate_counterclockwise")); INI_SET("input", "rotate_counterclockwise", key); key = InputManager::keyToString(InputManager::getBind("rotate_180")); INI_SET("input", "rotate_180", key); key = InputManager::keyToString(InputManager::getBind("pause")); INI_SET("input", "pause", key); key = InputManager::keyToString(InputManager::getBind("help")); INI_SET("input", "help", key); key = InputManager::keyToString(InputManager::getBind("hold")); INI_SET("input", "hold", key); key = InputManager::keyToString(InputManager::getBind("quit")); INI_SET("input", "quit", key); try { ini->saveAs(this->fileSettings); } catch(std::runtime_error& e) { // Couldn't save the file... // ... do nothing } // Now, to the Theme file! SAFE_DELETE(ini); try { ini = new INI::Parser(this->fileTheme); } catch(std::runtime_error& e) { ini = new INI::Parser(); ini->create(); } // FIXME: For now we're not dealing with colors, // only with block appearances! INI_SET("theme", "piece_colors", settings.theme.piece_has_colors); INI_SET("theme", "ghost_colors", settings.theme.ghost_has_colors); INI_SET("theme", "show_pivot_block", settings.theme.show_pivot_block); INI_SET("theme", "lock_piece_colors", settings.theme.lock_piece_color); try { ini->saveAs(this->fileTheme); } catch(std::runtime_error& e) { // Couldn't save the file... // ... do nothing } // std::string tmp; // #define INI_SET_THEME(var, text) // { // tmp = ini.get(text, var.appearance); // var.appearance[0] = tmp[0]; // var.appearance[1] = tmp[1]; // } // INI_SET_THEME(settings.theme.clear_line, "clear_line:block"); // INI_SET_THEME(settings.theme.piece_colorless, "piece_colorless:block"); // INI_SET_THEME(settings.theme.piece, "piece:block"); // INI_SET_THEME(settings.theme.ghost, "ghost:block"); // INI_SET_THEME(settings.theme.locked, "locked:block"); // INI_SET_THEME(settings.theme.invisible, "invisible:block"); // INI_SET_THEME(settings.theme.piece_S, "piece_S:block"); // INI_SET_THEME(settings.theme.piece_Z, "piece_Z:block"); // INI_SET_THEME(settings.theme.piece_O, "piece_O:block"); // INI_SET_THEME(settings.theme.piece_I, "piece_I:block"); // INI_SET_THEME(settings.theme.piece_L, "piece_L:block"); // INI_SET_THEME(settings.theme.piece_J, "piece_J:block"); // INI_SET_THEME(settings.theme.piece_T, "piece_T:block"); SAFE_DELETE(ini); }
Profile::Profile(std::string name): name(name), directory(Globals::Config::directory + name + "/"), fileSettings(directory + "settings.ini"), fileTheme(directory + "theme.ini"), fileStatistics(directory + "statistics.bin") { // Make sure we can load a default profile at startup // (meaning the global settings file must have a profile // name at `profiles:default`) if (! Utils::File::exists(Globals::Config::file)) { INI::Parser ini; ini.create(); ini.top().addGroup("profiles"); ini("profiles").addKey("default", name); try { ini.saveAs(Globals::Config::file); } catch(std::runtime_error& e) { // Couldn't save the file... // ... do nothing } } else { INI::Parser ini(Globals::Config::file); std::string buffer = ini("profiles")["default"]; if (buffer.empty()) { ini.top().addGroup("profiles"); ini("profiles").addKey("default", name); try { ini.saveAs(Globals::Config::file); } catch(std::runtime_error& e) { // Couldn't save the file... // ... do nothing } } } // Making sure default directories and files exist. if (! Utils::File::isDirectory(this->directory)) Utils::File::mkdir_p(this->directory); if (! Utils::File::exists(this->fileSettings)) Utils::File::create(this->fileSettings); if (! Utils::File::exists(this->fileTheme)) Utils::File::create(this->fileTheme); if (! Utils::File::exists(this->fileStatistics)) Utils::File::create(this->fileStatistics); // Now that the directories exist, let's make sure // it's on the global list of existing Profiles if (std::find(Profile::profiles.begin(), Profile::profiles.end(), name) == Profile::profiles.end()) { Profile::profiles.push_back(name); std::sort(Profile::profiles.begin(), Profile::profiles.end()); } // Starting all settings with default, hardcoded values. // Screen settings.screen.center_horizontally = true; settings.screen.center_vertically = true; settings.screen.show_borders = true; settings.screen.fancy_borders = true; settings.screen.outer_border = true; settings.screen.use_colors = true; settings.screen.show_statistics = true; settings.screen.animation_menu = std::string("random"); settings.screen.animation_game = std::string("none"); // Game settings.game.next_pieces = 7; settings.game.has_ghost = true; settings.game.can_hold = true; settings.game.has_game_over_animation = true; settings.game.line_clear_delay = 200; // ms // Theme settings.theme.text = ColorPair(); settings.theme.hilite_text = Colors::pair("cyan", "default"); settings.theme.textbox = settings.theme.hilite_text.reverse(); settings.theme.piece_has_colors = true; settings.theme.ghost_has_colors = true; settings.theme.show_pivot_block = false; settings.theme.lock_piece_color = false; settings.theme.clear_line = new Block(Colors::pair("white", "default"), ':', ':'); settings.theme.piece_colorless = new Block(Colors::pair("black", "white"), ' ', ' '); settings.theme.piece = new Block(Colors::pair("black", "white"), ' ', ' '); settings.theme.ghost = new Block(Colors::pair("black", "white", true), '[', ']'); settings.theme.locked = new Block(Colors::pair("white", "white"), ' ', ' '); settings.theme.invisible = new Block(Colors::pair("white", "default"), ' ', ' '); settings.theme.piece_S = new Block(Colors::pair("white", "green"), ' ', ' '); settings.theme.piece_Z = new Block(Colors::pair("white", "red"), ' ', ' '); settings.theme.piece_O = new Block(Colors::pair("white", "yellow"), ' ', ' '); settings.theme.piece_I = new Block(Colors::pair("white", "cyan", true), ' ', ' '); settings.theme.piece_L = new Block(Colors::pair("white", "yellow", true), ' ', ' '); settings.theme.piece_J = new Block(Colors::pair("white", "blue"), ' ', ' '); settings.theme.piece_T = new Block(Colors::pair("white", "magenta"), ' ', ' '); this->resetKeybindings(); this->scores = new ScoreFile(); }
void Globals::saveFile() { // Even if the file doesn't exist, we'll create it. INI::Parser* ini; try { ini = new INI::Parser(Globals::Config::file); } catch(std::runtime_error& e) { ini = new INI::Parser(); ini->create(); } // Will be used on this macro below std::string buffer; // Other macro to avoid typing, similar to the one // at loadFile() #define INI_SET(out, in, var) \ { \ buffer = Utils::String::toString(var); \ ini->top().addGroup(out); \ (* ini)(out).addKey(in, buffer); \ } INI_SET("screen", "center_horizontal", EngineGlobals::Screen::center_horizontally); INI_SET("screen", "center_vertical", EngineGlobals::Screen::center_vertically); INI_SET("screen", "borders", EngineGlobals::Screen::show_borders); INI_SET("screen", "fancy_borders", EngineGlobals::Screen::fancy_borders); INI_SET("screen", "outer_border", EngineGlobals::Screen::outer_border); INI_SET("game", "random_walls", Globals::Game::random_walls); INI_SET("game", "fruits_at_once", Globals::Game::fruits_at_once); INI_SET("game", "teleport", Globals::Game::teleport); INI_SET("game", "board_scroll_delay", Globals::Game::board_scroll_delay); INI_SET("game", "board_scroll_up", Globals::Game::board_scroll_up); INI_SET("game", "board_scroll_down", Globals::Game::board_scroll_down); INI_SET("game", "board_scroll_left", Globals::Game::board_scroll_left); INI_SET("game", "board_scroll_right", Globals::Game::board_scroll_right); // unsigned ints are the exception - their overloading // is ambiguous... I should consider removing them altogether int starting_speed = Globals::Game::starting_speed; buffer = Utils::String::toString(starting_speed); ini->top().addGroup("game"); (* ini)("game").addKey("starting_speed", buffer); // Special Cases // Input Keys std::string key; key = InputManager::keyToString(InputManager::getBind("left")); INI_SET("input", "left", key); key = InputManager::keyToString(InputManager::getBind("right")); INI_SET("input", "right", key); key = InputManager::keyToString(InputManager::getBind("up")); INI_SET("input", "up", key); key = InputManager::keyToString(InputManager::getBind("down")); INI_SET("input", "down", key); key = InputManager::keyToString(InputManager::getBind("pause")); INI_SET("input", "pause", key); key = InputManager::keyToString(InputManager::getBind("help")); INI_SET("input", "help", key); key = InputManager::keyToString(InputManager::getBind("quit")); INI_SET("input", "quit", key); // Board size int board_size = Globals::Game::boardSizeToInt(Globals::Game::board_size); INI_SET("game", "board_size", board_size); try { ini->saveAs(Globals::Config::file); } catch(std::runtime_error& e) { // Couldn't save the file... // ... do nothing } SAFE_DELETE(ini); }