From 5184f86e150fefba5dc673b846b38049090d8348 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Tue, 22 Sep 2009 14:33:46 +0000 Subject: - Merged scriptObjInit0() and scriptObjInit11() - Replaced some cases where getSciVersion() is used with _resMan->sciVersion(), as getSciVersion() will fail with the fallback detector (as the engine is not initialized). Object property accessors still crash currently, when used with the fallback detector svn-id: r44261 --- engines/sci/engine/seg_manager.cpp | 121 ++++++++++++------------------------- engines/sci/engine/seg_manager.h | 2 - engines/sci/engine/segment.cpp | 2 +- engines/sci/engine/segment.h | 5 +- engines/sci/engine/vm.cpp | 2 +- 5 files changed, 42 insertions(+), 90 deletions(-) (limited to 'engines/sci') diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index dbc6c64917..41fecec74a 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -130,18 +130,18 @@ Script *SegManager::allocateScript(int script_nr, SegmentId *seg_id) { void Script::setScriptSize(int script_nr, ResourceManager *resMan) { Resource *script = resMan->findResource(ResourceId(kResourceTypeScript, script_nr), 0); Resource *heap = resMan->findResource(ResourceId(kResourceTypeHeap, script_nr), 0); - bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY); + bool oldScriptHeader = (resMan->sciVersion() == SCI_VERSION_0_EARLY); _scriptSize = script->size; _heapSize = 0; // Set later - if (!script || (getSciVersion() >= SCI_VERSION_1_1 && !heap)) { + if (!script || (resMan->sciVersion() >= SCI_VERSION_1_1 && !heap)) { error("SegManager::setScriptSize: failed to load %s", !script ? "script" : "heap"); } if (oldScriptHeader) { _bufSize = script->size + READ_LE_UINT16(script->data) * 2; //locals_size = READ_LE_UINT16(script->data) * 2; - } else if (getSciVersion() < SCI_VERSION_1_1) { + } else if (resMan->sciVersion() < SCI_VERSION_1_1) { _bufSize = script->size; } else { _bufSize = script->size + heap->size; @@ -458,104 +458,61 @@ reg_t SegManager::getClassAddress(int classnr, ScriptLoadType lock, reg_t caller } } -Object *Script::scriptObjInit0(reg_t obj_pos) { +Object *Script::scriptObjInit(reg_t obj_pos, SciVersion version) { Object *obj; - obj_pos.offset -= SCRIPT_OBJECT_MAGIC_OFFSET; + if (version < SCI_VERSION_1_1) + obj_pos.offset += 8; // magic offset (SCRIPT_OBJECT_MAGIC_OFFSET) + VERIFY(obj_pos.offset < _bufSize, "Attempt to initialize object beyond end of script\n"); obj = allocateObject(obj_pos.offset); VERIFY(obj_pos.offset + SCRIPT_FUNCTAREAPTR_OFFSET < (int)_bufSize, "Function area pointer stored beyond end of script\n"); - { - byte *data = (byte *)(_buf + obj_pos.offset); - uint16 *funct_area = (uint16 *)(data + READ_LE_UINT16(data + SCRIPT_FUNCTAREAPTR_OFFSET)); - int variables_nr; - int functions_nr; - int is_class; - - obj->_flags = 0; - obj->_pos = obj_pos; + byte *data = (byte *)(_buf + obj_pos.offset); + uint16 *funct_area = 0; + bool isClass; - VERIFY((byte *)funct_area < _buf + _bufSize, "Function area pointer references beyond end of script"); + if (version < SCI_VERSION_1_1) { + obj->variable_names_nr = READ_LE_UINT16(data + SCRIPT_SELECTORCTR_OFFSET); + obj->base_vars = 0; + funct_area = (uint16 *)(data + READ_LE_UINT16(data + SCRIPT_FUNCTAREAPTR_OFFSET)); + obj->methods_nr = READ_LE_UINT16(funct_area - 1); + isClass = READ_LE_UINT16(data + 4) & SCRIPT_INFO_CLASS; // SCRIPT_INFO_OFFSET + } else { + obj->variable_names_nr = READ_LE_UINT16(data + 2); + obj->base_vars = (uint16 *)(_buf + READ_LE_UINT16(data + 4)); + funct_area = (uint16 *)(_buf + READ_LE_UINT16(data + 6)); + obj->methods_nr = READ_LE_UINT16(funct_area); + isClass = READ_LE_UINT16(data + 14) & SCRIPT_INFO_CLASS; + } - variables_nr = READ_LE_UINT16(data + SCRIPT_SELECTORCTR_OFFSET); - functions_nr = READ_LE_UINT16(funct_area - 1); - is_class = READ_LE_UINT16(data + SCRIPT_INFO_OFFSET) & SCRIPT_INFO_CLASS; + obj->_flags = 0; + obj->_pos = obj_pos; + obj->base_method = funct_area; - obj->base_method = funct_area; - obj->base_vars = NULL; + VERIFY((byte *)funct_area < _buf + _bufSize, "Function area pointer references beyond end of script"); - VERIFY((byte *)funct_area + functions_nr * 2 + if (version < SCI_VERSION_1_1) { + VERIFY((byte *)funct_area + obj->methods_nr * 2 // add again for classes, since those also store selectors - + (is_class ? functions_nr * 2 : 0) < _buf + _bufSize, "Function area extends beyond end of script"); - - obj->_variables.resize(variables_nr); - - obj->methods_nr = functions_nr; - obj->base = _buf; - obj->base_obj = data; - - for (int i = 0; i < variables_nr; i++) - obj->_variables[i] = make_reg(0, READ_LE_UINT16(data + (i * 2))); + + (isClass ? obj->methods_nr * 2 : 0) < _buf + _bufSize, "Function area extends beyond end of script"); + } else { + VERIFY(((byte *)funct_area + obj->variable_names_nr) < _buf + _bufSize, "Function area extends beyond end of script"); } - return obj; -} - -Object *Script::scriptObjInit11(reg_t obj_pos) { - Object *obj; - - VERIFY(obj_pos.offset < _bufSize, "Attempt to initialize object beyond end of script\n"); - - obj = allocateObject(obj_pos.offset); - - VERIFY(obj_pos.offset + SCRIPT_FUNCTAREAPTR_OFFSET < (int)_bufSize, "Function area pointer stored beyond end of script\n"); - - { - byte *data = (byte *)(_buf + obj_pos.offset); - uint16 *funct_area = (uint16 *)(_buf + READ_LE_UINT16(data + 6)); - uint16 *prop_area = (uint16 *)(_buf + READ_LE_UINT16(data + 4)); - int variables_nr; - int functions_nr; - int is_class; - - obj->_flags = 0; - obj->_pos = obj_pos; - - VERIFY((byte *)funct_area < _buf + _bufSize, "Function area pointer references beyond end of script"); - - variables_nr = READ_LE_UINT16(data + 2); - functions_nr = READ_LE_UINT16(funct_area); - is_class = READ_LE_UINT16(data + 14) & SCRIPT_INFO_CLASS; - - obj->base_method = funct_area; - obj->base_vars = prop_area; + obj->_variables.resize(obj->variable_names_nr); - VERIFY(((byte *)funct_area + functions_nr) < _buf + _bufSize, "Function area extends beyond end of script"); + obj->base = _buf; + obj->base_obj = data; - obj->variable_names_nr = variables_nr; - obj->_variables.resize(variables_nr); - - obj->methods_nr = functions_nr; - obj->base = _buf; - obj->base_obj = data; - - for (int i = 0; i < variables_nr; i++) - obj->_variables[i] = make_reg(0, READ_LE_UINT16(data + (i * 2))); - } + for (int i = 0; i < obj->variable_names_nr; i++) + obj->_variables[i] = make_reg(0, READ_LE_UINT16(data + (i * 2))); return obj; } -Object *Script::scriptObjInit(reg_t obj_pos) { - if (getSciVersion() < SCI_VERSION_1_1) - return scriptObjInit0(obj_pos); - else - return scriptObjInit11(obj_pos); -} - LocalVariables *SegManager::allocLocalsSegment(Script *scr, int count) { if (!count) { // No locals scr->_localsSegment = 0; @@ -594,7 +551,7 @@ void SegManager::scriptInitialiseLocals(reg_t location) { VERIFY(location.offset + 1 < (uint16)scr->_bufSize, "Locals beyond end of script\n"); - if (getSciVersion() >= SCI_VERSION_1_1) + if (_resMan->sciVersion() >= 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; @@ -661,7 +618,7 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) { reg.segment = seg; reg.offset = seeker - scr->_buf; - obj = scr->scriptObjInit(reg); + obj = scr->scriptObjInit(reg, _resMan->sciVersion()); #if 0 if (obj->_variables[5].offset != 0xffff) { diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h index 61b0c76e2e..7388fc5ec9 100644 --- a/engines/sci/engine/seg_manager.h +++ b/engines/sci/engine/seg_manager.h @@ -380,8 +380,6 @@ private: Hunk *alloc_Hunk(reg_t *); SegmentId findFreeSegment() const; - Object *scriptObjInit0(reg_t obj_pos); - Object *scriptObjInit11(reg_t obj_pos); /** * Check segment validity diff --git a/engines/sci/engine/segment.cpp b/engines/sci/engine/segment.cpp index 5410d82c24..6980ce1570 100644 --- a/engines/sci/engine/segment.cpp +++ b/engines/sci/engine/segment.cpp @@ -137,7 +137,7 @@ bool Script::init(int script_nr, ResourceManager *resMan) { _nr = script_nr; - if (getSciVersion() >= SCI_VERSION_1_1) + if (resMan->sciVersion() >= SCI_VERSION_1_1) _heapStart = _buf + _scriptSize; else _heapStart = _buf; diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h index f7d42894ad..f2f794a2ba 100644 --- a/engines/sci/engine/segment.h +++ b/engines/sci/engine/segment.h @@ -351,7 +351,7 @@ public: * @returns A newly created Object describing the object, * stored within the relevant script */ - Object *scriptObjInit(reg_t obj_pos); + Object *scriptObjInit(reg_t obj_pos, SciVersion version); /** * Processes a relocation block witin a script @@ -369,9 +369,6 @@ private: int relocateBlock(Common::Array &block, int block_location, SegmentId segment, int location); int relocateObject(Object &obj, SegmentId segment, int location); - Object *scriptObjInit0(reg_t obj_pos); - Object *scriptObjInit11(reg_t obj_pos); - public: // script lock operations diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 89e95781b0..1ae71eeb7e 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -1590,7 +1590,7 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr break; case SCI_OBJ_OBJECT: case SCI_OBJ_CLASS: { // object or class? - Object *obj = scr->scriptObjInit(addr); + Object *obj = scr->scriptObjInit(addr, resMan->sciVersion()); Object *base_obj; // Instantiate the superclass, if neccessary -- cgit v1.2.3