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

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Tue Sep 22 02:36:24 CEST 2009


Revision: 44244
          http://scummvm.svn.sourceforge.net/scummvm/?rev=44244&view=rev
Author:   fingolfin
Date:     2009-09-22 00:36:24 +0000 (Tue, 22 Sep 2009)

Log Message:
-----------
SCI: Add new type SegmentRef which ultimately will allow us to distinguish between raw and 'reg_t' memory blocks in client code

Modified Paths:
--------------
    scummvm/trunk/engines/sci/console.cpp
    scummvm/trunk/engines/sci/engine/seg_manager.cpp
    scummvm/trunk/engines/sci/engine/seg_manager.h
    scummvm/trunk/engines/sci/engine/segment.cpp
    scummvm/trunk/engines/sci/engine/segment.h

Modified: scummvm/trunk/engines/sci/console.cpp
===================================================================
--- scummvm/trunk/engines/sci/console.cpp	2009-09-22 00:36:05 UTC (rev 44243)
+++ scummvm/trunk/engines/sci/console.cpp	2009-09-22 00:36:24 UTC (rev 44244)
@@ -1951,7 +1951,8 @@
 			break;
 		case KSIG_REF: {
 			int size;
-			byte *block = _vm->_gamestate->segMan->dereference(reg, &size);
+			const SegmentRef block = _vm->_gamestate->segMan->dereference(reg);
+			size = block.maxSize;
 
 			DebugPrintf("raw data\n");
 
@@ -1966,7 +1967,7 @@
 			if (reg_end.segment != 0)
 				DebugPrintf("Block size less than or equal to %d\n", size);
 
-			Common::hexdump(block, size, 16, 0);
+			Common::hexdump(block.raw, size, 16, 0);
 			}
 			break;
 		case KSIG_ARITHMETIC:
@@ -2248,8 +2249,8 @@
 		return true;
 	}
 
-	_vm->_gamestate->segMan->dereference(vpc, &size);
-	size += vpc.offset; // total segment size
+	SegmentRef ref = _vm->_gamestate->segMan->dereference(vpc);
+	size = ref.maxSize + vpc.offset; // total segment size
 
 	for (int i = 2; i < argc; i++) {
 		if (!scumm_stricmp(argv[i], "bwt"))

Modified: scummvm/trunk/engines/sci/engine/seg_manager.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/seg_manager.cpp	2009-09-22 00:36:05 UTC (rev 44243)
+++ scummvm/trunk/engines/sci/engine/seg_manager.cpp	2009-09-22 00:36:24 UTC (rev 44244)
@@ -863,29 +863,30 @@
 	return &(table->_table[offset]);
 }
 
