[Scummvm-git-logs] scummvm master -> 1af583e6bd2c5244022c784f83e81ffc1972f0ee
mgerhardy
martin.gerhardy at gmail.com
Sat Mar 27 12:35:47 UTC 2021
This automated email contains information about 19 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
d8f8de5601 TWINE: renamed struct to I16Vec3
e637781769 TWINE: moved I16Vec3 into shared header
5fcaf25b48 TWINE: changed function return type of getVerticesBaseData
d137e3c52a TWINE: use BodyShade for getShadesBaseData
0c8305f53b TWINE: reduced visibility
a3acbceae9 TWINE: renamed method
22f040bab5 TWINE: removed cast
19d71f081b TWINE: use size of structs
cf587e5d80 TWINE: reduced visibility
cdc6281bd0 TWINE: extracted to methods
33371ae454 TWINE: use BodyData for rendering
b081f3e711 TWINE: doxygen
8c76c1fac7 TWINE: use EntityData
7cfb6f00d5 TWINE: updated actor bbox code and minor cleanup
fca24a4eb7 TWINE: use I16Vec3 in animation code
e0ba8d1d74 TWINE: use IVec3 and minor cleanup
750128b2cb TWINE: minor cleanup
b6b9cd5fbd TWINE: use IVec3 for bounding box checks
1af583e6bd TWINE: optimized renderPolygons by not looping twice over all the vertices
Commit: d8f8de5601f2a0fc9e27484b0902425878e94c73
https://github.com/scummvm/scummvm/commit/d8f8de5601f2a0fc9e27484b0902425878e94c73
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2021-03-27T13:35:27+01:00
Commit Message:
TWINE: renamed struct to I16Vec3
Changed paths:
engines/twine/renderer/renderer.cpp
engines/twine/renderer/renderer.h
diff --git a/engines/twine/renderer/renderer.cpp b/engines/twine/renderer/renderer.cpp
index c7dd869e67..9327ce4ccb 100644
--- a/engines/twine/renderer/renderer.cpp
+++ b/engines/twine/renderer/renderer.cpp
@@ -313,7 +313,7 @@ void Renderer::applyRotation(IMatrix3x3 *targetMatrix, const IMatrix3x3 *current
}
}
-void Renderer::applyPointsRotation(const pointTab *pointsPtr, int32 numPoints, pointTab *destPoints, const IMatrix3x3 *rotationMatrix) {
+void Renderer::applyPointsRotation(const I16Vec3 *pointsPtr, int32 numPoints, I16Vec3 *destPoints, const IMatrix3x3 *rotationMatrix) {
int32 numOfPoints2 = numPoints;
do {
@@ -330,8 +330,8 @@ void Renderer::applyPointsRotation(const pointTab *pointsPtr, int32 numPoints, p
} while (--numOfPoints2);
}
-void Renderer::processRotatedElement(IMatrix3x3 *targetMatrix, const pointTab *pointsPtr, int32 rotZ, int32 rotY, int32 rotX, const BonesBaseData *boneData, ModelData *modelData) {
- int32 firstPoint = boneData->firstPoint / sizeof(pointTab);
+void Renderer::processRotatedElement(IMatrix3x3 *targetMatrix, const I16Vec3 *pointsPtr, int32 rotZ, int32 rotY, int32 rotX, const BonesBaseData *boneData, ModelData *modelData) {
+ int32 firstPoint = boneData->firstPoint / sizeof(I16Vec3);
int32 numOfPoints2 = boneData->numOfPoints;
IVec3 renderAngle;
@@ -348,7 +348,7 @@ void Renderer::processRotatedElement(IMatrix3x3 *targetMatrix, const pointTab *p
destPos.y = 0;
destPos.z = 0;
} else {
- const int32 pointIdx = boneData->basePoint / sizeof(pointTab);
+ const int32 pointIdx = boneData->basePoint / sizeof(I16Vec3);
const int32 matrixIndex = boneData->baseElement / sizeof(BonesBaseData);
assert(matrixIndex >= 0 && matrixIndex < ARRAYSIZE(_matricesTable));
currentMatrix = &_matricesTable[matrixIndex];
@@ -367,7 +367,7 @@ void Renderer::processRotatedElement(IMatrix3x3 *targetMatrix, const pointTab *p
applyPointsRotation(&pointsPtr[firstPoint], numOfPoints2, &modelData->computedPoints[firstPoint], targetMatrix);
}
-void Renderer::applyPointsTranslation(const pointTab *pointsPtr, int32 numPoints, pointTab *destPoints, const IMatrix3x3 *translationMatrix, const IVec3 &angleVec) {
+void Renderer::applyPointsTranslation(const I16Vec3 *pointsPtr, int32 numPoints, I16Vec3 *destPoints, const IMatrix3x3 *translationMatrix, const IVec3 &angleVec) {
int32 numOfPoints2 = numPoints;
do {
@@ -384,7 +384,7 @@ void Renderer::applyPointsTranslation(const pointTab *pointsPtr, int32 numPoints
} while (--numOfPoints2);
}
-void Renderer::processTranslatedElement(IMatrix3x3 *targetMatrix, const pointTab *pointsPtr, int32 rotX, int32 rotY, int32 rotZ, const BonesBaseData *boneData, ModelData *modelData) {
+void Renderer::processTranslatedElement(IMatrix3x3 *targetMatrix, const I16Vec3 *pointsPtr, int32 rotX, int32 rotY, int32 rotZ, const BonesBaseData *boneData, ModelData *modelData) {
IVec3 renderAngle;
renderAngle.x = rotX;
renderAngle.y = rotY;
@@ -397,7 +397,7 @@ void Renderer::processTranslatedElement(IMatrix3x3 *targetMatrix, const pointTab
*targetMatrix = _baseMatrix;
} else { // dependent
- const int32 pointsIdx = boneData->basePoint / sizeof(pointTab);
+ const int32 pointsIdx = boneData->basePoint / sizeof(I16Vec3);
destPos.x = modelData->computedPoints[pointsIdx].x;
destPos.y = modelData->computedPoints[pointsIdx].y;
destPos.z = modelData->computedPoints[pointsIdx].z;
@@ -407,7 +407,7 @@ void Renderer::processTranslatedElement(IMatrix3x3 *targetMatrix, const pointTab
*targetMatrix = _matricesTable[matrixIndex];
}
- applyPointsTranslation(&pointsPtr[boneData->firstPoint / sizeof(pointTab)], boneData->numOfPoints, &modelData->computedPoints[boneData->firstPoint / sizeof(pointTab)], targetMatrix, renderAngle);
+ applyPointsTranslation(&pointsPtr[boneData->firstPoint / sizeof(I16Vec3)], boneData->numOfPoints, &modelData->computedPoints[boneData->firstPoint / sizeof(I16Vec3)], targetMatrix, renderAngle);
}
void Renderer::setLightVector(int32 angleX, int32 angleY, int32 angleZ) {
@@ -1173,7 +1173,7 @@ uint8 *Renderer::preparePolygons(Common::MemoryReadStream &stream, int32 &numOfP
const int16 vertexOffset = stream.readSint16LE();
const int16 vertexIndex = vertexOffset / 6;
- const pointTab *point = &modelData->flattenPoints[vertexIndex];
+ const I16Vec3 *point = &modelData->flattenPoints[vertexIndex];
vertex->colorIndex = shadeValue;
vertex->x = point->x;
@@ -1197,7 +1197,7 @@ uint8 *Renderer::preparePolygons(Common::MemoryReadStream &stream, int32 &numOfP
do {
const int16 vertexOffset = stream.readSint16LE();
const int16 vertexIndex = vertexOffset / 6;
- const pointTab *point = &modelData->flattenPoints[vertexIndex];
+ const I16Vec3 *point = &modelData->flattenPoints[vertexIndex];
vertex->colorIndex = destinationPolygon->colorIndex;
vertex->x = point->x;
@@ -1309,7 +1309,7 @@ bool Renderer::renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr, R
const int32 numVertices = Model::getNumVertices(bodyPtr);
const int32 numBones = Model::getNumBones(bodyPtr);
- const pointTab *pointsPtr = (const pointTab *)Model::getVerticesBaseData(bodyPtr);
+ const I16Vec3 *pointsPtr = (const I16Vec3 *)Model::getVerticesBaseData(bodyPtr);
IMatrix3x3 *modelMatrix = &_matricesTable[0];
@@ -1340,8 +1340,8 @@ bool Renderer::renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr, R
numOfPrimitives = numVertices;
- const pointTab *pointPtr = &modelData->computedPoints[0];
- pointTab *pointPtrDest = &modelData->flattenPoints[0];
+ const I16Vec3 *pointPtr = &modelData->computedPoints[0];
+ I16Vec3 *pointPtrDest = &modelData->flattenPoints[0];
if (_isUsingOrthoProjection) { // use standard projection
do {
diff --git a/engines/twine/renderer/renderer.h b/engines/twine/renderer/renderer.h
index aa48065d68..23a175b70d 100644
--- a/engines/twine/renderer/renderer.h
+++ b/engines/twine/renderer/renderer.h
@@ -242,13 +242,13 @@ private:
};
#include "common/pack-start.h"
- struct pointTab {
+ struct I16Vec3 {
int16 x = 0;
int16 y = 0;
int16 z = 0;
};
#include "common/pack-end.h"
- static_assert(sizeof(pointTab) == 6, "Unexpected pointTab size");
+ static_assert(sizeof(I16Vec3) == 6, "Unexpected pointTab size");
struct polyVertexHeader {
int16 shadeEntry = 0;
@@ -256,8 +256,8 @@ private:
};
struct ModelData {
- pointTab computedPoints[800];
- pointTab flattenPoints[800];
+ I16Vec3 computedPoints[800];
+ I16Vec3 flattenPoints[800];
int16 shadeTable[500]{0};
};
@@ -268,10 +268,10 @@ private:
bool renderModelElements(int32 numOfPrimitives, const uint8 *polygonPtr, RenderCommand **renderCmds, ModelData *modelData);
void getCameraAnglePositions(int32 x, int32 y, int32 z);
void applyRotation(IMatrix3x3 *targetMatrix, const IMatrix3x3 *currentMatrix, const IVec3 &angleVec);
- void applyPointsRotation(const pointTab *pointsPtr, int32 numPoints, pointTab *destPoints, const IMatrix3x3 *rotationMatrix);
- void processRotatedElement(IMatrix3x3 *targetMatrix, const pointTab *pointsPtr, int32 rotZ, int32 rotY, int32 rotX, const BonesBaseData *boneData, ModelData *modelData);
- void applyPointsTranslation(const pointTab *pointsPtr, int32 numPoints, pointTab *destPoints, const IMatrix3x3 *translationMatrix, const IVec3 &angleVec);
- void processTranslatedElement(IMatrix3x3 *targetMatrix, const pointTab *pointsPtr, int32 rotX, int32 rotY, int32 rotZ, const BonesBaseData *boneData, ModelData *modelData);
+ void applyPointsRotation(const I16Vec3 *pointsPtr, int32 numPoints, I16Vec3 *destPoints, const IMatrix3x3 *rotationMatrix);
+ void processRotatedElement(IMatrix3x3 *targetMatrix, const I16Vec3 *pointsPtr, int32 rotZ, int32 rotY, int32 rotX, const BonesBaseData *boneData, ModelData *modelData);
+ void applyPointsTranslation(const I16Vec3 *pointsPtr, int32 numPoints, I16Vec3 *destPoints, const IMatrix3x3 *translationMatrix, const IVec3 &angleVec);
+ void processTranslatedElement(IMatrix3x3 *targetMatrix, const I16Vec3 *pointsPtr, int32 rotX, int32 rotY, int32 rotZ, const BonesBaseData *boneData, ModelData *modelData);
void translateGroup(int32 x, int32 y, int32 z);
IVec3 _baseTransPos;
Commit: e6377817690b3a0db3c83b56d3a0baebb0b7e149
https://github.com/scummvm/scummvm/commit/e6377817690b3a0db3c83b56d3a0baebb0b7e149
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2021-03-27T13:35:27+01:00
Commit Message:
TWINE: moved I16Vec3 into shared header
Changed paths:
engines/twine/renderer/renderer.h
engines/twine/shared.h
diff --git a/engines/twine/renderer/renderer.h b/engines/twine/renderer/renderer.h
index 23a175b70d..cd4c9af0f7 100644
--- a/engines/twine/renderer/renderer.h
+++ b/engines/twine/renderer/renderer.h
@@ -241,15 +241,6 @@ private:
int16 radius = 0;
};
-#include "common/pack-start.h"
- struct I16Vec3 {
- int16 x = 0;
- int16 y = 0;
- int16 z = 0;
- };
-#include "common/pack-end.h"
- static_assert(sizeof(I16Vec3) == 6, "Unexpected pointTab size");
-
struct polyVertexHeader {
int16 shadeEntry = 0;
int16 dataOffset = 0;
diff --git a/engines/twine/shared.h b/engines/twine/shared.h
index c69597a01c..a512a20096 100644
--- a/engines/twine/shared.h
+++ b/engines/twine/shared.h
@@ -74,6 +74,15 @@
namespace TwinE {
+#include "common/pack-start.h"
+struct I16Vec3 {
+ int16 x = 0;
+ int16 y = 0;
+ int16 z = 0;
+};
+#include "common/pack-end.h"
+static_assert(sizeof(I16Vec3) == 6, "Unexpected pointTab size");
+
struct IVec3 {
constexpr IVec3() : x(0), y(0), z(0) {}
constexpr IVec3(int32 _x, int32 _y, int32 _z) : x(_x), y(_y), z(_z) {}
Commit: 5fcaf25b4823080ac9396e622c4b828c648474b8
https://github.com/scummvm/scummvm/commit/5fcaf25b4823080ac9396e622c4b828c648474b8
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2021-03-27T13:35:27+01:00
Commit Message:
TWINE: changed function return type of getVerticesBaseData
Changed paths:
engines/twine/renderer/renderer.cpp
engines/twine/renderer/renderer.h
diff --git a/engines/twine/renderer/renderer.cpp b/engines/twine/renderer/renderer.cpp
index 9327ce4ccb..21ff1670bb 100644
--- a/engines/twine/renderer/renderer.cpp
+++ b/engines/twine/renderer/renderer.cpp
@@ -1309,7 +1309,7 @@ bool Renderer::renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr, R
const int32 numVertices = Model::getNumVertices(bodyPtr);
const int32 numBones = Model::getNumBones(bodyPtr);
- const I16Vec3 *pointsPtr = (const I16Vec3 *)Model::getVerticesBaseData(bodyPtr);
+ const I16Vec3 *pointsPtr = Model::getVerticesBaseData(bodyPtr);
IMatrix3x3 *modelMatrix = &_matricesTable[0];
diff --git a/engines/twine/renderer/renderer.h b/engines/twine/renderer/renderer.h
index cd4c9af0f7..def1ff7792 100644
--- a/engines/twine/renderer/renderer.h
+++ b/engines/twine/renderer/renderer.h
@@ -131,8 +131,8 @@ public:
return (bodyHeader & 2) != 0;
}
- static const uint8 *getVerticesBaseData(const uint8 *bodyPtr) {
- return getData(bodyPtr) + 2;
+ static const I16Vec3 *getVerticesBaseData(const uint8 *bodyPtr) {
+ return (const I16Vec3*)(getData(bodyPtr) + 2);
}
static const BoneFrame *getBonesStateData(const uint8 *bodyPtr, int boneIdx) {
Commit: d137e3c52ab6002f7b115e9428a93f256d20c776
https://github.com/scummvm/scummvm/commit/d137e3c52ab6002f7b115e9428a93f256d20c776
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2021-03-27T13:35:27+01:00
Commit Message:
TWINE: use BodyShade for getShadesBaseData
Changed paths:
engines/twine/parser/body.cpp
engines/twine/parser/body.h
engines/twine/renderer/renderer.cpp
engines/twine/renderer/renderer.h
diff --git a/engines/twine/parser/body.cpp b/engines/twine/parser/body.cpp
index 1abf4c07eb..933eac1e9e 100644
--- a/engines/twine/parser/body.cpp
+++ b/engines/twine/parser/body.cpp
@@ -85,7 +85,7 @@ void BodyData::loadShades(Common::SeekableReadStream &stream) {
shape.col1 = stream.readSint16LE();
shape.col2 = stream.readSint16LE();
shape.col3 = stream.readSint16LE();
- shape.unk4 = stream.readSint16LE();
+ shape.unk4 = stream.readUint16LE();
_shades.push_back(shape);
}
}
diff --git a/engines/twine/parser/body.h b/engines/twine/parser/body.h
index 76abcada26..36b6575e89 100644
--- a/engines/twine/parser/body.h
+++ b/engines/twine/parser/body.h
@@ -54,7 +54,7 @@ struct BodyShade {
int16 col1;
int16 col2;
int16 col3;
- int16 unk4;
+ uint16 unk4;
};
struct BodyPolygon {
diff --git a/engines/twine/renderer/renderer.cpp b/engines/twine/renderer/renderer.cpp
index 21ff1670bb..1129e8d64d 100644
--- a/engines/twine/renderer/renderer.cpp
+++ b/engines/twine/renderer/renderer.cpp
@@ -1451,12 +1451,11 @@ bool Renderer::renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr, R
_shadeMatrix = *lightMatrix * _lightPos;
do { // for each normal
- const uint8 *shadePtr = Model::getShadesBaseData(bodyPtr, shadeIndex);
- const int16 *colPtr = (const int16 *)shadePtr;
+ const BodyShade *shadePtr = Model::getShadesBaseData(bodyPtr, shadeIndex);
- const int16 col1 = *((const int16 *)colPtr++);
- const int16 col2 = *((const int16 *)colPtr++);
- const int16 col3 = *((const int16 *)colPtr++);
+ const int16 col1 = shadePtr->col1;
+ const int16 col2 = shadePtr->col2;
+ const int16 col3 = shadePtr->col3;
int32 color = 0;
color += _shadeMatrix.row1[0] * col1 + _shadeMatrix.row1[1] * col2 + _shadeMatrix.row1[2] * col3;
@@ -1467,8 +1466,7 @@ bool Renderer::renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr, R
if (color > 0) {
color >>= 14;
- const uint8 *tmpShadePtr = (const uint8 *)shadePtr;
- color /= *((const uint16 *)(tmpShadePtr + 6));
+ color /= shadePtr->unk4;
shade = (uint16)color;
}
diff --git a/engines/twine/renderer/renderer.h b/engines/twine/renderer/renderer.h
index def1ff7792..60c0057348 100644
--- a/engines/twine/renderer/renderer.h
+++ b/engines/twine/renderer/renderer.h
@@ -165,9 +165,9 @@ public:
return READ_LE_INT16(verticesBase);
}
- static const uint8 *getShadesBaseData(const uint8 *bodyPtr, int16 shadeIdx = 0) {
+ static const BodyShade *getShadesBaseData(const uint8 *bodyPtr, int16 shadeIdx = 0) {
assert(shadeIdx <= getNumShades(bodyPtr));
- return getShadesData(bodyPtr) + 2 + (shadeIdx * 8);
+ return (const BodyShade*)(getShadesData(bodyPtr) + 2 + (shadeIdx * 8));
}
static const uint8 *getShadesData(const uint8 *bodyPtr) {
@@ -185,7 +185,7 @@ public:
}
static const uint8 *getPolygonData(const uint8 *bodyPtr) {
- const uint8 *shades = getShadesBaseData(bodyPtr);
+ const uint8 *shades = (const uint8*)getShadesBaseData(bodyPtr);
const int16 numShades = getNumShades(bodyPtr);
if (numShades <= 0) {
return shades;
Commit: 0c8305f53b237e7c81ab3982d65f98c30cb3d778
https://github.com/scummvm/scummvm/commit/0c8305f53b237e7c81ab3982d65f98c30cb3d778
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2021-03-27T13:35:27+01:00
Commit Message:
TWINE: reduced visibility
Changed paths:
engines/twine/renderer/renderer.h
diff --git a/engines/twine/renderer/renderer.h b/engines/twine/renderer/renderer.h
index 60c0057348..dcdc58aafb 100644
--- a/engines/twine/renderer/renderer.h
+++ b/engines/twine/renderer/renderer.h
@@ -125,6 +125,11 @@ private:
static const uint8 *getData(const uint8 *bodyPtr) {
return bodyPtr + 0x1A;
}
+
+ static const uint8 *getShadesData(const uint8 *bodyPtr) {
+ const int16 numBones = getNumBones(bodyPtr);
+ return (const uint8 *)getBonesBaseData(bodyPtr, numBones);
+ }
public:
static inline bool isAnimated(const uint8 *bodyPtr) {
const int16 bodyHeader = READ_LE_INT16(bodyPtr);
@@ -170,11 +175,6 @@ public:
return (const BodyShade*)(getShadesData(bodyPtr) + 2 + (shadeIdx * 8));
}
- static const uint8 *getShadesData(const uint8 *bodyPtr) {
- const int16 numBones = getNumBones(bodyPtr);
- return (const uint8 *)getBonesBaseData(bodyPtr, numBones);
- }
-
static int16 getNumShades(const uint8 *bodyPtr) {
const uint8 *shadesBase = getShadesData(bodyPtr);
return READ_LE_INT16(shadesBase);
Commit: a3acbceae9b7d1611da2b1597e1723fa6c385be5
https://github.com/scummvm/scummvm/commit/a3acbceae9b7d1611da2b1597e1723fa6c385be5
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2021-03-27T13:35:27+01:00
Commit Message:
TWINE: renamed method
Changed paths:
engines/twine/renderer/renderer.cpp
engines/twine/renderer/renderer.h
diff --git a/engines/twine/renderer/renderer.cpp b/engines/twine/renderer/renderer.cpp
index 1129e8d64d..732a45887a 100644
--- a/engines/twine/renderer/renderer.cpp
+++ b/engines/twine/renderer/renderer.cpp
@@ -1451,7 +1451,7 @@ bool Renderer::renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr, R
_shadeMatrix = *lightMatrix * _lightPos;
do { // for each normal
- const BodyShade *shadePtr = Model::getShadesBaseData(bodyPtr, shadeIndex);
+ const BodyShade *shadePtr = Model::getBodyShadesData(bodyPtr, shadeIndex);
const int16 col1 = shadePtr->col1;
const int16 col2 = shadePtr->col2;
diff --git a/engines/twine/renderer/renderer.h b/engines/twine/renderer/renderer.h
index dcdc58aafb..5646b210ca 100644
--- a/engines/twine/renderer/renderer.h
+++ b/engines/twine/renderer/renderer.h
@@ -170,7 +170,7 @@ public:
return READ_LE_INT16(verticesBase);
}
- static const BodyShade *getShadesBaseData(const uint8 *bodyPtr, int16 shadeIdx = 0) {
+ static const BodyShade *getBodyShadesData(const uint8 *bodyPtr, int16 shadeIdx = 0) {
assert(shadeIdx <= getNumShades(bodyPtr));
return (const BodyShade*)(getShadesData(bodyPtr) + 2 + (shadeIdx * 8));
}
@@ -185,7 +185,7 @@ public:
}
static const uint8 *getPolygonData(const uint8 *bodyPtr) {
- const uint8 *shades = (const uint8*)getShadesBaseData(bodyPtr);
+ const uint8 *shades = (const uint8*)getBodyShadesData(bodyPtr);
const int16 numShades = getNumShades(bodyPtr);
if (numShades <= 0) {
return shades;
Commit: 22f040bab583ea6d98bc4877aeec47812c71c569
https://github.com/scummvm/scummvm/commit/22f040bab583ea6d98bc4877aeec47812c71c569
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2021-03-27T13:35:27+01:00
Commit Message:
TWINE: removed cast
Changed paths:
engines/twine/scene/animations.cpp
diff --git a/engines/twine/scene/animations.cpp b/engines/twine/scene/animations.cpp
index 070d31a279..1f06ff8c18 100644
--- a/engines/twine/scene/animations.cpp
+++ b/engines/twine/scene/animations.cpp
@@ -149,22 +149,22 @@ bool Animations::setModelAnimation(int32 keyframeIdx, const AnimData &animData,
int16 boneIdx = 1;
int16 tmpNumOfPoints = MIN<int16>(lastKeyFramePtr->boneframes.size() - 1, numOfBonesInAnim - 1);
do {
- BoneFrame *modelStateBoneFrame = (BoneFrame *)Model::getBonesStateData(bodyPtr, boneIdx);
+ BoneFrame *boneState = Model::getBonesStateData(bodyPtr, boneIdx);
const BoneFrame &boneFrame = keyFrame->boneframes[boneIdx];
const BoneFrame &lastBoneFrame = lastKeyFramePtr->boneframes[boneIdx];
- modelStateBoneFrame->type = boneFrame.type;
+ boneState->type = boneFrame.type;
switch (boneFrame.type) {
case 0: // allow global rotate
- modelStateBoneFrame->x = applyAnimStepRotation(deltaTime, keyFrameLength, boneFrame.x, lastBoneFrame.x);
- modelStateBoneFrame->y = applyAnimStepRotation(deltaTime, keyFrameLength, boneFrame.y, lastBoneFrame.y);
- modelStateBoneFrame->z = applyAnimStepRotation(deltaTime, keyFrameLength, boneFrame.z, lastBoneFrame.z);
+ boneState->x = applyAnimStepRotation(deltaTime, keyFrameLength, boneFrame.x, lastBoneFrame.x);
+ boneState->y = applyAnimStepRotation(deltaTime, keyFrameLength, boneFrame.y, lastBoneFrame.y);
+ boneState->z = applyAnimStepRotation(deltaTime, keyFrameLength, boneFrame.z, lastBoneFrame.z);
break;
case 1: // disallow global rotate
case 2: // disallow global rotate + hide
- modelStateBoneFrame->x = applyAnimStepTranslation(deltaTime, keyFrameLength, boneFrame.x, lastBoneFrame.x);
- modelStateBoneFrame->y = applyAnimStepTranslation(deltaTime, keyFrameLength, boneFrame.y, lastBoneFrame.y);
- modelStateBoneFrame->z = applyAnimStepTranslation(deltaTime, keyFrameLength, boneFrame.z, lastBoneFrame.z);
+ boneState->x = applyAnimStepTranslation(deltaTime, keyFrameLength, boneFrame.x, lastBoneFrame.x);
+ boneState->y = applyAnimStepTranslation(deltaTime, keyFrameLength, boneFrame.y, lastBoneFrame.y);
+ boneState->z = applyAnimStepTranslation(deltaTime, keyFrameLength, boneFrame.z, lastBoneFrame.z);
break;
default:
error("Unsupported animation rotation mode %d", boneFrame.type);
@@ -230,7 +230,8 @@ void Animations::stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *animT
keyframe->boneframes.reserve(numBones);
for (int32 i = 0; i < numBones; ++i) {
- keyframe->boneframes.push_back(*Model::getBonesStateData(bodyPtr, i));
+ const BoneFrame *boneState = Model::getBonesStateData(bodyPtr, i);
+ keyframe->boneframes.push_back(*boneState);
}
}
Commit: 19d71f081b1380f0c6b02ce5c9ca87a5f37d5f7b
https://github.com/scummvm/scummvm/commit/19d71f081b1380f0c6b02ce5c9ca87a5f37d5f7b
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2021-03-27T13:35:27+01:00
Commit Message:
TWINE: use size of structs
Changed paths:
engines/twine/renderer/renderer.h
diff --git a/engines/twine/renderer/renderer.h b/engines/twine/renderer/renderer.h
index 5646b210ca..4d3ed9e472 100644
--- a/engines/twine/renderer/renderer.h
+++ b/engines/twine/renderer/renderer.h
@@ -109,13 +109,13 @@ private:
static uint8 *getBonesData(uint8 *bodyPtr) {
uint8 *verticesBase = getData(bodyPtr);
const int16 numVertices = READ_LE_INT16(verticesBase);
- return verticesBase + 2 + numVertices * 6;
+ return verticesBase + 2 + numVertices * sizeof(I16Vec3);
}
static const uint8 *getBonesData(const uint8 *bodyPtr) {
const uint8 *verticesBase = getData(bodyPtr);
const int16 numVertices = READ_LE_INT16(verticesBase);
- return verticesBase + 2 + numVertices * 6;
+ return verticesBase + 2 + numVertices * sizeof(I16Vec3);
}
static uint8 *getData(uint8 *bodyPtr) {
@@ -172,7 +172,7 @@ public:
static const BodyShade *getBodyShadesData(const uint8 *bodyPtr, int16 shadeIdx = 0) {
assert(shadeIdx <= getNumShades(bodyPtr));
- return (const BodyShade*)(getShadesData(bodyPtr) + 2 + (shadeIdx * 8));
+ return (const BodyShade*)(getShadesData(bodyPtr) + 2 + (shadeIdx * sizeof(BodyShade)));
}
static int16 getNumShades(const uint8 *bodyPtr) {
Commit: cf587e5d80c515e59c5cb8ff6b58ee61e26000d1
https://github.com/scummvm/scummvm/commit/cf587e5d80c515e59c5cb8ff6b58ee61e26000d1
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2021-03-27T13:35:27+01:00
Commit Message:
TWINE: reduced visibility
Changed paths:
engines/twine/renderer/renderer.h
diff --git a/engines/twine/renderer/renderer.h b/engines/twine/renderer/renderer.h
index 4d3ed9e472..3d653697e5 100644
--- a/engines/twine/renderer/renderer.h
+++ b/engines/twine/renderer/renderer.h
@@ -126,6 +126,11 @@ private:
return bodyPtr + 0x1A;
}
+ static BonesBaseData *getBonesBaseData(uint8 *bodyPtr, int boneIdx = 0) {
+ assert(boneIdx <= getNumBones(bodyPtr));
+ return (BonesBaseData *)(getBonesData(bodyPtr) + 2 + (boneIdx * sizeof(BonesBaseData)));
+ }
+
static const uint8 *getShadesData(const uint8 *bodyPtr) {
const int16 numBones = getNumBones(bodyPtr);
return (const uint8 *)getBonesBaseData(bodyPtr, numBones);
@@ -150,11 +155,6 @@ public:
return (BoneFrame*)((uint8*)getBonesBaseData(bodyPtr) + 8 + (boneIdx * sizeof(BonesBaseData)));
}
- static BonesBaseData *getBonesBaseData(uint8 *bodyPtr, int boneIdx = 0) {
- assert(boneIdx <= getNumBones(bodyPtr));
- return (BonesBaseData *)(getBonesData(bodyPtr) + 2 + (boneIdx * sizeof(BonesBaseData)));
- }
-
static const BonesBaseData *getBonesBaseData(const uint8 *bodyPtr, int boneIdx = 0) {
assert(boneIdx <= getNumBones(bodyPtr));
return (const BonesBaseData *)(getBonesData(bodyPtr) + 2 + (boneIdx * sizeof(BonesBaseData)));
Commit: cdc6281bd0944b691976d38746f68a3c3fc03453
https://github.com/scummvm/scummvm/commit/cdc6281bd0944b691976d38746f68a3c3fc03453
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2021-03-27T13:35:27+01:00
Commit Message:
TWINE: extracted to methods
Changed paths:
engines/twine/scene/animations.cpp
engines/twine/scene/animations.h
diff --git a/engines/twine/scene/animations.cpp b/engines/twine/scene/animations.cpp
index 1f06ff8c18..22aec815c4 100644
--- a/engines/twine/scene/animations.cpp
+++ b/engines/twine/scene/animations.cpp
@@ -130,11 +130,7 @@ bool Animations::setModelAnimation(int32 keyframeIdx, const AnimData &animData,
}
const int32 deltaTime = _engine->lbaTime - remainingFrameTime;
if (deltaTime >= keyFrameLength) {
- for (int32 i = 0; i < numOfBonesInAnim; ++i) {
- BoneFrame *boneState = Model::getBonesStateData(bodyPtr, i);
- *boneState = keyFrame->boneframes[i];
- }
-
+ copyKeyFrameToState(keyFrame, bodyPtr, numOfBonesInAnim);
animTimerDataPtr->ptr = keyFrame;
animTimerDataPtr->time = _engine->lbaTime;
return true;
@@ -205,12 +201,7 @@ void Animations::setAnimAtKeyframe(int32 keyframeIdx, const AnimData &animData,
numOfBonesInAnim = numBones;
}
- for (int32 i = 0; i < numOfBonesInAnim; ++i) {
- BoneFrame *boneState = Model::getBonesStateData(bodyPtr, i);
- *boneState = keyFrame->boneframes[i];
- }
-
- return;
+ copyKeyFrameToState(keyFrame, bodyPtr, numOfBonesInAnim);
}
void Animations::stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr) {
@@ -223,18 +214,27 @@ void Animations::stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *animT
}
animTimerDataPtr->time = _engine->lbaTime;
KeyFrame *keyframe = &animKeyframeBuf[animKeyframeBufIdx++];
- keyframe->boneframes.clear();
animTimerDataPtr->ptr = keyframe;
+ copyStateToKeyFrame(keyframe, bodyPtr);
+}
+void Animations::copyStateToKeyFrame(KeyFrame *keyframe, const uint8 *bodyPtr) const {
const int32 numBones = Model::getNumBones(bodyPtr);
+ keyframe->boneframes.clear();
keyframe->boneframes.reserve(numBones);
-
for (int32 i = 0; i < numBones; ++i) {
const BoneFrame *boneState = Model::getBonesStateData(bodyPtr, i);
keyframe->boneframes.push_back(*boneState);
}
}
+void Animations::copyKeyFrameToState(const KeyFrame *keyframe, uint8 *bodyPtr, int32 numBones) const {
+ for (int32 i = 0; i < numBones; ++i) {
+ BoneFrame *boneState = Model::getBonesStateData(bodyPtr, i);
+ *boneState = keyframe->boneframes[i];
+ }
+}
+
bool Animations::verifyAnimAtKeyframe(int32 keyframeIdx, const AnimData &animData, AnimTimerDataStruct *animTimerDataPtr) {
const KeyFrame *keyFrame = animData.getKeyframe(keyframeIdx);
const int32 keyFrameLength = keyFrame->length;
diff --git a/engines/twine/scene/animations.h b/engines/twine/scene/animations.h
index 677e622b0b..b28e2fd761 100644
--- a/engines/twine/scene/animations.h
+++ b/engines/twine/scene/animations.h
@@ -45,6 +45,9 @@ private:
*/
bool verifyAnimAtKeyframe(int32 keyframeIdx, const AnimData &animData, AnimTimerDataStruct *animTimerDataPtr);
+ void copyKeyFrameToState(const KeyFrame *keyframe, uint8 *bodyPtr, int32 numBones) const;
+ void copyStateToKeyFrame(KeyFrame *keyframe, const uint8 *bodyPtr) const;
+
int animKeyframeBufIdx = 0;
KeyFrame animKeyframeBuf[32];
Commit: 33371ae4544cfc5435618300e9ac37a3232cb102
https://github.com/scummvm/scummvm/commit/33371ae4544cfc5435618300e9ac37a3232cb102
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2021-03-27T13:35:27+01:00
Commit Message:
TWINE: use BodyData for rendering
Changed paths:
engines/twine/holomap.cpp
engines/twine/holomap.h
engines/twine/menu/menu.cpp
engines/twine/menu/menu.h
engines/twine/parser/anim.h
engines/twine/parser/body.cpp
engines/twine/parser/body.h
engines/twine/renderer/redraw.cpp
engines/twine/renderer/renderer.cpp
engines/twine/renderer/renderer.h
engines/twine/resources/resources.cpp
engines/twine/resources/resources.h
engines/twine/scene/actor.cpp
engines/twine/scene/animations.cpp
engines/twine/scene/animations.h
engines/twine/scene/gamestate.cpp
diff --git a/engines/twine/holomap.cpp b/engines/twine/holomap.cpp
index 48616de5e4..f58d6985e9 100644
--- a/engines/twine/holomap.cpp
+++ b/engines/twine/holomap.cpp
@@ -259,12 +259,12 @@ void Holomap::drawHolomapText(int32 centerx, int32 top, const char *title) {
_engine->_text->drawText(x, y, title);
}
-void Holomap::renderHolomapModel(const uint8 *bodyPtr, int32 x, int32 y, int32 zPos) {
+void Holomap::renderHolomapModel(const BodyData &bodyData, int32 x, int32 y, int32 zPos) {
_engine->_renderer->setBaseRotation(x, y, 0);
_engine->_renderer->getBaseRotationPosition(0, 0, zPos + 1000);
_engine->_renderer->getBaseRotationPosition(_engine->_renderer->destPos.x, _engine->_renderer->destPos.y, _engine->_renderer->destPos.z);
_engine->_interface->resetClip();
- _engine->_renderer->renderIsoModel(_engine->_renderer->destPos.x, _engine->_renderer->destPos.y, _engine->_renderer->destPos.z, x, y, 0, bodyPtr);
+ _engine->_renderer->renderIsoModel(_engine->_renderer->destPos.x, _engine->_renderer->destPos.y, _engine->_renderer->destPos.z, x, y, 0, bodyData);
}
void Holomap::drawHolomapTrajectory(int32 trajectoryIndex) {
@@ -296,8 +296,8 @@ void Holomap::drawHolomapTrajectory(int32 trajectoryIndex) {
AnimTimerDataStruct animTimerData;
AnimData animData;
animData.loadFromHQR(Resources::HQR_RESS_FILE, data->getAnimation());
- uint8 *modelPtr = nullptr;
- HQR::getAllocEntry(&modelPtr, Resources::HQR_RESS_FILE, data->getModel());
+ BodyData bodyData;
+ bodyData.loadFromHQR(Resources::HQR_RESS_FILE, data->getModel());
uint frameNumber = 0;
int32 frameTime = _engine->lbaTime;
int16 trajAnimFrameIdx = 0;
@@ -329,7 +329,7 @@ void Holomap::drawHolomapTrajectory(int32 trajectoryIndex) {
_engine->_movements->setActorAngleSafe(ANGLE_0, -ANGLE_90, 500, &move);
}
- if (_engine->_animations->setModelAnimation(frameNumber, animData, modelPtr, &animTimerData)) {
+ if (_engine->_animations->setModelAnimation(frameNumber, animData, bodyData, &animTimerData)) {
frameNumber++;
if (frameNumber >= animData.getNumKeyframes()) {
frameNumber = animData.getLoopFrame();
@@ -340,7 +340,7 @@ void Holomap::drawHolomapTrajectory(int32 trajectoryIndex) {
_engine->_renderer->setLightVector(-60, 128, 0);
const Common::Rect rect(0, 200, 199, 479);
_engine->_interface->drawFilledRect(rect, COLOR_BLACK);
- _engine->_renderer->renderIsoModel(0, 0, 0, 0, newAngle, 0, modelPtr);
+ _engine->_renderer->renderIsoModel(0, 0, 0, 0, newAngle, 0, bodyData);
_engine->copyBlockPhys(rect);
_engine->_renderer->setCameraPosition(400, 240, 128, 1024, 1024);
_engine->_renderer->setCameraAngle(0, 0, 0, data->pos.x, data->pos.y, data->pos.z, 5300);
@@ -377,7 +377,6 @@ void Holomap::drawHolomapTrajectory(int32 trajectoryIndex) {
_engine->_text->initSceneTextBank();
_engine->_input->enableKeyMap(mainKeyMapId);
- free(modelPtr);
}
int32 Holomap::getNextHolomapLocation(int32 currentLocation, int32 dir) const {
@@ -445,18 +444,18 @@ void Holomap::renderLocations(int xRot, int yRot, int zRot, bool lower) {
for (int i = 0; i < n; ++i) {
const DrawListStruct &drawList = _engine->_redraw->drawList[i];
const uint16 flags = drawList.type;
- const uint8 *bodyPtr = nullptr;
+ const BodyData *bodyData = nullptr;
if (flags == 1u) {
- bodyPtr = _engine->_resources->holomapArrowPtr;
+ bodyData = &_engine->_resources->holomapArrowPtr;
} else if (flags == 2u) {
- bodyPtr = _engine->_resources->holomapTwinsenModelPtr;
+ bodyData = &_engine->_resources->holomapTwinsenModelPtr;
} else if (flags == 3u) {
- bodyPtr = _engine->_resources->holomapTwinsenArrowPtr;
+ bodyData = &_engine->_resources->holomapTwinsenArrowPtr;
}
- if (bodyPtr != nullptr) {
+ if (bodyData != nullptr) {
int32 angleX = _locations[drawList.actorIdx].angle.x;
int32 angleY = _locations[drawList.actorIdx].angle.y;
- _engine->_renderer->renderIsoModel(drawList.x, drawList.y, drawList.z, angleX, angleY, 0, bodyPtr);
+ _engine->_renderer->renderIsoModel(drawList.x, drawList.y, drawList.z, angleX, angleY, 0, *bodyData);
}
}
}
diff --git a/engines/twine/holomap.h b/engines/twine/holomap.h
index 369204440c..1107e7638d 100644
--- a/engines/twine/holomap.h
+++ b/engines/twine/holomap.h
@@ -79,7 +79,7 @@ private:
void renderLocations(int xRot, int yRot, int zRot, bool lower);
- void renderHolomapModel(const uint8 *bodyPtr, int32 x, int32 y, int32 zPos);
+ void renderHolomapModel(const BodyData &bodyData, int32 x, int32 y, int32 zPos);
void prepareHolomapSurface();
void prepareHolomapProjectedPositions();
diff --git a/engines/twine/menu/menu.cpp b/engines/twine/menu/menu.cpp
index 7192c77ba9..8f1ac503a9 100644
--- a/engines/twine/menu/menu.cpp
+++ b/engines/twine/menu/menu.cpp
@@ -918,7 +918,7 @@ void Menu::drawBehaviour(int32 left, int32 top, HeroBehaviourType behaviour, int
uint currentAnimState = behaviourAnimState[(byte)behaviour];
- if (_engine->_animations->setModelAnimation(currentAnimState, currentAnimData, behaviourEntity, &behaviourAnimData[(byte)behaviour])) {
+ if (_engine->_animations->setModelAnimation(currentAnimState, currentAnimData, *behaviourEntity, &behaviourAnimData[(byte)behaviour])) {
currentAnimState++; // keyframe
if (currentAnimState >= currentAnimData.getNumKeyframes()) {
currentAnimState = currentAnimData.getLoopFrame();
@@ -963,7 +963,7 @@ void Menu::drawBehaviour(int32 left, int32 top, HeroBehaviourType behaviour, int
_engine->_interface->drawFilledRect(boxRect, COLOR_BLACK);
}
- _engine->_renderer->renderBehaviourModel(boxRect, -600, angle, behaviourEntity);
+ _engine->_renderer->renderBehaviourModel(boxRect, -600, angle, *behaviourEntity);
if (dirtyRect.isEmpty()) {
dirtyRect = boxRect;
@@ -976,7 +976,7 @@ void Menu::drawBehaviour(int32 left, int32 top, HeroBehaviourType behaviour, int
void Menu::prepareAndDrawBehaviour(int32 left, int32 top, int32 angle, HeroBehaviourType behaviour, Common::Rect &dirtyRect) {
const int animIdx = _engine->_actor->heroAnimIdx[(byte)behaviour];
- _engine->_animations->setAnimAtKeyframe(behaviourAnimState[(byte)behaviour], _engine->_resources->animData[animIdx], behaviourEntity, &behaviourAnimData[(byte)behaviour]);
+ _engine->_animations->setAnimAtKeyframe(behaviourAnimState[(byte)behaviour], _engine->_resources->animData[animIdx], *behaviourEntity, &behaviourAnimData[(byte)behaviour]);
drawBehaviour(left, top, behaviour, angle, false, dirtyRect);
}
@@ -1011,7 +1011,7 @@ void Menu::processBehaviourMenu() {
_engine->_actor->setBehaviour(HeroBehaviourType::kNormal);
}
- behaviourEntity = _engine->_resources->bodyTable[_engine->_scene->sceneHero->entity];
+ behaviourEntity = &_engine->_resources->bodyData[_engine->_scene->sceneHero->entity];
_engine->_actor->heroAnimIdx[(byte)HeroBehaviourType::kNormal] = _engine->_actor->heroAnimIdxNORMAL;
_engine->_actor->heroAnimIdx[(byte)HeroBehaviourType::kAthletic] = _engine->_actor->heroAnimIdxATHLETIC;
@@ -1034,7 +1034,7 @@ void Menu::processBehaviourMenu() {
HeroBehaviourType tmpHeroBehaviour = _engine->_actor->heroBehaviour;
const int animIdx = _engine->_actor->heroAnimIdx[(byte)_engine->_actor->heroBehaviour];
- _engine->_animations->setAnimAtKeyframe(behaviourAnimState[(byte)_engine->_actor->heroBehaviour], _engine->_resources->animData[animIdx], behaviourEntity, &behaviourAnimData[(byte)_engine->_actor->heroBehaviour]);
+ _engine->_animations->setAnimAtKeyframe(behaviourAnimState[(byte)_engine->_actor->heroBehaviour], _engine->_resources->animData[animIdx], *behaviourEntity, &behaviourAnimData[(byte)_engine->_actor->heroBehaviour]);
int32 tmpTime = _engine->lbaTime;
@@ -1080,7 +1080,7 @@ void Menu::processBehaviourMenu() {
tmpHeroBehaviour = _engine->_actor->heroBehaviour;
_engine->_movements->setActorAngleSafe(_engine->_scene->sceneHero->angle, _engine->_scene->sceneHero->angle - ANGLE_90, ANGLE_17, &moveMenu);
const int tmpAnimIdx = _engine->_actor->heroAnimIdx[(byte)_engine->_actor->heroBehaviour];
- _engine->_animations->setAnimAtKeyframe(behaviourAnimState[(byte)_engine->_actor->heroBehaviour], _engine->_resources->animData[tmpAnimIdx], behaviourEntity, &behaviourAnimData[(byte)_engine->_actor->heroBehaviour]);
+ _engine->_animations->setAnimAtKeyframe(behaviourAnimState[(byte)_engine->_actor->heroBehaviour], _engine->_resources->animData[tmpAnimIdx], *behaviourEntity, &behaviourAnimData[(byte)_engine->_actor->heroBehaviour]);
}
drawBehaviour(left, top, _engine->_actor->heroBehaviour, -1, true, dirtyRect);
diff --git a/engines/twine/menu/menu.h b/engines/twine/menu/menu.h
index c9edc85f72..b4315d76dc 100644
--- a/engines/twine/menu/menu.h
+++ b/engines/twine/menu/menu.h
@@ -137,7 +137,7 @@ class Menu {
private:
TwinEEngine *_engine;
/** Hero behaviour menu entity */
- uint8 *behaviourEntity = nullptr;
+ BodyData *behaviourEntity = nullptr;
/** Behaviour menu anim state */
uint behaviourAnimState[4]; // winTab
/** Behaviour menu anim data pointer */
diff --git a/engines/twine/parser/anim.h b/engines/twine/parser/anim.h
index c73f48ad83..d8c9f5f16d 100644
--- a/engines/twine/parser/anim.h
+++ b/engines/twine/parser/anim.h
@@ -31,6 +31,11 @@
namespace TwinE {
struct BoneFrame {
+ /**
+ * 0 = allow global rotate
+ * 1 = disallow global rotate
+ * 2 = disallow global rotate and hide
+ */
uint16 type = 0;
int16 x = 0;
int16 y = 0;
diff --git a/engines/twine/parser/body.cpp b/engines/twine/parser/body.cpp
index 933eac1e9e..ca3cc2258b 100644
--- a/engines/twine/parser/body.cpp
+++ b/engines/twine/parser/body.cpp
@@ -64,6 +64,8 @@ void BodyData::loadBones(Common::SeekableReadStream &stream) {
BodyBone bone;
bone.parent = baseElementOffset == -1 ? 0xffff : baseElementOffset / 38;
bone.vertex = basePoint;
+ bone.firstVertex = firstPoint;
+ bone.numVertices = numPoints;
bone.initalBoneState = boneframe;
bone.numOfShades = numOfShades;
@@ -73,6 +75,7 @@ void BodyData::loadBones(Common::SeekableReadStream &stream) {
}
_bones.push_back(bone);
+ _boneStates[i] = bone.initalBoneState;
}
}
@@ -96,18 +99,18 @@ void BodyData::loadPolygons(Common::SeekableReadStream &stream) {
_polygons.reserve(numPolygons);
for (uint16 i = 0; i < numPolygons; ++i) {
BodyPolygon poly;
- poly.renderType = stream.readSByte();
- const int8 numVertex = stream.readSByte();
+ poly.renderType = stream.readByte();
+ const uint8 numVertices = stream.readByte();
- poly.color = stream.readUint16LE();
+ poly.color = stream.readSint16LE();
int16 intensity = -1;
if (poly.renderType == POLYGONTYPE_GOURAUD || poly.renderType == POLYGONTYPE_DITHER) {
intensity = stream.readSint16LE();
}
- poly.indices.reserve(numVertex);
- poly.intensities.reserve(numVertex);
- for (int k = 0; k < numVertex; ++k) {
+ poly.indices.reserve(numVertices);
+ poly.intensities.reserve(numVertices);
+ for (int k = 0; k < numVertices; ++k) {
if (poly.renderType >= POLYGONTYPE_UNKNOWN) {
intensity = stream.readSint16LE();
}
@@ -126,8 +129,9 @@ void BodyData::loadLines(Common::SeekableReadStream &stream) {
_lines.reserve(numLines);
for (uint16 i = 0; i < numLines; ++i) {
BodyLine line;
- line.unk1 = stream.readUint16LE();
- line.color = stream.readUint16LE();
+ line.color = stream.readByte();
+ line.unk1 = stream.readByte();
+ line.unk2 = stream.readUint16LE();
line.vertex1 = stream.readUint16LE() / 6;
line.vertex2 = stream.readUint16LE() / 6;
_lines.push_back(line);
@@ -140,9 +144,10 @@ void BodyData::loadSpheres(Common::SeekableReadStream &stream) {
_spheres.reserve(numSpheres);
for (uint16 i = 0; i < numSpheres; ++i) {
BodySphere sphere;
+ sphere.unk1 = stream.readByte();
+ sphere.color = stream.readByte();
+ sphere.unk2 = stream.readUint16LE();
sphere.radius = stream.readUint16LE();
- sphere.color = stream.readUint16LE();
- sphere.size = stream.readUint16LE();
sphere.vertex = stream.readUint16LE() / 6;
_spheres.push_back(sphere);
}
diff --git a/engines/twine/parser/body.h b/engines/twine/parser/body.h
index 36b6575e89..a3f8cba601 100644
--- a/engines/twine/parser/body.h
+++ b/engines/twine/parser/body.h
@@ -42,6 +42,8 @@ struct BodyVertex {
struct BodyBone {
uint16 parent;
uint16 vertex;
+ int16 firstVertex;
+ int16 numVertices;
int32 numOfShades;
BoneFrame initalBoneState;
@@ -61,20 +63,22 @@ struct BodyPolygon {
Common::Array<uint16> indices;
Common::Array<uint16> intensities;
int8 renderType = 0;
- uint16 color = 0;
+ int16 color = 0;
};
struct BodyLine {
- uint16 unk1;
- uint16 color;
+ uint8 color;
+ uint8 unk1;
+ uint16 unk2;
uint16 vertex1;
uint16 vertex2;
};
struct BodySphere {
+ uint8 unk1;
+ uint8 color;
+ uint16 unk2;
uint16 radius;
- uint16 color;
- uint16 size;
uint16 vertex;
};
@@ -134,44 +138,44 @@ public:
return _vertices.size();
}
- BoneFrame* getBoneState(int16 boneIdx) {
+ BoneFrame *getBoneState(int16 boneIdx) {
return &_boneStates[boneIdx];
}
- const BoneFrame* getBoneState(int16 boneIdx) const {
+ const BoneFrame *getBoneState(int16 boneIdx) const {
return &_boneStates[boneIdx];
}
- const Common::Array<BodyPolygon>& getPolygons() const {
+ const Common::Array<BodyPolygon> &getPolygons() const {
return _polygons;
}
- const Common::Array<BodyVertex>& getVertices() const {
+ const Common::Array<BodyVertex> &getVertices() const {
return _vertices;
}
- const Common::Array<BodySphere>& getSpheres() const {
+ const Common::Array<BodySphere> &getSpheres() const {
return _spheres;
}
- const Common::Array<BodyShade>& getShades() const {
+ const Common::Array<BodyShade> &getShades() const {
return _shades;
}
- const BodyShade* getShade(int16 shadeIdx) const {
- return &_shades[shadeIdx];
+ const BodyShade &getShade(int16 shadeIdx) const {
+ return _shades[shadeIdx];
}
- const Common::Array<BodyLine>& getLines() const {
+ const Common::Array<BodyLine> &getLines() const {
return _lines;
}
- const Common::Array<BodyBone>& getBones() const {
+ const Common::Array<BodyBone> &getBones() const {
return _bones;
}
- const BodyBone* getBone(int16 boneIdx) const {
- return &_bones[boneIdx];
+ const BodyBone &getBone(int16 boneIdx) const {
+ return _bones[boneIdx];
}
bool loadFromStream(Common::SeekableReadStream &stream) override;
diff --git a/engines/twine/renderer/redraw.cpp b/engines/twine/renderer/redraw.cpp
index 1856bdd342..a210315b04 100644
--- a/engines/twine/renderer/redraw.cpp
+++ b/engines/twine/renderer/redraw.cpp
@@ -343,13 +343,13 @@ void Redraw::processDrawListActors(const DrawListStruct &drawCmd, bool bgRedraw)
ActorStruct *actor = _engine->_scene->getActor(actorIdx);
if (actor->previousAnimIdx >= 0) {
const AnimData &animData = _engine->_resources->animData[actor->previousAnimIdx];
- _engine->_animations->setModelAnimation(actor->animPosition, animData, _engine->_resources->bodyTable[actor->entity], &actor->animTimerData);
+ _engine->_animations->setModelAnimation(actor->animPosition, animData, _engine->_resources->bodyData[actor->entity], &actor->animTimerData);
}
const int32 x = actor->pos.x - _engine->_grid->camera.x;
const int32 y = actor->pos.y - _engine->_grid->camera.y;
const int32 z = actor->pos.z - _engine->_grid->camera.z;
- if (!_engine->_renderer->renderIsoModel(x, y, z, ANGLE_0, actor->angle, ANGLE_0, _engine->_resources->bodyTable[actor->entity])) {
+ if (!_engine->_renderer->renderIsoModel(x, y, z, ANGLE_0, actor->angle, ANGLE_0, _engine->_resources->bodyData[actor->entity])) {
return;
}
@@ -623,7 +623,7 @@ void Redraw::renderOverlays() {
_engine->_interface->drawFilledRect(rect, COLOR_BLACK);
_engine->_interface->setClip(rect);
- const uint8* bodyPtr = _engine->_resources->inventoryTable[item];
+ const BodyData &bodyPtr = _engine->_resources->inventoryTable[item];
_overlayRotation += 1; // overlayRotation += 8;
_engine->_renderer->renderInventoryItem(40, 40, bodyPtr, _overlayRotation, 16000);
_engine->_menu->drawBox(rect);
diff --git a/engines/twine/renderer/renderer.cpp b/engines/twine/renderer/renderer.cpp
index 732a45887a..3fe8e6ca50 100644
--- a/engines/twine/renderer/renderer.cpp
+++ b/engines/twine/renderer/renderer.cpp
@@ -27,6 +27,7 @@
#include "common/util.h"
#include "twine/menu/interface.h"
#include "twine/menu/menu.h"
+#include "twine/parser/body.h"
#include "twine/renderer/redraw.h"
#include "twine/renderer/shadeangletab.h"
#include "twine/resources/resources.h"
@@ -313,26 +314,24 @@ void Renderer::applyRotation(IMatrix3x3 *targetMatrix, const IMatrix3x3 *current
}
}
-void Renderer::applyPointsRotation(const I16Vec3 *pointsPtr, int32 numPoints, I16Vec3 *destPoints, const IMatrix3x3 *rotationMatrix) {
- int32 numOfPoints2 = numPoints;
-
- do {
- const int32 tmpX = pointsPtr->x;
- const int32 tmpY = pointsPtr->y;
- const int32 tmpZ = pointsPtr->z;
+void Renderer::applyPointsRotation(const Common::Array<BodyVertex> &vertices, int32 firstPoint, int32 numPoints, I16Vec3 *destPoints, const IMatrix3x3 *rotationMatrix) {
+ for (int32 i = 0; i < numPoints; ++i) {
+ const BodyVertex &vertex = vertices[i + firstPoint];
+ const int32 tmpX = vertex.x;
+ const int32 tmpY = vertex.y;
+ const int32 tmpZ = vertex.z;
destPoints->x = ((rotationMatrix->row1[0] * tmpX + rotationMatrix->row1[1] * tmpY + rotationMatrix->row1[2] * tmpZ) / SCENE_SIZE_HALF) + destPos.x;
destPoints->y = ((rotationMatrix->row2[0] * tmpX + rotationMatrix->row2[1] * tmpY + rotationMatrix->row2[2] * tmpZ) / SCENE_SIZE_HALF) + destPos.y;
destPoints->z = ((rotationMatrix->row3[0] * tmpX + rotationMatrix->row3[1] * tmpY + rotationMatrix->row3[2] * tmpZ) / SCENE_SIZE_HALF) + destPos.z;
destPoints++;
- pointsPtr++;
- } while (--numOfPoints2);
+ }
}
-void Renderer::processRotatedElement(IMatrix3x3 *targetMatrix, const I16Vec3 *pointsPtr, int32 rotZ, int32 rotY, int32 rotX, const BonesBaseData *boneData, ModelData *modelData) {
- int32 firstPoint = boneData->firstPoint / sizeof(I16Vec3);
- int32 numOfPoints2 = boneData->numOfPoints;
+void Renderer::processRotatedElement(IMatrix3x3 *targetMatrix, const Common::Array<BodyVertex> &vertices, int32 rotX, int32 rotY, int32 rotZ, const BodyBone &bone, ModelData *modelData) {
+ const int32 firstPoint = bone.firstVertex;
+ const int32 numOfPoints = bone.numVertices;
IVec3 renderAngle;
renderAngle.x = rotX;
@@ -341,15 +340,15 @@ void Renderer::processRotatedElement(IMatrix3x3 *targetMatrix, const I16Vec3 *po
const IMatrix3x3 *currentMatrix;
// if its the first point
- if (boneData->baseElement == -1) {
+ if (bone.isRoot()) {
currentMatrix = &_baseMatrix;
destPos.x = 0;
destPos.y = 0;
destPos.z = 0;
} else {
- const int32 pointIdx = boneData->basePoint / sizeof(I16Vec3);
- const int32 matrixIndex = boneData->baseElement / sizeof(BonesBaseData);
+ const int32 pointIdx = bone.vertex;
+ const int32 matrixIndex = bone.parent;
assert(matrixIndex >= 0 && matrixIndex < ARRAYSIZE(_matricesTable));
currentMatrix = &_matricesTable[matrixIndex];
@@ -360,54 +359,52 @@ void Renderer::processRotatedElement(IMatrix3x3 *targetMatrix, const I16Vec3 *po
applyRotation(targetMatrix, currentMatrix, renderAngle);
- if (!numOfPoints2) {
+ if (!numOfPoints) {
warning("RENDER WARNING: No points in this model!");
}
- applyPointsRotation(&pointsPtr[firstPoint], numOfPoints2, &modelData->computedPoints[firstPoint], targetMatrix);
+ applyPointsRotation(vertices, firstPoint, numOfPoints, &modelData->computedPoints[firstPoint], targetMatrix);
}
-void Renderer::applyPointsTranslation(const I16Vec3 *pointsPtr, int32 numPoints, I16Vec3 *destPoints, const IMatrix3x3 *translationMatrix, const IVec3 &angleVec) {
- int32 numOfPoints2 = numPoints;
-
- do {
- const int32 tmpX = pointsPtr->x + angleVec.z;
- const int32 tmpY = pointsPtr->y + angleVec.y;
- const int32 tmpZ = pointsPtr->z + angleVec.x;
+void Renderer::applyPointsTranslation(const Common::Array<BodyVertex> &vertices, int32 firstPoint, int32 numPoints, I16Vec3 *destPoints, const IMatrix3x3 *translationMatrix, const IVec3 &angleVec) {
+ for (int32 i = 0; i < numPoints; ++i) {
+ const BodyVertex &vertex = vertices[i + firstPoint];
+ const int32 tmpX = vertex.x + angleVec.z;
+ const int32 tmpY = vertex.y + angleVec.y;
+ const int32 tmpZ = vertex.z + angleVec.x;
destPoints->x = ((translationMatrix->row1[0] * tmpX + translationMatrix->row1[1] * tmpY + translationMatrix->row1[2] * tmpZ) / SCENE_SIZE_HALF) + destPos.x;
destPoints->y = ((translationMatrix->row2[0] * tmpX + translationMatrix->row2[1] * tmpY + translationMatrix->row2[2] * tmpZ) / SCENE_SIZE_HALF) + destPos.y;
destPoints->z = ((translationMatrix->row3[0] * tmpX + translationMatrix->row3[1] * tmpY + translationMatrix->row3[2] * tmpZ) / SCENE_SIZE_HALF) + destPos.z;
destPoints++;
- pointsPtr++;
- } while (--numOfPoints2);
+ }
}
-void Renderer::processTranslatedElement(IMatrix3x3 *targetMatrix, const I16Vec3 *pointsPtr, int32 rotX, int32 rotY, int32 rotZ, const BonesBaseData *boneData, ModelData *modelData) {
+void Renderer::processTranslatedElement(IMatrix3x3 *targetMatrix, const Common::Array<BodyVertex> &vertices, int32 rotX, int32 rotY, int32 rotZ, const BodyBone &bone, ModelData *modelData) {
IVec3 renderAngle;
renderAngle.x = rotX;
renderAngle.y = rotY;
renderAngle.z = rotZ;
- if (boneData->baseElement == -1) { // base point
+ if (bone.isRoot()) { // base point
destPos.x = 0;
destPos.y = 0;
destPos.z = 0;
*targetMatrix = _baseMatrix;
} else { // dependent
- const int32 pointsIdx = boneData->basePoint / sizeof(I16Vec3);
+ const int32 pointsIdx = bone.vertex;
destPos.x = modelData->computedPoints[pointsIdx].x;
destPos.y = modelData->computedPoints[pointsIdx].y;
destPos.z = modelData->computedPoints[pointsIdx].z;
- const int32 matrixIndex = boneData->baseElement / sizeof(BonesBaseData);
+ const int32 matrixIndex = bone.parent;
assert(matrixIndex >= 0 && matrixIndex < ARRAYSIZE(_matricesTable));
*targetMatrix = _matricesTable[matrixIndex];
}
- applyPointsTranslation(&pointsPtr[boneData->firstPoint / sizeof(I16Vec3)], boneData->numOfPoints, &modelData->computedPoints[boneData->firstPoint / sizeof(I16Vec3)], targetMatrix, renderAngle);
+ applyPointsTranslation(vertices, bone.firstVertex, bone.numVertices, &modelData->computedPoints[bone.firstVertex], targetMatrix, renderAngle);
}
void Renderer::setLightVector(int32 angleX, int32 angleY, int32 angleZ) {
@@ -1080,22 +1077,14 @@ void Renderer::circleFill(int32 x, int32 y, int32 radius, uint8 color) {
}
}
-uint8 *Renderer::prepareSpheres(Common::MemoryReadStream &stream, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData) {
- int16 numSpheres = stream.readSint16LE();
- if (numSpheres <= 0) {
- return renderBufferPtr;
- }
- numOfPrimitives += numSpheres;
- do {
- CmdRenderSphere *sphere = (CmdRenderSphere *)renderBufferPtr;
- stream.skip(1);
- sphere->colorIndex = stream.readByte();
- stream.skip(2);
- sphere->radius = stream.readUint16LE();
- const int16 centerOffset = stream.readUint16LE();
- const int16 centerIndex = centerOffset / 6;
- sphere->x = modelData->flattenPoints[centerIndex].x;
- sphere->y = modelData->flattenPoints[centerIndex].y;
+uint8 *Renderer::prepareSpheres(const Common::Array<BodySphere> &spheres, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData) {
+ for (const BodySphere &sphere : spheres) {
+ CmdRenderSphere *cmd = (CmdRenderSphere *)renderBufferPtr;
+ cmd->colorIndex = sphere.color;
+ cmd->radius = sphere.radius;
+ const int16 centerIndex = sphere.vertex;
+ cmd->x = modelData->flattenPoints[centerIndex].x;
+ cmd->y = modelData->flattenPoints[centerIndex].y;
(*renderCmds)->depth = modelData->flattenPoints[centerIndex].z;
(*renderCmds)->renderType = RENDERTYPE_DRAWSPHERE;
@@ -1103,51 +1092,38 @@ uint8 *Renderer::prepareSpheres(Common::MemoryReadStream &stream, int32 &numOfPr
(*renderCmds)++;
renderBufferPtr += sizeof(CmdRenderSphere);
- } while (--numSpheres);
-
+ }
+ numOfPrimitives += spheres.size();
return renderBufferPtr;
}
-uint8 *Renderer::prepareLines(Common::MemoryReadStream &stream, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData) {
- int16 numLines = stream.readSint16LE();
- if (numLines <= 0) {
- return renderBufferPtr;
- }
- numOfPrimitives += numLines;
-
- do {
- CmdRenderLine *lineCoordinatesPtr = (CmdRenderLine *)renderBufferPtr;
- lineCoordinatesPtr->colorIndex = stream.readByte();
- stream.skip(3);
- const int32 point1Index = stream.readSint16LE() / 6;
- const int32 point2Index = stream.readSint16LE() / 6;
- lineCoordinatesPtr->x1 = modelData->flattenPoints[point1Index].x;
- lineCoordinatesPtr->y1 = modelData->flattenPoints[point1Index].y;
- lineCoordinatesPtr->x2 = modelData->flattenPoints[point2Index].x;
- lineCoordinatesPtr->y2 = modelData->flattenPoints[point2Index].y;
+uint8 *Renderer::prepareLines(const Common::Array<BodyLine> &lines, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData) {
+ for (const BodyLine &line : lines) {
+ CmdRenderLine *cmd = (CmdRenderLine *)renderBufferPtr;
+ cmd->colorIndex = line.color;
+ const int32 point1Index = line.vertex1;
+ const int32 point2Index = line.vertex2;
+ cmd->x1 = modelData->flattenPoints[point1Index].x;
+ cmd->y1 = modelData->flattenPoints[point1Index].y;
+ cmd->x2 = modelData->flattenPoints[point2Index].x;
+ cmd->y2 = modelData->flattenPoints[point2Index].y;
(*renderCmds)->depth = MAX(modelData->flattenPoints[point1Index].z, modelData->flattenPoints[point2Index].z);
(*renderCmds)->renderType = RENDERTYPE_DRAWLINE;
(*renderCmds)->dataPtr = renderBufferPtr;
(*renderCmds)++;
renderBufferPtr += sizeof(CmdRenderLine);
- } while (--numLines);
-
+ }
+ numOfPrimitives += lines.size();
return renderBufferPtr;
}
-uint8 *Renderer::preparePolygons(Common::MemoryReadStream &stream, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData) {
- int16 numPolygons = stream.readSint16LE();
- if (numPolygons <= 0) {
- return renderBufferPtr;
- }
- int16 primitiveCounter = numPolygons; // the number of primitives = the number of polygons
-
- do { // loop that load all the polygons
- const uint8 renderType = stream.readByte();
- const uint8 numVertices = stream.readByte();
+uint8 *Renderer::preparePolygons(const Common::Array<BodyPolygon> &polygons, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData) {
+ for (const BodyPolygon &polygon : polygons) {
+ const uint8 renderType = polygon.renderType;
+ const uint8 numVertices = polygon.indices.size();
assert(numVertices <= 16);
- const int16 colorIndex = stream.readSint16LE();
+ const int16 colorIndex = polygon.color;
int16 bestDepth = -32000;
@@ -1160,19 +1136,16 @@ uint8 *Renderer::preparePolygons(Common::MemoryReadStream &stream, int32 &numOfP
renderBufferPtr += destinationPolygon->numVertices * sizeof(Vertex);
Vertex *vertex = vertices;
- int16 counter = destinationPolygon->numVertices;
// TODO: RECHECK coordinates axis
- if (renderType >= 9) {
- destinationPolygon->renderType = renderType - 2;
- destinationPolygon->colorIndex = colorIndex;
+ if (renderType >= POLYGONTYPE_UNKNOWN) {
+ destinationPolygon->renderType = polygon.renderType - 2;
+ destinationPolygon->colorIndex = polygon.color;
- do {
- const int16 shadeEntry = stream.readSint16LE();
+ for (int16 idx = 0; idx < numVertices; ++idx) {
+ const int16 shadeEntry = polygon.intensities[idx];
const int16 shadeValue = colorIndex + modelData->shadeTable[shadeEntry];
-
- const int16 vertexOffset = stream.readSint16LE();
- const int16 vertexIndex = vertexOffset / 6;
+ const int16 vertexIndex = polygon.indices[idx];
const I16Vec3 *point = &modelData->flattenPoints[vertexIndex];
vertex->colorIndex = shadeValue;
@@ -1180,12 +1153,12 @@ uint8 *Renderer::preparePolygons(Common::MemoryReadStream &stream, int32 &numOfP
vertex->y = point->y;
bestDepth = MAX(bestDepth, point->z);
++vertex;
- } while (--counter > 0);
+ }
} else {
if (renderType >= POLYGONTYPE_GOURAUD) {
// only 1 shade value is used
destinationPolygon->renderType = renderType - POLYGONTYPE_GOURAUD;
- const int16 shadeEntry = stream.readSint16LE();
+ const int16 shadeEntry = polygon.intensities[0];
const int16 shadeValue = colorIndex + modelData->shadeTable[shadeEntry];
destinationPolygon->colorIndex = shadeValue;
} else {
@@ -1194,9 +1167,8 @@ uint8 *Renderer::preparePolygons(Common::MemoryReadStream &stream, int32 &numOfP
destinationPolygon->colorIndex = colorIndex;
}
- do {
- const int16 vertexOffset = stream.readSint16LE();
- const int16 vertexIndex = vertexOffset / 6;
+ for (int16 idx = 0; idx < numVertices; ++idx) {
+ const int16 vertexIndex = polygon.indices[idx];
const I16Vec3 *point = &modelData->flattenPoints[vertexIndex];
vertex->colorIndex = destinationPolygon->colorIndex;
@@ -1204,7 +1176,7 @@ uint8 *Renderer::preparePolygons(Common::MemoryReadStream &stream, int32 &numOfP
vertex->y = point->y;
bestDepth = MAX(bestDepth, point->z);
++vertex;
- } while (--counter > 0);
+ }
}
numOfPrimitives++;
@@ -1213,7 +1185,7 @@ uint8 *Renderer::preparePolygons(Common::MemoryReadStream &stream, int32 &numOfP
(*renderCmds)->renderType = RENDERTYPE_DRAWPOLYGON;
(*renderCmds)->dataPtr = (uint8 *)destinationPolygon;
(*renderCmds)++;
- } while (--primitiveCounter);
+ }
return renderBufferPtr;
}
@@ -1223,14 +1195,11 @@ const Renderer::RenderCommand *Renderer::depthSortRenderCommands(int32 numOfPrim
return _renderCmds;
}
-bool Renderer::renderModelElements(int32 numOfPrimitives, const uint8 *polygonPtr, RenderCommand **renderCmds, ModelData *modelData) {
- // TODO: proper size
- Common::MemoryReadStream stream(polygonPtr, 100000);
-
+bool Renderer::renderModelElements(int32 numOfPrimitives, const BodyData &bodyData, RenderCommand **renderCmds, ModelData *modelData) {
uint8 *renderBufferPtr = _renderCoordinatesBuffer;
- renderBufferPtr = preparePolygons(stream, numOfPrimitives, renderCmds, renderBufferPtr, modelData);
- renderBufferPtr = prepareLines(stream, numOfPrimitives, renderCmds, renderBufferPtr, modelData);
- renderBufferPtr = prepareSpheres(stream, numOfPrimitives, renderCmds, renderBufferPtr, modelData);
+ renderBufferPtr = preparePolygons(bodyData.getPolygons(), numOfPrimitives, renderCmds, renderBufferPtr, modelData);
+ renderBufferPtr = prepareLines(bodyData.getLines(), numOfPrimitives, renderCmds, renderBufferPtr, modelData);
+ renderBufferPtr = prepareSpheres(bodyData.getSpheres(), numOfPrimitives, renderCmds, renderBufferPtr, modelData);
if (numOfPrimitives == 0) {
_engine->_redraw->renderRect.right = -1;
@@ -1268,7 +1237,7 @@ bool Renderer::renderModelElements(int32 numOfPrimitives, const uint8 *polygonPt
int32 radius = sphere->radius;
//if (isUsingOrthoProjection) {
- radius = (radius * 34) / 512;
+ radius = (radius * 34) / 512;
//} else {
// radius = (radius * cameraScaleY) / (cameraDepthOffset + *(const int16 *)pointer); // TODO: this does not make sense.
//}
@@ -1305,32 +1274,32 @@ bool Renderer::renderModelElements(int32 numOfPrimitives, const uint8 *polygonPt
return true;
}
-bool Renderer::renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr, RenderCommand *renderCmds, const IVec3 &angleVec, const IVec3 &renderPos) {
- const int32 numVertices = Model::getNumVertices(bodyPtr);
- const int32 numBones = Model::getNumBones(bodyPtr);
+bool Renderer::renderAnimatedModel(ModelData *modelData, const BodyData &bodyData, RenderCommand *renderCmds, const IVec3 &angleVec, const IVec3 &renderPos) {
+ const int32 numVertices = bodyData.getNumVertices();
+ const int32 numBones = bodyData.getNumBones();
- const I16Vec3 *pointsPtr = Model::getVerticesBaseData(bodyPtr);
+ const Common::Array<BodyVertex> &vertices = bodyData.getVertices();
IMatrix3x3 *modelMatrix = &_matricesTable[0];
- const BonesBaseData *boneData = Model::getBonesBaseData(bodyPtr, 0);
- processRotatedElement(modelMatrix, pointsPtr, angleVec.x, angleVec.y, angleVec.z, boneData, modelData);
+ const BodyBone &firstBone = bodyData.getBone(0);
+ processRotatedElement(modelMatrix, vertices, angleVec.x, angleVec.y, angleVec.z, firstBone, modelData);
int32 numOfPrimitives = 0;
if (numBones - 1 != 0) {
numOfPrimitives = numBones - 1;
- modelMatrix = &_matricesTable[1];
-
int boneIdx = 1;
+ modelMatrix = &_matricesTable[boneIdx];
+
do {
- boneData = Model::getBonesBaseData(bodyPtr, boneIdx);
- int16 boneType = boneData->flag;
+ const BodyBone &bone = bodyData.getBone(boneIdx);
+ const BoneFrame *boneData = bodyData.getBoneState(boneIdx);
- if (boneType == 0) {
- processRotatedElement(modelMatrix, pointsPtr, boneData->rotateX, boneData->rotateY, boneData->rotateZ, boneData, modelData);
- } else if (boneType == 1) {
- processTranslatedElement(modelMatrix, pointsPtr, boneData->rotateX, boneData->rotateY, boneData->rotateZ, boneData, modelData);
+ if (boneData->type == 0) {
+ processRotatedElement(modelMatrix, vertices, boneData->x, boneData->y, boneData->z, bone, modelData);
+ } else if (boneData->type == 1) {
+ processTranslatedElement(modelMatrix, vertices, boneData->x, boneData->y, boneData->z, bone, modelData);
}
++modelMatrix;
@@ -1432,7 +1401,7 @@ bool Renderer::renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr, R
} while (--numOfPrimitives);
}
- int32 numOfShades = Model::getNumShades(bodyPtr);
+ int32 numOfShades = bodyData.getShades().size();
if (numOfShades) { // process normal data
uint16 *currentShadeDestination = (uint16 *)modelData->shadeTable;
@@ -1443,7 +1412,7 @@ bool Renderer::renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr, R
int shadeIndex = 0;
int boneIdx = 0;
do { // for each element
- numOfShades = Model::getNumShadesBone(bodyPtr, boneIdx);
+ numOfShades = bodyData.getBone(boneIdx).numOfShades;
if (numOfShades) {
int32 numShades = numOfShades;
@@ -1451,11 +1420,11 @@ bool Renderer::renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr, R
_shadeMatrix = *lightMatrix * _lightPos;
do { // for each normal
- const BodyShade *shadePtr = Model::getBodyShadesData(bodyPtr, shadeIndex);
+ const BodyShade &shadePtr = bodyData.getShade(shadeIndex);
- const int16 col1 = shadePtr->col1;
- const int16 col2 = shadePtr->col2;
- const int16 col3 = shadePtr->col3;
+ const int16 col1 = shadePtr.col1;
+ const int16 col2 = shadePtr.col2;
+ const int16 col3 = shadePtr.col3;
int32 color = 0;
color += _shadeMatrix.row1[0] * col1 + _shadeMatrix.row1[1] * col2 + _shadeMatrix.row1[2] * col3;
@@ -1466,7 +1435,7 @@ bool Renderer::renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr, R
if (color > 0) {
color >>= 14;
- color /= shadePtr->unk4;
+ color /= shadePtr.unk4;
shade = (uint16)color;
}
@@ -1481,10 +1450,10 @@ bool Renderer::renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr, R
} while (--numOfPrimitives);
}
- return renderModelElements(numOfPrimitives, Model::getPolygonData(bodyPtr), &renderCmds, modelData);
+ return renderModelElements(numOfPrimitives, bodyData, &renderCmds, modelData);
}
-bool Renderer::renderIsoModel(int32 x, int32 y, int32 z, int32 angleX, int32 angleY, int32 angleZ, const uint8 *bodyPtr) {
+bool Renderer::renderIsoModel(int32 x, int32 y, int32 z, int32 angleX, int32 angleY, int32 angleZ, const BodyData &bodyData) {
IVec3 renderAngle;
renderAngle.x = angleX;
renderAngle.y = angleY;
@@ -1507,18 +1476,18 @@ bool Renderer::renderIsoModel(int32 x, int32 y, int32 z, int32 angleX, int32 ang
renderPos = destPos - baseRotPos; // RECHECK y
}
- if (!Model::isAnimated(bodyPtr)) {
+ if (!bodyData.isAnimated()) {
error("Unsupported unanimated model render!");
}
// restart at the beginning of the renderTable
- return renderAnimatedModel(&_modelData, bodyPtr, _renderCmds, renderAngle, renderPos);
+ return renderAnimatedModel(&_modelData, bodyData, _renderCmds, renderAngle, renderPos);
}
-void Renderer::renderBehaviourModel(const Common::Rect &rect, int32 y, int32 angle, const uint8 *bodyPtr) {
- renderBehaviourModel(rect.left, rect.top, rect.right, rect.bottom, y, angle, bodyPtr);
+void Renderer::renderBehaviourModel(const Common::Rect &rect, int32 y, int32 angle, const BodyData &bodyData) {
+ renderBehaviourModel(rect.left, rect.top, rect.right, rect.bottom, y, angle, bodyData);
}
-void Renderer::renderBehaviourModel(int32 boxLeft, int32 boxTop, int32 boxRight, int32 boxBottom, int32 y, int32 angle, const uint8 *bodyPtr) {
+void Renderer::renderBehaviourModel(int32 boxLeft, int32 boxTop, int32 boxRight, int32 boxBottom, int32 y, int32 angle, const BodyData &bodyData) {
const int32 ypos = (boxBottom + boxTop) / 2;
const int32 xpos = (boxRight + boxLeft) / 2;
@@ -1531,17 +1500,17 @@ void Renderer::renderBehaviourModel(int32 boxLeft, int32 boxTop, int32 boxRight,
if (move.numOfStep == 0) {
_engine->_movements->setActorAngleSafe(newAngle, newAngle - ANGLE_90, ANGLE_17, &move);
}
- renderIsoModel(0, y, 0, ANGLE_0, newAngle, ANGLE_0, bodyPtr);
+ renderIsoModel(0, y, 0, ANGLE_0, newAngle, ANGLE_0, bodyData);
} else {
- renderIsoModel(0, y, 0, ANGLE_0, angle, ANGLE_0, bodyPtr);
+ renderIsoModel(0, y, 0, ANGLE_0, angle, ANGLE_0, bodyData);
}
}
-void Renderer::renderInventoryItem(int32 x, int32 y, const uint8 *bodyPtr, int32 angle, int32 param) {
+void Renderer::renderInventoryItem(int32 x, int32 y, const BodyData &bodyData, int32 angle, int32 param) {
setCameraPosition(x, y, 128, 200, 200);
setCameraAngle(0, 0, 0, 60, 0, 0, param);
- renderIsoModel(0, 0, 0, ANGLE_0, angle, ANGLE_0, bodyPtr);
+ renderIsoModel(0, 0, 0, ANGLE_0, angle, ANGLE_0, bodyData);
}
void Renderer::computeHolomapPolygon(int32 top, int32 x1, int32 bottom, int32 x2, int16 *polygonTabPtr) {
diff --git a/engines/twine/renderer/renderer.h b/engines/twine/renderer/renderer.h
index 3d653697e5..9948486cdc 100644
--- a/engines/twine/renderer/renderer.h
+++ b/engines/twine/renderer/renderer.h
@@ -83,122 +83,6 @@ inline IMatrix3x3 operator*(const IMatrix3x3 &matrix, const IVec3 &vec) {
return out;
}
-#include "common/pack-start.h"
-struct BonesBaseData {
- int16 firstPoint = 0; // data1
- int16 numOfPoints = 0; // data2
- int16 basePoint = 0; // data3
- int16 baseElement = 0; // param
- int16 flag = 0;
- int16 rotateZ = 0;
- int16 rotateY = 0;
- int16 rotateX = 0;
- int16 unk1 = 0; // field_10
- int16 numOfShades = 0;
- int16 unk2 = 0;
- int32 field_18 = 0;
- int32 y = 0;
- int32 field_20 = 0;
- int32 field_24 = 0;
-};
-#include "common/pack-end.h"
-static_assert(sizeof(BonesBaseData) == 38, "Unexpected elementEntry size");
-
-class Model {
-private:
- static uint8 *getBonesData(uint8 *bodyPtr) {
- uint8 *verticesBase = getData(bodyPtr);
- const int16 numVertices = READ_LE_INT16(verticesBase);
- return verticesBase + 2 + numVertices * sizeof(I16Vec3);
- }
-
- static const uint8 *getBonesData(const uint8 *bodyPtr) {
- const uint8 *verticesBase = getData(bodyPtr);
- const int16 numVertices = READ_LE_INT16(verticesBase);
- return verticesBase + 2 + numVertices * sizeof(I16Vec3);
- }
-
- static uint8 *getData(uint8 *bodyPtr) {
- return bodyPtr + 0x1A;
- }
-
- static const uint8 *getData(const uint8 *bodyPtr) {
- return bodyPtr + 0x1A;
- }
-
- static BonesBaseData *getBonesBaseData(uint8 *bodyPtr, int boneIdx = 0) {
- assert(boneIdx <= getNumBones(bodyPtr));
- return (BonesBaseData *)(getBonesData(bodyPtr) + 2 + (boneIdx * sizeof(BonesBaseData)));
- }
-
- static const uint8 *getShadesData(const uint8 *bodyPtr) {
- const int16 numBones = getNumBones(bodyPtr);
- return (const uint8 *)getBonesBaseData(bodyPtr, numBones);
- }
-public:
- static inline bool isAnimated(const uint8 *bodyPtr) {
- const int16 bodyHeader = READ_LE_INT16(bodyPtr);
- return (bodyHeader & 2) != 0;
- }
-
- static const I16Vec3 *getVerticesBaseData(const uint8 *bodyPtr) {
- return (const I16Vec3*)(getData(bodyPtr) + 2);
- }
-
- static const BoneFrame *getBonesStateData(const uint8 *bodyPtr, int boneIdx) {
- assert(boneIdx <= getNumBones(bodyPtr));
- return (const BoneFrame*)((const uint8*)getBonesBaseData(bodyPtr) + 8 + (boneIdx * sizeof(BonesBaseData)));
- }
-
- static BoneFrame *getBonesStateData(uint8 *bodyPtr, int boneIdx) {
- assert(boneIdx <= getNumBones(bodyPtr));
- return (BoneFrame*)((uint8*)getBonesBaseData(bodyPtr) + 8 + (boneIdx * sizeof(BonesBaseData)));
- }
-
- static const BonesBaseData *getBonesBaseData(const uint8 *bodyPtr, int boneIdx = 0) {
- assert(boneIdx <= getNumBones(bodyPtr));
- return (const BonesBaseData *)(getBonesData(bodyPtr) + 2 + (boneIdx * sizeof(BonesBaseData)));
- }
-
- static int16 getNumBones(const uint8 *bodyPtr) {
- const uint8 *bonesBase = getBonesData(bodyPtr);
- return READ_LE_INT16(bonesBase);
- }
-
- static int16 getNumVertices(const uint8 *bodyPtr) {
- const uint8 *verticesBase = getData(bodyPtr);
- return READ_LE_INT16(verticesBase);
- }
-
- static const BodyShade *getBodyShadesData(const uint8 *bodyPtr, int16 shadeIdx = 0) {
- assert(shadeIdx <= getNumShades(bodyPtr));
- return (const BodyShade*)(getShadesData(bodyPtr) + 2 + (shadeIdx * sizeof(BodyShade)));
- }
-
- static int16 getNumShades(const uint8 *bodyPtr) {
- const uint8 *shadesBase = getShadesData(bodyPtr);
- return READ_LE_INT16(shadesBase);
- }
-
- static int16 getNumShadesBone(const uint8 *bodyPtr, int boneIdx) {
- return getBonesBaseData(bodyPtr, boneIdx)->numOfShades;
- }
-
- static const uint8 *getPolygonData(const uint8 *bodyPtr) {
- const uint8 *shades = (const uint8*)getBodyShadesData(bodyPtr);
- const int16 numShades = getNumShades(bodyPtr);
- if (numShades <= 0) {
- return shades;
- }
- const int16 bones = getNumBones(bodyPtr);
- for (int16 boneIdx = 0; boneIdx < bones; ++boneIdx) {
- int16 numOfShades = getNumShadesBone(bodyPtr, boneIdx);
- shades += numOfShades * 8;
- }
- return shades;
- }
-};
-
class Renderer {
private:
TwinEEngine *_engine;
@@ -254,15 +138,15 @@ private:
ModelData _modelData;
- bool renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr, RenderCommand *renderCmds, const IVec3 &angleVec, const IVec3 &renderPos);
+ bool renderAnimatedModel(ModelData *modelData, const BodyData &bodyData, RenderCommand *renderCmds, const IVec3 &angleVec, const IVec3 &renderPos);
void circleFill(int32 x, int32 y, int32 radius, uint8 color);
- bool renderModelElements(int32 numOfPrimitives, const uint8 *polygonPtr, RenderCommand **renderCmds, ModelData *modelData);
+ bool renderModelElements(int32 numOfPrimitives, const BodyData &bodyData, RenderCommand **renderCmds, ModelData *modelData);
void getCameraAnglePositions(int32 x, int32 y, int32 z);
void applyRotation(IMatrix3x3 *targetMatrix, const IMatrix3x3 *currentMatrix, const IVec3 &angleVec);
- void applyPointsRotation(const I16Vec3 *pointsPtr, int32 numPoints, I16Vec3 *destPoints, const IMatrix3x3 *rotationMatrix);
- void processRotatedElement(IMatrix3x3 *targetMatrix, const I16Vec3 *pointsPtr, int32 rotZ, int32 rotY, int32 rotX, const BonesBaseData *boneData, ModelData *modelData);
- void applyPointsTranslation(const I16Vec3 *pointsPtr, int32 numPoints, I16Vec3 *destPoints, const IMatrix3x3 *translationMatrix, const IVec3 &angleVec);
- void processTranslatedElement(IMatrix3x3 *targetMatrix, const I16Vec3 *pointsPtr, int32 rotX, int32 rotY, int32 rotZ, const BonesBaseData *boneData, ModelData *modelData);
+ void applyPointsRotation(const Common::Array<BodyVertex>& vertices, int32 firstPoint, int32 numPoints, I16Vec3 *destPoints, const IMatrix3x3 *rotationMatrix);
+ void processRotatedElement(IMatrix3x3 *targetMatrix, const Common::Array<BodyVertex>& vertices, int32 rotX, int32 rotY, int32 rotZ, const BodyBone &bone, ModelData *modelData);
+ void applyPointsTranslation(const Common::Array<BodyVertex>& vertices, int32 firstPoint, int32 numPoints, I16Vec3 *destPoints, const IMatrix3x3 *translationMatrix, const IVec3 &angleVec);
+ void processTranslatedElement(IMatrix3x3 *targetMatrix, const Common::Array<BodyVertex>& vertices, int32 rotX, int32 rotY, int32 rotZ, const BodyBone &bone, ModelData *modelData);
void translateGroup(int32 x, int32 y, int32 z);
IVec3 _baseTransPos;
@@ -312,9 +196,9 @@ private:
void computePolygons(int16 polyRenderType, const Vertex *vertices, int32 numVertices);
const RenderCommand *depthSortRenderCommands(int32 numOfPrimitives);
- uint8 *preparePolygons(Common::MemoryReadStream &stream, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData);
- uint8 *prepareSpheres(Common::MemoryReadStream &stream, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData);
- uint8 *prepareLines(Common::MemoryReadStream &stream, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData);
+ uint8 *preparePolygons(const Common::Array<BodyPolygon>& polygons, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData);
+ uint8 *prepareSpheres(const Common::Array<BodySphere>& spheres, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData);
+ uint8 *prepareLines(const Common::Array<BodyLine>& lines, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData);
void baseMatrixTranspose();
@@ -355,18 +239,18 @@ public:
void setBaseRotation(int32 x, int32 y, int32 z, bool transpose = false);
void setOrthoProjection(int32 x, int32 y, int32 z);
- bool renderIsoModel(int32 x, int32 y, int32 z, int32 angleX, int32 angleY, int32 angleZ, const uint8 *bodyPtr);
+ bool renderIsoModel(int32 x, int32 y, int32 z, int32 angleX, int32 angleY, int32 angleZ, const BodyData &bodyData);
/**
* @param angle A value of @c -1 means that the model is automatically rotated
*/
- void renderBehaviourModel(int32 boxLeft, int32 boxTop, int32 boxRight, int32 boxBottom, int32 y, int32 angle, const uint8 *bodyPtr);
+ void renderBehaviourModel(int32 boxLeft, int32 boxTop, int32 boxRight, int32 boxBottom, int32 y, int32 angle, const BodyData &bodyData);
/**
* @param angle A value of @c -1 means that the model is automatically rotated
*/
- void renderBehaviourModel(const Common::Rect &rect, int32 y, int32 angle, const uint8 *bodyPtr);
+ void renderBehaviourModel(const Common::Rect &rect, int32 y, int32 angle, const BodyData &bodyData);
- void renderInventoryItem(int32 x, int32 y, const uint8 *bodyPtr, int32 angle, int32 param);
+ void renderInventoryItem(int32 x, int32 y, const BodyData &bodyData, int32 angle, int32 param);
void renderHolomapVertices(const Vertex vertexCoordinates[3], const Vertex vertexAngles[3]);
};
diff --git a/engines/twine/resources/resources.cpp b/engines/twine/resources/resources.cpp
index 2ff14cd1a4..3a6860389f 100644
--- a/engines/twine/resources/resources.cpp
+++ b/engines/twine/resources/resources.cpp
@@ -34,26 +34,16 @@
namespace TwinE {
Resources::~Resources() {
- for (size_t i = 0; i < ARRAYSIZE(inventoryTable); ++i) {
- free(inventoryTable[i]);
- }
for (size_t i = 0; i < ARRAYSIZE(spriteTable); ++i) {
free(spriteTable[i]);
}
for (size_t i = 0; i < ARRAYSIZE(samplesTable); ++i) {
free(samplesTable[i]);
}
- for (size_t i = 0; i < ARRAYSIZE(bodyTable); ++i) {
- free(bodyTable[i]);
- }
free(fontPtr);
free(spriteShadowPtr);
free(holomapSurfacePtr);
free(holomapImagePtr);
- free(holomapTwinsenModelPtr);
- free(holomapPointModelPtr);
- free(holomapTwinsenArrowPtr);
- free(holomapArrowPtr);
free(_engine->_screens->mainPalette);
}
@@ -142,7 +132,7 @@ void Resources::preloadInventoryItems() {
}
debug("preload %i inventory items", numEntries);
for (int32 i = 0; i < numEntries; i++) {
- inventorySizeTable[i] = HQR::getAllocEntry(&inventoryTable[i], Resources::HQR_INVOBJ_FILE, i);
+ inventoryTable[i].loadFromHQR(Resources::HQR_INVOBJ_FILE, i);
}
}
@@ -179,23 +169,19 @@ void Resources::initResources() {
error("Failed to load holomap image");
}
- holomapTwinsenModelSize = HQR::getAllocEntry(&holomapTwinsenModelPtr, Resources::HQR_RESS_FILE, RESSHQR_HOLOTWINMDL);
- if (holomapTwinsenModelSize == 0) {
+ if (!holomapTwinsenModelPtr.loadFromHQR(Resources::HQR_RESS_FILE, RESSHQR_HOLOTWINMDL)) {
error("Failed to load holomap twinsen model");
}
- holomapPointModelSize = HQR::getAllocEntry(&holomapPointModelPtr, Resources::HQR_RESS_FILE, RESSHQR_HOLOPOINTMDL);
- if (holomapPointModelSize == 0) {
+ if (!holomapPointModelPtr.loadFromHQR(Resources::HQR_RESS_FILE, RESSHQR_HOLOPOINTMDL)) {
error("Failed to load holomap point model");
}
- holomapArrowSize = HQR::getAllocEntry(&holomapArrowPtr, Resources::HQR_RESS_FILE, RESSHQR_HOLOARROWMDL);
- if (holomapArrowSize == 0) {
+ if (!holomapArrowPtr.loadFromHQR(Resources::HQR_RESS_FILE, RESSHQR_HOLOARROWMDL)) {
error("Failed to load holomap arrow model");
}
- holomapTwinsenArrowSize = HQR::getAllocEntry(&holomapTwinsenArrowPtr, Resources::HQR_RESS_FILE, RESSHQR_HOLOTWINARROWMDL);
- if (holomapTwinsenArrowSize == 0) {
+ if (!holomapTwinsenArrowPtr.loadFromHQR(Resources::HQR_RESS_FILE, RESSHQR_HOLOTWINARROWMDL)) {
error("Failed to load holomap twinsen arrow model");
}
diff --git a/engines/twine/resources/resources.h b/engines/twine/resources/resources.h
index 7e88964e44..5785e1fc2e 100644
--- a/engines/twine/resources/resources.h
+++ b/engines/twine/resources/resources.h
@@ -160,9 +160,7 @@ public:
const Common::Array<int32>& getFlaMovieInfo(const Common::String &name) const;
/** Table with all loaded samples */
- uint8 *inventoryTable[NUM_INVENTORY_ITEMS] {nullptr};
- /** Table with all loaded samples sizes */
- uint32 inventorySizeTable[NUM_INVENTORY_ITEMS] {0};
+ BodyData inventoryTable[NUM_INVENTORY_ITEMS];
/** Table with all loaded sprites */
uint8 *spriteTable[NUM_SPRITES] {nullptr};
@@ -173,8 +171,6 @@ public:
AnimData animData[NUM_ANIMS];
/** Actors 3D body table - size of NUM_BODIES */
- uint8 *bodyTable[NUM_BODIES]{nullptr};
- int32 bodyTableSize[NUM_BODIES]{0};
BodyData bodyData[NUM_BODIES];
/** Table with all loaded samples */
@@ -194,14 +190,11 @@ public:
uint8 *holomapSurfacePtr = nullptr;
uint32 holomapImageSize = 0;
uint8 *holomapImagePtr = nullptr;
- uint32 holomapPointModelSize = 0;
- uint8 *holomapPointModelPtr = nullptr;
- uint32 holomapTwinsenModelSize = 0;
- uint8 *holomapTwinsenModelPtr = nullptr;
- uint32 holomapTwinsenArrowSize = 0;
- uint8 *holomapTwinsenArrowPtr = nullptr;
- uint32 holomapArrowSize = 0;
- uint8 *holomapArrowPtr = nullptr;
+
+ BodyData holomapPointModelPtr;
+ BodyData holomapTwinsenModelPtr;
+ BodyData holomapTwinsenArrowPtr;
+ BodyData holomapArrowPtr;
/** Initialize resource pointers */
void initResources();
diff --git a/engines/twine/scene/actor.cpp b/engines/twine/scene/actor.cpp
index b5dd57f227..c8fb42f8f2 100644
--- a/engines/twine/scene/actor.cpp
+++ b/engines/twine/scene/actor.cpp
@@ -188,11 +188,7 @@ int32 Actor::initBody(BodyType bodyIdx, int32 actorIdx, ActorBoundingBox &actorB
if (!(bodyIndex & 0x8000)) {
index = _currentPositionInBodyPtrTab;
_currentPositionInBodyPtrTab++;
- _engine->_resources->bodyTableSize[index] = HQR::getAllocEntry(&_engine->_resources->bodyTable[index], Resources::HQR_BODY_FILE, bodyIndex & 0xFFFF);
- if (_engine->_resources->bodyTableSize[index] == 0) {
- error("HQR ERROR: Loading body entity for actor %i: %i", actorIdx, (int)bodyIdx);
- }
- if (!_engine->_resources->bodyData[index].loadFromBuffer(_engine->_resources->bodyTable[index], _engine->_resources->bodyTableSize[index])) {
+ if (!_engine->_resources->bodyData[index].loadFromHQR(Resources::HQR_BODY_FILE, bodyIndex & 0xFFFF)) {
error("HQR ERROR: Parsing body entity for actor %i: %i", actorIdx, (int)bodyIdx);
}
stream.seek(stream.pos() - sizeof(uint16));
diff --git a/engines/twine/scene/animations.cpp b/engines/twine/scene/animations.cpp
index 22aec815c4..75aa2fbd60 100644
--- a/engines/twine/scene/animations.cpp
+++ b/engines/twine/scene/animations.cpp
@@ -101,8 +101,8 @@ int16 Animations::applyAnimStepTranslation(int32 deltaTime, int32 keyFrameLength
return computedPos;
}
-bool Animations::setModelAnimation(int32 keyframeIdx, const AnimData &animData, uint8 *const bodyPtr, AnimTimerDataStruct *animTimerDataPtr) {
- if (!Model::isAnimated(bodyPtr)) {
+bool Animations::setModelAnimation(int32 keyframeIdx, const AnimData &animData, BodyData &bodyData, AnimTimerDataStruct *animTimerDataPtr) {
+ if (!bodyData.isAnimated()) {
return false;
}
const KeyFrame *keyFrame = animData.getKeyframe(keyframeIdx);
@@ -114,7 +114,7 @@ bool Animations::setModelAnimation(int32 keyframeIdx, const AnimData &animData,
processRotationByAnim = keyFrame->boneframes[0].type;
processLastRotationAngle = ToAngle(keyFrame->boneframes[0].y);
- const int16 numBones = Model::getNumBones(bodyPtr);
+ const int16 numBones = bodyData.getNumBones();
int32 numOfBonesInAnim = animData.getNumBoneframes();
if (numOfBonesInAnim > numBones) {
@@ -130,7 +130,7 @@ bool Animations::setModelAnimation(int32 keyframeIdx, const AnimData &animData,
}
const int32 deltaTime = _engine->lbaTime - remainingFrameTime;
if (deltaTime >= keyFrameLength) {
- copyKeyFrameToState(keyFrame, bodyPtr, numOfBonesInAnim);
+ copyKeyFrameToState(keyFrame, bodyData, numOfBonesInAnim);
animTimerDataPtr->ptr = keyFrame;
animTimerDataPtr->time = _engine->lbaTime;
return true;
@@ -145,19 +145,19 @@ bool Animations::setModelAnimation(int32 keyframeIdx, const AnimData &animData,
int16 boneIdx = 1;
int16 tmpNumOfPoints = MIN<int16>(lastKeyFramePtr->boneframes.size() - 1, numOfBonesInAnim - 1);
do {
- BoneFrame *boneState = Model::getBonesStateData(bodyPtr, boneIdx);
+ BoneFrame *boneState = bodyData.getBoneState(boneIdx);
const BoneFrame &boneFrame = keyFrame->boneframes[boneIdx];
const BoneFrame &lastBoneFrame = lastKeyFramePtr->boneframes[boneIdx];
boneState->type = boneFrame.type;
switch (boneFrame.type) {
- case 0: // allow global rotate
+ case 0:
boneState->x = applyAnimStepRotation(deltaTime, keyFrameLength, boneFrame.x, lastBoneFrame.x);
boneState->y = applyAnimStepRotation(deltaTime, keyFrameLength, boneFrame.y, lastBoneFrame.y);
boneState->z = applyAnimStepRotation(deltaTime, keyFrameLength, boneFrame.z, lastBoneFrame.z);
break;
- case 1: // disallow global rotate
- case 2: // disallow global rotate + hide
+ case 1:
+ case 2:
boneState->x = applyAnimStepTranslation(deltaTime, keyFrameLength, boneFrame.x, lastBoneFrame.x);
boneState->y = applyAnimStepTranslation(deltaTime, keyFrameLength, boneFrame.y, lastBoneFrame.y);
boneState->z = applyAnimStepTranslation(deltaTime, keyFrameLength, boneFrame.z, lastBoneFrame.z);
@@ -172,8 +172,8 @@ bool Animations::setModelAnimation(int32 keyframeIdx, const AnimData &animData,
return false;
}
-void Animations::setAnimAtKeyframe(int32 keyframeIdx, const AnimData &animData, uint8 *const bodyPtr, AnimTimerDataStruct *animTimerDataPtr) {
- if (!Model::isAnimated(bodyPtr)) {
+void Animations::setAnimAtKeyframe(int32 keyframeIdx, const AnimData &animData, BodyData &bodyData, AnimTimerDataStruct *animTimerDataPtr) {
+ if (!bodyData.isAnimated()) {
return;
}
@@ -194,18 +194,18 @@ void Animations::setAnimAtKeyframe(int32 keyframeIdx, const AnimData &animData,
animTimerDataPtr->ptr = animData.getKeyframe(keyframeIdx);
animTimerDataPtr->time = _engine->lbaTime;
- const int16 numBones = Model::getNumBones(bodyPtr);
+ const int16 numBones = bodyData.getNumBones();
int16 numOfBonesInAnim = animData.getNumBoneframes();
if (numOfBonesInAnim > numBones) {
numOfBonesInAnim = numBones;
}
- copyKeyFrameToState(keyFrame, bodyPtr, numOfBonesInAnim);
+ copyKeyFrameToState(keyFrame, bodyData, numOfBonesInAnim);
}
-void Animations::stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr) {
- if (!Model::isAnimated(bodyPtr)) {
+void Animations::stockAnimation(const BodyData &bodyData, AnimTimerDataStruct *animTimerDataPtr) {
+ if (!bodyData.isAnimated()) {
return;
}
@@ -215,22 +215,22 @@ void Animations::stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *animT
animTimerDataPtr->time = _engine->lbaTime;
KeyFrame *keyframe = &animKeyframeBuf[animKeyframeBufIdx++];
animTimerDataPtr->ptr = keyframe;
- copyStateToKeyFrame(keyframe, bodyPtr);
+ copyStateToKeyFrame(keyframe, bodyData);
}
-void Animations::copyStateToKeyFrame(KeyFrame *keyframe, const uint8 *bodyPtr) const {
- const int32 numBones = Model::getNumBones(bodyPtr);
+void Animations::copyStateToKeyFrame(KeyFrame *keyframe, const BodyData &bodyData) const {
+ const int32 numBones = bodyData.getNumBones();
keyframe->boneframes.clear();
keyframe->boneframes.reserve(numBones);
for (int32 i = 0; i < numBones; ++i) {
- const BoneFrame *boneState = Model::getBonesStateData(bodyPtr, i);
+ const BoneFrame *boneState = bodyData.getBoneState(i);
keyframe->boneframes.push_back(*boneState);
}
}
-void Animations::copyKeyFrameToState(const KeyFrame *keyframe, uint8 *bodyPtr, int32 numBones) const {
+void Animations::copyKeyFrameToState(const KeyFrame *keyframe, BodyData &bodyData, int32 numBones) const {
for (int32 i = 0; i < numBones; ++i) {
- BoneFrame *boneState = Model::getBonesStateData(bodyPtr, i);
+ BoneFrame *boneState = bodyData.getBoneState(i);
*boneState = keyframe->boneframes[i];
}
}
@@ -436,10 +436,10 @@ bool Animations::initAnim(AnimationTypes newAnim, AnimType animType, AnimationTy
if (actor->previousAnimIdx == -1) {
// if no previous animation
- setAnimAtKeyframe(0, _engine->_resources->animData[animIndex], _engine->_resources->bodyTable[actor->entity], &actor->animTimerData);
+ setAnimAtKeyframe(0, _engine->_resources->animData[animIndex], _engine->_resources->bodyData[actor->entity], &actor->animTimerData);
} else {
// interpolation between animations
- stockAnimation(_engine->_resources->bodyTable[actor->entity], &actor->animTimerData);
+ stockAnimation(_engine->_resources->bodyData[actor->entity], &actor->animTimerData);
}
actor->previousAnimIdx = animIndex;
@@ -568,7 +568,7 @@ void Animations::processActorAnimations(int32 actorIdx) { // DoAnim
const AnimData &animData = _engine->_resources->animData[actor->previousAnimIdx];
bool keyFramePassed = false;
- if (Model::isAnimated(_engine->_resources->bodyTable[actor->entity])) {
+ if (_engine->_resources->bodyData[actor->entity].isAnimated()) {
keyFramePassed = verifyAnimAtKeyframe(actor->animPosition, animData, &actor->animTimerData);
}
diff --git a/engines/twine/scene/animations.h b/engines/twine/scene/animations.h
index b28e2fd761..2abe2bcbe8 100644
--- a/engines/twine/scene/animations.h
+++ b/engines/twine/scene/animations.h
@@ -45,8 +45,8 @@ private:
*/
bool verifyAnimAtKeyframe(int32 keyframeIdx, const AnimData &animData, AnimTimerDataStruct *animTimerDataPtr);
- void copyKeyFrameToState(const KeyFrame *keyframe, uint8 *bodyPtr, int32 numBones) const;
- void copyStateToKeyFrame(KeyFrame *keyframe, const uint8 *bodyPtr) const;
+ void copyKeyFrameToState(const KeyFrame *keyframe, BodyData &bodyData, int32 numBones) const;
+ void copyStateToKeyFrame(KeyFrame *keyframe, const BodyData &bodyData) const;
int animKeyframeBufIdx = 0;
KeyFrame animKeyframeBuf[32];
@@ -75,19 +75,19 @@ public:
* Set animation keyframe
* @param keyframIdx Animation keyframe index
* @param animData Animation data
- * @param bodyPtr Body model poitner
+ * @param bodyData Body model data
* @param animTimerDataPtr Animation time data
*/
- void setAnimAtKeyframe(int32 keyframeIdx, const AnimData &animData, uint8 *const bodyPtr, AnimTimerDataStruct *animTimerDataPtr);
+ void setAnimAtKeyframe(int32 keyframeIdx, const AnimData &animData, BodyData &bodyData, AnimTimerDataStruct *animTimerDataPtr);
/**
* Set new body animation
* @param keyframeIdx Animation key frame index
* @param animData Animation data
- * @param bodyPtr Body model poitner
+ * @param bodyData Body model data
* @param animTimerDataPtr Animation time data
*/
- bool setModelAnimation(int32 keyframeIdx, const AnimData &animData, uint8 *const bodyPtr, AnimTimerDataStruct *animTimerDataPtr);
+ bool setModelAnimation(int32 keyframeIdx, const AnimData &animData, BodyData &bodyData, AnimTimerDataStruct *animTimerDataPtr);
/**
* Get entity anim index (This is taken from File3D entities)
@@ -98,10 +98,10 @@ public:
/**
* Stock animation - copy the next keyFrame from a different buffer
- * @param bodyPtr Body model poitner
+ * @param bodyData Body model data
* @param animTimerDataPtr Animation time data
*/
- void stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr);
+ void stockAnimation(const BodyData &bodyData, AnimTimerDataStruct *animTimerDataPtr);
/**
* Initialize animation
diff --git a/engines/twine/scene/gamestate.cpp b/engines/twine/scene/gamestate.cpp
index bc46587b87..38f0c9657c 100644
--- a/engines/twine/scene/gamestate.cpp
+++ b/engines/twine/scene/gamestate.cpp
@@ -321,11 +321,11 @@ void GameState::processFoundItem(int32 item) {
const int32 itemCameraY = _engine->_grid->newCamera.y * BRICK_HEIGHT;
const int32 itemCameraZ = _engine->_grid->newCamera.z * BRICK_SIZE;
- uint8 *bodyPtr = _engine->_resources->bodyTable[_engine->_scene->sceneHero->entity];
+ BodyData &bodyData = _engine->_resources->bodyData[_engine->_scene->sceneHero->entity];
const int32 bodyX = _engine->_scene->sceneHero->pos.x - itemCameraX;
const int32 bodyY = _engine->_scene->sceneHero->pos.y - itemCameraY;
const int32 bodyZ = _engine->_scene->sceneHero->pos.z - itemCameraZ;
- _engine->_renderer->renderIsoModel(bodyX, bodyY, bodyZ, ANGLE_0, ANGLE_45, ANGLE_0, bodyPtr);
+ _engine->_renderer->renderIsoModel(bodyX, bodyY, bodyZ, ANGLE_0, ANGLE_45, ANGLE_0, bodyData);
_engine->_interface->setClip(_engine->_redraw->renderRect);
const int32 itemX = (_engine->_scene->sceneHero->pos.x + BRICK_HEIGHT) / BRICK_SIZE;
@@ -365,7 +365,7 @@ void GameState::processFoundItem(int32 item) {
AnimTimerDataStruct tmpAnimTimer = _engine->_scene->sceneHero->animTimerData;
- _engine->_animations->stockAnimation(bodyPtr, &_engine->_scene->sceneHero->animTimerData);
+ _engine->_animations->stockAnimation(bodyData, &_engine->_scene->sceneHero->animTimerData);
uint currentAnimState = 0;
@@ -391,14 +391,14 @@ void GameState::processFoundItem(int32 item) {
_engine->_interface->resetClip();
initEngineProjections();
- if (_engine->_animations->setModelAnimation(currentAnimState, currentAnimData, bodyPtr, &_engine->_scene->sceneHero->animTimerData)) {
+ if (_engine->_animations->setModelAnimation(currentAnimState, currentAnimData, bodyData, &_engine->_scene->sceneHero->animTimerData)) {
currentAnimState++; // keyframe
if (currentAnimState >= currentAnimData.getNumKeyframes()) {
currentAnimState = currentAnimData.getLoopFrame();
}
}
- _engine->_renderer->renderIsoModel(bodyX, bodyY, bodyZ, ANGLE_0, ANGLE_45, ANGLE_0, bodyPtr);
+ _engine->_renderer->renderIsoModel(bodyX, bodyY, bodyZ, ANGLE_0, ANGLE_45, ANGLE_0, bodyData);
_engine->_interface->setClip(_engine->_redraw->renderRect);
_engine->_grid->drawOverModelActor(itemX, itemY, itemZ);
_engine->_redraw->addRedrawArea(_engine->_redraw->renderRect);
@@ -495,8 +495,8 @@ void GameState::processGameoverAnimation() {
_engine->setPalette(_engine->_screens->paletteRGBA);
_engine->flip();
_engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
- uint8 *gameOverPtr = nullptr;
- if (HQR::getAllocEntry(&gameOverPtr, Resources::HQR_RESS_FILE, RESSHQR_GAMEOVERMDL) == 0) {
+ BodyData gameOverPtr;
+ if (!gameOverPtr.loadFromHQR(Resources::HQR_RESS_FILE, RESSHQR_GAMEOVERMDL)) {
return;
}
@@ -512,7 +512,6 @@ void GameState::processGameoverAnimation() {
ScopedFPS scopedFps(66);
_engine->readKeys();
if (_engine->shouldQuit()) {
- free(gameOverPtr);
return;
}
@@ -536,7 +535,6 @@ void GameState::processGameoverAnimation() {
_engine->delaySkip(2000);
_engine->_interface->resetClip();
- free(gameOverPtr);
_engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
_engine->flip();
initEngineProjections();
Commit: b081f3e71158084785b7f84339f7a489c847e6a0
https://github.com/scummvm/scummvm/commit/b081f3e71158084785b7f84339f7a489c847e6a0
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2021-03-27T13:35:27+01:00
Commit Message:
TWINE: doxygen
Changed paths:
engines/twine/parser/entity.h
diff --git a/engines/twine/parser/entity.h b/engines/twine/parser/entity.h
index 5cef8863e4..893ee68f0c 100644
--- a/engines/twine/parser/entity.h
+++ b/engines/twine/parser/entity.h
@@ -32,9 +32,9 @@
namespace TwinE {
struct EntityBody {
- int index; /**< index in file3d.hqr */
+ int index; /**< index in file3d.hqr */
ActorBoundingBox actorBoundingBox;
- int bodyIndex; /**< index in body.hqr */
+ int bodyIndex; /**< index in body.hqr */
};
struct EntityAnim {
@@ -64,6 +64,9 @@ struct EntityAnim {
Common::Array<Action> _actions;
};
+/**
+ * @brief Associate 3d models from body hqr with animations from anim.hqr for the game characters
+ */
class EntityData : public Parser {
private:
Common::Array<EntityBody> _bodies;
Commit: 8c76c1fac7c9f97fe45a074035ee0ce9e3a31597
https://github.com/scummvm/scummvm/commit/8c76c1fac7c9f97fe45a074035ee0ce9e3a31597
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2021-03-27T13:35:27+01:00
Commit Message:
TWINE: use EntityData
Changed paths:
engines/twine/parser/entity.cpp
engines/twine/resources/resources.cpp
engines/twine/scene/actor.cpp
engines/twine/scene/actor.h
engines/twine/scene/animations.cpp
engines/twine/scene/gamestate.cpp
engines/twine/scene/scene.cpp
diff --git a/engines/twine/parser/entity.cpp b/engines/twine/parser/entity.cpp
index 518c815c52..778cbf986a 100644
--- a/engines/twine/parser/entity.cpp
+++ b/engines/twine/parser/entity.cpp
@@ -156,6 +156,8 @@ bool EntityData::loadAnim(Common::SeekableReadStream &stream) {
}
bool EntityData::loadFromStream(Common::SeekableReadStream &stream) {
+ _animations.clear();
+ _bodies.clear();
do {
const uint8 opcode = stream.readByte();
if (opcode == 1) {
diff --git a/engines/twine/resources/resources.cpp b/engines/twine/resources/resources.cpp
index 3a6860389f..bff15c20f2 100644
--- a/engines/twine/resources/resources.cpp
+++ b/engines/twine/resources/resources.cpp
@@ -195,6 +195,13 @@ void Resources::initResources() {
preloadSamples();
preloadInventoryItems();
+ const int32 bodyCount = HQR::numEntries(Resources::HQR_BODY_FILE);
+ for (int32 i = 0; i < bodyCount; ++i) {
+ if (!bodyData[i].loadFromHQR(Resources::HQR_BODY_FILE, i)) {
+ error("HQR ERROR: Parsing body entity for model %i failed", i);
+ }
+ }
+
loadFlaInfo();
}
diff --git a/engines/twine/scene/actor.cpp b/engines/twine/scene/actor.cpp
index c8fb42f8f2..3fb58bde8e 100644
--- a/engines/twine/scene/actor.cpp
+++ b/engines/twine/scene/actor.cpp
@@ -43,15 +43,6 @@ namespace TwinE {
Actor::Actor(TwinEEngine *engine) : _engine(engine) {
}
-Actor::~Actor() {
- _engine->_scene->getActor(OWN_ACTOR_SCENE_INDEX)->entityDataPtr = nullptr;
- free(_heroEntityNORMAL);
- free(_heroEntityATHLETIC);
- free(_heroEntityAGGRESSIVE);
- free(_heroEntityDISCRETE);
- free(_heroEntityPROTOPACK);
-}
-
void Actor::restartHeroScene() {
ActorStruct *sceneHero = _engine->_scene->sceneHero;
sceneHero->controlMode = ControlMode::kManual;
@@ -77,28 +68,27 @@ void Actor::restartHeroScene() {
cropBottomScreen = 0;
}
-int32 Actor::loadBehaviourEntity(ActorStruct *sceneHero, uint8 **ptr, int16 &bodyAnimIndex, int32 index) {
- const int32 size = HQR::getAllocEntry(ptr, Resources::HQR_FILE3D_FILE, index);
- if (size == 0) {
+void Actor::loadBehaviourEntity(ActorStruct *actor, EntityData &entityData, int16 &bodyAnimIndex, int32 index) {
+ if (!entityData.loadFromHQR(Resources::HQR_FILE3D_FILE, index)) {
error("Failed to load actor 3d data for index: %i", index);
}
- sceneHero->entityDataPtr = *ptr;
- sceneHero->entityDataSize = size;
- bodyAnimIndex = _engine->_animations->getBodyAnimIndex(AnimationTypes::kStanding);
+
+ actor->entityData = &entityData;
+ bodyAnimIndex = entityData.getAnimIndex(AnimationTypes::kStanding);
if (bodyAnimIndex == -1) {
error("Could not find animation data for 3d data with index %i", index);
}
- return size;
}
void Actor::loadHeroEntities() {
ActorStruct *sceneHero = _engine->_scene->sceneHero;
- _heroEntityATHLETICSize = loadBehaviourEntity(sceneHero, &_heroEntityATHLETIC, heroAnimIdxATHLETIC, FILE3DHQR_HEROATHLETIC);
- _heroEntityAGGRESSIVESize = loadBehaviourEntity(sceneHero, &_heroEntityAGGRESSIVE, heroAnimIdxAGGRESSIVE, FILE3DHQR_HEROAGGRESSIVE);
- _heroEntityDISCRETESize = loadBehaviourEntity(sceneHero, &_heroEntityDISCRETE, heroAnimIdxDISCRETE, FILE3DHQR_HERODISCRETE);
- _heroEntityPROTOPACKSize = loadBehaviourEntity(sceneHero, &_heroEntityPROTOPACK, heroAnimIdxPROTOPACK, FILE3DHQR_HEROPROTOPACK);
- _heroEntityNORMALSize = loadBehaviourEntity(sceneHero, &_heroEntityNORMAL, heroAnimIdxNORMAL, FILE3DHQR_HERONORMAL);
+ loadBehaviourEntity(sceneHero, _heroEntityATHLETIC, heroAnimIdxATHLETIC, FILE3DHQR_HEROATHLETIC);
+ loadBehaviourEntity(sceneHero, _heroEntityAGGRESSIVE, heroAnimIdxAGGRESSIVE, FILE3DHQR_HEROAGGRESSIVE);
+ loadBehaviourEntity(sceneHero, _heroEntityDISCRETE, heroAnimIdxDISCRETE, FILE3DHQR_HERODISCRETE);
+ loadBehaviourEntity(sceneHero, _heroEntityPROTOPACK, heroAnimIdxPROTOPACK, FILE3DHQR_HEROPROTOPACK);
+ loadBehaviourEntity(sceneHero, _heroEntityNORMAL, heroAnimIdxNORMAL, FILE3DHQR_HERONORMAL);
+ _engine->_animations->currentActorAnimExtraPtr = AnimationTypes::kStanding;
sceneHero->animExtraPtr = _engine->_animations->currentActorAnimExtraPtr;
}
@@ -107,28 +97,23 @@ void Actor::setBehaviour(HeroBehaviourType behaviour) {
switch (behaviour) {
case HeroBehaviourType::kNormal:
heroBehaviour = behaviour;
- sceneHero->entityDataPtr = _heroEntityNORMAL;
- sceneHero->entityDataSize = _heroEntityNORMALSize;
+ sceneHero->entityData = &_heroEntityNORMAL;
break;
case HeroBehaviourType::kAthletic:
heroBehaviour = behaviour;
- sceneHero->entityDataPtr = _heroEntityATHLETIC;
- sceneHero->entityDataSize = _heroEntityATHLETICSize;
+ sceneHero->entityData = &_heroEntityATHLETIC;
break;
case HeroBehaviourType::kAggressive:
heroBehaviour = behaviour;
- sceneHero->entityDataPtr = _heroEntityAGGRESSIVE;
- sceneHero->entityDataSize = _heroEntityAGGRESSIVESize;
+ sceneHero->entityData = &_heroEntityAGGRESSIVE;
break;
case HeroBehaviourType::kDiscrete:
heroBehaviour = behaviour;
- sceneHero->entityDataPtr = _heroEntityDISCRETE;
- sceneHero->entityDataSize = _heroEntityDISCRETESize;
+ sceneHero->entityData = &_heroEntityDISCRETE;
break;
case HeroBehaviourType::kProtoPack:
heroBehaviour = behaviour;
- sceneHero->entityDataPtr = _heroEntityPROTOPACK;
- sceneHero->entityDataSize = _heroEntityPROTOPACKSize;
+ sceneHero->entityData = &_heroEntityPROTOPACK;
break;
};
@@ -163,61 +148,17 @@ int32 Actor::getTextIdForBehaviour() const {
return (int32)heroBehaviour;
}
-// see Animations::getBodyAnimIndex
int32 Actor::initBody(BodyType bodyIdx, int32 actorIdx, ActorBoundingBox &actorBoundingBox) {
if (bodyIdx == BodyType::btNone) {
return -1;
}
ActorStruct *actor = _engine->_scene->getActor(actorIdx);
- Common::MemorySeekableReadWriteStream stream(actor->entityDataPtr, actor->entityDataSize);
- do {
- const uint8 type = stream.readByte();
- if (type == 0xFF) {
- return -1;
- }
-
- BodyType idx = (BodyType)stream.readByte();
- const int32 pos = stream.pos();
- const uint8 size = stream.readByte();
- if (type == 1) { // 1 = body data - 3 is animdata
- if (idx == bodyIdx) {
- const int16 bodyIndex = stream.readUint16LE();
-
- // TODO: move into resources class
- int32 index;
- if (!(bodyIndex & 0x8000)) {
- index = _currentPositionInBodyPtrTab;
- _currentPositionInBodyPtrTab++;
- if (!_engine->_resources->bodyData[index].loadFromHQR(Resources::HQR_BODY_FILE, bodyIndex & 0xFFFF)) {
- error("HQR ERROR: Parsing body entity for actor %i: %i", actorIdx, (int)bodyIdx);
- }
- stream.seek(stream.pos() - sizeof(uint16));
- stream.writeUint16LE(index + 0x8000);
- } else {
- index = bodyIndex & 0x7FFF;
- }
-
- actorBoundingBox.hasBoundingBox = stream.readByte();
- if (!actorBoundingBox.hasBoundingBox) {
- return index;
- }
-
- if (stream.readByte() != ActionType::ACTION_ZV) {
- return index;
- }
-
- actorBoundingBox.bbox.mins.x = stream.readSint16LE();
- actorBoundingBox.bbox.mins.y = stream.readSint16LE();
- actorBoundingBox.bbox.mins.z = stream.readSint16LE();
- actorBoundingBox.bbox.maxs.x = stream.readSint16LE();
- actorBoundingBox.bbox.maxs.y = stream.readSint16LE();
- actorBoundingBox.bbox.maxs.z = stream.readSint16LE();
-
- return index;
- }
- }
- stream.seek(pos + size);
- } while (1);
+ const EntityBody* body = actor->entityData->getBody((int)bodyIdx);
+ if (body == nullptr) {
+ return -1;
+ }
+ actorBoundingBox = body->actorBoundingBox;
+ return body->bodyIndex;
}
void Actor::initModelActor(BodyType bodyIdx, int16 actorIdx) {
@@ -450,23 +391,16 @@ void Actor::processActorExtraBonus(int32 actorIdx) { // GiveExtraBonus
}
}
-void Actor::clearBodyTable() {
- _currentPositionInBodyPtrTab = 0;
-}
-
-ActorStruct::~ActorStruct() {
- free(entityDataPtr);
-}
-
void ActorStruct::loadModel(int32 modelIndex) {
entity = modelIndex;
if (!staticFlags.bIsSpriteActor) {
debug(1, "Init actor with model %i", modelIndex);
- entityDataSize = HQR::getAllocEntry(&entityDataPtr, Resources::HQR_FILE3D_FILE, modelIndex);
+ if (!_entityData.loadFromHQR(Resources::HQR_FILE3D_FILE, modelIndex)) {
+ error("Failed to load entity data for index %i", modelIndex);
+ }
+ entityData = &_entityData;
} else {
- entityDataSize = 0;
- free(entityDataPtr);
- entityDataPtr = nullptr;
+ entityData = nullptr;
}
}
diff --git a/engines/twine/scene/actor.h b/engines/twine/scene/actor.h
index 412eabda2a..ab0125dc52 100644
--- a/engines/twine/scene/actor.h
+++ b/engines/twine/scene/actor.h
@@ -159,9 +159,8 @@ private:
ShapeType _brickShape = ShapeType::kNone; // field_3
bool _brickCausesDamage = false;
+ EntityData _entityData;
public:
- ~ActorStruct();
-
StaticFlagsStruct staticFlags;
DynamicFlagsStruct dynamicFlags;
@@ -180,8 +179,7 @@ public:
AnimationTypes animExtra = AnimationTypes::kStanding; //field_2
AnimationTypes animExtraPtr = AnimationTypes::kAnimNone;
int32 sprite = 0; // field_8
- uint8 *entityDataPtr = nullptr;
- int32 entityDataSize = 0;
+ EntityData *entityData = nullptr;
bool isAttackWeaponAnimationActive() const;
bool isAttackAnimationActive() const;
@@ -261,23 +259,15 @@ private:
TwinEEngine *_engine;
/** Hero 3D entity for normal behaviour */
- uint8 *_heroEntityNORMAL = nullptr;
- int32 _heroEntityNORMALSize = 0;
+ EntityData _heroEntityNORMAL;
/** Hero 3D entity for athletic behaviour */
- uint8 *_heroEntityATHLETIC = nullptr;
- int32 _heroEntityATHLETICSize = 0;
+ EntityData _heroEntityATHLETIC;
/** Hero 3D entity for aggressive behaviour */
- uint8 *_heroEntityAGGRESSIVE = nullptr;
- int32 _heroEntityAGGRESSIVESize = 0;
+ EntityData _heroEntityAGGRESSIVE;
/** Hero 3D entity for discrete behaviour */
- uint8 *_heroEntityDISCRETE = nullptr;
- int32 _heroEntityDISCRETESize = 0;
+ EntityData _heroEntityDISCRETE;
/** Hero 3D entity for protopack behaviour */
- uint8 *_heroEntityPROTOPACK = nullptr;
- int32 _heroEntityPROTOPACKSize = 0;
-
- /** Current position in body table */
- int32 _currentPositionInBodyPtrTab;
+ EntityData _heroEntityPROTOPACK;
void initSpriteActor(int32 actorIdx);
@@ -288,11 +278,10 @@ private:
*/
int32 initBody(BodyType bodyIdx, int32 actorIdx, ActorBoundingBox &actorBoundingBox);
- int32 loadBehaviourEntity(ActorStruct *sceneHero, uint8 **ptr, int16 &bodyAnimIndex, int32 index);
+ void loadBehaviourEntity(ActorStruct *actor, EntityData &entityData, int16 &bodyAnimIndex, int32 index);
public:
Actor(TwinEEngine *engine);
- ~Actor();
ActorStruct *processActorPtr = nullptr;
@@ -323,8 +312,6 @@ public:
/** Hero anim for behaviour menu */
int16 heroAnimIdx[4];
- void clearBodyTable();
-
/** Restart hero variables while opening new scenes */
void restartHeroScene();
diff --git a/engines/twine/scene/animations.cpp b/engines/twine/scene/animations.cpp
index 75aa2fbd60..48cf51222e 100644
--- a/engines/twine/scene/animations.cpp
+++ b/engines/twine/scene/animations.cpp
@@ -56,10 +56,7 @@ Animations::Animations(TwinEEngine *engine) : _engine(engine) {
int32 Animations::getBodyAnimIndex(AnimationTypes animIdx, int32 actorIdx) {
ActorStruct *actor = _engine->_scene->getActor(actorIdx);
- // TODO: cache this
- EntityData entityData;
- entityData.loadFromBuffer(actor->entityDataPtr, actor->entityDataSize);
- const int32 bodyAnimIndex = entityData.getAnimIndex(animIdx);
+ const int32 bodyAnimIndex = actor->entityData->getAnimIndex(animIdx);
if (bodyAnimIndex != -1) {
currentActorAnimExtraPtr = animIdx;
}
@@ -270,14 +267,11 @@ bool Animations::verifyAnimAtKeyframe(int32 keyframeIdx, const AnimData &animDat
void Animations::processAnimActions(int32 actorIdx) {
ActorStruct *actor = _engine->_scene->getActor(actorIdx);
- if (actor->entityDataPtr == nullptr || actor->animExtraPtr == AnimationTypes::kAnimNone) {
+ if (actor->entityData == nullptr || actor->animExtraPtr == AnimationTypes::kAnimNone) {
return;
}
- // TODO: cache this
- EntityData entityData;
- entityData.loadFromBuffer(actor->entityDataPtr, actor->entityDataSize);
- const Common::Array<EntityAnim::Action> *actions = entityData.getActions(actor->animExtraPtr);
+ const Common::Array<EntityAnim::Action> *actions = actor->entityData->getActions(actor->animExtraPtr);
if (actions == nullptr) {
return;
}
diff --git a/engines/twine/scene/gamestate.cpp b/engines/twine/scene/gamestate.cpp
index 38f0c9657c..e5933e4630 100644
--- a/engines/twine/scene/gamestate.cpp
+++ b/engines/twine/scene/gamestate.cpp
@@ -82,8 +82,6 @@ void GameState::initGameStateVars() {
_engine->_scene->initSceneVars();
Common::fill(&holomapFlags[0], &holomapFlags[NUM_LOCATIONS], 0);
-
- _engine->_actor->clearBodyTable();
}
void GameState::initHeroVars() {
diff --git a/engines/twine/scene/scene.cpp b/engines/twine/scene/scene.cpp
index 9ae9f561ec..540ce7fc60 100644
--- a/engines/twine/scene/scene.cpp
+++ b/engines/twine/scene/scene.cpp
@@ -461,7 +461,6 @@ void Scene::resetScene() {
_engine->_redraw->overlayList[i].info0 = -1;
}
- _engine->_actor->clearBodyTable();
_engine->_screens->useAlternatePalette = false;
}
Commit: 7cfb6f00d5280f4f170b1731718572cfbe01cc22
https://github.com/scummvm/scummvm/commit/7cfb6f00d5280f4f170b1731718572cfbe01cc22
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2021-03-27T13:35:28+01:00
Commit Message:
TWINE: updated actor bbox code and minor cleanup
Changed paths:
engines/twine/scene/actor.cpp
diff --git a/engines/twine/scene/actor.cpp b/engines/twine/scene/actor.cpp
index 3fb58bde8e..f88256d747 100644
--- a/engines/twine/scene/actor.cpp
+++ b/engines/twine/scene/actor.cpp
@@ -178,10 +178,7 @@ void Actor::initModelActor(BodyType bodyIdx, int16 actorIdx) {
if (entityIdx == -1) {
localActor->body = BodyType::btNone;
localActor->entity = -1;
-
- BoundingBox &bbox = localActor->boudingBox;
- bbox.mins = IVec3();
- bbox.maxs = IVec3();
+ localActor->boudingBox = BoundingBox();
debug("Failed to initialize body %i for actor %i", (int)bodyIdx, actorIdx);
return;
}
@@ -194,22 +191,14 @@ void Actor::initModelActor(BodyType bodyIdx, int16 actorIdx) {
localActor->body = bodyIdx;
if (actorBoundingBox.hasBoundingBox) {
- BoundingBox &bbox = localActor->boudingBox;
- bbox.mins.x = actorBoundingBox.bbox.mins.x;
- bbox.maxs.x = actorBoundingBox.bbox.maxs.x;
- bbox.mins.y = actorBoundingBox.bbox.mins.y;
- bbox.maxs.y = actorBoundingBox.bbox.maxs.y;
- bbox.mins.z = actorBoundingBox.bbox.mins.z;
- bbox.maxs.z = actorBoundingBox.bbox.maxs.z;
+ localActor->boudingBox = actorBoundingBox.bbox;
} else {
- BoundingBox &bbox = localActor->boudingBox;
const BodyData &bd = _engine->_resources->bodyData[localActor->entity];
- bbox.mins.y = bd.bbox.mins.y;
- bbox.maxs.y = bd.bbox.maxs.y;
+ localActor->boudingBox = bd.bbox;
int32 result = 0;
- const int32 distX = bd.bbox.maxs.x - bd.bbox.mins.x;
- const int32 distZ = bd.bbox.maxs.z - bd.bbox.mins.z;
+ const int32 distX = localActor->boudingBox.maxs.x - localActor->boudingBox.mins.x;
+ const int32 distZ = localActor->boudingBox.maxs.z - localActor->boudingBox.mins.z;
if (localActor->staticFlags.bUseMiniZv) {
// take smaller for bound
result = MIN(distX, distZ);
@@ -223,10 +212,10 @@ void Actor::initModelActor(BodyType bodyIdx, int16 actorIdx) {
result >>= 2;
}
- bbox.mins.x = -result;
- bbox.maxs.x = result;
- bbox.mins.z = -result;
- bbox.maxs.z = result;
+ localActor->boudingBox.mins.x = -result;
+ localActor->boudingBox.maxs.x = result;
+ localActor->boudingBox.mins.z = -result;
+ localActor->boudingBox.maxs.z = result;
}
}
@@ -274,13 +263,9 @@ void Actor::resetActor(int16 actorIdx) {
actor->actorIdx = actorIdx;
actor->body = BodyType::btNormal;
actor->anim = AnimationTypes::kStanding;
- actor->pos.x = 0;
- actor->pos.y = -1;
- actor->pos.z = 0;
+ actor->pos = IVec3(0, -1, 0);
- BoundingBox &bbox = actor->boudingBox;
- bbox.mins = IVec3();
- bbox.maxs = IVec3();
+ actor->boudingBox = BoundingBox();
actor->angle = 0;
actor->speed = 40;
@@ -304,9 +289,7 @@ void Actor::resetActor(int16 actorIdx) {
actor->armor = 1;
actor->hitBy = -1;
actor->lastRotationAngle = ANGLE_0;
- actor->lastPos.x = 0;
- actor->lastPos.y = 0;
- actor->lastPos.z = 0;
+ actor->lastPos = IVec3();
actor->entity = -1;
actor->previousAnimIdx = -1;
actor->animType = AnimType::kAnimationTypeLoop;
Commit: fca24a4eb7ab056586c492f026d0f04b83e1f777
https://github.com/scummvm/scummvm/commit/fca24a4eb7ab056586c492f026d0f04b83e1f777
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2021-03-27T13:35:28+01:00
Commit Message:
TWINE: use I16Vec3 in animation code
Changed paths:
engines/twine/scene/animations.cpp
engines/twine/scene/animations.h
diff --git a/engines/twine/scene/animations.cpp b/engines/twine/scene/animations.cpp
index 48cf51222e..3359a8c895 100644
--- a/engines/twine/scene/animations.cpp
+++ b/engines/twine/scene/animations.cpp
@@ -104,9 +104,9 @@ bool Animations::setModelAnimation(int32 keyframeIdx, const AnimData &animData,
}
const KeyFrame *keyFrame = animData.getKeyframe(keyframeIdx);
- currentStepX = keyFrame->x;
- currentStepY = keyFrame->y;
- currentStepZ = keyFrame->z;
+ currentStep.x = keyFrame->x;
+ currentStep.y = keyFrame->y;
+ currentStep.z = keyFrame->z;
processRotationByAnim = keyFrame->boneframes[0].type;
processLastRotationAngle = ToAngle(keyFrame->boneframes[0].y);
@@ -181,9 +181,9 @@ void Animations::setAnimAtKeyframe(int32 keyframeIdx, const AnimData &animData,
const KeyFrame *keyFrame = animData.getKeyframe(keyframeIdx);
- currentStepX = keyFrame->x;
- currentStepY = keyFrame->y;
- currentStepZ = keyFrame->z;
+ currentStep.x = keyFrame->x;
+ currentStep.y = keyFrame->y;
+ currentStep.z = keyFrame->z;
processRotationByAnim = keyFrame->boneframes[0].type;
processLastRotationAngle = ToAngle(keyFrame->boneframes[0].y);
@@ -243,9 +243,9 @@ bool Animations::verifyAnimAtKeyframe(int32 keyframeIdx, const AnimData &animDat
const int32 deltaTime = _engine->lbaTime - remainingFrameTime;
- currentStepX = keyFrame->x;
- currentStepY = keyFrame->y;
- currentStepZ = keyFrame->z;
+ currentStep.x = keyFrame->x;
+ currentStep.y = keyFrame->y;
+ currentStep.z = keyFrame->z;
const BoneFrame &boneFrame = keyFrame->boneframes[0];
processRotationByAnim = boneFrame.type;
@@ -258,9 +258,9 @@ bool Animations::verifyAnimAtKeyframe(int32 keyframeIdx, const AnimData &animDat
}
processLastRotationAngle = (processLastRotationAngle * deltaTime) / keyFrameLength;
- currentStepX = (currentStepX * deltaTime) / keyFrameLength;
- currentStepY = (currentStepY * deltaTime) / keyFrameLength;
- currentStepZ = (currentStepZ * deltaTime) / keyFrameLength;
+ currentStep.x = (currentStep.x * deltaTime) / keyFrameLength;
+ currentStep.y = (currentStep.y * deltaTime) / keyFrameLength;
+ currentStep.z = (currentStep.z * deltaTime) / keyFrameLength;
return false;
}
@@ -575,18 +575,18 @@ void Animations::processActorAnimations(int32 actorIdx) { // DoAnim
actor->angle = ClampAngle(actor->angle + processLastRotationAngle - actor->lastRotationAngle);
actor->lastRotationAngle = processLastRotationAngle;
- _engine->_movements->rotateActor(currentStepX, currentStepZ, actor->angle);
+ _engine->_movements->rotateActor(currentStep.x, currentStep.z, actor->angle);
- currentStepX = _engine->_renderer->destPos.x;
- currentStepZ = _engine->_renderer->destPos.z;
+ currentStep.x = _engine->_renderer->destPos.x;
+ currentStep.z = _engine->_renderer->destPos.z;
- _engine->_movements->processActor.x = actor->pos.x + currentStepX - actor->lastPos.x;
- _engine->_movements->processActor.y = actor->pos.y + currentStepY - actor->lastPos.y;
- _engine->_movements->processActor.z = actor->pos.z + currentStepZ - actor->lastPos.z;
+ _engine->_movements->processActor.x = actor->pos.x + currentStep.x - actor->lastPos.x;
+ _engine->_movements->processActor.y = actor->pos.y + currentStep.y - actor->lastPos.y;
+ _engine->_movements->processActor.z = actor->pos.z + currentStep.z - actor->lastPos.z;
- actor->lastPos.x = currentStepX;
- actor->lastPos.y = currentStepY;
- actor->lastPos.z = currentStepZ;
+ actor->lastPos.x = currentStep.x;
+ actor->lastPos.y = currentStep.y;
+ actor->lastPos.z = currentStep.z;
actor->dynamicFlags.bAnimEnded = 0;
actor->dynamicFlags.bAnimFrameReached = 0;
diff --git a/engines/twine/scene/animations.h b/engines/twine/scene/animations.h
index 2abe2bcbe8..0a87d4d603 100644
--- a/engines/twine/scene/animations.h
+++ b/engines/twine/scene/animations.h
@@ -56,12 +56,8 @@ private:
/** Last rotation angle */
int16 processLastRotationAngle = ANGLE_0; // processActorVar6
- /** Current step X coornidate */
- int16 currentStepX = 0;
- /** Current step Y coornidate */
- int16 currentStepY = 0;
- /** Current step Z coornidate */
- int16 currentStepZ = 0;
+ /** Current step coordinates */
+ I16Vec3 currentStep;
public:
Animations(TwinEEngine *engine);
Commit: e0ba8d1d74ca0c3df4fd673bc8810f02d2176f75
https://github.com/scummvm/scummvm/commit/e0ba8d1d74ca0c3df4fd673bc8810f02d2176f75
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2021-03-27T13:35:28+01:00
Commit Message:
TWINE: use IVec3 and minor cleanup
Changed paths:
engines/twine/scene/animations.cpp
engines/twine/scene/animations.h
diff --git a/engines/twine/scene/animations.cpp b/engines/twine/scene/animations.cpp
index 3359a8c895..ae1bc9f54b 100644
--- a/engines/twine/scene/animations.cpp
+++ b/engines/twine/scene/animations.cpp
@@ -580,13 +580,9 @@ void Animations::processActorAnimations(int32 actorIdx) { // DoAnim
currentStep.x = _engine->_renderer->destPos.x;
currentStep.z = _engine->_renderer->destPos.z;
- _engine->_movements->processActor.x = actor->pos.x + currentStep.x - actor->lastPos.x;
- _engine->_movements->processActor.y = actor->pos.y + currentStep.y - actor->lastPos.y;
- _engine->_movements->processActor.z = actor->pos.z + currentStep.z - actor->lastPos.z;
+ _engine->_movements->processActor = actor->pos + currentStep - actor->lastPos;
- actor->lastPos.x = currentStep.x;
- actor->lastPos.y = currentStep.y;
- actor->lastPos.z = currentStep.z;
+ actor->lastPos = currentStep;
actor->dynamicFlags.bAnimEnded = 0;
actor->dynamicFlags.bAnimFrameReached = 0;
diff --git a/engines/twine/scene/animations.h b/engines/twine/scene/animations.h
index 0a87d4d603..3e98c9d4dc 100644
--- a/engines/twine/scene/animations.h
+++ b/engines/twine/scene/animations.h
@@ -57,7 +57,7 @@ private:
int16 processLastRotationAngle = ANGLE_0; // processActorVar6
/** Current step coordinates */
- I16Vec3 currentStep;
+ IVec3 currentStep;
public:
Animations(TwinEEngine *engine);
Commit: 750128b2cb971927c1b587786dc183d53f71e46e
https://github.com/scummvm/scummvm/commit/750128b2cb971927c1b587786dc183d53f71e46e
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2021-03-27T13:35:28+01:00
Commit Message:
TWINE: minor cleanup
Changed paths:
engines/twine/scene/animations.cpp
diff --git a/engines/twine/scene/animations.cpp b/engines/twine/scene/animations.cpp
index ae1bc9f54b..8f51703537 100644
--- a/engines/twine/scene/animations.cpp
+++ b/engines/twine/scene/animations.cpp
@@ -449,9 +449,7 @@ bool Animations::initAnim(AnimationTypes newAnim, AnimType animType, AnimationTy
processAnimActions(actorIdx);
actor->lastRotationAngle = ANGLE_0;
- actor->lastPos.x = 0;
- actor->lastPos.y = 0;
- actor->lastPos.z = 0;
+ actor->lastPos = IVec3();
return true;
}
@@ -600,7 +598,7 @@ void Animations::processActorAnimations(int32 actorIdx) { // DoAnim
if (actor->animType == AnimType::kAnimationTypeLoop) {
actor->animPosition = animData.getLoopFrame();
} else {
- actor->anim = (AnimationTypes)actor->animExtra;
+ actor->anim = actor->animExtra;
actor->previousAnimIdx = getBodyAnimIndex(actor->anim, actorIdx);
if (actor->previousAnimIdx == -1) {
Commit: b6b9cd5fbda64dbdd6d67bee5fb49e8b78e8a1bd
https://github.com/scummvm/scummvm/commit/b6b9cd5fbda64dbdd6d67bee5fb49e8b78e8a1bd
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2021-03-27T13:35:28+01:00
Commit Message:
TWINE: use IVec3 for bounding box checks
Changed paths:
engines/twine/scene/collision.cpp
engines/twine/scene/grid.h
diff --git a/engines/twine/scene/collision.cpp b/engines/twine/scene/collision.cpp
index 01932fd343..936774f3bb 100644
--- a/engines/twine/scene/collision.cpp
+++ b/engines/twine/scene/collision.cpp
@@ -44,51 +44,41 @@ bool Collision::standingOnActor(int32 actorIdx1, int32 actorIdx2) const {
const ActorStruct *actor1 = _engine->_scene->getActor(actorIdx1);
const ActorStruct *actor2 = _engine->_scene->getActor(actorIdx2);
- // Current actor (actor 1)
- const int32 x1Left = _engine->_movements->processActor.x + actor1->boudingBox.mins.x;
- const int32 x1Right = _engine->_movements->processActor.x + actor1->boudingBox.maxs.x;
- const int32 y1Left = _engine->_movements->processActor.y + actor1->boudingBox.mins.y;
- const int32 y1Right = _engine->_movements->processActor.y + actor1->boudingBox.maxs.y;
- const int32 z1Left = _engine->_movements->processActor.z + actor1->boudingBox.mins.z;
- const int32 z1Right = _engine->_movements->processActor.z + actor1->boudingBox.maxs.z;
-
- // Actor 2
- const int32 x2Left = actor2->pos.x + actor2->boudingBox.mins.x;
- const int32 x2Right = actor2->pos.x + actor2->boudingBox.maxs.x;
- const int32 y2Left = actor2->pos.y + actor2->boudingBox.mins.y;
- const int32 y2Right = actor2->pos.y + actor2->boudingBox.maxs.y;
- const int32 z2Left = actor2->pos.z + actor2->boudingBox.mins.z;
- const int32 z2Right = actor2->pos.z + actor2->boudingBox.maxs.z;
-
- if (x1Left >= x2Right) {
- return false; // not standing
+ const IVec3 &mins1 = _engine->_movements->processActor + actor1->boudingBox.mins;
+ const IVec3 &maxs1 = _engine->_movements->processActor + actor1->boudingBox.maxs;
+
+ const IVec3 &mins2 = actor2->pos + actor2->boudingBox.mins;
+ const IVec3 &maxs2 = actor2->pos + actor2->boudingBox.maxs;
+
+ if (mins1.x >= maxs2.x) {
+ return false;
}
- if (x1Right <= x2Left) {
+ if (maxs1.x <= mins2.x) {
return false;
}
- if (y1Left > (y2Right + 1)) {
+ if (mins1.y > (maxs2.y + 1)) {
return false;
}
- if (y1Left <= (y2Right - 0x100)) {
+ if (mins1.y <= (maxs2.y - BRICK_HEIGHT)) {
return false;
}
- if (y1Right <= y2Left) {
+ if (maxs1.y <= mins2.y) {
return false;
}
- if (z1Left >= z2Right) {
+ if (mins1.z >= maxs2.z) {
return false;
}
- if (z1Right <= z2Left) {
+ if (maxs1.z <= mins2.z) {
return false;
}
- return true; // standing
+ return true;
}
int32 Collision::getAverageValue(int32 start, int32 end, int32 maxDelay, int32 delay) const {
@@ -202,12 +192,8 @@ void Collision::reajustActorPosition(ShapeType brickShape) {
int32 Collision::checkCollisionWithActors(int32 actorIdx) {
ActorStruct *actor = _engine->_scene->getActor(actorIdx);
- int32 xLeft = _engine->_movements->processActor.x + actor->boudingBox.mins.x;
- int32 xRight = _engine->_movements->processActor.x + actor->boudingBox.maxs.x;
- int32 yLeft = _engine->_movements->processActor.y + actor->boudingBox.mins.y;
- int32 yRight = _engine->_movements->processActor.y + actor->boudingBox.maxs.y;
- int32 zLeft = _engine->_movements->processActor.z + actor->boudingBox.mins.z;
- int32 zRight = _engine->_movements->processActor.z + actor->boudingBox.maxs.z;
+ IVec3 mins = _engine->_movements->processActor + actor->boudingBox.mins;
+ IVec3 maxs = _engine->_movements->processActor + actor->boudingBox.maxs;
actor->collision = -1;
@@ -216,26 +202,22 @@ int32 Collision::checkCollisionWithActors(int32 actorIdx) {
// aviod current processed actor
if (a != actorIdx && actorTest->entity != -1 && !actor->staticFlags.bComputeLowCollision && actorTest->standOn != actorIdx) {
- const int32 xLeftTest = actorTest->pos.x + actorTest->boudingBox.mins.x;
- const int32 xRightTest = actorTest->pos.x + actorTest->boudingBox.maxs.x;
- const int32 yLeftTest = actorTest->pos.y + actorTest->boudingBox.mins.y;
- const int32 yRightTest = actorTest->pos.y + actorTest->boudingBox.maxs.y;
- const int32 zLeftTest = actorTest->pos.z + actorTest->boudingBox.mins.z;
- const int32 zRightTest = actorTest->pos.z + actorTest->boudingBox.maxs.z;
-
- if (xLeft < xRightTest && xRight > xLeftTest && yLeft < yRightTest && yRight > yLeftTest && zLeft < zRightTest && zRight > zLeftTest) {
+ const IVec3 &minsTest = actorTest->pos + actorTest->boudingBox.mins;
+ const IVec3 &maxsTest = actorTest->pos + actorTest->boudingBox.maxs;
+
+ if (mins.x < maxsTest.x && maxs.x > minsTest.x && mins.y < maxsTest.y && maxs.y > minsTest.y && mins.z < maxsTest.z && maxs.z > minsTest.z) {
actor->collision = a; // mark as collision with actor a
if (actorTest->staticFlags.bIsCarrierActor) {
if (actor->dynamicFlags.bIsFalling) {
- _engine->_movements->processActor.y = yRightTest - actor->boudingBox.mins.y + 1;
+ _engine->_movements->processActor.y = maxsTest.y - actor->boudingBox.mins.y + 1;
actor->standOn = a;
} else {
if (standingOnActor(actorIdx, a)) {
- _engine->_movements->processActor.y = yRightTest - actor->boudingBox.mins.y + 1;
+ _engine->_movements->processActor.y = maxsTest.y - actor->boudingBox.mins.y + 1;
actor->standOn = a;
} else {
- int32 newAngle = _engine->_movements->getAngleAndSetTargetActorDistance(_engine->_movements->processActor, actorTest->pos);
+ const int32 newAngle = _engine->_movements->getAngleAndSetTargetActorDistance(_engine->_movements->processActor, actorTest->pos);
if (actorTest->staticFlags.bCanBePushed && !actor->staticFlags.bCanBePushed) {
actorTest->lastPos.y = 0;
@@ -260,18 +242,18 @@ int32 Collision::checkCollisionWithActors(int32 actorIdx) {
}
if ((actorTest->boudingBox.maxs.x - actorTest->boudingBox.mins.x == actorTest->boudingBox.maxs.z - actorTest->boudingBox.mins.z) &&
- (actor->boudingBox.maxs.x - actor->boudingBox.mins.x == actor->boudingBox.maxs.z - actor->boudingBox.mins.z)) {
+ (actor->boudingBox.maxs.x - actor->boudingBox.mins.x == actor->boudingBox.maxs.z - actor->boudingBox.mins.z)) {
if (newAngle < ANGLE_135) {
- _engine->_movements->processActor.x = xLeftTest - actor->boudingBox.maxs.x;
+ _engine->_movements->processActor.x = minsTest.x - actor->boudingBox.maxs.x;
}
if (newAngle >= ANGLE_135 && newAngle < ANGLE_225) {
- _engine->_movements->processActor.z = zRightTest - actor->boudingBox.mins.z;
+ _engine->_movements->processActor.z = maxsTest.z - actor->boudingBox.mins.z;
}
if (newAngle >= ANGLE_225 && newAngle < ANGLE_315) {
- _engine->_movements->processActor.x = xRightTest - actor->boudingBox.mins.x;
+ _engine->_movements->processActor.x = maxsTest.x - actor->boudingBox.mins.x;
}
if (newAngle >= ANGLE_315 || (newAngle < ANGLE_315 && newAngle < ANGLE_45)) {
- _engine->_movements->processActor.z = zLeftTest - actor->boudingBox.maxs.z;
+ _engine->_movements->processActor.z = minsTest.z - actor->boudingBox.maxs.z;
}
} else {
if (!actor->dynamicFlags.bIsFalling) {
@@ -310,18 +292,18 @@ int32 Collision::checkCollisionWithActors(int32 actorIdx) {
}
if ((actorTest->boudingBox.maxs.x - actorTest->boudingBox.mins.x == actorTest->boudingBox.maxs.z - actorTest->boudingBox.mins.z) &&
- (actor->boudingBox.maxs.x - actor->boudingBox.mins.x == actor->boudingBox.maxs.z - actor->boudingBox.mins.z)) {
+ (actor->boudingBox.maxs.x - actor->boudingBox.mins.x == actor->boudingBox.maxs.z - actor->boudingBox.mins.z)) {
if (newAngle < ANGLE_135) {
- _engine->_movements->processActor.x = xLeftTest - actor->boudingBox.maxs.x;
+ _engine->_movements->processActor.x = minsTest.x - actor->boudingBox.maxs.x;
}
if (newAngle >= ANGLE_135 && newAngle < ANGLE_225) {
- _engine->_movements->processActor.z = zRightTest - actor->boudingBox.mins.z;
+ _engine->_movements->processActor.z = maxsTest.z - actor->boudingBox.mins.z;
}
if (newAngle >= ANGLE_225 && newAngle < ANGLE_315) {
- _engine->_movements->processActor.x = xRightTest - actor->boudingBox.mins.x;
+ _engine->_movements->processActor.x = maxsTest.x - actor->boudingBox.mins.x;
}
if (newAngle >= ANGLE_315 || (newAngle < ANGLE_315 && newAngle < ANGLE_45)) {
- _engine->_movements->processActor.z = zLeftTest - actor->boudingBox.maxs.z;
+ _engine->_movements->processActor.z = minsTest.z - actor->boudingBox.maxs.z;
}
} else {
if (!actor->dynamicFlags.bIsFalling) {
@@ -336,28 +318,22 @@ int32 Collision::checkCollisionWithActors(int32 actorIdx) {
if (actor->dynamicFlags.bIsHitting) {
_engine->_movements->rotateActor(0, 200, actor->angle);
- xLeft = _engine->_renderer->destPos.x + _engine->_movements->processActor.x + actor->boudingBox.mins.x;
- xRight = _engine->_renderer->destPos.x + _engine->_movements->processActor.x + actor->boudingBox.maxs.x;
-
- yLeft = _engine->_movements->processActor.y + actor->boudingBox.mins.y;
- yRight = _engine->_movements->processActor.y + actor->boudingBox.maxs.y;
+ mins.x = _engine->_renderer->destPos.x + _engine->_movements->processActor.x + actor->boudingBox.mins.x;
+ mins.y = _engine->_movements->processActor.y + actor->boudingBox.mins.y;
+ mins.z = _engine->_renderer->destPos.z + _engine->_movements->processActor.z + actor->boudingBox.mins.z;
- zLeft = _engine->_renderer->destPos.z + _engine->_movements->processActor.z + actor->boudingBox.mins.z;
- zRight = _engine->_renderer->destPos.z + _engine->_movements->processActor.z + actor->boudingBox.maxs.z;
+ maxs.x = _engine->_renderer->destPos.x + _engine->_movements->processActor.x + actor->boudingBox.maxs.x;
+ maxs.y = _engine->_movements->processActor.y + actor->boudingBox.maxs.y;
+ maxs.z = _engine->_renderer->destPos.z + _engine->_movements->processActor.z + actor->boudingBox.maxs.z;
for (int32 a = 0; a < _engine->_scene->sceneNumActors; a++) {
const ActorStruct *actorTest = _engine->_scene->getActor(a);
// aviod current processed actor
if (a != actorIdx && actorTest->entity != -1 && !actorTest->staticFlags.bIsHidden && actorTest->standOn != actorIdx) {
- const int32 xLeftTest = actorTest->pos.x + actorTest->boudingBox.mins.x;
- const int32 xRightTest = actorTest->pos.x + actorTest->boudingBox.maxs.x;
- const int32 yLeftTest = actorTest->pos.y + actorTest->boudingBox.mins.y;
- const int32 yRightTest = actorTest->pos.y + actorTest->boudingBox.maxs.y;
- const int32 zLeftTest = actorTest->pos.z + actorTest->boudingBox.mins.z;
- const int32 zRightTest = actorTest->pos.z + actorTest->boudingBox.maxs.z;
-
- if (xLeft < xRightTest && xRight > xLeftTest && yLeft < yRightTest && yRight > yLeftTest && zLeft < zRightTest && zRight > zLeftTest) {
+ const IVec3 minsTest = actorTest->pos + actorTest->boudingBox.mins;
+ const IVec3 maxsTest = actorTest->pos + actorTest->boudingBox.maxs;
+ if (mins.x < maxsTest.x && maxs.x > minsTest.x && mins.y < maxsTest.y && maxs.y > minsTest.y && mins.z < maxsTest.z && maxs.z > minsTest.z) {
_engine->_actor->hitActor(actorIdx, a, actor->strengthOfHit, actor->angle + ANGLE_180);
actor->dynamicFlags.bIsHitting = 0;
}
@@ -369,7 +345,7 @@ int32 Collision::checkCollisionWithActors(int32 actorIdx) {
}
void Collision::checkHeroCollisionWithBricks(int32 x, int32 y, int32 z, int32 damageMask) {
- ShapeType brickShape = _engine->_grid->getBrickShape(_engine->_movements->processActor.x, _engine->_movements->processActor.y, _engine->_movements->processActor.z);
+ ShapeType brickShape = _engine->_grid->getBrickShape(_engine->_movements->processActor);
_engine->_movements->processActor.x += x;
_engine->_movements->processActor.y += y;
@@ -377,7 +353,7 @@ void Collision::checkHeroCollisionWithBricks(int32 x, int32 y, int32 z, int32 da
if (_engine->_movements->processActor.x >= 0 && _engine->_movements->processActor.z >= 0 && _engine->_movements->processActor.x <= 0x7E00 && _engine->_movements->processActor.z <= 0x7E00) {
reajustActorPosition(brickShape);
- brickShape = _engine->_grid->getBrickShapeFull(_engine->_movements->processActor.x, _engine->_movements->processActor.y, _engine->_movements->processActor.z, _engine->_actor->processActorPtr->boudingBox.maxs.y);
+ brickShape = _engine->_grid->getBrickShapeFull(_engine->_movements->processActor, _engine->_actor->processActorPtr->boudingBox.maxs.y);
if (brickShape == ShapeType::kSolid) {
causeActorDamage |= damageMask;
@@ -399,7 +375,7 @@ void Collision::checkHeroCollisionWithBricks(int32 x, int32 y, int32 z, int32 da
}
void Collision::checkActorCollisionWithBricks(int32 x, int32 y, int32 z, int32 damageMask) {
- ShapeType brickShape = _engine->_grid->getBrickShape(_engine->_movements->processActor.x, _engine->_movements->processActor.y, _engine->_movements->processActor.z);
+ ShapeType brickShape = _engine->_grid->getBrickShape(_engine->_movements->processActor);
_engine->_movements->processActor.x += x;
_engine->_movements->processActor.y += y;
@@ -407,7 +383,7 @@ void Collision::checkActorCollisionWithBricks(int32 x, int32 y, int32 z, int32 d
if (_engine->_movements->processActor.x >= 0 && _engine->_movements->processActor.z >= 0 && _engine->_movements->processActor.x <= 0x7E00 && _engine->_movements->processActor.z <= 0x7E00) {
reajustActorPosition(brickShape);
- brickShape = _engine->_grid->getBrickShape(_engine->_movements->processActor.x, _engine->_movements->processActor.y, _engine->_movements->processActor.z);
+ brickShape = _engine->_grid->getBrickShape(_engine->_movements->processActor);
if (brickShape == ShapeType::kSolid) {
causeActorDamage |= damageMask;
@@ -456,25 +432,17 @@ void Collision::stopFalling() { // ReceptionObj()
int32 Collision::checkExtraCollisionWithActors(ExtraListStruct *extra, int32 actorIdx) {
const BoundingBox *bbox = _engine->_resources->spriteBoundingBox.bbox(extra->info0);
- const int32 xLeft = bbox->mins.x + extra->pos.x;
- const int32 xRight = bbox->maxs.x + extra->pos.x;
- const int32 yLeft = bbox->mins.y + extra->pos.y;
- const int32 yRight = bbox->maxs.y + extra->pos.y;
- const int32 zLeft = bbox->mins.z + extra->pos.z;
- const int32 zRight = bbox->maxs.z + extra->pos.z;
+ const IVec3 mins = bbox->mins + extra->pos;
+ const IVec3 maxs = bbox->maxs + extra->pos;
for (int32 a = 0; a < _engine->_scene->sceneNumActors; a++) {
const ActorStruct *actorTest = _engine->_scene->getActor(a);
if (a != actorIdx && actorTest->entity != -1) {
- const int32 xLeftTest = actorTest->pos.x + actorTest->boudingBox.mins.x;
- const int32 xRightTest = actorTest->pos.x + actorTest->boudingBox.maxs.x;
- const int32 yLeftTest = actorTest->pos.y + actorTest->boudingBox.mins.y;
- const int32 yRightTest = actorTest->pos.y + actorTest->boudingBox.maxs.y;
- const int32 zLeftTest = actorTest->pos.z + actorTest->boudingBox.mins.z;
- const int32 zRightTest = actorTest->pos.z + actorTest->boudingBox.maxs.z;
-
- if (xLeft < xRightTest && xRight > xLeftTest && yLeft < yRightTest && yRight > yLeftTest && zLeft < zRightTest && zRight > zLeftTest) {
+ const IVec3 minsTest = actorTest->pos + actorTest->boudingBox.mins;
+ const IVec3 maxsTest = actorTest->pos + actorTest->boudingBox.maxs;
+
+ if (mins.x < maxsTest.x && maxs.x > minsTest.x && mins.y < maxsTest.y && maxs.y > minsTest.y && mins.z < maxsTest.z && maxs.z > minsTest.z) {
if (extra->strengthOfHit != 0) {
_engine->_actor->hitActor(actorIdx, a, extra->strengthOfHit, -1);
}
@@ -514,29 +482,22 @@ bool Collision::checkExtraCollisionWithBricks(int32 x, int32 y, int32 z, int32 o
int32 Collision::checkExtraCollisionWithExtra(ExtraListStruct *extra, int32 extraIdx) const {
int32 index = extra->info0;
const BoundingBox *bbox = _engine->_resources->spriteBoundingBox.bbox(index);
- const int32 xLeft = bbox->mins.x + extra->pos.x;
- const int32 xRight = bbox->maxs.x + extra->pos.x;
- const int32 yLeft = bbox->mins.y + extra->pos.y;
- const int32 yRight = bbox->maxs.y + extra->pos.y;
- const int32 zLeft = bbox->mins.z + extra->pos.z;
- const int32 zRight = bbox->maxs.z + extra->pos.z;
+ const IVec3 mins = bbox->mins + extra->pos;
+ const IVec3 maxs = bbox->maxs + extra->pos;
for (int32 i = 0; i < EXTRA_MAX_ENTRIES; i++) {
const ExtraListStruct *extraTest = &_engine->_extra->extraList[i];
if (i != extraIdx && extraTest->info0 != -1) {
// TODO: shouldn't this be extraTest->info0 as index?
const BoundingBox *testbbox = _engine->_resources->spriteBoundingBox.bbox(++index);
- const int32 xLeftTest = testbbox->mins.x + extraTest->pos.x;
- const int32 xRightTest = testbbox->maxs.x + extraTest->pos.x;
- const int32 yLeftTest = testbbox->mins.y + extraTest->pos.y;
- const int32 yRightTest = testbbox->maxs.y + extraTest->pos.y;
- const int32 zLeftTest = testbbox->mins.z + extraTest->pos.z;
- const int32 zRightTest = testbbox->maxs.z + extraTest->pos.z;
-
- if (xLeft < xLeftTest) {
- if (xLeft < xRightTest && xRight > xLeftTest && yLeft < yRightTest && yRight > yLeftTest && zLeft < zRightTest && zRight > zLeftTest) {
- return i;
- }
+ const IVec3 minsTest = testbbox->mins + extraTest->pos;
+ const IVec3 maxsTest = testbbox->maxs + extraTest->pos;
+
+ if (mins.x >= minsTest.x) {
+ continue;
+ }
+ if (mins.x < maxsTest.x && maxs.x > minsTest.x && mins.y < maxsTest.y && maxs.y > minsTest.y && mins.z < maxsTest.z && maxs.z > minsTest.z) {
+ return i;
}
}
}
diff --git a/engines/twine/scene/grid.h b/engines/twine/scene/grid.h
index 527d9052dd..09b6b22fc4 100644
--- a/engines/twine/scene/grid.h
+++ b/engines/twine/scene/grid.h
@@ -294,6 +294,18 @@ public:
ShapeType getBrickShapeFull(int32 x, int32 y, int32 z, int32 y2);
int32 getBrickSoundType(int32 x, int32 y, int32 z);
+
+ inline ShapeType getBrickShape(const IVec3 &pos) {
+ return getBrickShape(pos.x, pos.y, pos.z);
+ }
+
+ inline ShapeType getBrickShapeFull(const IVec3 &pos, int32 y2) {
+ return getBrickShapeFull(pos.x, pos.y, pos.z, y2);
+ }
+
+ inline int32 getBrickSoundType(const IVec3 &pos) {
+ return getBrickSoundType(pos.x, pos.y, pos.z);
+ }
};
} // namespace TwinE
Commit: 1af583e6bd2c5244022c784f83e81ffc1972f0ee
https://github.com/scummvm/scummvm/commit/1af583e6bd2c5244022c784f83e81ffc1972f0ee
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2021-03-27T13:35:28+01:00
Commit Message:
TWINE: optimized renderPolygons by not looping twice over all the vertices
... to compute the bounding box
Changed paths:
engines/twine/renderer/renderer.cpp
engines/twine/renderer/renderer.h
engines/twine/text.cpp
diff --git a/engines/twine/renderer/renderer.cpp b/engines/twine/renderer/renderer.cpp
index 3fe8e6ca50..551cd1b32c 100644
--- a/engines/twine/renderer/renderer.cpp
+++ b/engines/twine/renderer/renderer.cpp
@@ -424,27 +424,10 @@ void Renderer::setLightVector(int32 angleX, int32 angleY, int32 angleZ) {
_lightPos = destPos;
}
-FORCEINLINE int16 clamp(int16 x, int16 a, int16 b) {
+static FORCEINLINE int16 clamp(int16 x, int16 a, int16 b) {
return x < a ? a : (x > b ? b : x);
}
-void Renderer::computeBoundingBox(Vertex *vertices, int32 numVertices, int &vleft, int &vright, int &vtop, int &vbottom) const {
- vleft = vtop = SCENE_SIZE_MAX;
- vright = vbottom = SCENE_SIZE_MIN;
- const int16 maxWidth = _engine->width() - 1;
- const int16 maxHeight = _engine->height() - 1;
-
- for (int32 i = 0; i < numVertices; i++) {
- vertices[i].x = clamp(vertices[i].x, 0, maxWidth);
- vleft = MIN<int>(vleft, vertices[i].x);
- vright = MAX<int>(vright, vertices[i].x);
-
- vertices[i].y = clamp(vertices[i].y, 0, maxHeight);
- vtop = MIN<int>(vtop, vertices[i].y);
- vbottom = MAX<int>(vbottom, vertices[i].y);
- }
-}
-
void Renderer::computePolygons(int16 polyRenderType, const Vertex *vertices, int32 numVertices) {
uint8 vertexParam1 = vertices[numVertices - 1].colorIndex;
int16 currentVertexX = vertices[numVertices - 1].x;
@@ -1013,15 +996,7 @@ void Renderer::renderPolygonsDither(uint8 *out, int vtop, int32 vsize) const {
void Renderer::renderPolygonsMarble(uint8 *out, int vtop, int32 vsize, uint8 color) const {
}
-void Renderer::renderPolygons(const CmdRenderPolygon &polygon, Vertex *vertices) {
- int vleft = 0;
- int vright = 0;
- int vtop = 0;
- int vbottom = 0;
-
- if (polygon.numVertices > 0) {
- computeBoundingBox(vertices, polygon.numVertices, vleft, vright, vtop, vbottom);
- }
+void Renderer::renderPolygons(const CmdRenderPolygon &polygon, Vertex *vertices, int vtop, int vbottom) {
computePolygons(polygon.renderType, vertices, polygon.numVertices);
uint8 *out = (uint8 *)_engine->frontVideoBuffer.getBasePtr(0, vtop);
@@ -1119,6 +1094,9 @@ uint8 *Renderer::prepareLines(const Common::Array<BodyLine> &lines, int32 &numOf
}
uint8 *Renderer::preparePolygons(const Common::Array<BodyPolygon> &polygons, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData) {
+ const int16 maxHeight = _engine->height() - 1;
+ const int16 maxWidth = _engine->width() - 1;
+
for (const BodyPolygon &polygon : polygons) {
const uint8 renderType = polygon.renderType;
const uint8 numVertices = polygon.indices.size();
@@ -1129,6 +1107,8 @@ uint8 *Renderer::preparePolygons(const Common::Array<BodyPolygon> &polygons, int
CmdRenderPolygon *destinationPolygon = (CmdRenderPolygon *)renderBufferPtr;
destinationPolygon->numVertices = numVertices;
+ destinationPolygon->top = SCENE_SIZE_MAX;
+ destinationPolygon->bottom = SCENE_SIZE_MIN;
renderBufferPtr += sizeof(CmdRenderPolygon);
@@ -1149,8 +1129,10 @@ uint8 *Renderer::preparePolygons(const Common::Array<BodyPolygon> &polygons, int
const I16Vec3 *point = &modelData->flattenPoints[vertexIndex];
vertex->colorIndex = shadeValue;
- vertex->x = point->x;
- vertex->y = point->y;
+ vertex->x = clamp(point->x, 0, maxWidth);
+ vertex->y = clamp(point->y, 0, maxHeight);
+ destinationPolygon->top = MIN<int>(destinationPolygon->top, vertex->y);
+ destinationPolygon->bottom = MAX<int>(destinationPolygon->bottom, vertex->y);
bestDepth = MAX(bestDepth, point->z);
++vertex;
}
@@ -1172,8 +1154,10 @@ uint8 *Renderer::preparePolygons(const Common::Array<BodyPolygon> &polygons, int
const I16Vec3 *point = &modelData->flattenPoints[vertexIndex];
vertex->colorIndex = destinationPolygon->colorIndex;
- vertex->x = point->x;
- vertex->y = point->y;
+ vertex->x = clamp(point->x, 0, maxWidth);
+ vertex->y = clamp(point->y, 0, maxHeight);
+ destinationPolygon->top = MIN<int>(destinationPolygon->top, vertex->y);
+ destinationPolygon->bottom = MAX<int>(destinationPolygon->bottom, vertex->y);
bestDepth = MAX(bestDepth, point->z);
++vertex;
}
@@ -1229,7 +1213,7 @@ bool Renderer::renderModelElements(int32 numOfPrimitives, const BodyData &bodyDa
case RENDERTYPE_DRAWPOLYGON: {
const CmdRenderPolygon *header = (const CmdRenderPolygon *)pointer;
Vertex *vertices = (Vertex *)(pointer + sizeof(CmdRenderPolygon));
- renderPolygons(*header, vertices);
+ renderPolygons(*header, vertices, header->top, header->bottom);
break;
}
case RENDERTYPE_DRAWSPHERE: {
diff --git a/engines/twine/renderer/renderer.h b/engines/twine/renderer/renderer.h
index 9948486cdc..903f6f60a7 100644
--- a/engines/twine/renderer/renderer.h
+++ b/engines/twine/renderer/renderer.h
@@ -58,6 +58,8 @@ struct CmdRenderPolygon {
uint8 renderType = 0;
uint8 numVertices = 0;
int16 colorIndex = 0;
+ int16 top = 0;
+ int16 bottom = 0;
// followed by Vertex array
};
@@ -192,7 +194,6 @@ private:
void renderPolygonsDither(uint8 *out, int vtop, int32 vsize) const;
void renderPolygonsMarble(uint8 *out, int vtop, int32 vsize, uint8 color) const;
- void computeBoundingBox(Vertex *vertices, int32 numVertices, int &vleft, int &vright, int &vtop, int &vbottom) const;
void computePolygons(int16 polyRenderType, const Vertex *vertices, int32 numVertices);
const RenderCommand *depthSortRenderCommands(int32 numOfPrimitives);
@@ -221,7 +222,7 @@ public:
void setLightVector(int32 angleX, int32 angleY, int32 angleZ);
void getBaseRotationPosition(int32 x, int32 y, int32 z);
- void renderPolygons(const CmdRenderPolygon &polygon, Vertex *vertices);
+ void renderPolygons(const CmdRenderPolygon &polygon, Vertex *vertices, int vtop, int vbottom);
inline int32 projectPositionOnScreen(const IVec3& pos) {
return projectPositionOnScreen(pos.x, pos.y, pos.z);
diff --git a/engines/twine/text.cpp b/engines/twine/text.cpp
index 9c5664c16e..6dde524a8d 100644
--- a/engines/twine/text.cpp
+++ b/engines/twine/text.cpp
@@ -489,7 +489,7 @@ void Text::renderContinueReadingTriangle() {
polygon.numVertices = ARRAYSIZE(vertices);
polygon.colorIndex = _dialTextStopColor;
polygon.renderType = POLYGONTYPE_FLAT;
- _engine->_renderer->renderPolygons(polygon, vertices);
+ _engine->_renderer->renderPolygons(polygon, vertices, top, bottom);
_engine->copyBlockPhys(Common::Rect(left, top, right, bottom));
}
More information about the Scummvm-git-logs
mailing list