aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/detection.cpp
diff options
context:
space:
mode:
authorFilippos Karapetis2010-05-19 15:57:58 +0000
committerFilippos Karapetis2010-05-19 15:57:58 +0000
commit480e5c84888c40a54f173c90bc634fa579b83b79 (patch)
treecf8c8d767962d8c2fea4954120b302ac70295d20 /engines/sci/detection.cpp
parent3f10841ae8f167cd6bc08ef266d0161c2d608624 (diff)
downloadscummvm-rg350-480e5c84888c40a54f173c90bc634fa579b83b79.tar.gz
scummvm-rg350-480e5c84888c40a54f173c90bc634fa579b83b79.tar.bz2
scummvm-rg350-480e5c84888c40a54f173c90bc634fa579b83b79.zip
Added a new method to the resource manager, to help determine if we got a SCI1.1 Mac game. Started rewriting the fallback detector so that it doesn't rely on the segment manager to find the internal game ID
svn-id: r49102
Diffstat (limited to 'engines/sci/detection.cpp')
-rw-r--r--engines/sci/detection.cpp58
1 files changed, 45 insertions, 13 deletions
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp
index b574484319..63fc95e04e 100644
--- a/engines/sci/detection.cpp
+++ b/engines/sci/detection.cpp
@@ -33,6 +33,7 @@
#include "sci/sci.h"
#include "sci/engine/kernel.h"
#include "sci/engine/savegame.h"
+#include "sci/engine/script.h"
#include "sci/engine/seg_manager.h"
#include "sci/engine/state.h"
#include "sci/engine/vm.h" // for convertSierraGameId
@@ -204,6 +205,49 @@ Common::Language charToScummVMLanguage(const char c) {
}
}
+#define READ_UINT16(buf) (!resMan->isSci11Mac() ? READ_LE_UINT16(buf) : READ_BE_UINT16(buf))
+
+// Finds the internal ID of the current game from script 0
+Common::String getSierraGameId(ResourceManager *resMan) {
+ Resource *script = resMan->findResource(ResourceId(kResourceTypeScript, 0), false);
+ Script *script000 = new Script();
+ script000->init(0, resMan);
+ script000->mcpyInOut(0, script->data, script->size);
+ uint16 curOffset = (getSciVersion() == SCI_VERSION_0_EARLY) ? 2 : 0;
+ uint16 objLength = 0;
+ int objType = 0;
+ int16 exportsOffset = 0;
+ Common::String sierraId;
+
+ // Now find the export table of the script
+ do {
+ objType = READ_UINT16(script000->_buf + curOffset);
+ if (!objType)
+ break;
+
+ objLength = READ_UINT16(script000->_buf + curOffset + 2);
+ curOffset += 4; // skip header
+
+ if (objType == SCI_OBJ_EXPORTS) {
+ exportsOffset = READ_UINT16(script000->_buf + curOffset + 2);
+ break;
+ }
+ } while (objType != 0);
+
+ // The game object is the first export. Script 0 is always at segment 1
+ reg_t gameObj = make_reg(1, exportsOffset);
+
+ // TODO: stop using the segment manager and read the object name here
+ SegManager *segMan = new SegManager(resMan);
+ script_instantiate(resMan, segMan, 0);
+ sierraId = segMan->getObjectName(gameObj);
+ delete segMan;
+
+ delete script000;
+
+ return sierraId;
+}
+
const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fslist) const {
bool foundResMap = false;
bool foundRes000 = false;
@@ -315,22 +359,10 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fsl
s_fallbackDesc.platform = Common::kPlatformAmiga;
// Determine the game id
- SegManager *segMan = new SegManager(resMan);
- if (!script_instantiate(resMan, segMan, 0)) {
- warning("fallbackDetect(): Could not instantiate script 0");
- SearchMan.remove("SCI_detection");
- delete segMan;
- delete resMan;
- return 0;
- }
- reg_t game_obj = segMan->lookupScriptExport(0, 0);
- const char *sierraGameId = segMan->getObjectName(game_obj);
- debug(2, "Detected ID: \"%s\" at %04x:%04x", sierraGameId, PRINT_REG(game_obj));
- Common::String gameId = convertSierraGameId(sierraGameId, &s_fallbackDesc.flags, resMan);
+ Common::String gameId = convertSierraGameId(getSierraGameId(resMan).c_str(), &s_fallbackDesc.flags, resMan);
strncpy(s_fallbackGameIdBuf, gameId.c_str(), sizeof(s_fallbackGameIdBuf) - 1);
s_fallbackGameIdBuf[sizeof(s_fallbackGameIdBuf) - 1] = 0; // Make sure string is NULL terminated
s_fallbackDesc.gameid = s_fallbackGameIdBuf;
- delete segMan;
// Try to determine the game language
// Load up text 0 and start looking for "#" characters