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

thebluegr at users.sourceforge.net thebluegr at users.sourceforge.net
Wed May 26 10:27:24 CEST 2010


Revision: 49228
          http://scummvm.svn.sourceforge.net/scummvm/?rev=49228&view=rev
Author:   thebluegr
Date:     2010-05-26 08:27:24 +0000 (Wed, 26 May 2010)

Log Message:
-----------
More work on controlling access to members of the Object class:
- Moved the code for initializing the object class, species and base object inside the Object class
- Made propertyOffsetToId() a method of the Object class
- Made relocateObject() a method of the Object class
- The Object getVariable() method now returns a reference to the requested variable

Only SegManager::reconstructScripts() is left needing direct access to the members of the Object class

Modified Paths:
--------------
    scummvm/trunk/engines/sci/engine/script.cpp
    scummvm/trunk/engines/sci/engine/scriptdebug.cpp
    scummvm/trunk/engines/sci/engine/segment.cpp
    scummvm/trunk/engines/sci/engine/segment.h
    scummvm/trunk/engines/sci/engine/vm.cpp

Modified: scummvm/trunk/engines/sci/engine/script.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/script.cpp	2010-05-26 06:53:08 UTC (rev 49227)
+++ scummvm/trunk/engines/sci/engine/script.cpp	2010-05-26 08:27:24 UTC (rev 49228)
@@ -318,8 +318,6 @@
 	return seg_id;
 }
 
-#define INST_LOOKUP_CLASS(id) ((id == 0xffff)? NULL_REG : segMan->getClassAddress(id, SCRIPT_GET_LOCK, addr))
-
 int script_instantiate_sci0(ResourceManager *resMan, SegManager *segMan, int script_nr) {
 	int objType;
 	uint32 objLength = 0;
@@ -429,21 +427,10 @@
 		case SCI_OBJ_OBJECT:
 		case SCI_OBJ_CLASS: { // object or class?
 			Object *obj = scr->scriptObjInit(addr);
+			obj->initSpecies(segMan, addr);
 
-			// Instantiate the superclass, if neccessary
-			obj->setSpeciesSelector(INST_LOOKUP_CLASS(obj->getSpeciesSelector().offset));
-
-			Object *baseObj = segMan->getObject(obj->getSpeciesSelector());
-
-			if (baseObj) {
-				obj->setVarCount(baseObj->getVarCount());
-				// Copy base from species class, as we need its selector IDs
-				obj->_baseObj = baseObj->_baseObj;
-
-				obj->setSuperClassSelector(INST_LOOKUP_CLASS(obj->getSuperClassSelector().offset));
-			} else {
+			if (!obj->initBaseObject(segMan, addr)) {
 				warning("Failed to locate base object for object at %04X:%04X; skipping", PRINT_REG(addr));
-
 				scr->scriptObjRemove(addr);
 			}
 		} // if object or class

Modified: scummvm/trunk/engines/sci/engine/scriptdebug.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/scriptdebug.cpp	2010-05-26 06:53:08 UTC (rev 49227)
+++ scummvm/trunk/engines/sci/engine/scriptdebug.cpp	2010-05-26 08:27:24 UTC (rev 49228)
@@ -67,37 +67,6 @@
 
 DebugState g_debugState;
 
-int propertyOffsetToId(SegManager *segMan, int prop_ofs, reg_t objp) {
-	Object *obj = segMan->getObject(objp);
-	byte *selectoroffset;
-	int selectors;
-
-	if (!obj) {
-		warning("Applied propertyOffsetToId on non-object at %04x:%04x", PRINT_REG(objp));
-		return -1;
-	}
-
-	selectors = obj->getVarCount();
-
-	if (getSciVersion() < SCI_VERSION_1_1)
-		selectoroffset = ((byte *)(obj->_baseObj)) + SCRIPT_SELECTOR_OFFSET + selectors * 2;
-	else {
-		if (!(obj->getInfoSelector().offset & SCRIPT_INFO_CLASS)) {
-			obj = segMan->getObject(obj->getSuperClassSelector());
-			selectoroffset = (byte *)obj->_baseVars;
-		} else
-			selectoroffset = (byte *)obj->_baseVars;
-	}
-
-	if (prop_ofs < 0 || (prop_ofs >> 1) >= selectors) {
-		warning("Applied propertyOffsetToId to invalid property offset %x (property #%d not in [0..%d]) on object at %04x:%04x",
-		          prop_ofs, prop_ofs >> 1, selectors - 1, PRINT_REG(objp));
-		return -1;
-	}
-
-	return READ_SCI11ENDIAN_UINT16(selectoroffset + prop_ofs);
-}
-
 // Disassembles one command from the heap, returns address of next command or 0 if a ret was encountered.
 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);
@@ -224,10 +193,11 @@
 	if (pos == scriptState.xs->addr.pc) { // Extra information if debugging the current opcode
 		if ((opcode == op_pTos) || (opcode == op_sTop) || (opcode == op_pToa) || (opcode == op_aTop) ||
 		        (opcode == op_dpToa) || (opcode == op_ipToa) || (opcode == op_dpTos) || (opcode == op_ipTos)) {
-			int prop_ofs = scr[pos.offset + 1];
-			int prop_id = propertyOffsetToId(s->_segMan, prop_ofs, scriptState.xs->objp);
-
-			printf("	(%s)", selector_name(s, prop_id));
+			Object *obj = s->_segMan->getObject(scriptState.xs->objp);
+			if (!obj)
+				warning("Attempted to reference on non-object at %04x:%04x", PRINT_REG(scriptState.xs->objp));
+			else
+				printf("	(%s)", selector_name(s, obj->propertyOffsetToId(s->_segMan, scr[pos.offset + 1])));
 		}
 	}
 

Modified: scummvm/trunk/engines/sci/engine/segment.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/segment.cpp	2010-05-26 06:53:08 UTC (rev 49227)
+++ scummvm/trunk/engines/sci/engine/segment.cpp	2010-05-26 08:27:24 UTC (rev 49228)
@@ -247,10 +247,6 @@
 		return 0; // No hands, no cookies
 }
 
