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;