aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
authorFilippos Karapetis2010-05-19 14:43:16 +0000
committerFilippos Karapetis2010-05-19 14:43:16 +0000
commitd1f1c71f5007eb26b3945f1508f886d219491f42 (patch)
treefe09a48f8597a16dee8482d253f1dee9400735c9 /engines/sci
parent9b4f35287027d6c9dafca8f6157fe60c620ee9c4 (diff)
downloadscummvm-rg350-d1f1c71f5007eb26b3945f1508f886d219491f42.tar.gz
scummvm-rg350-d1f1c71f5007eb26b3945f1508f886d219491f42.tar.bz2
scummvm-rg350-d1f1c71f5007eb26b3945f1508f886d219491f42.zip
Cleaned up script_instantiate_sci0()
svn-id: r49099
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/engine/script.cpp119
1 files 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) {