-int Script::relocateObject(Object &obj, SegmentId segment, int location) {
-	return relocateBlock(obj._variables, obj.getPos().offset, segment, location);
-}
-
 void Script::scriptAddCodeBlock(reg_t location) {
 	CodeBlock cb;
 	cb.pos = location;
@@ -276,7 +272,7 @@
 			ObjMap::iterator it;
 			const ObjMap::iterator end = _objects.end();
 			for (it = _objects.begin(); !done && it != end; ++it) {
-				if (relocateObject(it->_value, block.segment, pos))
+				if (it->_value.relocate(block.segment, pos, _scriptSize))
 					done = true;
 			}
 
@@ -321,7 +317,7 @@
 			ObjMap::iterator it;
 			const ObjMap::iterator end = _objects.end();
 			for (it = _objects.begin(); !done && it != end; ++it) {
-				if (relocateObject(it->_value, block.segment, pos))
+				if (it->_value.relocate(block.segment, pos, _scriptSize))
 					done = true;
 			}
 
@@ -673,6 +669,27 @@
 
 //-------------------- object ----------------------------
 
+void Object::init(byte *buf, reg_t obj_pos) {
+	byte *data = (byte *)(buf + obj_pos.offset);
+	_baseObj = data;
+	_pos = obj_pos;
+
+	if (getSciVersion() < SCI_VERSION_1_1) {
+		_variables.resize(READ_LE_UINT16(data + SCRIPT_SELECTORCTR_OFFSET));
+		_baseVars = (uint16 *)(_baseObj + _variables.size() * 2);
+		_baseMethod = (uint16 *)(data + READ_LE_UINT16(data + SCRIPT_FUNCTAREAPTR_OFFSET));
+		_methodCount = READ_LE_UINT16(_baseMethod - 1);
+	} else {
+		_variables.resize(READ_SCI11ENDIAN_UINT16(data + 2));
+		_baseVars = (uint16 *)(buf + READ_SCI11ENDIAN_UINT16(data + 4));
+		_baseMethod = (uint16 *)(buf + READ_SCI11ENDIAN_UINT16(data + 6));
+		_methodCount = READ_SCI11ENDIAN_UINT16(_baseMethod);
+	}
+
+	for (uint i = 0; i < _variables.size(); i++)
+		_variables[i] = make_reg(0, READ_SCI11ENDIAN_UINT16(data + (i * 2)));
+}
+
 Object *Object::getClass(SegManager *segMan) {
 	return isClass() ? this : segMan->getObject(getSuperClassSelector());
 }
@@ -698,6 +715,81 @@
 	return -1; // Failed
 }
 
