diff options
| -rw-r--r-- | engines/sci/console.cpp | 11 | ||||
| -rw-r--r-- | engines/sci/engine/kscripts.cpp | 10 | ||||
| -rw-r--r-- | engines/sci/engine/memobj.h | 84 | ||||
| -rw-r--r-- | engines/sci/engine/savegame.cpp | 4 | ||||
| -rw-r--r-- | engines/sci/engine/scriptdebug.cpp | 4 | ||||
| -rw-r--r-- | engines/sci/engine/seg_manager.cpp | 12 | ||||
| -rw-r--r-- | engines/sci/engine/state.cpp | 4 | ||||
| -rw-r--r-- | engines/sci/engine/vm.cpp | 24 | ||||
| -rw-r--r-- | engines/sci/engine/vm.h | 13 | 
9 files changed, 97 insertions, 69 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index 9f75b14d99..3f4148fcc0 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -3065,13 +3065,14 @@ int Console::printObject(reg_t pos) {  	DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(pos), s->segMan->getObjectName(pos),  				obj->_variables.size(), obj->methods_nr); -	if (!(obj->_variables[SCRIPT_INFO_SELECTOR].offset & SCRIPT_INFO_CLASS)) -		var_container = s->segMan->getObject(obj->_variables[SCRIPT_SUPERCLASS_SELECTOR]); +	if (!(obj->getInfoSelector(version).offset & SCRIPT_INFO_CLASS)) +		var_container = s->segMan->getObject(obj->getSuperClassSelector(version));  	DebugPrintf("  -- member variables:\n");  	for (i = 0; (uint)i < obj->_variables.size(); i++) {  		printf("    ");  		if (i < var_container->variable_names_nr) { -			DebugPrintf("[%03x] %s = ", VM_OBJECT_GET_VARSELECTOR(var_container, i), selector_name(s, VM_OBJECT_GET_VARSELECTOR(var_container, i))); +			uint16 varSelector = var_container->getVarSelector(i, version); +			DebugPrintf("[%03x] %s = ", varSelector, selector_name(s, varSelector));  		} else  			DebugPrintf("p#%x = ", i); @@ -3086,8 +3087,8 @@ int Console::printObject(reg_t pos) {  	}  	DebugPrintf("  -- methods:\n");  	for (i = 0; i < obj->methods_nr; i++) { -		reg_t fptr = VM_OBJECT_READ_FUNCTION(obj, i); -		DebugPrintf("    [%03x] %s = %04x:%04x\n", VM_OBJECT_GET_FUNCSELECTOR(obj, i), selector_name(s, VM_OBJECT_GET_FUNCSELECTOR(obj, i)), PRINT_REG(fptr)); +		reg_t fptr = obj->getFunction(i, version); +		DebugPrintf("    [%03x] %s = %04x:%04x\n", obj->getFuncSelector(i, version), selector_name(s, obj->getFuncSelector(i, version)), PRINT_REG(fptr));  	}  	if (s->segMan->_heap[pos.segment]->getType() == SEG_TYPE_SCRIPT)  		DebugPrintf("\nOwner script:\t%d\n", s->segMan->getScript(pos.segment)->_nr); diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp index 318d4b9c4d..157f285541 100644 --- a/engines/sci/engine/kscripts.cpp +++ b/engines/sci/engine/kscripts.cpp @@ -204,10 +204,10 @@ reg_t kClone(EngineState *s, int, int argc, reg_t *argv) {  	SciVersion version = s->resMan->sciVersion();	// for the selector defines  	// Mark as clone -	clone_obj->_variables[SCRIPT_INFO_SELECTOR].offset = SCRIPT_INFO_CLONE; -	clone_obj->_variables[SCRIPT_SPECIES_SELECTOR] = clone_obj->pos; -	if (IS_CLASS(parent_obj)) -		clone_obj->_variables[SCRIPT_SUPERCLASS_SELECTOR] = parent_obj->pos; +	clone_obj->setInfoSelector(make_reg(0, SCRIPT_INFO_CLONE), version); +	clone_obj->setSpeciesSelector(clone_obj->pos, version); +	if (parent_obj->isClass(version)) +		clone_obj->setSuperClassSelector(parent_obj->pos, version);  	s->segMan->getScript(parent_obj->pos.segment)->incrementLockers();  	s->segMan->getScript(clone_obj->pos.segment)->incrementLockers(); @@ -230,7 +230,7 @@ reg_t kDisposeClone(EngineState *s, int, int argc, reg_t *argv) {  	SciVersion version = s->resMan->sciVersion();	// for the selector defines -	if (victim_obj->_variables[SCRIPT_INFO_SELECTOR].offset != SCRIPT_INFO_CLONE) { +	if (victim_obj->getInfoSelector(version).offset != SCRIPT_INFO_CLONE) {  		//warning("Attempt to dispose something other than a clone at %04x", offset);  		// SCI silently ignores this behaviour; some games actually depend on it  		return s->r_acc; diff --git a/engines/sci/engine/memobj.h b/engines/sci/engine/memobj.h index e792ac80ae..38a165a33a 100644 --- a/engines/sci/engine/memobj.h +++ b/engines/sci/engine/memobj.h @@ -198,6 +198,7 @@ public:  /** Clone has been marked as 'freed' */  #define OBJECT_FLAG_FREED (0x1 << 0) +// TODO: convert to class, perhaps?  struct Object {  	int flags;  	reg_t pos; /**< Object offset within its script; for clones, this is their base */ @@ -208,6 +209,67 @@ struct Object {  	uint16 *base_method; /**< Pointer to the method selector area for this object */  	uint16 *base_vars; /**< Pointer to the varselector area for this object */  	Common::Array<reg_t> _variables; + +	uint16 getVarSelector(uint16 i, SciVersion version) { +		if (version < SCI_VERSION_1_1) +			return READ_LE_UINT16(base_obj + _variables.size() * 2 + i * 2); +		else +			return *(base_vars + i); +	} + +	reg_t getSpeciesSelector(SciVersion version) { +		return _variables[version < SCI_VERSION_1_1 ? 0 : 5]; +	} + +	void setSpeciesSelector(reg_t value, SciVersion version) { +		_variables[version < SCI_VERSION_1_1 ? 0 : 5] = value; +	} + +	reg_t getSuperClassSelector(SciVersion version) {  +		return _variables[version < SCI_VERSION_1_1 ? 1 : 6]; +	} + +	void setSuperClassSelector(reg_t value, SciVersion version) { +		_variables[version < SCI_VERSION_1_1 ? 1 : 6] = value; +	} + +	reg_t getInfoSelector(SciVersion version) { +		return _variables[version < SCI_VERSION_1_1 ? 2 : 7]; +	} + +	void setInfoSelector(reg_t value, SciVersion version) { +		_variables[version < SCI_VERSION_1_1 ? 2 : 7] = value; +	} + +	reg_t getNameSelector(SciVersion version) { +		return _variables[version < SCI_VERSION_1_1 ? 3 : 8]; +	} + +	void setNameSelector(reg_t value, SciVersion version) { +		_variables[version < SCI_VERSION_1_1 ? 3 : 8] = value; +	} + +	reg_t getClassScriptSelector() { +		return _variables[4]; +	} + +	void setClassScriptSelector(reg_t value) { +		_variables[4] = value; +	} + +	uint16 getFuncSelector(uint16 i, SciVersion version) { +		uint16 offset = (version < SCI_VERSION_1_1) ? i : i * 2 + 1; +		return READ_LE_UINT16((byte *) (base_method + offset)); +	} + +	reg_t getFunction(uint16 i, SciVersion version) { +		uint16 offset = (version < SCI_VERSION_1_1) ? methods_nr + 1 + i : i * 2 + 2; +		return make_reg(pos.segment, READ_LE_UINT16((byte *) (base_method + offset))); +	} +	 +	bool isClass(SciVersion version) { +		return (getInfoSelector(version).offset & SCRIPT_INFO_CLASS); +	}  };  struct CodeBlock { @@ -215,28 +277,6 @@ struct CodeBlock {  	int size;  }; -#define VM_OBJECT_GET_VARSELECTOR(obj, i)  \ -	(version < SCI_VERSION_1_1 ? \ -	 READ_LE_UINT16(obj->base_obj + obj->_variables.size() * 2 + i*2) : \ -	 *(obj->base_vars + i)) -#define VM_OBJECT_READ_PROPERTY(obj, i) (obj->_variables[i]) -#define VM_OBJECT_GET_FUNCSELECTOR(obj, i) \ -	(version < SCI_VERSION_1_1 ? \ -	 READ_LE_UINT16((byte *) (obj->base_method + i)) : \ -	 READ_LE_UINT16((byte *) (obj->base_method + i*2 + 1))) -#define VM_OBJECT_READ_FUNCTION(obj, i) \ -	(version < SCI_VERSION_1_1 ? \ -	 make_reg(obj->pos.segment, \ -		 READ_LE_UINT16((byte *) (obj->base_method \ -				 + obj->methods_nr + 1 \ -				 + i))) : \ -	 make_reg(obj->pos.segment, \ -		 READ_LE_UINT16((byte *) (obj->base_method \ -				 + i * 2 + 2)))) - - - -  class Script : public SegmentObj {  public:  	int _nr; /**< Script number */ diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index 11599797e2..0782530a7c 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -613,11 +613,11 @@ static void reconstruct_scripts(EngineState *s, SegManager *self) {  						int funct_area = READ_LE_UINT16( data + SCRIPT_FUNCTAREAPTR_OFFSET );  						Object *base_obj; -						base_obj = s->segMan->getObject(scr->_objects[j]._variables[SCRIPT_SPECIES_SELECTOR]); +						base_obj = s->segMan->getObject(scr->_objects[j].getSpeciesSelector(version));  						if (!base_obj) {  							warning("Object without a base class: Script %d, index %d (reg address %04x:%04x", -								  scr->_nr, j, PRINT_REG(scr->_objects[j]._variables[SCRIPT_SPECIES_SELECTOR])); +								  scr->_nr, j, PRINT_REG(scr->_objects[j].getSpeciesSelector(version)));  							continue;  						}  						scr->_objects[j].variable_names_nr = base_obj->_variables.size(); diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp index 38879a48ae..670aee3981 100644 --- a/engines/sci/engine/scriptdebug.cpp +++ b/engines/sci/engine/scriptdebug.cpp @@ -81,8 +81,8 @@ int propertyOffsetToId(SegManager *segMan, int prop_ofs, reg_t objp) {  	if (segMan->sciVersion() < SCI_VERSION_1_1)  		selectoroffset = ((byte *)(obj->base_obj)) + SCRIPT_SELECTOR_OFFSET + selectors * 2;  	else { -		if (!(obj->_variables[SCRIPT_INFO_SELECTOR].offset & SCRIPT_INFO_CLASS)) { -			obj = segMan->getObject(obj->_variables[SCRIPT_SUPERCLASS_SELECTOR]); +		if (!(obj->getInfoSelector(version).offset & SCRIPT_INFO_CLASS)) { +			obj = segMan->getObject(obj->getSuperClassSelector(version));  			selectoroffset = (byte *)obj->base_vars;  		} else  			selectoroffset = (byte *)obj->base_vars; diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index c503d7bcd0..cb178098b2 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -266,11 +266,11 @@ const char *SegManager::getObjectName(reg_t pos) {  	if (!obj)  		return "<no such object>"; -	reg_t nameReg = obj->_variables[SCRIPT_NAME_SELECTOR]; +	reg_t nameReg = obj->getNameSelector(version);  	if (nameReg.isNull())  		return "<no name>"; -	const char *name = derefString(obj->_variables[SCRIPT_NAME_SELECTOR]); +	const char *name = derefString(nameReg);  	if (!name)  		return "<invalid name>"; @@ -678,8 +678,8 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) {  #endif  		// Copy base from species class, as we need its selector IDs -		obj->_variables[SCRIPT_SUPERCLASS_SELECTOR] =  -			getClassAddress(obj->_variables[SCRIPT_SUPERCLASS_SELECTOR].offset, SCRIPT_GET_LOCK, NULL_REG); +		obj->setSuperClassSelector( +			getClassAddress(obj->getSuperClassSelector(version).offset, SCRIPT_GET_LOCK, NULL_REG), version);  		// Set the -classScript- selector to the script number.  		// FIXME: As this selector is filled in at run-time, it is likely @@ -687,7 +687,7 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) {  		// uses this selector together with -propDict- to compare classes.  		// For the purpose of Obj::isKindOf, using the script number appears  		// to be sufficient. -		obj->_variables[SCRIPT_CLASSSCRIPT_SELECTOR] = make_reg(0, scr->_nr); +		obj->setClassScriptSelector(make_reg(0, scr->_nr));  		seeker += READ_LE_UINT16(seeker + 2) * 2;  	} @@ -809,7 +809,7 @@ void SegManager::reconstructClones() {  						continue;  					CloneTable::Entry &seeker = ct->_table[j]; -					base_obj = getObject(seeker._variables[SCRIPT_SPECIES_SELECTOR]); +					base_obj = getObject(seeker.getSpeciesSelector(version));  					if (!base_obj) {  						warning("Clone entry without a base class: %d", j);  						seeker.base = NULL; diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index 4c60b26fa4..bf385d6551 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -335,7 +335,7 @@ SciVersion EngineState::detectSetCursorType() {  SciVersion EngineState::detectLofsType() {  	if (_lofsType == SCI_VERSION_AUTODETECT) { -		SciVersion version = segMan->sciVersion(); // FIXME: for VM_OBJECT_READ_FUNCTION +		SciVersion version = segMan->sciVersion();  		// This detection only works (and is only needed) pre-SCI1.1  		if (version >= SCI_VERSION_1_1) { @@ -355,7 +355,7 @@ SciVersion EngineState::detectLofsType() {  		// Check methods of the Game class for lofs operations  		if (obj) {  			for (int m = 0; m < obj->methods_nr; m++) { -				reg_t fptr = VM_OBJECT_READ_FUNCTION(obj, m); +				reg_t fptr = obj->getFunction(m, version);  				Script *script = segMan->getScript(fptr.segment); diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index c0381519cc..617016f3e6 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -1406,8 +1406,8 @@ static int _obj_locate_varselector(SegManager *segMan, Object *obj, Selector slc  		int selector_name_offset = varnum * 2 + SCRIPT_SELECTOR_OFFSET;  		buf = obj->base_obj + selector_name_offset;  	} else { -		if (!(obj->_variables[SCRIPT_INFO_SELECTOR].offset & SCRIPT_INFO_CLASS)) -			obj = segMan->getObject(obj->_variables[SCRIPT_SUPERCLASS_SELECTOR]); +		if (!(obj->getInfoSelector(version).offset & SCRIPT_INFO_CLASS)) +			obj = segMan->getObject(obj->getSuperClassSelector(version));  		buf = (byte *)obj->base_vars;  		varnum = obj->_variables[1].toUint16(); @@ -1428,7 +1428,7 @@ static int _class_locate_funcselector(Object *obj, Selector slc, SciVersion vers  	int i;  	for (i = 0; i < funcnum; i++) -		if (VM_OBJECT_GET_FUNCSELECTOR(obj, i) == slc) // Found it? +		if (obj->getFuncSelector(i, version) == slc) // Found it?  			return i; // report success  	return -1; // Failed @@ -1445,13 +1445,13 @@ static SelectorType _lookup_selector_function(SegManager *segMan, int seg_id, Ob  		if (index >= 0) {  			if (fptr) { -				*fptr = VM_OBJECT_READ_FUNCTION(obj, index); +				*fptr = obj->getFunction(index, version);  			}  			return kSelectorMethod;  		} else { -			seg_id = obj->_variables[SCRIPT_SUPERCLASS_SELECTOR].segment; -			obj = segMan->getObject(obj->_variables[SCRIPT_SUPERCLASS_SELECTOR]); +			seg_id = obj->getSuperClassSelector(version).segment; +			obj = segMan->getObject(obj->getSuperClassSelector(version));  		}  	} @@ -1475,15 +1475,15 @@ SelectorType lookup_selector(SegManager *segMan, reg_t obj_location, Selector se  				PRINT_REG(obj_location));  	} -	if (IS_CLASS(obj)) +	if (obj->isClass(version))  		species = obj;  	else -		species = segMan->getObject(obj->_variables[SCRIPT_SPECIES_SELECTOR]); +		species = segMan->getObject(obj->getSpeciesSelector(version));  	if (!obj) {  		error("lookup_selector(): Error while looking up Species class.\nOriginal address was %04x:%04x. Species address was %04x:%04x",  -			PRINT_REG(obj_location), PRINT_REG(obj->_variables[SCRIPT_SPECIES_SELECTOR])); +			PRINT_REG(obj_location), PRINT_REG(obj->getSpeciesSelector(version)));  		return kSelectorNone;  	} @@ -1694,14 +1694,14 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr  			Object *base_obj;  			// Instantiate the superclass, if neccessary -			obj->_variables[SCRIPT_SPECIES_SELECTOR] = INST_LOOKUP_CLASS(obj->_variables[SCRIPT_SPECIES_SELECTOR].offset); +			obj->setSpeciesSelector(INST_LOOKUP_CLASS(obj->getSpeciesSelector(version).offset), version); -			base_obj = segMan->getObject(obj->_variables[SCRIPT_SPECIES_SELECTOR]); +			base_obj = segMan->getObject(obj->getSpeciesSelector(version));  			obj->variable_names_nr = base_obj->_variables.size();  			obj->base_obj = base_obj->base_obj;  			// Copy base from species class, as we need its selector IDs -			obj->_variables[SCRIPT_SUPERCLASS_SELECTOR] = INST_LOOKUP_CLASS(obj->_variables[SCRIPT_SUPERCLASS_SELECTOR].offset); +			obj->setSuperClassSelector(INST_LOOKUP_CLASS(obj->getSuperClassSelector(version).offset), version);  		} // if object or class  		break;  		case SCI_OBJ_POINTERS: // A relocation table diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h index 57fad31c8f..f2d51fafb1 100644 --- a/engines/sci/engine/vm.h +++ b/engines/sci/engine/vm.h @@ -68,11 +68,9 @@ class ResourceManager;  /** Offset of the name pointer */  #define SCRIPT_NAME_OFFSET (version < SCI_VERSION_1_1 ? 14 -8 : 16) -#define SCRIPT_NAME_SELECTOR (version < SCI_VERSION_1_1 ? 3 : 8)  /** Object-relative offset of the -info- selector */  #define SCRIPT_INFO_OFFSET (version < SCI_VERSION_1_1 ? 12 -8 : 14) -#define SCRIPT_INFO_SELECTOR (version < SCI_VERSION_1_1 ? 2 : 7)  /** Flag fo the -info- selector */  #define SCRIPT_INFO_CLONE 0x0001 @@ -91,17 +89,9 @@ class ResourceManager;  #define SCRIPT_SUPERCLASS_OFFSET (version < SCI_VERSION_1_1 ? 10 -8 : 12) -/*---------------------------------*/ -/* Script selector index variables */ -/*---------------------------------*/ -#define SCRIPT_SPECIES_SELECTOR (version < SCI_VERSION_1_1 ? 0 : 5) -#define SCRIPT_SUPERCLASS_SELECTOR (version < SCI_VERSION_1_1 ? 1 : 6) -#define SCRIPT_CLASSSCRIPT_SELECTOR 4 -  /** Magic adjustment value for lofsa and lofss */  #define SCRIPT_LOFS_MAGIC 3 -  /** Stack pointer value: Use predecessor's value */  #define CALL_SP_CARRY NULL @@ -119,9 +109,6 @@ struct Class {  #define RAW_IS_OBJECT(datablock) (READ_LE_UINT16(((byte *) datablock) + SCRIPT_OBJECT_MAGIC_OFFSET) == SCRIPT_OBJECT_MAGIC_NUMBER) -#define IS_CLASS(obj) (obj->_variables[SCRIPT_INFO_SELECTOR].offset & SCRIPT_INFO_CLASS) - -  /** Contains selector IDs for a few selected selectors */  struct selector_map_t {  	Selector init; /**< Init function */  | 
