mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-01 15:09:47 +00:00
Cleaned up script_instantiate_sci0()
svn-id: r49099
This commit is contained in:
parent
9b4f352870
commit
d1f1c71f50
@ -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;
|
||||
curOffset += 4; // skip header
|
||||
|
||||
addr = data_base;
|
||||
|
||||
switch (objtype) {
|
||||
case SCI_OBJ_EXPORTS: {
|
||||
scr->setExportTableOffset(data_base.offset);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCI_OBJ_SYNONYMS:
|
||||
scr->setSynonymsOffset(addr.offset); // +4 is to step over the header
|
||||
scr->setSynonymsNr((objlength) / 4);
|
||||
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(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);
|
||||
|
||||
curOffset += objLength - 4;
|
||||
} while (objType != 0 && curOffset < script->size - 2);
|
||||
|
||||
// And now a second pass to adjust objects and class pointers, and the general pointers
|
||||
|
||||
objlength = 0;
|
||||
reg.offset = magic_pos_adder; // Reset counter
|
||||
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) {
|
||||
|
Loading…
Reference in New Issue
Block a user