From 1c0bbb10cbb20b8dd0bdc1cb748bb5ec9e538b42 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Wed, 26 May 2010 08:27:24 +0000 Subject: More work on controlling access to members of the Object class: - Moved the code for initializing the object class, species and base object inside the Object class - Made propertyOffsetToId() a method of the Object class - Made relocateObject() a method of the Object class - The Object getVariable() method now returns a reference to the requested variable Only SegManager::reconstructScripts() is left needing direct access to the members of the Object class svn-id: r49228 --- engines/sci/engine/script.cpp | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) (limited to 'engines/sci/engine/script.cpp') diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index e9b1ce3f28..aa3fbc995a 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -318,8 +318,6 @@ int script_instantiate_common(ResourceManager *resMan, SegManager *segMan, int s return seg_id; } -#define INST_LOOKUP_CLASS(id) ((id == 0xffff)? NULL_REG : segMan->getClassAddress(id, SCRIPT_GET_LOCK, addr)) - int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int script_nr) { int objType; uint32 objLength = 0; @@ -429,21 +427,10 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr case SCI_OBJ_OBJECT: case SCI_OBJ_CLASS: { // object or class? Object *obj = scr->scriptObjInit(addr); + obj->initSpecies(segMan, addr); - // Instantiate the superclass, if neccessary - obj->setSpeciesSelector(INST_LOOKUP_CLASS(obj->getSpeciesSelector().offset)); - - Object *baseObj = segMan->getObject(obj->getSpeciesSelector()); - - if (baseObj) { - obj->setVarCount(baseObj->getVarCount()); - // Copy base from species class, as we need its selector IDs - obj->_baseObj = baseObj->_baseObj; - - obj->setSuperClassSelector(INST_LOOKUP_CLASS(obj->getSuperClassSelector().offset)); - } else { + if (!obj->initBaseObject(segMan, addr)) { warning("Failed to locate base object for object at %04X:%04X; skipping", PRINT_REG(addr)); - scr->scriptObjRemove(addr); } } // if object or class -- cgit v1.2.3 From db475d1501452490ab4e95ecbd181380b0bec414 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Wed, 26 May 2010 18:11:17 +0000 Subject: SCI: More const related changes; remove unnecessary casts which hide const issues svn-id: r49248 --- engines/sci/engine/script.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'engines/sci/engine/script.cpp') diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index aa3fbc995a..9bbb7738e9 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -193,7 +193,7 @@ void SegManager::scriptInitialiseLocals(reg_t location) { LocalVariables *locals = allocLocalsSegment(scr, count); if (locals) { uint i; - byte *base = (byte *)(scr->_buf + location.offset); + const byte *base = (const byte *)(scr->_buf + location.offset); for (i = 0; i < count; i++) locals->_locals[i] = make_reg(0, READ_SCI11ENDIAN_UINT16(base + i * 2)); @@ -206,10 +206,10 @@ void SegManager::scriptRelocateExportsSci11(SegmentId seg) { /* We are forced to use an ugly heuristic here to distinguish function exports from object/class exports. The former kind points into the script resource, the latter into the heap resource. */ - uint16 location = READ_SCI11ENDIAN_UINT16((byte *)(scr->_exportTable + i)); + uint16 location = READ_SCI11ENDIAN_UINT16(scr->_exportTable + i); if ((location < scr->_heapSize - 1) && (READ_SCI11ENDIAN_UINT16(scr->_heapStart + location) == SCRIPT_OBJECT_MAGIC_NUMBER)) { - WRITE_SCI11ENDIAN_UINT16((byte *)(scr->_exportTable + i), location + scr->_heapStart - scr->_buf); + WRITE_SCI11ENDIAN_UINT16(scr->_exportTable + i, location + scr->_heapStart - scr->_buf); } else { // Otherwise it's probably a function export, // and we don't need to do anything. @@ -219,7 +219,7 @@ void SegManager::scriptRelocateExportsSci11(SegmentId seg) { void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) { Script *scr = getScript(seg); - byte *seeker = scr->_heapStart + 4 + READ_SCI11ENDIAN_UINT16(scr->_heapStart + 2) * 2; + const byte *seeker = scr->_heapStart + 4 + READ_SCI11ENDIAN_UINT16(scr->_heapStart + 2) * 2; while (READ_SCI11ENDIAN_UINT16(seeker) == SCRIPT_OBJECT_MAGIC_NUMBER) { if (READ_SCI11ENDIAN_UINT16(seeker + 14) & SCRIPT_INFO_CLASS) { -- cgit v1.2.3 From 453d13dc2d2bec3a4d7cc4395bf98bd2103c5ff8 Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Thu, 27 May 2010 17:41:20 +0000 Subject: SCI: fixing -propDict- selector on instances to contain -propDict- of the corresponding class - fixes sq4cd/room 381 talk-clicking on robot - thx to waltervn & wjp svn-id: r49263 --- engines/sci/engine/script.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'engines/sci/engine/script.cpp') diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 9bbb7738e9..e0bcd632cc 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -256,6 +256,16 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) { obj->setSuperClassSelector( getClassAddress(obj->getSuperClassSelector().offset, SCRIPT_GET_LOCK, NULL_REG)); + // If object is instance, get -propDict- from class and set it for this object + // This is needed for ::isMemberOf() to work. + // Example testcase - room 381 of sq4cd - if isMemberOf() doesn't work, talk-clicks on the robot will act like + // clicking on ego + if (!obj->isClass()) { + reg_t classObject = obj->getSuperClassSelector(); + Object *classObj = getObject(classObject); + obj->setPropDictSelector(classObj->getPropDictSelector()); + } + // Set the -classScript- selector to the script number. // FIXME: As this selector is filled in at run-time, it is likely // that it is supposed to hold a pointer. The Obj::isKindOf method -- cgit v1.2.3 From a6156a680583bfd3876bcd1c6d5e550763d0a677 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Sat, 29 May 2010 15:29:27 +0000 Subject: Removed the scriptRelocateExportsSci11() hack. The open spell in QFG1VGA works now (thanks to waltervn for all his help on this) svn-id: r49311 --- engines/sci/engine/script.cpp | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'engines/sci/engine/script.cpp') diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index e0bcd632cc..d1cbfbf551 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -200,23 +200,6 @@ void SegManager::scriptInitialiseLocals(reg_t location) { } } -void SegManager::scriptRelocateExportsSci11(SegmentId seg) { - Script *scr = getScript(seg); - for (int i = 0; i < scr->_numExports; i++) { - /* We are forced to use an ugly heuristic here to distinguish function - exports from object/class exports. The former kind points into the - script resource, the latter into the heap resource. */ - uint16 location = READ_SCI11ENDIAN_UINT16(scr->_exportTable + i); - - if ((location < scr->_heapSize - 1) && (READ_SCI11ENDIAN_UINT16(scr->_heapStart + location) == SCRIPT_OBJECT_MAGIC_NUMBER)) { - WRITE_SCI11ENDIAN_UINT16(scr->_exportTable + i, location + scr->_heapStart - scr->_buf); - } else { - // Otherwise it's probably a function export, - // and we don't need to do anything. - } - } -} - void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) { Script *scr = getScript(seg); const byte *seeker = scr->_heapStart + 4 + READ_SCI11ENDIAN_UINT16(scr->_heapStart + 2) * 2; @@ -484,7 +467,6 @@ int script_instantiate_sci11(ResourceManager *resMan, SegManager *segMan, int sc segMan->scriptInitialiseLocals(make_reg(seg_id, _heapStart + 4)); - segMan->scriptRelocateExportsSci11(seg_id); segMan->scriptInitialiseObjectsSci11(seg_id); scr->heapRelocate(make_reg(seg_id, READ_SCI11ENDIAN_UINT16(heap->data))); -- cgit v1.2.3 From 5f2ff0b1e7147a5638e66bbd1362196b5419c330 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Sat, 29 May 2010 23:56:37 +0000 Subject: Limit access to the _classTable array (now it's directly accessible only inside saveLoadWithSerializer() svn-id: r49318 --- engines/sci/engine/script.cpp | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) (limited to 'engines/sci/engine/script.cpp') diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index d1cbfbf551..051cb0d215 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -123,13 +123,13 @@ void SegManager::createClassTable() { error("SegManager: failed to open vocab 996"); int totalClasses = vocab996->size >> 2; - _classtable.resize(totalClasses); + _classTable.resize(totalClasses); for (uint16 classNr = 0; classNr < totalClasses; classNr++) { uint16 scriptNr = READ_SCI11ENDIAN_UINT16(vocab996->data + classNr * 4 + 2); - _classtable[classNr].reg = NULL_REG; - _classtable[classNr].script = scriptNr; + _classTable[classNr].reg = NULL_REG; + _classTable[classNr].script = scriptNr; } _resMan->unlockResource(vocab996); @@ -139,11 +139,11 @@ reg_t SegManager::getClassAddress(int classnr, ScriptLoadType lock, reg_t caller if (classnr == 0xffff) return NULL_REG; - if (classnr < 0 || (int)_classtable.size() <= classnr || _classtable[classnr].script < 0) { - error("[VM] Attempt to dereference class %x, which doesn't exist (max %x)", classnr, _classtable.size()); + if (classnr < 0 || (int)_classTable.size() <= classnr || _classTable[classnr].script < 0) { + error("[VM] Attempt to dereference class %x, which doesn't exist (max %x)", classnr, _classTable.size()); return NULL_REG; } else { - Class *the_class = &_classtable[classnr]; + Class *the_class = &_classTable[classnr]; if (!the_class->reg.segment) { getScriptSegment(the_class->script, lock); @@ -209,14 +209,14 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) { int classpos = seeker - scr->_buf; int species = READ_SCI11ENDIAN_UINT16(seeker + 10); - if (species < 0 || species >= (int)_classtable.size()) { + if (species < 0 || species >= (int)_classTable.size()) { error("Invalid species %d(0x%x) not in interval [0,%d) while instantiating script %d", - species, species, _classtable.size(), scr->_nr); + species, species, _classTable.size(), scr->_nr); return; } - _classtable[species].reg.segment = seg; - _classtable[species].reg.offset = classpos; + _classTable[species].reg.segment = seg; + _classTable[species].reg.offset = classpos; } seeker += READ_SCI11ENDIAN_UINT16(seeker + 2) * 2; } @@ -372,22 +372,21 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr case SCI_OBJ_CLASS: { int classpos = curOffset - SCRIPT_OBJECT_MAGIC_OFFSET; int species = scr->getHeap(curOffset - SCRIPT_OBJECT_MAGIC_OFFSET + SCRIPT_SPECIES_OFFSET); - if (species < 0 || species >= (int)segMan->_classtable.size()) { - if (species == (int)segMan->_classtable.size()) { + if (species < 0 || species >= (int)segMan->classTableSize()) { + if (species == (int)segMan->classTableSize()) { // Happens in the LSL2 demo warning("Applying workaround for an off-by-one invalid species access"); - segMan->_classtable.resize(segMan->_classtable.size() + 1); + segMan->resizeClassTable(segMan->classTableSize() + 1); } else { warning("Invalid species %d(0x%x) not in interval " "[0,%d) while instantiating script %d\n", - species, species, segMan->_classtable.size(), + species, species, segMan->classTableSize(), script_nr); return 0; } } - segMan->_classtable[species].reg.segment = seg_id; - segMan->_classtable[species].reg.offset = classpos; + segMan->setClassOffset(species, make_reg(seg_id, classpos)); // Set technical class position-- into the block allocated for it } break; @@ -507,7 +506,7 @@ void script_uninstantiate_sci0(SegManager *segMan, int script_nr, SegmentId seg) superclass = scr->getHeap(reg.offset + SCRIPT_SUPERCLASS_OFFSET); // Get superclass... if (superclass >= 0) { - int superclass_script = segMan->_classtable[superclass].script; + int superclass_script = segMan->getClass(superclass).script; if (superclass_script == script_nr) { if (scr->getLockers()) @@ -541,9 +540,9 @@ void script_uninstantiate(SegManager *segMan, int script_nr) { return; // Free all classtable references to this script - for (uint i = 0; i < segMan->_classtable.size(); i++) - if (segMan->_classtable[i].reg.segment == segment) - segMan->_classtable[i].reg = NULL_REG; + for (uint i = 0; i < segMan->classTableSize(); i++) + if (segMan->getClass(i).reg.segment == segment) + segMan->setClassOffset(i, NULL_REG); if (getSciVersion() < SCI_VERSION_1_1) script_uninstantiate_sci0(segMan, script_nr, segment); -- cgit v1.2.3 From c32e88fe0bb61e75ca983072ba28102d4efbf123 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Sun, 30 May 2010 16:14:31 +0000 Subject: Limit access to the _bufSize, _scriptSize and _heapSize members of the Script class svn-id: r49327 --- engines/sci/engine/script.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'engines/sci/engine/script.cpp') diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 051cb0d215..ab0ab69083 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -175,7 +175,7 @@ void SegManager::scriptInitialiseLocals(reg_t location) { Script *scr = getScript(location.segment); unsigned int count; - VERIFY(location.offset + 1 < (uint16)scr->_bufSize, "Locals beyond end of script\n"); + VERIFY(location.offset + 1 < (uint16)scr->getBufSize(), "Locals beyond end of script\n"); if (getSciVersion() >= SCI_VERSION_1_1) count = READ_SCI11ENDIAN_UINT16(scr->_buf + location.offset - 2); @@ -185,9 +185,9 @@ void SegManager::scriptInitialiseLocals(reg_t location) { scr->_localsOffset = location.offset; - if (!(location.offset + count * 2 + 1 < scr->_bufSize)) { - warning("Locals extend beyond end of script: offset %04x, count %x vs size %x", location.offset, count, (uint)scr->_bufSize); - count = (scr->_bufSize - location.offset) >> 1; + if (!(location.offset + count * 2 + 1 < scr->getBufSize())) { + warning("Locals extend beyond end of script: offset %04x, count %x vs size %x", location.offset, count, (uint)scr->getBufSize()); + count = (scr->getBufSize() - location.offset) >> 1; } LocalVariables *locals = allocLocalsSegment(scr, count); -- cgit v1.2.3 From 29c2f30558e9c40d5c1a76ab600611b21ee72851 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Sun, 30 May 2010 17:02:21 +0000 Subject: Unified the script loading code, and marked an issue with the SCI11 heap addresses svn-id: r49329 --- engines/sci/engine/script.cpp | 60 ++++++++++++++----------------------------- 1 file changed, 19 insertions(+), 41 deletions(-) (limited to 'engines/sci/engine/script.cpp') diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index ab0ab69083..d52cdd693b 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -263,24 +263,9 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) { -int script_instantiate_common(ResourceManager *resMan, SegManager *segMan, int script_nr, Resource **script, Resource **heap, int *was_new) { +int script_instantiate_common(ResourceManager *resMan, SegManager *segMan, int script_nr, int *was_new) { *was_new = 1; - *script = resMan->findResource(ResourceId(kResourceTypeScript, script_nr), 0); - if (getSciVersion() >= SCI_VERSION_1_1) - *heap = resMan->findResource(ResourceId(kResourceTypeHeap, script_nr), 0); - - if (!*script || (getSciVersion() >= SCI_VERSION_1_1 && !heap)) { - warning("Script 0x%x requested but not found", script_nr); - if (getSciVersion() >= SCI_VERSION_1_1) { - if (*heap) - warning("Inconsistency: heap resource WAS found"); - else if (*script) - warning("Inconsistency: script resource WAS found"); - } - return 0; - } - SegmentId seg_id = segMan->getScriptSegment(script_nr); Script *scr = segMan->getScriptIfLoaded(seg_id); if (scr) { @@ -292,13 +277,10 @@ int script_instantiate_common(ResourceManager *resMan, SegManager *segMan, int s } } else { scr = segMan->allocateScript(script_nr, &seg_id); - if (!scr) { // ALL YOUR SCRIPT BASE ARE BELONG TO US - error("Not enough heap space for script size 0x%x of script 0x%x (Should this happen?)", (*script)->size, script_nr); - return 0; - } } scr->init(script_nr, resMan); + scr->load(resMan); // Set heap position (beyond the size word) scr->setLockers(1); @@ -315,26 +297,24 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr int objType; uint32 objLength = 0; int relocation = -1; - Resource *script; int was_new; bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY); - const int seg_id = script_instantiate_common(resMan, segMan, script_nr, &script, NULL, &was_new); + const int seg_id = script_instantiate_common(resMan, segMan, script_nr, &was_new); uint16 curOffset = oldScriptHeader ? 2 : 0; if (was_new) return seg_id; Script *scr = segMan->getScript(seg_id); - scr->mcpyInOut(0, script->data, script->size); if (oldScriptHeader) { // Old script block // There won't be a localvar block in this case // Instead, the script starts with a 16 bit int specifying the // number of locals we need; these are then allocated and zeroed. - int locals_nr = READ_LE_UINT16(script->data); - if (locals_nr) - segMan->scriptInitialiseLocalsZero(seg_id, locals_nr); + int localsCount = READ_LE_UINT16(scr->_buf); + if (localsCount) + segMan->scriptInitialiseLocalsZero(seg_id, localsCount); } // Now do a first pass through the script objects to find the @@ -396,7 +376,7 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr } curOffset += objLength - 4; - } while (objType != 0 && curOffset < script->size - 2); + } while (objType != 0 && curOffset < scr->getScriptSize() - 2); // And now a second pass to adjust objects and class pointers, and the general pointers objLength = 0; @@ -436,7 +416,7 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr } curOffset += objLength - 4; - } while (objType != 0 && curOffset < script->size - 2); + } while (objType != 0 && curOffset < scr->getScriptSize() - 2); if (relocation >= 0) scr->scriptRelocate(make_reg(seg_id, relocation)); @@ -445,30 +425,28 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr } int script_instantiate_sci11(ResourceManager *resMan, SegManager *segMan, int script_nr) { - Resource *script, *heap; int was_new; - const int seg_id = script_instantiate_common(resMan, segMan, script_nr, &script, &heap, &was_new); + const int seg_id = script_instantiate_common(resMan, segMan, script_nr, &was_new); if (was_new) return seg_id; Script *scr = segMan->getScript(seg_id); - int _heapStart = script->size; - - if (script->size & 2) - _heapStart++; - - scr->mcpyInOut(0, script->data, script->size); - scr->mcpyInOut(_heapStart, heap->data, heap->size); - if (READ_SCI11ENDIAN_UINT16(script->data + 6) > 0) + if (READ_SCI11ENDIAN_UINT16(scr->_buf + 6) > 0) scr->setExportTableOffset(6); - segMan->scriptInitialiseLocals(make_reg(seg_id, _heapStart + 4)); + int heapStart = scr->getScriptSize(); - segMan->scriptInitialiseObjectsSci11(seg_id); + // FIXME: This code was used to ensure that the heap address is word-aligned + // Make sure that this is used in all places where the heap is referenced, + // not just here... + //if (heapStart & 2) + // heapStart++; - scr->heapRelocate(make_reg(seg_id, READ_SCI11ENDIAN_UINT16(heap->data))); + segMan->scriptInitialiseLocals(make_reg(seg_id, heapStart + 4)); + segMan->scriptInitialiseObjectsSci11(seg_id); + scr->heapRelocate(make_reg(seg_id, READ_SCI11ENDIAN_UINT16(scr->_heapStart))); return seg_id; } -- cgit v1.2.3 From 016862ac3a4928529d9eaedf6edf3e916c89155c Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Sun, 30 May 2010 18:45:07 +0000 Subject: Moved setScriptSize() inside Script::init(), and removed a FIXME - the SCI1.1 word-align is done inside Script::init() svn-id: r49330 --- engines/sci/engine/script.cpp | 7 ------- 1 file changed, 7 deletions(-) (limited to 'engines/sci/engine/script.cpp') diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index d52cdd693b..99a567d1e7 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -437,13 +437,6 @@ int script_instantiate_sci11(ResourceManager *resMan, SegManager *segMan, int sc scr->setExportTableOffset(6); int heapStart = scr->getScriptSize(); - - // FIXME: This code was used to ensure that the heap address is word-aligned - // Make sure that this is used in all places where the heap is referenced, - // not just here... - //if (heapStart & 2) - // heapStart++; - segMan->scriptInitialiseLocals(make_reg(seg_id, heapStart + 4)); segMan->scriptInitialiseObjectsSci11(seg_id); scr->heapRelocate(make_reg(seg_id, READ_SCI11ENDIAN_UINT16(scr->_heapStart))); -- cgit v1.2.3 From dc4d61f7181edf332d426bab9d16e0055e3d0f21 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Sun, 30 May 2010 20:06:50 +0000 Subject: - Merged the SCI0 scriptRelocate() and SCI11 heapRelocate() functions inside relocate(). scriptRelocate checked one more relocation entry, which seems wrong, so we're now checking for the correct number of relocations in all SCI versions - Re-added the error when script + heap exceed 64KB (better than an assert) - this should theoretically never happen, and it never has for the games tested - Removed the relocated sanity check - again, it shouldn't occur (else something else is wrong) svn-id: r49332 --- engines/sci/engine/script.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'engines/sci/engine/script.cpp') diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 99a567d1e7..aa975cc1d0 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -419,7 +419,7 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr } while (objType != 0 && curOffset < scr->getScriptSize() - 2); if (relocation >= 0) - scr->scriptRelocate(make_reg(seg_id, relocation)); + scr->relocate(make_reg(seg_id, relocation)); return seg_id; // instantiation successful } @@ -439,7 +439,7 @@ int script_instantiate_sci11(ResourceManager *resMan, SegManager *segMan, int sc int heapStart = scr->getScriptSize(); segMan->scriptInitialiseLocals(make_reg(seg_id, heapStart + 4)); segMan->scriptInitialiseObjectsSci11(seg_id); - scr->heapRelocate(make_reg(seg_id, READ_SCI11ENDIAN_UINT16(scr->_heapStart))); + scr->relocate(make_reg(seg_id, READ_SCI11ENDIAN_UINT16(scr->_heapStart))); return seg_id; } -- cgit v1.2.3 From 3b96e4833e0035ce5d54efbdd1badeaca858f5ae Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Sun, 30 May 2010 20:30:07 +0000 Subject: Cleanup svn-id: r49334 --- engines/sci/engine/script.cpp | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'engines/sci/engine/script.cpp') diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index aa975cc1d0..fda7d05aa0 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -205,7 +205,7 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) { const byte *seeker = scr->_heapStart + 4 + READ_SCI11ENDIAN_UINT16(scr->_heapStart + 2) * 2; while (READ_SCI11ENDIAN_UINT16(seeker) == SCRIPT_OBJECT_MAGIC_NUMBER) { - if (READ_SCI11ENDIAN_UINT16(seeker + 14) & SCRIPT_INFO_CLASS) { + if (READ_SCI11ENDIAN_UINT16(seeker + 14) & SCRIPT_INFO_CLASS) { // -info- selector int classpos = seeker - scr->_buf; int species = READ_SCI11ENDIAN_UINT16(seeker + 10); @@ -226,15 +226,6 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) { reg_t reg = make_reg(seg, seeker - scr->_buf); Object *obj = scr->scriptObjInit(reg); -#if 0 - if (obj->_variables[5].offset != 0xffff) { - obj->_variables[5] = INST_LOOKUP_CLASS(obj->_variables[5].offset); - baseObj = getObject(obj->_variables[5]); - obj->variable_names_nr = baseObj->variables_nr; - obj->_baseObj = baseObj->_baseObj; - } -#endif - // Copy base from species class, as we need its selector IDs obj->setSuperClassSelector( getClassAddress(obj->getSuperClassSelector().offset, SCRIPT_GET_LOCK, NULL_REG)); -- cgit v1.2.3 From a0ee93ece52213cd989a50902281d917fe392ea4 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Sun, 30 May 2010 21:49:07 +0000 Subject: SCI: Script exports and synonyms are now initialized when a script is loaded. Removed a sanity check inside script_instantiate_sci0 for a bug which no longer exists svn-id: r49336 --- engines/sci/engine/script.cpp | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) (limited to 'engines/sci/engine/script.cpp') diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index fda7d05aa0..793f78e030 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -275,9 +275,7 @@ int script_instantiate_common(ResourceManager *resMan, SegManager *segMan, int s // Set heap position (beyond the size word) scr->setLockers(1); - scr->setExportTableOffset(0); - scr->setSynonymsOffset(0); - scr->setSynonymsNr(0); + *was_new = 0; @@ -309,7 +307,7 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr } // Now do a first pass through the script objects to find the - // export table and local variable block + // local variable blocks do { objType = scr->getHeap(curOffset); @@ -317,29 +315,12 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr break; objLength = scr->getHeap(curOffset + 2); - - // This happens in some demos (e.g. the EcoQuest 1 demo). Not sure what is the - // actual cause of it, but the scripts of these demos can't be loaded properly - // and we're stuck forever in this loop, as objLength never changes - if (!objLength) { - warning("script_instantiate_sci0: objLength is 0, unable to parse script"); - return 0; - } - curOffset += 4; // skip header switch (objType) { - case SCI_OBJ_EXPORTS: - scr->setExportTableOffset(curOffset); - break; - case SCI_OBJ_SYNONYMS: - scr->setSynonymsOffset(curOffset); - scr->setSynonymsNr((objLength) / 4); - break; case SCI_OBJ_LOCALVARS: segMan->scriptInitialiseLocals(make_reg(seg_id, curOffset)); break; - case SCI_OBJ_CLASS: { int classpos = curOffset - SCRIPT_OBJECT_MAGIC_OFFSET; int species = scr->getHeap(curOffset - SCRIPT_OBJECT_MAGIC_OFFSET + SCRIPT_SPECIES_OFFSET); @@ -424,9 +405,6 @@ int script_instantiate_sci11(ResourceManager *resMan, SegManager *segMan, int sc Script *scr = segMan->getScript(seg_id); - if (READ_SCI11ENDIAN_UINT16(scr->_buf + 6) > 0) - scr->setExportTableOffset(6); - int heapStart = scr->getScriptSize(); segMan->scriptInitialiseLocals(make_reg(seg_id, heapStart + 4)); segMan->scriptInitialiseObjectsSci11(seg_id); -- cgit v1.2.3 From 4e25867a671a8847b167decba1ed1e95cf699e66 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Sun, 30 May 2010 23:00:32 +0000 Subject: SCI: Merge setLockers(1) call into Script::init svn-id: r49337 --- engines/sci/engine/script.cpp | 4 ---- 1 file changed, 4 deletions(-) (limited to 'engines/sci/engine/script.cpp') diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 793f78e030..07fc75596e 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -273,10 +273,6 @@ int script_instantiate_common(ResourceManager *resMan, SegManager *segMan, int s scr->init(script_nr, resMan); scr->load(resMan); - // Set heap position (beyond the size word) - scr->setLockers(1); - - *was_new = 0; return seg_id; -- cgit v1.2.3 From 66d4bddb30498419cebf0478a83b77ca3abb8131 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Mon, 31 May 2010 08:11:49 +0000 Subject: Merged several script instantiation-related functions inside script_instantiate() svn-id: r49343 --- engines/sci/engine/script.cpp | 95 +++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 62 deletions(-) (limited to 'engines/sci/engine/script.cpp') diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 07fc75596e..304fd4d6fd 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -252,46 +252,13 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) { } } - - -int script_instantiate_common(ResourceManager *resMan, SegManager *segMan, int script_nr, int *was_new) { - *was_new = 1; - - SegmentId seg_id = segMan->getScriptSegment(script_nr); - Script *scr = segMan->getScriptIfLoaded(seg_id); - if (scr) { - if (!scr->isMarkedAsDeleted()) { - scr->incrementLockers(); - return seg_id; - } else { - scr->freeScript(); - } - } else { - scr = segMan->allocateScript(script_nr, &seg_id); - } - - scr->init(script_nr, resMan); - scr->load(resMan); - - *was_new = 0; - - return seg_id; -} - -int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int script_nr) { +int script_instantiate_sci0(Script *scr, int segmentId, SegManager *segMan) { int objType; uint32 objLength = 0; int relocation = -1; - int was_new; bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY); - const int seg_id = script_instantiate_common(resMan, segMan, script_nr, &was_new); uint16 curOffset = oldScriptHeader ? 2 : 0; - if (was_new) - return seg_id; - - Script *scr = segMan->getScript(seg_id); - if (oldScriptHeader) { // Old script block // There won't be a localvar block in this case @@ -299,7 +266,7 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr // number of locals we need; these are then allocated and zeroed. int localsCount = READ_LE_UINT16(scr->_buf); if (localsCount) - segMan->scriptInitialiseLocalsZero(seg_id, localsCount); + segMan->scriptInitialiseLocalsZero(segmentId, localsCount); } // Now do a first pass through the script objects to find the @@ -315,7 +282,7 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr switch (objType) { case SCI_OBJ_LOCALVARS: - segMan->scriptInitialiseLocals(make_reg(seg_id, curOffset)); + segMan->scriptInitialiseLocals(make_reg(segmentId, curOffset)); break; case SCI_OBJ_CLASS: { int classpos = curOffset - SCRIPT_OBJECT_MAGIC_OFFSET; @@ -327,14 +294,14 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr segMan->resizeClassTable(segMan->classTableSize() + 1); } else { warning("Invalid species %d(0x%x) not in interval " - "[0,%d) while instantiating script %d\n", + "[0,%d) while instantiating script at segment %d\n", species, species, segMan->classTableSize(), - script_nr); + segmentId); return 0; } } - segMan->setClassOffset(species, make_reg(seg_id, classpos)); + segMan->setClassOffset(species, make_reg(segmentId, classpos)); // Set technical class position-- into the block allocated for it } break; @@ -358,7 +325,7 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr objLength = scr->getHeap(curOffset + 2); curOffset += 4; // skip header - reg_t addr = make_reg(seg_id, curOffset); + reg_t addr = make_reg(segmentId, curOffset); switch (objType) { case SCI_OBJ_CODE: @@ -387,33 +354,37 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr } while (objType != 0 && curOffset < scr->getScriptSize() - 2); if (relocation >= 0) - scr->relocate(make_reg(seg_id, relocation)); + scr->relocate(make_reg(segmentId, relocation)); - return seg_id; // instantiation successful + return segmentId; // instantiation successful } -int script_instantiate_sci11(ResourceManager *resMan, SegManager *segMan, int script_nr) { - int was_new; - const int seg_id = script_instantiate_common(resMan, segMan, script_nr, &was_new); - - if (was_new) - return seg_id; - - Script *scr = segMan->getScript(seg_id); - - int heapStart = scr->getScriptSize(); - segMan->scriptInitialiseLocals(make_reg(seg_id, heapStart + 4)); - segMan->scriptInitialiseObjectsSci11(seg_id); - scr->relocate(make_reg(seg_id, READ_SCI11ENDIAN_UINT16(scr->_heapStart))); +int script_instantiate(ResourceManager *resMan, SegManager *segMan, int scriptNum) { + SegmentId segmentId = segMan->getScriptSegment(scriptNum); + Script *scr = segMan->getScriptIfLoaded(segmentId); + if (scr) { + if (!scr->isMarkedAsDeleted()) { + scr->incrementLockers(); + return segmentId; + } else { + scr->freeScript(); + } + } else { + scr = segMan->allocateScript(scriptNum, &segmentId); + } - return seg_id; -} + scr->init(scriptNum, resMan); + scr->load(resMan); -int script_instantiate(ResourceManager *resMan, SegManager *segMan, int script_nr) { - if (getSciVersion() >= SCI_VERSION_1_1) - return script_instantiate_sci11(resMan, segMan, script_nr); - else - return script_instantiate_sci0(resMan, segMan, script_nr); + if (getSciVersion() >= SCI_VERSION_1_1) { + int heapStart = scr->getScriptSize(); + segMan->scriptInitialiseLocals(make_reg(segmentId, heapStart + 4)); + segMan->scriptInitialiseObjectsSci11(segmentId); + scr->relocate(make_reg(segmentId, READ_SCI11ENDIAN_UINT16(scr->_heapStart))); + return segmentId; + } else { + return script_instantiate_sci0(scr, segmentId, segMan); + } } void script_uninstantiate_sci0(SegManager *segMan, int script_nr, SegmentId seg) { -- cgit v1.2.3 From 844ef9ba1a08de70058cfa8014f55a801b7c77aa Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Mon, 31 May 2010 18:35:13 +0000 Subject: Merged all the script relocation code inside script_instantiate(), and changed the warning when reading an invalid species into an error (as it's severe, and if it happens it means something is seriously wrong) svn-id: r49361 --- engines/sci/engine/script.cpp | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) (limited to 'engines/sci/engine/script.cpp') diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 304fd4d6fd..3fb8a5763e 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -252,10 +252,9 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) { } } -int script_instantiate_sci0(Script *scr, int segmentId, SegManager *segMan) { +void script_instantiate_sci0(Script *scr, int segmentId, SegManager *segMan) { int objType; uint32 objLength = 0; - int relocation = -1; bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY); uint16 curOffset = oldScriptHeader ? 2 : 0; @@ -293,11 +292,11 @@ int script_instantiate_sci0(Script *scr, int segmentId, SegManager *segMan) { warning("Applying workaround for an off-by-one invalid species access"); segMan->resizeClassTable(segMan->classTableSize() + 1); } else { - warning("Invalid species %d(0x%x) not in interval " + error("Invalid species %d(0x%x) not in interval " "[0,%d) while instantiating script at segment %d\n", species, species, segMan->classTableSize(), segmentId); - return 0; + return; } } @@ -342,21 +341,12 @@ int script_instantiate_sci0(Script *scr, int segmentId, SegManager *segMan) { } } // if object or class break; - case SCI_OBJ_POINTERS: // A relocation table - relocation = addr.offset; - break; - default: break; } curOffset += objLength - 4; } while (objType != 0 && curOffset < scr->getScriptSize() - 2); - - if (relocation >= 0) - scr->relocate(make_reg(segmentId, relocation)); - - return segmentId; // instantiation successful } int script_instantiate(ResourceManager *resMan, SegManager *segMan, int scriptNum) { @@ -381,10 +371,14 @@ int script_instantiate(ResourceManager *resMan, SegManager *segMan, int scriptNu segMan->scriptInitialiseLocals(make_reg(segmentId, heapStart + 4)); segMan->scriptInitialiseObjectsSci11(segmentId); scr->relocate(make_reg(segmentId, READ_SCI11ENDIAN_UINT16(scr->_heapStart))); - return segmentId; } else { - return script_instantiate_sci0(scr, segmentId, segMan); + script_instantiate_sci0(scr, segmentId, segMan); + byte *relocationBlock = scr->findBlock(SCI_OBJ_POINTERS); + if (relocationBlock) + scr->relocate(make_reg(segmentId, relocationBlock - scr->_buf + 4)); } + + return segmentId; } void script_uninstantiate_sci0(SegManager *segMan, int script_nr, SegmentId seg) { -- cgit v1.2.3 From 86b452d36cb781c24e1b167dd6cef768b7c6286b Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Thu, 3 Jun 2010 10:16:21 +0000 Subject: Moved several object-related defines inside vm.h into segment.h, where the Object class resides. Also, removed several unused defines svn-id: r49406 --- engines/sci/engine/script.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/sci/engine/script.cpp') diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 3fb8a5763e..1f32e50b67 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -205,7 +205,7 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) { const byte *seeker = scr->_heapStart + 4 + READ_SCI11ENDIAN_UINT16(scr->_heapStart + 2) * 2; while (READ_SCI11ENDIAN_UINT16(seeker) == SCRIPT_OBJECT_MAGIC_NUMBER) { - if (READ_SCI11ENDIAN_UINT16(seeker + 14) & SCRIPT_INFO_CLASS) { // -info- selector + if (READ_SCI11ENDIAN_UINT16(seeker + 14) & kInfoFlagClass) { // -info- selector int classpos = seeker - scr->_buf; int species = READ_SCI11ENDIAN_UINT16(seeker + 10); -- cgit v1.2.3