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();
}
Exemple #2
0
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);
}
Exemple #3
0
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();
}
Exemple #4
0
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);
}