Beispiel #1
0
void savegame::finish_save_game(const config_writer &out)
{
	std::string name = gamestate_.classification().label;
	replace_space2underbar(name);
	std::string fname(get_saves_dir() + "/" + name);

	try {
		if(!out.good()) {
			throw game::save_game_failed(_("Could not write to file"));
		}

		config& summary = save_index::save_summary(gamestate_.classification().label);
		extract_summary_data_from_save(summary);
		const int mod_time = static_cast<int>(file_create_time(fname));
		summary["mod_time"] = str_cast(mod_time);
		save_index::write_save_index();
	} catch(io_exception& e) {
		throw game::save_game_failed(e.what());
	}
}
Beispiel #2
0
void savegame::write_game_to_disk(const std::string& filename)
{
	filename_ = filename;
	filename_ += ".sav";

	std::stringstream ss;
	{
		config_writer out(ss, false);
		write_game(out);
	}

	// start scenario data(write it to stream only first, others write stream to file direct)
	if (!gamestate_.start_scenario_ss.str().length()) {
		::write(gamestate_.start_scenario_ss, gamestate_.starting_pos);
	}
	if (!gamestate_.start_hero_data_) {
		gamestate_.start_hero_data_ = (uint8_t*)malloc(heros_start_.file_size());
		heros_start_.map_to_mem(gamestate_.start_hero_data_);
	}

	config cfg_summary;
	std::stringstream summary_ss;
	extract_summary_data_from_save(cfg_summary);
	::write(summary_ss, cfg_summary);

	// if enable compress, ss.str() is compressed format data.
	posix_file_t fp;
	uint32_t summary_size, scenario_size, side_size, start_scenario_size, start_hero_size, replay_size, hero_size, member_data_size, bytertd;
	int size;

	// replace_space2underbar(filename_);
	std::string fullfilename = get_saves_dir() + "/" + filename_;
#ifdef _WIN32
	// utf8 ---> utf16
	int wlen = MultiByteToWideChar(CP_UTF8, 0, fullfilename.c_str(), -1, NULL, 0);
	WCHAR *wc = new WCHAR[wlen];
	MultiByteToWideChar(CP_UTF8, 0, fullfilename.c_str(), -1, wc, wlen);
			
	fp = CreateFileW(wc, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
			CREATE_ALWAYS, 0, NULL);
	// posix_fopen(wc, GENERIC_WRITE, CREATE_ALWAYS, fp);
	delete [] wc;
#else
	posix_fopen(fullfilename.c_str(), GENERIC_WRITE, CREATE_ALWAYS, fp);
#endif
	
	if (fp == INVALID_FILE) {
		throw game::save_game_failed(_("Could not write to file"));
	}

	// length of summary data
	summary_size = summary_ss.str().length();
	// length of scenario data
	scenario_size = ss.str().length();
	// length of side data
	side_size = ((unit_segment2*)game_config::savegame_cache)->size_;
	// length of start scenario data
	start_scenario_size = gamestate_.start_scenario_ss.str().length();
	// length of start hero data
	start_hero_size = heros_start_.file_size();
	// length of replay data
	if (gamestate_.replay_data.pool_pos_vsize()) {
		replay_size = 16 + gamestate_.replay_data.pool_data_gzip_size() + gamestate_.replay_data.pool_pos_vsize() * sizeof(unsigned int);
	} else {
		replay_size = 0;
	}
	// length of runtime hero data
	hero_size = heros_.file_size();
	// length of runtime-member data
	member_data_size = runtime_groups::size();

	// [write] length of summary data
	posix_fwrite(fp, &summary_size, sizeof(summary_size), bytertd);
	// [write] length of scenario data
	posix_fwrite(fp, &scenario_size, sizeof(scenario_size), bytertd);
	// [write] length of side data
	posix_fwrite(fp, &side_size, sizeof(side_size), bytertd);
	// [write] length of start scenario data
	posix_fwrite(fp, &start_scenario_size, sizeof(start_scenario_size), bytertd);
	// [write] length of start hero data
	posix_fwrite(fp, &start_hero_size, sizeof(start_hero_size), bytertd);
	// [write] length of replay data
	posix_fwrite(fp, &replay_size, sizeof(replay_size), bytertd);
	// [write] length of runtime hero data
	posix_fwrite(fp, &hero_size, sizeof(hero_size), bytertd);
	// [write] length of member data
	posix_fwrite(fp, &member_data_size, sizeof(member_data_size), bytertd);

	// summary data
	posix_fwrite(fp, summary_ss.str().c_str(), summary_ss.str().length(), bytertd);
	// scenario data
	posix_fwrite(fp, ss.str().c_str(), ss.str().length(), bytertd);
	// side data
	if (side_size) {
		posix_fwrite(fp, game_config::savegame_cache, side_size, bytertd);
	}
	// start scenario data
	posix_fwrite(fp, gamestate_.start_scenario_ss.str().c_str(), gamestate_.start_scenario_ss.str().length(), bytertd);
	// start hero data
	posix_fwrite(fp, gamestate_.start_hero_data_, start_hero_size, bytertd);
	
	// replay data
	if (replay_size) {
		size = gamestate_.replay_data.pool_data_size();
		posix_fwrite(fp, &size, sizeof(size), bytertd);
		size = gamestate_.replay_data.pool_data_gzip_size();
		posix_fwrite(fp, &size, sizeof(size), bytertd);
		size = gamestate_.replay_data.pool_pos_size();
		posix_fwrite(fp, &size, sizeof(size), bytertd);
		size = gamestate_.replay_data.pool_pos_vsize();
		posix_fwrite(fp, &size, sizeof(size), bytertd);
		// pool data
		posix_fwrite(fp, gamestate_.replay_data.pool_data(), gamestate_.replay_data.pool_data_gzip_size(), bytertd);
		// pool pos
		posix_fwrite(fp, gamestate_.replay_data.pool_pos(), gamestate_.replay_data.pool_pos_vsize() * sizeof(unsigned int), bytertd);
	}

	// hero data
	heros_.map_to_file_fp(fp);
	// member data
	runtime_groups::to_fp(fp); 

	posix_fclose(fp);
}