From 34368e5650c81cd52ae20d91d475be979359cfe3 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Sat, 20 Dec 2008 23:08:37 +0000 Subject: Fixed loading Discworld 2 savegames from GMM. svn-id: r35453 --- engines/tinsel/detection.cpp | 40 +++++++++++++++++++++++++++++++++++++++- engines/tinsel/saveload.cpp | 21 +++++++-------------- engines/tinsel/savescn.cpp | 4 ++-- engines/tinsel/savescn.h | 6 +++--- 4 files changed, 51 insertions(+), 20 deletions(-) (limited to 'engines') diff --git a/engines/tinsel/detection.cpp b/engines/tinsel/detection.cpp index c1ce5fe83d..5b22659d26 100644 --- a/engines/tinsel/detection.cpp +++ b/engines/tinsel/detection.cpp @@ -535,7 +535,45 @@ void TinselMetaEngine::removeSaveState(const char *target, int slot) const { namespace Tinsel { Common::Error TinselEngine::loadGameState(int slot) { - RestoreGame(slot, true); + // FIXME: Hopefully this is only used when loading games via + // the launcher, since we do a hacky savegame slot to savelist + // entry mapping here. + // + // You might wonder why is needed and here is the answer: + // The save/load dialog of the GMM operates with the physical + // savegame slots, while Tinsel internally uses entry numbers in + // a savelist (which is sorted latest to first). Now to allow + // proper loading of (especially Discworld2) saves we need to + // get a savelist entry number instead of the physical slot. + // + // There are different possible solutions: + // + // One way to fix this would be to pass the filename instead of + // the savelist entry number to RestoreGame, though it could make + // problems how DW2 handles CD switches. Normally DW2 would pass + // '-2' as slot when it changes CDs. + // + // Another way would be to convert all of Tinsel to use physical + // slot numbers instead of savelist entry numbers for loading. + // This would also allow '-2' as slot for CD changes without + // any major hackery. + + int listSlot = -1; + const int numStates = Tinsel::getList(); + for (int i = 0; i < numStates; ++i) { + const char *fileName = Tinsel::ListEntry(i, Tinsel::LE_NAME); + const int saveSlot = atoi(fileName + strlen(fileName) - 2); + + if (saveSlot == slot) { + listSlot = i; + break; + } + } + + if (listSlot == -1) + return Common::kUnknownError; // TODO: proper error code + + RestoreGame(listSlot); return Common::kNoError; // TODO: return success/failure } diff --git a/engines/tinsel/saveload.cpp b/engines/tinsel/saveload.cpp index 5693e31caa..02153aed59 100644 --- a/engines/tinsel/saveload.cpp +++ b/engines/tinsel/saveload.cpp @@ -96,7 +96,7 @@ struct SaveGameHeader { enum { DW1_SAVEGAME_ID = 0x44575399, // = 'DWSc' = "DiscWorld 1 ScummVM" - DW2_SAVEGAME_ID = 0x44573253, // = 'DW2S' = "DiscWOrld 2 ScummVM" + DW2_SAVEGAME_ID = 0x44573253, // = 'DW2S' = "DiscWorld 2 ScummVM" SAVEGAME_HEADER_SIZE = 4 + 4 + 4 + SG_DESC_LEN + 7 }; @@ -429,15 +429,9 @@ static void DoSync(Serializer &s) { /** * DoRestore */ -static bool DoRestore(bool fromGMM) { - Common::InSaveFile *f; - uint32 id; +static bool DoRestore() { + Common::InSaveFile *f = _vm->getSaveFileMan()->openForLoading(savedFiles[RestoreGameNumber].name); - if (!fromGMM) - f = _vm->getSaveFileMan()->openForLoading(savedFiles[RestoreGameNumber].name); - else - f = _vm->getSaveFileMan()->openForLoading(_vm->getSavegameFilename(RestoreGameNumber).c_str()); - if (f == NULL) { return false; } @@ -451,7 +445,7 @@ static bool DoRestore(bool fromGMM) { DoSync(s); - id = f->readSint32LE(); + uint32 id = f->readSint32LE(); if (id != (uint32)0xFEEDFACE) error("Incompatible saved game"); @@ -519,8 +513,7 @@ save_failure: void ProcessSRQueue(void) { switch (SRstate) { case SR_DORESTORE: - case SR_DORESTORE_GMM: - if (DoRestore(SRstate == SR_DORESTORE_GMM)) { + if (DoRestore()) { DoRestoreScene(srsd, false); } SRstate = SR_IDLE; @@ -547,7 +540,7 @@ void RequestSaveGame(char *name, char *desc, SAVED_DATA *sd, int *pSsCount, SAVE SRstate = SR_DOSAVE; } -void RequestRestoreGame(int num, SAVED_DATA *sd, int *pSsCount, SAVED_DATA *pSsData, bool fromGMM) { +void RequestRestoreGame(int num, SAVED_DATA *sd, int *pSsCount, SAVED_DATA *pSsData) { if (TinselV2) { if (num == -1) return; @@ -563,7 +556,7 @@ void RequestRestoreGame(int num, SAVED_DATA *sd, int *pSsCount, SAVED_DATA *pSsD SaveSceneSsCount = pSsCount; SaveSceneSsData = (char *)pSsData; srsd = sd; - SRstate = (!fromGMM) ? SR_DORESTORE : SR_DORESTORE_GMM; + SRstate = SR_DORESTORE; } /** diff --git a/engines/tinsel/savescn.cpp b/engines/tinsel/savescn.cpp index 93b81051f5..66564f1c81 100644 --- a/engines/tinsel/savescn.cpp +++ b/engines/tinsel/savescn.cpp @@ -404,10 +404,10 @@ static int DoRestoreSceneFrame(SAVED_DATA *sd, int n) { * Restore game * @param num num */ -void RestoreGame(int num, bool fromGMM) { +void RestoreGame(int num) { KillInventory(); - RequestRestoreGame(num, &sgData, &savedSceneCount, ssData, fromGMM); + RequestRestoreGame(num, &sgData, &savedSceneCount, ssData); // Actual restoring is performed by ProcessSRQueue } diff --git a/engines/tinsel/savescn.h b/engines/tinsel/savescn.h index 7bc4faefd0..e7a4f18adf 100644 --- a/engines/tinsel/savescn.h +++ b/engines/tinsel/savescn.h @@ -83,7 +83,7 @@ struct SAVED_DATA { enum SRSTATE { - SR_IDLE, SR_DORESTORE, SR_DORESTORE_GMM, SR_DONERESTORE, + SR_IDLE, SR_DORESTORE, SR_DONERESTORE, SR_DOSAVE, SR_DONESAVE, SR_ABORTED }; @@ -103,13 +103,13 @@ char *ListEntry(int i, letype which); int getList(void); void setNeedLoad(void); -void RestoreGame(int num, bool fromGMM = false); +void RestoreGame(int num); void SaveGame(char *name, char *desc); void ProcessSRQueue(void); void RequestSaveGame(char *name, char *desc, SAVED_DATA *sd, int *ssCount, SAVED_DATA *ssData); -void RequestRestoreGame(int num, SAVED_DATA *sd, int *ssCount, SAVED_DATA *ssData, bool fromGMM); +void RequestRestoreGame(int num, SAVED_DATA *sd, int *ssCount, SAVED_DATA *ssData); void InitialiseSaveScenes(void); void FreeSaveScenes(void); -- cgit v1.2.3