diff options
| -rw-r--r-- | engines/sci/engine/kscripts.cpp | 8 | ||||
| -rw-r--r-- | engines/sci/engine/memobj.cpp | 26 | ||||
| -rw-r--r-- | engines/sci/engine/memobj.h | 44 | ||||
| -rw-r--r-- | engines/sci/engine/seg_manager.cpp | 81 | ||||
| -rw-r--r-- | engines/sci/engine/seg_manager.h | 33 | ||||
| -rw-r--r-- | engines/sci/engine/vm.cpp | 10 | 
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;  } | 
