Esempio n. 1
0
bool KyraEngine_v1::saveFileLoadable(int slot) {
	if (slot < 0 || slot > 999)
		return false;

	SaveHeader header;
	Common::SeekableReadStream *in = openSaveForReading(getSavegameFilename(slot), header);

	if (in) {
		delete in;
		return true;
	}

	return false;
}
Esempio n. 2
0
Common::Error KyraEngine_MR::loadGameState(int slot) {
	const char *fileName = getSavegameFilename(slot);

	SaveHeader header;
	Common::InSaveFile *saveFile = openSaveForReading(fileName, header);
	if (!saveFile) {
		showMessageFromCCode(17, 0xB3, 0);
		snd_playSoundEffect(0x0D, 0xC8);
		return Common::kUnknownError;
	}

	if (header.originalSave)
		warning("Trying to load savegame from original interpreter, while this is possible, it is not officially supported");

	if (_inventoryState) {
		updateCharacterAnim(0);
		restorePage3();
		drawAnimObjects();
		_inventoryState = true;
		refreshAnimObjects(0);
		hideInventory();
	}

	_deathHandler = -1;
	if (!_unkSceneScreenFlag1)
		_lastMusicCommand = -1;

	int curShapes = _characterShapeFile;

	Common::SeekableSubReadStreamEndian in(saveFile, saveFile->pos(), saveFile->size(), !header.originalSave, DisposeAfterUse::YES);

	_screen->hideMouse();

	if (!header.originalSave) {
		_timer->loadDataFromFile(in, header.version);

		uint32 flagsSize = in.readUint32BE();
		assert(flagsSize <= sizeof(_flagsTable));
		in.read(_flagsTable, flagsSize);
	}

	_lastMusicCommand = in.readSint16();
	_currentChapter = in.readByte();
	_characterShapeFile = in.readByte();

	if (header.version >= 12 || header.originalSave)
		_album.curPage = in.readByte();
	if (header.originalSave)
		in.readByte();

	_score = in.readSint16();
	_scoreMax = in.readSint16();
	_malcolmsMood = in.readByte();

	if (header.originalSave)
		in.seek(8, SEEK_CUR);

	for (int i = 0; i < 30; ++i)
		in.read(_conversationState[i], 30);

	if (!header.originalSave) {
		in.read(_newSceneDlgState, 40);
	} else {
		for (int i = 0; i < 40; ++i)
			_newSceneDlgState[i] = in.readUint16();
	}

	for (int i = 0; i < 100; ++i)
		_hiddenItems[i] = in.readSint16();

	if (header.originalSave)
		in.read(_flagsTable, 69);
	in.read(_scoreFlagTable, 26);

	_mainCharacter.sceneId = in.readUint16();
	_mainCharacter.dlgIndex = in.readSint16();
	_mainCharacter.height = in.readByte();
	_mainCharacter.facing = in.readByte();
	_mainCharacter.animFrame = in.readUint16();
	if (!header.originalSave) {
		_mainCharacter.walkspeed = in.readByte();
	} else {
		in.seek(2, SEEK_CUR);
		_mainCharacter.walkspeed = in.readUint32();
	}
	for (int i = 0; i < 10; ++i)
		_mainCharacter.inventory[i] = in.readUint16();
	_mainCharacter.x1 = in.readSint16();
	_mainCharacter.y1 = in.readSint16();
	_mainCharacter.x2 = in.readSint16();
	_mainCharacter.y2 = in.readSint16();
	_mainCharacter.x3 = in.readSint16();
	_mainCharacter.y3 = in.readSint16();

	for (int i = 0; i < 50; ++i) {
		_itemList[i].id = in.readSint16();
		_itemList[i].sceneId = in.readUint16();
		_itemList[i].x = in.readSint16();
		_itemList[i].y = in.readSint16();
		if (header.version <= 9 || header.originalSave)
			in.readUint16();
	}

	for (int i = 0; i < 88; ++i) {
		in.read(_talkObjectList[i].filename, 13);
		_talkObjectList[i].sceneAnim = in.readByte();
		_talkObjectList[i].sceneScript = in.readByte();
		_talkObjectList[i].x = in.readSint16();
		_talkObjectList[i].y = in.readSint16();
		_talkObjectList[i].color = in.readByte();
		if (header.version >= 13 || header.originalSave)
			_talkObjectList[i].sceneId = in.readByte();
	}

	for (int i = 0; i < 98; ++i) {
		if (!header.originalSave) {
			in.read(_sceneList[i].filename1, 10);
		} else {
			in.read(_sceneList[i].filename1, 9);
			_sceneList[i].filename1[9] = 0;
		}

		if (!header.originalSave) {
			in.read(_sceneList[i].filename2, 10);
		} else {
			in.read(_sceneList[i].filename2, 9);
			_sceneList[i].filename2[9] = 0;
		}

		_sceneList[i].exit1 = in.readUint16();
		_sceneList[i].exit2 = in.readUint16();
		_sceneList[i].exit3 = in.readUint16();
		_sceneList[i].exit4 = in.readUint16();
		_sceneList[i].flags = in.readByte();
		_sceneList[i].sound = in.readByte();
	}

	_itemInHand = in.readSint16();

	if (header.originalSave) {
		uint32 currentTime = _system->getMillis();

		for (int i = 0; i < 6; ++i)
			_timer->setDelay(i, in.readSint32LE());

		for (int i = 0; i < 6; ++i) {
			if (in.readUint16LE())
				_timer->enable(i);
			else
				_timer->disable(i);
		}

		for (int i = 0; i < 6; ++i)
			_timer->setNextRun(i, currentTime + (in.readUint32LE() * _tickLength));

		_timer->resetNextRun();
	}

	_sceneExit1 = in.readUint16();
	_sceneExit2 = in.readUint16();
	_sceneExit3 = in.readUint16();
	_sceneExit4 = in.readUint16();

	if (saveFile->err() || saveFile->eos()) {
		warning("Load failed ('%s', '%s').", fileName, header.description.c_str());
		return Common::kUnknownError;
	} else {
		debugC(1, kDebugLevelMain, "Loaded savegame '%s.'", header.description.c_str());
	}

	_loadingState = true;
	updateCharacterAnim(0);
	_loadingState = false;

	if (curShapes != _characterShapeFile)
		loadCharacterShapes(_characterShapeFile);

	_mainCharX = _mainCharacter.x2 = _mainCharacter.x1;
	_mainCharY = _mainCharacter.y2 = _mainCharacter.y1;
	_mainCharacter.facing = 4;
	_badConscienceShown = false;
	_badConsciencePosition = false;
	_goodConscienceShown = false;
	_goodConsciencePosition = false;

	enterNewScene(_mainCharacter.sceneId, _mainCharacter.facing, 0, 0, 1);
	setHandItem(_itemInHand);

	if (_lastMusicCommand >= 0 && !_unkSceneScreenFlag1)
		snd_playWanderScoreViaMap(_lastMusicCommand, 1);
	else if (_lastMusicCommand == -1)
		snd_playWanderScoreViaMap(28, 1);

	while (!_screen->isMouseVisible())
		_screen->showMouse();

	setCommandLineRestoreTimer(7);
	_shownMessage = " ";
	_restoreCommandLine = false;

	// We didn't explicitly set the walk speed, but it's saved as part of
	// the _timers array, so we need to re-sync it with _configWalkspeed.
	setWalkspeed(_configWalkspeed);

	return Common::kNoError;
}
Esempio n. 3
0
Common::Error KyraEngine_HoF::loadGameState(int slot) {
	const char *fileName = getSavegameFilename(slot);

	SaveHeader header;
	Common::InSaveFile *saveFile = openSaveForReading(fileName, header);
	if (!saveFile) {
		showMessageFromCCode(0x35, 0x84, 0);
		snd_playSoundEffect(0x0D);
		return Common::kUnknownError;
	}

	if (header.originalSave)
		warning("Trying to load savegame from original interpreter, while this is possible, it is not officially supported");

	bool setFlag1EE = (queryGameFlag(0x1EE) != 0);

	_deathHandler = -1;
	if (!_unkSceneScreenFlag1) {
		_sound->beginFadeOut();
		_system->delayMillis(5 * _tickLength);
		_lastMusicCommand = -1;
	}

	int loadedZTable = _characterShapeFile;

	Common::SeekableSubReadStreamEndian in(saveFile, saveFile->pos(), saveFile->size(), !header.originalSave, DisposeAfterUse::YES);

	_screen->hideMouse();

	if (!header.originalSave) {
		_timer->loadDataFromFile(in, header.version);

		uint32 flagsSize = in.readUint32BE();
		assert(flagsSize <= sizeof(_flagsTable));
		in.read(_flagsTable, flagsSize);
	}

	// usually we have to save the flag set by opcode 10 here
	//word_2AB05 = in.readUint16();
	if (header.originalSave)
		in.readUint16();
	_lastMusicCommand = in.readSint16();
	_newChapterFile = in.readByte();
	_characterShapeFile = in.readByte();
	_cauldronState = in.readByte();
	_colorCodeFlag1 = in.readByte();
	_colorCodeFlag2 = in.readByte();
	_bookCurPage = in.readByte();
	_bookMaxPage = in.readByte();
	for (int i = 0; i < 7; ++i)
		_presetColorCode[i] = in.readByte();
	for (int i = 0; i < 7; ++i)
		_inputColorCode[i] = in.readByte();
	for (int i = 0; i < 25; ++i)
		_cauldronTable[i] = in.readSint16();
	for (int i = 0; i < 20; ++i)
		_hiddenItems[i] = in.readSint16();

	if (header.originalSave) {
		assert(sizeof(_flagsTable) >= 0x41);
		in.read(_flagsTable, 0x41);
	}

	for (int i = 0; i < 19; ++i)
		in.read(_conversationState[i], 14);

	if (!header.originalSave) {
		in.read(_newSceneDlgState, 32);
	} else {
		for (int i = 0; i < 31; ++i)
			_newSceneDlgState[i] = in.readUint16();
	}

	_cauldronUseCount = in.readSint16();

	if (header.originalSave)
		in.seek(6, SEEK_CUR);

	_mainCharacter.sceneId = in.readUint16();
	_mainCharacter.dlgIndex = in.readSint16();
	_mainCharacter.height = in.readByte();
	_mainCharacter.facing = in.readByte();
	_mainCharacter.animFrame = in.readUint16();

	if (header.version <= 10 || header.originalSave)
		in.seek(3, SEEK_CUR);

	for (int i = 0; i < 20; ++i)
		_mainCharacter.inventory[i] = in.readUint16();
	_mainCharacter.x1 = in.readSint16();
	_mainCharacter.y1 = in.readSint16();
	_mainCharacter.x2 = in.readSint16();
	_mainCharacter.y2 = in.readSint16();

	for (int i = 0; i < 30; ++i) {
		_itemList[i].id = in.readSint16();
		_itemList[i].sceneId = in.readUint16();
		_itemList[i].x = in.readSint16();
		_itemList[i].y = in.readByte();
		if (header.version <= 9 || header.originalSave)
			in.readUint16();
	}

	for (int i = 0; i < 72; ++i) {
		in.read(_talkObjectList[i].filename, 13);
		_talkObjectList[i].scriptId = in.readByte();
		_talkObjectList[i].x = in.readSint16();
		_talkObjectList[i].y = in.readSint16();
		_talkObjectList[i].color = in.readByte();
	}

	for (int i = 0; i < 86; ++i) {
		if (!header.originalSave) {
			in.read(_sceneList[i].filename1, 10);
		} else {
			in.read(_sceneList[i].filename1, 9);
			_sceneList[i].filename1[9] = 0;
		}

		_sceneList[i].exit1 = in.readUint16();
		_sceneList[i].exit2 = in.readUint16();
		_sceneList[i].exit3 = in.readUint16();
		_sceneList[i].exit4 = in.readUint16();
		_sceneList[i].flags = in.readByte();
		_sceneList[i].sound = in.readByte();
	}

	_itemInHand = in.readSint16();

	if (header.originalSave) {
		uint32 currentTime = _system->getMillis();

		for (int i = 0; i < 6; ++i)
			_timer->setDelay(i, in.readSint32LE());

		for (int i = 0; i < 6; ++i) {
			if (in.readUint16LE())
				_timer->enable(i);
			else
				_timer->disable(i);
		}

		for (int i = 0; i < 6; ++i)
			_timer->setNextRun(i, currentTime + (in.readUint32LE() * _tickLength));

		_timer->resetNextRun();
	}

	_sceneExit1 = in.readUint16();
	_sceneExit2 = in.readUint16();
	_sceneExit3 = in.readUint16();
	_sceneExit4 = in.readUint16();

	if (saveFile->err() || saveFile->eos()) {
		warning("Load failed ('%s', '%s').", fileName, header.description.c_str());
		return Common::kUnknownError;
	} else {
		debugC(1, kDebugLevelMain, "Loaded savegame '%s.'", header.description.c_str());
	}

	if (loadedZTable != _characterShapeFile)
		loadCharacterShapes(_characterShapeFile);

	_screen->loadBitmap("_PLAYFLD.CPS", 3, 3, 0);
	if (!queryGameFlag(1))
		_screen->copyRegion(0xCE, 0x90, 0xCE, 0x90, 0x2C, 0x2C, 2, 0, Screen::CR_NO_P_CHECK);
	if (!queryGameFlag(2))
		_screen->copyRegion(0xFA, 0x90, 0xFA, 0x90, 0x46, 0x2C, 2, 0, Screen::CR_NO_P_CHECK);
	_screen->loadBitmap("_PLAYALL.CPS", 3, 3, 0);
	if (queryGameFlag(1))
		_screen->copyRegion(0xCE, 0x90, 0xCE, 0x90, 0x2C, 0x2C, 2, 0, Screen::CR_NO_P_CHECK);
	if (queryGameFlag(2))
		_screen->copyRegion(0xFA, 0x90, 0xFA, 0x90, 0x46, 0x2C, 2, 0, Screen::CR_NO_P_CHECK);

	redrawInventory(0);
	int cauldronUseCount = _cauldronUseCount;
	setCauldronState(_cauldronState, 0);
	_cauldronUseCount = cauldronUseCount;
	_mainCharX = _mainCharacter.x2 = _mainCharacter.x1;
	_mainCharY = _mainCharacter.y2 = _mainCharacter.y1;
	_mainCharacter.facing = 4;

	enterNewScene(_mainCharacter.sceneId, _mainCharacter.facing, 0, 0, 1);
	setDelayedCursorUpdate();

	if (_lastMusicCommand >= 0 && !_unkSceneScreenFlag1)
		snd_playWanderScoreViaMap(_lastMusicCommand, 1);

	while (!_screen->isMouseVisible())
		_screen->showMouse();

	setTimer1DelaySecs(7);
	_shownMessage = " ";
	_fadeMessagePalette = false;

	if (setFlag1EE)
		setGameFlag(0x1EE);

	// We didn't explicitly set the walk speed, but it's saved as part of
	// the _timers array, so we need to re-sync it with _configWalkspeed.
	setWalkspeed(_configWalkspeed);

	return Common::kNoError;
}
Esempio n. 4
0
Common::Error EoBCoreEngine::loadGameState(int slot) {
	// Special slot id -1 for EOB1 party transfer
	const char *fileName = (slot == -1) ? _savegameFilename.c_str() : getSavegameFilename(slot);

	SaveHeader header;
	Common::InSaveFile *saveFile = openSaveForReading(fileName, header, (slot != -1));
	if (!saveFile)
		return Common::Error(Common::kReadingFailed);

	Common::SeekableSubReadStreamEndian in(saveFile, saveFile->pos(), saveFile->size(), !header.originalSave, DisposeAfterUse::YES);
	_loading = true;

	if (slot != -1)
		_screen->fadeToBlack(10);

	for (int i = 0; i < 6; i++) {
		EoBCharacter *c = &_characters[i];
		c->id = in.readByte();
		c->flags = in.readByte();
		in.read(c->name, 11);
		c->strengthCur = in.readSByte();
		c->strengthMax = in.readSByte();
		c->strengthExtCur = in.readSByte();
		c->strengthExtMax = in.readSByte();
		c->intelligenceCur = in.readSByte();
		c->intelligenceMax = in.readSByte();
		c->wisdomCur = in.readSByte();
		c->wisdomMax = in.readSByte();
		c->dexterityCur = in.readSByte();
		c->dexterityMax = in.readSByte();
		c->constitutionCur = in.readSByte();
		c->constitutionMax = in.readSByte();
		c->charismaCur = in.readSByte();
		c->charismaMax = in.readSByte();
		c->hitPointsCur = in.readSint16BE();
		c->hitPointsMax = in.readSint16BE();
		c->armorClass = in.readSByte();
		c->disabledSlots = in.readByte();
		c->raceSex = in.readByte();
		c->cClass = in.readByte();
		c->alignment = in.readByte();
		c->portrait = in.readSByte();
		if (slot == -1 && c->portrait < 0)
			c->portrait = -c->portrait + 43;
		c->food = in.readByte();
		in.read(c->level, 3);
		for (int ii = 0; ii < 3; ii++)
			c->experience[ii] = in.readUint32BE();
		delete[] c->faceShape;
		c->faceShape = 0;
		in.read(c->mageSpells, 80);
		in.read(c->clericSpells, 80);
		c->mageSpellsAvailableFlags = in.readUint32BE();
		for (int ii = 0; ii < 27; ii++)
			c->inventory[ii] = in.readSint16BE();
		uint32 ct = _system->getMillis();
		for (int ii = 0; ii < 10; ii++) {
			c->timers[ii] = in.readUint32BE();
			if (c->timers[ii])
				c->timers[ii] += ct;
		}
		in.read(c->events, 10);
		in.read(c->effectsRemainder, 4);
		c->effectFlags = in.readUint32BE();
		c->damageTaken = in.readByte();
		in.read(c->slotStatus, 5);
	}

	setupCharacterTimers();

	_screen->loadShapeSetBitmap("CHARGENA", 3, 3);
	for (int i = 0; i < 6; i++) {
		EoBCharacter *c = &_characters[i];
		if (!c->flags || c->portrait < 0)
			continue;
		c->faceShape = _screen->encodeShape((c->portrait % 10) << 2, (c->portrait / 10) << 5, 4, 32, true);
	}

	_screen->loadShapeSetBitmap(_flags.gameID == GI_EOB2 ? "OUTPORTS" : "OUTTAKE", 3, 3);
	for (int i = 0; i < 6; i++) {
		EoBCharacter *c = &_characters[i];
		if (!c->flags || c->portrait >= 0)
			continue;
		c->faceShape = _screen->encodeShape((-(c->portrait + 1)) << 2, _flags.gameID == GI_EOB2 ? 0 : 160, 4, 32, true);
	}
	_screen->_curPage = 0;

	if (slot == -1) {
		// Skip all settings which aren't necessary for party transfer.
		// Jump directly to the items list.
		in.skip(108);
	} else {
		_currentLevel = in.readByte();
		_currentSub = in.readSByte();
		_currentBlock = in.readUint16BE();
		_currentDirection = in.readUint16BE();
		_itemInHand = in.readSint16BE();
		_hasTempDataFlags = in.readUint32BE();
		_partyEffectFlags = in.readUint32BE();

		_updateFlags = in.readUint16BE();
		_compassDirection = in.readUint16BE();
		_currentControlMode = in.readUint16BE();
		_updateCharNum = in.readUint16BE();
		_openBookSpellLevel = in.readSByte();
		_openBookSpellSelectedItem  = in.readSByte();
		_openBookSpellListOffset = in.readSByte();
		_openBookChar = in.readByte();
		_openBookType = in.readByte();
		_openBookCharBackup = in.readByte();
		_openBookTypeBackup = in.readByte();
		_activeSpellCharId = in.readByte();
		_activeSpellCharacterPos = in.readByte();
		_activeSpell = in.readByte();
		_returnAfterSpellCallback = in.readByte() ? true : false;

		_inf->loadState(in);
	}

	for (int i = 0; i < 600; i++) {
		EoBItem *t = &_items[i];
		t->nameUnid = in.readByte();
		t->nameId = in.readByte();
		t->flags = in.readByte();
		t->icon = in.readSByte();
		t->type = in.readSByte();
		t->pos = in.readSByte();
		t->block = in.readSint16BE();
		t->next = in.readSint16BE();
		t->prev = in.readSint16BE();
		t->level = in.readByte();
		t->value = in.readSByte();
	}

	// No more data needed for party transfer
	if (slot == -1) {
		_loading = false;
		return Common::kNoError;
	}

	for (int i = 51; i < 65; i++) {
		EoBItemType *t = &_itemTypes[i];
		t->invFlags = in.readUint16BE();
		t->handFlags = in.readUint16BE();
		t->armorClass = in.readSByte();
		t->allowedClasses = in.readSByte();
		t->requiredHands = in.readSByte();
		t->dmgNumDiceS = in.readSByte();
		t->dmgNumPipsS = in.readSByte();
		t->dmgIncS = in.readSByte();
		t->dmgNumDiceL = in.readSByte();
		t->dmgNumPipsL = in.readSByte();
		t->dmgIncL = in.readSByte();
		t->unk1 = in.readByte();
		t->extraProperties = in.readUint16BE();
	}

	for (int i = 0; i < 18; i++) {
		if (!(_hasTempDataFlags & (1 << i)))
			continue;

		if (_lvlTempData[i]) {
			delete[] _lvlTempData[i]->wallsXorData;
			delete[] _lvlTempData[i]->flags;
			releaseMonsterTempData(_lvlTempData[i]);
			releaseFlyingObjectTempData(_lvlTempData[i]);
			releaseWallOfForceTempData(_lvlTempData[i]);
			delete _lvlTempData[i];
		}

		_lvlTempData[i] = new LevelTempData;
		LevelTempData *l = _lvlTempData[i];
		l->wallsXorData = new uint8[4096];
		l->flags = new uint16[1024];
		EoBMonsterInPlay *lm = new EoBMonsterInPlay[30];
		l->monsters = lm;
		EoBFlyingObject *lf = new EoBFlyingObject[_numFlyingObjects];
		l->flyingObjects = lf;
		WallOfForce *lw = new WallOfForce[5];
		l->wallsOfForce = lw;

		in.read(l->wallsXorData, 4096);
		for (int ii = 0; ii < 1024; ii++)
			l->flags[ii] = in.readByte();

		for (int ii = 0; ii < 30; ii++) {
			EoBMonsterInPlay *m = &lm[ii];
			m->type = in.readByte();
			m->unit = in.readByte();
			m->block = in.readUint16BE();
			m->pos = in.readByte();
			m->dir = in.readSByte();
			m->animStep = in.readByte();
			m->shpIndex = in.readByte();
			m->mode = in.readSByte();
			m->f_9 = in.readSByte();
			m->curAttackFrame = in.readSByte();
			m->spellStatusLeft = in.readSByte();
			m->hitPointsMax = in.readSint16BE();
			m->hitPointsCur = in.readSint16BE();
			m->dest = in.readUint16BE();
			m->randItem = in.readUint16BE();
			m->fixedItem = in.readUint16BE();
			m->flags = in.readByte();
			m->idleAnimState = in.readByte();
			m->curRemoteWeapon = in.readByte();
			m->numRemoteAttacks = in.readByte();
			m->palette = in.readSByte();
			m->directionChanged = in.readByte();
			m->stepsTillRemoteAttack = in.readByte();
			m->sub = in.readByte();
		}

		for (int ii = 0; ii < _numFlyingObjects; ii++) {
			EoBFlyingObject *m = &lf[ii];
			m->enable = in.readByte();
			m->objectType = in.readByte();
			m->attackerId = in.readSint16BE();
			m->item = in.readSint16BE();
			m->curBlock = in.readUint16BE();
			m->u2 = in.readUint16BE();
			m->u1 = in.readByte();
			m->direction = in.readByte();
			m->distance = in.readByte();
			m->callBackIndex = in.readSByte();
			m->curPos = in.readByte();
			m->flags = in.readByte();
			m->unused = in.readByte();
		}

		for (int ii = 0; ii < 5; ii++) {
			WallOfForce *w = &lw[ii];
			w->block = in.readUint16BE();
			w->duration = in.readUint32BE();
		}
	}

	loadLevel(_currentLevel, _currentSub);
	_sceneUpdateRequired = true;
	_screen->setFont(Screen::FID_6_FNT);

	for (int i = 0; i < 6; i++) {
		for (int ii = 0; ii < 10; ii++) {
			if (_characters[i].events[ii] == -57)
				spellCallback_start_trueSeeing();
		}
	}

	_screen->setCurPage(0);
	gui_drawPlayField(false);

	if (_currentControlMode)
		_screen->copyRegion(176, 0, 0, 0, 144, 168, 0, 5, Screen::CR_NO_P_CHECK);

	_screen->setCurPage(0);
	gui_drawAllCharPortraitsWithStats();
	drawScene(1);

	if (_updateFlags) {
		_updateFlags = 0;
		useMagicBookOrSymbol(_openBookChar, _openBookType);
	}

	_screen->copyRegion(0, 120, 0, 0, 176, 24, 0, 12, Screen::CR_NO_P_CHECK);

	gui_toggleButtons();
	setHandItem(_itemInHand);

	while (!_screen->isMouseVisible())
		_screen->showMouse();

	_loading = false;
	_screen->fadeFromBlack(20);
	removeInputTop();

	return Common::kNoError;
}
Esempio n. 5
0
Common::Error LoLEngine::loadGameState(int slot) {
	const uint16 *cdf[] = { _charDefsMan, _charDefsWoman, _charDefsKieran, _charDefsMan, _charDefsAkshel };

	const char *fileName = getSavegameFilename(slot);

	SaveHeader header;
	Common::InSaveFile *saveFile = openSaveForReading(fileName, header);
	if (!saveFile) {
		_txt->printMessage(2, "%s", getLangString(0x425d));
		return Common::kNoError;
	}

	_screen->fadeClearSceneWindow(10);
	completeDoorOperations();
	_screen->fillRect(112, 0, 287, 119, 0, 0);
	_screen->updateScreen();

	Common::SeekableSubReadStreamEndian in(saveFile, saveFile->pos(), saveFile->size(), !header.originalSave, DisposeAfterUse::YES);

	for (int i = 0; i < 4; i++) {
		LoLCharacter *c = &_characters[i];
		c->flags = in.readUint16BE();
		in.read(c->name, 11);
		c->raceClassSex = in.readByte();
		c->id = in.readSint16BE();
		c->curFaceFrame = in.readByte();
		c->tempFaceFrame = in.readByte();
		c->screamSfx = in.readByte();
		for (int ii = 0; ii < 8; ii++)
			c->itemsMight[ii] = in.readUint16BE();
		for (int ii = 0; ii < 8; ii++)
			c->protectionAgainstItems[ii] = in.readUint16BE();
		c->itemProtection = in.readUint16BE();
		c->hitPointsCur = in.readSint16BE();
		c->hitPointsMax = in.readUint16BE();
		c->magicPointsCur = in.readSint16BE();
		c->magicPointsMax = in.readUint16BE();
		c->field_41 = in.readByte();
		c->damageSuffered = in.readUint16BE();
		c->weaponHit = in.readUint16BE();
		c->totalMightModifier = in.readUint16BE();
		c->totalProtectionModifier = in.readUint16BE();
		c->might = in.readUint16BE();
		c->protection = in.readUint16BE();
		c->nextAnimUpdateCountdown = in.readSint16BE();
		for (int ii = 0; ii < 11; ii++)
			c->items[ii] = in.readUint16BE();
		for (int ii = 0; ii < 3; ii++)
			c->skillLevels[ii] = in.readByte();
		for (int ii = 0; ii < 3; ii++)
			c->skillModifiers[ii] = in.readSByte();
		for (int ii = 0; ii < 3; ii++)
			c->experiencePts[ii] = in.readUint32BE();
		for (int ii = 0; ii < 5; ii++)
			c->characterUpdateEvents[ii] = in.readByte();
		for (int ii = 0; ii < 5; ii++)
			c->characterUpdateDelay[ii] = in.readByte();

		if (c->flags & 1) {
			loadCharFaceShapes(i, c->id);
			c->defaultModifiers = cdf[c->raceClassSex];
		}
	}

	in.read(_wllBuffer4, 80);

	_currentBlock = in.readUint16BE();
	_partyPosX = in.readUint16BE();
	_partyPosY = in.readUint16BE();
	_updateFlags = in.readUint16BE();
	_scriptDirection = in.readByte();
	_selectedSpell = in.readByte();
	_sceneDefaultUpdate = in.readByte();
	_compassBroken = in.readByte();
	_drainMagic = in.readByte();
	_currentDirection = in.readUint16BE();
	_compassDirection = in.readUint16BE();
	_selectedCharacter = in.readSByte();
	_currentLevel = in.readByte();
	for (int i = 0; i < 48; i++)
		_inventory[i] = in.readSint16BE();
	_inventoryCurItem = in.readSint16BE();
	_itemInHand = in.readSint16BE();
	_lastMouseRegion = in.readSint16BE();

	if (header.version <= 15) {
		uint16 flags[40];
		memset(flags, 0, sizeof(flags));

		if (header.version == 14) {
			for (int i = 0; i < 16; i++)
				flags[i] = in.readUint16BE();
			flags[26] = in.readUint16BE();
			flags[36] = in.readUint16BE();
		} else if (header.version == 15) {
			for (int i = 0; i < 40; i++)
				flags[i] = in.readUint16BE();
		}

		memset(_flagsTable, 0, sizeof(_flagsTable));
		for (uint i = 0; i < ARRAYSIZE(flags); ++i) {
			for (uint k = 0; k < 16; ++k) {
				if (flags[i] & (1 << k))
					setGameFlag(((i << 4) & 0xFFF0) | (k & 0x000F));
			}
		}
	} else {
		uint32 flagsSize = in.readUint32BE();
		assert(flagsSize <= sizeof(_flagsTable));
		in.read(_flagsTable, flagsSize);
	}

	for (int i = 0; i < 24; i++)
		_globalScriptVars[i] = in.readUint16BE();
	_brightness = in.readByte();
	_lampOilStatus = in.readByte();
	_lampEffect = in.readSByte();
	_credits = in.readUint16BE();
	for (int i = 0; i < 8; i++)
		_globalScriptVars2[i] = in.readUint16BE();
	in.read(_availableSpells, 7);
	_hasTempDataFlags = in.readUint32BE();

	for (int i = 0; i < 400; i++) {
		ItemInPlay *t = &_itemsInPlay[i];
		t->nextAssignedObject = in.readUint16BE();
		t->nextDrawObject = in.readUint16BE();
		t->flyingHeight = in.readByte();
		t->block = in.readUint16BE();
		t->x = in.readUint16BE();
		t->y = in.readUint16BE();
		t->level = in.readSByte();
		t->itemPropertyIndex = in.readUint16BE();
		t->shpCurFrame_flg = in.readUint16BE();
		t->destDirection = in.readByte();
		t->hitOffsX = in.readSByte();
		t->hitOffsY = in.readSByte();
		t->currentSubFrame = in.readByte();
	}

	for (int i = 0; i < 1024; i++) {
		LevelBlockProperty *l = &_levelBlockProperties[i];
		l->assignedObjects = l->drawObjects = 0;
		l->direction = 5;
	}

	for (int i = 0; i < 29; i++) {
		if (!(_hasTempDataFlags & (1 << i)))
			continue;

		if (_lvlTempData[i]) {
			delete[] _lvlTempData[i]->wallsXorData;
			delete[] _lvlTempData[i]->flags;
			delete[] _lvlTempData[i]->monsters;
			delete[] _lvlTempData[i]->flyingObjects;
			delete _lvlTempData[i];
		}

		_lvlTempData[i] = new LevelTempData;
		_lvlTempData[i]->wallsXorData = new uint8[4096];
		_lvlTempData[i]->flags = new uint8[1024];
		_lvlTempData[i]->monsters = new MonsterInPlay[30];
		_lvlTempData[i]->flyingObjects = new FlyingObject[8];
		LevelTempData *l = _lvlTempData[i];

		in.read(l->wallsXorData, 4096);
		in.read(l->flags, 1024);

		for (int ii = 0; ii < 30; ii++) {
			MonsterInPlay *m = &l->monsters[ii];
			m->nextAssignedObject = in.readUint16BE();
			m->nextDrawObject = in.readUint16BE();
			m->flyingHeight = in.readByte();
			m->block = in.readUint16BE();
			m->x = in.readUint16BE();
			m->y = in.readUint16BE();
			m->shiftStep = in.readSByte();
			m->destX = in.readUint16BE();
			m->destY = in.readUint16BE();
			m->destDirection = in.readByte();
			m->hitOffsX = in.readSByte();
			m->hitOffsY = in.readSByte();
			m->currentSubFrame = in.readByte();
			m->mode = in.readByte();
			m->fightCurTick = in.readSByte();
			m->id = in.readByte();
			m->direction = in.readByte();
			m->facing = in.readByte();
			m->flags = in.readUint16BE();
			m->damageReceived = in.readUint16BE();
			m->hitPoints = in.readSint16BE();
			m->speedTick = in.readByte();
			m->type = in.readByte();
			m->numDistAttacks = in.readByte();
			m->curDistWeapon = in.readByte();
			m->distAttackTick = in.readSByte();
			m->assignedItems = in.readUint16BE();
			m->properties = &_monsterProperties[m->type];
			in.read(m->equipmentShapes, 4);
		}

		for (int ii = 0; ii < 8; ii++) {
			FlyingObject *m = &l->flyingObjects[ii];
			m->enable = in.readByte();
			m->objectType = in.readByte();
			m->attackerId = in.readUint16BE();
			m->item = in.readSint16BE();
			m->x = in.readUint16BE();
			m->y = in.readUint16BE();
			m->flyingHeight = in.readByte();
			m->direction = in.readByte();
			m->distance = in.readByte();
			m->field_D = in.readSByte();
			m->c = in.readByte();
			m->flags = in.readByte();
			m->wallFlags = in.readByte();
		}
		l->monsterDifficulty = in.readByte();
	}

	calcCharPortraitXpos();
	memset(_moneyColumnHeight, 0, sizeof(_moneyColumnHeight));
	int t = _credits;
	_credits = 0;
	giveCredits(t, 0);
	setDelayedCursorUpdate();
	loadLevel(_currentLevel);
	gui_drawPlayField();
	timerSpecialCharacterUpdate(0);
	_flagsTable[73] |= 0x08;

	while (!_screen->isMouseVisible())
		_screen->showMouse();

	return Common::kNoError;
}