aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/sci/engine/kscripts.cpp8
-rw-r--r--engines/sci/engine/memobj.cpp26
-rw-r--r--engines/sci/engine/memobj.h44
-rw-r--r--engines/sci/engine/seg_manager.cpp81
-rw-r--r--engines/sci/engine/seg_manager.h33
-rw-r--r--engines/sci/engine/vm.cpp10
6 files changed, 105 insertions, 97 deletions
diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp
index f3689a6025..5aabd86732 100644
--- a/engines/sci/engine/kscripts.cpp
+++ b/engines/sci/engine/kscripts.cpp
@@ -318,9 +318,13 @@ reg_t kDisposeScript(EngineState *s, int, int argc, reg_t *argv) {
}
}
-int is_heap_object(EngineState *s, reg_t pos) {
+bool is_heap_object(EngineState *s, reg_t pos) {
Object *obj = s->segMan->getObject(pos);
- return (obj != NULL && (!(obj->flags & OBJECT_FLAG_FREED)) && (!s->segMan->scriptIsMarkedAsDeleted(pos.segment)));
+ if (obj == NULL)
+ return false;
+ if (obj->flags & OBJECT_FLAG_FREED)
+ return false;
+ return !s->segMan->scriptIsMarkedAsDeleted(pos.segment);
}
reg_t kIsObject(EngineState *s, int, int argc, reg_t *argv) {
diff --git a/engines/sci/engine/memobj.cpp b/engines/sci/engine/memobj.cpp
index 9ed5eb8758..4697e0a706 100644
--- a/engines/sci/engine/memobj.cpp
+++ b/engines/sci/engine/memobj.cpp
@@ -114,7 +114,21 @@ void Script::freeScript() {
_codeBlocks.clear();
}
-void Script::init() {
+bool Script::init(int script_nr, ResourceManager *resMan) {
+ setScriptSize(script_nr, resMan);
+
+ _buf = (byte *)malloc(_bufSize);
+
+#ifdef DEBUG_segMan
+ printf("_buf = %p ", _buf);
+#endif
+ if (!_buf) {
+ freeScript();
+ warning("Not enough memory space for script size");
+ _bufSize = 0;
+ return false;
+ }
+
_localsOffset = 0;
_localsBlock = NULL;
@@ -124,6 +138,16 @@ void Script::init() {
_markedAsDeleted = false;
_objIndices = new IntMapper();
+
+ _nr = script_nr;
+
+ _sciVersion = resMan->sciVersion();
+ if (_sciVersion >= SCI_VERSION_1_1)
+ _heapStart = _buf + _scriptSize;
+ else
+ _heapStart = _buf;
+
+ return true;
}
Object *Script::allocateObject(uint16 offset) {
diff --git a/engines/sci/engine/memobj.h b/engines/sci/engine/memobj.h
index 500d268bc5..0294fb01c9 100644
--- a/engines/sci/engine/memobj.h
+++ b/engines/sci/engine/memobj.h
@@ -258,6 +258,8 @@ protected:
IntMapper *_objIndices;
+ SciVersion _sciVersion;
+
public:
/**
* Table for objects, contains property variables.
@@ -279,7 +281,7 @@ public:
~Script();
void freeScript();
- void init();
+ bool init(int script_nr, ResourceManager *resMan);
virtual bool isValidOffset(uint16 offset) const;
virtual byte *dereference(reg_t pointer, int *size);
@@ -293,6 +295,43 @@ public:
Object *allocateObject(uint16 offset);
Object *getObject(uint16 offset);
+ /**
+ * Informs the segment manager that a code block must be relocated
+ * @param location Start of block to relocate
+ */
+ void scriptAddCodeBlock(reg_t location);
+
+ /**
+ * Initializes an object within the segment manager
+ * @param obj_pos Location (segment, offset) of the object. It must
+ * point to the beginning of the script/class block
+ * (as opposed to what the VM considers to be the
+ * object location)
+ * @returns A newly created Object describing the object,
+ * stored within the relevant script
+ */
+ Object *scriptObjInit(reg_t obj_pos);
+
+ /**
+ * Processes a relocation block witin a script
+ * This function is idempotent, but it must only be called after all
+ * objects have been instantiated, or a run-time error will occur.
+ * @param obj_pos Location (segment, offset) of the block
+ * @return Location of the relocation block
+ */
+ void scriptRelocate(reg_t block);
+
+ void heapRelocate(reg_t block);
+
+private:
+ int relocateLocal(SegmentId segment, int location);
+ int relocateBlock(Common::Array<reg_t> &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
/** Increments the number of lockers of this script by one. */
@@ -382,6 +421,9 @@ public:
* @return the value read from the specified location
*/
int16 getHeap(uint16 offset) const;
+
+private:
+ void setScriptSize(int script_nr, ResourceManager *resMan);
};
/** Data stack */
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index 5e6d15a1d4..e2c56852fa 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -133,7 +133,8 @@ Script *SegManager::allocateScript(int script_nr, SegmentId *seg_id) {
return (Script *)mem;
}
-void SegManager::setScriptSize(Script &scr, int script_nr) {
+void Script::setScriptSize(int script_nr, ResourceManager *_resMan) {
+ Script &scr = *this; // FIXME: Hack
Resource *script = _resMan->findResource(ResourceId(kResourceTypeScript, script_nr), 0);
Resource *heap = _resMan->findResource(ResourceId(kResourceTypeHeap, script_nr), 0);
bool oldScriptHeader = (_resMan->sciVersion() == SCI_VERSION_0_EARLY);
@@ -169,34 +170,6 @@ void SegManager::setScriptSize(Script &scr, int script_nr) {
}
}
-int SegManager::initialiseScript(Script &scr, int script_nr) {
- // allocate the script._buf
-
- setScriptSize(scr, script_nr);
- scr._buf = (byte *)malloc(scr._bufSize);
-
-#ifdef DEBUG_segMan
- printf("scr._buf = %p ", scr._buf);
-#endif
- if (!scr._buf) {
- scr.freeScript();
- warning("SegManager: Not enough memory space for script size");
- scr._bufSize = 0;
- return 0;
- }
-
- // Initialize objects
- scr.init();
- scr._nr = script_nr;
-
- if (_resMan->sciVersion() >= SCI_VERSION_1_1)
- scr._heapStart = scr._buf + scr._scriptSize;
- else
- scr._heapStart = scr._buf;
-
- return 1;
-}
-
int SegManager::deallocate(SegmentId seg, bool recursive) {
MemObject *mobj;
VERIFY(check(seg), "invalid seg id");
@@ -332,7 +305,7 @@ void SegManager::setExportAreWide(bool flag) {
_exportsAreWide = flag;
}
-int SegManager::relocateBlock(Common::Array<reg_t> &block, int block_location, SegmentId segment, int location) {
+int Script::relocateBlock(Common::Array<reg_t> &block, int block_location, SegmentId segment, int location) {
int rel = location - block_location;
if (rel < 0)
@@ -348,34 +321,32 @@ int SegManager::relocateBlock(Common::Array<reg_t> &block, int block_location, S
return 0;
}
block[idx].segment = segment; // Perform relocation
- if (_resMan->sciVersion() >= SCI_VERSION_1_1)
- block[idx].offset += getScript(segment)->_scriptSize;
+ if (_sciVersion >= SCI_VERSION_1_1)
+ block[idx].offset += _scriptSize;
return 1;
}
-int SegManager::relocateLocal(Script *scr, SegmentId segment, int location) {
- if (scr->_localsBlock)
- return relocateBlock(scr->_localsBlock->_locals, scr->_localsOffset, segment, location);
+int Script::relocateLocal(SegmentId segment, int location) {
+ if (_localsBlock)
+ return relocateBlock(_localsBlock->_locals, _localsOffset, segment, location);
else
return 0; // No hands, no cookies
}
-int SegManager::relocateObject(Object *obj, SegmentId segment, int location) {
+int Script::relocateObject(Object *obj, SegmentId segment, int location) {
return relocateBlock(obj->_variables, obj->pos.offset, segment, location);
}
-void SegManager::scriptAddCodeBlock(reg_t location) {
- Script *scr = getScript(location.segment);
-
+void Script::scriptAddCodeBlock(reg_t location) {
CodeBlock cb;
cb.pos = location;
- cb.size = READ_LE_UINT16(scr->_buf + location.offset - 2);
- scr->_codeBlocks.push_back(cb);
+ cb.size = READ_LE_UINT16(_buf + location.offset - 2);
+ _codeBlocks.push_back(cb);
}
-void SegManager::scriptRelocate(reg_t block) {
- Script *scr = getScript(block.segment);
+void Script::scriptRelocate(reg_t block) {
+ Script *scr = this; // FIXME: Hack
VERIFY(block.offset < (uint16)scr->_bufSize && READ_LE_UINT16(scr->_buf + block.offset) * 2 + block.offset < (uint16)scr->_bufSize,
"Relocation block outside of script\n");
@@ -387,7 +358,7 @@ void SegManager::scriptRelocate(reg_t block) {
if (!pos)
continue; // FIXME: A hack pending investigation
- if (!relocateLocal(scr, block.segment, pos)) {
+ if (!relocateLocal(block.segment, pos)) {
bool done = false;
uint k;
@@ -418,8 +389,8 @@ void SegManager::scriptRelocate(reg_t block) {
}
}
-void SegManager::heapRelocate(reg_t block) {
- Script *scr = getScript(block.segment);
+void Script::heapRelocate(reg_t block) {
+ Script *scr = this; // FIXME: Hack
VERIFY(block.offset < (uint16)scr->_heapSize && READ_LE_UINT16(scr->_heapStart + block.offset) * 2 + block.offset < (uint16)scr->_bufSize,
"Relocation block outside of script\n");
@@ -432,7 +403,7 @@ void SegManager::heapRelocate(reg_t block) {
for (int i = 0; i < count; i++) {
int pos = READ_LE_UINT16(scr->_heapStart + block.offset + 2 + (i * 2)) + scr->_scriptSize;
- if (!relocateLocal(scr, block.segment, pos)) {
+ if (!relocateLocal(block.segment, pos)) {
bool done = false;
uint k;
@@ -504,12 +475,12 @@ reg_t SegManager::getClassAddress(int classnr, ScriptLoadType lock, reg_t caller
}
}
-Object *SegManager::scriptObjInit0(reg_t obj_pos) {
+Object *Script::scriptObjInit0(reg_t obj_pos) {
Object *obj;
- SciVersion version = _resMan->sciVersion(); // for the offset defines
+ SciVersion version = _sciVersion; // for the offset defines
uint base = obj_pos.offset - SCRIPT_OBJECT_MAGIC_OFFSET;
- Script *scr = getScript(obj_pos.segment);
+ Script *scr = this; // FIXME: Hack
VERIFY(base < scr->_bufSize, "Attempt to initialize object beyond end of script\n");
@@ -553,11 +524,11 @@ Object *SegManager::scriptObjInit0(reg_t obj_pos) {
return obj;
}
-Object *SegManager::scriptObjInit11(reg_t obj_pos) {
+Object *Script::scriptObjInit11(reg_t obj_pos) {
Object *obj;
uint base = obj_pos.offset;
- Script *scr = getScript(obj_pos.segment);
+ Script *scr = this; // FIXME: Hack
VERIFY(base < scr->_bufSize, "Attempt to initialize object beyond end of script\n");
@@ -602,8 +573,8 @@ Object *SegManager::scriptObjInit11(reg_t obj_pos) {
return obj;
}
-Object *SegManager::scriptObjInit(reg_t obj_pos) {
- if (_resMan->sciVersion() < SCI_VERSION_1_1)
+Object *Script::scriptObjInit(reg_t obj_pos) {
+ if (_sciVersion < SCI_VERSION_1_1)
return scriptObjInit0(obj_pos);
else
return scriptObjInit11(obj_pos);
@@ -715,7 +686,7 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) {
reg.segment = seg;
reg.offset = seeker - scr->_buf;
- obj = scriptObjInit(reg);
+ obj = scr->scriptObjInit(reg);
#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 9b274890d5..a4a7851fac 100644
--- a/engines/sci/engine/seg_manager.h
+++ b/engines/sci/engine/seg_manager.h
@@ -156,38 +156,12 @@ public:
void scriptInitialiseLocals(reg_t location);
/**
- * Initializes an object within the segment manager
- * @param obj_pos Location (segment, offset) of the object. It must
- * point to the beginning of the script/class block
- * (as opposed to what the VM considers to be the
- * object location)
- * @returns A newly created Object describing the object,
- * stored within the relevant script
- */
- Object *scriptObjInit(reg_t obj_pos);
-
- /**
- * Informs the segment manager that a code block must be relocated
- * @param location Start of block to relocate
- */
- void scriptAddCodeBlock(reg_t location);
-
- /**
* Tells the segment manager whether exports are wide (32-bit) or not.
* @param flag true if exports are wide, false otherwise
*/
void setExportAreWide(bool flag);
/**
- * Processes a relocation block witin a script
- * This function is idempotent, but it must only be called after all
- * objects have been instantiated, or a run-time error will occur.
- * @param obj_pos Location (segment, offset) of the block
- * @return Location of the relocation block
- */
- void scriptRelocate(reg_t block);
-
- /**
* Determines whether the script referenced by the indicated segment
* is marked as being deleted.
* Will return 0 when applied to an invalid or non-script seg.
@@ -387,10 +361,8 @@ public:
*/
const char *getObjectName(reg_t pos);
- void heapRelocate(reg_t block);
void scriptRelocateExportsSci11(SegmentId seg);
void scriptInitialiseObjectsSci11(SegmentId seg);
- int initialiseScript(Script &scr, int script_nr);
SciVersion sciVersion() { return _resMan->sciVersion(); }
@@ -417,12 +389,7 @@ private:
Hunk *alloc_Hunk(reg_t *);
- int relocateLocal(Script *scr, SegmentId segment, int location);
- int relocateBlock(Common::Array<reg_t> &block, int block_location, SegmentId segment, int location);
- int relocateObject(Object *obj, SegmentId segment, int location);
-
SegmentId findFreeSegment() const;
- void setScriptSize(Script &scr, int script_nr);
Object *scriptObjInit0(reg_t obj_pos);
Object *scriptObjInit11(reg_t obj_pos);
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index 69366758ea..dc22666188 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -1546,7 +1546,7 @@ int script_instantiate_common(ResourceManager *resMan, SegManager *segMan, int s
}
}
- segMan->initialiseScript(*scr, script_nr);
+ scr->init(script_nr, resMan);
reg.segment = seg_id;
reg.offset = 0;
@@ -1688,11 +1688,11 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr
switch (objtype) {
case SCI_OBJ_CODE:
- segMan->scriptAddCodeBlock(addr);
+ scr->scriptAddCodeBlock(addr);
break;
case SCI_OBJ_OBJECT:
case SCI_OBJ_CLASS: { // object or class?
- Object *obj = segMan->scriptObjInit(addr);
+ Object *obj = scr->scriptObjInit(addr);
Object *base_obj;
// Instantiate the superclass, if neccessary
@@ -1717,7 +1717,7 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr
} while (objtype != 0 && reg.offset < script->size - 2);
if (relocation >= 0)
- segMan->scriptRelocate(make_reg(seg_id, relocation));
+ scr->scriptRelocate(make_reg(seg_id, relocation));
return reg.segment; // instantiation successful
}
@@ -1753,7 +1753,7 @@ int script_instantiate_sci11(ResourceManager *resMan, SegManager *segMan, int sc
segMan->scriptInitialiseObjectsSci11(seg_id);
reg.offset = READ_LE_UINT16(heap->data);
- segMan->heapRelocate(reg);
+ scr->heapRelocate(reg);
return seg_id;
}