diff options
author | Martin Kiewitz | 2015-05-14 20:33:21 +0200 |
---|---|---|
committer | Martin Kiewitz | 2015-05-14 20:33:21 +0200 |
commit | bfab4c4cbe3d857ef6a067440ea17baa8b30ec4d (patch) | |
tree | 39101ed09bdb030013425ae96e39ec99785df7e5 | |
parent | fdfb7775a49ec6b93cbaa720b88fee37e052a86c (diff) | |
download | scummvm-rg350-bfab4c4cbe3d857ef6a067440ea17baa8b30ec4d.tar.gz scummvm-rg350-bfab4c4cbe3d857ef6a067440ea17baa8b30ec4d.tar.bz2 scummvm-rg350-bfab4c4cbe3d857ef6a067440ea17baa8b30ec4d.zip |
SCI: debug commands scro, scrs and script_said
implement string collecting for SCI3
implement object offset collecting for SCI0-SCI2
implement said-str offset collecting for SCI0-SCI1
add new debug command scro / script_objects
add new debug command script_said
string without terminating NUL now a warning
the latter happens in qfg2 for amiga room 84
-rw-r--r-- | engines/sci/console.cpp | 151 | ||||
-rw-r--r-- | engines/sci/console.h | 3 | ||||
-rw-r--r-- | engines/sci/engine/script.cpp | 259 | ||||
-rw-r--r-- | engines/sci/engine/script.h | 26 |
4 files changed, 369 insertions, 70 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index dc017a7a70..c7069709d4 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -209,8 +209,11 @@ Console::Console(SciEngine *engine) : GUI::Debugger(), registerCmd("bpe", WRAP_METHOD(Console, cmdBreakpointFunction)); // alias // VM registerCmd("script_steps", WRAP_METHOD(Console, cmdScriptSteps)); + registerCmd("script_objects", WRAP_METHOD(Console, cmdScriptObjects)); + registerCmd("scro", WRAP_METHOD(Console, cmdScriptObjects)); registerCmd("script_strings", WRAP_METHOD(Console, cmdScriptStrings)); registerCmd("scrs", WRAP_METHOD(Console, cmdScriptStrings)); + registerCmd("script_said", WRAP_METHOD(Console, cmdScriptSaid)); registerCmd("vm_varlist", WRAP_METHOD(Console, cmdVMVarlist)); registerCmd("vmvarlist", WRAP_METHOD(Console, cmdVMVarlist)); // alias registerCmd("vl", WRAP_METHOD(Console, cmdVMVarlist)); // alias @@ -2830,28 +2833,85 @@ bool Console::cmdScriptSteps(int argc, const char **argv) { return true; } -bool Console::cmdScriptStrings(int argc, const char **argv) { - SegManager *segMan = _engine->_gamestate->_segMan; +bool Console::cmdScriptObjects(int argc, const char **argv) { int curScriptNr = -1; - SegmentId curSegmentNr; - Common::List<SegmentId> segmentNrList; - SegmentType curSegmentType = SEG_TYPE_INVALID; - SegmentObj *curSegmentObj = NULL; - Script *curScriptObj = NULL; + if (argc < 2) { + debugPrintf("Shows all objects inside a specified script.\n"); + debugPrintf("Usage: %s <script number>\n", argv[0]); + debugPrintf("Example: %s 999\n", argv[0]); + debugPrintf("<script number> may be * to show objects inside all loaded scripts\n"); + return true; + } + + if (strcmp(argv[1], "*") == 0) { + // get said-strings of all currently loaded scripts + curScriptNr = -1; + } else { + curScriptNr = atoi(argv[1]); + } + + printOffsets(curScriptNr, SCI_SCR_OFFSET_TYPE_OBJECT); + return true; +} + +bool Console::cmdScriptStrings(int argc, const char **argv) { + int curScriptNr = -1; if (argc < 2) { - debugPrintf("Shows the strings inside a specified script.\n"); + debugPrintf("Shows all strings inside a specified script.\n"); debugPrintf("Usage: %s <script number>\n", argv[0]); debugPrintf("Example: %s 999\n", argv[0]); debugPrintf("<script number> may be * to show strings inside all loaded scripts\n"); return true; } - segmentNrList.clear(); - if (strcmp(argv[1], "*") == 0) { // get strings of all currently loaded scripts + curScriptNr = -1; + } else { + curScriptNr = atoi(argv[1]); + } + + printOffsets(curScriptNr, SCI_SCR_OFFSET_TYPE_STRING); + return true; +} + +bool Console::cmdScriptSaid(int argc, const char **argv) { + int curScriptNr = -1; + + if (argc < 2) { + debugPrintf("Shows all said-strings inside a specified script.\n"); + debugPrintf("Usage: %s <script number>\n", argv[0]); + debugPrintf("Example: %s 999\n", argv[0]); + debugPrintf("<script number> may be * to show said-strings inside all loaded scripts\n"); + return true; + } + + if (strcmp(argv[1], "*") == 0) { + // get said-strings of all currently loaded scripts + curScriptNr = -1; + } else { + curScriptNr = atoi(argv[1]); + } + + printOffsets(curScriptNr, SCI_SCR_OFFSET_TYPE_SAID); + return true; +} + +void Console::printOffsets(int scriptNr, uint16 showType) { + SegManager *segMan = _engine->_gamestate->_segMan; + SegmentId curSegmentNr; + Common::List<SegmentId> segmentNrList; + + SegmentType curSegmentType = SEG_TYPE_INVALID; + SegmentObj *curSegmentObj = NULL; + Script *curScriptObj = NULL; + const byte *curScriptData = NULL; + + segmentNrList.clear(); + if (scriptNr < 0) { + // get offsets of all currently loaded scripts for (curSegmentNr = 0; curSegmentNr < segMan->_heap.size(); curSegmentNr++) { curSegmentObj = segMan->_heap[curSegmentNr]; if (curSegmentObj && curSegmentObj->getType() == SEG_TYPE_SCRIPT) { @@ -2860,15 +2920,22 @@ bool Console::cmdScriptStrings(int argc, const char **argv) { } } else { - curScriptNr = atoi(argv[1]); - curSegmentNr = segMan->getScriptSegment(curScriptNr); + curSegmentNr = segMan->getScriptSegment(scriptNr); if (!curSegmentNr) { - debugPrintf("Script %d is currently not loaded/available\n", curScriptNr); - return true; + debugPrintf("Script %d is currently not loaded/available\n", scriptNr); + return; } segmentNrList.push_back(curSegmentNr); } + const offsetLookupArrayType *scriptOffsetLookupArray; + offsetLookupArrayType::const_iterator arrayIterator; + int showTypeCount = 0; + + reg_t objectPos; + const char *objectNamePtr = NULL; + const byte *stringPtr = NULL; + Common::List<SegmentId>::iterator it; const Common::List<SegmentId>::iterator end = segmentNrList.end(); @@ -2884,15 +2951,61 @@ bool Console::cmdScriptStrings(int argc, const char **argv) { continue; curScriptObj = (Script *)curSegmentObj; - debugPrintf("=== SCRIPT %d from Segment %d ===\n", curScriptObj->getScriptNumber(), curSegmentNr); - debugN("=== SCRIPT %d from Segment %d ===\n", curScriptObj->getScriptNumber(), curSegmentNr); + debugPrintf("=== SCRIPT %d inside Segment %d ===\n", curScriptObj->getScriptNumber(), curSegmentNr); + debugN("=== SCRIPT %d inside Segment %d ===\n", curScriptObj->getScriptNumber(), curSegmentNr); + + // now print the list + scriptOffsetLookupArray = curScriptObj->getOffsetArray(); + curScriptData = curScriptObj->getBuf(); + showTypeCount = 0; + + for (arrayIterator = scriptOffsetLookupArray->begin(); arrayIterator != scriptOffsetLookupArray->end(); arrayIterator++) { + if (arrayIterator->type == showType) { + switch (showType) { + case SCI_SCR_OFFSET_TYPE_OBJECT: + objectPos = make_reg(curSegmentNr, arrayIterator->offset); + objectNamePtr = segMan->getObjectName(objectPos); + debugPrintf(" %03d:%04x: %s\n", arrayIterator->id, arrayIterator->offset, objectNamePtr); + debugN(" %03d:%04x: %s\n", arrayIterator->id, arrayIterator->offset, objectNamePtr); + break; + case SCI_SCR_OFFSET_TYPE_STRING: + stringPtr = curScriptData + arrayIterator->offset; + debugPrintf(" %03d:%04x: '%s' (size %d)\n", arrayIterator->id, arrayIterator->offset, stringPtr, arrayIterator->stringSize); + debugN(" %03d:%04x: '%s' (size %d)\n", arrayIterator->id, arrayIterator->offset, stringPtr, arrayIterator->stringSize); + break; + case SCI_SCR_OFFSET_TYPE_SAID: + debugPrintf(" %03d:%04x:\n", arrayIterator->id, arrayIterator->offset); + debugN(" %03d:%04x:\n", arrayIterator->id, arrayIterator->offset); + break; + default: + break; + } + showTypeCount++; + } + } + + if (showTypeCount == 0) { + switch (showType) { + case SCI_SCR_OFFSET_TYPE_OBJECT: + debugPrintf(" no objects\n"); + debugN(" no objects\n"); + break; + case SCI_SCR_OFFSET_TYPE_STRING: + debugPrintf(" no strings\n"); + debugN(" no strings\n"); + break; + case SCI_SCR_OFFSET_TYPE_SAID: + debugPrintf(" no said-strings\n"); + debugN(" no said-strings\n"); + break; + default: + break; + } + } - // now print the string list - curScriptObj->debugPrintStrings(this); debugPrintf("\n"); debugN("\n"); } - return true; } bool Console::cmdBacktrace(int argc, const char **argv) { diff --git a/engines/sci/console.h b/engines/sci/console.h index 00d95b511f..8b10912fbe 100644 --- a/engines/sci/console.h +++ b/engines/sci/console.h @@ -147,7 +147,9 @@ private: bool cmdBreakpointFunction(int argc, const char **argv); // VM bool cmdScriptSteps(int argc, const char **argv); + bool cmdScriptObjects(int argc, const char **argv); bool cmdScriptStrings(int argc, const char **argv); + bool cmdScriptSaid(int argc, const char **argv); bool cmdVMVarlist(int argc, const char **argv); bool cmdVMVars(int argc, const char **argv); bool cmdStack(int argc, const char **argv); @@ -167,6 +169,7 @@ private: void printList(List *list); int printNode(reg_t addr); void hexDumpReg(const reg_t *data, int len, int regsPerLine = 4, int startOffset = 0, bool isArray = false); + void printOffsets(int scriptNr, uint16 showType); private: /** diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 69f52495e0..fbf00abf9b 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -65,7 +65,7 @@ void Script::freeScript() { _lockers = 1; _markedAsDeleted = false; _objects.clear(); - _stringLookupList.clear(); + _offsetLookupArray.clear(); } void Script::load(int script_nr, ResourceManager *resMan, ScriptPatcher *scriptPatcher) { @@ -208,39 +208,41 @@ void Script::load(int script_nr, ResourceManager *resMan, ScriptPatcher *scriptP } // find all strings of this script - identifyStrings(); + identifyOffsets(); } -void Script::identifyStrings() { - stringLookupListEntry listEntry; +void Script::identifyOffsets() { + offsetLookupArrayEntry arrayEntry; byte *scriptDataPtr = NULL; byte *stringStartPtr = NULL; byte *stringDataPtr = NULL; int scriptDataLeft = 0; int stringDataLeft = 0; byte stringDataByte = 0; + uint16 typeObject_id = 0; + uint16 typeString_id = 0; + uint16 typeSaid_id = 0; - _stringLookupList.clear(); - //stringLookupListType _stringLookupList; // Table of string data, that is inside the currently loaded script - + _offsetLookupArray.clear(); if (getSciVersion() < SCI_VERSION_1_1) { + // SCI0 + SCI1 scriptDataPtr = _buf; scriptDataLeft = _bufSize; - // Go through all SCI_OBJ_STRINGS blocks + // Go through all blocks if (getSciVersion() == SCI_VERSION_0_EARLY) { if (scriptDataLeft < 2) - error("Script::identifyStrings(): unexpected end of script"); + error("Script::identifyOffsets(): unexpected end of script %d", _nr); scriptDataPtr += 2; scriptDataLeft -= 2; } - + uint16 blockType; uint16 blockSize; do { if (scriptDataLeft < 2) - error("Script::identifyStrings(): unexpected end of script"); + error("Script::identifyOffsets(): unexpected end of script %d", _nr); blockType = READ_LE_UINT16(scriptDataPtr); scriptDataPtr += 2; @@ -249,29 +251,49 @@ void Script::identifyStrings() { break; if (scriptDataLeft < 2) - error("Script::identifyStrings(): unexpected end of script"); + error("Script::identifyOffsets(): unexpected end of script %d", _nr); blockSize = READ_LE_UINT16(scriptDataPtr); if (blockSize < 4) - error("Script::identifyStrings(): invalid block size"); + error("Script::identifyOffsets(): invalid block size in script %d", _nr); blockSize -= 4; // block size includes block-type UINT16 and block-size UINT16 scriptDataPtr += 2; scriptDataLeft -= 2; if (scriptDataLeft < blockSize) - error("Script::identifyStrings(): invalid block size"); - - if (blockType == SCI_OBJ_STRINGS) { + error("Script::identifyOffsets(): invalid block size in script %d", _nr); + + switch (blockType) { + case SCI_OBJ_OBJECT: + case SCI_OBJ_CLASS: + typeObject_id++; + arrayEntry.type = SCI_SCR_OFFSET_TYPE_OBJECT; + arrayEntry.id = typeObject_id; + arrayEntry.offset = scriptDataPtr - _buf + 8; // Calculate offset inside script data (VM uses +8) + arrayEntry.stringSize = 0; + _offsetLookupArray.push_back(arrayEntry); + break; + + case SCI_OBJ_STRINGS: // string block detected, we now grab all NUL terminated strings out of this block stringDataPtr = scriptDataPtr; stringDataLeft = blockSize; + arrayEntry.type = SCI_SCR_OFFSET_TYPE_STRING; + do { if (stringDataLeft < 1) // no more bytes left break; stringStartPtr = stringDataPtr; - listEntry.ptrOffset = stringStartPtr - _buf; // Calculate offset inside script data + + if (stringDataLeft == 1) { + // only 1 byte left and that byte is a [00], in that case we also exit + stringDataByte = *stringStartPtr; + if (stringDataByte == 0x00) + break; + } + // now look for terminating [NUL] do { stringDataByte = *stringDataPtr; @@ -279,13 +301,75 @@ void Script::identifyStrings() { stringDataLeft--; if (!stringDataByte) // NUL found, exit this loop break; + if (stringDataLeft < 1) { + // no more bytes left + warning("Script::identifyOffsets(): string without terminating NUL in script %d", _nr); + break; + } + } while (1); + + if (stringDataByte) + break; + + typeString_id++; + arrayEntry.id = typeString_id; + arrayEntry.offset = stringStartPtr - _buf; // Calculate offset inside script data + arrayEntry.stringSize = stringDataPtr - stringStartPtr; + _offsetLookupArray.push_back(arrayEntry); + } while (1); + break; + + case SCI_OBJ_SAID: + // said block detected, we now try to find every single said "string" inside this block + // said strings are terminated with a 0xFF, the string itself may contain words (2 bytes), where + // the second byte of a word may also be a 0xFF. + stringDataPtr = scriptDataPtr; + stringDataLeft = blockSize; + + arrayEntry.type = SCI_SCR_OFFSET_TYPE_SAID; + + do { + if (stringDataLeft < 1) // no more bytes left + break; + + stringStartPtr = stringDataPtr; + if (stringDataLeft == 1) { + // only 1 byte left and that byte is a [00], in that case we also exit + // happens in some scripts, for example Conquests of Camelot, script 997 + // may have been a bug in the compiler or just an intentional filler byte + stringDataByte = *stringStartPtr; + if (stringDataByte == 0x00) + break; + } + + // now look for terminating 0xFF + do { + stringDataByte = *stringDataPtr; + stringDataPtr++; + stringDataLeft--; + if (stringDataByte == 0xFF) // Terminator found, exit this loop + break; if (stringDataLeft < 1) // no more bytes left - error("Script::identifyStrings(): string without terminating NUL"); + error("Script::identifyOffsets(): said-string without terminator in script %d", _nr); + if (stringDataByte < 0xF0) { + // Part of a word, skip second byte + stringDataPtr++; + stringDataLeft--; + if (stringDataLeft < 1) // no more bytes left + error("Script::identifyOffsets(): said-string without terminator in script %d", _nr); + } } while (1); - listEntry.stringSize = stringDataPtr - stringStartPtr; - _stringLookupList.push_back(listEntry); + typeSaid_id++; + arrayEntry.id = typeSaid_id; + arrayEntry.offset = stringStartPtr - _buf; // Calculate offset inside script data + arrayEntry.stringSize = 0; + _offsetLookupArray.push_back(arrayEntry); } while (1); + break; + + default: + break; } scriptDataPtr += blockSize; @@ -293,20 +377,20 @@ void Script::identifyStrings() { } while (1); } else if (getSciVersion() >= SCI_VERSION_1_1 && getSciVersion() <= SCI_VERSION_2_1) { - // Strings in SCI1.1 come after the object instances + // Strings in SCI1.1 up to SCI2 come after the object instances scriptDataPtr = _heapStart; scriptDataLeft = _heapSize; if (scriptDataLeft < 4) - error("Script::identifyStrings(): unexpected end of script"); + error("Script::identifyOffsets(): unexpected end of script in script %d", _nr); uint16 endOfStringOffset = READ_SCI11ENDIAN_UINT16(scriptDataPtr); uint16 objectStartOffset = READ_SCI11ENDIAN_UINT16(scriptDataPtr + 2) * 2 + 4; if (scriptDataLeft < objectStartOffset) - error("Script::identifyStrings(): object start is beyond heap size"); + error("Script::identifyOffsets(): object start is beyond heap size in script %d", _nr); if (scriptDataLeft < endOfStringOffset) - error("Script::identifyStrings(): end of string is beyond heap size"); + error("Script::identifyOffsets(): end of string is beyond heap size in script %d", _nr); byte *endOfStringPtr = scriptDataPtr + endOfStringOffset; @@ -316,10 +400,10 @@ void Script::identifyStrings() { uint16 blockType; uint16 blockSize; - // skip all objects + // go through all objects do { if (scriptDataLeft < 2) - error("Script::identifyStrings(): unexpected end of script"); + error("Script::identifyOffsets(): unexpected end of script %d", _nr); blockType = READ_SCI11ENDIAN_UINT16(scriptDataPtr); scriptDataPtr += 2; @@ -327,15 +411,23 @@ void Script::identifyStrings() { if (blockType != SCRIPT_OBJECT_MAGIC_NUMBER) break; + // Object found, add offset of object + typeObject_id++; + arrayEntry.type = SCI_SCR_OFFSET_TYPE_OBJECT; + arrayEntry.id = typeObject_id; + arrayEntry.offset = scriptDataPtr - _buf - 2; // the VM uses a pointer to the Magic-Number + arrayEntry.stringSize = 0; + _offsetLookupArray.push_back(arrayEntry); + if (scriptDataLeft < 2) - error("Script::identifyStrings(): unexpected end of script"); + error("Script::identifyOffsets(): unexpected end of script in script %d", _nr); blockSize = READ_SCI11ENDIAN_UINT16(scriptDataPtr) * 2; scriptDataPtr += 2; scriptDataLeft -= 2; blockSize -= 4; // blocksize contains UINT16 type and UINT16 size if (scriptDataLeft < blockSize) - error("Script::identifyStrings(): invalid block size"); + error("Script::identifyOffsets(): invalid block size in script %d", _nr); scriptDataPtr += blockSize; scriptDataLeft -= blockSize; @@ -343,17 +435,17 @@ void Script::identifyStrings() { // now scriptDataPtr points to right at the start of the strings if (scriptDataPtr > endOfStringPtr) - error("Script::identifyStrings(): string block / end-of-string block mismatch"); + error("Script::identifyOffsets(): string block / end-of-string block mismatch in script %d", _nr); stringDataPtr = scriptDataPtr; stringDataLeft = endOfStringPtr - scriptDataPtr; // Calculate byte count within string-block + arrayEntry.type = SCI_SCR_OFFSET_TYPE_STRING; do { if (stringDataLeft < 1) // no more bytes left break; stringStartPtr = stringDataPtr; - listEntry.ptrOffset = stringStartPtr - _buf; // Calculate offset inside script data // now look for terminating [NUL] do { stringDataByte = *stringDataPtr; @@ -361,35 +453,112 @@ void Script::identifyStrings() { stringDataLeft--; if (!stringDataByte) // NUL found, exit this loop break; - if (stringDataLeft < 1) // no more bytes left - error("Script::identifyStrings(): string without terminating NUL"); + if (stringDataLeft < 1) { + // no more bytes left + warning("Script::identifyOffsets(): string without terminating NUL in script %d", _nr); + break; + } } while (1); - listEntry.stringSize = stringDataPtr - stringStartPtr; - _stringLookupList.push_back(listEntry); + if (stringDataByte) + break; + + typeString_id++; + arrayEntry.id = typeString_id; + arrayEntry.offset = stringStartPtr - _buf; // Calculate offset inside script data + arrayEntry.stringSize = stringDataPtr - stringStartPtr; + _offsetLookupArray.push_back(arrayEntry); } while (1); } else if (getSciVersion() == SCI_VERSION_3) { - warning("TODO: identifyStrings(): Implement SCI3 variant"); + // SCI3 + uint32 sci3stringOffset = 0; + uint32 sci3relocationOffset = 0; + + if (_bufSize < 22) + error("Script::identifyOffsets(): script %d smaller than expected SCI3-header", _nr); + + sci3stringOffset = READ_LE_UINT32(_buf + 4); + sci3relocationOffset = READ_LE_UINT32(_buf + 8); + + if (sci3relocationOffset > _bufSize) + error("Script::identifyOffsets(): relocation offset is beyond end of script %d", _nr); + + if (sci3stringOffset > 0) { + // string offset set, we expect strings + if (sci3stringOffset > _bufSize) + error("Script::identifyOffsets(): string offset is beyond end of script %d", _nr); + + if (sci3relocationOffset < sci3stringOffset) + error("Script::identifyOffsets(): string offset points beyond relocation offset in script %d", _nr); + + stringDataPtr = _buf + sci3stringOffset; + stringDataLeft = sci3relocationOffset - sci3stringOffset; + + arrayEntry.type = SCI_SCR_OFFSET_TYPE_STRING; + + do { + if (stringDataLeft < 1) // no more bytes left + break; + + stringStartPtr = stringDataPtr; + + if (stringDataLeft == 1) { + // only 1 byte left and that byte is a [00], in that case we also exit + stringDataByte = *stringStartPtr; + if (stringDataByte == 0x00) + break; + } + + // now look for terminating [NUL] + do { + stringDataByte = *stringDataPtr; + stringDataPtr++; + stringDataLeft--; + if (!stringDataByte) // NUL found, exit this loop + break; + if (stringDataLeft < 1) { + // no more bytes left + warning("Script::identifyOffsets(): string without terminating NUL in script %d", _nr); + break; + } + } while (1); + + if (stringDataByte) + break; + + typeString_id++; + arrayEntry.id = typeString_id; + arrayEntry.offset = stringStartPtr - _buf; // Calculate offset inside script data + arrayEntry.stringSize = stringDataPtr - stringStartPtr; + _offsetLookupArray.push_back(arrayEntry); + } while (1); + } + + // Figure out more stuff in SCI3 scripts + warning("TODO: identifyOffsets(): Implement SCI3 variant"); return; } } void Script::debugPrintStrings(Console *con) { - stringLookupListType::iterator it; - const stringLookupListType::iterator end = _stringLookupList.end(); + offsetLookupArrayType::iterator it; + const offsetLookupArrayType::iterator end = _offsetLookupArray.end(); byte *stringPtr; + int stringCount = 0; + + for (it = _offsetLookupArray.begin(); it != end; ++it) { + if (it->type == SCI_SCR_OFFSET_TYPE_STRING) { + stringPtr = _buf + it->offset; + con->debugPrintf(" %03d:%04x: '%s' (size %d)\n", it->id, it->offset, stringPtr, it->stringSize); + debugN(" %03d:%04x: '%s' (size %d)\n", it->id, it->offset, stringPtr, it->stringSize); + stringCount++; + } + } - if (!_stringLookupList.size()) { + if (stringCount == 0) { con->debugPrintf(" no strings\n"); debugN(" no strings\n"); - return; - } - - for (it = _stringLookupList.begin(); it != end; ++it) { - stringPtr = _buf + it->ptrOffset; - con->debugPrintf(" %04x: '%s' (size %d)\n", it->ptrOffset, stringPtr, it->stringSize); - debugN(" %04x: '%s' (size %d)\n", it->ptrOffset, stringPtr, it->stringSize); } } diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h index fe774aeab5..3f24bb191b 100644 --- a/engines/sci/engine/script.h +++ b/engines/sci/engine/script.h @@ -49,12 +49,20 @@ enum ScriptObjectTypes { typedef Common::HashMap<uint16, Object> ObjMap; -struct stringLookupListEntry { - uint16 ptrOffset; // offset of the string +enum ScriptOffsetEntryTypes { + SCI_SCR_OFFSET_TYPE_OBJECT = 0, // classes are handled by this type as well + SCI_SCR_OFFSET_TYPE_STRING, + SCI_SCR_OFFSET_TYPE_SAID +}; + +struct offsetLookupArrayEntry { + uint16 type; // type of entry + uint16 id; // id of this type, first item inside script data is 1, second item is 2, etc. + uint32 offset; // offset of entry within script resource data uint16 stringSize; // size of string, including terminating [NUL] }; -typedef Common::List<stringLookupListEntry> stringLookupListType; +typedef Common::Array<offsetLookupArrayEntry> offsetLookupArrayType; class Script : public SegmentObj { private: @@ -82,7 +90,8 @@ private: ObjMap _objects; /**< Table for objects, contains property variables */ - stringLookupListType _stringLookupList; // Table of string data, that is inside the currently loaded script +protected: + offsetLookupArrayType _offsetLookupArray; // Table of all elements of currently loaded script, that may get pointed to public: int getLocalsOffset() const { return _localsOffset; } @@ -258,6 +267,11 @@ public: int getCodeBlockOffsetSci3() { return READ_SCI11ENDIAN_UINT32(_buf); } /** + * Get the offset array + */ + const offsetLookupArrayType *getOffsetArray() { return &_offsetLookupArray; }; + + /** * Print string lookup table (list) to debug console */ void debugPrintStrings(Console *con); @@ -310,9 +324,9 @@ private: LocalVariables *allocLocalsSegment(SegManager *segMan); /** - * Identifies strings within script data and set up lookup-table + * Identifies certain offsets within script data and set up lookup-table */ - void identifyStrings(); + void identifyOffsets(); }; } // End of namespace Sci |