From 91a800cf028d46822536d1760ab1bc1b679b86c4 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Mon, 17 Mar 2008 18:10:52 +0000 Subject: Implemented quick (via hotkeys) save/load suppot for HoF. svn-id: r31154 --- engines/kyra/gui_v1.cpp | 7 -- engines/kyra/kyra.cpp | 10 ++ engines/kyra/kyra.h | 13 ++ engines/kyra/kyra_v1.h | 9 +- engines/kyra/kyra_v2.cpp | 17 ++- engines/kyra/kyra_v2.h | 13 +- engines/kyra/module.mk | 2 + engines/kyra/saveload.cpp | 129 ++++++++++++++++++++ engines/kyra/saveload_v1.cpp | 85 ++----------- engines/kyra/saveload_v2.cpp | 278 +++++++++++++++++++++++++++++++++++++++++++ engines/kyra/timer.cpp | 3 + 11 files changed, 482 insertions(+), 84 deletions(-) create mode 100644 engines/kyra/saveload.cpp create mode 100644 engines/kyra/saveload_v2.cpp (limited to 'engines') diff --git a/engines/kyra/gui_v1.cpp b/engines/kyra/gui_v1.cpp index e7161e8fcd..1b86b1bb80 100644 --- a/engines/kyra/gui_v1.cpp +++ b/engines/kyra/gui_v1.cpp @@ -756,13 +756,6 @@ int KyraEngine_v1::gui_resumeGame(Button *button) { return 0; } -const char *KyraEngine_v1::getSavegameFilename(int num) { - static char saveLoadSlot[12]; - - sprintf(saveLoadSlot, "%s.%.3d", _targetName.c_str(), num); - return saveLoadSlot; -} - int KyraEngine_v1::getNextSavegameSlot() { Common::InSaveFile *in; diff --git a/engines/kyra/kyra.cpp b/engines/kyra/kyra.cpp index 7fd28dce05..fa2f9d8b77 100644 --- a/engines/kyra/kyra.cpp +++ b/engines/kyra/kyra.cpp @@ -313,6 +313,16 @@ bool KyraEngine::textEnabled() { return !_flags.isTalkie || (_configVoice == 0 || _configVoice == 2); } +const char *KyraEngine::getSavegameFilename(int num) { + static Common::String filename; + char extension[5]; + sprintf(extension, "%3d", num); + + filename = _targetName + "." + extension; + + return filename.c_str(); +} + } // End of namespace Kyra diff --git a/engines/kyra/kyra.h b/engines/kyra/kyra.h index b15e21df5b..d8dc0f4a3a 100644 --- a/engines/kyra/kyra.h +++ b/engines/kyra/kyra.h @@ -33,6 +33,11 @@ #include "kyra/util.h" +namespace Common { +class InSaveFile; +class OutSaveFile; +} // end of namespace Common + namespace Kyra { struct GameFlags { @@ -208,6 +213,14 @@ protected: static const int8 _addXPosTable[]; static const int8 _addYPosTable[]; + + // save/load + virtual uint32 saveGameID() const = 0; + virtual uint32 curSaveVersion() const = 0; + + const char *getSavegameFilename(int num); + Common::InSaveFile *openSaveForReading(const char *filename, uint32 &version, char *saveName); + Common::OutSaveFile *openSaveForWriting(const char *filename, const char *saveName) const; }; } // End of namespace Kyra diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h index fb336f5c65..3944a5b0ed 100644 --- a/engines/kyra/kyra_v1.h +++ b/engines/kyra/kyra_v1.h @@ -280,6 +280,14 @@ public: virtual void snd_playVoiceFile(int id); void snd_voiceWaitForFinish(bool ingame = true); +protected: + enum { + kSaveGameVersion = 8 + }; + + uint32 saveGameID() const { return 'KYRA'; } + uint32 curSaveVersion() const { return kSaveGameVersion; } + void saveGame(const char *fileName, const char *saveName); void loadGame(const char *fileName); @@ -468,7 +476,6 @@ protected: void processMenuButton(Button *button); void processAllMenuButtons(); - const char *getSavegameFilename(int num); void setupSavegames(Menu &menu, int num); int getNextSavegameSlot(); diff --git a/engines/kyra/kyra_v2.cpp b/engines/kyra/kyra_v2.cpp index b0e3c2ae04..35ee9ebc7a 100644 --- a/engines/kyra/kyra_v2.cpp +++ b/engines/kyra/kyra_v2.cpp @@ -422,7 +422,7 @@ void KyraEngine_v2::runLoop() { } } - int inputFlag = checkInput(_buttonList); + int inputFlag = checkInput(_buttonList, true); removeInputTop(); update(); @@ -742,7 +742,7 @@ void KyraEngine_v2::updateInput() { } } -int KyraEngine_v2::checkInput(Button *buttonList) { +int KyraEngine_v2::checkInput(Button *buttonList, bool mainLoop) { updateInput(); int keys = 0; @@ -753,7 +753,18 @@ int KyraEngine_v2::checkInput(Button *buttonList) { switch (event.type) { case Common::EVENT_KEYDOWN: - if (event.kbd.flags == Common::KBD_CTRL) { + if (event.kbd.keycode >= '1' && event.kbd.keycode <= '9' && + (event.kbd.flags == Common::KBD_CTRL || event.kbd.flags == Common::KBD_ALT) && mainLoop) { + const char *saveLoadSlot = getSavegameFilename(event.kbd.keycode - '0'); + + if (event.kbd.flags == Common::KBD_CTRL) + loadGame(saveLoadSlot); + else { + char savegameName[14]; + sprintf(savegameName, "Quicksave %d", event.kbd.keycode - '0'); + saveGame(saveLoadSlot, savegameName); + } + } else if (event.kbd.flags == Common::KBD_CTRL) { if (event.kbd.keycode == 'd') _debugger->attach(); } diff --git a/engines/kyra/kyra_v2.h b/engines/kyra/kyra_v2.h index f94e97b339..07c3271e05 100644 --- a/engines/kyra/kyra_v2.h +++ b/engines/kyra/kyra_v2.h @@ -308,7 +308,7 @@ protected: void updateMouse(); struct Button; - int checkInput(Button *buttonList); + int checkInput(Button *buttonList, bool mainLoop = false); void removeInputTop(); void handleInput(int x, int y); bool handleInputUnkSub(int x, int y); @@ -1167,6 +1167,17 @@ protected: uint8 _inputColorCode[7]; uint32 _scriptCountDown; int _dbgPass; + + // save/load specific + enum { + kSaveGameVersion = 1 + }; + + uint32 saveGameID() const { return 'HOFS'; } + uint32 curSaveVersion() const { return kSaveGameVersion; } + + void saveGame(const char *fileName, const char *saveName); + void loadGame(const char *fileName); }; } // end of namespace Kyra diff --git a/engines/kyra/module.mk b/engines/kyra/module.mk index bce7364cc8..866cb61280 100644 --- a/engines/kyra/module.mk +++ b/engines/kyra/module.mk @@ -14,7 +14,9 @@ MODULE_OBJS := \ kyra_v2.o \ kyra_v3.o \ resource.o \ + saveload.o \ saveload_v1.o \ + saveload_v2.o \ scene.o \ scene_v1.o \ scene_v2.o \ diff --git a/engines/kyra/saveload.cpp b/engines/kyra/saveload.cpp new file mode 100644 index 0000000000..30c6782fb2 --- /dev/null +++ b/engines/kyra/saveload.cpp @@ -0,0 +1,129 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/endian.h" +#include "common/savefile.h" +#include "common/system.h" + +#include "kyra/kyra.h" + +#define GF_FLOPPY (1 << 0) +#define GF_TALKIE (1 << 1) +#define GF_FMTOWNS (1 << 2) + +namespace Kyra { + +Common::InSaveFile *KyraEngine::openSaveForReading(const char *filename, uint32 &version, char *saveName) { + debugC(9, kDebugLevelMain, "KyraEngine::openSaveForReading('%s', %p, %p)", filename, (const void*)&version, saveName); + + Common::InSaveFile *in = 0; + if (!(in = _saveFileMan->openForLoading(filename))) { + warning("Can't open file '%s', game not loaded", filename); + return 0; + } + + uint32 type = in->readUint32BE(); + + // FIXME: The kyra savegame code used to be endian unsafe. Uncomment the + // following line to graciously handle old savegames from LE machines. + // if (type != MKID_BE('KYRA') && type != MKID_BE('ARYK')) { + if (type != MKID_BE(saveGameID())) { + warning("No Kyrandia savefile header."); + delete in; + return 0; + } + + version = in->readUint32BE(); + if (version > curSaveVersion()) { + warning("Savegame is not the right version (%u)", version); + delete in; + return 0; + } + + char saveNameBuffer[31]; + if (!saveName) + saveName = saveNameBuffer; + in->read(saveName, 31); + + if (_flags.gameID == GI_KYRA1 && version < 2) { + warning("Make sure your savefile was from this version! (too old savefile version to detect that)"); + } else { + uint32 flags = in->readUint32BE(); + if ((flags & GF_FLOPPY) && _flags.isTalkie) { + warning("Can not load floppy savefile for this (non floppy) gameversion"); + delete in; + return 0; + } else if ((flags & GF_TALKIE) && !(_flags.isTalkie)) { + warning("Can not load cdrom savefile for this (non cdrom) gameversion"); + delete in; + return 0; + } else if ((flags & GF_FMTOWNS) && !(_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98)) { + warning("can not load FM-Towns/PC98 savefile for this (non FM-Towns/PC98) gameversion"); + delete in; + return 0; + } + } + + if (in->ioFailed()) { + error("Load failed ('%s', '%s').", filename, saveName); + delete in; + return 0; + } + + return in; +} + +Common::OutSaveFile *KyraEngine::openSaveForWriting(const char *filename, const char *saveName) const { + debugC(9, kDebugLevelMain, "KyraEngine::openSaveForWriting('%s', '%s')", filename, saveName); + if (_quitFlag) + return 0; + + Common::OutSaveFile *out = 0; + if (!(out = _saveFileMan->openForSaving(filename))) { + warning("Can't create file '%s', game not saved", filename); + return 0; + } + + // Savegame version + out->writeUint32BE(saveGameID()); + out->writeUint32BE(curSaveVersion()); + out->write(saveName, 31); + if (_flags.isTalkie) + out->writeUint32BE(GF_TALKIE); + else if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) + out->writeUint32BE(GF_FMTOWNS); + else + out->writeUint32BE(GF_FLOPPY); + + if (out->ioFailed()) { + warning("Can't write file '%s'. (Disk full?)", filename); + delete out; + return 0; + } + + return out; +} + +} // end of namespace Kyra diff --git a/engines/kyra/saveload_v1.cpp b/engines/kyra/saveload_v1.cpp index bd4aa24cf1..37ad1fc8d3 100644 --- a/engines/kyra/saveload_v1.cpp +++ b/engines/kyra/saveload_v1.cpp @@ -34,63 +34,15 @@ #include "kyra/sound.h" #include "kyra/timer.h" -#define CURRENT_VERSION 8 - -// TODO: our current savefiles still use the old -// flag system to check the version, we should -// change that some day, but for now it works -#define GF_FLOPPY (1 << 0) -#define GF_TALKIE (1 << 1) -#define GF_FMTOWNS (1 << 2) - namespace Kyra { void KyraEngine_v1::loadGame(const char *fileName) { - debugC(9, kDebugLevelMain, "loadGame('%s')", fileName); - Common::InSaveFile *in; - - if (!(in = _saveFileMan->openForLoading(fileName))) { - warning("Can't open file '%s', game not loaded", fileName); - return; - } - - uint32 type = in->readUint32BE(); - - // FIXME: The kyra savegame code used to be endian unsafe. Uncomment the - // following line to graciously handle old savegames from LE machines. - // if (type != MKID_BE('KYRA') && type != MKID_BE('ARYK')) { - if (type != MKID_BE('KYRA')) { - warning("No Kyrandia 1 savefile header"); - delete in; - return; - } - uint32 version = in->readUint32BE(); - if (version > CURRENT_VERSION) { - warning("Savegame is not the right version (%u)", version); - delete in; - return; - } + debugC(9, kDebugLevelMain, "KyraEngine_v1::loadGame('%s')", fileName); + uint32 version = 0; char saveName[31]; - in->read(saveName, 31); - - if (version >= 2) { - uint32 flags = in->readUint32BE(); - if ((flags & GF_FLOPPY) && _flags.isTalkie) { - warning("Can not load floppy savefile for this (non floppy) gameversion"); - delete in; - return; - } else if ((flags & GF_TALKIE) && !(_flags.isTalkie)) { - warning("Can not load cdrom savefile for this (non cdrom) gameversion"); - delete in; - return; - } else if ((flags & GF_FMTOWNS) && !(_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98)) { - warning("can not load FM-Towns/PC98 savefile for this (non FM-Towns/PC98) gameversion"); - delete in; - return; - } - } else { - warning("Make sure your savefile was from this version! (too old savefile version to detect that)"); - } + Common::InSaveFile *in = openSaveForReading(fileName, version, saveName); + if (!in) + return; snd_playSoundEffect(0x0A); snd_playWanderScoreViaMap(0, 1); @@ -248,7 +200,7 @@ void KyraEngine_v1::loadGame(const char *fileName) { setMousePos(brandonX, brandonY); if (in->ioFailed()) - error("Load failed."); + error("Load failed ('%s', '%s').", fileName, saveName); else debugC(1, kDebugLevelMain, "Loaded savegame '%s.'", saveName); @@ -260,26 +212,15 @@ void KyraEngine_v1::loadGame(const char *fileName) { } void KyraEngine_v1::saveGame(const char *fileName, const char *saveName) { - debugC(9, kDebugLevelMain, "saveGame('%s', '%s')", fileName, saveName); - Common::OutSaveFile *out; - if (_quitFlag) return; - - if (!(out = _saveFileMan->openForSaving(fileName))) { - warning("Can't create file '%s', game not saved", fileName); + debugC(9, kDebugLevelMain, "KyraEngine_v1::saveGame('%s', '%s')", fileName, saveName); + + if (_quitFlag) return; - } - - // Savegame version - out->writeUint32BE(MKID_BE('KYRA')); - out->writeUint32BE(CURRENT_VERSION); - out->write(saveName, 31); - if (_flags.isTalkie) - out->writeUint32BE(GF_TALKIE); - else if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98) - out->writeUint32BE(GF_FMTOWNS); - else - out->writeUint32BE(GF_FLOPPY); + Common::OutSaveFile *out = openSaveForWriting(fileName, saveName); + if (!out) + return; + for (int i = 0; i < 11; i++) { out->writeUint16BE(_characterList[i].sceneId); out->writeByte(_characterList[i].height); diff --git a/engines/kyra/saveload_v2.cpp b/engines/kyra/saveload_v2.cpp new file mode 100644 index 0000000000..a3d63ac36c --- /dev/null +++ b/engines/kyra/saveload_v2.cpp @@ -0,0 +1,278 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/endian.h" +#include "common/savefile.h" +#include "common/system.h" + +#include "kyra/kyra_v2.h" +#include "kyra/screen_v2.h" +#include "kyra/resource.h" +#include "kyra/sound.h" +#include "kyra/timer.h" + +namespace Kyra { + +void KyraEngine_v2::saveGame(const char *fileName, const char *saveName) { + debugC(9, kDebugLevelMain, "KyraEngine_v2::saveGame('%s', '%s')", fileName, saveName); + + Common::OutSaveFile *out = openSaveForWriting(fileName, saveName); + if (!out) + return; + + _timer->saveDataToFile(out); + + out->writeUint32BE(sizeof(_flagsTable)); + out->write(_flagsTable, sizeof(_flagsTable)); + + // usually we have to save the flag set by opcode 10 here + //out->writeUint16BE(word_2AB05); + out->writeSint16BE(_lastMusicCommand); + out->writeByte(_newChapterFile); + out->writeByte(_loadedZTable); + out->writeByte(_cauldronState); + out->writeByte(_colorCodeFlag1); + out->writeByte(_colorCodeFlag2); + out->writeByte(_bookCurPage); + out->writeByte(_bookMaxPage); + for (int i = 0; i < 7; ++i) + out->writeByte(_presetColorCode[i]); + for (int i = 0; i < 7; ++i) + out->writeByte(_inputColorCode[i]); + for (int i = 0; i < 25; ++i) + out->writeSint16BE(_cauldronTable[i]); + for (int i = 0; i < 20; ++i) + out->writeUint16BE(_hiddenItems[i]); + for (int i = 0; i < 19; ++i) + out->write(_conversationState[i], 14); + out->write(_newSceneDlgState, 32); + out->writeSint16BE(_cauldronUseCount); + + out->writeUint16BE(_mainCharacter.sceneId); + out->writeUint16BE(_mainCharacter.dlgIndex); + out->writeByte(_mainCharacter.height); + out->writeByte(_mainCharacter.facing); + out->writeUint16BE(_mainCharacter.animFrame); + out->writeByte(_mainCharacter.unk8); + out->writeByte(_mainCharacter.unk9); + out->writeByte(_mainCharacter.unkA); + for (int i = 0; i < 20; ++i) + out->writeUint16BE(_mainCharacter.inventory[i]); + out->writeSint16BE(_mainCharacter.x1); + out->writeSint16BE(_mainCharacter.y1); + out->writeSint16BE(_mainCharacter.x2); + out->writeSint16BE(_mainCharacter.y2); + + for (int i = 0; i < 30; ++i) { + out->writeUint16BE(_itemList[i].id); + out->writeUint16BE(_itemList[i].sceneId); + out->writeSint16BE(_itemList[i].x); + out->writeByte(_itemList[i].y); + out->writeUint16BE(_itemList[i].unk7); + } + + for (int i = 0; i < 72; ++i) { + out->write(_talkObjectList[i].filename, 13); + out->writeByte(_talkObjectList[i].scriptId); + out->writeSint16BE(_talkObjectList[i].x); + out->writeSint16BE(_talkObjectList[i].y); + out->writeByte(_talkObjectList[i].color); + } + + for (int i = 0; i < 86; ++i) { + out->write(_sceneList[i].filename, 10); + out->writeUint16BE(_sceneList[i].exit1); + out->writeUint16BE(_sceneList[i].exit2); + out->writeUint16BE(_sceneList[i].exit3); + out->writeUint16BE(_sceneList[i].exit4); + out->writeByte(_sceneList[i].flags); + out->writeByte(_sceneList[i].sound); + } + + out->writeSint16BE(_itemInHand); + out->writeUint16BE(_sceneExit1); + out->writeUint16BE(_sceneExit2); + out->writeUint16BE(_sceneExit3); + out->writeUint16BE(_sceneExit4); + + out->finalize(); + + // check for errors + if (out->ioFailed()) + warning("Can't write file '%s'. (Disk full?)", fileName); + else + debugC(1, kDebugLevelMain, "Saved game '%s.'", saveName); + + delete out; +} + +void KyraEngine_v2::loadGame(const char *fileName) { + debugC(9, kDebugLevelMain, "KyraEngine_v2::loadGame('%s')", fileName); + + uint32 version = 0; + char saveName[31]; + Common::InSaveFile *in = openSaveForReading(fileName, version, saveName); + if (!in) + return; + + bool setFlag1EE = (queryGameFlag(0x1EE) != 0); + + //_unk1 = -1; + if (!_unkSceneScreenFlag1) { + _sound->beginFadeOut(); + _system->delayMillis(5 * _tickLength); + _lastMusicCommand = -1; + } + + int loadedZTable = _loadedZTable; + + _screen->hideMouse(); + + _timer->loadDataFromFile(in, 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->readUint16BE(); + _lastMusicCommand = in->readSint16BE(); + _newChapterFile = in->readByte(); + _loadedZTable = 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->readSint16BE(); + for (int i = 0; i < 20; ++i) + _hiddenItems[i] = in->readUint16BE(); + for (int i = 0; i < 19; ++i) + in->read(_conversationState[i], 14); + in->read(_newSceneDlgState, 32); + _cauldronUseCount = in->readSint16BE(); + + _mainCharacter.sceneId = in->readUint16BE(); + _mainCharacter.dlgIndex = in->readUint16BE(); + _mainCharacter.height = in->readByte(); + _mainCharacter.facing = in->readByte(); + _mainCharacter.animFrame = in->readUint16BE(); + _mainCharacter.unk8 = in->readByte(); + _mainCharacter.unk9 = in->readByte(); + _mainCharacter.unkA = in->readByte(); + for (int i = 0; i < 20; ++i) + _mainCharacter.inventory[i] = in->readUint16BE(); + _mainCharacter.x1 = in->readSint16BE(); + _mainCharacter.y1 = in->readSint16BE(); + _mainCharacter.x2 = in->readSint16BE(); + _mainCharacter.y2 = in->readSint16BE(); + + for (int i = 0; i < 30; ++i) { + _itemList[i].id = in->readUint16BE(); + _itemList[i].sceneId = in->readUint16BE(); + _itemList[i].x = in->readSint16BE(); + _itemList[i].y = in->readByte(); + _itemList[i].unk7 = in->readUint16BE(); + } + + for (int i = 0; i < 72; ++i) { + in->read(_talkObjectList[i].filename, 13); + _talkObjectList[i].scriptId = in->readByte(); + _talkObjectList[i].x = in->readSint16BE(); + _talkObjectList[i].y = in->readSint16BE(); + _talkObjectList[i].color = in->readByte(); + } + + for (int i = 0; i < 86; ++i) { + in->read(_sceneList[i].filename, 10); + _sceneList[i].exit1 = in->readUint16BE(); + _sceneList[i].exit2 = in->readUint16BE(); + _sceneList[i].exit3 = in->readUint16BE(); + _sceneList[i].exit4 = in->readUint16BE(); + _sceneList[i].flags = in->readByte(); + _sceneList[i].sound = in->readByte(); + } + + _itemInHand = in->readSint16BE(); + _sceneExit1 = in->readUint16BE(); + _sceneExit2 = in->readUint16BE(); + _sceneExit3 = in->readUint16BE(); + _sceneExit4 = in->readUint16BE(); + + if (in->ioFailed()) + error("Load failed ('%s', '%s').", fileName, saveName); + else + debugC(1, kDebugLevelMain, "Loaded savegame '%s.'", saveName); + + delete in; + + int itemInHand = _itemInHand; + if (loadedZTable != _loadedZTable) + loadZShapes(_loadedZTable); + + _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; + int origX = _mainCharX = _mainCharacter.x2 = _mainCharacter.x1; + int origY = _mainCharY = _mainCharacter.y2 = _mainCharacter.y1; + int origFacing = _mainCharacter.facing; + _mainCharacter.facing = 4; + + enterNewScene(_mainCharacter.sceneId, _mainCharacter.facing, 0, 0, 1); + setHandItem(_itemInHand); + + if (_lastMusicCommand >= 0 && !_unkSceneScreenFlag1) + snd_playWanderScoreViaMap(_lastMusicCommand, 1); + + _screen->showMouse(); + + _mainCharX = _mainCharacter.x2 = _mainCharacter.x1 = origX; + _mainCharY = _mainCharacter.y2 = _mainCharacter.y2 = origY; + _mainCharacter.facing = origFacing; + updateCharacterAnim(0); + flagAnimObjsForRefresh(); + refreshAnimObjectsIfNeed(); + + setTimer1DelaySecs(7); + _shownMessage = " "; + _msgUnk1 = 0; + + if (setFlag1EE) + setGameFlag(0x1EE); +} + +} // end of namespace Kyra diff --git a/engines/kyra/timer.cpp b/engines/kyra/timer.cpp index c0f47111c6..62e64773c8 100644 --- a/engines/kyra/timer.cpp +++ b/engines/kyra/timer.cpp @@ -198,6 +198,9 @@ void TimerManager::disable(uint8 id) { void TimerManager::loadDataFromFile(Common::InSaveFile *file, int version) { debugC(9, kDebugLevelTimer, "TimerManager::loadDataFromFile(%p, %d)", (const void*)file, version); + if (_vm->game() != GI_KYRA1) + version += 7; + if (version <= 7) { _nextRun = 0; for (int i = 0; i < 32; ++i) { -- cgit v1.2.3