From d1f1c71f5007eb26b3945f1508f886d219491f42 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Wed, 19 May 2010 14:43:16 +0000 Subject: Cleaned up script_instantiate_sci0() svn-id: r49099 --- engines/sci/engine/script.cpp | 119 ++++++++++++++++-------------------------- 1 file changed, 46 insertions(+), 73 deletions(-) diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 289140215e..0f88f759ce 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -116,9 +116,6 @@ void script_adjust_opcode_formats(EngineState *s) { #endif } -#define INST_LOOKUP_CLASS(id) ((id == 0xffff)? NULL_REG : segMan->getClassAddress(id, SCRIPT_GET_LOCK, reg)) - - void SegManager::createClassTable() { Resource *vocab996 = _resMan->findResource(ResourceId(kResourceTypeVocab, 996), 1); @@ -329,93 +326,69 @@ 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; - unsigned int objlength; + int objType; + uint32 objLength = 0; int relocation = -1; - int magic_pos_adder; // Usually 0; 2 for older SCI versions 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); + int16 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) { - // - int locals_nr = READ_LE_UINT16(script->data); - // 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. - - scr->mcpyInOut(0, script->data, script->size); - magic_pos_adder = 2; // Step over the funny prefix - + int locals_nr = READ_LE_UINT16(script->data); if (locals_nr) segMan->scriptInitialiseLocalsZero(seg_id, locals_nr); - - } else { - scr->mcpyInOut(0, script->data, script->size); - magic_pos_adder = 0; } // Now do a first pass through the script objects to find the // export table and local variable block - reg_t reg; - reg.segment = seg_id; - reg.offset = magic_pos_adder; - - objlength = 0; - do { - reg_t data_base; - reg_t addr; - reg.offset += objlength; // Step over the last checked object - objtype = scr->getHeap(reg.offset); - if (!objtype) + objType = scr->getHeap(curOffset); + if (!objType) break; - objlength = scr->getHeap(reg.offset + 2); + 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"); + // 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; } - data_base = reg; - data_base.offset += 4; - - addr = data_base; - - switch (objtype) { - case SCI_OBJ_EXPORTS: { - scr->setExportTableOffset(data_base.offset); - } - break; + curOffset += 4; // skip header + switch (objType) { + case SCI_OBJ_EXPORTS: + scr->setExportTableOffset(curOffset); + break; case SCI_OBJ_SYNONYMS: - scr->setSynonymsOffset(addr.offset); // +4 is to step over the header - scr->setSynonymsNr((objlength) / 4); + scr->setSynonymsOffset(curOffset); + scr->setSynonymsNr((objLength) / 4); break; - case SCI_OBJ_LOCALVARS: - segMan->scriptInitialiseLocals(data_base); + segMan->scriptInitialiseLocals(make_reg(seg_id, curOffset)); break; case SCI_OBJ_CLASS: { - int classpos = addr.offset - SCRIPT_OBJECT_MAGIC_OFFSET; - int species; - species = scr->getHeap(addr.offset - SCRIPT_OBJECT_MAGIC_OFFSET + SCRIPT_SPECIES_OFFSET); + 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()) { // Happens in the LSL2 demo @@ -430,7 +403,7 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr } } - segMan->_classtable[species].reg = addr; + segMan->_classtable[species].reg.segment = seg_id; segMan->_classtable[species].reg.offset = classpos; // Set technical class position-- into the block allocated for it } @@ -439,26 +412,25 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr default: break; } - } while (objtype != 0); - // And now a second pass to adjust objects and class pointers, and the general pointers + curOffset += objLength - 4; + } while (objType != 0 && curOffset < script->size - 2); - objlength = 0; - reg.offset = magic_pos_adder; // Reset counter + // And now a second pass to adjust objects and class pointers, and the general pointers + objLength = 0; + curOffset = oldScriptHeader ? 2 : 0; do { - reg_t addr; - reg.offset += objlength; // Step over the last checked object - objtype = scr->getHeap(reg.offset); - if (!objtype) + objType = scr->getHeap(curOffset); + if (!objType) break; - objlength = scr->getHeap(reg.offset + 2); + objLength = scr->getHeap(curOffset + 2); + curOffset += 4; // skip header - addr = reg; - addr.offset += 4; // Step over header + reg_t addr = make_reg(seg_id, curOffset); - switch (objtype) { + switch (objType) { case SCI_OBJ_CODE: scr->scriptAddCodeBlock(addr); break; @@ -492,12 +464,13 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr break; } - } while (objtype != 0 && reg.offset < script->size - 2); + curOffset += objLength - 4; + } while (objType != 0 && curOffset < script->size - 2); if (relocation >= 0) scr->scriptRelocate(make_reg(seg_id, relocation)); - return reg.segment; // instantiation successful + return curOffset; // instantiation successful } int script_instantiate_sci11(ResourceManager *resMan, SegManager *segMan, int script_nr) { @@ -546,23 +519,23 @@ int script_instantiate(ResourceManager *resMan, SegManager *segMan, int script_n void script_uninstantiate_sci0(SegManager *segMan, int script_nr, SegmentId seg) { bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY); reg_t reg = make_reg(seg, oldScriptHeader ? 2 : 0); - int objtype, objlength; + int objType, objLength; Script *scr = segMan->getScript(seg); // Make a pass over the object in order uninstantiate all superclasses - objlength = 0; + objLength = 0; do { - reg.offset += objlength; // Step over the last checked object + reg.offset += objLength; // Step over the last checked object - objtype = scr->getHeap(reg.offset); - if (!objtype) + objType = scr->getHeap(reg.offset); + if (!objType) break; - objlength = scr->getHeap(reg.offset + 2); // use SEG_UGET_HEAP ?? + objLength = scr->getHeap(reg.offset + 2); // use SEG_UGET_HEAP ?? reg.offset += 4; // Step over header - if ((objtype == SCI_OBJ_OBJECT) || (objtype == SCI_OBJ_CLASS)) { // object or class? + if ((objType == SCI_OBJ_OBJECT) || (objType == SCI_OBJ_CLASS)) { // object or class? int superclass; reg.offset -= SCRIPT_OBJECT_MAGIC_OFFSET; @@ -585,7 +558,7 @@ void script_uninstantiate_sci0(SegManager *segMan, int script_nr, SegmentId seg) reg.offset -= 4; // Step back on header - } while (objtype != 0); + } while (objType != 0); } void script_uninstantiate(SegManager *segMan, int script_nr) { -- cgit v1.2.3