Beispiel #1
0
SaveStateDescriptor DreamWebMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
	Common::String filename = Common::String::format("DREAMWEB.D%02d", slot);
	Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(filename.c_str());

	if (in) {
		DreamWeb::FileHeader header;
		in->read((uint8 *)&header, sizeof(DreamWeb::FileHeader));

		Common::String saveName;
		byte descSize = header.len(0);
		byte i;

		for (i = 0; i < descSize; i++)
			saveName += (char)in->readByte();

		SaveStateDescriptor desc(slot, saveName);

		// Check if there is a ScummVM data block
		if (header.len(6) == SCUMMVM_BLOCK_MAGIC_SIZE) {
			// Skip the game data
			for (i = 1; i <= 5; i++)
				in->skip(header.len(i));

			uint32 tag = in->readUint32BE();
			if (tag != SCUMMVM_HEADER) {
				warning("ScummVM data block found, but the block header is incorrect - skipping");
				delete in;
				return desc;
			}

			byte version = in->readByte();
			if (version > SAVEGAME_VERSION) {
				warning("ScummVM data block found, but it has been saved with a newer version of ScummVM - skipping");
				delete in;
				return desc;
			}

			uint32 saveDate = in->readUint32LE();
			uint32 saveTime = in->readUint32LE();
			uint32 playTime = in->readUint32LE();
			Graphics::Surface *thumbnail = Graphics::loadThumbnail(*in);

			int day = (saveDate >> 24) & 0xFF;
			int month = (saveDate >> 16) & 0xFF;
			int year = saveDate & 0xFFFF;
			int hour = (saveTime >> 16) & 0xFF;
			int minutes = (saveTime >> 8) & 0xFF;

			desc.setSaveDate(year, month, day);
			desc.setSaveTime(hour, minutes);
			desc.setPlayTime(playTime * 1000);
			desc.setThumbnail(thumbnail);
		}

		delete in;
		return desc;
	}

	return SaveStateDescriptor();
}
Beispiel #2
0
Common::HashMap<Common::String, uint32> DefaultSaveFileManager::loadTimestamps() {
	Common::HashMap<Common::String, uint32> timestamps;

	//refresh the files list
	Common::Array<Common::String> files;
	g_system->getSavefileManager()->updateSavefilesList(files);

	//start with listing all the files in saves/ directory and setting invalid timestamp to them
	Common::StringArray localFiles = g_system->getSavefileManager()->listSavefiles("*");
	for (uint32 i = 0; i < localFiles.size(); ++i)
		timestamps[localFiles[i]] = INVALID_TIMESTAMP;

	//now actually load timestamps from file
	Common::InSaveFile *file = g_system->getSavefileManager()->openRawFile(TIMESTAMPS_FILENAME);
	if (!file) {
		warning("DefaultSaveFileManager: failed to open '%s' file to load timestamps", TIMESTAMPS_FILENAME);
		return timestamps;
	}

	while (!file->eos()) {
		//read filename into buffer (reading until the first ' ')
		Common::String buffer;
		while (!file->eos()) {
			byte b = file->readByte();
			if (b == ' ') break;
			buffer += (char)b;
		}

		//read timestamp info buffer (reading until ' ' or some line ending char)
		Common::String filename = buffer;
		while (true) {
			bool lineEnded = false;
			buffer = "";
			while (!file->eos()) {
				byte b = file->readByte();
				if (b == ' ' || b == '\n' || b == '\r') {
					lineEnded = (b == '\n');
					break;
				}
				buffer += (char)b;
			}

			if (buffer == "" && file->eos()) break;
			if (!lineEnded) filename += " " + buffer;
			else break;
		}

		//parse timestamp
		uint32 timestamp = buffer.asUint64();
		if (buffer == "" || timestamp == 0) break;
		if (timestamps.contains(filename))
			timestamps[filename] = timestamp;
	}

	delete file;
	return timestamps;
}
Beispiel #3
0
void GraphicsManager::showThumbnail(const Common::String &filename, int atX, int atY) {
	Common::InSaveFile *fp = g_system->getSavefileManager()->openForLoading(filename);

	if (fp == nullptr)
		return;

	bool headerBad = false;
	if (fp->readByte() != 'S')
		headerBad = true;
	if (fp->readByte() != 'L')
		headerBad = true;
	if (fp->readByte() != 'U')
		headerBad = true;
	if (fp->readByte() != 'D')
		headerBad = true;
	if (fp->readByte() != 'S')
		headerBad = true;
	if (fp->readByte() != 'A')
		headerBad = true;
	if (headerBad) {
		fatal(ERROR_GAME_LOAD_NO, filename);
		return;
	}
	char c = fp->readByte();
	while ((c = fp->readByte()))
		;

	int majVersion = fp->readByte();
	int minVersion = fp->readByte();
	int ssgVersion = VERSION(majVersion, minVersion);

	if (ssgVersion >= VERSION(1, 4)) {
		int fileWidth = fp->readUint32LE();
		int fileHeight = fp->readUint32LE();

		Graphics::TransparentSurface thumbnail;
		if (!ImgLoader::loadPNGImage(fp, &thumbnail))
			return;

		delete fp;
		fp = nullptr;


		if (atX < 0) {
			fileWidth += atX;
			atX = 0;
		}
		if (atY < 0) {
			fileHeight += atY;
			atY = 0;
		}
		if (fileWidth + atX > (int)_sceneWidth)
			fileWidth = _sceneWidth - atX;
		if (fileHeight + atY > (int)_sceneHeight)
			fileHeight = _sceneHeight - atY;

		thumbnail.blit(_backdropSurface, atX, atY, Graphics::FLIP_NONE, nullptr, TS_ARGB(255, 255, 255, 255), fileWidth, fileHeight);
		thumbnail.free();
	}
}
Beispiel #4
0
SaveStateDescriptor HugoMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
	Common::String fileName = Common::String::format("%s-%02d.SAV", target, slot);
	Common::InSaveFile *file = g_system->getSavefileManager()->openForLoading(fileName);

	if (file) {
		int saveVersion = file->readByte();

		if (saveVersion != kSavegameVersion) {
			warning("Savegame of incompatible version");
			delete file;
			return SaveStateDescriptor();
		}

		uint32 saveNameLength = file->readUint16BE();
		char saveName[256];
		file->read(saveName, saveNameLength);
		saveName[saveNameLength] = 0;

		SaveStateDescriptor desc(slot, saveName);

		Graphics::Surface *thumbnail = new Graphics::Surface();
		assert(thumbnail);
		if (!Graphics::loadThumbnail(*file, *thumbnail)) {
			delete thumbnail;
			thumbnail = 0;
		}
		desc.setThumbnail(thumbnail);

		desc.setDeletableFlag(true);
		desc.setWriteProtectedFlag(false);

		uint32 saveDate = file->readUint32BE();
		uint16 saveTime = file->readUint16BE();

		int day = (saveDate >> 24) & 0xFF;
		int month = (saveDate >> 16) & 0xFF;
		int year = saveDate & 0xFFFF;

		desc.setSaveDate(year, month, day);

		int hour = (saveTime >> 8) & 0xFF;
		int minutes = saveTime & 0xFF;

		desc.setSaveTime(hour, minutes);

		// Slot 0 is used for the 'restart game' save in all Hugo games, thus
		// we prevent it from being deleted.
		desc.setDeletableFlag(slot != 0);
		desc.setWriteProtectedFlag(slot == 0);

		delete file;
		return desc;
	}
	return SaveStateDescriptor();
}
Beispiel #5
0
SaveStateDescriptor AgiMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
	const uint32 AGIflag = MKTAG('A','G','I',':');
	char fileName[MAXPATHLEN];
	sprintf(fileName, "%s.%03d", target, slot);

	Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(fileName);

	if (in) {
		if (in->readUint32BE() != AGIflag) {
			delete in;
			return SaveStateDescriptor();
		}

		char name[32];
		in->read(name, 31);

		SaveStateDescriptor desc(slot, name);

		// Do not allow save slot 0 (used for auto-saving) to be deleted or
		// overwritten.
		desc.setDeletableFlag(slot != 0);
		desc.setWriteProtectedFlag(slot == 0);

		char saveVersion = in->readByte();
		if (saveVersion >= 4) {
			Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*in);

			desc.setThumbnail(thumbnail);

			uint32 saveDate = in->readUint32BE();
			uint16 saveTime = in->readUint16BE();
			if (saveVersion >= 6) {
				uint32 playTime = in->readUint32BE();
				desc.setPlayTime(playTime * 1000);
			}

			int day = (saveDate >> 24) & 0xFF;
			int month = (saveDate >> 16) & 0xFF;
			int year = saveDate & 0xFFFF;

			desc.setSaveDate(year, month, day);

			int hour = (saveTime >> 8) & 0xFF;
			int minutes = saveTime & 0xFF;

			desc.setSaveTime(hour, minutes);

			// TODO: played time
		}


		delete in;

		return desc;
	} else {
Beispiel #6
0
SaveStateDescriptor GnapMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
	Common::String fileName = Common::String::format("%s.%03d", target, slot);
	Common::InSaveFile *file = g_system->getSavefileManager()->openForLoading(fileName);
	if (file) {
		char saveIdentBuffer[5];
		file->read(saveIdentBuffer, 5);

		int32 version = file->readByte();
		if (version > GNAP_SAVEGAME_VERSION) {
			delete file;
			return SaveStateDescriptor();
		}

		Common::String saveName;
		char ch;
		while ((ch = (char)file->readByte()) != '\0')
			saveName += ch;

		SaveStateDescriptor desc(slot, saveName);

		if (version != 1) {
			Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*file);
			desc.setThumbnail(thumbnail);
		}

		int year = file->readSint16LE();
		int month = file->readSint16LE();
		int day = file->readSint16LE();
		int hour = file->readSint16LE();
		int minutes = file->readSint16LE();

		desc.setSaveDate(year, month, day);
		desc.setSaveTime(hour, minutes);

		delete file;
		return desc;
	}

	return SaveStateDescriptor();
}
Beispiel #7
0
SaveStateList AvalancheMetaEngine::listSaves(const char *target) const {
	Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
	Common::StringArray filenames;
	Common::String pattern = target;
	pattern.toUppercase();
	pattern += ".???";

	filenames = saveFileMan->listSavefiles(pattern);
	sort(filenames.begin(), filenames.end());   // Sort (hopefully ensuring we are sorted numerically..)

	SaveStateList saveList;
	for (Common::StringArray::const_iterator filename = filenames.begin(); filename != filenames.end(); ++filename) {
		const Common::String &fname = *filename;
		int slotNum = atoi(fname.c_str() + fname.size() - 3);
		if (slotNum >= 0 && slotNum <= getMaximumSaveSlot()) {
			Common::InSaveFile *file = saveFileMan->openForLoading(fname);
			if (file) {
				// Check for our signature.
				uint32 signature = file->readUint32LE();
				if (signature != MKTAG('A', 'V', 'A', 'L')) {
					warning("Savegame of incompatible type!");
					delete file;
					continue;
				}

				// Check version.
				byte saveVersion = file->readByte();
				if (saveVersion != kSavegameVersion) {
					warning("Savegame of incompatible version!");
					delete file;
					continue;
				}

				// Read name.
				uint32 nameSize = file->readUint32LE();
				if (nameSize >= 255) {
					delete file;
					continue;
				}
				char *name = new char[nameSize + 1];
				file->read(name, nameSize);
				name[nameSize] = 0;

				saveList.push_back(SaveStateDescriptor(slotNum, name));
				delete[] name;
				delete file;
			}
		}
	}

	return saveList;
}
Beispiel #8
0
int Minigame::loadHiscore(int minigameNum) {
	int score = 0;
	Common::String filename = _vm->getTargetName() + "-highscore.dat";
	Common::InSaveFile *file = g_system->getSavefileManager()->openForLoading(filename);
	if (file) {
		file->readByte();
		for (int i = 0; i < kMinigameCount; ++i)
			_hiScoreTable[i] = file->readUint32LE();
		delete file;
		score = _hiScoreTable[minigameNum];
	}
	return score;
}
Beispiel #9
0
SaveStateDescriptor AvalancheMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
	Common::String fileName = Common::String::format("%s.%03d", target, slot);
	Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(fileName);

	if (f) {
		// Check for our signature.
		uint32 signature = f->readUint32LE();
		if (signature != MKTAG('A', 'V', 'A', 'L')) {
			warning("Savegame of incompatible type!");
			delete f;
			return SaveStateDescriptor();
		}

		// Check version.
		byte saveVersion = f->readByte();
		if (saveVersion > kSavegameVersion) {
			warning("Savegame of a too recent version!");
			delete f;
			return SaveStateDescriptor();
		}

		// Read the description.
		uint32 descSize = f->readUint32LE();
		Common::String description;
		for (uint32 i = 0; i < descSize; i++) {
			char actChar = f->readByte();
			description += actChar;
		}

		SaveStateDescriptor desc(slot, description);

		Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*f);
		desc.setThumbnail(thumbnail);

		delete f;
		return desc;
	}
	return SaveStateDescriptor();
}
Beispiel #10
0
SaveStateDescriptor AdlMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
	Common::String fileName = Common::String::format("%s.s%02d", target, slot);
	Common::InSaveFile *inFile = g_system->getSavefileManager()->openForLoading(fileName);

	if (!inFile)
		return SaveStateDescriptor();

	if (inFile->readUint32BE() != MKTAG('A', 'D', 'L', ':')) {
		delete inFile;
		return SaveStateDescriptor();
	}

	byte saveVersion = inFile->readByte();
	if (saveVersion != SAVEGAME_VERSION) {
		delete inFile;
		return SaveStateDescriptor();
	}

	char name[SAVEGAME_NAME_LEN] = { };
	inFile->read(name, sizeof(name) - 1);
	inFile->readByte();

	if (inFile->eos() || inFile->err()) {
		delete inFile;
		return SaveStateDescriptor();
	}

	SaveStateDescriptor sd(slot, name);

	int year = inFile->readUint16BE();
	int month = inFile->readByte();
	int day = inFile->readByte();
	sd.setSaveDate(year + 1900, month + 1, day);

	int hour = inFile->readByte();
	int minutes = inFile->readByte();
	sd.setSaveTime(hour, minutes);

	uint32 playTime = inFile->readUint32BE();
	sd.setPlayTime(playTime);

	if (inFile->eos() || inFile->err()) {
		delete inFile;
		return SaveStateDescriptor();
	}

	Graphics::Surface *thumbnail;
	if (!Graphics::loadThumbnail(*inFile, thumbnail)) {
		delete inFile;
		return SaveStateDescriptor();
	}
	sd.setThumbnail(thumbnail);

	delete inFile;
	return sd;
}
Beispiel #11
0
SaveStateList AdlMetaEngine::listSaves(const char *target) const {
	Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
	Common::StringArray files = saveFileMan->listSavefiles(Common::String(target) + ".s##");

	SaveStateList saveList;

	for (uint i = 0; i < files.size(); ++i) {
		const Common::String &fileName = files[i];
		Common::InSaveFile *inFile = saveFileMan->openForLoading(fileName);
		if (!inFile) {
			warning("Cannot open save file '%s'", fileName.c_str());
			continue;
		}

		if (inFile->readUint32BE() != MKTAG('A', 'D', 'L', ':')) {
			warning("No header found in '%s'", fileName.c_str());
			delete inFile;
			continue;
		}

		byte saveVersion = inFile->readByte();
		if (saveVersion != SAVEGAME_VERSION) {
			warning("Unsupported save game version %i found in '%s'", saveVersion, fileName.c_str());
			delete inFile;
			continue;
		}

		char name[SAVEGAME_NAME_LEN] = { };
		inFile->read(name, sizeof(name) - 1);
		delete inFile;

		int slotNum = atoi(fileName.c_str() + fileName.size() - 2);
		SaveStateDescriptor sd(slotNum, name);
		saveList.push_back(sd);
	}

	// Sort saves based on slot number.
	Common::sort(saveList.begin(), saveList.end(), SaveStateDescriptorSlotComparator());
	return saveList;
}
Beispiel #12
0
void ToltecsEngine::loadgame(const char *filename) {
	Common::InSaveFile *in;
	if (!(in = g_system->getSavefileManager()->openForLoading(filename))) {
		warning("Can't open file '%s', game not loaded", filename);
		return;
	}

	SaveHeader header;

	kReadSaveHeaderError errorCode = readSaveHeader(in, false, header);
	
	if (errorCode != kRSHENoError) {
		warning("Error loading savegame '%s'", filename);
		delete in;
		return;
	}
	
	_sound->stopAll();
	_music->stopSequence();
	g_engine->setTotalPlayTime(header.playTime * 1000);

	_cameraX = in->readUint16LE();
	_cameraY = in->readUint16LE();
	_cameraHeight = in->readUint16LE();

	_guiHeight = in->readUint16LE();

	_sceneWidth = in->readUint16LE();
	_sceneHeight = in->readUint16LE();
	_sceneResIndex = in->readUint32LE();

	_walkSpeedX = in->readUint16LE();
	_walkSpeedY = in->readUint16LE();

	_counter01 = in->readUint32LE();
	_counter02 = in->readUint32LE();
	_movieSceneFlag = in->readByte() != 0;
	_flag01 = in->readByte();

	_mouseX = in->readUint16LE();
	_mouseY = in->readUint16LE();
	_mouseDisabled = in->readUint16LE();
	
	_system->warpMouse(_mouseX, _mouseY);
 	_system->showMouse(_mouseDisabled == 0);

	_palette->loadState(in);
	_script->loadState(in);
	_anim->loadState(in);
	_screen->loadState(in);
	if (header.version >= 2)
		_sound->loadState(in);
	if (header.version >= 3)
		_music->loadState(in);

	delete in;

	loadScene(_sceneResIndex);

	_newCameraX = _cameraX;
	_newCameraY = _cameraY;
}
Beispiel #13
0
Common::InSaveFile *SaveLoad::openForLoading(const Common::String &target, int slot, SaveStateDescriptor *descriptor) {
	// Validate the slot number
	if (!isSlotValid(slot)) {
		return nullptr;
	}

	// Open the savefile
	Common::String savename = getSlotSaveName(target, slot);
	Common::InSaveFile *savefile = g_system->getSavefileManager()->openForLoading(savename);
	if (!savefile) {
		return nullptr;
	}

	// Read the savefile version
	uint8 version;
	if (savefile->size() == 1024) {
		version = 0;
	} else {
		version = savefile->readByte();
	}

	// Verify we can read this version
	if (version > SUPPORTED_SAVEFILE_VERSION) {
		//TODO: show the error about unsupported savefile version
	}

	// Save the current position as the start for the engine data
	int metaDataSize = savefile->pos();

	// Fill the SaveStateDescriptor if it was provided
	if (descriptor) {
		// Initialize the SaveStateDescriptor
		descriptor->setSaveSlot(slot);

		// TODO: Add extra information
		//setSaveDate(int year, int month, int day)
		//setSaveTime(int hour, int min)
		//setPlayTime(int hours, int minutes)

		// Read the savegame description
		Common::String description;
		unsigned char c = 1;
		for (int i = 0; (c != 0) && (i < 15); i++) {
			c = savefile->readByte();
			switch (c) {
				case 0:
					break;
				case 16: // @
				// fall through intended
				case 254: // . (generated when pressing space)
					c = ' ';
					break;
				case 244: // $
					c = 0;
					break;
				default:
					c += 0x30;
			}
			if (c != 0) {
				description += c;
			}
		}
		descriptor->setDescription(description);
	}

	// Return a substream, skipping the metadata
	Common::SeekableSubReadStream *sub = new Common::SeekableSubReadStream(savefile, metaDataSize, savefile->size(), DisposeAfterUse::YES);

	// Move to the beginning of the substream
	sub->seek(0, SEEK_SET);

	return sub;
}
Beispiel #14
0
int AgiEngine::loadGame(const Common::String &fileName, bool checkId) {
	char description[31], saveVersion, loadId[8];
	int i, vtEntries = MAX_VIEWTABLE;
	uint8 t;
	int16 parm[7];
	Common::InSaveFile *in;

	debugC(3, kDebugLevelMain | kDebugLevelSavegame, "AgiEngine::loadGame(%s)", fileName.c_str());

	if (!(in = _saveFileMan->openForLoading(fileName))) {
		warning("Can't open file '%s', game not loaded", fileName.c_str());
		return errBadFileOpen;
	} else {
		debugC(3, kDebugLevelMain | kDebugLevelSavegame, "Successfully opened %s for reading", fileName.c_str());
	}

	uint32 typea = in->readUint32BE();
	if (typea == AGIflag) {
		debugC(6, kDebugLevelMain | kDebugLevelSavegame, "Has AGI flag, good start");
	} else {
		warning("This doesn't appear to be an AGI savegame, game not restored");
		delete in;
		return errOK;
	}

	in->read(description, 31);

	debugC(6, kDebugLevelMain | kDebugLevelSavegame, "Description is: %s", description);

	saveVersion = in->readByte();
	if (saveVersion < 2)	// is the save game pre-ScummVM?
		warning("Old save game version (%d, current version is %d). Will try and read anyway, but don't be surprised if bad things happen", saveVersion, SAVEGAME_VERSION);

	if (saveVersion < 3)
		warning("This save game contains no AGIPAL data, if the game is using the AGIPAL hack, it won't work correctly");

	if (saveVersion >= 4) {
		// We don't need the thumbnail here, so just read it and discard it
		Graphics::skipThumbnail(*in);

		in->readUint32BE();	// save date
		in->readUint16BE(); // save time
		// TODO: played time
	}

	_game.state = (State)in->readByte();

	in->read(loadId, 8);
	if (strcmp(loadId, _game.id) && checkId) {
		delete in;
		warning("This save seems to be from a different AGI game (save from %s, running %s), not loaded", loadId, _game.id);
		return errBadFileOpen;
	}

	strncpy(_game.id, loadId, 8);

	if (saveVersion >= 5) {
		char md5[32 + 1];

		for (i = 0; i < 32; i++) {
			md5[i] = in->readByte();

		}
		md5[i] = 0; // terminate

		// As noted above in AgiEngine::saveGame the MD5 sum field may be all zero
		// when the save was made via a fallback matched game. In this case we will
		// replace the MD5 sum with a nicer string, so that the user can easily see
		// this fact in the debug output. The string saved in "md5" will never match
		// any valid MD5 sum, thus it is safe to do that here.
		if (md5[0] == 0)
			strcpy(md5, "fallback matched");

		debug(0, "Saved game MD5: \"%s\"", md5);

		if (!getGameMD5()) {
			warning("Since your game was only detected via the fallback detector, there is no possibility to assure the save is compatible with your game version");

			debug(0, "The game used for saving is \"%s\".", md5);
		} else if (strcmp(md5, getGameMD5())) {
			warning("Game was saved with different gamedata - you may encounter problems");

			debug(0, "Your game is \"%s\" and save is \"%s\".", getGameMD5(), md5);
		}
	}

	for (i = 0; i < MAX_FLAGS; i++)
		_game.flags[i] = in->readByte();
	for (i = 0; i < MAX_VARS; i++)
		_game.vars[i] = in->readByte();

	setvar(vFreePages, 180); // Set amount of free memory to realistic value (Overwriting the just loaded value)

	_game.horizon = in->readSint16BE();
	_game.lineStatus = in->readSint16BE();
	_game.lineUserInput = in->readSint16BE();
	_game.lineMinPrint = in->readSint16BE();

	// These are never saved
	_game.cursorPos = 0;
	_game.inputBuffer[0] = 0;
	_game.echoBuffer[0] = 0;
	_game.keypress = 0;

	_game.inputMode = (InputMode)in->readSint16BE();
	_game.lognum = in->readSint16BE();

	_game.playerControl = in->readSint16BE();
	if (in->readSint16BE())
		quitGame();
	_game.statusLine = in->readSint16BE();
	_game.clockEnabled = in->readSint16BE();
	_game.exitAllLogics = in->readSint16BE();
	_game.pictureShown = in->readSint16BE();
	_game.hasPrompt = in->readSint16BE();
	_game.gameFlags = in->readSint16BE();
	_game.inputEnabled = in->readSint16BE();

	for (i = 0; i < _HEIGHT; i++)
		_game.priTable[i] = in->readByte();

	if (_game.hasWindow)
		closeWindow();

	_game.msgBoxTicks = 0;
	_game.block.active = false;
	// game.window - fixed by close_window()
	// game.has_window - fixed by close_window()

	_game.gfxMode = in->readSint16BE();
	_game.cursorChar = in->readByte();
	_game.colorFg = in->readSint16BE();
	_game.colorBg = in->readSint16BE();

	// game.hires - rebuilt from image stack
	// game.sbuf - rebuilt from image stack

	// game.ego_words - fixed by clean_input
	// game.num_ego_words - fixed by clean_input

	_game.numObjects = in->readSint16BE();
	for (i = 0; i < (int16)_game.numObjects; i++)
		objectSetLocation(i, in->readSint16BE());

	// Those are not serialized
	for (i = 0; i < MAX_DIRS; i++) {
		_game.controllerOccured[i] = false;
	}

	for (i = 0; i < MAX_STRINGS; i++)
		in->read(_game.strings[i], MAX_STRINGLEN);

	for (i = 0; i < MAX_DIRS; i++) {
		if (in->readByte() & RES_LOADED)
			agiLoadResource(rLOGIC, i);
		else
			agiUnloadResource(rLOGIC, i);
		_game.logics[i].sIP = in->readSint16BE();
		_game.logics[i].cIP = in->readSint16BE();
	}

	for (i = 0; i < MAX_DIRS; i++) {
		if (in->readByte() & RES_LOADED)
			agiLoadResource(rPICTURE, i);
		else
			agiUnloadResource(rPICTURE, i);
	}

	for (i = 0; i < MAX_DIRS; i++) {
		if (in->readByte() & RES_LOADED)
			agiLoadResource(rVIEW, i);
		else
			agiUnloadResource(rVIEW, i);
	}

	for (i = 0; i < MAX_DIRS; i++) {
		if (in->readByte() & RES_LOADED)
			agiLoadResource(rSOUND, i);
		else
			agiUnloadResource(rSOUND, i);
	}

	// game.pictures - loaded above
	// game.logics - loaded above
	// game.views - loaded above
	// game.sounds - loaded above

	for (i = 0; i < vtEntries; i++) {
		VtEntry *v = &_game.viewTable[i];

		v->stepTime = in->readByte();
		v->stepTimeCount = in->readByte();
		v->entry = in->readByte();
		v->xPos = in->readSint16BE();
		v->yPos = in->readSint16BE();
		v->currentView = in->readByte();

		// v->view_data - fixed below

		v->currentLoop = in->readByte();
		v->numLoops = in->readByte();

		// v->loop_data - fixed below

		v->currentCel = in->readByte();
		v->numCels = in->readByte();

		// v->cel_data - fixed below
		// v->cel_data_2 - fixed below

		v->xPos2 = in->readSint16BE();
		v->yPos2 = in->readSint16BE();

		// v->s - fixed below

		v->xSize = in->readSint16BE();
		v->ySize = in->readSint16BE();
		v->stepSize = in->readByte();
		v->cycleTime = in->readByte();
		v->cycleTimeCount = in->readByte();
		v->direction = in->readByte();

		v->motion = (MotionType)in->readByte();
		v->cycle = (CycleType)in->readByte();
		v->priority = in->readByte();

		v->flags = in->readUint16BE();

		v->parm1 = in->readByte();
		v->parm2 = in->readByte();
		v->parm3 = in->readByte();
		v->parm4 = in->readByte();
	}
	for (i = vtEntries; i < MAX_VIEWTABLE; i++) {
		memset(&_game.viewTable[i], 0, sizeof(VtEntry));
	}

	// Fix some pointers in viewtable

	for (i = 0; i < MAX_VIEWTABLE; i++) {
		VtEntry *v = &_game.viewTable[i];

		if (_game.dirView[v->currentView].offset == _EMPTY)
			continue;

		if (!(_game.dirView[v->currentView].flags & RES_LOADED))
			agiLoadResource(rVIEW, v->currentView);

		setView(v, v->currentView);	// Fix v->view_data
		setLoop(v, v->currentLoop);	// Fix v->loop_data
		setCel(v, v->currentCel);	// Fix v->cel_data
		v->celData2 = v->celData;
		v->s = NULL;	// not sure if it is used...
	}

	_sprites->eraseBoth();

	// Clear input line
	_gfx->clearScreen(0);
	writeStatus();

	// Recreate background from saved image stack
	clearImageStack();
	while ((t = in->readByte()) != 0) {
		for (i = 0; i < 7; i++)
			parm[i] = in->readSint16BE();
		replayImageStackCall(t, parm[0], parm[1], parm[2],
				parm[3], parm[4], parm[5], parm[6]);
	}

	// Load AGIPAL Data
	if (saveVersion >= 3)
		_gfx->setAGIPal(in->readSint16BE());

	delete in;
	debugC(3, kDebugLevelMain | kDebugLevelSavegame, "Closed %s", fileName.c_str());

	setflag(fRestoreJustRan, true);

	_game.hasPrompt = 0;	// force input line repaint if necessary
	cleanInput();

	_sprites->eraseBoth();
	_sprites->blitBoth();
	_sprites->commitBoth();
	_picture->showPic();
	_gfx->doUpdate();

	return errOK;
}
Beispiel #15
0
bool AvalancheEngine::loadGame(const int16 slot) {
	Common::String fileName = getSaveFileName(slot);
	Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(fileName);
	if (!f)
		return false;

	uint32 signature = f->readUint32LE();
	if (signature != MKTAG('A', 'V', 'A', 'L'))
		return false;

	// Check version. We can't restore from obsolete versions.
	byte saveVersion = f->readByte();
	if (saveVersion > kSavegameVersion) {
		warning("Savegame of incompatible version!");
		delete f;
		return false;
	}

	// Read the description.
	uint32 descSize = f->readUint32LE();
	Common::String description;
	for (uint32 i = 0; i < descSize; i++) {
		char actChar = f->readByte();
		description += actChar;
	}

	description.toUppercase();
	Graphics::skipThumbnail(*f);

	// Read the time the game was saved.
	TimeDate t;
	t.tm_mday = f->readSint16LE();
	t.tm_mon = f->readSint16LE();
	t.tm_year = f->readSint16LE();

	resetAllVariables();

	Common::Serializer sz(f, NULL);
	synchronize(sz);
	delete f;

	_isLoaded = true;

	_animationsEnabled = false;

	if (_holdTheDawn) {
		_holdTheDawn = false;
		fadeIn();
	}

	_background->release();
	minorRedraw();
	_dropdown->setup();
	setRoom(kPeopleAvalot, _room);
	_alive = true;
	refreshObjectList();
	_animation->updateSpeed();
	drawDirection();
	_animation->animLink();
	_background->update();

	Common::String tmpStr = Common::String::format("%cLoaded: %c%s.ASG%c%c%c%s%c%csaved on %s.",
		kControlItalic, kControlRoman, description.c_str(), kControlCenter, kControlNewLine,
		kControlNewLine, _roomnName.c_str(), kControlNewLine, kControlNewLine,
		expandDate(t.tm_mday, t.tm_mon, t.tm_year).c_str());
	_dialogs->displayText(tmpStr);

	AnimationType *avvy = _animation->_sprites[0];
	if (avvy->_quick && avvy->_visible)
		_animation->setMoveSpeed(0, _animation->getDirection()); // We push Avvy in the right direction is he was moving.

	return true;
}
Beispiel #16
0
LoadgameResult DMEngine::loadgame(int16 slot) {
    if (slot == -1 && _newGameFl == k0_modeLoadSavedGame)
        return kDMLoadgameFailure;

    bool fadePalette = true;
    Common::String fileName;
    Common::SaveFileManager *saveFileManager = nullptr;
    Common::InSaveFile *file = nullptr;

    struct {
        SaveTarget _saveTarget;
        int32 _saveVersion;
        OriginalSaveFormat _saveFormat;
        OriginalSavePlatform _savePlatform;
        uint16 _dungeonId;
    } dmSaveHeader;

    if (_newGameFl) {
        //L1366_B_FadePalette = !F0428_DIALOG_RequireGameDiskInDrive_NoDialogDrawn(C0_DO_NOT_FORCE_DIALOG_DM_CSB, true);
        _restartGameAllowed = false;
        _championMan->_partyChampionCount = 0;
        _championMan->_leaderHandObject = Thing::_none;
    } else {
        fileName = getSavefileName(slot);
        saveFileManager = _system->getSavefileManager();
        file = saveFileManager->openForLoading(fileName);

        SaveGameHeader header;
        readSaveGameHeader(file, &header);

        warning("MISSING CODE: missing check for matching format and platform in save in f435_loadgame");

        dmSaveHeader._saveTarget = (SaveTarget)file->readSint32BE();
        dmSaveHeader._saveVersion = file->readSint32BE();
        dmSaveHeader._saveFormat = (OriginalSaveFormat)file->readSint32BE();
        dmSaveHeader._savePlatform = (OriginalSavePlatform)file->readSint32BE();

        // Skip _gameId, which was useless
        file->readSint32BE();
        dmSaveHeader._dungeonId = file->readUint16BE();

        _gameTime = file->readSint32BE();
        // G0349_ul_LastRandomNumber = L1371_s_GlobalData.LastRandomNumber;
        _championMan->_partyChampionCount = file->readUint16BE();
        _dungeonMan->_partyMapX = file->readSint16BE();
        _dungeonMan->_partyMapY = file->readSint16BE();
        _dungeonMan->_partyDir = (Direction)file->readUint16BE();
        _dungeonMan->_partyMapIndex = file->readByte();
        _championMan->_leaderIndex = (ChampionIndex)file->readSint16BE();
        _championMan->_magicCasterChampionIndex = (ChampionIndex)file->readSint16BE();
        _timeline->_eventCount = file->readUint16BE();
        _timeline->_firstUnusedEventIndex = file->readUint16BE();
        _timeline->_eventMaxCount = file->readUint16BE();
        _groupMan->_currActiveGroupCount = file->readUint16BE();
        _projexpl->_lastCreatureAttackTime = file->readSint32BE();
        _projexpl->_lastPartyMovementTime = file->readSint32BE();
        _disabledMovementTicks = file->readSint16BE();
        _projectileDisableMovementTicks = file->readSint16BE();
        _lastProjectileDisabledMovementDirection = file->readSint16BE();
        _championMan->_leaderHandObject = Thing(file->readUint16BE());
        _groupMan->_maxActiveGroupCount = file->readUint16BE();
        if (!_restartGameRequest) {
            _timeline->initTimeline();
            _groupMan->initActiveGroups();
        }

        _groupMan->loadActiveGroupPart(file);
        _championMan->loadPartyPart2(file);
        _timeline->loadEventsPart(file);
        _timeline->loadTimelinePart(file);

        // read sentinel
        uint32 sentinel = file->readUint32BE();
        assert(sentinel == 0x6f85e3d3);

        _dungeonId = dmSaveHeader._dungeonId;
    }

    _dungeonMan->loadDungeonFile(file);
    delete file;

    if (_newGameFl) {
        _timeline->initTimeline();
        _groupMan->initActiveGroups();

        if (fadePalette) {
            _displayMan->startEndFadeToPalette(_displayMan->_blankBuffer);
            delay(1);
            _displayMan->fillScreen(kDMColorBlack);
            _displayMan->startEndFadeToPalette(_displayMan->_paletteTopAndBottomScreen);
        }
    } else {
        _restartGameAllowed = true;

        switch (getGameLanguage()) { // localized
        case Common::DE_DEU:
            _dialog->dialogDraw(nullptr, "SPIEL WIRD GELADEN . . .", nullptr, nullptr, nullptr, nullptr, true, true, true);
            break;
        case Common::FR_FRA:
            _dialog->dialogDraw(nullptr, "CHARGEMENT DU JEU . . .", nullptr, nullptr, nullptr, nullptr, true, true, true);
            break;
        default:
            _dialog->dialogDraw(nullptr, "LOADING GAME . . .", nullptr, nullptr, nullptr, nullptr, true, true, true);
            break;
        }
    }
    _championMan->_partyDead = false;

    return kDMLoadgameSuccess;
}
Beispiel #17
0
/**
 * Restore game from supplied slot number
 */
