[Scummvm-cvs-logs] SF.net SVN: scummvm:[44878] scummvm/trunk/engines/sci

thebluegr at users.sourceforge.net thebluegr at users.sourceforge.net
Sat Oct 10 17:58:51 CEST 2009


Revision: 44878
          http://scummvm.svn.sourceforge.net/scummvm/?rev=44878&view=rev
Author:   thebluegr
Date:     2009-10-10 15:58:51 +0000 (Sat, 10 Oct 2009)

Log Message:
-----------
Started rewriting the Object struct into a class

Modified Paths:
--------------
    scummvm/trunk/engines/sci/console.cpp
    scummvm/trunk/engines/sci/engine/gc.cpp
    scummvm/trunk/engines/sci/engine/kscripts.cpp
    scummvm/trunk/engines/sci/engine/savegame.cpp
    scummvm/trunk/engines/sci/engine/scriptdebug.cpp
    scummvm/trunk/engines/sci/engine/seg_manager.cpp
    scummvm/trunk/engines/sci/engine/segment.cpp
    scummvm/trunk/engines/sci/engine/segment.h
    scummvm/trunk/engines/sci/engine/selector.cpp
    scummvm/trunk/engines/sci/engine/state.cpp
    scummvm/trunk/engines/sci/engine/vm.cpp
    scummvm/trunk/engines/sci/engine/vm.h

Modified: scummvm/trunk/engines/sci/console.cpp
===================================================================
--- scummvm/trunk/engines/sci/console.cpp	2009-10-10 14:55:56 UTC (rev 44877)
+++ scummvm/trunk/engines/sci/console.cpp	2009-10-10 15:58:51 UTC (rev 44878)
@@ -1353,11 +1353,11 @@
 		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 @@
 				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 @@
 	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 @@
 
 	// 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 @@
 		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));
 	}

Modified: scummvm/trunk/engines/sci/engine/gc.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/gc.cpp	2009-10-10 14:55:56 UTC (rev 44877)
+++ scummvm/trunk/engines/sci/engine/gc.cpp	2009-10-10 15:58:51 UTC (rev 44878)
@@ -122,7 +122,7 @@
 				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());
 				}
 			}
 		}

Modified: scummvm/trunk/engines/sci/engine/kscripts.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kscripts.cpp	2009-10-10 14:55:56 UTC (rev 44877)
+++ scummvm/trunk/engines/sci/engine/kscripts.cpp	2009-10-10 15:58:51 UTC (rev 44878)
@@ -123,15 +123,14 @@
 	}
 
 	*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 @@
 	}
 #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;

Modified: scummvm/trunk/engines/sci/engine/savegame.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/savegame.cpp	2009-10-10 14:55:56 UTC (rev 44877)
+++ scummvm/trunk/engines/sci/engine/savegame.cpp	2009-10-10 15:58:51 UTC (rev 44878)
@@ -312,14 +312,21 @@
 	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 @@
 		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 @@
 		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 @@
 		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 @@
 						  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);
 			}
 		}
 	}

Modified: scummvm/trunk/engines/sci/engine/scriptdebug.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/scriptdebug.cpp	2009-10-10 14:55:56 UTC (rev 44877)
+++ scummvm/trunk/engines/sci/engine/scriptdebug.cpp	2009-10-10 15:58:51 UTC (rev 44878)
@@ -75,7 +75,7 @@
 		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;

Modified: scummvm/trunk/engines/sci/engine/seg_manager.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/seg_manager.cpp	2009-10-10 14:55:56 UTC (rev 44877)
+++ scummvm/trunk/engines/sci/engine/seg_manager.cpp	2009-10-10 15:58:51 UTC (rev 44878)
@@ -184,10 +184,8 @@
 
 bool SegManager::isHeapObject(reg_t pos) {
 	Object *obj = getObject(pos);
-	if (obj == NULL)
+	if (obj == NULL || (obj && obj->isFreed()))
 		return false;
-	if (obj->_flags & OBJECT_FLAG_FREED)
-		return false;
 	Script *scr = getScriptIfLoaded(pos.segment);
 	return !(scr && scr->_markedAsDeleted);
 }
@@ -305,7 +303,7 @@
 
 			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::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 @@
 				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 @@
 				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,46 +543,8 @@
 
 	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;
+	obj->init(_buf, obj_pos);
 
-	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)));
-
 	return obj;
 }
 
@@ -829,12 +789,10 @@
 					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;

Modified: scummvm/trunk/engines/sci/engine/segment.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/segment.cpp	2009-10-10 14:55:56 UTC (rev 44877)
+++ scummvm/trunk/engines/sci/engine/segment.cpp	2009-10-10 15:58:51 UTC (rev 44878)
@@ -336,8 +336,8 @@
 			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 @@
 	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));
 }
 

Modified: scummvm/trunk/engines/sci/engine/segment.h
===================================================================
--- scummvm/trunk/engines/sci/engine/segment.h	2009-10-10 14:55:56 UTC (rev 44877)
+++ scummvm/trunk/engines/sci/engine/segment.h	2009-10-10 15:58:51 UTC (rev 44878)
@@ -191,80 +191,112 @@
 };
 
 /** 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;
+	}
 
-	uint16 getVarSelector(uint16 i) {
+	~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; }
+
+	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 {

Modified: scummvm/trunk/engines/sci/engine/selector.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/selector.cpp	2009-10-10 14:55:56 UTC (rev 44877)
+++ scummvm/trunk/engines/sci/engine/selector.cpp	2009-10-10 15:58:51 UTC (rev 44878)
@@ -104,7 +104,7 @@
 	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 @@
 			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 @@
 	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 @@
 				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 @@
 			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

Modified: scummvm/trunk/engines/sci/engine/state.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/state.cpp	2009-10-10 14:55:56 UTC (rev 44877)
+++ scummvm/trunk/engines/sci/engine/state.cpp	2009-10-10 15:58:51 UTC (rev 44878)
@@ -403,7 +403,7 @@
 
 		// 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);

Modified: scummvm/trunk/engines/sci/engine/vm.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/vm.cpp	2009-10-10 14:55:56 UTC (rev 44877)
+++ scummvm/trunk/engines/sci/engine/vm.cpp	2009-10-10 15:58:51 UTC (rev 44878)
@@ -67,9 +67,9 @@
 		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 @@
 			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
 

Modified: scummvm/trunk/engines/sci/engine/vm.h
===================================================================
--- scummvm/trunk/engines/sci/engine/vm.h	2009-10-10 14:55:56 UTC (rev 44877)
+++ scummvm/trunk/engines/sci/engine/vm.h	2009-10-10 15:58:51 UTC (rev 44878)
@@ -37,7 +37,7 @@
 
 class SegManager;
 struct EngineState;
-struct Object;
+class Object;
 class ResourceManager;
 
 /** Number of bytes to be allocated for the stack */


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list