-byte *SegManager::dereference(reg_t pointer, int *size) {
+SegmentRef SegManager::dereference(reg_t pointer) {
+	SegmentRef ret;
+
 	if (!pointer.segment || (pointer.segment >= _heap.size()) || !_heap[pointer.segment]) {
 		// This occurs in KQ5CD when interacting with certain objects
 		warning("Attempt to dereference invalid pointer %04x:%04x", PRINT_REG(pointer));
-		return NULL; /* Invalid */
+		return ret; /* Invalid */
 	}
 
 	SegmentObj *mobj = _heap[pointer.segment];
-	return mobj->dereference(pointer, size);
+	return mobj->dereference(pointer);
 }
 
 static void *_kernel_dereference_pointer(SegManager *segMan, reg_t pointer, int entries) {
-	int maxsize;
-	void *retval = segMan->dereference(pointer, &maxsize);
+	SegmentRef ret = segMan->dereference(pointer);
 
-	if (!retval)
+	if (!ret.raw)
 		return NULL;
 
-	if (entries > maxsize) {
+	if (entries > ret.maxSize) {
 		warning("Trying to dereference pointer %04x:%04x beyond end of segment", PRINT_REG(pointer));
 		return NULL;
 	}
-	return retval;
+	return ret.raw;
 
 }
 

Modified: scummvm/trunk/engines/sci/engine/seg_manager.h
===================================================================
--- scummvm/trunk/engines/sci/engine/seg_manager.h	2009-09-22 00:36:05 UTC (rev 44243)
+++ scummvm/trunk/engines/sci/engine/seg_manager.h	2009-09-22 00:36:24 UTC (rev 44244)
@@ -279,10 +279,9 @@
 	/**
 	 * Dereferences a raw memory pointer
 	 * @param[in]  reg	The reference to dereference
-	 * @param[out] size	(optional) The theoretical maximum size
 	 * @return			The data block referenced
 	 */
-	byte *dereference(reg_t reg, int *size);
+	SegmentRef dereference(reg_t pointer);
 
 	/**
 	 * Dereferences a heap pointer pointing to raw memory.

Modified: scummvm/trunk/engines/sci/engine/segment.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/segment.cpp	2009-09-22 00:36:05 UTC (rev 44243)
+++ scummvm/trunk/engines/sci/engine/segment.cpp	2009-09-22 00:36:24 UTC (rev 44244)
@@ -214,79 +214,97 @@
 //	return (_buf[offset] | (_buf[offset+1]) << 8);
 }
 
-byte *SegmentObj::dereference(reg_t pointer, int *size) {
+SegmentRef SegmentObj::dereference(reg_t pointer) {
 	error("Error: Trying to dereference pointer %04x:%04x to inappropriate segment",
 		          PRINT_REG(pointer));
-	return NULL;
+	return SegmentRef();
 }
 
 bool Script::isValidOffset(uint16 offset) const {
 	return offset < _bufSize;
 }
 
-byte *Script::dereference(reg_t pointer, int *size) {
+SegmentRef Script::dereference(reg_t pointer) {
 	if (pointer.offset > _bufSize) {
-		warning("Attempt to dereference invalid pointer %04x:%04x into script segment (script size=%d)\n",
+		warning("Attempt to dereference invalid pointer %04x:%04x into script segment (script size=%d)",
 				  PRINT_REG(pointer), (uint)_bufSize);
-		return NULL;
+		return SegmentRef();
 	}
-	if (size)
-		*size = _bufSize - pointer.offset;
-	return _buf + pointer.offset;
+
+	SegmentRef ret;
+	ret.isRaw = true;
+	ret.maxSize = _bufSize - pointer.offset;
+	ret.raw = _buf + pointer.offset;
+	return ret;
 }
 
 bool LocalVariables::isValidOffset(uint16 offset) const {
 	return offset < _locals.size() * sizeof(reg_t);
 }
 
-byte *LocalVariables::dereference(reg_t pointer, int *size) {
-	if (size)
-		*size = _locals.size() * sizeof(reg_t);
-
+SegmentRef LocalVariables::dereference(reg_t pointer) {
 	// FIXME: The following doesn't seem to be endian safe.
 	// To fix this, we'd have to always treat the reg_t
 	// values stored here as in the little endian format.
-	byte *base = (byte *)&_locals[0];
-	return base + pointer.offset;
+	// Anyway, generate a warning for now to see if this ever
+	// happens.
+	// One has to wonder whether we return the right value anyway.
+	// Here are three potential options:
+	//   1:  ((byte *)&_locals[0]) + pointer.offset
+	//   2:  ((byte *)&_locals[pointer.offset/2]) + (pointer.offset % 2)
+	//   3:  ((byte *)&_locals[pointer.offset])
+	// So which one is correct? :)
+	if (pointer.offset & 1)
+		warning("LocalVariables::dereference: Odd offset in pointer  %04x:%04x", PRINT_REG(pointer));
+
+	SegmentRef ret;
+	ret.isRaw = false;	// reg_t based data!
+	ret.maxSize = _locals.size() * sizeof(reg_t);
+	ret.raw = (byte *)&_locals[0] + pointer.offset;
+	return ret;
 }
 
 bool DataStack::isValidOffset(uint16 offset) const {
 	return offset < _capacity * sizeof(reg_t);
 }
 
-byte *DataStack::dereference(reg_t pointer, int *size) {
-	if (size)
-		*size = _capacity * sizeof(reg_t);
-
-	byte *base = (byte *)_entries;
-	return base + pointer.offset;
+SegmentRef DataStack::dereference(reg_t pointer) {
+	SegmentRef ret;
+	ret.isRaw = false;	// reg_t based data!
+	ret.maxSize = _capacity * sizeof(reg_t);
+	// FIXME: Is this correct? See comment in LocalVariables::dereference
+	ret.raw = (byte *)_entries + pointer.offset;
+	return ret;
 }
 
 bool DynMem::isValidOffset(uint16 offset) const {
 	return offset < _size;
 }
 
-byte *DynMem::dereference(reg_t pointer, int *size) {
-	if (size)
-		*size = _size;
-
-	byte *base = (byte *)_buf;
-	return base + pointer.offset;
+SegmentRef DynMem::dereference(reg_t pointer) {
+	SegmentRef ret;
+	ret.isRaw = true;
+	ret.maxSize = _size;
+	ret.raw = _buf + pointer.offset;
+	return ret;
 }
 
 bool SystemStrings::isValidOffset(uint16 offset) const {
 	return offset < SYS_STRINGS_MAX && !strings[offset]._name.empty();
 }
 
-byte *SystemStrings::dereference(reg_t pointer, int *size) {
-	if (size)
-		*size = strings[pointer.offset].max_size;
+SegmentRef SystemStrings::dereference(reg_t pointer) {
+	SegmentRef ret;
+	ret.isRaw = false;	// FIXME: Raw or not raw? the sys strings code is totally incoherent in this regard
+	ret.maxSize = strings[pointer.offset].max_size;
 	if (isValidOffset(pointer.offset))
-		return (byte *)(strings[pointer.offset].value);
+		ret.raw = (byte *)(strings[pointer.offset].value);
+	else {
+		// This occurs in KQ5CD when interacting with certain objects
+		warning("Attempt to dereference invalid pointer %04x:%04x", PRINT_REG(pointer));
+	}
 
-	// This occurs in KQ5CD when interacting with certain objects
-	warning("Attempt to dereference invalid pointer %04x:%04x", PRINT_REG(pointer));
-	return NULL;
+	return ret;
 }
 
 

Modified: scummvm/trunk/engines/sci/engine/segment.h
===================================================================
--- scummvm/trunk/engines/sci/engine/segment.h	2009-09-22 00:36:05 UTC (rev 44243)
+++ scummvm/trunk/engines/sci/engine/segment.h	2009-09-22 00:36:24 UTC (rev 44244)
@@ -34,6 +34,23 @@
 
 namespace Sci {
 
+struct SegmentRef {
+	bool isRaw;	///! true if data is raw, false if it is a reg_t sequence
+	union {
+		byte *raw;
+		reg_t *reg;
+	};
+	int maxSize;	///! number of available bytes
+	// TODO: Add this?
+	//reg_t pointer;	// Original pointer
+
+	// TODO: Add this?
+	//SegmentType type;
+
+	SegmentRef() : isRaw(true), raw(0), maxSize(0) {}
+};
+
+
 enum SegmentType {
 	SEG_TYPE_INVALID = 0,
 	SEG_TYPE_SCRIPT = 1,
@@ -73,10 +90,9 @@
 	/**
 	 * Dereferences a raw memory pointer.
 	 * @param reg	reference to dereference
-	 * @param size	if not NULL, set to the theoretical maximum size of the referenced data block
 	 * @return		the data block referenced
 	 */
-	virtual byte *dereference(reg_t pointer, int *size);
+	virtual SegmentRef dereference(reg_t pointer);
 
 	/**
 	 * Finds the canonic address associated with sub_reg.
@@ -161,7 +177,7 @@
 	}
 
 	virtual bool isValidOffset(uint16 offset) const;
-	virtual byte *dereference(reg_t pointer, int *size);
+	virtual SegmentRef dereference(reg_t pointer);
 
 	virtual void saveLoadWithSerializer(Common::Serializer &ser);
 };
@@ -176,7 +192,7 @@
 	}
 
 	virtual bool isValidOffset(uint16 offset) const;
-	virtual byte *dereference(reg_t pointer, int *size);
+	virtual SegmentRef dereference(reg_t pointer);
 	virtual reg_t findCanonicAddress(SegManager *segMan, reg_t sub_addr);
 	virtual void listAllOutgoingReferences(reg_t object, void *param, NoteCallback note);
 
@@ -309,7 +325,7 @@
 	bool init(int script_nr, ResourceManager *resMan);
 
 	virtual bool isValidOffset(uint16 offset) const;
-	virtual byte *dereference(reg_t pointer, int *size);
+	virtual SegmentRef dereference(reg_t pointer);
 	virtual reg_t findCanonicAddress(SegManager *segMan, reg_t sub_addr);
 	virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr);
 	virtual void listAllDeallocatable(SegmentId segId, void *param, NoteCallback note);
@@ -467,7 +483,7 @@
 	}
 
 	virtual bool isValidOffset(uint16 offset) const;
-	virtual byte *dereference(reg_t pointer, int *size);
+	virtual SegmentRef dereference(reg_t pointer);
 	virtual reg_t findCanonicAddress(SegManager *segMan, reg_t sub_addr);
 	virtual void listAllOutgoingReferences(reg_t object, void *param, NoteCallback note);
 
@@ -624,7 +640,7 @@
 	}
 
 	virtual bool isValidOffset(uint16 offset) const;
-	virtual byte *dereference(reg_t pointer, int *size);
+	virtual SegmentRef dereference(reg_t pointer);
 	virtual reg_t findCanonicAddress(SegManager *segMan, reg_t sub_addr);
 	virtual void listAllDeallocatable(SegmentId segId, void *param, NoteCallback note);
 


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