diff options
| author | Filippos Karapetis | 2009-10-10 15:58:51 +0000 | 
|---|---|---|
| committer | Filippos Karapetis | 2009-10-10 15:58:51 +0000 | 
| commit | d6f5d93dbf554bf7e133b0de7e675b6453736356 (patch) | |
| tree | 13c1f08b23745536e400344e00a55a0d4bcb2bb4 | |
| parent | 8fd29ecf9f5b7f66824b7df45e3f04dfc2b5cfeb (diff) | |
| download | scummvm-rg350-d6f5d93dbf554bf7e133b0de7e675b6453736356.tar.gz scummvm-rg350-d6f5d93dbf554bf7e133b0de7e675b6453736356.tar.bz2 scummvm-rg350-d6f5d93dbf554bf7e133b0de7e675b6453736356.zip  | |
Started rewriting the Object struct into a class
svn-id: r44878
| -rw-r--r-- | engines/sci/console.cpp | 28 | ||||
| -rw-r--r-- | engines/sci/engine/gc.cpp | 2 | ||||
| -rw-r--r-- | engines/sci/engine/kscripts.cpp | 13 | ||||
| -rw-r--r-- | engines/sci/engine/savegame.cpp | 32 | ||||
| -rw-r--r-- | engines/sci/engine/scriptdebug.cpp | 2 | ||||
| -rw-r--r-- | engines/sci/engine/seg_manager.cpp | 54 | ||||
| -rw-r--r-- | engines/sci/engine/segment.cpp | 10 | ||||
| -rw-r--r-- | engines/sci/engine/segment.h | 132 | ||||
| -rw-r--r-- | engines/sci/engine/selector.cpp | 72 | ||||
| -rw-r--r-- | engines/sci/engine/state.cpp | 2 | ||||
| -rw-r--r-- | engines/sci/engine/vm.cpp | 6 | ||||
| -rw-r--r-- | engines/sci/engine/vm.h | 2 | 
12 files changed, 158 insertions, 197 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index 03700abe65..04d9eaf475 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -1353,11 +1353,11 @@ bool Console::segmentInfo(int nr) {  		for (it = scr->_objects.begin(); it != end; ++it) {  			DebugPrintf("    ");  			// Object header -			Object *obj = _vm->_gamestate->_segMan->getObject(it->_value._pos); +			Object *obj = _vm->_gamestate->_segMan->getObject(it->_value.getPos());  			if (obj) -				DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(it->_value._pos), -							_vm->_gamestate->_segMan->getObjectName(it->_value._pos), -							obj->_variables.size(), obj->methods_nr); +				DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(it->_value.getPos()), +							_vm->_gamestate->_segMan->getObjectName(it->_value.getPos()), +							obj->getVarCount(), obj->getMethodCount());  		}  	}  	break; @@ -1400,11 +1400,11 @@ bool Console::segmentInfo(int nr) {  				objpos.segment = nr;  				DebugPrintf("  [%04x] %s; copy of ", i, _vm->_gamestate->_segMan->getObjectName(objpos));  				// Object header -				Object *obj = _vm->_gamestate->_segMan->getObject(ct->_table[i]._pos); +				Object *obj = _vm->_gamestate->_segMan->getObject(ct->_table[i].getPos());  				if (obj) -					DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(ct->_table[i]._pos), -								_vm->_gamestate->_segMan->getObjectName(ct->_table[i]._pos), -								obj->_variables.size(), obj->methods_nr); +					DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(ct->_table[i].getPos()), +								_vm->_gamestate->_segMan->getObjectName(ct->_table[i].getPos()), +								obj->getVarCount(), obj->getMethodCount());  			}  	}  	break; @@ -2935,7 +2935,7 @@ int Console::printObject(reg_t pos) {  	EngineState *s = _vm->_gamestate;	// for the several defines in this function  	Object *obj = s->_segMan->getObject(pos);  	Object *var_container = obj; -	int i; +	uint i;  	if (!obj) {  		DebugPrintf("[%04x:%04x]: Not an object.", PRINT_REG(pos)); @@ -2944,20 +2944,20 @@ int Console::printObject(reg_t pos) {  	// Object header  	DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(pos), s->_segMan->getObjectName(pos), -				obj->_variables.size(), obj->methods_nr); +				obj->getVarCount(), obj->getMethodCount());  	if (!(obj->getInfoSelector().offset & SCRIPT_INFO_CLASS))  		var_container = s->_segMan->getObject(obj->getSuperClassSelector());  	DebugPrintf("  -- member variables:\n"); -	for (i = 0; (uint)i < obj->_variables.size(); i++) { +	for (i = 0; (uint)i < obj->getVarCount(); i++) {  		printf("    "); -		if (i < var_container->variable_names_nr) { +		if (i < var_container->getVarCount()) {  			uint16 varSelector = var_container->getVarSelector(i);  			DebugPrintf("[%03x] %s = ", varSelector, selector_name(s, varSelector));  		} else  			DebugPrintf("p#%x = ", i); -		reg_t val = obj->_variables[i]; +		reg_t val = obj->getVariable(i);  		DebugPrintf("%04x:%04x", PRINT_REG(val));  		Object *ref = s->_segMan->getObject(val); @@ -2967,7 +2967,7 @@ int Console::printObject(reg_t pos) {  		DebugPrintf("\n");  	}  	DebugPrintf("  -- methods:\n"); -	for (i = 0; i < obj->methods_nr; i++) { +	for (i = 0; i < obj->getMethodCount(); i++) {  		reg_t fptr = obj->getFunction(i);  		DebugPrintf("    [%03x] %s = %04x:%04x\n", obj->getFuncSelector(i), selector_name(s, obj->getFuncSelector(i)), PRINT_REG(fptr));  	} diff --git a/engines/sci/engine/gc.cpp b/engines/sci/engine/gc.cpp index 160842ebe4..a4d9d4f053 100644 --- a/engines/sci/engine/gc.cpp +++ b/engines/sci/engine/gc.cpp @@ -122,7 +122,7 @@ reg_t_hash_map *find_all_used_references(EngineState *s) {  				ObjMap::iterator it;  				const ObjMap::iterator end = script->_objects.end();  				for (it = script->_objects.begin(); it != end; ++it) { -					wm.push(it->_value._pos); +					wm.push(it->_value.getPos());  				}  			}  		} diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp index e409e1a010..6d0433d62a 100644 --- a/engines/sci/engine/kscripts.cpp +++ b/engines/sci/engine/kscripts.cpp @@ -123,15 +123,14 @@ reg_t kClone(EngineState *s, int argc, reg_t *argv) {  	}  	*clone_obj = *parent_obj; -	clone_obj->_flags = 0;  	// Mark as clone  	clone_obj->setInfoSelector(make_reg(0, SCRIPT_INFO_CLONE)); -	clone_obj->setSpeciesSelector(clone_obj->_pos); +	clone_obj->setSpeciesSelector(clone_obj->getPos());  	if (parent_obj->isClass()) -		clone_obj->setSuperClassSelector(parent_obj->_pos); -	s->_segMan->getScript(parent_obj->_pos.segment)->incrementLockers(); -	s->_segMan->getScript(clone_obj->_pos.segment)->incrementLockers(); +		clone_obj->setSuperClassSelector(parent_obj->getPos()); +	s->_segMan->getScript(parent_obj->getPos().segment)->incrementLockers(); +	s->_segMan->getScript(clone_obj->getPos().segment)->incrementLockers();  	return clone_addr;  } @@ -167,8 +166,8 @@ reg_t kDisposeClone(EngineState *s, int argc, reg_t *argv) {  	}  #endif -	victim_obj->_flags |= OBJECT_FLAG_FREED; - +	victim_obj->markAsFreed(); +	  	_k_view_list_mark_free(s, victim_addr); // Free on view list, if neccessary  	return s->r_acc; diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index 0586bec484..4e161fabaf 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -312,14 +312,21 @@ void LocalVariables::saveLoadWithSerializer(Common::Serializer &s) {  	syncArray<reg_t>(s, _locals);  } -template <> -void syncWithSerializer(Common::Serializer &s, Object &obj) { -	s.syncAsSint32LE(obj._flags); -	sync_reg_t(s, obj._pos); -	s.syncAsSint32LE(obj.variable_names_nr); -	s.syncAsSint32LE(obj.methods_nr); -	syncArray<reg_t>(s, obj._variables); +void Object::saveLoadWithSerializer(Common::Serializer &s) { +	s.syncAsSint32LE(_flags); +	sync_reg_t(s, _pos); +	int varCount; +	if (s.isLoading()) { +		s.syncAsSint32LE(varCount); +		_variables.resize(varCount); +	} else { +		varCount = _variables.size(); +		s.syncAsSint32LE(varCount); +	} +	s.syncAsSint32LE(_methodCount);		// that's actually a uint16 + +	syncArray<reg_t>(s, _variables);  }  template <> @@ -411,7 +418,7 @@ void Script::saveLoadWithSerializer(Common::Serializer &s) {  		Object tmp;  		for (uint i = 0; i < numObjs; ++i) {  			syncWithSerializer<Object>(s, tmp); -			_objects[tmp._pos.offset] = tmp; +			_objects[tmp.getPos().offset] = tmp;  		}  	} else {  		ObjMap::iterator it; @@ -605,8 +612,7 @@ void SegManager::reconstructScripts(EngineState *s) {  		ObjMap::iterator it;  		const ObjMap::iterator end = scr->_objects.end();  		for (it = scr->_objects.begin(); it != end; ++it) { -			byte *data = scr->_buf + it->_value._pos.offset; -			it->_value.base = scr->_buf; +			byte *data = scr->_buf + it->_value.getPos().offset;  			it->_value.base_obj = data;  		}  	} @@ -622,7 +628,7 @@ void SegManager::reconstructScripts(EngineState *s) {  		ObjMap::iterator it;  		const ObjMap::iterator end = scr->_objects.end();  		for (it = scr->_objects.begin(); it != end; ++it) { -			byte *data = scr->_buf + it->_value._pos.offset; +			byte *data = scr->_buf + it->_value.getPos().offset;  			if (getSciVersion() >= SCI_VERSION_1_1) {  				uint16 *funct_area = (uint16 *)(scr->_buf + READ_LE_UINT16( data + 6 )); @@ -641,11 +647,11 @@ void SegManager::reconstructScripts(EngineState *s) {  						  scr->_nr, i, PRINT_REG(it->_value.getSpeciesSelector()));  					continue;  				} -				it->_value.variable_names_nr = base_obj->_variables.size(); +				it->_value.setVarCount(base_obj->getVarCount());  				it->_value.base_obj = base_obj->base_obj;  				it->_value.base_method = (uint16 *)(data + funct_area); -				it->_value.base_vars = (uint16 *)(data + it->_value.variable_names_nr * 2 + SCRIPT_SELECTOR_OFFSET); +				it->_value.base_vars = (uint16 *)(data + it->_value.getVarCount() * 2 + SCRIPT_SELECTOR_OFFSET);  			}  		}  	} diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp index e6b5c56899..5da75638e3 100644 --- a/engines/sci/engine/scriptdebug.cpp +++ b/engines/sci/engine/scriptdebug.cpp @@ -75,7 +75,7 @@ int propertyOffsetToId(SegManager *segMan, int prop_ofs, reg_t objp) {  		return -1;  	} -	selectors = obj->_variables.size(); +	selectors = obj->getVarCount();  	if (getSciVersion() < SCI_VERSION_1_1)  		selectoroffset = ((byte *)(obj->base_obj)) + SCRIPT_SELECTOR_OFFSET + selectors * 2; diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index e7132eda00..50a0d094af 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -184,9 +184,7 @@ int SegManager::deallocate(SegmentId seg, bool recursive) {  bool SegManager::isHeapObject(reg_t pos) {  	Object *obj = getObject(pos); -	if (obj == NULL) -		return false; -	if (obj->_flags & OBJECT_FLAG_FREED) +	if (obj == NULL || (obj && obj->isFreed()))  		return false;  	Script *scr = getScriptIfLoaded(pos.segment);  	return !(scr && scr->_markedAsDeleted); @@ -305,7 +303,7 @@ reg_t SegManager::findObjectByName(const Common::String &name, int index) {  			if (mobj->getType() == SEG_TYPE_SCRIPT) {  				obj = &(it->_value); -				objpos.offset = obj->_pos.offset; +				objpos.offset = obj->getPos().offset;  				++it;  			} else if (mobj->getType() == SEG_TYPE_CLONES) {  				if (!ct->isValidEntry(idx)) @@ -396,7 +394,7 @@ int Script::relocateLocal(SegmentId segment, int location) {  }  int Script::relocateObject(Object &obj, SegmentId segment, int location) { -	return relocateBlock(obj._variables, obj._pos.offset, segment, location); +	return relocateBlock(obj._variables, obj.getPos().offset, segment, location);  }  void Script::scriptAddCodeBlock(reg_t location) { @@ -442,7 +440,7 @@ void Script::scriptRelocate(reg_t block) {  				else  					printf("- No locals\n");  				for (it = _objects.begin(), k = 0; it != end; ++it, ++k) -					printf("- obj#%d at %04x w/ %d vars\n", k, it->_value._pos.offset, it->_value._variables.size()); +					printf("- obj#%d at %04x w/ %d vars\n", k, it->_value.getPos().offset, it->_value.getVarCount());  				// SQ3 script 71 has broken relocation entries.  				printf("Trying to continue anyway...\n");  			} @@ -481,7 +479,7 @@ void Script::heapRelocate(reg_t block) {  				else  					printf("- No locals\n");  				for (it = _objects.begin(), k = 0; it != end; ++it, ++k) -					printf("- obj#%d at %04x w/ %d vars\n", k, it->_value._pos.offset, it->_value._variables.size()); +					printf("- obj#%d at %04x w/ %d vars\n", k, it->_value.getPos().offset, it->_value.getVarCount());  				error("Breakpoint in %s, line %d", __FILE__, __LINE__);  			}  		} @@ -545,45 +543,7 @@ Object *Script::scriptObjInit(reg_t obj_pos) {  	VERIFY(obj_pos.offset + SCRIPT_FUNCTAREAPTR_OFFSET < (int)_bufSize, "Function area pointer stored beyond end of script\n"); -	byte *data = (byte *)(_buf + obj_pos.offset); -	uint16 *funct_area = 0; -	bool isClass; - -	if (getSciVersion() < SCI_VERSION_1_1) { -		obj->variable_names_nr = READ_LE_UINT16(data + SCRIPT_SELECTORCTR_OFFSET); -		obj->base_vars = 0; -		funct_area = (uint16 *)(data + READ_LE_UINT16(data + SCRIPT_FUNCTAREAPTR_OFFSET)); -		obj->methods_nr = READ_LE_UINT16(funct_area - 1); -		isClass = READ_LE_UINT16(data + 4) & SCRIPT_INFO_CLASS;	// SCRIPT_INFO_OFFSET -	} else { -		obj->variable_names_nr = READ_LE_UINT16(data + 2); -		obj->base_vars = (uint16 *)(_buf + READ_LE_UINT16(data + 4)); -		funct_area = (uint16 *)(_buf + READ_LE_UINT16(data + 6)); -		obj->methods_nr = READ_LE_UINT16(funct_area); -		isClass = READ_LE_UINT16(data + 14) & SCRIPT_INFO_CLASS; -	} - -	obj->_flags = 0; -	obj->_pos = obj_pos; -	obj->base_method = funct_area; - -	VERIFY((byte *)funct_area < _buf + _bufSize, "Function area pointer references beyond end of script"); - -	if (getSciVersion() < SCI_VERSION_1_1) { -		VERIFY((byte *)funct_area + obj->methods_nr * 2 -		       // add again for classes, since those also store selectors -		       + (isClass ? obj->methods_nr * 2 : 0) < _buf + _bufSize, "Function area extends beyond end of script"); -	} else { -		VERIFY(((byte *)funct_area + obj->variable_names_nr) < _buf + _bufSize, "Function area extends beyond end of script"); -	} - -	obj->_variables.resize(obj->variable_names_nr); - -	obj->base = _buf; -	obj->base_obj = data; - -	for (int i = 0; i < obj->variable_names_nr; i++) -		obj->_variables[i] = make_reg(0, READ_LE_UINT16(data + (i * 2))); +	obj->init(_buf, obj_pos);  	return obj;  } @@ -829,12 +789,10 @@ void SegManager::reconstructClones() {  					base_obj = getObject(seeker.getSpeciesSelector());  					if (!base_obj) {  						warning("Clone entry without a base class: %d", j); -						seeker.base = NULL;  						seeker.base_obj = NULL;  						seeker.base_vars = NULL;  						seeker.base_method = NULL;  					} else { -						seeker.base = base_obj->base;  						seeker.base_obj = base_obj->base_obj;  						seeker.base_vars = base_obj->base_vars;  						seeker.base_method = base_obj->base_method; diff --git a/engines/sci/engine/segment.cpp b/engines/sci/engine/segment.cpp index 2decf26c5e..38af3e8b29 100644 --- a/engines/sci/engine/segment.cpp +++ b/engines/sci/engine/segment.cpp @@ -336,8 +336,8 @@ void Script::listAllOutgoingReferences(reg_t addr, void *param, NoteCallback not  			if (_localsSegment)  				(*note)(param, make_reg(_localsSegment, 0)); -			for (uint i = 0; i < obj->_variables.size(); i++) -				(*note)(param, obj->_variables[i]); +			for (uint i = 0; i < obj->getVarCount(); i++) +				(*note)(param, obj->getVariable(i));  		} else {  			warning("Request for outgoing script-object reference at %04x:%04x failed", PRINT_REG(addr));  		} @@ -362,11 +362,11 @@ void CloneTable::listAllOutgoingReferences(reg_t addr, void *param, NoteCallback  	clone = &(_table[addr.offset]);  	// Emit all member variables (including references to the 'super' delegate) -	for (uint i = 0; i < clone->_variables.size(); i++) -		(*note)(param, clone->_variables[i]); +	for (uint i = 0; i < clone->getVarCount(); i++) +		(*note)(param, clone->getVariable(i));  	// Note that this also includes the 'base' object, which is part of the script and therefore also emits the locals. -	(*note)(param, clone->_pos); +	(*note)(param, clone->getPos());  	//debugC(2, kDebugLevelGC, "[GC] Reporting clone-pos %04x:%04x\n", PRINT_REG(clone->pos));  } diff --git a/engines/sci/engine/segment.h b/engines/sci/engine/segment.h index b04747dbf6..38f1895fdd 100644 --- a/engines/sci/engine/segment.h +++ b/engines/sci/engine/segment.h @@ -191,80 +191,112 @@ public:  };  /** Clone has been marked as 'freed' */ -#define OBJECT_FLAG_FREED (0x1 << 0) +#define OBJECT_FLAG_FREED (1 << 0) -// TODO: convert to class, perhaps? -struct Object { -	int _flags; -	reg_t _pos; /**< Object offset within its script; for clones, this is their base */ -	int variable_names_nr; /**< Number of variable names, may be less than variables_nr */ -	int methods_nr; -	byte *base; /**< Points to a buffer all relative references (code, strings) point to */ -	byte *base_obj; /**< base + object offset within base */ -	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; +class Object { +public: +	Object() { +		_flags = 0; +		_offset = getSciVersion() < SCI_VERSION_1_1 ? 0 : 5; +	} + +	~Object() { } + +	reg_t getSpeciesSelector() { return _variables[_offset]; } +	void setSpeciesSelector(reg_t value) { _variables[_offset] = value; } + +	reg_t getSuperClassSelector() {	return _variables[_offset + 1];	} +	void setSuperClassSelector(reg_t value) { _variables[_offset + 1] = value; } + +	reg_t getInfoSelector() { return _variables[_offset + 2]; } +	void setInfoSelector(reg_t value) {	_variables[_offset + 2] = value; } -	uint16 getVarSelector(uint16 i) { +	reg_t getNameSelector() { return _variables[_offset + 3]; } +	void setNameSelector(reg_t value) {	_variables[_offset + 3] = value; } + +	reg_t getClassScriptSelector() { return _variables[4]; } +	void setClassScriptSelector(reg_t value) { _variables[4] = value; } + +	Selector getVarSelector(uint16 i) {  		if (getSciVersion() < SCI_VERSION_1_1)  			return READ_LE_UINT16(base_obj + _variables.size() * 2 + i * 2);  		else  			return *(base_vars + i);  	} -	reg_t getSpeciesSelector() { -		return _variables[getSciVersion() < SCI_VERSION_1_1 ? 0 : 5]; +	Selector getFuncSelector(uint16 i) { +		uint16 offset = (getSciVersion() < SCI_VERSION_1_1) ? i : i * 2 + 1; +		return READ_LE_UINT16((byte *) (base_method + offset));  	} -	void setSpeciesSelector(reg_t value) { -		_variables[getSciVersion() < SCI_VERSION_1_1 ? 0 : 5] = value; -	} +	/** +	 * Determines if this object is a class and explicitly defines the +	 * selector as a funcselector. Does NOT say anything about the object's +	 * superclasses, i.e. failure may be returned even if one of the +	 * superclasses defines the funcselector +	 */ +	int funcSelectorPosition(Selector sel) { +		for (uint i = 0; i < _methodCount; i++) +			if (getFuncSelector(i) == sel) +				return i; -	reg_t getSuperClassSelector() { -		return _variables[getSciVersion() < SCI_VERSION_1_1 ? 1 : 6]; +		return -1;  	} -	void setSuperClassSelector(reg_t value) { -		_variables[getSciVersion() < SCI_VERSION_1_1 ? 1 : 6] = value; +	reg_t getFunction(uint16 i) { +		uint16 offset = (getSciVersion() < SCI_VERSION_1_1) ? _methodCount + 1 + i : i * 2 + 2; +		return make_reg(_pos.segment, READ_LE_UINT16((byte *) (base_method + offset)));  	} -	reg_t getInfoSelector() { -		return _variables[getSciVersion() < SCI_VERSION_1_1 ? 2 : 7]; -	} +	bool isClass() { return (getInfoSelector().offset & SCRIPT_INFO_CLASS);	} -	void setInfoSelector(reg_t value) { -		_variables[getSciVersion() < SCI_VERSION_1_1 ? 2 : 7] = value; -	} +	void markAsFreed() { _flags |= OBJECT_FLAG_FREED; } +	bool isFreed() { return _flags & OBJECT_FLAG_FREED;	} -	reg_t getNameSelector() { -		return _variables[getSciVersion() < SCI_VERSION_1_1 ? 3 : 8]; -	} +	void setVarCount(uint size) { _variables.resize(size); } +	uint getVarCount() { return _variables.size(); } -	void setNameSelector(reg_t value) { -		_variables[getSciVersion() < SCI_VERSION_1_1 ? 3 : 8] = value; -	} +	void init(byte *buf, reg_t obj_pos) { +		byte *data = (byte *)(buf + obj_pos.offset); +		base_obj = data; +		_pos = obj_pos; -	reg_t getClassScriptSelector() { -		return _variables[4]; -	} +		if (getSciVersion() < SCI_VERSION_1_1) { +			setVarCount(READ_LE_UINT16(data + SCRIPT_SELECTORCTR_OFFSET)); +			base_vars = 0; +			base_method = (uint16 *)(data + READ_LE_UINT16(data + SCRIPT_FUNCTAREAPTR_OFFSET)); +			_methodCount = READ_LE_UINT16(base_method - 1); +		} else { +			setVarCount(READ_LE_UINT16(data + 2)); +			base_vars = (uint16 *)(buf + READ_LE_UINT16(data + 4)); +			base_method = (uint16 *)(buf + READ_LE_UINT16(data + 6)); +			_methodCount = READ_LE_UINT16(base_method); +		} -	void setClassScriptSelector(reg_t value) { -		_variables[4] = value; +		for (uint i = 0; i < _variables.size(); i++) +			_variables[i] = make_reg(0, READ_LE_UINT16(data + (i * 2)));  	} -	uint16 getFuncSelector(uint16 i) { -		uint16 offset = (getSciVersion() < SCI_VERSION_1_1) ? i : i * 2 + 1; -		return READ_LE_UINT16((byte *) (base_method + offset)); -	} +	reg_t getVariable(uint var) { return _variables[var]; } -	reg_t getFunction(uint16 i) { -		uint16 offset = (getSciVersion() < SCI_VERSION_1_1) ? methods_nr + 1 + i : i * 2 + 2; -		return make_reg(_pos.segment, READ_LE_UINT16((byte *) (base_method + offset))); -	} +	uint16 getMethodCount() { return _methodCount; } +	reg_t getPos() { return _pos; } -	bool isClass() { -		return (getInfoSelector().offset & SCRIPT_INFO_CLASS); -	} +	void saveLoadWithSerializer(Common::Serializer &ser); + +	// TODO: make private. Used by validate_property(), ObjVarRef::getPointer and Script::relocateObject +	Common::Array<reg_t> _variables; + +	// TODO: make private +	byte *base_obj; /**< base + object offset within base */ +	uint16 *base_method; /**< Pointer to the method selector area for this object */ +	uint16 *base_vars; /**< Pointer to the varselector area for this object */ + +private: +	uint16 _methodCount; +	int _flags; +	uint16 _offset; +	reg_t _pos; /**< Object offset within its script; for clones, this is their base */  };  struct CodeBlock { diff --git a/engines/sci/engine/selector.cpp b/engines/sci/engine/selector.cpp index 1d44691af5..aa9545d724 100644 --- a/engines/sci/engine/selector.cpp +++ b/engines/sci/engine/selector.cpp @@ -104,7 +104,7 @@ static int _obj_locate_varselector(SegManager *segMan, Object *obj, Selector slc  	uint varnum;  	if (getSciVersion() < SCI_VERSION_1_1) { -		varnum = obj->variable_names_nr; +		varnum = obj->getVarCount();  		int selector_name_offset = varnum * 2 + SCRIPT_SELECTOR_OFFSET;  		buf = obj->base_obj + selector_name_offset;  	} else { @@ -112,7 +112,7 @@ static int _obj_locate_varselector(SegManager *segMan, Object *obj, Selector slc  			obj = segMan->getObject(obj->getSuperClassSelector());  		buf = (byte *)obj->base_vars; -		varnum = obj->_variables[1].toUint16(); +		varnum = obj->getVariable(1).toUint16();  	}  	for (uint i = 0; i < varnum; i++) @@ -122,46 +122,8 @@ static int _obj_locate_varselector(SegManager *segMan, Object *obj, Selector slc  	return -1; // Failed  } -static int _class_locate_funcselector(Object *obj, Selector slc) { -	// Determines if obj is a class and explicitly defines slc as a funcselector -	// Does NOT say anything about obj's superclasses, i.e. failure may be -	// returned even if one of the superclasses defines the funcselector. -	int funcnum = obj->methods_nr; -	int i; - -	for (i = 0; i < funcnum; i++) -		if (obj->getFuncSelector(i) == slc) // Found it? -			return i; // report success - -	return -1; // Failed -} - -static SelectorType _lookup_selector_function(SegManager *segMan, int seg_id, Object *obj, Selector selector_id, reg_t *fptr) { -	int index; - -	// "recursive" lookup - -	while (obj) { -		index = _class_locate_funcselector(obj, selector_id); - -		if (index >= 0) { -			if (fptr) { -				*fptr = obj->getFunction(index); -			} - -			return kSelectorMethod; -		} else { -			seg_id = obj->getSuperClassSelector().segment; -			obj = segMan->getObject(obj->getSuperClassSelector()); -		} -	} - -	return kSelectorNone; -} -  SelectorType lookup_selector(SegManager *segMan, reg_t obj_location, Selector selector_id, ObjVarRef *varp, reg_t *fptr) {  	Object *obj = segMan->getObject(obj_location); -	Object *species;  	int index;  	bool oldScriptHeader = (getSciVersion() == SCI_VERSION_0_EARLY); @@ -175,18 +137,6 @@ SelectorType lookup_selector(SegManager *segMan, reg_t obj_location, Selector se  				PRINT_REG(obj_location));  	} -	if (obj->isClass()) -		species = obj; -	else -		species = segMan->getObject(obj->getSpeciesSelector()); - - -	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->getSpeciesSelector())); -		return kSelectorNone; -	} -  	index = _obj_locate_varselector(segMan, obj, selector_id);  	if (index >= 0) { @@ -196,9 +146,25 @@ SelectorType lookup_selector(SegManager *segMan, reg_t obj_location, Selector se  			varp->varindex = index;  		}  		return kSelectorVariable; +	} else { +		// Check if it's a method, with recursive lookup in superclasses +		while (obj) { +			index = obj->funcSelectorPosition(selector_id); +			if (index >= 0) { +				if (fptr) +					*fptr = obj->getFunction(index); + +				return kSelectorMethod; +			} else { +				obj = segMan->getObject(obj->getSuperClassSelector()); +			} +		} + +		return kSelectorNone;  	} -	return _lookup_selector_function(segMan, obj_location.segment, obj, selector_id, fptr); + +//	return _lookup_selector_function(segMan, obj, selector_id, fptr);  }  } // End of namespace Sci diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index 328cdd4971..047d6ca6c2 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -403,7 +403,7 @@ SciVersion EngineState::detectLofsType() {  		// Check methods of the Game class for lofs operations  		if (obj) { -			for (int m = 0; m < obj->methods_nr; m++) { +			for (uint m = 0; m < obj->getMethodCount(); m++) {  				reg_t fptr = obj->getFunction(m);  				Script *script = _segMan->getScript(fptr.segment); diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 2f3e2a618c..80c38fb986 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -67,9 +67,9 @@ static reg_t &validate_property(Object *obj, int index) {  		return dummyReg;  	} -	if (index < 0 || (uint)index >= obj->_variables.size()) { +	if (index < 0 || (uint)index >= obj->getVarCount()) {  		debugC(2, kDebugLevelVM, "[VM] Invalid property #%d (out of [0..%d]) requested!\n",  -			index, obj->_variables.size()); +			index, obj->getVarCount());  		return dummyReg;  	} @@ -1598,7 +1598,7 @@ int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int scr  			obj->setSpeciesSelector(INST_LOOKUP_CLASS(obj->getSpeciesSelector().offset));  			base_obj = segMan->getObject(obj->getSpeciesSelector()); -			obj->variable_names_nr = base_obj->_variables.size(); +			obj->setVarCount(base_obj->getVarCount());  			obj->base_obj = base_obj->base_obj;  			// Copy base from species class, as we need its selector IDs diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h index e63a09ca16..dddd5d9672 100644 --- a/engines/sci/engine/vm.h +++ b/engines/sci/engine/vm.h @@ -37,7 +37,7 @@ namespace Sci {  class SegManager;  struct EngineState; -struct Object; +class Object;  class ResourceManager;  /** Number of bytes to be allocated for the stack */  | 