+bool Object::relocate(SegmentId segment, int location, size_t scriptSize) {
+	int rel = location - getPos().offset;
+
+	if (rel < 0)
+		return false;
+
+	uint idx = rel >> 1;
+
+	if (idx >= _variables.size())
+		return false;
+
+	if (rel & 1) {
+		warning("Attempt to relocate odd variable #%d.5e (relative to %04x)\n", idx, getPos().offset);
+		return false;
+	}
+	_variables[idx].segment = segment; // Perform relocation
+	if (getSciVersion() >= SCI_VERSION_1_1)
+		_variables[idx].offset += scriptSize;
+
+	return true;
+}
+
+int Object::propertyOffsetToId(SegManager *segMan, int propertyOffset) {
+	int selectors = getVarCount();
+
+	if (propertyOffset < 0 || (propertyOffset >> 1) >= selectors) {
+		warning("Applied propertyOffsetToId to invalid property offset %x (property #%d not in [0..%d])",
+		          propertyOffset, propertyOffset >> 1, selectors - 1);
+		return -1;
+	}
+
+	if (getSciVersion() < SCI_VERSION_1_1) {
+		byte *selectoroffset = ((byte *)(_baseObj)) + SCRIPT_SELECTOR_OFFSET + selectors * 2;
+		return READ_SCI11ENDIAN_UINT16(selectoroffset + propertyOffset);
+	} else {
+		Object *obj = this;
+		if (!(getInfoSelector().offset & SCRIPT_INFO_CLASS))
+			obj = segMan->getObject(getSuperClassSelector());
+
+		return READ_SCI11ENDIAN_UINT16((byte *)obj->_baseVars + propertyOffset);
+	}
+}
+
+void Object::initSpecies(SegManager *segMan, reg_t addr) {
+	uint16 speciesOffset = getSpeciesSelector().offset;
+
+	if (speciesOffset == 0xffff)		// -1
+		setSpeciesSelector(NULL_REG);	// no species
+	else
+		setSpeciesSelector(segMan->getClassAddress(speciesOffset, SCRIPT_GET_LOCK, addr));
+}
+
+void Object::initSuperClass(SegManager *segMan, reg_t addr) {
+	uint16 superClassOffset = getSuperClassSelector().offset;
+
+	if (superClassOffset == 0xffff)			// -1
+		setSuperClassSelector(NULL_REG);	// no superclass
+	else
+		setSuperClassSelector(segMan->getClassAddress(superClassOffset, SCRIPT_GET_LOCK, addr));
+}
+
+bool Object::initBaseObject(SegManager *segMan, reg_t addr) {
+	Object *baseObj = segMan->getObject(getSpeciesSelector());
+
+	if (baseObj) {
+		setVarCount(baseObj->getVarCount());
+		// Copy base from species class, as we need its selector IDs
+		_baseObj = baseObj->_baseObj;
+		initSuperClass(segMan, addr);
+		return true;
+	}
+
+	return false;
+}
+
 //-------------------- dynamic memory --------------------
 
 reg_t DynMem::findCanonicAddress(SegManager *segMan, reg_t addr) {

Modified: scummvm/trunk/engines/sci/engine/segment.h
===================================================================
--- scummvm/trunk/engines/sci/engine/segment.h	2010-05-26 06:53:08 UTC (rev 49227)
+++ scummvm/trunk/engines/sci/engine/segment.h	2010-05-26 08:27:24 UTC (rev 49228)
@@ -270,29 +270,10 @@
 	void setVarCount(uint size) { _variables.resize(size); }
 	uint getVarCount() { return _variables.size(); }
 
-	void init(byte *buf, reg_t obj_pos) {
-		byte *data = (byte *)(buf + obj_pos.offset);
-		_baseObj = data;
-		_pos = obj_pos;
+	void init(byte *buf, reg_t obj_pos);
 
-		if (getSciVersion() < SCI_VERSION_1_1) {
-			_variables.resize(READ_LE_UINT16(data + SCRIPT_SELECTORCTR_OFFSET));
-			_baseVars = (uint16 *)(_baseObj + _variables.size() * 2);
-			_baseMethod = (uint16 *)(data + READ_LE_UINT16(data + SCRIPT_FUNCTAREAPTR_OFFSET));
-			_methodCount = READ_LE_UINT16(_baseMethod - 1);
-		} else {
-			_variables.resize(READ_SCI11ENDIAN_UINT16(data + 2));
-			_baseVars = (uint16 *)(buf + READ_SCI11ENDIAN_UINT16(data + 4));
-			_baseMethod = (uint16 *)(buf + READ_SCI11ENDIAN_UINT16(data + 6));
-			_methodCount = READ_SCI11ENDIAN_UINT16(_baseMethod);
-		}
+	reg_t &getVariable(uint var) { return _variables[var]; }
 
-		for (uint i = 0; i < _variables.size(); i++)
-			_variables[i] = make_reg(0, READ_SCI11ENDIAN_UINT16(data + (i * 2)));
-	}
-
-	reg_t getVariable(uint var) { return _variables[var]; }
-
 	uint16 getMethodCount() { return _methodCount; }
 	reg_t getPos() { return _pos; }
 
@@ -304,13 +285,23 @@
 		_baseVars = obj ? obj->_baseVars : NULL;
 	}
 
