Пример #1
0
bool GameLoader::writeSavegame(Scene *sc, const char *fname) {
	GameVar *v = _gameVar->getSubVarByName("OBJSTATES")->getSubVarByName("SAVEGAME");

	if (!v) {
		v = _gameVar->getSubVarByName("OBJSTATES")->addSubVarAsInt("SAVEGAME", 0);

		if (!v) {
			warning("No state to save");
			return false;
		}
	}

	SaveHeader header;

	v->setSubVarAsInt("Scene", sc->_sceneId);

	saveScenePicAniInfos(sc->_sceneId);
	memset(&header, 0, sizeof(header));

	header.version = 48; // '0'
	strcpy(header.magic, "FullPipe Savegame");
	header.updateCounter = _updateCounter;
	header.unkField = 1;

	Common::MemoryWriteStreamDynamic stream;

	MfcArchive *archive = new MfcArchive(&stream);

	v = _gameVar->getSubVarByName("OBJSTATES");

	GameVar *nxt = 0;
	GameVar *prv = 0;
	GameVar *par;
	if (v) {
		nxt = v->_nextVarObj;
		prv = v->_prevVarObj;
		par = v->_parentVarObj;
		v->_parentVarObj = 0;
		v->_nextVarObj = 0;
		v->_prevVarObj = 0;
	}

	archive->writeObject(v);

	if (v) {
		v->_parentVarObj = par;
		v->_nextVarObj = nxt;
		v->_prevVarObj = prv;
	}

	getGameLoaderInventory()->savePartial(*archive);

	archive->writeUint32LE(_sc2array.size());

	debugC(3, kDebugLoading, "Saving %d infos", _sc2array.size());

	for (uint i = 0; i < _sc2array.size(); i++) {
		archive->writeUint32LE(_sc2array[i]._picAniInfosCount);

		if (_sc2array[i]._picAniInfosCount)
			debugC(3, kDebugLoading, "Count %d: %d", i, _sc2array[i]._picAniInfosCount);

		for (uint j = 0; j < _sc2array[i]._picAniInfosCount; j++) {
			_sc2array[i]._picAniInfos[j]->save(*archive);
		}
	}

	header.encSize = stream.size();

	// Now obfuscate the data
	for (uint i = 0; i < header.encSize; i++)
		stream.getData()[i] += i & 0x7f;

	if (_savegameCallback)
		_savegameCallback(archive, true);

	// Now dump it into save file
	Common::OutSaveFile *saveFile = g_system->getSavefileManager()->openForSaving(fname);

	if (!saveFile) {
		warning("Cannot open file for writing: %s", fname);
		return false;
	}

	saveFile->writeUint32LE(header.version);
	saveFile->write(header.magic, 32);
	saveFile->writeUint32LE(header.updateCounter);
	saveFile->writeUint32LE(header.unkField);
	saveFile->writeUint32LE(header.encSize);

	debugC(3, kDebugLoading, "version: %d magic: %s updateCounter: %d unkField: %d encSize: %d, pos: %d",
			header.version, header.magic, header.updateCounter, header.unkField, header.encSize, saveFile->pos());

	saveFile->write(stream.getData(), stream.size());

	uint headerPos = saveFile->pos();
	FullpipeSavegameHeader header2;

	strcpy(header2.id, "SVMCR");
	header2.version = FULLPIPE_SAVEGAME_VERSION;

	TimeDate curTime;
	g_system->getTimeAndDate(curTime);

	header2.date = ((curTime.tm_mday & 0xFF) << 24) | (((curTime.tm_mon + 1) & 0xFF) << 16) | ((curTime.tm_year + 1900) & 0xFFFF);
	header2.time = ((curTime.tm_hour & 0xFF) << 8) | ((curTime.tm_min) & 0xFF);

	header2.playtime = g_fp->getTotalPlayTime() / 1000;

	saveFile->write(header2.id, 6);
	saveFile->writeByte(header2.version);
	saveFile->writeUint32LE(header2.date);
	saveFile->writeUint16LE(header2.time);
	saveFile->writeUint32LE(header2.playtime);

	g_fp->_currentScene->draw();

	Graphics::saveThumbnail(*saveFile); // FIXME. Render proper screen

	saveFile->writeUint32LE(headerPos);	// Store where the header starts

	saveFile->finalize();

	delete saveFile;
	delete archive;

	return true;
}