[Scummvm-git-logs] scummvm master -> f7710a5cbed8b2e7bcef587bd28e3a43f411ba24

neuromancer noreply at scummvm.org
Wed Aug 16 06:02:50 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:
f7710a5cbe FREESCAPE: implemented group parsing for dark


Commit: f7710a5cbed8b2e7bcef587bd28e3a43f411ba24
    https://github.com/scummvm/scummvm/commit/f7710a5cbed8b2e7bcef587bd28e3a43f411ba24
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2023-08-16T08:02:28+02:00

Commit Message:
FREESCAPE: implemented group parsing for dark

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


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 443a21def1e..a86f0f85f88 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -200,6 +200,9 @@ public:
 	Area *load8bitArea(Common::SeekableReadStream *file, uint16 ncolors);
 	Object *load8bitObject(Common::SeekableReadStream *file);
 	Group *load8bitGroup(Common::SeekableReadStream *file, byte rawFlagsAndType);
+	Group *load8bitGroupV1(Common::SeekableReadStream *file, byte rawFlagsAndType);
+	Group *load8bitGroupV2(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 5e2f52db0f1..cb371d457d2 100644
--- a/engines/freescape/loaders/8bitBinaryLoader.cpp
+++ b/engines/freescape/loaders/8bitBinaryLoader.cpp
@@ -83,6 +83,94 @@ Common::Array<uint16> FreescapeEngine::readArray(Common::SeekableReadStream *fil
 }
 
 Group *FreescapeEngine::load8bitGroup(Common::SeekableReadStream *file, byte rawFlagsAndType) {
+	if (isDark())
+		return load8bitGroupV1(file, rawFlagsAndType);
+	else
+		return load8bitGroupV2(file, rawFlagsAndType);
+}
+
+Group *FreescapeEngine::load8bitGroupV1(Common::SeekableReadStream *file, byte rawFlagsAndType) {
+	debugC(1, kFreescapeDebugParser, "Object of type 'group'");
+	Common::Array<AnimationOpcode *> animation;
+	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 value = 0;
+		if (isAmiga() || isAtariST())
+			value = readField(file, 16);
+		else
+			value = readField(file, 8);
+
+		int opcode = value >> 8;
+		AnimationOpcode* operation = new AnimationOpcode(opcode);
+		byteSizeOfObject--;
+		if (opcode == 0xff) {
+			debugC(1, kFreescapeDebugParser, "Group operation rewind");
+		} else if (opcode == 0x01) {
+			debugC(1, kFreescapeDebugParser, "Group operation script execution");
+			// get the length
+			uint32 lengthOfCondition = value & 0xff;
+			assert(lengthOfCondition > 0);
+			debugC(1, kFreescapeDebugParser, "Length of condition: %d at %lx", lengthOfCondition, long(file->pos()));
+			// get the condition
+			Common::Array<uint16> conditionArray = readArray(file, lengthOfCondition);
+			operation->conditionSource = detokenise8bitCondition(conditionArray, operation->condition, isAmiga() || isAtariST());
+			debugC(1, kFreescapeDebugParser, "%s", operation->conditionSource.c_str());
+			byteSizeOfObject = byteSizeOfObject - lengthOfCondition;
+		} else {
+			if (byteSizeOfObject >= 1) {
+				operation->position.x() = value >> 8;
+				operation->position.y() = file->readByte();
+				operation->position.z() = file->readByte();
+				debugC(1, kFreescapeDebugParser, "Group operation %d move to: %f %f %f", opcode, operation->position.x(), operation->position.y(), operation->position.z());
+				byteSizeOfObject = byteSizeOfObject - 1;
+			} else {
+				debugC(1, kFreescapeDebugParser, "Incomplete group operation %d", opcode);
+				byteSizeOfObject = 0;
+				continue;
+			}
+		}
+		animation.push_back(operation);
+	}
+
+	return new Group(
+		objectID,
+		rawFlagsAndType,
+		groupObjects,
+		animation);
+}
+
+
+Group *FreescapeEngine::load8bitGroupV2(Common::SeekableReadStream *file, byte rawFlagsAndType) {
 	debugC(1, kFreescapeDebugParser, "Object of type 'group'");
 	Common::Array<AnimationOpcode *> animation;
 	Common::Array<uint16> groupObjects = readArray(file, 6);
diff --git a/engines/freescape/objects/group.cpp b/engines/freescape/objects/group.cpp
index e2f183503ea..4e6c51f29b4 100644
--- a/engines/freescape/objects/group.cpp
+++ b/engines/freescape/objects/group.cpp
@@ -35,7 +35,12 @@ const Common::Array<AnimationOpcode *> operations_) {
 	_finished = false;
 	_step = 0;
 
-	_objectIds = objectIds_;
+	for (int i = 0; i < int(objectIds_.size()); i++) {
+		if (objectIds_[i] == 0 || objectIds_[i] == 0xffff)
+			break;
+		_objectIds.push_back(objectIds_[i]);
+	}
+
 	_operations = operations_;
 
 	if (isDestroyed()) // If the object is destroyed, restore it
@@ -90,14 +95,18 @@ void Group::run() {
 }
 
 void Group::run(int index) {
-	if (_operations[_step]->opcode == 0x80) {
+	if (_step < 0)
+		return;
+
+	int opcode = _operations[_step]->opcode;
+	if (opcode == 0x80 || opcode == 0xff) {
 		_step = -1;
 		_active = false;
 		_finished = false;
-	} else if (_operations[_step]->opcode == 0x01) {
+	} else if (opcode == 0x01) {
 		g_freescape->executeCode(_operations[_step]->condition, false, true, false, false);
 	} else {
-		if (_operations[_step]->opcode == 0x10)
+		if (opcode == 0x10)
 			if (!_active) {
 				_step = -1;
 				return;




More information about the Scummvm-git-logs mailing list