bool FileManager::restoreGame(const int16 slot) {
	debugC(1, kDebugFile, "restoreGame(%d)", slot);

	int16 savegameId;

	if (slot == -1) {
		GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Restore game:", "Restore", false);
		savegameId = dialog->runModalWithCurrentTarget();
		delete dialog;
	} else {
		savegameId = slot;
	}

	if (savegameId < 0)                             // dialog aborted
		return false;

	Common::String savegameFile = _vm->getSavegameFilename(savegameId);
	Common::SaveFileManager *saveMan = g_system->getSavefileManager();
	Common::InSaveFile *in = saveMan->openForLoading(savegameFile);

	if (!in)
		return false;

	// Initialize new-game status
	_vm->initStatus();

	// Check version, can't restore from different versions
	int saveVersion = in->readByte();
	if (saveVersion != kSavegameVersion) {
		warning("Savegame of incompatible version");
		delete in;
		return false;
	}

	// Skip over description
	int32 saveGameNameSize = in->readSint16BE();
	in->skip(saveGameNameSize);

	Graphics::skipThumbnail(*in);

	in->skip(6);                                    // Skip date & time

	// If hero image is currently swapped, swap it back before restore
	if (_vm->_heroImage != kHeroIndex)
		_vm->_object->swapImages(kHeroIndex, _vm->_heroImage);

	_vm->_object->restoreObjects(in);

	_vm->_heroImage = in->readByte();

	// If hero swapped in saved game, swap it
	byte heroImg = _vm->_heroImage;
	if (heroImg != kHeroIndex)
		_vm->_object->swapImages(kHeroIndex, _vm->_heroImage);
	_vm->_heroImage = heroImg;

	Status &gameStatus = _vm->getGameStatus();

	int score = in->readSint16BE();
	_vm->setScore(score);

	gameStatus._storyModeFl = (in->readByte() == 1);
	_vm->_mouse->setJumpExitFl(in->readByte() == 1);
	gameStatus._gameOverFl = (in->readByte() == 1);
	for (int i = 0; i < _vm->_numStates; i++)
		_vm->_screenStates[i] = in->readByte();

	_vm->_scheduler->restoreSchedulerData(in);

	// Restore palette and change it if necessary
	_vm->_screen->restorePal(in);

	// Restore maze status
	_vm->_maze._enabledFl = (in->readByte() == 1);
	_vm->_maze._size = in->readByte();
	_vm->_maze._x1 = in->readSint16BE();
	_vm->_maze._y1 = in->readSint16BE();
	_vm->_maze._x2 = in->readSint16BE();
	_vm->_maze._y2 = in->readSint16BE();
	_vm->_maze._x3 = in->readSint16BE();
	_vm->_maze._x4 = in->readSint16BE();
	_vm->_maze._firstScreenIndex = in->readByte();

	_vm->_scheduler->restoreScreen(*_vm->_screenPtr);
	if ((_vm->getGameStatus()._viewState = (Vstate) in->readByte()) != kViewPlay)
		_vm->_screen->hideCursor();


	delete in;
	return true;
}
Beispiel #18
0
bool loadGame(const Common::String &fname) {
	Common::InSaveFile *fp = g_system->getSavefileManager()->openForLoading(fname);
	FILETIME savedGameTime;

	while (allRunningFunctions)
		finishFunction(allRunningFunctions);

	if (fp == NULL)
		return false;

	bool headerBad = false;
	if (fp->readByte() != 'S')
		headerBad = true;
	if (fp->readByte() != 'L')
		headerBad = true;
	if (fp->readByte() != 'U')
		headerBad = true;
	if (fp->readByte() != 'D')
		headerBad = true;
	if (fp->readByte() != 'S')
		headerBad = true;
	if (fp->readByte() != 'A')
		headerBad = true;
	if (headerBad) {
		fatal(ERROR_GAME_LOAD_NO, fname);
		return NULL;
	}
	char c;
	c = fp->readByte();
	while ((c = fp->readByte()))
		;

	int majVersion = fp->readByte();
	int minVersion = fp->readByte();
	ssgVersion = VERSION(majVersion, minVersion);

	if (ssgVersion >= VERSION(1, 4)) {
		if (!g_sludge->_gfxMan->skipThumbnail(fp))
			return fatal(ERROR_GAME_LOAD_CORRUPT, fname);
	}

	uint32 bytes_read = fp->read(&savedGameTime, sizeof(FILETIME));
	if (bytes_read != sizeof(FILETIME) && fp->err()) {
		warning("Reading error in loadGame.");
	}

	if (savedGameTime.dwLowDateTime != fileTime.dwLowDateTime || savedGameTime.dwHighDateTime != fileTime.dwHighDateTime) {
		return fatal(ERROR_GAME_LOAD_WRONG, fname);
	}

	// DON'T ADD ANYTHING NEW BEFORE THIS POINT!

	if (ssgVersion >= VERSION(1, 4)) {
		allowAnyFilename = fp->readByte();
	}
	captureAllKeys = fp->readByte();
	fp->readByte();  // updateDisplay (part of movie playing)

	g_sludge->_txtMan->loadFont(ssgVersion, fp);

	killAllPeople();
	killAllRegions();

	int camerX = fp->readUint16BE();
	int camerY = fp->readUint16BE();
	float camerZ;
	if (ssgVersion >= VERSION(2, 0)) {
		camerZ = fp->readFloatLE();
	} else {
		camerZ = 1.0;
	}

	brightnessLevel = fp->readByte();

	g_sludge->_gfxMan->loadHSI(fp, 0, 0, true);
	g_sludge->_evtMan->loadHandlers(fp);
	loadRegions(fp);

	if (!g_sludge->_cursorMan->loadCursor(fp)) {
		return false;
	}

	LoadedFunction *rFunc;
	LoadedFunction **buildList = &allRunningFunctions;

	int countFunctions = fp->readUint16BE();
	while (countFunctions--) {
		rFunc = loadFunction(fp);
		rFunc->next = NULL;
		(*buildList) = rFunc;
		buildList = &(rFunc->next);
	}

	for (int a = 0; a < numGlobals; a++) {
		unlinkVar(globalVars[a]);
		loadVariable(&globalVars[a], fp);
	}

	loadPeople(fp);

	if (fp->readByte()) {
		if (!setFloor(fp->readUint16BE()))
			return false;
	} else
		setFloorNull();

	if (!g_sludge->_gfxMan->loadZBuffer(fp))
		return false;

	if (!g_sludge->_gfxMan->loadLightMap(ssgVersion, fp)) {
		return false;
	}

	fadeMode = fp->readByte();
	g_sludge->_speechMan->load(fp);
	loadStatusBars(fp);
	g_sludge->_soundMan->loadSounds(fp);

	saveEncoding = fp->readUint16BE();

	if (ssgVersion >= VERSION(1, 6)) {
		if (ssgVersion < VERSION(2, 0)) {
			// aaLoad
			fp->readByte();
			fp->readFloatLE();
			fp->readFloatLE();
		}

		blur_loadSettings(fp);
	}

	if (ssgVersion >= VERSION(1, 3)) {
		g_sludge->_gfxMan->loadColors(fp);

		// Read parallax layers
		while (fp->readByte()) {
			int im = fp->readUint16BE();
			int fx = fp->readUint16BE();
			int fy = fp->readUint16BE();

			if (!g_sludge->_gfxMan->loadParallax(im, fx, fy))
				return false;
		}

		g_sludge->_languageMan->loadLanguageSetting(fp);
	}

	g_sludge->_gfxMan->nosnapshot();
	if (ssgVersion >= VERSION(1, 4)) {
		if (fp->readByte()) {
			if (!g_sludge->_gfxMan->restoreSnapshot(fp))
				return false;
		}
	}

	delete fp;

	g_sludge->_gfxMan->setCamera(camerX, camerY, camerZ);

	clearStackLib();
	return true;
}