From 9b6a3712d6c237ac8453221b07a5a14ad0409e96 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Sat, 22 May 2010 16:50:15 +0000 Subject: Rewrote and simplified the game ID detector. It now properly works with SCI0-SCI2.1 games svn-id: r49142 --- engines/sci/detection.cpp | 82 ++++++++++++++++------------------------------- 1 file changed, 28 insertions(+), 54 deletions(-) (limited to 'engines/sci') 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; -- cgit v1.2.3