From 3007bbe17827e795eff448ab931d1d5504e5c75c Mon Sep 17 00:00:00 2001 From: Bastien Bouclet Date: Sun, 6 Aug 2017 08:32:28 +0200 Subject: [PATCH] MOHAWK: Riven: Load only the data files for the current game version The Steam version is a DVD version, but also has files from the CD version in the data folder. We need to load only the files from the DVD version to prevent data inconsistencies. Also check on startup that all the required datafiles are present. Possibly fixes #10052. --- engines/mohawk/riven.cpp | 104 +++++++++++++++++++++++++++++++++------ engines/mohawk/riven.h | 4 ++ 2 files changed, 94 insertions(+), 14 deletions(-) diff --git a/engines/mohawk/riven.cpp b/engines/mohawk/riven.cpp index 4d4f54c2403c..8fd28052e02a 100644 --- a/engines/mohawk/riven.cpp +++ b/engines/mohawk/riven.cpp @@ -139,6 +139,11 @@ Common::Error MohawkEngine_Riven::run() { initVars(); + // Check the user has copied all the required datafiles + if (!checkDatafiles()) { + return Common::kNoGameDataFoundError; + } + // We need to have a cursor source, or the game won't work if (!_cursor->hasSource()) { Common::String message = _("You're missing a Riven executable. The Windows executable is 'riven.exe' or 'rivendmo.exe'. "); @@ -289,11 +294,6 @@ void MohawkEngine_Riven::pauseEngineIntern(bool pause) { // Stack/Card-Related Functions void MohawkEngine_Riven::changeToStack(uint16 stackId) { - // The endings are in reverse order because of the way the 1.02 patch works. - // The only "Data3" file is j_Data3.mhk from that patch. Patch files have higher - // priorities over the regular files and are therefore loaded and checked first. - static const char *endings[] = { "_Data3.mhk", "_Data2.mhk", "_Data1.mhk", "_Data.mhk", "_Sounds.mhk" }; - // Don't change stack to the current stack (if the files are loaded) if (_stack && _stack->getId() == stackId && !_mhk.empty()) return; @@ -318,15 +318,16 @@ void MohawkEngine_Riven::changeToStack(uint16 stackId) { // Get the prefix character for the destination stack char prefix = RivenStacks::getName(stackId)[0]; - // Load any file that fits the patterns - for (int i = 0; i < ARRAYSIZE(endings); i++) { - Common::String filename = Common::String(prefix) + endings[i]; - - MohawkArchive *mhk = new MohawkArchive(); - if (mhk->openFile(filename)) - _mhk.push_back(mhk); - else - delete mhk; + // Load files that start with the prefix + const char **datafiles = listExpectedDatafiles(); + for (int i = 0; datafiles[i] != nullptr; i++) { + if (datafiles[i][0] == prefix) { + MohawkArchive *mhk = new MohawkArchive(); + if (mhk->openFile(datafiles[i])) + _mhk.push_back(mhk); + else + delete mhk; + } } // Make sure we have loaded files @@ -337,6 +338,81 @@ void MohawkEngine_Riven::changeToStack(uint16 stackId) { _stack = constructStackById(stackId); } +const char **MohawkEngine_Riven::listExpectedDatafiles() const { + // The files are in reverse order because of the way the 1.02 patch works. + // The only "Data3" file is j_Data3.mhk from that patch. Patch files have higher + // priorities over the regular files and are therefore loaded and checked first. + static const char *datafilesDVD[] = { + "a_Data.mhk", "a_Sounds.mhk", + "b_Data.mhk", "b_Sounds.mhk", + "g_Data.mhk", "g_Sounds.mhk", + "j_Data2.mhk", "j_Data1.mhk", "j_Sounds.mhk", + "o_Data.mhk", "o_Sounds.mhk", + "p_Data.mhk", "p_Sounds.mhk", + "r_Data.mhk", "r_Sounds.mhk", + "t_Data2.mhk", "t_Data1.mhk", "t_Sounds.mhk", + nullptr + }; + + static const char *datafilesCD[] = { + "a_Data.mhk", "a_Sounds.mhk", + "b_Data1.mhk", "b_Data.mhk", "b_Sounds.mhk", + "g_Data.mhk", "g_Sounds.mhk", + "j_Data3.mhk", "j_Data2.mhk", "j_Data1.mhk", "j_Sounds.mhk", + "o_Data.mhk", "o_Sounds.mhk", + "p_Data.mhk", "p_Sounds.mhk", + "r_Data.mhk", "r_Sounds.mhk", + "t_Data.mhk", "t_Sounds.mhk", + nullptr + }; + + static const char *datafilesDemo[] = { + "a_Data.mhk", "a_Sounds.mhk", + "j_Data.mhk", "j_Sounds.mhk", + "t_Data.mhk", "t_Sounds.mhk", + nullptr + }; + + const char **datafiles; + if (getFeatures() & GF_DEMO) { + datafiles = datafilesDemo; + } else if (getFeatures() & GF_DVD) { + datafiles = datafilesDVD; + } else { + datafiles = datafilesCD; + } + return datafiles; +} + +bool MohawkEngine_Riven::checkDatafiles() { + Common::String missingFiles; + + const char **datafiles = listExpectedDatafiles(); + for (int i = 0; datafiles[i] != nullptr; i++) { + if (!SearchMan.hasFile(datafiles[i])) { + if (strcmp(datafiles[i], "j_Data3.mhk") == 0) { + // j_Data3.mhk comes from the 1.02 patch. It is not required to play. + continue; + } + + if (!missingFiles.empty()) { + missingFiles += ", "; + } + missingFiles += datafiles[i]; + } + } + + if (missingFiles.empty()) { + return true; + } + + Common::String message = _("You are missing the following required Riven data files:\n") + missingFiles; + warning("%s", message.c_str()); + GUIErrorMessage(message); + + return false; +} + RivenStack *MohawkEngine_Riven::constructStackById(uint16 id) { switch (id) { case kStackAspit: diff --git a/engines/mohawk/riven.h b/engines/mohawk/riven.h index 4c4e303fa3be..58d0855074c2 100644 --- a/engines/mohawk/riven.h +++ b/engines/mohawk/riven.h @@ -107,7 +107,11 @@ class MohawkEngine_Riven : public MohawkEngine { void doFrame(); private: + // Datafiles MohawkArchive *_extrasFile; // We need a separate handle for the extra data + const char **listExpectedDatafiles() const; + bool checkDatafiles(); + RivenConsole *_console; RivenSaveLoad *_saveLoad; RivenOptionsDialog *_optionsDialog;