Esempio n. 1
0
/**
 * DoRestore
 */
static bool DoRestore() {
	Common::InSaveFile *f =  _vm->getSaveFileMan()->openForLoading(g_savedFiles[g_RestoreGameNumber].name);

	if (f == NULL) {
		return false;
	}

	Common::Serializer s(f, 0);
	SaveGameHeader hdr;
	if (!syncSaveGameHeader(s, hdr)) {
		delete f;	// Invalid header, or savegame too new -> skip it
		return false;
	}

	DoSync(s);

	uint32 id = f->readSint32LE();
	if (id != (uint32)0xFEEDFACE)
		error("Incompatible saved game");

	bool failed = (f->eos() || f->err());

	delete f;

	if (failed) {
		GUI::MessageDialog dialog(_("Failed to load game state from file."));
		dialog.runModal();
	}

	return !failed;
}
Esempio n. 2
0
/**
 * Compute a list of all available saved game files.
 * Store the file details, ordered by time, in savedFiles[] and return
 * the number of files found.
 */
int getList(Common::SaveFileManager *saveFileMan, const Common::String &target) {
	// No change since last call?
	// TODO/FIXME: Just always reload this data? Be careful about slow downs!!!
	if (!g_NeedLoad)
		return g_numSfiles;

	int i;

	const Common::String pattern = target +  ".???";
	Common::StringArray files = saveFileMan->listSavefiles(pattern);

	g_numSfiles = 0;

	for (Common::StringArray::const_iterator file = files.begin(); file != files.end(); ++file) {
		if (g_numSfiles >= MAX_SAVED_FILES)
			break;

		const Common::String &fname = *file;
		Common::InSaveFile *f = saveFileMan->openForLoading(fname);
		if (f == NULL) {
			continue;
		}

		// Try to load save game header
		Common::Serializer s(f, 0);
		SaveGameHeader hdr;
		bool validHeader = syncSaveGameHeader(s, hdr);
		delete f;
		if (!validHeader) {
			continue;	// Invalid header, or savegame too new -> skip it
			// TODO: In SCUMM, we still show an entry for the save, but with description
			// "incompatible version".
		}

		i = g_numSfiles;
#ifndef DISABLE_SAVEGAME_SORTING
		for (i = 0; i < g_numSfiles; i++) {
			if (cmpTimeDate(hdr.dateTime, g_savedFiles[i].dateTime) > 0) {
				Common::copy_backward(&g_savedFiles[i], &g_savedFiles[g_numSfiles], &g_savedFiles[g_numSfiles + 1]);
				break;
			}
		}
#endif

		Common::strlcpy(g_savedFiles[i].name, fname.c_str(), FNAMELEN);
		Common::strlcpy(g_savedFiles[i].desc, hdr.desc, SG_DESC_LEN);
		g_savedFiles[i].dateTime = hdr.dateTime;

		++g_numSfiles;
	}

	// Next getList() needn't do its stuff again
	g_NeedLoad = false;

	return g_numSfiles;
}
Esempio n. 3
0
/**
 * DoSave
 */
static void DoSave() {
	Common::OutSaveFile *f;
	const char *fname;

	// Next getList() must do its stuff again
	NeedLoad = true;

	if (SaveSceneName == NULL)
		SaveSceneName = NewName();
	if (SaveSceneDesc[0] == 0)
		SaveSceneDesc = "unnamed";

	fname = SaveSceneName;

	f = _vm->getSaveFileMan()->openForSaving(fname);
	Common::Serializer s(0, f);

	if (f == NULL)
		goto save_failure;

	// Write out a savegame header
	SaveGameHeader hdr;
	hdr.id = SAVEGAME_ID;
	hdr.size = SAVEGAME_HEADER_SIZE;
	hdr.ver = CURRENT_VER;
	memcpy(hdr.desc, SaveSceneDesc, SG_DESC_LEN);
	hdr.desc[SG_DESC_LEN - 1] = 0;
	g_system->getTimeAndDate(hdr.dateTime);
	if (!syncSaveGameHeader(s, hdr) || f->err()) {
		goto save_failure;
	}

	DoSync(s);

	// Write out the special Id for Discworld savegames
	f->writeUint32LE(0xFEEDFACE);
	if (f->err())
		goto save_failure;

	f->finalize();
	delete f;
	return;

save_failure:
	if (f) {
		delete f;
		_vm->getSaveFileMan()->removeSavefile(fname);
	}
	GUI::MessageDialog dialog("Failed to save game state to file.");
	dialog.runModal();
}
Esempio n. 4
0
/**
 * DoRestore
 */
