diff options
| -rw-r--r-- | engines/sci/engine/script.cpp | 50 | ||||
| -rw-r--r-- | engines/sci/engine/seg_manager.cpp | 6 | ||||
| -rw-r--r-- | engines/sci/engine/seg_manager.h | 2 | ||||
| -rw-r--r-- | engines/sci/engine/segment.cpp | 24 | ||||
| -rw-r--r-- | engines/sci/engine/segment.h | 6 | 
5 files changed, 42 insertions, 46 deletions
diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 54edd38f90..6dfd39a496 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -161,49 +161,19 @@ reg_t SegManager::getClassAddress(int classnr, ScriptLoadType lock, reg_t caller  void SegManager::scriptInitialiseLocals(SegmentId segmentId) {  	Script *scr = getScript(segmentId); -	uint16 count; - -	if (getSciVersion() == SCI_VERSION_0_EARLY) { -		// 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. -		int localsCount = READ_LE_UINT16(scr->_buf); -		if (localsCount) { -			scr->_localsOffset = -localsCount * 2; // Make sure it's invalid -			LocalVariables *locals = allocLocalsSegment(scr, localsCount); -			if (locals) { -				for (int i = 0; i < localsCount; i++) -					locals->_locals[i] = NULL_REG; -			} -		} - -		return; -	} - -	// Check if the script actually has local variables -	if (scr->_localsOffset == 0) -		return; -	VERIFY(scr->_localsOffset + 1 < (uint16)scr->getBufSize(), "Locals beyond end of script\n"); - -	if (getSciVersion() >= SCI_VERSION_1_1) -		count = READ_SCI11ENDIAN_UINT16(scr->_buf + scr->_localsOffset - 2); -	else -		count = (READ_LE_UINT16(scr->_buf + scr->_localsOffset - 2) - 4) >> 1; -	// half block size - -	if (!(scr->_localsOffset + count * 2 + 1 < (uint16)scr->getBufSize())) { -		warning("Locals extend beyond end of script: offset %04x, count %x vs size %x", scr->_localsOffset, count, (uint)scr->getBufSize()); -		count = (scr->getBufSize() - scr->_localsOffset) >> 1; -	} - -	LocalVariables *locals = allocLocalsSegment(scr, count); +	LocalVariables *locals = allocLocalsSegment(scr);  	if (locals) { -		uint i; -		const byte *base = (const byte *)(scr->_buf + scr->_localsOffset); +		if (getSciVersion() > SCI_VERSION_0_EARLY) { +			const byte *base = (const byte *)(scr->_buf + scr->getLocalsOffset()); -		for (i = 0; i < count; i++) -			locals->_locals[i] = make_reg(0, READ_SCI11ENDIAN_UINT16(base + i * 2)); +			for (uint16 i = 0; i < scr->getLocalsCount(); i++) +				locals->_locals[i] = make_reg(0, READ_SCI11ENDIAN_UINT16(base + i * 2)); +		} else { +			// In SCI0 early, locals are set at run time, thus zero them all here +			for (uint16 i = 0; i < scr->getLocalsCount(); i++) +				locals->_locals[i] = NULL_REG; +		}  	}  } diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index 4d3e6f754e..8d51b27099 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -377,8 +377,8 @@ SegmentId SegManager::getScriptSegment(int script_nr, ScriptLoadType load) {  	return segment;  } -LocalVariables *SegManager::allocLocalsSegment(Script *scr, int count) { -	if (!count) { // No locals +LocalVariables *SegManager::allocLocalsSegment(Script *scr) { +	if (!scr->getLocalsCount()) { // No locals  		scr->_localsSegment = 0;  		scr->_localsBlock = NULL;  		return NULL; @@ -395,7 +395,7 @@ LocalVariables *SegManager::allocLocalsSegment(Script *scr, int count) {  		scr->_localsBlock = locals;  		locals->script_id = scr->_nr; -		locals->_locals.resize(count); +		locals->_locals.resize(scr->getLocalsCount());  		return locals;  	} diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h index 62dcddbcbe..ec89e42f9c 100644 --- a/engines/sci/engine/seg_manager.h +++ b/engines/sci/engine/seg_manager.h @@ -478,7 +478,7 @@ private:  private:  	SegmentObj *allocSegment(SegmentObj *mem, SegmentId *segid); -	LocalVariables *allocLocalsSegment(Script *scr, int count); +	LocalVariables *allocLocalsSegment(Script *scr);  	int deallocate(SegmentId seg, bool recursive);  	void createClassTable(); diff --git a/engines/sci/engine/segment.cpp b/engines/sci/engine/segment.cpp index 4b3df11d8f..c32823a7c2 100644 --- a/engines/sci/engine/segment.cpp +++ b/engines/sci/engine/segment.cpp @@ -100,6 +100,7 @@ Script::Script() : SegmentObj(SEG_TYPE_SCRIPT) {  	_localsOffset = 0;  	_localsSegment = 0;  	_localsBlock = NULL; +	_localsCount = 0;  	_markedAsDeleted = false;  } @@ -122,6 +123,7 @@ void Script::init(int script_nr, ResourceManager *resMan) {  	_localsOffset = 0;  	_localsBlock = NULL; +	_localsCount = 0;  	_codeBlocks.clear(); @@ -198,6 +200,7 @@ void Script::load(ResourceManager *resMan) {  			_exportTable = (const uint16 *)(_buf + 1 + 5 + 2);  			_numExports = READ_SCI11ENDIAN_UINT16(_exportTable - 1);  			_localsOffset = _scriptSize + 4; +			_localsCount = READ_SCI11ENDIAN_UINT16(_buf + _localsOffset - 2);  		}  	} else {  		_exportTable = (const uint16 *)findBlock(SCI_OBJ_EXPORTS); @@ -211,8 +214,27 @@ void Script::load(ResourceManager *resMan) {  			_synonyms += 4;	// skip header  		}  		const byte* localsBlock = findBlock(SCI_OBJ_LOCALVARS); -		if (localsBlock) +		if (localsBlock) {  			_localsOffset = localsBlock - _buf + 4; +			_localsCount = (READ_LE_UINT16(_buf + _localsOffset - 2) - 4) >> 1;	// half block size +		} +	} + +	if (getSciVersion() > SCI_VERSION_0_EARLY) { +		// Does the script actually have locals? If not, set the locals offset to 0 +		if (!_localsCount) +			_localsOffset = 0; + +		if (_localsOffset + _localsCount * 2 + 1 >= (int)_bufSize) { +			warning("Locals extend beyond end of script: offset %04x, count %x vs size %x", _localsOffset, _localsCount, _bufSize); +			_localsCount = (_bufSize - _localsOffset) >> 1; +		} +	} else { +		// 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. +		_localsCount = READ_LE_UINT16(_buf); +		_localsOffset = -_localsCount * 2; // Make sure it's invalid  	}  } diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h index f1b6dccaa2..8759c630e8 100644 --- a/engines/sci/engine/segment.h +++ b/engines/sci/engine/segment.h @@ -364,6 +364,9 @@ private:  	Common::Array<CodeBlock> _codeBlocks; +	int _localsOffset; +	uint16 _localsCount; +  public:  	/**  	 * Table for objects, contains property variables. @@ -371,7 +374,8 @@ public:  	 */  	ObjMap _objects; -	int _localsOffset; +	int getLocalsOffset() const { return _localsOffset; } +	uint16 getLocalsCount() const { return _localsCount; }  	SegmentId _localsSegment; /**< The local variable segment */  	LocalVariables *_localsBlock;  | 
