diff options
| -rw-r--r-- | engines/sci/console.cpp | 10 | ||||
| -rw-r--r-- | engines/sci/engine/features.cpp | 10 | ||||
| -rw-r--r-- | engines/sci/engine/kernel.cpp | 2 | ||||
| -rw-r--r-- | engines/sci/engine/savegame.cpp | 4 | ||||
| -rw-r--r-- | engines/sci/engine/script.cpp | 33 | ||||
| -rw-r--r-- | engines/sci/engine/script.h | 54 | ||||
| -rw-r--r-- | engines/sci/engine/scriptdebug.cpp | 6 | ||||
| -rw-r--r-- | engines/sci/engine/seg_manager.cpp | 24 | ||||
| -rw-r--r-- | engines/sci/engine/vm.cpp | 6 | ||||
| -rw-r--r-- | engines/sci/engine/vm.h | 2 | 
10 files changed, 76 insertions, 75 deletions
| diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index 611d1481ad..f682e0e524 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -1381,7 +1381,7 @@ bool Console::cmdPrintSegmentTable(int argc, const char **argv) {  			switch (mobj->getType()) {  			case SEG_TYPE_SCRIPT: -				DebugPrintf("S  script.%03d l:%d ", (*(Script *)mobj)._nr, (*(Script *)mobj).getLockers()); +				DebugPrintf("S  script.%03d l:%d ", (*(Script *)mobj).getScriptNumber(), (*(Script *)mobj).getLockers());  				break;  			case SEG_TYPE_CLONES: @@ -1455,9 +1455,9 @@ bool Console::segmentInfo(int nr) {  	case SEG_TYPE_SCRIPT: {  		Script *scr = (Script *)mobj; -		DebugPrintf("script.%03d locked by %d, bufsize=%d (%x)\n", scr->_nr, scr->getLockers(), (uint)scr->getBufSize(), (uint)scr->getBufSize()); +		DebugPrintf("script.%03d locked by %d, bufsize=%d (%x)\n", scr->getScriptNumber(), scr->getLockers(), (uint)scr->getBufSize(), (uint)scr->getBufSize());  		if (scr->getExportTable()) -			DebugPrintf("  Exports: %4d at %d\n", scr->getExportsNr(), (int)(((const byte *)scr->getExportTable()) - ((const byte *)scr->_buf))); +			DebugPrintf("  Exports: %4d at %d\n", scr->getExportsNr(), (int)(((const byte *)scr->getExportTable()) - ((const byte *)scr->getBuf())));  		else  			DebugPrintf("  Exports: none\n"); @@ -2377,7 +2377,7 @@ bool Console::cmdBacktrace(int argc, const char **argv) {  		DebugPrintf(" argp:ST:%04x", (unsigned)(call.variables_argp - _engine->_gamestate->stack_base));  		if (call.type == EXEC_STACK_TYPE_CALL) -			DebugPrintf(" script: %d", (*(Script *)_engine->_gamestate->_segMan->_heap[call.addr.pc.segment])._nr); +			DebugPrintf(" script: %d", (*(Script *)_engine->_gamestate->_segMan->_heap[call.addr.pc.segment]).getScriptNumber());  		DebugPrintf("\n");  	} @@ -3351,7 +3351,7 @@ int Console::printObject(reg_t pos) {  		DebugPrintf("    [%03x] %s = %04x:%04x\n", obj->getFuncSelector(i), _engine->getKernel()->getSelectorName(obj->getFuncSelector(i)).c_str(), PRINT_REG(fptr));  	}  	if (s->_segMan->_heap[pos.segment]->getType() == SEG_TYPE_SCRIPT) -		DebugPrintf("\nOwner script: %d\n", s->_segMan->getScript(pos.segment)->_nr); +		DebugPrintf("\nOwner script: %d\n", s->_segMan->getScript(pos.segment)->getScriptNumber());  	return 0;  } diff --git a/engines/sci/engine/features.cpp b/engines/sci/engine/features.cpp index 75f271f3ad..2ad494b37f 100644 --- a/engines/sci/engine/features.cpp +++ b/engines/sci/engine/features.cpp @@ -84,7 +84,7 @@ bool GameFeatures::autoDetectSoundType() {  		int16 opparams[4];  		byte extOpcode;  		byte opcode; -		offset += readPMachineInstruction(script->_buf + offset, extOpcode, opparams); +		offset += readPMachineInstruction(script->getBuf(offset), extOpcode, opparams);  		opcode = extOpcode >> 1;  		// Check for end of script @@ -220,7 +220,7 @@ bool GameFeatures::autoDetectLofsType(int methodNum) {  		int16 opparams[4];  		byte extOpcode;  		byte opcode; -		offset += readPMachineInstruction(script->_buf + offset, extOpcode, opparams); +		offset += readPMachineInstruction(script->getBuf(offset), extOpcode, opparams);  		opcode = extOpcode >> 1;  		// Check for end of script @@ -306,7 +306,7 @@ bool GameFeatures::autoDetectGfxFunctionsType(int methodNum) {  		int16 opparams[4];  		byte extOpcode;  		byte opcode; -		offset += readPMachineInstruction(script->_buf + offset, extOpcode, opparams); +		offset += readPMachineInstruction(script->getBuf(offset), extOpcode, opparams);  		opcode = extOpcode >> 1;  		// Check for end of script @@ -409,7 +409,7 @@ bool GameFeatures::autoDetectSci21KernelType() {  		int16 opparams[4];  		byte extOpcode;  		byte opcode; -		offset += readPMachineInstruction(script->_buf + offset, extOpcode, opparams); +		offset += readPMachineInstruction(script->getBuf(offset), extOpcode, opparams);  		opcode = extOpcode >> 1;  		// Check for end of script @@ -462,7 +462,7 @@ bool GameFeatures::autoDetectMoveCountType() {  		int16 opparams[4];  		byte extOpcode;  		byte opcode; -		offset += readPMachineInstruction(script->_buf + offset, extOpcode, opparams); +		offset += readPMachineInstruction(script->getBuf(offset), extOpcode, opparams);  		opcode = extOpcode >> 1;  		// Check for end of script diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index d6dcf650bc..9bf0371a7a 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -644,7 +644,7 @@ int Kernel::findRegType(reg_t reg) {  	case SEG_TYPE_SCRIPT:  		if (reg.offset <= (*(Script *)mobj).getBufSize() &&  			reg.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET && -		    RAW_IS_OBJECT((*(Script *)mobj)._buf + reg.offset)) { +		    RAW_IS_OBJECT((*(Script *)mobj).getBuf(reg.offset)) ) {  			return ((Script *)mobj)->getObject(reg.offset) ? KSIG_OBJECT : KSIG_REF;  		} else  			return KSIG_REF; diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index f6a6afd196..c0ed515981 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -278,7 +278,7 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) {  		// If we are loading a script, hook it up in the script->segment map.  		if (s.isLoading() && type == SEG_TYPE_SCRIPT) { -			_scriptSegMap[((Script *)mobj)->_nr] = i; +			_scriptSegMap[((Script *)mobj)->getScriptNumber()] = i;  		}  	} @@ -765,7 +765,7 @@ void SegManager::reconstructScripts(EngineState *s) {  		scr->_localsBlock = (scr->_localsSegment == 0) ? NULL : (LocalVariables *)(_heap[scr->_localsSegment]);  		for (ObjMap::iterator it = scr->_objects.begin(); it != scr->_objects.end(); ++it) -			it->_value._baseObj = scr->_buf + it->_value.getPos().offset; +			it->_value._baseObj = scr->getBuf(it->_value.getPos().offset);  	}  	for (i = 0; i < _heap.size(); i++) { diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index f9584a2897..ac6fb6f26d 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -88,14 +88,13 @@ void Script::init(int script_nr, ResourceManager *resMan) {  	if (getSciVersion() == SCI_VERSION_0_EARLY) {  		_bufSize += READ_LE_UINT16(script->data) * 2;  	} else if (getSciVersion() >= SCI_VERSION_1_1) { -		/** -		 * In SCI11, the heap was in a separate space from the script. -		 * We append it to the end of the script, and adjust addressing accordingly. -		 * However, since we address the heap with a 16-bit pointer, the combined -		 * size of the stack and the heap must be 64KB. So far this has worked -		 * for SCI11, SCI2 and SCI21 games. SCI3 games use a different script format, -		 * and theoretically they can exceed the 64KB boundary using relocation. -		 */ +		// In SCI11, the heap was in a separate space from the script. We append +		// it to the end of the script, and adjust addressing accordingly. +		// However, since we address the heap with a 16-bit pointer, the +		// combined size of the stack and the heap must be 64KB. So far this has +		// worked for SCI11, SCI2 and SCI21 games. SCI3 games use a different +		// script format, and theoretically they can exceed the 64KB boundary +		// using relocation.  		Resource *heap = resMan->findResource(ResourceId(kResourceTypeHeap, script_nr), 0);  		_bufSize += heap->size;  		_heapSize = heap->size; @@ -109,8 +108,8 @@ void Script::init(int script_nr, ResourceManager *resMan) {  		// As mentioned above, the script and the heap together should not exceed 64KB  		if (script->size + heap->size > 65535)  			error("Script and heap sizes combined exceed 64K. This means a fundamental " -					"design bug was made regarding SCI1.1 and newer games.\nPlease " -					"report this error to the ScummVM team"); +					"design bug was made regarding SCI1.1 and newer games.\n" +					"Please report this error to the ScummVM team");  	}  } @@ -256,7 +255,7 @@ bool Script::relocateLocal(SegmentId segment, int location) {  }  void Script::relocate(reg_t block) { -	byte *heap = _buf; +	const byte *heap = _buf;  	uint16 heapSize = (uint16)_bufSize;  	uint16 heapOffset = 0; @@ -452,10 +451,9 @@ void Script::initialiseClasses(SegManager *segMan) {  	}  } -void Script::initialiseObjectsSci0(SegManager *segMan) { +void Script::initialiseObjectsSci0(SegManager *segMan, SegmentId segmentId) {  	bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY);  	const byte *seeker = _buf + (oldScriptHeader ? 2 : 0); -	SegmentId segmentId = segMan->getScriptSegment(_nr);  	do {  		uint16 objType = READ_SCI11ENDIAN_UINT16(seeker); @@ -487,11 +485,14 @@ void Script::initialiseObjectsSci0(SegManager *segMan) {  		seeker += READ_SCI11ENDIAN_UINT16(seeker + 2);  	} while ((uint32)(seeker - _buf) < getScriptSize() - 2); + +	byte *relocationBlock = findBlock(SCI_OBJ_POINTERS); +	if (relocationBlock) +		relocate(make_reg(segmentId, relocationBlock - getBuf() + 4));  } -void Script::initialiseObjectsSci11(SegManager *segMan) { +void Script::initialiseObjectsSci11(SegManager *segMan, SegmentId segmentId) {  	const byte *seeker = _heapStart + 4 + READ_SCI11ENDIAN_UINT16(_heapStart + 2) * 2; -	SegmentId segmentId = segMan->getScriptSegment(_nr);  	while (READ_SCI11ENDIAN_UINT16(seeker) == SCRIPT_OBJECT_MAGIC_NUMBER) {  		reg_t reg = make_reg(segmentId, seeker - _buf); @@ -521,6 +522,8 @@ void Script::initialiseObjectsSci11(SegManager *segMan) {  		seeker += READ_SCI11ENDIAN_UINT16(seeker + 2) * 2;  	} + +	relocate(make_reg(segmentId, READ_SCI11ENDIAN_UINT16(_heapStart)));  }  } // End of namespace Sci diff --git a/engines/sci/engine/script.h b/engines/sci/engine/script.h index 296570c218..aab073f3a1 100644 --- a/engines/sci/engine/script.h +++ b/engines/sci/engine/script.h @@ -51,19 +51,12 @@ enum ScriptObjectTypes {  typedef Common::HashMap<uint16, Object> ObjMap;  class Script : public SegmentObj { -public: +private:  	int _nr; /**< Script number */  	byte *_buf; /**< Static data buffer, or NULL if not used */  	byte *_heapStart; /**< Start of heap if SCI1.1, NULL otherwise */ -	uint32 getScriptSize() { return _scriptSize; } -	uint32 getHeapSize() { return _heapSize; } -	uint32 getBufSize() { return _bufSize; } - -protected:  	int _lockers; /**< Number of classes and objects that require this script */ - -private:  	size_t _scriptSize;  	size_t _heapSize;  	uint16 _bufSize; @@ -77,19 +70,27 @@ private:  	int _localsOffset;  	uint16 _localsCount; +	bool _markedAsDeleted; +  public:  	/**  	 * Table for objects, contains property variables.  	 * Indexed by the TODO offset.  	 */  	ObjMap _objects; +	SegmentId _localsSegment; /**< The local variable segment */ +	LocalVariables *_localsBlock; +public:  	int getLocalsOffset() const { return _localsOffset; }  	uint16 getLocalsCount() const { return _localsCount; } -	SegmentId _localsSegment; /**< The local variable segment */ -	LocalVariables *_localsBlock; -	bool _markedAsDeleted; +	uint32 getScriptSize() const { return _scriptSize; } +	uint32 getHeapSize() const { return _heapSize; } +	uint32 getBufSize() const { return _bufSize; } +	const byte *getBuf(uint offset = 0) const { return _buf + offset; } + +	int getScriptNumber() const { return _nr; }  public:  	Script(); @@ -130,15 +131,6 @@ public:  	void scriptObjRemove(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 relocate(reg_t block); - -	/**  	 * Initializes the script's local variables  	 * @param segMan	A reference to the segment manager  	 */ @@ -153,19 +145,17 @@ public:  	/**  	 * Initializes the script's objects (SCI0)  	 * @param segMan	A reference to the segment manager +	 * @param segmentId	The script's segment id  	 */ -	void initialiseObjectsSci0(SegManager *segMan); +	void initialiseObjectsSci0(SegManager *segMan, SegmentId segmentId);  	/**  	 * Initializes the script's objects (SCI1.1+)  	 * @param segMan	A reference to the segment manager +	 * @param segmentId	The script's segment id  	 */ -	void initialiseObjectsSci11(SegManager *segMan); - -private: -	bool relocateLocal(SegmentId segment, int location); +	void initialiseObjectsSci11(SegManager *segMan, SegmentId segmentId); -public:  	// script lock operations  	/** Increments the number of lockers of this script by one. */ @@ -246,6 +236,18 @@ public:  	 * Finds the pointer where a block of a specific type starts from  	 */  	byte *findBlock(int type); + +private: +	/** +	 * 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 relocate(reg_t block); + +	bool relocateLocal(SegmentId segment, int location);  };  } // End of namespace Sci diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp index d730856332..4813e083fd 100644 --- a/engines/sci/engine/scriptdebug.cpp +++ b/engines/sci/engine/scriptdebug.cpp @@ -69,7 +69,7 @@ DebugState g_debugState;	// FIXME: Avoid non-const global vars  reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecode) {  	SegmentObj *mobj = s->_segMan->getSegment(pos.segment, SEG_TYPE_SCRIPT);  	Script *script_entity = NULL; -	byte *scr; +	const byte *scr;  	int scr_size;  	reg_t retval = make_reg(pos.segment, pos.offset + 1);  	uint16 param_value; @@ -82,7 +82,7 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod  	} else  		script_entity = (Script *)mobj; -	scr = script_entity->_buf; +	scr = script_entity->getBuf();  	scr_size = script_entity->getBufSize();  	if (pos.offset >= scr_size) { @@ -291,7 +291,7 @@ void script_debug(EngineState *s) {  			if (mobj) {  				Script *scr = (Script *)mobj; -				byte *code_buf = scr->_buf; +				const byte *code_buf = scr->getBuf();  				int code_buf_size = scr->getBufSize();  				int opcode = s->xs->addr.pc.offset >= code_buf_size ? 0 : code_buf[s->xs->addr.pc.offset];  				int op = opcode >> 1; diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index b56a539c63..56591c4726 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -157,7 +157,7 @@ int SegManager::deallocate(SegmentId seg, bool recursive) {  	if (mobj->getType() == SEG_TYPE_SCRIPT) {  		Script *scr = (Script *)mobj; -		_scriptSegMap.erase(scr->_nr); +		_scriptSegMap.erase(scr->getScriptNumber());  		if (recursive && scr->_localsSegment)  			deallocate(scr->_localsSegment, recursive);  	} @@ -173,7 +173,7 @@ bool SegManager::isHeapObject(reg_t pos) {  	if (obj == NULL || (obj && obj->isFreed()))  		return false;  	Script *scr = getScriptIfLoaded(pos.segment); -	return !(scr && scr->_markedAsDeleted); +	return !(scr && scr->isMarkedAsDeleted());  }  void SegManager::deallocateScript(int script_nr) { @@ -237,7 +237,7 @@ Object *SegManager::getObject(reg_t pos) {  		} else if (mobj->getType() == SEG_TYPE_SCRIPT) {  			Script *scr = (Script *)mobj;  			if (pos.offset <= scr->getBufSize() && pos.offset >= -SCRIPT_OBJECT_MAGIC_OFFSET -			        && RAW_IS_OBJECT(scr->_buf + pos.offset)) { +			        && RAW_IS_OBJECT(scr->getBuf(pos.offset))) {  				obj = scr->getObject(pos.offset);  			}  		} @@ -384,12 +384,12 @@ LocalVariables *SegManager::allocLocalsSegment(Script *scr) {  			locals = (LocalVariables *)_heap[scr->_localsSegment];  			VERIFY(locals != NULL, "Re-used locals segment was NULL'd out");  			VERIFY(locals->getType() == SEG_TYPE_LOCALS, "Re-used locals segment did not consist of local variables"); -			VERIFY(locals->script_id == scr->_nr, "Re-used locals segment belonged to other script"); +			VERIFY(locals->script_id == scr->getScriptNumber(), "Re-used locals segment belonged to other script");  		} else  			locals = (LocalVariables *)allocSegment(new LocalVariables(), &scr->_localsSegment);  		scr->_localsBlock = locals; -		locals->script_id = scr->_nr; +		locals->script_id = scr->getScriptNumber();  		locals->_locals.resize(scr->getLocalsCount());  		return locals; @@ -1012,13 +1012,9 @@ int SegManager::instantiateScript(int scriptNum) {  	scr->initialiseClasses(this);  	if (getSciVersion() >= SCI_VERSION_1_1) { -		scr->initialiseObjectsSci11(this); -		scr->relocate(make_reg(segmentId, READ_SCI11ENDIAN_UINT16(scr->_heapStart))); +		scr->initialiseObjectsSci11(this, segmentId);  	} else { -		scr->initialiseObjectsSci0(this); -		byte *relocationBlock = scr->findBlock(SCI_OBJ_POINTERS); -		if (relocationBlock) -			scr->relocate(make_reg(segmentId, relocationBlock - scr->_buf + 4)); +		scr->initialiseObjectsSci0(this, segmentId);  	}  	return segmentId; @@ -1067,16 +1063,16 @@ void SegManager::uninstantiateScriptSci0(int script_nr) {  	do {  		reg.offset += objLength; // Step over the last checked object -		objType = READ_SCI11ENDIAN_UINT16(scr->_buf + reg.offset); +		objType = READ_SCI11ENDIAN_UINT16(scr->getBuf(reg.offset));  		if (!objType)  			break; -		objLength = READ_SCI11ENDIAN_UINT16(scr->_buf + reg.offset + 2); +		objLength = READ_SCI11ENDIAN_UINT16(scr->getBuf(reg.offset + 2));  		reg.offset += 4; // Step over header  		if ((objType == SCI_OBJ_OBJECT) || (objType == SCI_OBJ_CLASS)) { // object or class?  			reg.offset += 8;	// magic offset (SCRIPT_OBJECT_MAGIC_OFFSET) -			int16 superclass = READ_SCI11ENDIAN_UINT16(scr->_buf + reg.offset + 2); +			int16 superclass = READ_SCI11ENDIAN_UINT16(scr->getBuf(reg.offset + 2));  			if (superclass >= 0) {  				int superclass_script = getClass(superclass).script; diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 555576f579..686603ae21 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -299,7 +299,7 @@ static reg_t validate_read_var(reg_t *r, reg_t *stack_base, int type, int max, i  			EngineState *state = g_sci->getEngineState();  			ExecStack *lastCall = state->xs;  			Script *local_script = state->_segMan->getScriptIfLoaded(lastCall->local_segment); -			int curScriptNr = local_script->_nr; +			int curScriptNr = local_script->getScriptNumber();  			if (lastCall->localCallOffset != -1) {  				// if lastcall was actually a local call search back for a real call @@ -943,7 +943,7 @@ void run_vm(EngineState *s, bool restoring) {  			s->_executionStackPosChanged = false;  			obj = s->_segMan->getObject(s->xs->objp); -			code_buf = scr->_buf; +			code_buf = scr->getBuf();  			code_buf_size = scr->getBufSize();  			local_script = s->_segMan->getScriptIfLoaded(s->xs->local_segment);  			if (!local_script) { @@ -1287,7 +1287,7 @@ void run_vm(EngineState *s, bool restoring) {  //			for (int i = 0; i < opparams[0]; i++)  //				s->xs->sp[i] = make_reg(0, 'ss'); -			//if (local_script->_nr == 140 && isIslandOfDrBrain) { +			//if (local_script->getScriptNumber() == 140 && isIslandOfDrBrain) {  			//	// WORKAROUND for The Island of Dr. Brain, room 140.  			//	// Script 140 runs in an endless loop if we set its  			//	// variables to 0 here. diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h index ed4cc4a456..49169a456c 100644 --- a/engines/sci/engine/vm.h +++ b/engines/sci/engine/vm.h @@ -64,7 +64,7 @@ struct Class {  	reg_t reg; ///< offset; script-relative offset, segment: 0 if not instantiated  }; -#define RAW_IS_OBJECT(datablock) (READ_SCI11ENDIAN_UINT16(((byte *) datablock) + SCRIPT_OBJECT_MAGIC_OFFSET) == SCRIPT_OBJECT_MAGIC_NUMBER) +#define RAW_IS_OBJECT(datablock) (READ_SCI11ENDIAN_UINT16(((const byte *) datablock) + SCRIPT_OBJECT_MAGIC_OFFSET) == SCRIPT_OBJECT_MAGIC_NUMBER)  // A reference to an object's variable.  // The object is stored as a reg_t, the variable as an index into _variables | 
