[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