+	bool relocate(SegmentId segment, int location, size_t scriptSize);
+
+	int propertyOffsetToId(SegManager *segMan, int propertyOffset);
+
+	void initSpecies(SegManager *segMan, reg_t addr);
+	void initSuperClass(SegManager *segMan, reg_t addr);
+	bool initBaseObject(SegManager *segMan, reg_t addr);
+
 	// TODO: make private
-	Common::Array<reg_t> _variables;
+	// Only SegManager::reconstructScripts() is left needing direct access to these
+public:
 	byte *_baseObj; /**< base + object offset within base */
 	uint16 *_baseVars; /**< Pointer to the varselector area for this object */
 	uint16 *_baseMethod; /**< Pointer to the method selector area for this object */
 
 private:
+	Common::Array<reg_t> _variables;
 	uint16 _methodCount;
 	int _flags;
 	uint16 _offset;
@@ -414,7 +405,6 @@
 private:
 	int relocateLocal(SegmentId segment, int location);
 	int relocateBlock(Common::Array<reg_t> &block, int block_location, SegmentId segment, int location);
-	int relocateObject(Object &obj, SegmentId segment, int location);
 
 public:
 	// script lock operations

Modified: scummvm/trunk/engines/sci/engine/vm.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/vm.cpp	2010-05-26 06:53:08 UTC (rev 49227)
+++ scummvm/trunk/engines/sci/engine/vm.cpp	2010-05-26 08:27:24 UTC (rev 49228)
@@ -120,7 +120,7 @@
 		return dummyReg;
 	}
 
-	return obj->_variables[index];
+	return obj->getVariable(index);
 }
 
 static StackPtr validate_stack_addr(EngineState *s, StackPtr sp) {
@@ -1758,8 +1758,7 @@
 
 reg_t* ObjVarRef::getPointer(SegManager *segMan) const {
 	Object *o = segMan->getObject(obj);
-	if (!o) return 0;
-	return &(o->_variables[varindex]);
+	return o ? &o->getVariable(varindex) : 0;
 }
 
 reg_t* ExecStack::getVarPointer(SegManager *segMan) const {


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