- Simplified some functions to accept only the parts of the EngineState they need as parameters, instead of the whole EngineState
- Moved the class table in the Segment manager - it's the only class using it directly - Removed the sci11 flag from save games (we already know this, we don't need to store it) - Moved script_get_segment() and get_class_address() inside the segment manager class - Removed the script_locate_by_segment wrapper - Simplified script_lookup_export() a lot by removing some paranoia checks - Added some WIP code for automatically determining the game id in the fallback detector (still not working) - General cleanup svn-id: r43458
This commit is contained in:
parent
0d4fc81698
commit
c38f58598b
14 changed files with 293 additions and 298 deletions
|
@ -52,7 +52,7 @@ namespace Sci {
|
|||
|
||||
#define INVALID_SCRIPT_ID -1
|
||||
|
||||
SegManager::SegManager(bool sci1_1) {
|
||||
SegManager::SegManager(ResourceManager *resMgr, SciVersion version) {
|
||||
id_seg_map = new IntMapper();
|
||||
reserved_id = INVALID_SCRIPT_ID;
|
||||
id_seg_map->checkKey(reserved_id, true); // reserve entry 0 for INVALID_SCRIPT_ID
|
||||
|
@ -66,7 +66,8 @@ SegManager::SegManager(bool sci1_1) {
|
|||
Hunks_seg_id = 0;
|
||||
|
||||
exports_wide = 0;
|
||||
isSci1_1 = sci1_1;
|
||||
_version = version;
|
||||
_resMgr = resMgr;
|
||||
}
|
||||
|
||||
// Destroy the object, free the memorys if allocated before
|
||||
|
@ -109,7 +110,7 @@ MemObject *SegManager::allocNonscriptSegment(MemObjectType type, SegmentId *segi
|
|||
// Returns : 0 - allocation failure
|
||||
// 1 - allocated successfully
|
||||
// seg_id - allocated segment id
|
||||
Script *SegManager::allocateScript(EngineState *s, int script_nr, SegmentId *seg_id) {
|
||||
Script *SegManager::allocateScript(int script_nr, SegmentId *seg_id) {
|
||||
bool was_added;
|
||||
MemObject *mem;
|
||||
|
||||
|
@ -128,20 +129,20 @@ Script *SegManager::allocateScript(EngineState *s, int script_nr, SegmentId *seg
|
|||
return (Script *)mem;
|
||||
}
|
||||
|
||||
void SegManager::setScriptSize(Script &scr, EngineState *s, int script_nr) {
|
||||
Resource *script = s->resmgr->findResource(ResourceId(kResourceTypeScript, script_nr), 0);
|
||||
Resource *heap = s->resmgr->findResource(ResourceId(kResourceTypeHeap, script_nr), 0);
|
||||
void SegManager::setScriptSize(Script &scr, int script_nr) {
|
||||
Resource *script = _resMgr->findResource(ResourceId(kResourceTypeScript, script_nr), 0);
|
||||
Resource *heap = _resMgr->findResource(ResourceId(kResourceTypeHeap, script_nr), 0);
|
||||
|
||||
scr.script_size = script->size;
|
||||
scr.heap_size = 0; // Set later
|
||||
|
||||
if (!script || (s->_version >= SCI_VERSION_1_1 && !heap)) {
|
||||
if (!script || (_version >= SCI_VERSION_1_1 && !heap)) {
|
||||
error("SegManager::setScriptSize: failed to load %s", !script ? "script" : "heap");
|
||||
}
|
||||
if (((SciEngine*)g_engine)->getKernel()->hasOldScriptHeader()) {
|
||||
scr.buf_size = script->size + READ_LE_UINT16(script->data) * 2;
|
||||
//locals_size = READ_LE_UINT16(script->data) * 2;
|
||||
} else if (s->_version < SCI_VERSION_1_1) {
|
||||
} else if (_version < SCI_VERSION_1_1) {
|
||||
scr.buf_size = script->size;
|
||||
} else {
|
||||
scr.buf_size = script->size + heap->size;
|
||||
|
@ -163,10 +164,10 @@ void SegManager::setScriptSize(Script &scr, EngineState *s, int script_nr) {
|
|||
}
|
||||
}
|
||||
|
||||
int SegManager::initialiseScript(Script &scr, EngineState *s, int script_nr) {
|
||||
int SegManager::initialiseScript(Script &scr, int script_nr) {
|
||||
// allocate the script.buf
|
||||
|
||||
setScriptSize(scr, s, script_nr);
|
||||
setScriptSize(scr, script_nr);
|
||||
scr.buf = (byte *)malloc(scr.buf_size);
|
||||
|
||||
#ifdef DEBUG_SEG_MANAGER
|
||||
|
@ -191,7 +192,7 @@ int SegManager::initialiseScript(Script &scr, EngineState *s, int script_nr) {
|
|||
|
||||
scr.obj_indices = new IntMapper();
|
||||
|
||||
if (s->_version >= SCI_VERSION_1_1)
|
||||
if (_version >= SCI_VERSION_1_1)
|
||||
scr.heap_start = scr.buf + scr.script_size;
|
||||
else
|
||||
scr.heap_start = scr.buf;
|
||||
|
@ -319,7 +320,7 @@ int SegManager::relocateBlock(Common::Array<reg_t> &block, int block_location, S
|
|||
return 0;
|
||||
}
|
||||
block[idx].segment = segment; // Perform relocation
|
||||
if (isSci1_1)
|
||||
if (_version == SCI_VERSION_1_1)
|
||||
block[idx].offset += getScript(segment)->script_size;
|
||||
|
||||
return 1;
|
||||
|
@ -429,13 +430,51 @@ void SegManager::heapRelocate(reg_t block) {
|
|||
}
|
||||
}
|
||||
|
||||
#define INST_LOOKUP_CLASS(id) ((id == 0xffff) ? NULL_REG : get_class_address(s, id, SCRIPT_GET_LOCK, NULL_REG))
|
||||
SegmentId SegManager::getSegment(int script_nr, SCRIPT_GET load) {
|
||||
SegmentId segment;
|
||||
|
||||
reg_t get_class_address(EngineState *s, int classnr, SCRIPT_GET lock, reg_t caller);
|
||||
if ((load & SCRIPT_GET_LOAD) == SCRIPT_GET_LOAD)
|
||||
script_instantiate(_resMgr, this, _version, script_nr);
|
||||
|
||||
Object *SegManager::scriptObjInit0(EngineState *s, reg_t obj_pos) {
|
||||
segment = segGet(script_nr);
|
||||
|
||||
if (segment > 0) {
|
||||
if ((load & SCRIPT_GET_LOCK) == SCRIPT_GET_LOCK)
|
||||
getScript(segment)->incrementLockers();
|
||||
|
||||
return segment;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define INST_LOOKUP_CLASS(id) ((id == 0xffff) ? NULL_REG : get_class_address(id, SCRIPT_GET_LOCK, NULL_REG))
|
||||
|
||||
reg_t SegManager::get_class_address(int classnr, SCRIPT_GET lock, reg_t caller) {
|
||||
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];
|
||||
if (!the_class->reg.segment) {
|
||||
getSegment(the_class->script, lock);
|
||||
|
||||
if (!the_class->reg.segment) {
|
||||
error("[VM] Trying to instantiate class %x by instantiating script 0x%x (%03d) failed;"
|
||||
" Entering debugger.", classnr, the_class->script, the_class->script);
|
||||
return NULL_REG;
|
||||
}
|
||||
} else
|
||||
if (caller.segment != the_class->reg.segment)
|
||||
getScript(the_class->reg.segment)->incrementLockers();
|
||||
|
||||
return the_class->reg;
|
||||
}
|
||||
}
|
||||
|
||||
Object *SegManager::scriptObjInit0(reg_t obj_pos) {
|
||||
Object *obj;
|
||||
int id;
|
||||
SciVersion version = _version; // for the offset defines
|
||||
unsigned int base = obj_pos.offset - SCRIPT_OBJECT_MAGIC_OFFSET;
|
||||
reg_t temp;
|
||||
|
||||
|
@ -489,7 +528,7 @@ Object *SegManager::scriptObjInit0(EngineState *s, reg_t obj_pos) {
|
|||
return obj;
|
||||
}
|
||||
|
||||
Object *SegManager::scriptObjInit11(EngineState *s, reg_t obj_pos) {
|
||||
Object *SegManager::scriptObjInit11(reg_t obj_pos) {
|
||||
Object *obj;
|
||||
int id;
|
||||
int base = obj_pos.offset;
|
||||
|
@ -543,11 +582,11 @@ Object *SegManager::scriptObjInit11(EngineState *s, reg_t obj_pos) {
|
|||
return obj;
|
||||
}
|
||||
|
||||
Object *SegManager::scriptObjInit(EngineState *s, reg_t obj_pos) {
|
||||
if (!isSci1_1)
|
||||
return scriptObjInit0(s, obj_pos);
|
||||
Object *SegManager::scriptObjInit(reg_t obj_pos) {
|
||||
if (_version != SCI_VERSION_1_1)
|
||||
return scriptObjInit0(obj_pos);
|
||||
else
|
||||
return scriptObjInit11(s, obj_pos);
|
||||
return scriptObjInit11(obj_pos);
|
||||
}
|
||||
|
||||
LocalVariables *SegManager::allocLocalsSegment(Script *scr, int count) {
|
||||
|
@ -588,7 +627,7 @@ void SegManager::scriptInitialiseLocals(reg_t location) {
|
|||
|
||||
VERIFY(location.offset + 1 < (uint16)scr->buf_size, "Locals beyond end of script\n");
|
||||
|
||||
if (isSci1_1)
|
||||
if (_version == SCI_VERSION_1_1)
|
||||
count = READ_LE_UINT16(scr->buf + location.offset - 2);
|
||||
else
|
||||
count = (READ_LE_UINT16(scr->buf + location.offset - 2) - 4) >> 1;
|
||||
|
@ -627,24 +666,25 @@ void SegManager::scriptRelocateExportsSci11(SegmentId seg) {
|
|||
}
|
||||
}
|
||||
|
||||
void SegManager::scriptInitialiseObjectsSci11(EngineState *s, SegmentId seg) {
|
||||
void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) {
|
||||
Script *scr = getScript(seg);
|
||||
byte *seeker = scr->heap_start + 4 + READ_LE_UINT16(scr->heap_start + 2) * 2;
|
||||
SciVersion version = _version; // for the selector defines
|
||||
|
||||
while (READ_LE_UINT16(seeker) == SCRIPT_OBJECT_MAGIC_NUMBER) {
|
||||
if (READ_LE_UINT16(seeker + 14) & SCRIPT_INFO_CLASS) {
|
||||
int classpos = seeker - scr->buf;
|
||||
int species = READ_LE_UINT16(seeker + 10);
|
||||
|
||||
if (species < 0 || species >= (int)s->_classtable.size()) {
|
||||
if (species < 0 || species >= (int)_classtable.size()) {
|
||||
error("Invalid species %d(0x%x) not in interval [0,%d) while instantiating script %d\n",
|
||||
species, species, s->_classtable.size(), scr->nr);
|
||||
species, species, _classtable.size(), scr->nr);
|
||||
return;
|
||||
}
|
||||
|
||||
s->_classtable[species].script = scr->nr;
|
||||
s->_classtable[species].reg.segment = seg;
|
||||
s->_classtable[species].reg.offset = classpos;
|
||||
_classtable[species].script = scr->nr;
|
||||
_classtable[species].reg.segment = seg;
|
||||
_classtable[species].reg.offset = classpos;
|
||||
}
|
||||
seeker += READ_LE_UINT16(seeker + 2) * 2;
|
||||
}
|
||||
|
@ -656,12 +696,12 @@ void SegManager::scriptInitialiseObjectsSci11(EngineState *s, SegmentId seg) {
|
|||
|
||||
reg.segment = seg;
|
||||
reg.offset = seeker - scr->buf;
|
||||
obj = scriptObjInit(s, reg);
|
||||
obj = scriptObjInit(reg);
|
||||
|
||||
#if 0
|
||||
if (obj->_variables[5].offset != 0xffff) {
|
||||
obj->_variables[5] = INST_LOOKUP_CLASS(obj->_variables[5].offset);
|
||||
base_obj = obj_get(s, obj->_variables[5]);
|
||||
base_obj = obj_get(s->seg_manager, s->_version, obj->_variables[5]);
|
||||
obj->variable_names_nr = base_obj->variables_nr;
|
||||
obj->base_obj = base_obj->base_obj;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue