aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/detection.cpp
diff options
context:
space:
mode:
authorFilippos Karapetis2010-05-22 16:50:15 +0000
committerFilippos Karapetis2010-05-22 16:50:15 +0000
commit9b6a3712d6c237ac8453221b07a5a14ad0409e96 (patch)
treeb3bb6556bc68bf8fa078919d6d9bf45299921dfa /engines/sci/detection.cpp
parent45a5c29cdf01d7cade0dbfaf7ae2ee92bd75cc56 (diff)
downloadscummvm-rg350-9b6a3712d6c237ac8453221b07a5a14ad0409e96.tar.gz
scummvm-rg350-9b6a3712d6c237ac8453221b07a5a14ad0409e96.tar.bz2
scummvm-rg350-9b6a3712d6c237ac8453221b07a5a14ad0409e96.zip
Rewrote and simplified the game ID detector. It now properly works with SCI0-SCI2.1 games
svn-id: r49142
Diffstat (limited to 'engines/sci/detection.cpp')
-rw-r--r--engines/sci/detection.cpp82
1 files changed, 28 insertions, 54 deletions
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp
index ba8353c545..55816b769b 100644
--- a/engines/sci/detection.cpp
+++ b/engines/sci/detection.cpp
@@ -205,70 +205,44 @@ Common::Language charToScummVMLanguage(const char c) {
}
}
-#define READ_UINT16(buf) (!resMan->isSci11Mac() ? READ_LE_UINT16(buf) : READ_BE_UINT16(buf))
+#define READ_UINT16(ptr) (!resMan->isSci11Mac() ? READ_LE_UINT16(ptr) : READ_BE_UINT16(ptr))
// Finds the internal ID of the current game from script 0
Common::String getSierraGameId(ResourceManager *resMan) {
Resource *script = resMan->findResource(ResourceId(kResourceTypeScript, 0), false);
- uint16 curOffset = (getSciVersion() == SCI_VERSION_0_EARLY) ? 2 : 0;
- uint16 objLength = 0;
- int objType = 0;
- int16 exportsOffset = 0;
- int16 magicOffset = (getSciVersion() < SCI_VERSION_1_1) ? 8 : 0;
-
- // TODO: SCI1.1 version
- if (getSciVersion() >= SCI_VERSION_1_1) {
- //if (READ_UINT16(script->data + 6) > 0)
- // exportsOffset = READ_UINT16(script->data + 6 + 2);
- return "sci";
+ // In SCI0-SCI1, the heap is embedded in the script. In SCI1.1+, it's separated
+ Resource *heap = 0;
+ int nameSelector = 0;
+ byte *exportPtr, *heapPtr;
+
+ // Seek to the name selector of the first export
+ if (getSciVersion() < SCI_VERSION_1_1) {
+ int extraSci0EarlyBytes = (getSciVersion() == SCI_VERSION_0_EARLY) ? 2 : 0;
+ nameSelector = 3;
+ exportPtr = script->data + extraSci0EarlyBytes + 4 + 2;
+ heapPtr = script->data;
+ } else {
+ nameSelector = 5 + 3;
+ exportPtr = script->data + 4 + 2 + 2;
+ heap = resMan->findResource(ResourceId(kResourceTypeHeap, 0), false);
+ heapPtr = heap->data;
}
- // Now find the export table of the script
- do {
- objType = READ_UINT16(script->data + curOffset);
- if (!objType)
- break;
-
- objLength = READ_UINT16(script->data + curOffset + 2);
- curOffset += 4; // skip header
-
- switch (objType) {
- case SCI_OBJ_EXPORTS:
- exportsOffset = READ_UINT16(script->data + curOffset + 2);
- break;
- case SCI_OBJ_OBJECT:
- case SCI_OBJ_CLASS:
- // The game object is the first export
- if (curOffset == exportsOffset - magicOffset) {
- // The name selector is the third one
- uint16 nameSelectorOffset = READ_UINT16(script->data + curOffset + magicOffset + 3 * 2);
-
- char sierraId[20];
- int i = 0;
- byte curChar = 0;
-
- do {
- curChar = *(script->data + nameSelectorOffset + i);
- sierraId[i++] = curChar;
- } while (curChar != 0);
-
- return sierraId;
- }
- break;
- case SCI_OBJ_CODE:
- case SCI_OBJ_SYNONYMS:
- case SCI_OBJ_LOCALVARS:
- case SCI_OBJ_POINTERS: // A relocation table
- // Ignore
- break;
- }
+ byte *seeker = heapPtr + READ_UINT16(heapPtr + READ_UINT16(exportPtr) + nameSelector * 2);
+ char sierraId[20];
+ int i = 0;
+ byte curChar = 0;
- curOffset += objLength - 4;
- } while (objType != 0 && curOffset < script->size - 2);
+ do {
+ curChar = *(seeker + i);
+ sierraId[i++] = curChar;
+ } while (curChar != 0);
- return "sci"; // detection failed
+ return sierraId;
}
+#undef READ_UINT16
+
const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fslist) const {
bool foundResMap = false;
bool foundRes000 = false;