static bool DoRestore() {
	Common::InSaveFile *f =  _vm->getSaveFileMan()->openForLoading(g_savedFiles[g_RestoreGameNumber].name);

	if (f == NULL) {
		return false;
	}

	Common::Serializer s(f, 0);
	SaveGameHeader hdr;
	if (!syncSaveGameHeader(s, hdr)) {
		delete f;	// Invalid header, or savegame too new -> skip it
		return false;
	}
	
	// Load in the data. For older savegame versions, we potentially need to load the data twice, once
	// for pre 1.5 savegames, and if that fails, a second time for 1.5 savegames
	int numInterpreters = hdr.numInterpreters;
	int32 currentPos = f->pos();
	for (int tryNumber = 0; tryNumber < ((hdr.ver >= 2) ? 1 : 2); ++tryNumber) {
		// If it's the second loop iteration, try with the 1.5 savegame number of interpreter contexts
		if (tryNumber == 1) {
			f->seek(currentPos);
			numInterpreters = 80;
		}

		// Load the savegame data
		if (DoSync(s, numInterpreters))
			// Data load was successful (or likely), so break out of loop
			break;
	}

	uint32 id = f->readSint32LE();
	if (id != (uint32)0xFEEDFACE)
		error("Incompatible saved game");

	bool failed = (f->eos() || f->err());

	delete f;

	if (failed) {
		GUI::MessageDialog dialog(_("Failed to load game state from file."));
		dialog.runModal();
	}

	return !failed;
}
Esempio n. 5
0
/**
 * DoSave
 */
static void DoSave() {
	Common::OutSaveFile *f;
	char tmpName[FNAMELEN];

	// Next getList() must do its stuff again
	g_NeedLoad = true;

	if (g_SaveSceneName == NULL) {
		// Generate a new unique save name
		int	i;
		int	ano = 1;	// Allocated number

		while (1) {
			Common::String fname = _vm->getSavegameFilename(ano);
			strcpy(tmpName, fname.c_str());

			for (i = 0; i < g_numSfiles; i++)
				if (!strcmp(g_savedFiles[i].name, tmpName))
					break;

			if (i == g_numSfiles)
				break;
			ano++;
		}

		g_SaveSceneName = tmpName;
	}


	if (g_SaveSceneDesc[0] == 0)
		g_SaveSceneDesc = "unnamed";

	f = _vm->getSaveFileMan()->openForSaving(g_SaveSceneName);
	Common::Serializer s(0, f);

	if (f == NULL) {
		SaveFailure(f);
		return;
	}

	// Write out a savegame header
	SaveGameHeader hdr;
	hdr.id = SAVEGAME_ID;
	hdr.size = SAVEGAME_HEADER_SIZE;
	hdr.ver = CURRENT_VER;
	memcpy(hdr.desc, g_SaveSceneDesc, SG_DESC_LEN);
	hdr.desc[SG_DESC_LEN - 1] = 0;
	g_system->getTimeAndDate(hdr.dateTime);
	hdr.scnFlag = _vm->getFeatures() & GF_SCNFILES;
	hdr.language = _vm->_config->_language;

	if (!syncSaveGameHeader(s, hdr) || f->err()) {
		SaveFailure(f);
		return;
	}

	DoSync(s, hdr.numInterpreters);

	// Write out the special Id for Discworld savegames
	f->writeUint32LE(0xFEEDFACE);
	if (f->err()) {
		SaveFailure(f);
		return;
	}

	f->finalize();
	delete f;
	g_SaveSceneName = NULL;	// Invalidate save name
}
Esempio n. 6
0
/**
 * DoSave
 */
static void DoSave() {
	Common::OutSaveFile *f;
	char tmpName[FNAMELEN];

	// Next getList() must do its stuff again
	NeedLoad = true;

	if (SaveSceneName == NULL) {
		// Generate a new unique save name	
		int	i;
		int	ano = 1;	// Allocated number

		while (1) {
			Common::String fname = _vm->getSavegameFilename(ano);
			strcpy(tmpName, fname.c_str());

			for (i = 0; i < numSfiles; i++)
				if (!strcmp(savedFiles[i].name, tmpName))
					break;

			if (i == numSfiles)
				break;
			ano++;
		}

		SaveSceneName = tmpName;
	}


	if (SaveSceneDesc[0] == 0)
		SaveSceneDesc = "unnamed";

	f = _vm->getSaveFileMan()->openForSaving(SaveSceneName);
	Common::Serializer s(0, f);

	if (f == NULL)
		goto save_failure;

	// Write out a savegame header
	SaveGameHeader hdr;
	hdr.id = SAVEGAME_ID;
	hdr.size = SAVEGAME_HEADER_SIZE;
	hdr.ver = CURRENT_VER;
	memcpy(hdr.desc, SaveSceneDesc, SG_DESC_LEN);
	hdr.desc[SG_DESC_LEN - 1] = 0;
	g_system->getTimeAndDate(hdr.dateTime);
	if (!syncSaveGameHeader(s, hdr) || f->err()) {
		goto save_failure;
	}

	DoSync(s);

	// Write out the special Id for Discworld savegames
	f->writeUint32LE(0xFEEDFACE);
	if (f->err())
		goto save_failure;

	f->finalize();
	delete f;
	SaveSceneName = NULL;	// Invalidate save name
	return;

save_failure:
	if (f) {
		delete f;
		_vm->getSaveFileMan()->removeSavefile(SaveSceneName);
		SaveSceneName = NULL;	// Invalidate save name
	}
	GUI::MessageDialog dialog("Failed to save game state to file.");
	dialog.runModal();
}