[Scummvm-git-logs] scummvm master -> 34246e25ccc2023008eb267f64776541d24c7887

neuromancer noreply at scummvm.org
Sun Aug 13 19:00:40 UTC 2023


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
34246e25cc FREESCAPE: refactored group parsing code


Commit: 34246e25ccc2023008eb267f64776541d24c7887
    https://github.com/scummvm/scummvm/commit/34246e25ccc2023008eb267f64776541d24c7887
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-08-13T20:56:45+02:00

Commit Message:
FREESCAPE: refactored group parsing code

Changed paths:
    engines/freescape/freescape.h
    engines/freescape/loaders/8bitBinaryLoader.cpp
    engines/freescape/objects/group.cpp
    engines/freescape/objects/group.h


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 041bdf0ef57..443a21def1e 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -192,12 +192,14 @@ public:
 	Common::Event decodeDOSMouseEvent(int code, int repetition);
 
 	uint16 readField(Common::SeekableReadStream *file, int nbits);
+	uint16 readPtr(Common::SeekableReadStream *file);
 	Common::Array<uint16> readArray(Common::SeekableReadStream *file, int size);
 
 	// 8-bit
 	void load8bitBinary(Common::SeekableReadStream *file, int offset, int ncolors);
 	Area *load8bitArea(Common::SeekableReadStream *file, uint16 ncolors);
 	Object *load8bitObject(Common::SeekableReadStream *file);
+	Group *load8bitGroup(Common::SeekableReadStream *file, byte rawFlagsAndType);
 	void loadGlobalObjects(Common::SeekableReadStream *file, int offset, int size);
 	void renderPixels8bitBinImage(Graphics::ManagedSurface *surface, int &i, int &j, uint8 pixels, int color);
 
diff --git a/engines/freescape/loaders/8bitBinaryLoader.cpp b/engines/freescape/loaders/8bitBinaryLoader.cpp
index 473ff8e1541..d0c4b93fc4a 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -31,17 +31,26 @@
 
 namespace Freescape {
 
+uint16 FreescapeEngine::readPtr(Common::SeekableReadStream *file) {
+	uint16 value;
+	if (isAmiga() || isAtariST()) {
+		uint16 lo = file->readUint16BE();
+		assert(lo < 256);
+		uint16 hi = file->readUint16BE();
+		assert(hi < 256);
+		value = 256 * hi + lo;
+		value = 2 * value;
+	} else
+		value = file->readUint16LE();
+	return value;
+}
+
 uint16 FreescapeEngine::readField(Common::SeekableReadStream *file, int bits) {
 	uint16 value;
 	assert(bits == 8 || bits == 16);
 	if (isAmiga() || isAtariST()) {
 		if (bits == 16) {
-			uint16 lo = file->readUint16BE();
-			assert(lo < 256);
-			uint16 hi = file->readUint16BE();
-			assert(hi < 256);
-			value = 256 * hi + lo;
-			value = 2 * value; // Unclear why, but this reads a pointer
+			value = file->readUint16BE();
 		} else {
 			assert(bits == 8);
 			value = file->readUint16BE();
@@ -73,12 +82,96 @@ Common::Array<uint16> FreescapeEngine::readArray(Common::SeekableReadStream *fil
 	return array;
 }
 
+Group *FreescapeEngine::load8bitGroup(Common::SeekableReadStream *file, byte rawFlagsAndType) {
+	debugC(1, kFreescapeDebugParser, "Object of type 'group'");
+	Common::Array<uint16> groupObjects = readArray(file, 6);
+
+	// object ID
+	uint16 objectID = readField(file, 8);
+	// size of object on disk; we've accounted for 8 bytes
+	// already so we can subtract that to get the remaining
+	// length beyond here
+	uint8 byteSizeOfObject = readField(file, 8);
+	debugC(1, kFreescapeDebugParser, "Raw object %d ; type group ; size %d", objectID, byteSizeOfObject);
+	if (byteSizeOfObject < 9) {
+		error("Not enough bytes %d to read object %d with type group", byteSizeOfObject, objectID);
+	}
+
+	assert(byteSizeOfObject >= 9);
+	byteSizeOfObject = byteSizeOfObject - 9;
+
+	for (int i = 0; i < 3; i++) {
+		uint16 value = 0;
+		if (isAmiga() || isAtariST())
+			value = readField(file, 16);
+		else
+			value = readField(file, 8);
+		groupObjects.push_back(value);
+	}
+
+	byteSizeOfObject = byteSizeOfObject - 3;
+	for (int i = 0; i < 9; i++)
+		debugC(1, kFreescapeDebugParser, "Group object[%d] = %d", i, groupObjects[i]);
+
+	Common::Array<uint16> groupOperations;
+	Common::Array<Math::Vector3d> groupPositions;
+	while (byteSizeOfObject > 0) {
+		uint16 operation = 0;
+		if (isAmiga() || isAtariST())
+			operation = readField(file, 16);
+		else
+			operation = readField(file, 8);
+
+		byteSizeOfObject--;
+		Math::Vector3d position;
+		if (operation == 0x80) {
+			debugC(1, kFreescapeDebugParser, "Group operation rewind");
+		} else if (operation == 0x01) {
+			debugC(1, kFreescapeDebugParser, "Group operation script execution");
+			FCLInstructionVector instructions;
+			// get the length
+			uint32 lengthOfCondition = readField(file, 8);
+			assert(lengthOfCondition > 0);
+			byteSizeOfObject--;
+			debugC(1, kFreescapeDebugParser, "Length of condition: %d at %lx", lengthOfCondition, long(file->pos()));
+			// get the condition
+			Common::Array<uint16> conditionArray = readArray(file, lengthOfCondition);
+			Common::String conditionSource = detokenise8bitCondition(conditionArray, instructions, isAmiga() || isAtariST());
+			debugC(1, kFreescapeDebugParser, "%s", conditionSource.c_str());
+			byteSizeOfObject = byteSizeOfObject - lengthOfCondition;
+		} else {
+			if (byteSizeOfObject >= 3) {
+				position.x() = readField(file, 8);
+				position.y() = readField(file, 8);
+				position.z() = readField(file, 8);
+				debugC(1, kFreescapeDebugParser, "Group operation %d move to: %f %f %f", operation, position.x(), position.y(), position.z());
+				byteSizeOfObject = byteSizeOfObject - 3;
+			} else {
+				byteSizeOfObject = 0;
+				continue;
+			}
+		}
+		groupOperations.push_back(operation);
+		groupPositions.push_back(position);
+	}
+
+	return new Group(
+		objectID,
+		rawFlagsAndType,
+		groupObjects,
+		groupOperations,
+		groupPositions);
+}
+
 Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 
 	byte rawFlagsAndType = readField(file, 8);
 	debugC(1, kFreescapeDebugParser, "Raw object data flags and type: %d", rawFlagsAndType);
 	ObjectType objectType = (ObjectType)(rawFlagsAndType & 0x1F);
 
+	if (objectType == ObjectType::kGroupType)
+		return load8bitGroup(file, rawFlagsAndType);
+
 	Math::Vector3d position, v;
 
 	position.x() = readField(file, 8);
@@ -267,7 +360,7 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 		byte color = readField(file, 8) & 0xf;
 		assert(color > 0);
 		byte firingInterval = readField(file, 8);
-		uint16 firingRange = readField(file, 16) / 2;
+		uint16 firingRange = readPtr(file) / 2;
 		if (isDark())
 			firingRange = firingRange / 2;
 		byte sensorAxis = readField(file, 8);
@@ -295,33 +388,7 @@ Object *FreescapeEngine::load8bitObject(Common::SeekableReadStream *file) {
 	} break;
 
 	case kGroupType:
-		debugC(1, kFreescapeDebugParser, "Object of type 'group'");
-		Common::Array<uint8> groupDataArray;
-		groupDataArray.push_back(uint8(position.x()));
-		groupDataArray.push_back(uint8(position.y()));
-		groupDataArray.push_back(uint8(position.z()));
-
-		groupDataArray.push_back(uint8(v.x()));
-		groupDataArray.push_back(uint8(v.y()));
-		groupDataArray.push_back(uint8(v.z()));
-
-		byteSizeOfObject++;
-		while(--byteSizeOfObject > 0)
-			if (isAmiga() || isAtariST()) {
-				uint16 field = file->readUint16BE();
-				if (isCastle())
-					assert(field >> 8 == 0);
-				else
-					groupDataArray.push_back(field >> 8);
-
-				groupDataArray.push_back(field & 0xff);
-			} else
-				groupDataArray.push_back(readField(file, 8));
-
-		return new Group(
-			objectID,
-			rawFlagsAndType,
-			groupDataArray);
+		error("Unreachable");
 		break;
 	}
 	// Unreachable
@@ -445,7 +512,7 @@ Area *FreescapeEngine::load8bitArea(Common::SeekableReadStream *file, uint16 nco
 	uint8 numberOfObjects = readField(file, 8);
 	uint8 areaNumber = readField(file, 8);
 
-	uint16 cPtr = readField(file, 16);
+	uint16 cPtr = readPtr(file);
 	debugC(1, kFreescapeDebugParser, "Condition pointer: %x", cPtr);
 	uint8 scale = readField(file, 8);
 	debugC(1, kFreescapeDebugParser, "Scale: %d", scale);
@@ -618,7 +685,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 			numberOfAreas = isDemo() ? 87 : 104;
 	}
 
-	uint32 dbSize = readField(file, 16);
+	uint32 dbSize = readPtr(file);
 	debugC(1, kFreescapeDebugParser, "Database ends at %x", dbSize);
 
 	uint8 startArea = readField(file, 8);
@@ -669,11 +736,11 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 		file->seek(offset + 0x46);
 
 	uint16 demoDataTable;
-	demoDataTable = readField(file, 16);
+	demoDataTable = readPtr(file);
 	debugC(1, kFreescapeDebugParser, "Pointer to demo data: %x\n", demoDataTable);
 
 	uint16 globalByteCodeTable;
-	globalByteCodeTable = readField(file, 16);
+	globalByteCodeTable = readPtr(file);
 	debugC(1, kFreescapeDebugParser, "GBCT: %x\n", globalByteCodeTable);
 
 	if (isDOS())
@@ -743,7 +810,7 @@ void FreescapeEngine::load8bitBinary(Common::SeekableReadStream *file, int offse
 	debugC(1, kFreescapeDebugParser, "areas index at: %lx", long(file->pos()));
 	uint16 *fileOffsetForArea = new uint16[numberOfAreas];
 	for (uint16 area = 0; area < numberOfAreas; area++) {
-		fileOffsetForArea[area] = readField(file, 16);
+		fileOffsetForArea[area] = readPtr(file);
 		debugC(1, kFreescapeDebugParser, "offset: %x", fileOffsetForArea[area]);
 	}
 
diff --git a/engines/freescape/objects/group.cpp b/engines/freescape/objects/group.cpp
index 8e4e46595f2..d2cbd77efaa 100644
--- a/engines/freescape/objects/group.cpp
+++ b/engines/freescape/objects/group.cpp
@@ -25,7 +25,10 @@
 
 namespace Freescape {
 
-Group::Group(uint16 objectID_, uint16 flags_, const Common::Array<byte> data_) {
+Group::Group(uint16 objectID_, uint16 flags_,
+const Common::Array<uint16> objectIds_,
+const Common::Array<uint16> objectOperations_,
+const Common::Array<Math::Vector3d> objectPositions_) {
 	_objectID = objectID_;
 	_flags = flags_;
 	_scale = 0;
@@ -33,47 +36,9 @@ Group::Group(uint16 objectID_, uint16 flags_, const Common::Array<byte> data_) {
 	_finished = false;
 	_step = 0;
 
-	int i;
-	for (i = 0; i < 5; i++) {
-		debugC(1, kFreescapeDebugParser, "group data[%d] = %d", i, data_[i]);
-		if (data_[i] > 0)
-			_objectIds.push_back(data_[i]);
-	}
-	for (i = 5; i < 9; i++)
-		debugC(1, kFreescapeDebugParser, "group data[%d] = %d", i, data_[i]);
-	i = 9;
-	while (i < int(data_.size())) {
-		int operation = data_[i];
-		_objectOperations.push_back(operation);
-		debugC(1, kFreescapeDebugParser, "group data[%d] = %d (operation)", i, operation);
-		if (operation == 0x80) {
-			i++;
-			_objectPositions.push_back(Math::Vector3d());
-		} else if (operation == 0x01) {
-			i++;
-			int scriptSize = data_[i];
-			assert(scriptSize > 0);
-			Common::Array<uint16> conditionData;
-			FCLInstructionVector instructions;
-			for (int j = i + 1; j < i + 1 + scriptSize && j < int(data_.size()); j++) {
-				conditionData.push_back(data_[j]);
-			}
-			Common::String conditionStr = detokenise8bitCondition(conditionData, instructions, false);
-			debugC(1, kFreescapeDebugParser, "group condition:\n%s", conditionStr.c_str());
-			_objectPositions.push_back(Math::Vector3d());
-			i = i + 1 + scriptSize;
-		} else {
-			if (i < int(data_.size() - 4)) {
-				debugC(1, kFreescapeDebugParser, "group data[%d] = %d", i + 1, data_[i + 1]);
-				debugC(1, kFreescapeDebugParser, "group data[%d] = %d", i + 2, data_[i + 2]);
-				debugC(1, kFreescapeDebugParser, "group data[%d] = %d", i + 3, data_[i + 3]);
-				Math::Vector3d position(data_[i + 1], data_[i + 2], data_[i + 3]);
-				_objectPositions.push_back(position);
-			} else
-				_objectOperations.pop_back();
-			i = i + 4;
-		}
-	}
+	_objectIds = objectIds_;
+	_objectOperations = objectOperations_;
+	_objectPositions = objectPositions_;
 
 	if (isDestroyed()) // If the object is destroyed, restore it
 		restore();
diff --git a/engines/freescape/objects/group.h b/engines/freescape/objects/group.h
index 2f2b07975b6..b691d6b2899 100644
--- a/engines/freescape/objects/group.h
+++ b/engines/freescape/objects/group.h
@@ -29,7 +29,10 @@ namespace Freescape {
 
 class Group : public Object {
 public:
-	Group(uint16 objectID_, uint16 flags_, const Common::Array<byte> data_);
+	Group(uint16 objectID_, uint16 flags_,
+		const Common::Array<uint16> objectIds_,
+		const Common::Array<uint16> objectOperations_,
+		const Common::Array<Math::Vector3d> objectPositions_);
 	void linkObject(Object *obj);
 	void assemble(int index);
 	void step();
@@ -39,8 +42,8 @@ public:
 	Common::Array<Object *> _objects;
 	Common::Array<Math::Vector3d> _origins;
 	Common::Array<Math::Vector3d> _objectPositions;
-	Common::Array<int16> _objectOperations;
-	Common::Array<int16> _objectIds;
+	Common::Array<uint16> _objectOperations;
+	Common::Array<uint16> _objectIds;
 	int _scale;
 	int _step;
 	bool _active;




More information about the Scummvm-git-logs mailing list