[Scummvm-git-logs] scummvm master -> 2e8f22508e07c43e3b20bfdcdd397da6397be32b

mgerhardy martin.gerhardy at gmail.com
Tue Dec 22 16:18:49 UTC 2020


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

Summary:
977c28af4f TWINE: made elementEntry public
8ba2ba7578 TWINE: added body parsing code
cf3d1bc213 TWINE: moved code into subdir
b384031d1b TWINE: anim parser
463cd54c38 TWINE: cleanup animation code
86e73c9d97 TWINE: group functions
d8645be0b2 TWINE: don't advance the animBufferPos twice
0271d54568 TWINE: cleanup animation code
c084931674 TWINE: unify bone transfer
dbe4698984 TWINE: unified animation code
123d8a163c TWINE: renamed variables
cbbfea5a33 TWINE: unified animation code
3c3fd773f1 TWINE: reduced cyclic complexity and fixed potential endless loop
dffd8cc63f TWINE: make it easier to follow the data offsets
4d9bfa493b TWINE: removed unused return value
1a5a3da35b TWINE: renamed method parameters
c811e4e099 TWINE: removed unused method parameter
39b79a85f2 TWINE: renamed method and stack vars
ecb56f62c5 TWINE: reduced code duplication
f018858023 TWINE: reduced code duplication
0ff83ff300 TWINE: started to use AnimData in setModelAnimation
802f66086a TWINE: use BoneFrame struct to copy the bone state
4301e49da2 TWINE: started to remove raw byte buffer helper methods
e88280ac62 TWINE: moved methods for reading body data
48f356d25b TWINE: minor cleanup
05cccc0f83 TWINE: ensure that shadeAngleTab3 is always a valid pointer
47fa979332 TWINE: removed unused code
4e8f7b72d3 TWINE: reduced cyclic complexity
ae555d7aea TWINE: reduced cyclic complexity
cef7d733f1 TWINE: started to cleanup draw list handling
6c337d5488 TWINE: finished splitting type and index
f7f3a3f141 TWINE: introduced enum for draw list type
ea55717bc2 TWINE: named unknown member
db857a9d0d TWINE: extract into single methods
22d9dc3b7b TWINE: extract to method
1f70b4776c TWINE: replaced magic numbers
59ac0e304a TWINE: renamed variables
66994f008d TWINE: added model/body header methods
5e589d4f88 TWINE: use Model helper functions
1c7520d1c1 TWINE: const
65a2a9fe4c TWINE: name unknown members
cc1bbc5a4a TWINE: const
628df7be6e TWINE: converted more raw byte buffer actions to the Model helper functions
7050c8225f TWINE: model helper functions
023114f03c TWINE: updated body parser
456801b29f TWINE: removed lineData struct
1aad7cd666 TWINE: don't advance the buffer pointer, but use the helper method
5a1d31eb4e TWINE: reduced scope
e20cd47a3e TWINE: parse into BodyData
fd94d8fc99 TWINE: extended Model helper functions with wrappers
c95ae66847 TWINE: a new helper method for the Model class
b6841dbc25 TWINE: Model helper functions
5eb8ae2f26 TWINE: use the Model helper functions
cbac794beb TWINE: more model helper
01816aa860 TWINE: extract to method
c7e3309b59 TWINE: renamed methods
f9cce28c82 TWINE: reduced cyclic complexity and extract to local vars
506f236eef TWINE: format the code
97dbec8cab TWINE: reduced code duplication
d1aa2e3cb3 TWINE: started to reorganize the folder structure
73fc3f05cc TWINE: format the code
b5a13114df TWINE: moved file into subdir
c883e1e2e0 TWINE: moved struct into shared
2317f89914 TWINE: new sprite bbox parser
28611c1cf2 TWINE: const + reduced scope
7a5f170e73 TWINE: added base class for parsers
48d71f82b3 TWINE: extended parser to load from hqr
bd5dff8912 TWINE: use the SpriteBoundingBoxData class for parsing
cb39a1f648 TWINE: ported code from residualvm twin code to directly use a readstream for hqr ressources
9ab92f8320 TWINE: let loadFromHQR use a read stream and not a buffer
06d2a71511 TWINE: moved resource management files into own subdir
80181d111c TWINE: bit extraction helper
e20d35b03e TWINE: moved sprite specific offset
30d67202bb TWINE: const + removed unused variables
d0721f3586 TWINE: const for Grid::drawBrickSprite
fe51a71c28 TWINE: use bit extraction helper in Grid::drawBrickSprite
490dde3bd5 TWINE: moved one of the clipping checks out of the inner loops
39c3b3022e TWINE: perform some minor clipping optimizations
7cad24ad90 TWINE: new debug command to render clip zones
d0b7676b9d TWINE: renamed variables
42f0634d6d TWINE: draw actor clips
02e51f0ecb TWINE: const
e6bb08f606 TWINE: format the code
475d32380f TWINE: specify the palette index for loadImage()
b7486b2249 TWINE: holoamp input actions
ef27d13958 TWINE: given default value for ScopedFPS
b6a854677b TWINE: use surface method to set back the front buffer
5bb0f3b6b5 TWINE: renamed method parameters
f308252543 TWINE: holomap loop
08c6815112 TWINE: reset the proper camera projections on leaving the holomap 'menu'
e751448b99 TWINE: comments
a3be0c2c6d TWINE: removed unused vars from Text::drawCharacter
bfa517ae7a TWINE: moved overlay from script code into holomap code
2e8f22508e TWINE: holomap text rendering


Commit: 977c28af4f26f2fe959f5f42cb42a2f31de52782
    https://github.com/scummvm/scummvm/commit/977c28af4f26f2fe959f5f42cb42a2f31de52782
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: made elementEntry public

Changed paths:
    engines/twine/renderer.h


diff --git a/engines/twine/renderer.h b/engines/twine/renderer.h
index 70b6304c3a..998420f040 100644
--- a/engines/twine/renderer.h
+++ b/engines/twine/renderer.h
@@ -97,6 +97,26 @@ struct Model {
 	}
 };
 
+#include "common/pack-start.h"
+struct elementEntry {
+	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;
+	int32 numOfShades = 0; // field_10
+	int32 field_14 = 0;
+	int32 field_18 = 0;
+	int32 y = 0;
+	int32 field_20 = 0;
+	int16 field_24 = 0;
+};
+#include "common/pack-end.h"
+static_assert(sizeof(elementEntry) == 38, "Unexpected elementEntry size");
+
 class Renderer {
 private:
 	TwinEEngine *_engine;
@@ -134,26 +154,6 @@ private:
 	#include "common/pack-end.h"
 	static_assert(sizeof(pointTab) == 6, "Unexpected pointTab size");
 
-	#include "common/pack-start.h"
-	struct elementEntry {
-		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;
-		int32 numOfShades = 0; // field_10
-		int32 field_14 = 0;
-		int32 field_18 = 0;
-		int32 y = 0;
-		int32 field_20 = 0;
-		int16 field_24 = 0;
-	};
-	#include "common/pack-end.h"
-	static_assert(sizeof(elementEntry) == 38, "Unexpected elementEntry size");
-
 	struct lineData {
 		uint8 colorIndex = 0;
 		uint8 unk1 = 0;


Commit: 8ba2ba757810ca191fbd0e52cb48b1cb5ea57fe4
    https://github.com/scummvm/scummvm/commit/8ba2ba757810ca191fbd0e52cb48b1cb5ea57fe4
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: added body parsing code

Changed paths:
  A engines/twine/parser/body.cpp
  A engines/twine/parser/body.h
    engines/twine/module.mk


diff --git a/engines/twine/module.mk b/engines/twine/module.mk
index 421a25d1be..311d95b039 100644
--- a/engines/twine/module.mk
+++ b/engines/twine/module.mk
@@ -1,6 +1,7 @@
 MODULE := engines/twine
 
 MODULE_OBJS := \
+	parser/body.o \
 	actor.o \
 	animations.o \
 	collision.o \
diff --git a/engines/twine/parser/body.cpp b/engines/twine/parser/body.cpp
new file mode 100644
index 0000000000..931c24d130
--- /dev/null
+++ b/engines/twine/parser/body.cpp
@@ -0,0 +1,170 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "twine/parser/body.h"
+#include "twine/renderer.h"
+#include "common/memstream.h"
+
+namespace TwinE {
+
+void BodyData::loadVertices(Common::SeekableReadStream &stream) {
+	const uint16 numVertices = stream.readUint16LE();
+	_vertices.clear();
+	_vertices.reserve(numVertices);
+	for (uint16 i = 0U; i < numVertices; ++i) {
+		const int16 x = stream.readSint16LE();
+		const int16 y = stream.readSint16LE();
+		const int16 z = stream.readSint16LE();
+		const uint16 bone = 0;
+		_vertices.push_back({x, y, z, bone});
+	}
+}
+
+void BodyData::loadBones(Common::SeekableReadStream &stream) {
+	const uint16 numBones = stream.readUint16LE();
+	_bones.clear();
+	_bones.reserve(numBones);
+	for (uint16 i = 0; i < numBones; ++i) {
+		const int16 firstPoint = stream.readSint16LE() / 6;
+		const int16 numPoints = stream.readSint16LE();
+		const int16 basePoint = stream.readSint16LE() / 6;
+		const int16 baseElementOffset = stream.readSint16LE();
+		/*int16 type =*/ stream.readSint16LE();
+		/*int16 rotateX =*/ stream.readSint16LE();
+		/*int16 rotateY =*/ stream.readSint16LE();
+		/*int16 rotateZ =*/ stream.readSint16LE();
+		/*int32 numOfShades =*/stream.readSint32LE();
+		/*int32 field_14 =*/ stream.readSint32LE();
+		/*int32 field_18 =*/ stream.readSint32LE();
+		/*int32 y =*/ stream.readSint32LE();
+		/*int32 field_20 =*/ stream.readSint32LE();
+		/*int16 field_24 =*/ stream.readSint16LE();
+
+		BodyBone bone;
+		bone.parent = baseElementOffset == -1 ? 0xffff : baseElementOffset / 38;
+		bone.vertex = basePoint;
+
+		// assign the vertices to the bones
+		for (int j = 0; j < numPoints; ++j) {
+			_vertices[firstPoint + j].bone = i;
+		}
+
+		_bones.push_back(bone);
+	}
+}
+
+void BodyData::loadShades(Common::SeekableReadStream &stream) {
+	const uint16 numShades = stream.readUint16LE();
+	_shades.clear();
+	_shades.reserve(numShades);
+	for (uint16 i = 0; i < numShades; ++i) {
+		BodyShade shape;
+		shape.unk1 = stream.readSint16LE();
+		shape.unk2 = stream.readSint16LE();
+		shape.unk3 = stream.readSint16LE();
+		shape.unk4 = stream.readSint16LE();
+		_shades.push_back(shape);
+	}
+}
+
+void BodyData::loadPolygons(Common::SeekableReadStream &stream) {
+	const uint16 numPolygons = stream.readUint16LE();
+	_polygons.clear();
+	_polygons.reserve(numPolygons);
+	for (uint16 i = 0; i < numPolygons; ++i) {
+		BodyPolygon poly;
+		poly.renderType = stream.readSByte();
+		const int8 numVertex = stream.readSByte();
+
+		poly.color = stream.readUint16LE();
+		if (poly.renderType >= 7 && poly.renderType < 9) {
+			poly.intensity = stream.readSint16LE();
+		}
+
+		poly.indices.reserve(numVertex);
+		for (int k = 0; k < numVertex; ++k) {
+			if (poly.renderType >= 9) {
+				poly.intensity = stream.readSint16LE();
+			}
+			poly.indices.push_back(stream.readUint16LE() / 6);
+		}
+
+		_polygons.push_back(poly);
+	}
+}
+
+void BodyData::loadLines(Common::SeekableReadStream &stream) {
+	const uint16 numLines = stream.readUint16LE();
+	_lines.clear();
+	_lines.reserve(numLines);
+	for (uint16 i = 0; i < numLines; ++i) {
+		BodyLine line;
+		line.unk1 = stream.readUint16LE();
+		line.color = stream.readUint16LE();
+		line.vertex1 = stream.readUint16LE() / 6;
+		line.vertex2 = stream.readUint16LE() / 6;
+		_lines.push_back(line);
+	}
+}
+
+void BodyData::loadSpheres(Common::SeekableReadStream &stream) {
+	const uint16 numSpheres = stream.readUint16LE();
+	_spheres.clear();
+	_spheres.reserve(numSpheres);
+	for (uint16 i = 0; i < numSpheres; ++i) {
+		BodySphere sphere;
+		sphere.unk1 = stream.readUint16LE();
+		sphere.color = stream.readUint16LE();
+		sphere.size = stream.readUint16LE();
+		sphere.vertex = stream.readUint16LE() / 6;
+		_spheres.push_back(sphere);
+	}
+}
+
+bool BodyData::loadFromStream(Common::SeekableReadStream &stream) {
+	*(uint16 *)&bodyFlag = stream.readUint16LE();
+	minsx = stream.readSint16LE();
+	maxsx = stream.readSint16LE();
+	minsy = stream.readSint16LE();
+	maxsy = stream.readSint16LE();
+	minsz = stream.readSint16LE();
+	maxsz = stream.readSint16LE();
+
+	stream.seek(0x1A);
+	loadVertices(stream);
+	loadBones(stream);
+	loadShades(stream);
+	loadPolygons(stream);
+	loadLines(stream);
+	loadSpheres(stream);
+	return !stream.err();
+}
+
+bool BodyData::loadFromBuffer(const uint8 *buf, uint32 size) {
+	if (size == 0) {
+		return false;
+	}
+	Common::MemoryReadStream stream(buf, size);
+	return loadFromStream(stream);
+}
+
+} // namespace TwinE
diff --git a/engines/twine/parser/body.h b/engines/twine/parser/body.h
new file mode 100644
index 0000000000..ad3c377460
--- /dev/null
+++ b/engines/twine/parser/body.h
@@ -0,0 +1,137 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TWINE_BODY_H
+#define TWINE_BODY_H
+
+#include "common/array.h"
+#include "common/memstream.h"
+#include "common/stream.h"
+#include "twine/shared.h"
+
+namespace TwinE {
+
+struct BodyVertex {
+	int16 x;
+	int16 y;
+	int16 z;
+	uint16 bone;
+};
+
+struct BodyBone {
+	uint16 parent;
+	uint16 vertex;
+};
+
+struct BodyShade {
+	int16 unk1;
+	int16 unk2;
+	int16 unk3;
+	int16 unk4;
+};
+
+struct BodyPolygon {
+	Common::Array<uint16> indices;
+	int16 intensity = 0;
+	int8 renderType = 0;
+	uint16 color = 0;
+};
+
+struct BodyLine {
+	uint16 unk1;
+	uint16 color;
+	uint16 vertex1;
+	uint16 vertex2;
+};
+
+struct BodySphere {
+	uint16 unk1;
+	uint16 color;
+	uint16 size;
+	uint16 vertex;
+};
+
+class BodyData {
+private:
+	void loadVertices(Common::SeekableReadStream &stream);
+	void loadBones(Common::SeekableReadStream &stream);
+	void loadShades(Common::SeekableReadStream &stream);
+	void loadPolygons(Common::SeekableReadStream &stream);
+	void loadLines(Common::SeekableReadStream &stream);
+	void loadSpheres(Common::SeekableReadStream &stream);
+
+	Common::Array<BodyPolygon> _polygons;
+	Common::Array<BodyVertex> _vertices;
+	Common::Array<BodySphere> _spheres;
+	Common::Array<BodyShade> _shades;
+	Common::Array<BodyLine> _lines;
+	Common::Array<BodyBone> _bones;
+
+public:
+	struct BodyFlags {
+		uint16 unk1 : 1;            // 1 << 0
+		uint16 animated : 1;        // 1 << 1
+		uint16 unk3 : 1;            // 1 << 2
+		uint16 unk4 : 1;            // 1 << 3
+		uint16 unk5 : 1;            // 1 << 4
+		uint16 unk6 : 1;            // 1 << 5
+		uint16 unk7 : 1;            // 1 << 6
+		uint16 alreadyPrepared : 1; // 1 << 7
+		uint16 unk9 : 1;            // 1 << 8
+		uint16 unk10 : 1;           // 1 << 9
+		uint16 unk11 : 1;           // 1 << 10
+		uint16 unk12 : 1;           // 1 << 11
+		uint16 unk13 : 1;           // 1 << 12
+		uint16 unk14 : 1;           // 1 << 13
+		uint16 unk15 : 1;           // 1 << 14
+		uint16 unk16 : 1;           // 1 << 15
+	} bodyFlag;
+
+	int16 minsx = 0;
+	int16 maxsx = 0;
+	int16 minsy = 0;
+	int16 maxsy = 0;
+	int16 minsz = 0;
+	int16 maxsz = 0;
+	int16 offsetToData = 0;
+
+	inline bool isAnimated() const {
+		return bodyFlag.animated;
+	}
+
+	inline uint numBones() const {
+		return _bones.size();
+	}
+
+	bool loadFromStream(Common::SeekableReadStream &stream);
+
+	bool loadFromBuffer(const uint8 *buf, uint32 size);
+
+	static inline bool isAnimated(const uint8* bodyPtr) {
+		const int16 bodyHeader = READ_LE_INT16(bodyPtr);
+		return (bodyHeader & 2) != 0;
+	}
+};
+
+} // End of namespace TwinE
+
+#endif


Commit: cf3d1bc2131e08927bdf74dd27d46fa536524b91
    https://github.com/scummvm/scummvm/commit/cf3d1bc2131e08927bdf74dd27d46fa536524b91
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: moved code into subdir

Changed paths:
  A engines/twine/parser/entity.cpp
  A engines/twine/parser/entity.h
  R engines/twine/entity.cpp
  R engines/twine/entity.h
    engines/twine/actor.cpp
    engines/twine/actor.h
    engines/twine/animations.cpp
    engines/twine/module.mk


diff --git a/engines/twine/actor.cpp b/engines/twine/actor.cpp
index 55c44d0133..96dc50f4c9 100644
--- a/engines/twine/actor.cpp
+++ b/engines/twine/actor.cpp
@@ -25,7 +25,7 @@
 #include "common/system.h"
 #include "common/textconsole.h"
 #include "twine/animations.h"
-#include "twine/entity.h"
+#include "twine/parser/entity.h"
 #include "twine/extra.h"
 #include "twine/gamestate.h"
 #include "twine/grid.h"
diff --git a/engines/twine/actor.h b/engines/twine/actor.h
index b9df8535d5..c1a2ec46fc 100644
--- a/engines/twine/actor.h
+++ b/engines/twine/actor.h
@@ -24,7 +24,7 @@
 #define TWINE_ACTOR_H
 
 #include "common/scummsys.h"
-#include "twine/entity.h"
+#include "twine/parser/entity.h"
 #include "twine/shared.h"
 
 namespace TwinE {
diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index c8ddabe3cb..203debcce5 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -28,7 +28,7 @@
 #include "common/util.h"
 #include "twine/actor.h"
 #include "twine/collision.h"
-#include "twine/entity.h"
+#include "twine/parser/entity.h"
 #include "twine/gamestate.h"
 #include "twine/grid.h"
 #include "twine/movements.h"
diff --git a/engines/twine/module.mk b/engines/twine/module.mk
index 311d95b039..a25748f146 100644
--- a/engines/twine/module.mk
+++ b/engines/twine/module.mk
@@ -2,6 +2,7 @@ MODULE := engines/twine
 
 MODULE_OBJS := \
 	parser/body.o \
+	parser/entity.o \
 	actor.o \
 	animations.o \
 	collision.o \
@@ -10,7 +11,6 @@ MODULE_OBJS := \
 	debug_grid.o \
 	debug_scene.o \
 	detection.o \
-	entity.o \
 	extra.o \
 	flamovies.o \
 	gamestate.o \
diff --git a/engines/twine/entity.cpp b/engines/twine/parser/entity.cpp
similarity index 99%
rename from engines/twine/entity.cpp
rename to engines/twine/parser/entity.cpp
index af5beab502..d5a1a38ffe 100644
--- a/engines/twine/entity.cpp
+++ b/engines/twine/parser/entity.cpp
@@ -20,7 +20,7 @@
  *
  */
 
-#include "twine/entity.h"
+#include "twine/parser/entity.h"
 #include "common/stream.h"
 
 namespace TwinE {
diff --git a/engines/twine/entity.h b/engines/twine/parser/entity.h
similarity index 100%
rename from engines/twine/entity.h
rename to engines/twine/parser/entity.h


Commit: b384031d1b721cbaedff273d552d0f3e1785173e
    https://github.com/scummvm/scummvm/commit/b384031d1b721cbaedff273d552d0f3e1785173e
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: anim parser

Changed paths:
  A engines/twine/parser/anim.cpp
  A engines/twine/parser/anim.h
    engines/twine/module.mk
    engines/twine/parser/body.cpp


diff --git a/engines/twine/module.mk b/engines/twine/module.mk
index a25748f146..9342588444 100644
--- a/engines/twine/module.mk
+++ b/engines/twine/module.mk
@@ -1,6 +1,7 @@
 MODULE := engines/twine
 
 MODULE_OBJS := \
+	parser/anim.o \
 	parser/body.o \
 	parser/entity.o \
 	actor.o \
diff --git a/engines/twine/parser/anim.cpp b/engines/twine/parser/anim.cpp
new file mode 100644
index 0000000000..2fb947e9f3
--- /dev/null
+++ b/engines/twine/parser/anim.cpp
@@ -0,0 +1,93 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "twine/parser/anim.h"
+#include "common/memstream.h"
+
+namespace TwinE {
+
+bool AnimData::loadBoneFrame(KeyFrame &keyframe, Common::SeekableReadStream &stream) {
+	BoneFrame boneframe;
+	boneframe.type = stream.readSint16LE();
+	boneframe.x = stream.readSint16LE();
+	boneframe.y = stream.readSint16LE();
+	boneframe.z = stream.readSint16LE();
+	keyframe.boneframes.push_back(boneframe);
+	return boneframe.type != 0;
+}
+
+void AnimData::loadKeyFrames(Common::SeekableReadStream &stream) {
+	for (uint16 i = 0U; i < _numKeyframes; ++i) {
+		KeyFrame keyframe;
+		keyframe.length = stream.readUint16LE();
+		keyframe.x = stream.readSint16LE();
+		keyframe.y = stream.readSint16LE();
+		keyframe.z = stream.readSint16LE();
+
+		for (uint16 j = 0U; j < _numBoneframes; ++j) {
+			loadBoneFrame(keyframe, stream);
+		}
+
+		_keyframes.push_back(keyframe);
+		assert(keyframe.boneframes.size() == (uint)_numBoneframes);
+	}
+}
+
+bool AnimData::loadFromStream(Common::SeekableReadStream &stream) {
+	_numKeyframes = stream.readUint16LE();
+	_numBoneframes = stream.readUint16LE();
+	_loopFrame = stream.readUint16LE();
+	stream.readUint16LE();
+
+	loadKeyFrames(stream);
+
+	return !stream.err();
+}
+
+bool AnimData::loadFromBuffer(const uint8 *buf, uint32 size) {
+	if (size == 0) {
+		return false;
+	}
+	Common::MemoryReadStream stream(buf, size);
+	return loadFromStream(stream);
+}
+
+const Common::Array<KeyFrame>& AnimData::getKeyframes() const {
+	return _keyframes;
+}
+
+const KeyFrame* AnimData::getKeyframe(uint index) const {
+	if (index >= _numKeyframes) {
+		return nullptr;
+	}
+	return &_keyframes[index];
+}
+
+uint16 AnimData::getLoopFrame() const {
+	return _loopFrame;
+}
+
+uint16 AnimData::getNumBoneframes() const {
+	return _numBoneframes;
+}
+
+} // namespace TwinE
diff --git a/engines/twine/parser/anim.h b/engines/twine/parser/anim.h
new file mode 100644
index 0000000000..eede78f716
--- /dev/null
+++ b/engines/twine/parser/anim.h
@@ -0,0 +1,71 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TWINE_BODY_H
+#define TWINE_BODY_H
+
+#include "common/array.h"
+#include "common/stream.h"
+#include "twine/shared.h"
+
+namespace TwinE {
+
+struct BoneFrame {
+	uint16 type = 0;
+	int16 x = 0;
+	int16 y = 0;
+	int16 z = 0;
+};
+
+struct KeyFrame {
+	uint16 length = 0;
+	int16 x = 0;
+	int16 y = 0;
+	int16 z = 0;
+	Common::Array<BoneFrame> boneframes;
+};
+
+class AnimData {
+private:
+	Common::Array<KeyFrame> _keyframes;
+
+	bool loadBoneFrame(KeyFrame &keyframe, Common::SeekableReadStream &stream);
+	void loadKeyFrames(Common::SeekableReadStream &stream);
+
+	uint16 _numKeyframes;
+	uint16 _numBoneframes;
+	uint16 _loopFrame;
+
+public:
+	bool loadFromStream(Common::SeekableReadStream &stream);
+
+	bool loadFromBuffer(const uint8 *buf, uint32 size);
+
+	const KeyFrame* getKeyframe(uint index) const;
+	const Common::Array<KeyFrame>& getKeyframes() const;
+	uint16 getLoopFrame() const;
+	uint16 getNumBoneframes() const;
+};
+
+} // End of namespace TwinE
+
+#endif
diff --git a/engines/twine/parser/body.cpp b/engines/twine/parser/body.cpp
index 931c24d130..8077486e34 100644
--- a/engines/twine/parser/body.cpp
+++ b/engines/twine/parser/body.cpp
@@ -63,7 +63,7 @@ void BodyData::loadBones(Common::SeekableReadStream &stream) {
 		bone.parent = baseElementOffset == -1 ? 0xffff : baseElementOffset / 38;
 		bone.vertex = basePoint;
 
-		// assign the vertices to the bones
+		// assign the bone index to the vertices
 		for (int j = 0; j < numPoints; ++j) {
 			_vertices[firstPoint + j].bone = i;
 		}


Commit: 463cd54c38fea934a0fb0a715fe377d3a403dcdc
    https://github.com/scummvm/scummvm/commit/463cd54c38fea934a0fb0a715fe377d3a403dcdc
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: cleanup animation code

Changed paths:
    engines/twine/animations.cpp
    engines/twine/animations.h


diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index 203debcce5..9e46254715 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -21,6 +21,7 @@
  */
 
 #include "twine/animations.h"
+#include "common/endian.h"
 #include "common/memstream.h"
 #include "common/stream.h"
 #include "common/system.h"
@@ -67,11 +68,8 @@ int32 Animations::setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uin
 		return 0;
 	}
 
-	int16 numOfBonesInAnim = READ_LE_INT16(animPtr + 2);
-
-	// A bones is 8 bytes - length uint16, x, y and z as sint16
-	// additional 8 bytes for the animation header numkeyframes, numboneframes, loopframe and unkown uint16 fields
-	const uint8 *ptrToData = (const uint8 *)((numOfBonesInAnim * 8 + 8) * keyframeIdx + animPtr + 8);
+	int16 numOfBonesInAnim = getNumBoneframes(animPtr);
+	const uint8 *ptrToData = getKeyFrameData(keyframeIdx, animPtr);
 
 	animTimerDataPtr->ptr = ptrToData;
 	animTimerDataPtr->time = _engine->lbaTime;
@@ -89,9 +87,16 @@ int32 Animations::setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uin
 		numOfBonesInAnim = numBones;
 	}
 
-	const uint8 *ptrToDataBackup = ptrToData;
+	ptrToData += 2;
 
-	ptrToData += 8;
+	currentStepX = READ_LE_INT16(ptrToData + 0);
+	currentStepY = READ_LE_INT16(ptrToData + 2);
+	currentStepZ = READ_LE_INT16(ptrToData + 4);
+
+	processRotationByAnim = READ_LE_INT16(ptrToData + 6);
+	processLastRotationAngle = ToAngle(READ_LE_INT16(ptrToData + 10));
+
+	ptrToData += 6;
 
 	do {
 		for (int32 i = 0; i < 8; i++) {
@@ -101,23 +106,28 @@ int32 Animations::setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uin
 		bonesPtr += 30;
 	} while (--numOfBonesInAnim);
 
-	ptrToData = ptrToDataBackup + 2;
 
-	currentStepX = READ_LE_INT16(ptrToData + 0);
-	currentStepY = READ_LE_INT16(ptrToData + 2);
-	currentStepZ = READ_LE_INT16(ptrToData + 4);
+	return 1;
+}
 
-	processRotationByAnim = READ_LE_INT16(ptrToData + 6);
-	processLastRotationAngle = ToAngle(READ_LE_INT16(ptrToData + 10));
+const uint8* Animations::getKeyFrameData(int32 frameIdx, const uint8 *animPtr) {
+	const int16 numOfBonesInAnim = getNumBoneframes(animPtr);
+	return (const uint8 *)((numOfBonesInAnim * 8 + 8) * frameIdx + animPtr + 8);
+}
 
-	return 1;
+int16 Animations::getKeyFrameLength(int32 frameIdx, const uint8 *animPtr) {
+	return READ_LE_INT16(getKeyFrameData(frameIdx, animPtr));
 }
 
-int32 Animations::getNumKeyframes(const uint8 *animPtr) {
-	return READ_LE_INT16(animPtr);
+int16 Animations::getNumBoneframes(const uint8 *animPtr) {
+	return READ_LE_INT16(animPtr + 2);
 }
 
-int32 Animations::getStartKeyframe(const uint8 *animPtr) {
+int16 Animations::getNumKeyframes(const uint8 *animPtr) {
+	return READ_LE_INT16(animPtr + 0);
+}
+
+int16 Animations::getStartKeyframe(const uint8 *animPtr) {
 	return READ_LE_INT16(animPtr + 4);
 }
 
@@ -185,9 +195,9 @@ bool Animations::setModelAnimation(int32 animState, const uint8 *animPtr, uint8
 	if (!Model::isAnimated(bodyPtr)) {
 		return false;
 	}
-	int32 numOfPointInAnim = READ_LE_INT16(animPtr + 2);
-	const uint8 *keyFramePtr = ((numOfPointInAnim * 8 + 8) * animState) + animPtr + 8;
-	const int32 keyFrameLength = READ_LE_INT16(keyFramePtr);
+	int32 numOfPointInAnim = getNumBoneframes(animPtr);
+	const uint8 *keyFramePtr = getKeyFrameData(animState, animPtr);
+	const int32 keyFrameLength = getKeyFrameLength(animState, animPtr);
 
 	const uint8 *lastKeyFramePtr = animTimerDataPtr->ptr;
 	int32 remainingFrameTime = animTimerDataPtr->time;
@@ -212,6 +222,13 @@ bool Animations::setModelAnimation(int32 animState, const uint8 *animPtr, uint8
 
 	const int32 deltaTime = _engine->lbaTime - remainingFrameTime;
 
+	currentStepX = READ_LE_INT16(keyFramePtr + 2);
+	currentStepY = READ_LE_INT16(keyFramePtr + 4);
+	currentStepZ = READ_LE_INT16(keyFramePtr + 6);
+
+	processRotationByAnim = READ_LE_INT16(keyFramePtr + 8);
+	processLastRotationAngle = ToAngle(READ_LE_INT16(keyFramePtr + 12));
+
 	uint8 *edi = bonesBase + 8;
 	if (deltaTime >= keyFrameLength) {
 		const int32 *sourcePtr = (const int32 *)(keyFramePtr + 8);
@@ -226,25 +243,13 @@ bool Animations::setModelAnimation(int32 animState, const uint8 *animPtr, uint8
 		animTimerDataPtr->ptr = keyFramePtr;
 		animTimerDataPtr->time = _engine->lbaTime;
 
-		currentStepX = READ_LE_INT16(keyFramePtr + 2);
-		currentStepY = READ_LE_INT16(keyFramePtr + 4);
-		currentStepZ = READ_LE_INT16(keyFramePtr + 6);
-
-		processRotationByAnim = READ_LE_INT16(keyFramePtr + 8);
-		processLastRotationAngle = ToAngle(READ_LE_INT16(keyFramePtr + 12));
-
 		return true;
 	}
-	const uint8 *keyFramePtrOld = keyFramePtr;
 
-	lastKeyFramePtr += 8;
-	keyFramePtr += 8;
+	processLastRotationAngle = (processLastRotationAngle * deltaTime) / keyFrameLength;
 
-	processRotationByAnim = READ_LE_INT16(keyFramePtr);
-	processLastRotationAngle = ToAngle((READ_LE_INT16(keyFramePtr + 4) * deltaTime) / keyFrameLength);
-
-	lastKeyFramePtr += 8;
-	keyFramePtr += 8;
+	lastKeyFramePtr += 16;
+	keyFramePtr += 16;
 
 	edi += 38;
 
@@ -274,10 +279,6 @@ bool Animations::setModelAnimation(int32 animState, const uint8 *animPtr, uint8
 		} while (--tmpNumOfPoints);
 	}
 
-	currentStepX = (READ_LE_INT16(keyFramePtrOld + 2) * deltaTime) / keyFrameLength;
-	currentStepY = (READ_LE_INT16(keyFramePtrOld + 4) * deltaTime) / keyFrameLength;
-	currentStepZ = (READ_LE_INT16(keyFramePtrOld + 6) * deltaTime) / keyFrameLength;
-
 	return false;
 }
 
@@ -325,7 +326,7 @@ int32 Animations::stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *anim
 
 	animBufferPos += var2;
 
-	if (animBuffer + 4488 < animBufferPos) {
+	if (animBuffer + (560 * 8) + 8 < animBufferPos) {
 		animBufferPos = animBuffer;
 	}
 
@@ -333,9 +334,8 @@ int32 Animations::stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *anim
 }
 
 bool Animations::verifyAnimAtKeyframe(int32 animIdx, const uint8 *animPtr, AnimTimerDataStruct *animTimerDataPtr) {
-	const int32 numOfPointInAnim = READ_LE_INT16(animPtr + 2);
-	const uint8 *keyFramePtr = ((numOfPointInAnim * 8 + 8) * animIdx) + animPtr + 8;
-	const int32 keyFrameLength = READ_LE_INT16(keyFramePtr);
+	const uint8 *keyFramePtr = getKeyFrameData(animIdx, animPtr);
+	const int32 keyFrameLength = getKeyFrameLength(animIdx, animPtr);
 
 	const uint8 *lastKeyFramePtr = animTimerDataPtr->ptr;
 	int32 remainingFrameTime = animTimerDataPtr->time;
@@ -347,33 +347,23 @@ bool Animations::verifyAnimAtKeyframe(int32 animIdx, const uint8 *animPtr, AnimT
 
 	const int32 deltaTime = _engine->lbaTime - remainingFrameTime;
 
+	currentStepX = READ_LE_INT16(keyFramePtr + 2);
+	currentStepY = READ_LE_INT16(keyFramePtr + 4);
+	currentStepZ = READ_LE_INT16(keyFramePtr + 6);
+
+	processRotationByAnim = READ_LE_INT16(keyFramePtr + 8);
+	processLastRotationAngle = ToAngle(READ_LE_INT16(keyFramePtr + 12));
+
 	if (deltaTime >= keyFrameLength) {
 		animTimerDataPtr->ptr = keyFramePtr;
 		animTimerDataPtr->time = _engine->lbaTime;
-
-		currentStepX = READ_LE_INT16(keyFramePtr + 2);
-		currentStepY = READ_LE_INT16(keyFramePtr + 4);
-		currentStepZ = READ_LE_INT16(keyFramePtr + 6);
-
-		processRotationByAnim = READ_LE_INT16(keyFramePtr + 8);
-		processLastRotationAngle = ToAngle(READ_LE_INT16(keyFramePtr + 12));
-
 		return true;
 	}
-	const uint8 *keyFramePtrOld = keyFramePtr;
-
-	lastKeyFramePtr += 8;
-	keyFramePtr += 8;
-
-	processRotationByAnim = READ_LE_INT16(keyFramePtr);
-	processLastRotationAngle = ToAngle((READ_LE_INT16(keyFramePtr + 4) * deltaTime) / keyFrameLength);
-
-	lastKeyFramePtr += 8;
-	keyFramePtr += 8;
 
-	currentStepX = (READ_LE_INT16(keyFramePtrOld + 2) * deltaTime) / keyFrameLength;
-	currentStepY = (READ_LE_INT16(keyFramePtrOld + 4) * deltaTime) / keyFrameLength;
-	currentStepZ = (READ_LE_INT16(keyFramePtrOld + 6) * deltaTime) / keyFrameLength;
+	processLastRotationAngle = (processLastRotationAngle * deltaTime) / keyFrameLength;
+	currentStepX = (currentStepX * deltaTime) / keyFrameLength;
+	currentStepY = (currentStepY * deltaTime) / keyFrameLength;
+	currentStepZ = (currentStepZ * deltaTime) / keyFrameLength;
 
 	return false;
 }
@@ -536,7 +526,7 @@ bool Animations::initAnim(AnimationTypes newAnim, int16 animType, AnimationTypes
 	} else {
 		// interpolation between animations
 		animBufferPos += stockAnimation(_engine->_actor->bodyTable[actor->entity], &actor->animTimerData);
-		if (animBuffer + 4488 < animBufferPos) {
+		if (animBuffer + (560 * 8) + 8 < animBufferPos) {
 			animBufferPos = animBuffer;
 		}
 	}
diff --git a/engines/twine/animations.h b/engines/twine/animations.h
index 26d600cb98..d77b34eb74 100644
--- a/engines/twine/animations.h
+++ b/engines/twine/animations.h
@@ -79,17 +79,21 @@ public:
 	 */
 	int32 setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr);
 
+	int16 getNumBoneframes(const uint8 *animPtr);
+	const uint8* getKeyFrameData(int32 frameIdx, const uint8 *animPtr);
+	int16 getKeyFrameLength(int32 frameIdx, const uint8 *animPtr);
+
 	/**
 	 * Get total number of keyframes in animation
 	 * @param animPtr Pointer to animation
 	 */
-	int32 getNumKeyframes(const uint8 *animPtr);
+	int16 getNumKeyframes(const uint8 *animPtr);
 
 	/**
 	 * Get first keyframes in animation
 	 * @param animPtr Pointer to animation
 	 */
-	int32 getStartKeyframe(const uint8 *animPtr);
+	int16 getStartKeyframe(const uint8 *animPtr);
 
 	/**
 	 * Set new body animation


Commit: 86e73c9d97835ef52243a38f65a6dcbcceca4f76
    https://github.com/scummvm/scummvm/commit/86e73c9d97835ef52243a38f65a6dcbcceca4f76
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: group functions

Changed paths:
    engines/twine/animations.cpp


diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index 9e46254715..1461ea3d1b 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -58,56 +58,15 @@ Animations::~Animations() {
 	free(animBuffer);
 }
 
-int32 Animations::setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr) {
-	const int16 numOfKeyframeInAnim = READ_LE_INT16(animPtr);
-	if (keyframeIdx >= numOfKeyframeInAnim) {
-		return numOfKeyframeInAnim;
-	}
-
-	if (!Model::isAnimated(bodyPtr)) {
-		return 0;
-	}
-
-	int16 numOfBonesInAnim = getNumBoneframes(animPtr);
-	const uint8 *ptrToData = getKeyFrameData(keyframeIdx, animPtr);
-
-	animTimerDataPtr->ptr = ptrToData;
-	animTimerDataPtr->time = _engine->lbaTime;
-
-	uint8 *verticesBase = bodyPtr + 0x1A;
-	int32 numVertices = READ_LE_INT16(verticesBase);
-
-	uint8 *bonesBase = verticesBase + numVertices * 6 + 2;
-	const int16 numBones = READ_LE_INT16(bonesBase);
-
-	uint8 *bonesPtr = bonesBase + 2;
-	bonesPtr += 8;
-
-	if (numOfBonesInAnim > numBones) {
-		numOfBonesInAnim = numBones;
+int32 Animations::getBodyAnimIndex(AnimationTypes animIdx, int32 actorIdx) {
+	ActorStruct *actor = _engine->_scene->getActor(actorIdx);
+	EntityData entityData;
+	entityData.loadFromBuffer(actor->entityDataPtr, actor->entityDataSize);
+	const int32 bodyAnimIndex = entityData.getAnimIndex(animIdx);
+	if (bodyAnimIndex != -1) {
+		currentActorAnimExtraPtr = animIdx;
 	}
-
-	ptrToData += 2;
-
-	currentStepX = READ_LE_INT16(ptrToData + 0);
-	currentStepY = READ_LE_INT16(ptrToData + 2);
-	currentStepZ = READ_LE_INT16(ptrToData + 4);
-
-	processRotationByAnim = READ_LE_INT16(ptrToData + 6);
-	processLastRotationAngle = ToAngle(READ_LE_INT16(ptrToData + 10));
-
-	ptrToData += 6;
-
-	do {
-		for (int32 i = 0; i < 8; i++) {
-			*bonesPtr++ = *ptrToData++;
-		}
-
-		bonesPtr += 30;
-	} while (--numOfBonesInAnim);
-
-
-	return 1;
+	return bodyAnimIndex;
 }
 
 const uint8* Animations::getKeyFrameData(int32 frameIdx, const uint8 *animPtr) {
@@ -282,15 +241,56 @@ bool Animations::setModelAnimation(int32 animState, const uint8 *animPtr, uint8
 	return false;
 }
 
-int32 Animations::getBodyAnimIndex(AnimationTypes animIdx, int32 actorIdx) {
-	ActorStruct *actor = _engine->_scene->getActor(actorIdx);
-	EntityData entityData;
-	entityData.loadFromBuffer(actor->entityDataPtr, actor->entityDataSize);
-	const int32 bodyAnimIndex = entityData.getAnimIndex(animIdx);
-	if (bodyAnimIndex != -1) {
-		currentActorAnimExtraPtr = animIdx;
+int32 Animations::setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr) {
+	const int16 numOfKeyframeInAnim = READ_LE_INT16(animPtr);
+	if (keyframeIdx >= numOfKeyframeInAnim) {
+		return numOfKeyframeInAnim;
 	}
-	return bodyAnimIndex;
+
+	if (!Model::isAnimated(bodyPtr)) {
+		return 0;
+	}
+
+	int16 numOfBonesInAnim = getNumBoneframes(animPtr);
+	const uint8 *ptrToData = getKeyFrameData(keyframeIdx, animPtr);
+
+	animTimerDataPtr->ptr = ptrToData;
+	animTimerDataPtr->time = _engine->lbaTime;
+
+	uint8 *verticesBase = bodyPtr + 0x1A;
+	int32 numVertices = READ_LE_INT16(verticesBase);
+
+	uint8 *bonesBase = verticesBase + numVertices * 6 + 2;
+	const int16 numBones = READ_LE_INT16(bonesBase);
+
+	uint8 *bonesPtr = bonesBase + 2;
+	bonesPtr += 8;
+
+	if (numOfBonesInAnim > numBones) {
+		numOfBonesInAnim = numBones;
+	}
+
+	ptrToData += 2;
+
+	currentStepX = READ_LE_INT16(ptrToData + 0);
+	currentStepY = READ_LE_INT16(ptrToData + 2);
+	currentStepZ = READ_LE_INT16(ptrToData + 4);
+
+	processRotationByAnim = READ_LE_INT16(ptrToData + 6);
+	processLastRotationAngle = ToAngle(READ_LE_INT16(ptrToData + 10));
+
+	ptrToData += 6;
+
+	do {
+		for (int32 i = 0; i < 8; i++) {
+			*bonesPtr++ = *ptrToData++;
+		}
+
+		bonesPtr += 30;
+	} while (--numOfBonesInAnim);
+
+
+	return 1;
 }
 
 int32 Animations::stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr) {


Commit: d8645be0b2b00509fe8c5c796f324265eb2a0950
    https://github.com/scummvm/scummvm/commit/d8645be0b2b00509fe8c5c796f324265eb2a0950
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: don't advance the animBufferPos twice

this is already done in stockAnimation()

Changed paths:
    engines/twine/animations.cpp
    engines/twine/animations.h


diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index 1461ea3d1b..0fb6747226 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -293,9 +293,9 @@ int32 Animations::setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uin
 	return 1;
 }
 
-int32 Animations::stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr) {
+void Animations::stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr) {
 	if (!Model::isAnimated(bodyPtr)) {
-		return 0;
+		return;
 	}
 	uint8 *animPtr = animBufferPos;
 
@@ -329,8 +329,6 @@ int32 Animations::stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *anim
 	if (animBuffer + (560 * 8) + 8 < animBufferPos) {
 		animBufferPos = animBuffer;
 	}
-
-	return var2;
 }
 
 bool Animations::verifyAnimAtKeyframe(int32 animIdx, const uint8 *animPtr, AnimTimerDataStruct *animTimerDataPtr) {
@@ -525,10 +523,7 @@ bool Animations::initAnim(AnimationTypes newAnim, int16 animType, AnimationTypes
 		setAnimAtKeyframe(0, _engine->_resources->animTable[animIndex], _engine->_actor->bodyTable[actor->entity], &actor->animTimerData);
 	} else {
 		// interpolation between animations
-		animBufferPos += stockAnimation(_engine->_actor->bodyTable[actor->entity], &actor->animTimerData);
-		if (animBuffer + (560 * 8) + 8 < animBufferPos) {
-			animBufferPos = animBuffer;
-		}
+		stockAnimation(_engine->_actor->bodyTable[actor->entity], &actor->animTimerData);
 	}
 
 	actor->previousAnimIdx = animIndex;
diff --git a/engines/twine/animations.h b/engines/twine/animations.h
index d77b34eb74..81b004e114 100644
--- a/engines/twine/animations.h
+++ b/engines/twine/animations.h
@@ -116,7 +116,7 @@ public:
 	 * @param bodyPtr Body model poitner
 	 * @param animTimerDataPtr Animation time data
 	 */
-	int32 stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr);
+	void stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr);
 
 	/**
 	 * Initialize animation


Commit: 0271d545687861b08fa266662a36c9c756ba0f5e
    https://github.com/scummvm/scummvm/commit/0271d545687861b08fa266662a36c9c756ba0f5e
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: cleanup animation code

Changed paths:
    engines/twine/animations.cpp


diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index 0fb6747226..2a318c46a4 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -297,34 +297,27 @@ void Animations::stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *animT
 	if (!Model::isAnimated(bodyPtr)) {
 		return;
 	}
-	uint8 *animPtr = animBufferPos;
-
-	const uint8 *verticesBase = bodyPtr + 0x1A;
 
 	animTimerDataPtr->time = _engine->lbaTime;
-	animTimerDataPtr->ptr = animPtr;
+	animTimerDataPtr->ptr = animBufferPos;
 
+	const uint8 *verticesBase = bodyPtr + 0x1A;
 	int32 numVertices = READ_LE_INT16(verticesBase);
-	const uint8 *ptr = verticesBase + numVertices * 6 + 2;
+	const uint8 *bonesBase = verticesBase + numVertices * 6 + 2;
+	int32 numBones = READ_LE_INT16(bonesBase);
 
-	int32 numBones = READ_LE_INT16(ptr);
-	ptr += 2;
-
-	int32 counter = numBones;
-	// 8 = 4xint16 - firstpoint, numpoints, basepoint, baseelement - see elementEntry
-	int32 var2 = (numBones * 8) + 8;
+	int32 *edi = (int32 *)(animBufferPos + 8);
+	const int32 *esi = (const int32 *)(bonesBase + 10);
 
-	int32 *edi = (int32 *)(animPtr + 8);
-	const int32 *esi = (const int32 *)(ptr + 8);
-
-	do {
+	for (int32 i = 0; i < numBones; ++i) {
 		*(edi++) = *(esi++);
 		*(edi++) = *(esi++);
 
 		esi = (const int32 *)(((const int8 *)esi) + 30);
-	} while (counter--);
+	}
 
-	animBufferPos += var2;
+	// 8 = 4xint16 - firstpoint, numpoints, basepoint, baseelement - see elementEntry
+	animBufferPos += (numBones * 8) + 8;
 
 	if (animBuffer + (560 * 8) + 8 < animBufferPos) {
 		animBufferPos = animBuffer;


Commit: c08493167459bb803420f6c7dc2fff43fb6ce47b
    https://github.com/scummvm/scummvm/commit/c08493167459bb803420f6c7dc2fff43fb6ce47b
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: unify bone transfer

Changed paths:
    engines/twine/animations.cpp


diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index 2a318c46a4..9256b1f3b3 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -306,14 +306,14 @@ void Animations::stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *animT
 	const uint8 *bonesBase = verticesBase + numVertices * 6 + 2;
 	int32 numBones = READ_LE_INT16(bonesBase);
 
-	int32 *edi = (int32 *)(animBufferPos + 8);
-	const int32 *esi = (const int32 *)(bonesBase + 10);
+	uint8 *bonesPtr = animBufferPos + 8;
+	const uint8 *ptrToData = bonesBase + 10;
 
 	for (int32 i = 0; i < numBones; ++i) {
-		*(edi++) = *(esi++);
-		*(edi++) = *(esi++);
-
-		esi = (const int32 *)(((const int8 *)esi) + 30);
+		for (int32 j = 0; j < 8; j++) {
+			*bonesPtr++ = *ptrToData++;
+		}
+		ptrToData += 30;
 	}
 
 	// 8 = 4xint16 - firstpoint, numpoints, basepoint, baseelement - see elementEntry


Commit: dbe4698984a675fc28d808109133d0ac5d0dd4c7
    https://github.com/scummvm/scummvm/commit/dbe4698984a675fc28d808109133d0ac5d0dd4c7
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: unified animation code

Changed paths:
    engines/twine/animations.cpp


diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index 9256b1f3b3..b0cd93d21f 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -259,27 +259,23 @@ int32 Animations::setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uin
 
 	uint8 *verticesBase = bodyPtr + 0x1A;
 	int32 numVertices = READ_LE_INT16(verticesBase);
-
 	uint8 *bonesBase = verticesBase + numVertices * 6 + 2;
 	const int16 numBones = READ_LE_INT16(bonesBase);
-
-	uint8 *bonesPtr = bonesBase + 2;
-	bonesPtr += 8;
+	uint8 *bonesPtr = bonesBase + 2 + 8;
 
 	if (numOfBonesInAnim > numBones) {
 		numOfBonesInAnim = numBones;
 	}
 
-	ptrToData += 2;
 
-	currentStepX = READ_LE_INT16(ptrToData + 0);
-	currentStepY = READ_LE_INT16(ptrToData + 2);
-	currentStepZ = READ_LE_INT16(ptrToData + 4);
+	currentStepX = READ_LE_INT16(ptrToData + 2);
+	currentStepY = READ_LE_INT16(ptrToData + 4);
+	currentStepZ = READ_LE_INT16(ptrToData + 6);
 
-	processRotationByAnim = READ_LE_INT16(ptrToData + 6);
-	processLastRotationAngle = ToAngle(READ_LE_INT16(ptrToData + 10));
+	processRotationByAnim = READ_LE_INT16(ptrToData + 8);
+	processLastRotationAngle = ToAngle(READ_LE_INT16(ptrToData + 12));
 
-	ptrToData += 6;
+	ptrToData += 8;
 
 	do {
 		for (int32 i = 0; i < 8; i++) {


Commit: 123d8a163c0a5cede8203c04f6b2d4c63e96d6e1
    https://github.com/scummvm/scummvm/commit/123d8a163c0a5cede8203c04f6b2d4c63e96d6e1
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: renamed variables

Changed paths:
    engines/twine/animations.cpp


diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index b0cd93d21f..34ab0e0d5e 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -167,13 +167,9 @@ bool Animations::setModelAnimation(int32 animState, const uint8 *animPtr, uint8
 	}
 
 	uint8 *verticesBase = bodyPtr + 0x1A;
-
 	const int16 numVertices = READ_LE_INT16(verticesBase);
-	verticesBase += 2;
-	uint8 *bonesBase = verticesBase + numVertices * 6;
-
+	uint8 *bonesBase = verticesBase + 2 + numVertices * 6;
 	const int32 numBones = READ_LE_INT16(bonesBase);
-	bonesBase += 2;
 
 	if (numOfPointInAnim > numBones) {
 		numOfPointInAnim = numBones;
@@ -188,10 +184,10 @@ bool Animations::setModelAnimation(int32 animState, const uint8 *animPtr, uint8
 	processRotationByAnim = READ_LE_INT16(keyFramePtr + 8);
 	processLastRotationAngle = ToAngle(READ_LE_INT16(keyFramePtr + 12));
 
-	uint8 *edi = bonesBase + 8;
+	uint8 *bonesPtr = bonesBase + 8 + 2;
 	if (deltaTime >= keyFrameLength) {
 		const int32 *sourcePtr = (const int32 *)(keyFramePtr + 8);
-		int32 *destPtr = (int32 *)edi; // keyframe
+		int32 *destPtr = (int32 *)bonesPtr; // keyframe
 
 		do {
 			*(destPtr++) = *(sourcePtr++);
@@ -210,31 +206,31 @@ bool Animations::setModelAnimation(int32 animState, const uint8 *animPtr, uint8
 	lastKeyFramePtr += 16;
 	keyFramePtr += 16;
 
-	edi += 38;
+	bonesPtr += 38;
 
 	if (--numOfPointInAnim) {
 		int16 tmpNumOfPoints = numOfPointInAnim;
 
 		do {
-			const int16 animOpcode = getAnimMode(&edi, &keyFramePtr, &lastKeyFramePtr);
+			const int16 animOpcode = getAnimMode(&bonesPtr, &keyFramePtr, &lastKeyFramePtr);
 
 			switch (animOpcode) {
 			case 0: // allow global rotate
-				applyAnimStepRotation(&edi, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
-				applyAnimStepRotation(&edi, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
-				applyAnimStepRotation(&edi, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
+				applyAnimStepRotation(&bonesPtr, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
+				applyAnimStepRotation(&bonesPtr, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
+				applyAnimStepRotation(&bonesPtr, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
 				break;
 			case 1: // dissallow global rotate
 			case 2: // dissallow global rotate + hide
-				applyAnimStep(&edi, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
-				applyAnimStep(&edi, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
-				applyAnimStep(&edi, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
+				applyAnimStep(&bonesPtr, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
+				applyAnimStep(&bonesPtr, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
+				applyAnimStep(&bonesPtr, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
 				break;
 			default:
 				error("Unsupported animation rotation mode %d", animOpcode);
 			}
 
-			edi += 30;
+			bonesPtr += 30;
 		} while (--tmpNumOfPoints);
 	}
 
@@ -242,7 +238,7 @@ bool Animations::setModelAnimation(int32 animState, const uint8 *animPtr, uint8
 }
 
 int32 Animations::setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr) {
-	const int16 numOfKeyframeInAnim = READ_LE_INT16(animPtr);
+	const int16 numOfKeyframeInAnim = getNumKeyframes(animPtr);
 	if (keyframeIdx >= numOfKeyframeInAnim) {
 		return numOfKeyframeInAnim;
 	}
@@ -267,7 +263,6 @@ int32 Animations::setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uin
 		numOfBonesInAnim = numBones;
 	}
 
-
 	currentStepX = READ_LE_INT16(ptrToData + 2);
 	currentStepY = READ_LE_INT16(ptrToData + 4);
 	currentStepZ = READ_LE_INT16(ptrToData + 6);
@@ -277,14 +272,13 @@ int32 Animations::setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uin
 
 	ptrToData += 8;
 
-	do {
-		for (int32 i = 0; i < 8; i++) {
+	for (int32 i = 0; i < numOfBonesInAnim; ++i) {
+		for (int32 j = 0; j < 8; j++) {
 			*bonesPtr++ = *ptrToData++;
 		}
 
 		bonesPtr += 30;
-	} while (--numOfBonesInAnim);
-
+	}
 
 	return 1;
 }


Commit: cbbfea5a3309be8204464ff3c4cd4d3b244c2c9c
    https://github.com/scummvm/scummvm/commit/cbbfea5a3309be8204464ff3c4cd4d3b244c2c9c
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: unified animation code

Changed paths:
    engines/twine/animations.cpp


diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index 34ab0e0d5e..10be7f6dc4 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -154,7 +154,7 @@ bool Animations::setModelAnimation(int32 animState, const uint8 *animPtr, uint8
 	if (!Model::isAnimated(bodyPtr)) {
 		return false;
 	}
-	int32 numOfPointInAnim = getNumBoneframes(animPtr);
+	int32 numOfBonesInAnim = getNumBoneframes(animPtr);
 	const uint8 *keyFramePtr = getKeyFrameData(animState, animPtr);
 	const int32 keyFrameLength = getKeyFrameLength(animState, animPtr);
 
@@ -171,8 +171,8 @@ bool Animations::setModelAnimation(int32 animState, const uint8 *animPtr, uint8
 	uint8 *bonesBase = verticesBase + 2 + numVertices * 6;
 	const int32 numBones = READ_LE_INT16(bonesBase);
 
-	if (numOfPointInAnim > numBones) {
-		numOfPointInAnim = numBones;
+	if (numOfBonesInAnim > numBones) {
+		numOfBonesInAnim = numBones;
 	}
 
 	const int32 deltaTime = _engine->lbaTime - remainingFrameTime;
@@ -186,18 +186,16 @@ bool Animations::setModelAnimation(int32 animState, const uint8 *animPtr, uint8
 
 	uint8 *bonesPtr = bonesBase + 8 + 2;
 	if (deltaTime >= keyFrameLength) {
-		const int32 *sourcePtr = (const int32 *)(keyFramePtr + 8);
-		int32 *destPtr = (int32 *)bonesPtr; // keyframe
-
-		do {
-			*(destPtr++) = *(sourcePtr++);
-			*(destPtr++) = *(sourcePtr++);
-			destPtr = (int32 *)(((int8 *)destPtr) + 30);
-		} while (--numOfPointInAnim);
+		const uint8 *ptrToData = keyFramePtr + 8;
+		for (int32 i = 0; i < numOfBonesInAnim; ++i) {
+			for (int32 j = 0; j < 8; j++) {
+				*bonesPtr++ = *ptrToData++;
+			}
+			bonesPtr += 30;
+		}
 
 		animTimerDataPtr->ptr = keyFramePtr;
 		animTimerDataPtr->time = _engine->lbaTime;
-
 		return true;
 	}
 
@@ -208,8 +206,8 @@ bool Animations::setModelAnimation(int32 animState, const uint8 *animPtr, uint8
 
 	bonesPtr += 38;
 
-	if (--numOfPointInAnim) {
-		int16 tmpNumOfPoints = numOfPointInAnim;
+	if (numOfBonesInAnim > 0) {
+		int16 tmpNumOfPoints = numOfBonesInAnim - 1;
 
 		do {
 			const int16 animOpcode = getAnimMode(&bonesPtr, &keyFramePtr, &lastKeyFramePtr);


Commit: 3c3fd773f1cc3df2b4a72a7b334facdb6391cdb3
    https://github.com/scummvm/scummvm/commit/3c3fd773f1cc3df2b4a72a7b334facdb6391cdb3
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: reduced cyclic complexity and fixed potential endless loop

if numOfBonesInAnim was just 1

Changed paths:
    engines/twine/animations.cpp


diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index 10be7f6dc4..0220fe609c 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -206,32 +206,33 @@ bool Animations::setModelAnimation(int32 animState, const uint8 *animPtr, uint8
 
 	bonesPtr += 38;
 
-	if (numOfBonesInAnim > 0) {
-		int16 tmpNumOfPoints = numOfBonesInAnim - 1;
-
-		do {
-			const int16 animOpcode = getAnimMode(&bonesPtr, &keyFramePtr, &lastKeyFramePtr);
-
-			switch (animOpcode) {
-			case 0: // allow global rotate
-				applyAnimStepRotation(&bonesPtr, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
-				applyAnimStepRotation(&bonesPtr, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
-				applyAnimStepRotation(&bonesPtr, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
-				break;
-			case 1: // dissallow global rotate
-			case 2: // dissallow global rotate + hide
-				applyAnimStep(&bonesPtr, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
-				applyAnimStep(&bonesPtr, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
-				applyAnimStep(&bonesPtr, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
-				break;
-			default:
-				error("Unsupported animation rotation mode %d", animOpcode);
-			}
-
-			bonesPtr += 30;
-		} while (--tmpNumOfPoints);
+	if (numOfBonesInAnim <= 1) {
+		return false;
 	}
 
+	int16 tmpNumOfPoints = numOfBonesInAnim - 1;
+	do {
+		const int16 animOpcode = getAnimMode(&bonesPtr, &keyFramePtr, &lastKeyFramePtr);
+
+		switch (animOpcode) {
+		case 0: // allow global rotate
+			applyAnimStepRotation(&bonesPtr, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
+			applyAnimStepRotation(&bonesPtr, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
+			applyAnimStepRotation(&bonesPtr, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
+			break;
+		case 1: // dissallow global rotate
+		case 2: // dissallow global rotate + hide
+			applyAnimStep(&bonesPtr, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
+			applyAnimStep(&bonesPtr, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
+			applyAnimStep(&bonesPtr, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
+			break;
+		default:
+			error("Unsupported animation rotation mode %d", animOpcode);
+		}
+
+		bonesPtr += 30;
+	} while (--tmpNumOfPoints);
+
 	return false;
 }
 


Commit: dffd8cc63f16bc3213b08de05f93cbc8a380a79f
    https://github.com/scummvm/scummvm/commit/dffd8cc63f16bc3213b08de05f93cbc8a380a79f
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: make it easier to follow the data offsets

Changed paths:
    engines/twine/animations.cpp
    engines/twine/animations.h


diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index 0220fe609c..0f1d08b5c1 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -90,12 +90,9 @@ int16 Animations::getStartKeyframe(const uint8 *animPtr) {
 	return READ_LE_INT16(animPtr + 4);
 }
 
-void Animations::applyAnimStepRotation(uint8 **ptr, int32 bp, int32 bx, const uint8 **keyFramePtr, const uint8 **lastKeyFramePtr) {
-	const int16 lastAngle = ClampAngle(READ_LE_INT16(*lastKeyFramePtr));
-	*lastKeyFramePtr += 2;
-
-	const int16 newAngle = ClampAngle(READ_LE_INT16(*keyFramePtr));
-	*keyFramePtr += 2;
+void Animations::applyAnimStepRotation(uint8 *ptr, int32 bp, int32 bx, const uint8 *keyFramePtr, const uint8 *lastKeyFramePtr) {
+	const int16 lastAngle = ClampAngle(READ_LE_INT16(lastKeyFramePtr));
+	const int16 newAngle = ClampAngle(READ_LE_INT16(keyFramePtr));
 
 	int16 angleDiff = newAngle - lastAngle;
 
@@ -112,17 +109,12 @@ void Animations::applyAnimStepRotation(uint8 **ptr, int32 bp, int32 bx, const ui
 		computedAngle = lastAngle;
 	}
 
-	int16 *dest = (int16 *)*(ptr);
-	*dest = ClampAngle(computedAngle);
-	*(ptr) = *(ptr) + 2;
+	*(int16 *)ptr = ClampAngle(computedAngle);
 }
 
-void Animations::applyAnimStep(uint8 **ptr, int32 bp, int32 bx, const uint8 **keyFramePtr, const uint8 **lastKeyFramePtr) {
-	int16 lastAngle = READ_LE_INT16(*lastKeyFramePtr);
-	*lastKeyFramePtr += 2;
-
-	int16 newAngle = READ_LE_INT16(*keyFramePtr);
-	*keyFramePtr += 2;
+void Animations::applyAnimStep(uint8 *ptr, int32 bp, int32 bx, const uint8 *keyFramePtr, const uint8 *lastKeyFramePtr) {
+	int16 lastAngle = READ_LE_INT16(lastKeyFramePtr);
+	int16 newAngle = READ_LE_INT16(keyFramePtr);
 
 	int16 angleDif = newAngle - lastAngle;
 
@@ -133,20 +125,12 @@ void Animations::applyAnimStep(uint8 **ptr, int32 bp, int32 bx, const uint8 **ke
 		computedAngle = lastAngle;
 	}
 
-	int16 *dest = (int16 *)*(ptr);
-	*dest = computedAngle;
-	*(ptr) = *(ptr) + 2;
+	*(int16 *)ptr = computedAngle;
 }
 
-int32 Animations::getAnimMode(uint8 **ptr, const uint8 **keyFramePtr, const uint8 **lastKeyFramePtr) {
-	int16 *lptr = (int16 *)*ptr;
-	int16 opcode = READ_LE_INT16(*keyFramePtr);
-	*(int16 *)(lptr) = opcode;
-
-	*keyFramePtr += 2;
-	*(ptr) = *(ptr) + 2;
-	*lastKeyFramePtr += 2;
-
+int32 Animations::getAnimMode(uint8 *ptr, const uint8 *keyFramePtr, const uint8 *lastKeyFramePtr) {
+	const int16 opcode = READ_LE_INT16(keyFramePtr);
+	*(int16 *)ptr = opcode;
 	return opcode;
 }
 
@@ -161,7 +145,7 @@ bool Animations::setModelAnimation(int32 animState, const uint8 *animPtr, uint8
 	const uint8 *lastKeyFramePtr = animTimerDataPtr->ptr;
 	int32 remainingFrameTime = animTimerDataPtr->time;
 
-	if (!lastKeyFramePtr) {
+	if (lastKeyFramePtr == nullptr) {
 		lastKeyFramePtr = keyFramePtr;
 		remainingFrameTime = keyFrameLength;
 	}
@@ -184,10 +168,11 @@ bool Animations::setModelAnimation(int32 animState, const uint8 *animPtr, uint8
 	processRotationByAnim = READ_LE_INT16(keyFramePtr + 8);
 	processLastRotationAngle = ToAngle(READ_LE_INT16(keyFramePtr + 12));
 
-	uint8 *bonesPtr = bonesBase + 8 + 2;
+	uint8 *bonesPtr = bonesBase + 2 + 8;
 	if (deltaTime >= keyFrameLength) {
 		const uint8 *ptrToData = keyFramePtr + 8;
 		for (int32 i = 0; i < numOfBonesInAnim; ++i) {
+			// these are 4 int16 values
 			for (int32 j = 0; j < 8; j++) {
 				*bonesPtr++ = *ptrToData++;
 			}
@@ -212,25 +197,27 @@ bool Animations::setModelAnimation(int32 animState, const uint8 *animPtr, uint8
 
 	int16 tmpNumOfPoints = numOfBonesInAnim - 1;
 	do {
-		const int16 animOpcode = getAnimMode(&bonesPtr, &keyFramePtr, &lastKeyFramePtr);
+		const int16 animOpcode = getAnimMode(bonesPtr + 0, keyFramePtr + 0, lastKeyFramePtr + 0);
 
 		switch (animOpcode) {
 		case 0: // allow global rotate
-			applyAnimStepRotation(&bonesPtr, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
-			applyAnimStepRotation(&bonesPtr, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
-			applyAnimStepRotation(&bonesPtr, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
+			applyAnimStepRotation(bonesPtr + 2, deltaTime, keyFrameLength, keyFramePtr + 2, lastKeyFramePtr + 2);
+			applyAnimStepRotation(bonesPtr + 4, deltaTime, keyFrameLength, keyFramePtr + 4, lastKeyFramePtr + 4);
+			applyAnimStepRotation(bonesPtr + 6, deltaTime, keyFrameLength, keyFramePtr + 6, lastKeyFramePtr + 6);
 			break;
-		case 1: // dissallow global rotate
-		case 2: // dissallow global rotate + hide
-			applyAnimStep(&bonesPtr, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
-			applyAnimStep(&bonesPtr, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
-			applyAnimStep(&bonesPtr, deltaTime, keyFrameLength, &keyFramePtr, &lastKeyFramePtr);
+		case 1: // disallow global rotate
+		case 2: // disallow global rotate + hide
+			applyAnimStep(bonesPtr + 2, deltaTime, keyFrameLength, keyFramePtr + 2, lastKeyFramePtr + 2);
+			applyAnimStep(bonesPtr + 4, deltaTime, keyFrameLength, keyFramePtr + 4, lastKeyFramePtr + 4);
+			applyAnimStep(bonesPtr + 6, deltaTime, keyFrameLength, keyFramePtr + 6, lastKeyFramePtr + 6);
 			break;
 		default:
 			error("Unsupported animation rotation mode %d", animOpcode);
 		}
 
-		bonesPtr += 30;
+		lastKeyFramePtr += 8;
+		keyFramePtr += 8;
+		bonesPtr += 38;
 	} while (--tmpNumOfPoints);
 
 	return false;
@@ -254,7 +241,7 @@ int32 Animations::setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uin
 
 	uint8 *verticesBase = bodyPtr + 0x1A;
 	int32 numVertices = READ_LE_INT16(verticesBase);
-	uint8 *bonesBase = verticesBase + numVertices * 6 + 2;
+	uint8 *bonesBase = verticesBase + 2 + numVertices * 6;
 	const int16 numBones = READ_LE_INT16(bonesBase);
 	uint8 *bonesPtr = bonesBase + 2 + 8;
 
@@ -272,6 +259,7 @@ int32 Animations::setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uin
 	ptrToData += 8;
 
 	for (int32 i = 0; i < numOfBonesInAnim; ++i) {
+		// these are 4 int16 values
 		for (int32 j = 0; j < 8; j++) {
 			*bonesPtr++ = *ptrToData++;
 		}
@@ -292,13 +280,14 @@ void Animations::stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *animT
 
 	const uint8 *verticesBase = bodyPtr + 0x1A;
 	int32 numVertices = READ_LE_INT16(verticesBase);
-	const uint8 *bonesBase = verticesBase + numVertices * 6 + 2;
+	const uint8 *bonesBase = verticesBase + 2 + numVertices * 6;
 	int32 numBones = READ_LE_INT16(bonesBase);
 
 	uint8 *bonesPtr = animBufferPos + 8;
 	const uint8 *ptrToData = bonesBase + 10;
 
 	for (int32 i = 0; i < numBones; ++i) {
+		// these are 4 int16 values
 		for (int32 j = 0; j < 8; j++) {
 			*bonesPtr++ = *ptrToData++;
 		}
@@ -320,7 +309,7 @@ bool Animations::verifyAnimAtKeyframe(int32 animIdx, const uint8 *animPtr, AnimT
 	const uint8 *lastKeyFramePtr = animTimerDataPtr->ptr;
 	int32 remainingFrameTime = animTimerDataPtr->time;
 
-	if (!lastKeyFramePtr) {
+	if (lastKeyFramePtr == nullptr) {
 		lastKeyFramePtr = keyFramePtr;
 		remainingFrameTime = keyFrameLength;
 	}
diff --git a/engines/twine/animations.h b/engines/twine/animations.h
index 81b004e114..9586a16fbf 100644
--- a/engines/twine/animations.h
+++ b/engines/twine/animations.h
@@ -34,9 +34,9 @@ class TwinEEngine;
 class Animations {
 private:
 	TwinEEngine *_engine;
-	void applyAnimStepRotation(uint8 **ptr, int32 bp, int32 bx, const uint8 **keyFramePtr, const uint8 **lastKeyFramePtr);
-	int32 getAnimMode(uint8 **ptr, const uint8 **keyFramePtr, const uint8 **lastKeyFramePtr);
-	void applyAnimStep(uint8 **ptr, int32 bp, int32 bx, const uint8 **keyFramePtr, const uint8 **lastKeyFramePtr);
+	void applyAnimStepRotation(uint8 *ptr, int32 bp, int32 bx, const uint8 *keyFramePtr, const uint8 *lastKeyFramePtr);
+	int32 getAnimMode(uint8 *ptr, const uint8 *keyFramePtr, const uint8 *lastKeyFramePtr);
+	void applyAnimStep(uint8 *ptr, int32 bp, int32 bx, const uint8 *keyFramePtr, const uint8 *lastKeyFramePtr);
 
 	/**
 	 * Verify animation at keyframe


Commit: 4d9bfa493bcc823f3fa85e76270da0f7f3de6ea8
    https://github.com/scummvm/scummvm/commit/4d9bfa493bcc823f3fa85e76270da0f7f3de6ea8
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: removed unused return value

Changed paths:
    engines/twine/animations.cpp
    engines/twine/animations.h


diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index 0f1d08b5c1..df8bbf5b43 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -223,14 +223,14 @@ bool Animations::setModelAnimation(int32 animState, const uint8 *animPtr, uint8
 	return false;
 }
 
-int32 Animations::setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr) {
+void Animations::setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr) {
 	const int16 numOfKeyframeInAnim = getNumKeyframes(animPtr);
-	if (keyframeIdx >= numOfKeyframeInAnim) {
-		return numOfKeyframeInAnim;
+	if (keyframeIdx < 0 || keyframeIdx >= numOfKeyframeInAnim) {
+		return;
 	}
 
 	if (!Model::isAnimated(bodyPtr)) {
-		return 0;
+		return;
 	}
 
 	int16 numOfBonesInAnim = getNumBoneframes(animPtr);
@@ -267,7 +267,7 @@ int32 Animations::setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uin
 		bonesPtr += 30;
 	}
 
-	return 1;
+	return;
 }
 
 void Animations::stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr) {
diff --git a/engines/twine/animations.h b/engines/twine/animations.h
index 9586a16fbf..616e54be33 100644
--- a/engines/twine/animations.h
+++ b/engines/twine/animations.h
@@ -77,7 +77,7 @@ public:
 	 * @param bodyPtr Body model poitner
 	 * @param animTimerDataPtr Animation time data
 	 */
-	int32 setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr);
+	void setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr);
 
 	int16 getNumBoneframes(const uint8 *animPtr);
 	const uint8* getKeyFrameData(int32 frameIdx, const uint8 *animPtr);


Commit: 1a5a3da35bccccee5be55b805b7ad7d2b5e30b89
    https://github.com/scummvm/scummvm/commit/1a5a3da35bccccee5be55b805b7ad7d2b5e30b89
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: renamed method parameters

Changed paths:
    engines/twine/animations.cpp
    engines/twine/animations.h


diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index df8bbf5b43..faccbd9c1c 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -90,7 +90,7 @@ int16 Animations::getStartKeyframe(const uint8 *animPtr) {
 	return READ_LE_INT16(animPtr + 4);
 }
 
-void Animations::applyAnimStepRotation(uint8 *ptr, int32 bp, int32 bx, const uint8 *keyFramePtr, const uint8 *lastKeyFramePtr) {
+void Animations::applyAnimStepRotation(uint8 *ptr, int32 deltaTime, int32 keyFrameLength, const uint8 *keyFramePtr, const uint8 *lastKeyFramePtr) {
 	const int16 lastAngle = ClampAngle(READ_LE_INT16(lastKeyFramePtr));
 	const int16 newAngle = ClampAngle(READ_LE_INT16(keyFramePtr));
 
@@ -104,7 +104,7 @@ void Animations::applyAnimStepRotation(uint8 *ptr, int32 bp, int32 bx, const uin
 			angleDiff -= ANGLE_360;
 		}
 
-		computedAngle = lastAngle + (angleDiff * bp) / bx;
+		computedAngle = lastAngle + (angleDiff * deltaTime) / keyFrameLength;
 	} else {
 		computedAngle = lastAngle;
 	}
@@ -112,7 +112,7 @@ void Animations::applyAnimStepRotation(uint8 *ptr, int32 bp, int32 bx, const uin
 	*(int16 *)ptr = ClampAngle(computedAngle);
 }
 
-void Animations::applyAnimStep(uint8 *ptr, int32 bp, int32 bx, const uint8 *keyFramePtr, const uint8 *lastKeyFramePtr) {
+void Animations::applyAnimStep(uint8 *ptr, int32 deltaTime, int32 keyFrameLength, const uint8 *keyFramePtr, const uint8 *lastKeyFramePtr) {
 	int16 lastAngle = READ_LE_INT16(lastKeyFramePtr);
 	int16 newAngle = READ_LE_INT16(keyFramePtr);
 
@@ -120,7 +120,7 @@ void Animations::applyAnimStep(uint8 *ptr, int32 bp, int32 bx, const uint8 *keyF
 
 	int16 computedAngle;
 	if (angleDif) {
-		computedAngle = lastAngle + (angleDif * bp) / bx;
+		computedAngle = lastAngle + (angleDif * deltaTime) / keyFrameLength;
 	} else {
 		computedAngle = lastAngle;
 	}
@@ -134,13 +134,13 @@ int32 Animations::getAnimMode(uint8 *ptr, const uint8 *keyFramePtr, const uint8
 	return opcode;
 }
 
-bool Animations::setModelAnimation(int32 animState, const uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr) {
+bool Animations::setModelAnimation(int32 keyframeIdx, const uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr) {
 	if (!Model::isAnimated(bodyPtr)) {
 		return false;
 	}
 	int32 numOfBonesInAnim = getNumBoneframes(animPtr);
-	const uint8 *keyFramePtr = getKeyFrameData(animState, animPtr);
-	const int32 keyFrameLength = getKeyFrameLength(animState, animPtr);
+	const uint8 *keyFramePtr = getKeyFrameData(keyframeIdx, animPtr);
+	const int32 keyFrameLength = getKeyFrameLength(keyframeIdx, animPtr);
 
 	const uint8 *lastKeyFramePtr = animTimerDataPtr->ptr;
 	int32 remainingFrameTime = animTimerDataPtr->time;
@@ -302,9 +302,9 @@ void Animations::stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *animT
 	}
 }
 
-bool Animations::verifyAnimAtKeyframe(int32 animIdx, const uint8 *animPtr, AnimTimerDataStruct *animTimerDataPtr) {
-	const uint8 *keyFramePtr = getKeyFrameData(animIdx, animPtr);
-	const int32 keyFrameLength = getKeyFrameLength(animIdx, animPtr);
+bool Animations::verifyAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, AnimTimerDataStruct *animTimerDataPtr) {
+	const uint8 *keyFramePtr = getKeyFrameData(keyframeIdx, animPtr);
+	const int32 keyFrameLength = getKeyFrameLength(keyframeIdx, animPtr);
 
 	const uint8 *lastKeyFramePtr = animTimerDataPtr->ptr;
 	int32 remainingFrameTime = animTimerDataPtr->time;
diff --git a/engines/twine/animations.h b/engines/twine/animations.h
index 616e54be33..38ee0c47e7 100644
--- a/engines/twine/animations.h
+++ b/engines/twine/animations.h
@@ -34,17 +34,17 @@ class TwinEEngine;
 class Animations {
 private:
 	TwinEEngine *_engine;
-	void applyAnimStepRotation(uint8 *ptr, int32 bp, int32 bx, const uint8 *keyFramePtr, const uint8 *lastKeyFramePtr);
+	void applyAnimStepRotation(uint8 *ptr, int32 deltaTime, int32 keyFrameLength, const uint8 *keyFramePtr, const uint8 *lastKeyFramePtr);
 	int32 getAnimMode(uint8 *ptr, const uint8 *keyFramePtr, const uint8 *lastKeyFramePtr);
-	void applyAnimStep(uint8 *ptr, int32 bp, int32 bx, const uint8 *keyFramePtr, const uint8 *lastKeyFramePtr);
+	void applyAnimStep(uint8 *ptr, int32 deltaTime, int32 keyFrameLength, const uint8 *keyFramePtr, const uint8 *lastKeyFramePtr);
 
 	/**
 	 * Verify animation at keyframe
-	 * @param animIdx Animation index
+	 * @param keyframeIdx Animation key frame index
 	 * @param animPtr Animation pointer
 	 * @param animTimerDataPtr Animation time data
 	 */
-	bool verifyAnimAtKeyframe(int32 animPos, const uint8 *animPtr, AnimTimerDataStruct *animTimerDataPtr);
+	bool verifyAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, AnimTimerDataStruct *animTimerDataPtr);
 
 	uint8 *const animBuffer;
 	uint8 *animBufferPos = nullptr;
@@ -97,12 +97,12 @@ public:
 
 	/**
 	 * Set new body animation
-	 * @param animIdx Animation index
+	 * @param keyframeIdx Animation key frame index
 	 * @param animPtr Animation pointer
 	 * @param bodyPtr Body model poitner
 	 * @param animTimerDataPtr Animation time data
 	 */
-	bool setModelAnimation(int32 animIdx, const uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr);
+	bool setModelAnimation(int32 keyframeIdx, const uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr);
 
 	/**
 	 * Get entity anim index (This is taken from File3D entities)


Commit: c811e4e099b5863ace769bb956f023a31c706d91
    https://github.com/scummvm/scummvm/commit/c811e4e099b5863ace769bb956f023a31c706d91
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: removed unused method parameter

Changed paths:
    engines/twine/animations.cpp
    engines/twine/animations.h


diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index faccbd9c1c..c18d15a486 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -128,7 +128,7 @@ void Animations::applyAnimStep(uint8 *ptr, int32 deltaTime, int32 keyFrameLength
 	*(int16 *)ptr = computedAngle;
 }
 
-int32 Animations::getAnimMode(uint8 *ptr, const uint8 *keyFramePtr, const uint8 *lastKeyFramePtr) {
+int32 Animations::getAnimMode(uint8 *ptr, const uint8 *keyFramePtr) {
 	const int16 opcode = READ_LE_INT16(keyFramePtr);
 	*(int16 *)ptr = opcode;
 	return opcode;
@@ -197,7 +197,7 @@ bool Animations::setModelAnimation(int32 keyframeIdx, const uint8 *animPtr, uint
 
 	int16 tmpNumOfPoints = numOfBonesInAnim - 1;
 	do {
-		const int16 animOpcode = getAnimMode(bonesPtr + 0, keyFramePtr + 0, lastKeyFramePtr + 0);
+		const int16 animOpcode = getAnimMode(bonesPtr + 0, keyFramePtr + 0);
 
 		switch (animOpcode) {
 		case 0: // allow global rotate
diff --git a/engines/twine/animations.h b/engines/twine/animations.h
index 38ee0c47e7..df6c2f75b6 100644
--- a/engines/twine/animations.h
+++ b/engines/twine/animations.h
@@ -35,7 +35,7 @@ class Animations {
 private:
 	TwinEEngine *_engine;
 	void applyAnimStepRotation(uint8 *ptr, int32 deltaTime, int32 keyFrameLength, const uint8 *keyFramePtr, const uint8 *lastKeyFramePtr);
-	int32 getAnimMode(uint8 *ptr, const uint8 *keyFramePtr, const uint8 *lastKeyFramePtr);
+	int32 getAnimMode(uint8 *ptr, const uint8 *keyFramePtr);
 	void applyAnimStep(uint8 *ptr, int32 deltaTime, int32 keyFrameLength, const uint8 *keyFramePtr, const uint8 *lastKeyFramePtr);
 
 	/**


Commit: 39b79a85f26427e85966e5c73f892b360470883b
    https://github.com/scummvm/scummvm/commit/39b79a85f26427e85966e5c73f892b360470883b
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: renamed method and stack vars

Changed paths:
    engines/twine/animations.cpp
    engines/twine/animations.h


diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index c18d15a486..46849209f2 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -112,20 +112,20 @@ void Animations::applyAnimStepRotation(uint8 *ptr, int32 deltaTime, int32 keyFra
 	*(int16 *)ptr = ClampAngle(computedAngle);
 }
 
-void Animations::applyAnimStep(uint8 *ptr, int32 deltaTime, int32 keyFrameLength, const uint8 *keyFramePtr, const uint8 *lastKeyFramePtr) {
-	int16 lastAngle = READ_LE_INT16(lastKeyFramePtr);
-	int16 newAngle = READ_LE_INT16(keyFramePtr);
+void Animations::applyAnimStepTranslation(uint8 *ptr, int32 deltaTime, int32 keyFrameLength, const uint8 *keyFramePtr, const uint8 *lastKeyFramePtr) {
+	int16 lastPos = READ_LE_INT16(lastKeyFramePtr);
+	int16 newPos = READ_LE_INT16(keyFramePtr);
 
-	int16 angleDif = newAngle - lastAngle;
+	int16 distance = newPos - lastPos;
 
-	int16 computedAngle;
-	if (angleDif) {
-		computedAngle = lastAngle + (angleDif * deltaTime) / keyFrameLength;
+	int16 computedPos;
+	if (distance) {
+		computedPos = lastPos + (distance * deltaTime) / keyFrameLength;
 	} else {
-		computedAngle = lastAngle;
+		computedPos = lastPos;
 	}
 
-	*(int16 *)ptr = computedAngle;
+	*(int16 *)ptr = computedPos;
 }
 
 int32 Animations::getAnimMode(uint8 *ptr, const uint8 *keyFramePtr) {
@@ -207,9 +207,9 @@ bool Animations::setModelAnimation(int32 keyframeIdx, const uint8 *animPtr, uint
 			break;
 		case 1: // disallow global rotate
 		case 2: // disallow global rotate + hide
-			applyAnimStep(bonesPtr + 2, deltaTime, keyFrameLength, keyFramePtr + 2, lastKeyFramePtr + 2);
-			applyAnimStep(bonesPtr + 4, deltaTime, keyFrameLength, keyFramePtr + 4, lastKeyFramePtr + 4);
-			applyAnimStep(bonesPtr + 6, deltaTime, keyFrameLength, keyFramePtr + 6, lastKeyFramePtr + 6);
+			applyAnimStepTranslation(bonesPtr + 2, deltaTime, keyFrameLength, keyFramePtr + 2, lastKeyFramePtr + 2);
+			applyAnimStepTranslation(bonesPtr + 4, deltaTime, keyFrameLength, keyFramePtr + 4, lastKeyFramePtr + 4);
+			applyAnimStepTranslation(bonesPtr + 6, deltaTime, keyFrameLength, keyFramePtr + 6, lastKeyFramePtr + 6);
 			break;
 		default:
 			error("Unsupported animation rotation mode %d", animOpcode);
diff --git a/engines/twine/animations.h b/engines/twine/animations.h
index df6c2f75b6..25f3127785 100644
--- a/engines/twine/animations.h
+++ b/engines/twine/animations.h
@@ -35,8 +35,8 @@ class Animations {
 private:
 	TwinEEngine *_engine;
 	void applyAnimStepRotation(uint8 *ptr, int32 deltaTime, int32 keyFrameLength, const uint8 *keyFramePtr, const uint8 *lastKeyFramePtr);
+	void applyAnimStepTranslation(uint8 *ptr, int32 deltaTime, int32 keyFrameLength, const uint8 *keyFramePtr, const uint8 *lastKeyFramePtr);
 	int32 getAnimMode(uint8 *ptr, const uint8 *keyFramePtr);
-	void applyAnimStep(uint8 *ptr, int32 deltaTime, int32 keyFrameLength, const uint8 *keyFramePtr, const uint8 *lastKeyFramePtr);
 
 	/**
 	 * Verify animation at keyframe


Commit: ecb56f62c53016975c2cc70aac05179497aa200e
    https://github.com/scummvm/scummvm/commit/ecb56f62c53016975c2cc70aac05179497aa200e
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: reduced code duplication

Changed paths:
    engines/twine/animations.cpp


diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index 46849209f2..cf55ba5979 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -704,13 +704,14 @@ void Animations::processActorAnimations(int32 actorIdx) { // DoAnim
 
 	// actor standing on another actor
 	if (actor->standOn != -1) {
-		_engine->_movements->processActorX -= _engine->_scene->getActor(actor->standOn)->collisionX;
-		_engine->_movements->processActorY -= _engine->_scene->getActor(actor->standOn)->collisionY;
-		_engine->_movements->processActorZ -= _engine->_scene->getActor(actor->standOn)->collisionZ;
-
-		_engine->_movements->processActorX += _engine->_scene->getActor(actor->standOn)->x;
-		_engine->_movements->processActorY += _engine->_scene->getActor(actor->standOn)->y;
-		_engine->_movements->processActorZ += _engine->_scene->getActor(actor->standOn)->z;
+		const ActorStruct* standOnActor = _engine->_scene->getActor(actor->standOn);
+		_engine->_movements->processActorX -= standOnActor->collisionX;
+		_engine->_movements->processActorY -= standOnActor->collisionY;
+		_engine->_movements->processActorZ -= standOnActor->collisionZ;
+
+		_engine->_movements->processActorX += standOnActor->x;
+		_engine->_movements->processActorY += standOnActor->y;
+		_engine->_movements->processActorZ += standOnActor->z;
 
 		if (!_engine->_collision->standingOnActor(actorIdx, actor->standOn)) {
 			actor->standOn = -1; // no longer standing on other actor


Commit: f0188580235286e0d4fe27f7643428b5bedf6bad
    https://github.com/scummvm/scummvm/commit/f0188580235286e0d4fe27f7643428b5bedf6bad
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: reduced code duplication

Changed paths:
    engines/twine/animations.cpp
    engines/twine/animations.h


diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index cf55ba5979..5b66e87f34 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -74,6 +74,27 @@ const uint8* Animations::getKeyFrameData(int32 frameIdx, const uint8 *animPtr) {
 	return (const uint8 *)((numOfBonesInAnim * 8 + 8) * frameIdx + animPtr + 8);
 }
 
+const uint8* Animations::getBonesData(const uint8 *bodyPtr) const {
+	const uint8 *verticesBase = bodyPtr + 0x1A;
+	const int16 numVertices = READ_LE_INT16(verticesBase);
+	const uint8 *bonesBase = verticesBase + 2 + numVertices * 6;
+	return bonesBase + 2 + 8;
+}
+
+uint8* Animations::getBonesData(uint8 *bodyPtr) const {
+	uint8 *verticesBase = bodyPtr + 0x1A;
+	const int16 numVertices = READ_LE_INT16(verticesBase);
+	uint8 *bonesBase = verticesBase + 2 + numVertices * 6;
+	return bonesBase + 2 + 8;
+}
+
+int16 Animations::getNumBones(const uint8 *bodyPtr) const {
+	const uint8 *verticesBase = bodyPtr + 0x1A;
+	const int16 numVertices = READ_LE_INT16(verticesBase);
+	const uint8 *bonesBase = verticesBase + 2 + numVertices * 6;
+	return READ_LE_INT16(bonesBase);
+}
+
 int16 Animations::getKeyFrameLength(int32 frameIdx, const uint8 *animPtr) {
 	return READ_LE_INT16(getKeyFrameData(frameIdx, animPtr));
 }
@@ -138,37 +159,31 @@ bool Animations::setModelAnimation(int32 keyframeIdx, const uint8 *animPtr, uint
 	if (!Model::isAnimated(bodyPtr)) {
 		return false;
 	}
-	int32 numOfBonesInAnim = getNumBoneframes(animPtr);
 	const uint8 *keyFramePtr = getKeyFrameData(keyframeIdx, animPtr);
-	const int32 keyFrameLength = getKeyFrameLength(keyframeIdx, animPtr);
 
-	const uint8 *lastKeyFramePtr = animTimerDataPtr->ptr;
-	int32 remainingFrameTime = animTimerDataPtr->time;
+	currentStepX = READ_LE_INT16(keyFramePtr + 2);
+	currentStepY = READ_LE_INT16(keyFramePtr + 4);
+	currentStepZ = READ_LE_INT16(keyFramePtr + 6);
 
-	if (lastKeyFramePtr == nullptr) {
-		lastKeyFramePtr = keyFramePtr;
-		remainingFrameTime = keyFrameLength;
-	}
+	processRotationByAnim = READ_LE_INT16(keyFramePtr + 8);
+	processLastRotationAngle = ToAngle(READ_LE_INT16(keyFramePtr + 12));
 
-	uint8 *verticesBase = bodyPtr + 0x1A;
-	const int16 numVertices = READ_LE_INT16(verticesBase);
-	uint8 *bonesBase = verticesBase + 2 + numVertices * 6;
-	const int32 numBones = READ_LE_INT16(bonesBase);
+	const int16 numBones = getNumBones(bodyPtr);
+	uint8 *bonesPtr = getBonesData(bodyPtr);
 
+	int32 numOfBonesInAnim = getNumBoneframes(animPtr);
 	if (numOfBonesInAnim > numBones) {
 		numOfBonesInAnim = numBones;
 	}
+	const int32 keyFrameLength = getKeyFrameLength(keyframeIdx, animPtr);
 
+	const uint8 *lastKeyFramePtr = animTimerDataPtr->ptr;
+	int32 remainingFrameTime = animTimerDataPtr->time;
+	if (lastKeyFramePtr == nullptr) {
+		lastKeyFramePtr = keyFramePtr;
+		remainingFrameTime = keyFrameLength;
+	}
 	const int32 deltaTime = _engine->lbaTime - remainingFrameTime;
-
-	currentStepX = READ_LE_INT16(keyFramePtr + 2);
-	currentStepY = READ_LE_INT16(keyFramePtr + 4);
-	currentStepZ = READ_LE_INT16(keyFramePtr + 6);
-
-	processRotationByAnim = READ_LE_INT16(keyFramePtr + 8);
-	processLastRotationAngle = ToAngle(READ_LE_INT16(keyFramePtr + 12));
-
-	uint8 *bonesPtr = bonesBase + 2 + 8;
 	if (deltaTime >= keyFrameLength) {
 		const uint8 *ptrToData = keyFramePtr + 8;
 		for (int32 i = 0; i < numOfBonesInAnim; ++i) {
@@ -233,29 +248,24 @@ void Animations::setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uint
 		return;
 	}
 
-	int16 numOfBonesInAnim = getNumBoneframes(animPtr);
 	const uint8 *ptrToData = getKeyFrameData(keyframeIdx, animPtr);
+	currentStepX = READ_LE_INT16(ptrToData + 2);
+	currentStepY = READ_LE_INT16(ptrToData + 4);
+	currentStepZ = READ_LE_INT16(ptrToData + 6);
+
+	processRotationByAnim = READ_LE_INT16(ptrToData + 8);
+	processLastRotationAngle = ToAngle(READ_LE_INT16(ptrToData + 12));
 
 	animTimerDataPtr->ptr = ptrToData;
 	animTimerDataPtr->time = _engine->lbaTime;
 
-	uint8 *verticesBase = bodyPtr + 0x1A;
-	int32 numVertices = READ_LE_INT16(verticesBase);
-	uint8 *bonesBase = verticesBase + 2 + numVertices * 6;
-	const int16 numBones = READ_LE_INT16(bonesBase);
-	uint8 *bonesPtr = bonesBase + 2 + 8;
+	const int16 numBones = getNumBones(bodyPtr);
+	uint8 *bonesPtr = getBonesData(bodyPtr);
 
+	int16 numOfBonesInAnim = getNumBoneframes(animPtr);
 	if (numOfBonesInAnim > numBones) {
 		numOfBonesInAnim = numBones;
 	}
-
-	currentStepX = READ_LE_INT16(ptrToData + 2);
-	currentStepY = READ_LE_INT16(ptrToData + 4);
-	currentStepZ = READ_LE_INT16(ptrToData + 6);
-
-	processRotationByAnim = READ_LE_INT16(ptrToData + 8);
-	processLastRotationAngle = ToAngle(READ_LE_INT16(ptrToData + 12));
-
 	ptrToData += 8;
 
 	for (int32 i = 0; i < numOfBonesInAnim; ++i) {
@@ -278,13 +288,10 @@ void Animations::stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *animT
 	animTimerDataPtr->time = _engine->lbaTime;
 	animTimerDataPtr->ptr = animBufferPos;
 
-	const uint8 *verticesBase = bodyPtr + 0x1A;
-	int32 numVertices = READ_LE_INT16(verticesBase);
-	const uint8 *bonesBase = verticesBase + 2 + numVertices * 6;
-	int32 numBones = READ_LE_INT16(bonesBase);
+	const int32 numBones = getNumBones(bodyPtr);
+	const uint8 *ptrToData = getBonesData(bodyPtr);
 
 	uint8 *bonesPtr = animBufferPos + 8;
-	const uint8 *ptrToData = bonesBase + 10;
 
 	for (int32 i = 0; i < numBones; ++i) {
 		// these are 4 int16 values
diff --git a/engines/twine/animations.h b/engines/twine/animations.h
index 25f3127785..941a5ee2fd 100644
--- a/engines/twine/animations.h
+++ b/engines/twine/animations.h
@@ -38,6 +38,10 @@ private:
 	void applyAnimStepTranslation(uint8 *ptr, int32 deltaTime, int32 keyFrameLength, const uint8 *keyFramePtr, const uint8 *lastKeyFramePtr);
 	int32 getAnimMode(uint8 *ptr, const uint8 *keyFramePtr);
 
+	const uint8* getBonesData(const uint8 *bodyPtr) const;
+	uint8* getBonesData(uint8 *bodyPtr) const;
+	int16 getNumBones(const uint8 *bodyPtr) const;
+
 	/**
 	 * Verify animation at keyframe
 	 * @param keyframeIdx Animation key frame index


Commit: 0ff83ff30011f686a090dafeb38117e4661f529b
    https://github.com/scummvm/scummvm/commit/0ff83ff30011f686a090dafeb38117e4661f529b
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: started to use AnimData in setModelAnimation

Changed paths:
    engines/twine/animations.cpp


diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index 5b66e87f34..90e77ea2c8 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -29,6 +29,7 @@
 #include "common/util.h"
 #include "twine/actor.h"
 #include "twine/collision.h"
+#include "twine/parser/anim.h"
 #include "twine/parser/entity.h"
 #include "twine/gamestate.h"
 #include "twine/grid.h"
@@ -159,24 +160,27 @@ bool Animations::setModelAnimation(int32 keyframeIdx, const uint8 *animPtr, uint
 	if (!Model::isAnimated(bodyPtr)) {
 		return false;
 	}
-	const uint8 *keyFramePtr = getKeyFrameData(keyframeIdx, animPtr);
+	AnimData animData;
+	animData.loadFromBuffer(animPtr, 100000);
+	const KeyFrame* keyFrame = animData.getKeyframe(keyframeIdx);
 
-	currentStepX = READ_LE_INT16(keyFramePtr + 2);
-	currentStepY = READ_LE_INT16(keyFramePtr + 4);
-	currentStepZ = READ_LE_INT16(keyFramePtr + 6);
+	currentStepX = keyFrame->x;
+	currentStepY = keyFrame->y;
+	currentStepZ = keyFrame->z;
 
-	processRotationByAnim = READ_LE_INT16(keyFramePtr + 8);
-	processLastRotationAngle = ToAngle(READ_LE_INT16(keyFramePtr + 12));
+	processRotationByAnim = keyFrame->boneframes[0].type;
+	processLastRotationAngle = ToAngle(keyFrame->boneframes[0].y);
 
 	const int16 numBones = getNumBones(bodyPtr);
 	uint8 *bonesPtr = getBonesData(bodyPtr);
 
-	int32 numOfBonesInAnim = getNumBoneframes(animPtr);
+	int32 numOfBonesInAnim = animData.getNumBoneframes();
 	if (numOfBonesInAnim > numBones) {
 		numOfBonesInAnim = numBones;
 	}
-	const int32 keyFrameLength = getKeyFrameLength(keyframeIdx, animPtr);
+	const int32 keyFrameLength = keyFrame->length;
 
+	const uint8 *keyFramePtr = getKeyFrameData(keyframeIdx, animPtr);
 	const uint8 *lastKeyFramePtr = animTimerDataPtr->ptr;
 	int32 remainingFrameTime = animTimerDataPtr->time;
 	if (lastKeyFramePtr == nullptr) {


Commit: 802f66086af75b65e82edf8f0b839db8018bb67f
    https://github.com/scummvm/scummvm/commit/802f66086af75b65e82edf8f0b839db8018bb67f
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: use BoneFrame struct to copy the bone state

Changed paths:
    engines/twine/animations.cpp


diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index 90e77ea2c8..9358307040 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -189,13 +189,13 @@ bool Animations::setModelAnimation(int32 keyframeIdx, const uint8 *animPtr, uint
 	}
 	const int32 deltaTime = _engine->lbaTime - remainingFrameTime;
 	if (deltaTime >= keyFrameLength) {
-		const uint8 *ptrToData = keyFramePtr + 8;
 		for (int32 i = 0; i < numOfBonesInAnim; ++i) {
-			// these are 4 int16 values
-			for (int32 j = 0; j < 8; j++) {
-				*bonesPtr++ = *ptrToData++;
-			}
-			bonesPtr += 30;
+			const BoneFrame &boneframe = keyFrame->boneframes[i];
+			WRITE_LE_UINT16(bonesPtr + 0, boneframe.type);
+			WRITE_LE_INT16(bonesPtr + 2, boneframe.x);
+			WRITE_LE_INT16(bonesPtr + 4, boneframe.y);
+			WRITE_LE_INT16(bonesPtr + 6, boneframe.z);
+			bonesPtr += 38;
 		}
 
 		animTimerDataPtr->ptr = keyFramePtr;
@@ -252,33 +252,35 @@ void Animations::setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uint
 		return;
 	}
 
-	const uint8 *ptrToData = getKeyFrameData(keyframeIdx, animPtr);
-	currentStepX = READ_LE_INT16(ptrToData + 2);
-	currentStepY = READ_LE_INT16(ptrToData + 4);
-	currentStepZ = READ_LE_INT16(ptrToData + 6);
+	AnimData animData;
+	animData.loadFromBuffer(animPtr, 100000);
+	const KeyFrame* keyFrame = animData.getKeyframe(keyframeIdx);
+
+	currentStepX = keyFrame->x;
+	currentStepY = keyFrame->y;
+	currentStepZ = keyFrame->z;
 
-	processRotationByAnim = READ_LE_INT16(ptrToData + 8);
-	processLastRotationAngle = ToAngle(READ_LE_INT16(ptrToData + 12));
+	processRotationByAnim = keyFrame->boneframes[0].type;
+	processLastRotationAngle = ToAngle(keyFrame->boneframes[0].y);
 
-	animTimerDataPtr->ptr = ptrToData;
+	animTimerDataPtr->ptr = getKeyFrameData(keyframeIdx, animPtr);
 	animTimerDataPtr->time = _engine->lbaTime;
 
 	const int16 numBones = getNumBones(bodyPtr);
 	uint8 *bonesPtr = getBonesData(bodyPtr);
 
-	int16 numOfBonesInAnim = getNumBoneframes(animPtr);
+	int16 numOfBonesInAnim = animData.getNumBoneframes();
 	if (numOfBonesInAnim > numBones) {
 		numOfBonesInAnim = numBones;
 	}
-	ptrToData += 8;
 
 	for (int32 i = 0; i < numOfBonesInAnim; ++i) {
-		// these are 4 int16 values
-		for (int32 j = 0; j < 8; j++) {
-			*bonesPtr++ = *ptrToData++;
-		}
-
-		bonesPtr += 30;
+		const BoneFrame &boneframe = keyFrame->boneframes[i];
+		WRITE_LE_UINT16(bonesPtr + 0, boneframe.type);
+		WRITE_LE_INT16(bonesPtr + 2, boneframe.x);
+		WRITE_LE_INT16(bonesPtr + 4, boneframe.y);
+		WRITE_LE_INT16(bonesPtr + 6, boneframe.z);
+		bonesPtr += 38;
 	}
 
 	return;


Commit: 4301e49da22a99163254ca74c0652d3bae5bb65b
    https://github.com/scummvm/scummvm/commit/4301e49da22a99163254ca74c0652d3bae5bb65b
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: started to remove raw byte buffer helper methods

Changed paths:
    engines/twine/animations.cpp
    engines/twine/animations.h


diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index 9358307040..d017f67a94 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -71,7 +71,7 @@ int32 Animations::getBodyAnimIndex(AnimationTypes animIdx, int32 actorIdx) {
 }
 
 const uint8* Animations::getKeyFrameData(int32 frameIdx, const uint8 *animPtr) {
-	const int16 numOfBonesInAnim = getNumBoneframes(animPtr);
+	const int16 numOfBonesInAnim = READ_LE_INT16(animPtr + 2);
 	return (const uint8 *)((numOfBonesInAnim * 8 + 8) * frameIdx + animPtr + 8);
 }
 
@@ -96,14 +96,6 @@ int16 Animations::getNumBones(const uint8 *bodyPtr) const {
 	return READ_LE_INT16(bonesBase);
 }
 
-int16 Animations::getKeyFrameLength(int32 frameIdx, const uint8 *animPtr) {
-	return READ_LE_INT16(getKeyFrameData(frameIdx, animPtr));
-}
-
-int16 Animations::getNumBoneframes(const uint8 *animPtr) {
-	return READ_LE_INT16(animPtr + 2);
-}
-
 int16 Animations::getNumKeyframes(const uint8 *animPtr) {
 	return READ_LE_INT16(animPtr + 0);
 }
@@ -243,17 +235,17 @@ bool Animations::setModelAnimation(int32 keyframeIdx, const uint8 *animPtr, uint
 }
 
 void Animations::setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr) {
-	const int16 numOfKeyframeInAnim = getNumKeyframes(animPtr);
-	if (keyframeIdx < 0 || keyframeIdx >= numOfKeyframeInAnim) {
-		return;
-	}
-
 	if (!Model::isAnimated(bodyPtr)) {
 		return;
 	}
 
 	AnimData animData;
 	animData.loadFromBuffer(animPtr, 100000);
+	const int32 numOfKeyframeInAnim = animData.getKeyframes().size();
+	if (keyframeIdx < 0 || keyframeIdx >= numOfKeyframeInAnim) {
+		return;
+	}
+
 	const KeyFrame* keyFrame = animData.getKeyframe(keyframeIdx);
 
 	currentStepX = keyFrame->x;
@@ -316,28 +308,28 @@ void Animations::stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *animT
 }
 
 bool Animations::verifyAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, AnimTimerDataStruct *animTimerDataPtr) {
-	const uint8 *keyFramePtr = getKeyFrameData(keyframeIdx, animPtr);
-	const int32 keyFrameLength = getKeyFrameLength(keyframeIdx, animPtr);
+	AnimData animData;
+	animData.loadFromBuffer(animPtr, 100000);
+	const KeyFrame* keyFrame = animData.getKeyframe(keyframeIdx);
+	const int32 keyFrameLength = keyFrame->length;
 
-	const uint8 *lastKeyFramePtr = animTimerDataPtr->ptr;
 	int32 remainingFrameTime = animTimerDataPtr->time;
-
-	if (lastKeyFramePtr == nullptr) {
-		lastKeyFramePtr = keyFramePtr;
+	if (animTimerDataPtr->ptr == nullptr) {
 		remainingFrameTime = keyFrameLength;
 	}
 
 	const int32 deltaTime = _engine->lbaTime - remainingFrameTime;
 
-	currentStepX = READ_LE_INT16(keyFramePtr + 2);
-	currentStepY = READ_LE_INT16(keyFramePtr + 4);
-	currentStepZ = READ_LE_INT16(keyFramePtr + 6);
+	currentStepX = keyFrame->x;
+	currentStepY = keyFrame->y;
+	currentStepZ = keyFrame->z;
 
-	processRotationByAnim = READ_LE_INT16(keyFramePtr + 8);
-	processLastRotationAngle = ToAngle(READ_LE_INT16(keyFramePtr + 12));
+	const BoneFrame& boneFrame = keyFrame->boneframes[0];
+	processRotationByAnim = boneFrame.type;
+	processLastRotationAngle = ToAngle(boneFrame.y);
 
 	if (deltaTime >= keyFrameLength) {
-		animTimerDataPtr->ptr = keyFramePtr;
+		animTimerDataPtr->ptr = getKeyFrameData(keyframeIdx, animPtr);;
 		animTimerDataPtr->time = _engine->lbaTime;
 		return true;
 	}
diff --git a/engines/twine/animations.h b/engines/twine/animations.h
index 941a5ee2fd..7b666780be 100644
--- a/engines/twine/animations.h
+++ b/engines/twine/animations.h
@@ -83,9 +83,7 @@ public:
 	 */
 	void setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr);
 
-	int16 getNumBoneframes(const uint8 *animPtr);
 	const uint8* getKeyFrameData(int32 frameIdx, const uint8 *animPtr);
-	int16 getKeyFrameLength(int32 frameIdx, const uint8 *animPtr);
 
 	/**
 	 * Get total number of keyframes in animation


Commit: e88280ac6234f58b390f25a0421373b45d218aad
    https://github.com/scummvm/scummvm/commit/e88280ac6234f58b390f25a0421373b45d218aad
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: moved methods for reading body data

Changed paths:
    engines/twine/animations.cpp
    engines/twine/animations.h
    engines/twine/renderer.h


diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index d017f67a94..4cce032338 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -75,27 +75,6 @@ const uint8* Animations::getKeyFrameData(int32 frameIdx, const uint8 *animPtr) {
 	return (const uint8 *)((numOfBonesInAnim * 8 + 8) * frameIdx + animPtr + 8);
 }
 
-const uint8* Animations::getBonesData(const uint8 *bodyPtr) const {
-	const uint8 *verticesBase = bodyPtr + 0x1A;
-	const int16 numVertices = READ_LE_INT16(verticesBase);
-	const uint8 *bonesBase = verticesBase + 2 + numVertices * 6;
-	return bonesBase + 2 + 8;
-}
-
-uint8* Animations::getBonesData(uint8 *bodyPtr) const {
-	uint8 *verticesBase = bodyPtr + 0x1A;
-	const int16 numVertices = READ_LE_INT16(verticesBase);
-	uint8 *bonesBase = verticesBase + 2 + numVertices * 6;
-	return bonesBase + 2 + 8;
-}
-
-int16 Animations::getNumBones(const uint8 *bodyPtr) const {
-	const uint8 *verticesBase = bodyPtr + 0x1A;
-	const int16 numVertices = READ_LE_INT16(verticesBase);
-	const uint8 *bonesBase = verticesBase + 2 + numVertices * 6;
-	return READ_LE_INT16(bonesBase);
-}
-
 int16 Animations::getNumKeyframes(const uint8 *animPtr) {
 	return READ_LE_INT16(animPtr + 0);
 }
@@ -163,8 +142,8 @@ bool Animations::setModelAnimation(int32 keyframeIdx, const uint8 *animPtr, uint
 	processRotationByAnim = keyFrame->boneframes[0].type;
 	processLastRotationAngle = ToAngle(keyFrame->boneframes[0].y);
 
-	const int16 numBones = getNumBones(bodyPtr);
-	uint8 *bonesPtr = getBonesData(bodyPtr);
+	const int16 numBones = Model::getNumBones(bodyPtr);
+	uint8 *bonesPtr = Model::getBonesData(bodyPtr);
 
 	int32 numOfBonesInAnim = animData.getNumBoneframes();
 	if (numOfBonesInAnim > numBones) {
@@ -258,8 +237,8 @@ void Animations::setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uint
 	animTimerDataPtr->ptr = getKeyFrameData(keyframeIdx, animPtr);
 	animTimerDataPtr->time = _engine->lbaTime;
 
-	const int16 numBones = getNumBones(bodyPtr);
-	uint8 *bonesPtr = getBonesData(bodyPtr);
+	const int16 numBones = Model::getNumBones(bodyPtr);
+	uint8 *bonesPtr = Model::getBonesData(bodyPtr);
 
 	int16 numOfBonesInAnim = animData.getNumBoneframes();
 	if (numOfBonesInAnim > numBones) {
@@ -286,8 +265,8 @@ void Animations::stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *animT
 	animTimerDataPtr->time = _engine->lbaTime;
 	animTimerDataPtr->ptr = animBufferPos;
 
-	const int32 numBones = getNumBones(bodyPtr);
-	const uint8 *ptrToData = getBonesData(bodyPtr);
+	const int32 numBones = Model::getNumBones(bodyPtr);
+	const uint8 *ptrToData = Model::getBonesData(bodyPtr);
 
 	uint8 *bonesPtr = animBufferPos + 8;
 
diff --git a/engines/twine/animations.h b/engines/twine/animations.h
index 7b666780be..9e4203dbff 100644
--- a/engines/twine/animations.h
+++ b/engines/twine/animations.h
@@ -38,10 +38,6 @@ private:
 	void applyAnimStepTranslation(uint8 *ptr, int32 deltaTime, int32 keyFrameLength, const uint8 *keyFramePtr, const uint8 *lastKeyFramePtr);
 	int32 getAnimMode(uint8 *ptr, const uint8 *keyFramePtr);
 
-	const uint8* getBonesData(const uint8 *bodyPtr) const;
-	uint8* getBonesData(uint8 *bodyPtr) const;
-	int16 getNumBones(const uint8 *bodyPtr) const;
-
 	/**
 	 * Verify animation at keyframe
 	 * @param keyframeIdx Animation key frame index
diff --git a/engines/twine/renderer.h b/engines/twine/renderer.h
index 998420f040..50d3c18531 100644
--- a/engines/twine/renderer.h
+++ b/engines/twine/renderer.h
@@ -95,6 +95,27 @@ struct Model {
 		const int16 bodyHeader = READ_LE_INT16(bodyPtr);
 		return (bodyHeader & 2) != 0;
 	}
+
+	static const uint8* getBonesData(const uint8 *bodyPtr) {
+		const uint8 *verticesBase = bodyPtr + 0x1A;
+		const int16 numVertices = READ_LE_INT16(verticesBase);
+		const uint8 *bonesBase = verticesBase + 2 + numVertices * 6;
+		return bonesBase + 2 + 8;
+	}
+
+	static uint8* getBonesData(uint8 *bodyPtr) {
+		uint8 *verticesBase = bodyPtr + 0x1A;
+		const int16 numVertices = READ_LE_INT16(verticesBase);
+		uint8 *bonesBase = verticesBase + 2 + numVertices * 6;
+		return bonesBase + 2 + 8;
+	}
+
+	static int16 getNumBones(const uint8 *bodyPtr) {
+		const uint8 *verticesBase = bodyPtr + 0x1A;
+		const int16 numVertices = READ_LE_INT16(verticesBase);
+		const uint8 *bonesBase = verticesBase + 2 + numVertices * 6;
+		return READ_LE_INT16(bonesBase);
+	}
 };
 
 #include "common/pack-start.h"


Commit: 48f356d25b2f38a83b73bbb372f8a33af6917a1b
    https://github.com/scummvm/scummvm/commit/48f356d25b2f38a83b73bbb372f8a33af6917a1b
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: minor cleanup

Changed paths:
    engines/twine/renderer.cpp
    engines/twine/renderer.h
    engines/twine/shadeangletab.h


diff --git a/engines/twine/renderer.cpp b/engines/twine/renderer.cpp
index a741803006..7417f6f4bb 100644
--- a/engines/twine/renderer.cpp
+++ b/engines/twine/renderer.cpp
@@ -1255,6 +1255,9 @@ int32 Renderer::renderModelElements(int32 numOfPrimitives, uint8 *ptr, RenderCom
 }
 
 int32 Renderer::renderAnimatedModel(ModelData *modelData, uint8 *bodyPtr, RenderCommand *renderCmds) {
+	// jump after the header
+	bodyPtr += 0x1A;
+
 	const int32 numOfPoints = *((const uint16 *)bodyPtr);
 	bodyPtr += 2;
 	const pointTab *pointsPtr = (const pointTab *)bodyPtr;
@@ -1465,7 +1468,7 @@ void Renderer::prepareIsoModel(uint8 *bodyPtr) { // loadGfxSub
 	bodyHeader->bodyFlag.alreadyPrepared = 1;
 
 	// no animation applicable
-	if (!bodyHeader->bodyFlag.animated) {
+	if (!Model::isAnimated(bodyPtr)) {
 		return;
 	}
 
@@ -1509,13 +1512,9 @@ int32 Renderer::renderIsoModel(int32 x, int32 y, int32 z, int32 angleX, int32 an
 		renderZ = destZ - baseRotPosZ;
 	}
 
-	Model *bodyHeader = (Model *)bodyPtr;
-	if (bodyHeader->bodyFlag.animated) {
-		// jump after the header
-		uint8 *ptr = bodyPtr + 0x1A;
-		// the mostly used renderer code
+	if (Model::isAnimated(bodyPtr)) {
 		// restart at the beginning of the renderTable
-		return renderAnimatedModel(&_modelData, ptr, _renderCmds);
+		return renderAnimatedModel(&_modelData, bodyPtr, _renderCmds);
 	}
 	error("Unsupported unanimated model render!");
 	return 0;
@@ -1525,7 +1524,7 @@ void Renderer::renderBehaviourModel(const Common::Rect &rect, int32 y, int32 ang
 	renderBehaviourModel(rect.left, rect.top, rect.right, rect.bottom, y, angle, entityPtr);
 }
 
-void Renderer::renderBehaviourModel(int32 boxLeft, int32 boxTop, int32 boxRight, int32 boxBottom, int32 y, int32 angle, uint8 *entityPtr) {
+void Renderer::renderBehaviourModel(int32 boxLeft, int32 boxTop, int32 boxRight, int32 boxBottom, int32 y, int32 angle, uint8 *bodyPtr) {
 	int32 tmpBoxRight = boxRight;
 
 	int32 ypos = boxBottom + boxTop;
@@ -1543,9 +1542,9 @@ void Renderer::renderBehaviourModel(int32 boxLeft, int32 boxTop, int32 boxRight,
 		if (move.numOfStep == 0) {
 			_engine->_movements->setActorAngleSafe(newAngle, newAngle - ANGLE_90, 50, &move);
 		}
-		renderIsoModel(0, y, 0, 0, newAngle, 0, entityPtr);
+		renderIsoModel(0, y, 0, 0, newAngle, 0, bodyPtr);
 	} else {
-		renderIsoModel(0, y, 0, 0, angle, 0, entityPtr);
+		renderIsoModel(0, y, 0, 0, angle, 0, bodyPtr);
 	}
 }
 
diff --git a/engines/twine/renderer.h b/engines/twine/renderer.h
index 50d3c18531..721baa6122 100644
--- a/engines/twine/renderer.h
+++ b/engines/twine/renderer.h
@@ -305,7 +305,7 @@ public:
 
 	int32 renderIsoModel(int32 x, int32 y, int32 z, int32 angleX, int32 angleY, int32 angleZ, uint8 *bodyPtr);
 
-	void renderBehaviourModel(int32 boxLeft, int32 boxTop, int32 boxRight, int32 boxBottom, int32 y, int32 angle, uint8 *entityPtr);
+	void renderBehaviourModel(int32 boxLeft, int32 boxTop, int32 boxRight, int32 boxBottom, int32 y, int32 angle, uint8 *bodyPtr);
 	void renderBehaviourModel(const Common::Rect &rect, int32 y, int32 angle, uint8 *entityPtr);
 
 	void renderInventoryItem(int32 x, int32 y, uint8 *itemBodyPtr, int32 angle, int32 param);
diff --git a/engines/twine/shadeangletab.h b/engines/twine/shadeangletab.h
index bb7f51c489..02a2d1b4db 100644
--- a/engines/twine/shadeangletab.h
+++ b/engines/twine/shadeangletab.h
@@ -24,10 +24,11 @@
 #define TWINE_SHADEANGLETAB_H
 
 #include "common/scummsys.h"
+#include "twine/shared.h"
 
 namespace TwinE {
 
-const int16 shadeAngleTable[1024] = {
+const int16 shadeAngleTable[ANGLE_360] = {
     0, // tab1
     101,
     201,


Commit: 05cccc0f83ed57430cc34826dba185f4e4f692cb
    https://github.com/scummvm/scummvm/commit/05cccc0f83ed57430cc34826dba185f4e4f692cb
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: ensure that shadeAngleTab3 is always a valid pointer

Changed paths:
    engines/twine/renderer.cpp
    engines/twine/renderer.h


diff --git a/engines/twine/renderer.cpp b/engines/twine/renderer.cpp
index 7417f6f4bb..24ad9c1266 100644
--- a/engines/twine/renderer.cpp
+++ b/engines/twine/renderer.cpp
@@ -39,6 +39,9 @@ namespace TwinE {
 #define RENDERTYPE_DRAWPOLYGON 1
 #define RENDERTYPE_DRAWSPHERE 2
 
+Renderer::Renderer(TwinEEngine *engine) : _engine(engine), shadeAngleTab3(&shadeAngleTable[384]) {
+}
+
 int32 Renderer::projectPositionOnScreen(int32 cX, int32 cY, int32 cZ) {
 	if (!isUsingOrhoProjection) {
 		cX -= baseRotPosX;
@@ -101,8 +104,6 @@ void Renderer::getBaseRotationPosition(int32 x, int32 y, int32 z) {
 }
 
 void Renderer::setBaseRotation(int32 x, int32 y, int32 z) {
-	shadeAngleTab3 = &shadeAngleTable[384];
-
 	double Xradians = (double)((ANGLE_90 - x) % ANGLE_360) * 2 * M_PI / ANGLE_360;
 	double Yradians = (double)((ANGLE_90 - y) % ANGLE_360) * 2 * M_PI / ANGLE_360;
 	double Zradians = (double)((ANGLE_90 - z) % ANGLE_360) * 2 * M_PI / ANGLE_360;
diff --git a/engines/twine/renderer.h b/engines/twine/renderer.h
index 721baa6122..6db0c505f4 100644
--- a/engines/twine/renderer.h
+++ b/engines/twine/renderer.h
@@ -270,7 +270,7 @@ private:
 	uint8* prepareLines(Common::MemoryReadStream &stream, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData);
 
 public:
-	Renderer(TwinEEngine *engine) : _engine(engine) {}
+	Renderer(TwinEEngine *engine);
 
 	int16 projPosXScreen = 0; // fullRedrawVar1
 	int16 projPosYScreen = 0; // fullRedrawVar2
@@ -287,7 +287,7 @@ public:
 	int32 destY = 0;
 	int32 destZ = 0;
 
-	const int16 *shadeAngleTab3 = nullptr; // tab3
+	const int16 * const shadeAngleTab3;
 
 	int16 vertexCoordinates[193] {0};
 


Commit: 47fa979332e11d627736c776b1477769a1f439a5
    https://github.com/scummvm/scummvm/commit/47fa979332e11d627736c776b1477769a1f439a5
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: removed unused code

Changed paths:
    engines/twine/renderer.cpp


diff --git a/engines/twine/renderer.cpp b/engines/twine/renderer.cpp
index 24ad9c1266..4e7ef22161 100644
--- a/engines/twine/renderer.cpp
+++ b/engines/twine/renderer.cpp
@@ -51,8 +51,9 @@ int32 Renderer::projectPositionOnScreen(int32 cX, int32 cY, int32 cZ) {
 		if (cZ >= 0) {
 			int32 posZ = cZ + cameraPosX;
 
-			if (posZ < 0)
+			if (posZ < 0) {
 				posZ = 0x7FFF;
+			}
 
 			projPosX = (cX * cameraPosY) / posZ + orthoProjX;
 			projPosY = (-cY * cameraPosZ) / posZ + orthoProjY;
@@ -321,9 +322,9 @@ void Renderer::processTranslatedElement(Matrix *targetMatrix, const pointTab *po
 }
 
 void Renderer::translateGroup(int16 ax, int16 bx, int16 cx) {
-	int32 ebp = ax;
-	int32 ebx = bx;
-	int32 ecx = cx;
+	const int32 ebp = ax;
+	const int32 ebx = bx;
+	const int32 ecx = cx;
 
 	int32 edi = shadeMatrix.row1[0];
 	int32 eax = shadeMatrix.row1[1];
@@ -347,13 +348,6 @@ void Renderer::translateGroup(int16 ax, int16 bx, int16 cx) {
 	eax += edi;
 	eax >>= 14;
 	destY = eax;
-
-	ebp *= shadeMatrix.row3[0];
-	ebx *= shadeMatrix.row3[1];
-	ecx *= shadeMatrix.row3[2];
-	ebx += ebp;
-	ebx += ecx;
-	ebx >>= 14;
 	destZ = eax;
 }
 


Commit: 4e8f7b72d32d6eacc94240a717dd121bc0145c9f
    https://github.com/scummvm/scummvm/commit/4e8f7b72d32d6eacc94240a717dd121bc0145c9f
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: reduced cyclic complexity

Changed paths:
    engines/twine/renderer.cpp


diff --git a/engines/twine/renderer.cpp b/engines/twine/renderer.cpp
index 4e7ef22161..b1ae6ff238 100644
--- a/engines/twine/renderer.cpp
+++ b/engines/twine/renderer.cpp
@@ -43,34 +43,33 @@ Renderer::Renderer(TwinEEngine *engine) : _engine(engine), shadeAngleTab3(&shade
 }
 
 int32 Renderer::projectPositionOnScreen(int32 cX, int32 cY, int32 cZ) {
-	if (!isUsingOrhoProjection) {
-		cX -= baseRotPosX;
-		cY -= baseRotPosY;
-		cZ -= baseRotPosZ;
-
-		if (cZ >= 0) {
-			int32 posZ = cZ + cameraPosX;
-
-			if (posZ < 0) {
-				posZ = 0x7FFF;
-			}
+	if (isUsingOrhoProjection) {
+		projPosX = ((cX - cZ) * 24) / 512 + orthoProjX;
+		projPosY = (((cX + cZ) * 12) - cY * 30) / 512 + orthoProjY;
+		projPosZ = cZ - cY - cX;
+		return 1;
+	}
 
-			projPosX = (cX * cameraPosY) / posZ + orthoProjX;
-			projPosY = (-cY * cameraPosZ) / posZ + orthoProjY;
-			projPosZ = posZ;
-			return -1;
-		}
+	cX -= baseRotPosX;
+	cY -= baseRotPosY;
+	cZ -= baseRotPosZ;
 
+	if (cZ < 0) {
 		projPosX = 0;
 		projPosY = 0;
 		projPosZ = 0;
 		return 0;
 	}
-	projPosX = ((cX - cZ) * 24) / 512 + orthoProjX;
-	projPosY = (((cX + cZ) * 12) - cY * 30) / 512 + orthoProjY;
-	projPosZ = cZ - cY - cX;
 
-	return 1;
+	int32 posZ = cZ + cameraPosX;
+	if (posZ < 0) {
+		posZ = 0x7FFF;
+	}
+
+	projPosX = (cX * cameraPosY) / posZ + orthoProjX;
+	projPosY = (-cY * cameraPosZ) / posZ + orthoProjY;
+	projPosZ = posZ;
+	return -1;
 }
 
 void Renderer::setCameraPosition(int32 x, int32 y, int32 cX, int32 cY, int32 cZ) {


Commit: ae555d7aea458e92ef83be1c31de46fff0e02c91
    https://github.com/scummvm/scummvm/commit/ae555d7aea458e92ef83be1c31de46fff0e02c91
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: reduced cyclic complexity

Changed paths:
    engines/twine/redraw.cpp


diff --git a/engines/twine/redraw.cpp b/engines/twine/redraw.cpp
index f6dd1cfeb0..1713151e2d 100644
--- a/engines/twine/redraw.cpp
+++ b/engines/twine/redraw.cpp
@@ -236,7 +236,7 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 
 	int32 modelActorPos = 0;
 	int32 drawListPos = 0;
-	int32 spriteActorPos = 0x1000;
+	const int32 spriteActorPos = 0x1000;
 	int32 shadowActorPos = 0x0C00;
 
 	// Process actors drawing list
@@ -244,67 +244,69 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 		ActorStruct *actor = _engine->_scene->getActor(modelActorPos);
 		actor->dynamicFlags.bIsVisible = 0; // reset visible state
 
-		if (_engine->_grid->useCellingGrid == -1 || actor->y <= _engine->_scene->sceneZones[_engine->_grid->cellingGridIdx].topRight.y) {
-			// no redraw required
-			if (actor->staticFlags.bIsBackgrounded && bgRedraw == 0) {
-				// get actor position on screen
-				_engine->_renderer->projectPositionOnScreen(actor->x - _engine->_grid->cameraX, actor->y - _engine->_grid->cameraY, actor->z - _engine->_grid->cameraZ);
-
-				// check if actor is visible on screen, otherwise don't display it
-				if (_engine->_renderer->projPosX > -50 && _engine->_renderer->projPosX < 680 && _engine->_renderer->projPosY > -30 && _engine->_renderer->projPosY < 580) {
-					actor->dynamicFlags.bIsVisible = 1;
-				}
-			} else {
-				// if the actor isn't set as hidden
-				if (actor->entity != -1 && !(actor->staticFlags.bIsHidden)) {
-					// get actor position on screen
-					_engine->_renderer->projectPositionOnScreen(actor->x - _engine->_grid->cameraX, actor->y - _engine->_grid->cameraY, actor->z - _engine->_grid->cameraZ);
-
-					if ((actor->staticFlags.bUsesClipping && _engine->_renderer->projPosX > -112 && _engine->_renderer->projPosX < 752 && _engine->_renderer->projPosY > -50 && _engine->_renderer->projPosY < 651) ||
-					    ((!actor->staticFlags.bUsesClipping) && _engine->_renderer->projPosX > -50 && _engine->_renderer->projPosX < 680 && _engine->_renderer->projPosY > -30 && _engine->_renderer->projPosY < 580)) {
+		if (_engine->_grid->useCellingGrid != -1 && actor->y > _engine->_scene->sceneZones[_engine->_grid->cellingGridIdx].topRight.y) {
+			continue;
+		}
+		// no redraw required
+		if (actor->staticFlags.bIsBackgrounded && bgRedraw == 0) {
+			// get actor position on screen
+			_engine->_renderer->projectPositionOnScreen(actor->x - _engine->_grid->cameraX, actor->y - _engine->_grid->cameraY, actor->z - _engine->_grid->cameraZ);
+
+			// check if actor is visible on screen, otherwise don't display it
+			if (_engine->_renderer->projPosX > -50 && _engine->_renderer->projPosX < 680 && _engine->_renderer->projPosY > -30 && _engine->_renderer->projPosY < 580) {
+				actor->dynamicFlags.bIsVisible = 1;
+			}
+			continue;
+		}
+		// if the actor isn't set as hidden
+		if (actor->entity == -1 || actor->staticFlags.bIsHidden) {
+			continue;
+		}
+		// get actor position on screen
+		_engine->_renderer->projectPositionOnScreen(actor->x - _engine->_grid->cameraX, actor->y - _engine->_grid->cameraY, actor->z - _engine->_grid->cameraZ);
 
-						int32 tmpVal = actor->z + actor->x - _engine->_grid->cameraX - _engine->_grid->cameraZ;
+		if ((actor->staticFlags.bUsesClipping && _engine->_renderer->projPosX > -112 && _engine->_renderer->projPosX < 752 && _engine->_renderer->projPosY > -50 && _engine->_renderer->projPosY < 651) ||
+			((!actor->staticFlags.bUsesClipping) && _engine->_renderer->projPosX > -50 && _engine->_renderer->projPosX < 680 && _engine->_renderer->projPosY > -30 && _engine->_renderer->projPosY < 580)) {
 
-						// if actor is above another actor
-						if (actor->standOn != -1) {
-							const ActorStruct *standOnActor = _engine->_scene->getActor(actor->standOn);
-							tmpVal = standOnActor->x - _engine->_grid->cameraX + standOnActor->z - _engine->_grid->cameraZ + 2;
-						}
+			int32 tmpVal = actor->z + actor->x - _engine->_grid->cameraX - _engine->_grid->cameraZ;
 
-						if (actor->staticFlags.bIsSpriteActor) {
-							drawList[drawListPos].index = spriteActorPos; // > 0x1000
-							if (actor->staticFlags.bUsesClipping) {
-								tmpVal = actor->lastX - _engine->_grid->cameraX + actor->lastZ - _engine->_grid->cameraZ;
-							}
-						} else {
-							drawList[drawListPos].index = modelActorPos;
-						}
+			// if actor is above another actor
+			if (actor->standOn != -1) {
+				const ActorStruct *standOnActor = _engine->_scene->getActor(actor->standOn);
+				tmpVal = standOnActor->x - _engine->_grid->cameraX + standOnActor->z - _engine->_grid->cameraZ + 2;
+			}
 
-						drawList[drawListPos].posValue = tmpVal;
+			if (actor->staticFlags.bIsSpriteActor) {
+				drawList[drawListPos].index = spriteActorPos; // > 0x1000
+				if (actor->staticFlags.bUsesClipping) {
+					tmpVal = actor->lastX - _engine->_grid->cameraX + actor->lastZ - _engine->_grid->cameraZ;
+				}
+			} else {
+				drawList[drawListPos].index = modelActorPos;
+			}
 
-						drawListPos++;
+			drawList[drawListPos].posValue = tmpVal;
 
-						// if use shadows
-						if (_engine->cfgfile.ShadowMode != 0 && !(actor->staticFlags.bDoesntCastShadow)) {
-							if (actor->standOn != -1) {
-								_engine->_actor->shadowX = actor->x;
-								_engine->_actor->shadowY = actor->y - 1;
-								_engine->_actor->shadowZ = actor->z;
-							} else {
-								_engine->_movements->getShadowPosition(actor->x, actor->y, actor->z);
-							}
+			drawListPos++;
 
-							tmpVal--;
-							drawList[drawListPos].posValue = tmpVal; // save the shadow entry in the drawList
-							drawList[drawListPos].index = 0xC00;     // shadowActorPos
-							drawList[drawListPos].x = _engine->_actor->shadowX;
-							drawList[drawListPos].y = _engine->_actor->shadowY;
-							drawList[drawListPos].z = _engine->_actor->shadowZ;
-							drawList[drawListPos].offset = 2;
-							drawListPos++;
-						}
-					}
+			// if use shadows
+			if (_engine->cfgfile.ShadowMode != 0 && !(actor->staticFlags.bDoesntCastShadow)) {
+				if (actor->standOn != -1) {
+					_engine->_actor->shadowX = actor->x;
+					_engine->_actor->shadowY = actor->y - 1;
+					_engine->_actor->shadowZ = actor->z;
+				} else {
+					_engine->_movements->getShadowPosition(actor->x, actor->y, actor->z);
 				}
+
+				tmpVal--;
+				drawList[drawListPos].posValue = tmpVal; // save the shadow entry in the drawList
+				drawList[drawListPos].index = 0xC00;     // shadowActorPos
+				drawList[drawListPos].x = _engine->_actor->shadowX;
+				drawList[drawListPos].y = _engine->_actor->shadowY;
+				drawList[drawListPos].z = _engine->_actor->shadowZ;
+				drawList[drawListPos].offset = 2;
+				drawListPos++;
 			}
 		}
 	}
@@ -312,34 +314,35 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 	// second loop
 	for (int32 i = 0; i < EXTRA_MAX_ENTRIES; i++) {
 		ExtraListStruct *extra = &_engine->_extra->extraList[i];
-		if (extra->info0 != -1) {
-			if (extra->type & ExtraType::TIME_IN) {
-				if (_engine->lbaTime - extra->spawnTime > 35) {
-					extra->spawnTime = _engine->lbaTime;
-					extra->type &= ~ExtraType::TIME_IN;
-					_engine->_sound->playSample(Samples::ItemPopup, 1, extra->x, extra->y, extra->z);
-				}
-			} else {
-				if ((extra->type & ExtraType::TIME_OUT) || (extra->type & ExtraType::FLASH) || (extra->payload.lifeTime + extra->spawnTime - 150 < _engine->lbaTime) || (!((_engine->lbaTime + extra->spawnTime) & 8))) {
-					_engine->_renderer->projectPositionOnScreen(extra->x - _engine->_grid->cameraX, extra->y - _engine->_grid->cameraY, extra->z - _engine->_grid->cameraZ);
-
-					if (_engine->_renderer->projPosX > -50 && _engine->_renderer->projPosX < 680 && _engine->_renderer->projPosY > -30 && _engine->_renderer->projPosY < 580) {
-						drawList[drawListPos].posValue = extra->x - _engine->_grid->cameraX + extra->z - _engine->_grid->cameraZ;
-						drawList[drawListPos].index = 0x1800 + i;
-						drawListPos++;
-
-						if (_engine->cfgfile.ShadowMode == 2 && !(extra->info0 & 0x8000)) {
-							_engine->_movements->getShadowPosition(extra->x, extra->y, extra->z);
-
-							drawList[drawListPos].posValue = extra->x - _engine->_grid->cameraX + extra->z - _engine->_grid->cameraZ - 1;
-							drawList[drawListPos].index = 0xC00;
-							drawList[drawListPos].x = _engine->_actor->shadowX;
-							drawList[drawListPos].y = _engine->_actor->shadowY;
-							drawList[drawListPos].z = _engine->_actor->shadowZ;
-							drawList[drawListPos].offset = 0;
-							drawListPos++;
-						}
-					}
+		if (extra->info0 == -1) {
+			continue;
+		}
+		if (extra->type & ExtraType::TIME_IN) {
+			if (_engine->lbaTime - extra->spawnTime > 35) {
+				extra->spawnTime = _engine->lbaTime;
+				extra->type &= ~ExtraType::TIME_IN;
+				_engine->_sound->playSample(Samples::ItemPopup, 1, extra->x, extra->y, extra->z);
+			}
+			continue;
+		}
+		if ((extra->type & ExtraType::TIME_OUT) || (extra->type & ExtraType::FLASH) || (extra->payload.lifeTime + extra->spawnTime - 150 < _engine->lbaTime) || (!((_engine->lbaTime + extra->spawnTime) & 8))) {
+			_engine->_renderer->projectPositionOnScreen(extra->x - _engine->_grid->cameraX, extra->y - _engine->_grid->cameraY, extra->z - _engine->_grid->cameraZ);
+
+			if (_engine->_renderer->projPosX > -50 && _engine->_renderer->projPosX < 680 && _engine->_renderer->projPosY > -30 && _engine->_renderer->projPosY < 580) {
+				drawList[drawListPos].posValue = extra->x - _engine->_grid->cameraX + extra->z - _engine->_grid->cameraZ;
+				drawList[drawListPos].index = 0x1800 + i;
+				drawListPos++;
+
+				if (_engine->cfgfile.ShadowMode == 2 && !(extra->info0 & 0x8000)) {
+					_engine->_movements->getShadowPosition(extra->x, extra->y, extra->z);
+
+					drawList[drawListPos].posValue = extra->x - _engine->_grid->cameraX + extra->z - _engine->_grid->cameraZ - 1;
+					drawList[drawListPos].index = 0xC00;
+					drawList[drawListPos].x = _engine->_actor->shadowX;
+					drawList[drawListPos].y = _engine->_actor->shadowY;
+					drawList[drawListPos].z = _engine->_actor->shadowZ;
+					drawList[drawListPos].offset = 0;
+					drawListPos++;
 				}
 			}
 		}
@@ -401,7 +404,7 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 							const Common::Rect rect(_engine->_interface->textWindow.left, _engine->_interface->textWindow.top, renderRect.right, renderRect.bottom);
 							addRedrawArea(rect);
 
-							if (actor2->staticFlags.bIsBackgrounded && bgRedraw == 1) {
+							if (actor2->staticFlags.bIsBackgrounded && bgRedraw) {
 								_engine->_interface->blitBox(rect, _engine->frontVideoBuffer, _engine->workVideoBuffer);
 							}
 						}


Commit: cef7d733f1e631aae4f71d19949b76fdbc91a9ab
    https://github.com/scummvm/scummvm/commit/cef7d733f1e631aae4f71d19949b76fdbc91a9ab
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: started to cleanup draw list handling

Changed paths:
    engines/twine/redraw.cpp
    engines/twine/redraw.h


diff --git a/engines/twine/redraw.cpp b/engines/twine/redraw.cpp
index 1713151e2d..8c7372140d 100644
--- a/engines/twine/redraw.cpp
+++ b/engines/twine/redraw.cpp
@@ -236,11 +236,9 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 
 	int32 modelActorPos = 0;
 	int32 drawListPos = 0;
-	const int32 spriteActorPos = 0x1000;
-	int32 shadowActorPos = 0x0C00;
 
 	// Process actors drawing list
-	for (modelActorPos = 0; modelActorPos < _engine->_scene->sceneNumActors; modelActorPos++, spriteActorPos++, shadowActorPos++) {
+	for (modelActorPos = 0; modelActorPos < _engine->_scene->sceneNumActors; modelActorPos++) {
 		ActorStruct *actor = _engine->_scene->getActor(modelActorPos);
 		actor->dynamicFlags.bIsVisible = 0; // reset visible state
 
@@ -277,11 +275,13 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 			}
 
 			if (actor->staticFlags.bIsSpriteActor) {
-				drawList[drawListPos].index = spriteActorPos; // > 0x1000
+				drawList[drawListPos].type = 0x1000;
+				drawList[drawListPos].index = 0x1000 + modelActorPos;
 				if (actor->staticFlags.bUsesClipping) {
 					tmpVal = actor->lastX - _engine->_grid->cameraX + actor->lastZ - _engine->_grid->cameraZ;
 				}
 			} else {
+				drawList[drawListPos].type = 0;
 				drawList[drawListPos].index = modelActorPos;
 			}
 
@@ -301,7 +301,8 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 
 				tmpVal--;
 				drawList[drawListPos].posValue = tmpVal; // save the shadow entry in the drawList
-				drawList[drawListPos].index = 0xC00;     // shadowActorPos
+				drawList[drawListPos].type = 0xC00;     // shadowActorPos
+				drawList[drawListPos].index = 0xC00;
 				drawList[drawListPos].x = _engine->_actor->shadowX;
 				drawList[drawListPos].y = _engine->_actor->shadowY;
 				drawList[drawListPos].z = _engine->_actor->shadowZ;
@@ -331,6 +332,7 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 			if (_engine->_renderer->projPosX > -50 && _engine->_renderer->projPosX < 680 && _engine->_renderer->projPosY > -30 && _engine->_renderer->projPosY < 580) {
 				drawList[drawListPos].posValue = extra->x - _engine->_grid->cameraX + extra->z - _engine->_grid->cameraZ;
 				drawList[drawListPos].index = 0x1800 + i;
+				drawList[drawListPos].type = 0x1800;
 				drawListPos++;
 
 				if (_engine->cfgfile.ShadowMode == 2 && !(extra->info0 & 0x8000)) {
@@ -338,6 +340,7 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 
 					drawList[drawListPos].posValue = extra->x - _engine->_grid->cameraX + extra->z - _engine->_grid->cameraZ - 1;
 					drawList[drawListPos].index = 0xC00;
+					drawList[drawListPos].type = 0xC00;
 					drawList[drawListPos].x = _engine->_actor->shadowX;
 					drawList[drawListPos].y = _engine->_actor->shadowY;
 					drawList[drawListPos].z = _engine->_actor->shadowZ;
@@ -358,7 +361,7 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 		do {
 			int32 actorIdx = drawList[pos].index & 0x3FF;
 			ActorStruct *actor2 = _engine->_scene->getActor(actorIdx);
-			uint32 flags = ((uint32)drawList[pos].index) & 0xFC00;
+			const uint32 flags = drawList[pos].type;
 
 			// Drawing actors
 			if (flags < 0xC00) {
diff --git a/engines/twine/redraw.h b/engines/twine/redraw.h
index c47f58800c..d1de609a6b 100644
--- a/engines/twine/redraw.h
+++ b/engines/twine/redraw.h
@@ -60,6 +60,7 @@ private:
 	TwinEEngine *_engine;
 	struct DrawListStruct {
 		int16 posValue = 0;
+		uint32 type = 0;
 		uint16 index = 0; // field_2
 		uint16 x = 0;
 		uint16 y = 0;


Commit: 6c337d54881bf9ede3ef3153297ef3efb22e7844
    https://github.com/scummvm/scummvm/commit/6c337d54881bf9ede3ef3153297ef3efb22e7844
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: finished splitting type and index

Changed paths:
    engines/twine/redraw.cpp
    engines/twine/redraw.h


diff --git a/engines/twine/redraw.cpp b/engines/twine/redraw.cpp
index 8c7372140d..2d48ae15e1 100644
--- a/engines/twine/redraw.cpp
+++ b/engines/twine/redraw.cpp
@@ -276,13 +276,13 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 
 			if (actor->staticFlags.bIsSpriteActor) {
 				drawList[drawListPos].type = 0x1000;
-				drawList[drawListPos].index = 0x1000 + modelActorPos;
+				drawList[drawListPos].actorIdx = modelActorPos;
 				if (actor->staticFlags.bUsesClipping) {
 					tmpVal = actor->lastX - _engine->_grid->cameraX + actor->lastZ - _engine->_grid->cameraZ;
 				}
 			} else {
 				drawList[drawListPos].type = 0;
-				drawList[drawListPos].index = modelActorPos;
+				drawList[drawListPos].actorIdx = modelActorPos;
 			}
 
 			drawList[drawListPos].posValue = tmpVal;
@@ -302,7 +302,7 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 				tmpVal--;
 				drawList[drawListPos].posValue = tmpVal; // save the shadow entry in the drawList
 				drawList[drawListPos].type = 0xC00;     // shadowActorPos
-				drawList[drawListPos].index = 0xC00;
+				drawList[drawListPos].actorIdx = 0;
 				drawList[drawListPos].x = _engine->_actor->shadowX;
 				drawList[drawListPos].y = _engine->_actor->shadowY;
 				drawList[drawListPos].z = _engine->_actor->shadowZ;
@@ -331,7 +331,7 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 
 			if (_engine->_renderer->projPosX > -50 && _engine->_renderer->projPosX < 680 && _engine->_renderer->projPosY > -30 && _engine->_renderer->projPosY < 580) {
 				drawList[drawListPos].posValue = extra->x - _engine->_grid->cameraX + extra->z - _engine->_grid->cameraZ;
-				drawList[drawListPos].index = 0x1800 + i;
+				drawList[drawListPos].actorIdx = i;
 				drawList[drawListPos].type = 0x1800;
 				drawListPos++;
 
@@ -339,7 +339,7 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 					_engine->_movements->getShadowPosition(extra->x, extra->y, extra->z);
 
 					drawList[drawListPos].posValue = extra->x - _engine->_grid->cameraX + extra->z - _engine->_grid->cameraZ - 1;
-					drawList[drawListPos].index = 0xC00;
+					drawList[drawListPos].actorIdx = 0;
 					drawList[drawListPos].type = 0xC00;
 					drawList[drawListPos].x = _engine->_actor->shadowX;
 					drawList[drawListPos].y = _engine->_actor->shadowY;
@@ -359,7 +359,7 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 		int32 pos = 0;
 
 		do {
-			int32 actorIdx = drawList[pos].index & 0x3FF;
+			int32 actorIdx = drawList[pos].actorIdx;
 			ActorStruct *actor2 = _engine->_scene->getActor(actorIdx);
 			const uint32 flags = drawList[pos].type;
 
diff --git a/engines/twine/redraw.h b/engines/twine/redraw.h
index d1de609a6b..8a8ec139f8 100644
--- a/engines/twine/redraw.h
+++ b/engines/twine/redraw.h
@@ -61,7 +61,7 @@ private:
 	struct DrawListStruct {
 		int16 posValue = 0;
 		uint32 type = 0;
-		uint16 index = 0; // field_2
+		uint16 actorIdx = 0;
 		uint16 x = 0;
 		uint16 y = 0;
 		uint16 z = 0;


Commit: f7f3a3f14174ffd8c4b839a35e72b73a1686fc66
    https://github.com/scummvm/scummvm/commit/f7f3a3f14174ffd8c4b839a35e72b73a1686fc66
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: introduced enum for draw list type

Changed paths:
    engines/twine/redraw.cpp
    engines/twine/redraw.h


diff --git a/engines/twine/redraw.cpp b/engines/twine/redraw.cpp
index 2d48ae15e1..138ed862a6 100644
--- a/engines/twine/redraw.cpp
+++ b/engines/twine/redraw.cpp
@@ -246,7 +246,7 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 			continue;
 		}
 		// no redraw required
-		if (actor->staticFlags.bIsBackgrounded && bgRedraw == 0) {
+		if (actor->staticFlags.bIsBackgrounded && !bgRedraw) {
 			// get actor position on screen
 			_engine->_renderer->projectPositionOnScreen(actor->x - _engine->_grid->cameraX, actor->y - _engine->_grid->cameraY, actor->z - _engine->_grid->cameraZ);
 
@@ -275,7 +275,7 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 			}
 
 			if (actor->staticFlags.bIsSpriteActor) {
-				drawList[drawListPos].type = 0x1000;
+				drawList[drawListPos].type = DrawListType::DrawActorSprites;
 				drawList[drawListPos].actorIdx = modelActorPos;
 				if (actor->staticFlags.bUsesClipping) {
 					tmpVal = actor->lastX - _engine->_grid->cameraX + actor->lastZ - _engine->_grid->cameraZ;
@@ -301,7 +301,7 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 
 				tmpVal--;
 				drawList[drawListPos].posValue = tmpVal; // save the shadow entry in the drawList
-				drawList[drawListPos].type = 0xC00;     // shadowActorPos
+				drawList[drawListPos].type = DrawListType::DrawShadows;     // shadowActorPos
 				drawList[drawListPos].actorIdx = 0;
 				drawList[drawListPos].x = _engine->_actor->shadowX;
 				drawList[drawListPos].y = _engine->_actor->shadowY;
@@ -332,7 +332,7 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 			if (_engine->_renderer->projPosX > -50 && _engine->_renderer->projPosX < 680 && _engine->_renderer->projPosY > -30 && _engine->_renderer->projPosY < 580) {
 				drawList[drawListPos].posValue = extra->x - _engine->_grid->cameraX + extra->z - _engine->_grid->cameraZ;
 				drawList[drawListPos].actorIdx = i;
-				drawList[drawListPos].type = 0x1800;
+				drawList[drawListPos].type = DrawListType::DrawExtras;
 				drawListPos++;
 
 				if (_engine->cfgfile.ShadowMode == 2 && !(extra->info0 & 0x8000)) {
@@ -340,7 +340,7 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 
 					drawList[drawListPos].posValue = extra->x - _engine->_grid->cameraX + extra->z - _engine->_grid->cameraZ - 1;
 					drawList[drawListPos].actorIdx = 0;
-					drawList[drawListPos].type = 0xC00;
+					drawList[drawListPos].type = DrawListType::DrawShadows;
 					drawList[drawListPos].x = _engine->_actor->shadowX;
 					drawList[drawListPos].y = _engine->_actor->shadowY;
 					drawList[drawListPos].z = _engine->_actor->shadowZ;
@@ -364,8 +364,8 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 			const uint32 flags = drawList[pos].type;
 
 			// Drawing actors
-			if (flags < 0xC00) {
-				if (!flags) {
+			if (flags < DrawListType::DrawShadows) {
+				if (flags == 0) {
 					_engine->_animations->setModelAnimation(actor2->animPosition, _engine->_resources->animTable[actor2->previousAnimIdx], _engine->_actor->bodyTable[actor2->entity], &actor2->animTimerData);
 
 					if (!_engine->_renderer->renderIsoModel(actor2->x - _engine->_grid->cameraX, actor2->y - _engine->_grid->cameraY, actor2->z - _engine->_grid->cameraZ, 0, actor2->angle, 0, _engine->_actor->bodyTable[actor2->entity])) {
@@ -415,7 +415,7 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 				}
 			}
 			// Drawing shadows
-			else if (flags == 0xC00 && !_engine->_actor->cropBottomScreen) {
+			else if (flags == DrawListType::DrawShadows && !_engine->_actor->cropBottomScreen) {
 				const DrawListStruct& shadow = drawList[pos];
 
 				// get actor position on screen
@@ -448,12 +448,12 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 				//drawBox(_engine->_renderer->renderRect.left, _engine->_renderer->renderRect.top, _engine->_renderer->renderRect.right, _engine->_renderer->renderRect.bottom);
 			}
 			// Drawing unknown
-			else if (flags < 0x1000) {
+			else if (flags < DrawListType::DrawActorSprites) {
 				// TODO reverse this part of the code
 				warning("Not yet reversed part of the rendering code");
 			}
 			// Drawing sprite actors, doors and entities
-			else if (flags == 0x1000) {
+			else if (flags == DrawListType::DrawActorSprites) {
 				const uint8 *spritePtr = _engine->_resources->spriteTable[actor2->entity];
 
 				// get actor position on screen
@@ -497,7 +497,7 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 
 					addRedrawArea(_engine->_interface->textWindow);
 
-					if (actor2->staticFlags.bIsBackgrounded && bgRedraw == 1) {
+					if (actor2->staticFlags.bIsBackgrounded && bgRedraw) {
 						_engine->_interface->blitBox(_engine->_interface->textWindow, _engine->frontVideoBuffer, _engine->workVideoBuffer);
 					}
 
@@ -506,7 +506,7 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 				}
 			}
 			// Drawing extras
-			else if (flags == 0x1800) {
+			else if (flags == DrawListType::DrawExtras) {
 				ExtraListStruct *extra = &_engine->_extra->extraList[actorIdx];
 
 				_engine->_renderer->projectPositionOnScreen(extra->x - _engine->_grid->cameraX, extra->y - _engine->_grid->cameraY, extra->z - _engine->_grid->cameraZ);
diff --git a/engines/twine/redraw.h b/engines/twine/redraw.h
index 8a8ec139f8..116d7403a0 100644
--- a/engines/twine/redraw.h
+++ b/engines/twine/redraw.h
@@ -58,6 +58,12 @@ class TwinEEngine;
 class Redraw {
 private:
 	TwinEEngine *_engine;
+	enum DrawListType {
+		DrawActorSprites = 0x1000,
+		DrawExtras = 0x1800,
+		DrawShadows = 0xC00
+	};
+
 	struct DrawListStruct {
 		int16 posValue = 0;
 		uint32 type = 0;


Commit: ea55717bc21f4fd1978a2580a8e2e13864a78416
    https://github.com/scummvm/scummvm/commit/ea55717bc21f4fd1978a2580a8e2e13864a78416
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: named unknown member

Changed paths:
    engines/twine/parser/body.cpp
    engines/twine/parser/body.h


diff --git a/engines/twine/parser/body.cpp b/engines/twine/parser/body.cpp
index 8077486e34..bb81d5ca49 100644
--- a/engines/twine/parser/body.cpp
+++ b/engines/twine/parser/body.cpp
@@ -132,7 +132,7 @@ void BodyData::loadSpheres(Common::SeekableReadStream &stream) {
 	_spheres.reserve(numSpheres);
 	for (uint16 i = 0; i < numSpheres; ++i) {
 		BodySphere sphere;
-		sphere.unk1 = stream.readUint16LE();
+		sphere.radius = stream.readUint16LE();
 		sphere.color = stream.readUint16LE();
 		sphere.size = stream.readUint16LE();
 		sphere.vertex = stream.readUint16LE() / 6;
diff --git a/engines/twine/parser/body.h b/engines/twine/parser/body.h
index ad3c377460..ce0479df13 100644
--- a/engines/twine/parser/body.h
+++ b/engines/twine/parser/body.h
@@ -64,7 +64,7 @@ struct BodyLine {
 };
 
 struct BodySphere {
-	uint16 unk1;
+	uint16 radius;
 	uint16 color;
 	uint16 size;
 	uint16 vertex;


Commit: db857a9d0dd64b7a6b72f73fe0b9f494b2751400
    https://github.com/scummvm/scummvm/commit/db857a9d0dd64b7a6b72f73fe0b9f494b2751400
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: extract into single methods

Changed paths:
    engines/twine/redraw.cpp
    engines/twine/redraw.h


diff --git a/engines/twine/redraw.cpp b/engines/twine/redraw.cpp
index 138ed862a6..fe19ba6f33 100644
--- a/engines/twine/redraw.cpp
+++ b/engines/twine/redraw.cpp
@@ -207,38 +207,9 @@ void Redraw::updateOverlayTypePosition(int16 x1, int16 y1, int16 x2, int16 y2) {
 	}
 }
 
-// TODO: convert to bool and check if this isn't always true...
-void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
-	int16 tmp_projPosX = _engine->_renderer->projPosXScreen;
-	int16 tmp_projPosY = _engine->_renderer->projPosYScreen;
-
-	_engine->_interface->resetClip();
-
-	if (bgRedraw) {
-		_engine->freezeTime();
-		if (_engine->_scene->needChangeScene != -1 && _engine->_scene->needChangeScene != -2) {
-			_engine->_screens->fadeOut(_engine->_screens->paletteRGBA);
-		}
-		_engine->_screens->clearScreen();
-		_engine->_grid->redrawGrid();
-		updateOverlayTypePosition(tmp_projPosX, tmp_projPosY, _engine->_renderer->projPosXScreen, _engine->_renderer->projPosYScreen);
-		_engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
-
-		if (_engine->_scene->needChangeScene != -1 && _engine->_scene->needChangeScene != -2) {
-			_engine->_screens->fadeIn(_engine->_screens->paletteRGBA);
-			_engine->setPalette(_engine->_screens->paletteRGBA);
-		}
-	} else {
-		blitBackgroundAreas();
-	}
-
-	// first loop
-
-	int32 modelActorPos = 0;
+int32 Redraw::processActorDrawingList(bool bgRedraw) {
 	int32 drawListPos = 0;
-
-	// Process actors drawing list
-	for (modelActorPos = 0; modelActorPos < _engine->_scene->sceneNumActors; modelActorPos++) {
+	for (int32 modelActorPos = 0; modelActorPos < _engine->_scene->sceneNumActors; modelActorPos++) {
 		ActorStruct *actor = _engine->_scene->getActor(modelActorPos);
 		actor->dynamicFlags.bIsVisible = 0; // reset visible state
 
@@ -301,7 +272,7 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 
 				tmpVal--;
 				drawList[drawListPos].posValue = tmpVal; // save the shadow entry in the drawList
-				drawList[drawListPos].type = DrawListType::DrawShadows;     // shadowActorPos
+				drawList[drawListPos].type = DrawListType::DrawShadows;
 				drawList[drawListPos].actorIdx = 0;
 				drawList[drawListPos].x = _engine->_actor->shadowX;
 				drawList[drawListPos].y = _engine->_actor->shadowY;
@@ -311,8 +282,10 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 			}
 		}
 	}
+	return drawListPos;
+}
 
-	// second loop
+int32 Redraw::processExtraDrawingList(int32 drawListPos) {
 	for (int32 i = 0; i < EXTRA_MAX_ENTRIES; i++) {
 		ExtraListStruct *extra = &_engine->_extra->extraList[i];
 		if (extra->info0 == -1) {
@@ -350,203 +323,236 @@ void Redraw::redrawEngineActions(bool bgRedraw) { // fullRedraw
 			}
 		}
 	}
+	return drawListPos;
+}
 
-	sortDrawingList(drawList, drawListPos);
-
-	currNumOfRedrawBox = 0;
+void Redraw::processDrawList(int32 drawListPos, bool bgRedraw) {
 	// if has something to draw
-	if (drawListPos > 0) {
-		int32 pos = 0;
-
-		do {
-			int32 actorIdx = drawList[pos].actorIdx;
-			ActorStruct *actor2 = _engine->_scene->getActor(actorIdx);
-			const uint32 flags = drawList[pos].type;
-
-			// Drawing actors
-			if (flags < DrawListType::DrawShadows) {
-				if (flags == 0) {
-					_engine->_animations->setModelAnimation(actor2->animPosition, _engine->_resources->animTable[actor2->previousAnimIdx], _engine->_actor->bodyTable[actor2->entity], &actor2->animTimerData);
-
-					if (!_engine->_renderer->renderIsoModel(actor2->x - _engine->_grid->cameraX, actor2->y - _engine->_grid->cameraY, actor2->z - _engine->_grid->cameraZ, 0, actor2->angle, 0, _engine->_actor->bodyTable[actor2->entity])) {
-						if (renderRect.left < SCREEN_TEXTLIMIT_LEFT) {
-							renderRect.left = SCREEN_TEXTLIMIT_LEFT;
-						}
+	if (drawListPos <= 0) {
+		return;
+	}
+	int32 pos = 0;
 
-						if (renderRect.top < SCREEN_TEXTLIMIT_TOP) {
-							renderRect.top = SCREEN_TEXTLIMIT_TOP;
-						}
+	do {
+		int32 actorIdx = drawList[pos].actorIdx;
+		ActorStruct *actor2 = _engine->_scene->getActor(actorIdx);
+		const uint32 flags = drawList[pos].type;
 
-						if (renderRect.right >= SCREEN_WIDTH) {
-							renderRect.right = SCREEN_TEXTLIMIT_RIGHT;
-						}
+		// Drawing actors
+		if (flags < DrawListType::DrawShadows) {
+			if (flags == 0) {
+				_engine->_animations->setModelAnimation(actor2->animPosition, _engine->_resources->animTable[actor2->previousAnimIdx], _engine->_actor->bodyTable[actor2->entity], &actor2->animTimerData);
 
-						if (renderRect.bottom >= SCREEN_HEIGHT) {
-							renderRect.bottom = SCREEN_TEXTLIMIT_BOTTOM;
-						}
+				if (!_engine->_renderer->renderIsoModel(actor2->x - _engine->_grid->cameraX, actor2->y - _engine->_grid->cameraY, actor2->z - _engine->_grid->cameraZ, 0, actor2->angle, 0, _engine->_actor->bodyTable[actor2->entity])) {
+					if (renderRect.left < SCREEN_TEXTLIMIT_LEFT) {
+						renderRect.left = SCREEN_TEXTLIMIT_LEFT;
+					}
 
-						_engine->_interface->setClip(renderRect);
+					if (renderRect.top < SCREEN_TEXTLIMIT_TOP) {
+						renderRect.top = SCREEN_TEXTLIMIT_TOP;
+					}
 
-						if (_engine->_interface->textWindow.left <= _engine->_interface->textWindow.right && _engine->_interface->textWindow.top <= _engine->_interface->textWindow.bottom) {
-							actor2->dynamicFlags.bIsVisible = 1;
+					if (renderRect.right >= SCREEN_WIDTH) {
+						renderRect.right = SCREEN_TEXTLIMIT_RIGHT;
+					}
 
-							const int32 tempX = (actor2->x + 0x100) >> 9;
-							int32 tempY = actor2->y >> 8;
-							if (actor2->brickShape() != ShapeType::kNone) {
-								tempY++;
-							}
+					if (renderRect.bottom >= SCREEN_HEIGHT) {
+						renderRect.bottom = SCREEN_TEXTLIMIT_BOTTOM;
+					}
 
-							const int32 tempZ = (actor2->z + 0x100) >> 9;
+					_engine->_interface->setClip(renderRect);
 
-							_engine->_grid->drawOverModelActor(tempX, tempY, tempZ);
+					if (_engine->_interface->textWindow.left <= _engine->_interface->textWindow.right && _engine->_interface->textWindow.top <= _engine->_interface->textWindow.bottom) {
+						actor2->dynamicFlags.bIsVisible = 1;
 
-							if (_engine->_actor->cropBottomScreen) {
-								renderRect.bottom = _engine->_interface->textWindow.bottom = _engine->_actor->cropBottomScreen + 10;
-							}
+						const int32 tempX = (actor2->x + 0x100) >> 9;
+						int32 tempY = actor2->y >> 8;
+						if (actor2->brickShape() != ShapeType::kNone) {
+							tempY++;
+						}
+
+						const int32 tempZ = (actor2->z + 0x100) >> 9;
+
+						_engine->_grid->drawOverModelActor(tempX, tempY, tempZ);
+
+						if (_engine->_actor->cropBottomScreen) {
+							renderRect.bottom = _engine->_interface->textWindow.bottom = _engine->_actor->cropBottomScreen + 10;
+						}
 
-							const Common::Rect rect(_engine->_interface->textWindow.left, _engine->_interface->textWindow.top, renderRect.right, renderRect.bottom);
-							addRedrawArea(rect);
+						const Common::Rect rect(_engine->_interface->textWindow.left, _engine->_interface->textWindow.top, renderRect.right, renderRect.bottom);
+						addRedrawArea(rect);
 
-							if (actor2->staticFlags.bIsBackgrounded && bgRedraw) {
-								_engine->_interface->blitBox(rect, _engine->frontVideoBuffer, _engine->workVideoBuffer);
-							}
+						if (actor2->staticFlags.bIsBackgrounded && bgRedraw) {
+							_engine->_interface->blitBox(rect, _engine->frontVideoBuffer, _engine->workVideoBuffer);
 						}
 					}
 				}
 			}
-			// Drawing shadows
-			else if (flags == DrawListType::DrawShadows && !_engine->_actor->cropBottomScreen) {
-				const DrawListStruct& shadow = drawList[pos];
+		}
+		// Drawing shadows
+		else if (flags == DrawListType::DrawShadows && !_engine->_actor->cropBottomScreen) {
+			const DrawListStruct& shadow = drawList[pos];
 
-				// get actor position on screen
-				_engine->_renderer->projectPositionOnScreen(shadow.x - _engine->_grid->cameraX, shadow.y - _engine->_grid->cameraY, shadow.z - _engine->_grid->cameraZ);
+			// get actor position on screen
+			_engine->_renderer->projectPositionOnScreen(shadow.x - _engine->_grid->cameraX, shadow.y - _engine->_grid->cameraY, shadow.z - _engine->_grid->cameraZ);
 
-				int32 spriteWidth, spriteHeight;
-				_engine->_grid->getSpriteSize(shadow.offset, &spriteWidth, &spriteHeight, _engine->_resources->spriteShadowPtr);
+			int32 spriteWidth, spriteHeight;
+			_engine->_grid->getSpriteSize(shadow.offset, &spriteWidth, &spriteHeight, _engine->_resources->spriteShadowPtr);
 
-				// calculate sprite size and position on screen
-				renderRect.left = _engine->_renderer->projPosX - (spriteWidth / 2);
-				renderRect.top = _engine->_renderer->projPosY - (spriteHeight / 2);
-				renderRect.right = _engine->_renderer->projPosX + (spriteWidth / 2);
-				renderRect.bottom = _engine->_renderer->projPosY + (spriteHeight / 2);
+			// calculate sprite size and position on screen
+			renderRect.left = _engine->_renderer->projPosX - (spriteWidth / 2);
+			renderRect.top = _engine->_renderer->projPosY - (spriteHeight / 2);
+			renderRect.right = _engine->_renderer->projPosX + (spriteWidth / 2);
+			renderRect.bottom = _engine->_renderer->projPosY + (spriteHeight / 2);
 
+			_engine->_interface->setClip(renderRect);
+
+			if (_engine->_interface->textWindow.left <= _engine->_interface->textWindow.right && _engine->_interface->textWindow.top <= _engine->_interface->textWindow.bottom) {
+				_engine->_grid->drawSprite(shadow.offset, renderRect.left, renderRect.top, _engine->_resources->spriteShadowPtr);
+			}
+
+			const int32 tmpX = (shadow.x + 0x100) >> 9;
+			const int32 tmpY = shadow.y >> 8;
+			const int32 tmpZ = (shadow.z + 0x100) >> 9;
+
+			_engine->_grid->drawOverModelActor(tmpX, tmpY, tmpZ);
+
+			addRedrawArea(_engine->_interface->textWindow.left, _engine->_interface->textWindow.top, renderRect.right, renderRect.bottom);
+
+			// show clipping area
+			//drawBox(_engine->_renderer->renderRect.left, _engine->_renderer->renderRect.top, _engine->_renderer->renderRect.right, _engine->_renderer->renderRect.bottom);
+		}
+		// Drawing unknown
+		else if (flags < DrawListType::DrawActorSprites) {
+			// TODO reverse this part of the code
+			warning("Not yet reversed part of the rendering code");
+		}
+		// Drawing sprite actors, doors and entities
+		else if (flags == DrawListType::DrawActorSprites) {
+			const uint8 *spritePtr = _engine->_resources->spriteTable[actor2->entity];
+
+			// get actor position on screen
+			_engine->_renderer->projectPositionOnScreen(actor2->x - _engine->_grid->cameraX, actor2->y - _engine->_grid->cameraY, actor2->z - _engine->_grid->cameraZ);
+
+			int32 spriteWidth, spriteHeight;
+			_engine->_grid->getSpriteSize(0, &spriteWidth, &spriteHeight, spritePtr);
+
+			// calculate sprite position on screen
+			Common::MemoryReadStream stream(_engine->_resources->spriteBoundingBoxPtr, _engine->_resources->spriteBoundingBoxSize);
+			stream.seek(actor2->entity * 16);
+			renderRect.left = _engine->_renderer->projPosX + stream.readSint16LE();
+			renderRect.top = _engine->_renderer->projPosY + stream.readSint16LE();
+			renderRect.right = renderRect.left + spriteWidth;
+			renderRect.bottom = renderRect.top + spriteHeight;
+
+			if (actor2->staticFlags.bUsesClipping) {
+				const Common::Rect rect(_engine->_renderer->projPosXScreen + actor2->cropLeft, _engine->_renderer->projPosYScreen + actor2->cropTop, _engine->_renderer->projPosXScreen + actor2->cropRight, _engine->_renderer->projPosYScreen + actor2->cropBottom);
+				_engine->_interface->setClip(rect);
+			} else {
 				_engine->_interface->setClip(renderRect);
+			}
 
-				if (_engine->_interface->textWindow.left <= _engine->_interface->textWindow.right && _engine->_interface->textWindow.top <= _engine->_interface->textWindow.bottom) {
-					_engine->_grid->drawSprite(shadow.offset, renderRect.left, renderRect.top, _engine->_resources->spriteShadowPtr);
-				}
+			if (_engine->_interface->textWindow.left <= _engine->_interface->textWindow.right && _engine->_interface->textWindow.top <= _engine->_interface->textWindow.bottom) {
+				_engine->_grid->drawSprite(0, renderRect.left, renderRect.top, spritePtr);
 
-				const int32 tmpX = (shadow.x + 0x100) >> 9;
-				const int32 tmpY = shadow.y >> 8;
-				const int32 tmpZ = (shadow.z + 0x100) >> 9;
+				actor2->dynamicFlags.bIsVisible = 1;
 
-				_engine->_grid->drawOverModelActor(tmpX, tmpY, tmpZ);
+				if (actor2->staticFlags.bUsesClipping) {
+					_engine->_grid->drawOverSpriteActor((actor2->lastX + 0x100) >> 9, actor2->lastY >> 8, (actor2->lastZ + 0x100) >> 9);
+				} else {
+					const int32 tmpX = (actor2->x + actor2->boudingBox.x.topRight + 0x100) >> 9;
+					int32 tmpY = actor2->y >> 8;
+					if (actor2->brickShape() != ShapeType::kNone) {
+						tmpY++;
+					}
+					const int32 tmpZ = (actor2->z + actor2->boudingBox.z.topRight + 0x100) >> 9;
 
-				addRedrawArea(_engine->_interface->textWindow.left, _engine->_interface->textWindow.top, renderRect.right, renderRect.bottom);
+					_engine->_grid->drawOverSpriteActor(tmpX, tmpY, tmpZ);
+				}
+
+				addRedrawArea(_engine->_interface->textWindow);
+
+				if (actor2->staticFlags.bIsBackgrounded && bgRedraw) {
+					_engine->_interface->blitBox(_engine->_interface->textWindow, _engine->frontVideoBuffer, _engine->workVideoBuffer);
+				}
 
 				// show clipping area
-				//drawBox(_engine->_renderer->renderRect.left, _engine->_renderer->renderRect.top, _engine->_renderer->renderRect.right, _engine->_renderer->renderRect.bottom);
-			}
-			// Drawing unknown
-			else if (flags < DrawListType::DrawActorSprites) {
-				// TODO reverse this part of the code
-				warning("Not yet reversed part of the rendering code");
+				//drawBox(renderRect.left, renderRect.top, renderRect.right, renderRect.bottom);
 			}
-			// Drawing sprite actors, doors and entities
-			else if (flags == DrawListType::DrawActorSprites) {
-				const uint8 *spritePtr = _engine->_resources->spriteTable[actor2->entity];
+		}
+		// Drawing extras
+		else if (flags == DrawListType::DrawExtras) {
+			ExtraListStruct *extra = &_engine->_extra->extraList[actorIdx];
 
-				// get actor position on screen
-				_engine->_renderer->projectPositionOnScreen(actor2->x - _engine->_grid->cameraX, actor2->y - _engine->_grid->cameraY, actor2->z - _engine->_grid->cameraZ);
+			_engine->_renderer->projectPositionOnScreen(extra->x - _engine->_grid->cameraX, extra->y - _engine->_grid->cameraY, extra->z - _engine->_grid->cameraZ);
 
+			if (extra->info0 & 0x8000) {
+				_engine->_extra->drawExtraSpecial(actorIdx, _engine->_renderer->projPosX, _engine->_renderer->projPosY);
+			} else {
 				int32 spriteWidth, spriteHeight;
-				_engine->_grid->getSpriteSize(0, &spriteWidth, &spriteHeight, spritePtr);
+				_engine->_grid->getSpriteSize(0, &spriteWidth, &spriteHeight, _engine->_resources->spriteTable[extra->info0]);
 
 				// calculate sprite position on screen
 				Common::MemoryReadStream stream(_engine->_resources->spriteBoundingBoxPtr, _engine->_resources->spriteBoundingBoxSize);
-				stream.seek(actor2->entity * 16);
+				stream.seek(extra->info0 * 16);
 				renderRect.left = _engine->_renderer->projPosX + stream.readSint16LE();
 				renderRect.top = _engine->_renderer->projPosY + stream.readSint16LE();
 				renderRect.right = renderRect.left + spriteWidth;
 				renderRect.bottom = renderRect.top + spriteHeight;
 
-				if (actor2->staticFlags.bUsesClipping) {
-					const Common::Rect rect(_engine->_renderer->projPosXScreen + actor2->cropLeft, _engine->_renderer->projPosYScreen + actor2->cropTop, _engine->_renderer->projPosXScreen + actor2->cropRight, _engine->_renderer->projPosYScreen + actor2->cropBottom);
-					_engine->_interface->setClip(rect);
-				} else {
-					_engine->_interface->setClip(renderRect);
-				}
-
-				if (_engine->_interface->textWindow.left <= _engine->_interface->textWindow.right && _engine->_interface->textWindow.top <= _engine->_interface->textWindow.bottom) {
-					_engine->_grid->drawSprite(0, renderRect.left, renderRect.top, spritePtr);
-
-					actor2->dynamicFlags.bIsVisible = 1;
-
-					if (actor2->staticFlags.bUsesClipping) {
-						_engine->_grid->drawOverSpriteActor((actor2->lastX + 0x100) >> 9, actor2->lastY >> 8, (actor2->lastZ + 0x100) >> 9);
-					} else {
-						const int32 tmpX = (actor2->x + actor2->boudingBox.x.topRight + 0x100) >> 9;
-						int32 tmpY = actor2->y >> 8;
-						if (actor2->brickShape() != ShapeType::kNone) {
-							tmpY++;
-						}
-						const int32 tmpZ = (actor2->z + actor2->boudingBox.z.topRight + 0x100) >> 9;
+				_engine->_grid->drawSprite(0, renderRect.left, renderRect.top, _engine->_resources->spriteTable[extra->info0]);
+			}
 
-						_engine->_grid->drawOverSpriteActor(tmpX, tmpY, tmpZ);
-					}
+			_engine->_interface->setClip(renderRect);
 
-					addRedrawArea(_engine->_interface->textWindow);
+			if (_engine->_interface->textWindow.left <= _engine->_interface->textWindow.right && _engine->_interface->textWindow.top <= _engine->_interface->textWindow.bottom) {
+				const int32 tmpX = (drawList[pos].x + 0x100) >> 9;
+				const int32 tmpY = drawList[pos].y >> 8;
+				const int32 tmpZ = (drawList[pos].z + 0x100) >> 9;
 
-					if (actor2->staticFlags.bIsBackgrounded && bgRedraw) {
-						_engine->_interface->blitBox(_engine->_interface->textWindow, _engine->frontVideoBuffer, _engine->workVideoBuffer);
-					}
+				_engine->_grid->drawOverModelActor(tmpX, tmpY, tmpZ);
+				addRedrawArea(_engine->_interface->textWindow.left, _engine->_interface->textWindow.top, renderRect.right, renderRect.bottom);
 
-					// show clipping area
-					//drawBox(renderRect.left, renderRect.top, renderRect.right, renderRect.bottom);
-				}
+				// show clipping area
+				//drawBox(renderRect);
 			}
-			// Drawing extras
-			else if (flags == DrawListType::DrawExtras) {
-				ExtraListStruct *extra = &_engine->_extra->extraList[actorIdx];
+		}
 
-				_engine->_renderer->projectPositionOnScreen(extra->x - _engine->_grid->cameraX, extra->y - _engine->_grid->cameraY, extra->z - _engine->_grid->cameraZ);
+		_engine->_interface->resetClip();
+		pos++;
+	} while (pos < drawListPos);
+}
 
-				if (extra->info0 & 0x8000) {
-					_engine->_extra->drawExtraSpecial(actorIdx, _engine->_renderer->projPosX, _engine->_renderer->projPosY);
-				} else {
-					int32 spriteWidth, spriteHeight;
-					_engine->_grid->getSpriteSize(0, &spriteWidth, &spriteHeight, _engine->_resources->spriteTable[extra->info0]);
-
-					// calculate sprite position on screen
-					Common::MemoryReadStream stream(_engine->_resources->spriteBoundingBoxPtr, _engine->_resources->spriteBoundingBoxSize);
-					stream.seek(extra->info0 * 16);
-					renderRect.left = _engine->_renderer->projPosX + stream.readSint16LE();
-					renderRect.top = _engine->_renderer->projPosY + stream.readSint16LE();
-					renderRect.right = renderRect.left + spriteWidth;
-					renderRect.bottom = renderRect.top + spriteHeight;
-
-					_engine->_grid->drawSprite(0, renderRect.left, renderRect.top, _engine->_resources->spriteTable[extra->info0]);
-				}
+void Redraw::redrawEngineActions(bool bgRedraw) {
+	int16 tmp_projPosX = _engine->_renderer->projPosXScreen;
+	int16 tmp_projPosY = _engine->_renderer->projPosYScreen;
 
-				_engine->_interface->setClip(renderRect);
+	_engine->_interface->resetClip();
 
-				if (_engine->_interface->textWindow.left <= _engine->_interface->textWindow.right && _engine->_interface->textWindow.top <= _engine->_interface->textWindow.bottom) {
-					const int32 tmpX = (drawList[pos].x + 0x100) >> 9;
-					const int32 tmpY = drawList[pos].y >> 8;
-					const int32 tmpZ = (drawList[pos].z + 0x100) >> 9;
+	if (bgRedraw) {
+		_engine->freezeTime();
+		if (_engine->_scene->needChangeScene != -1 && _engine->_scene->needChangeScene != -2) {
+			_engine->_screens->fadeOut(_engine->_screens->paletteRGBA);
+		}
+		_engine->_screens->clearScreen();
+		_engine->_grid->redrawGrid();
+		updateOverlayTypePosition(tmp_projPosX, tmp_projPosY, _engine->_renderer->projPosXScreen, _engine->_renderer->projPosYScreen);
+		_engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
 
-					_engine->_grid->drawOverModelActor(tmpX, tmpY, tmpZ);
-					addRedrawArea(_engine->_interface->textWindow.left, _engine->_interface->textWindow.top, renderRect.right, renderRect.bottom);
+		if (_engine->_scene->needChangeScene != -1 && _engine->_scene->needChangeScene != -2) {
+			_engine->_screens->fadeIn(_engine->_screens->paletteRGBA);
+			_engine->setPalette(_engine->_screens->paletteRGBA);
+		}
+	} else {
+		blitBackgroundAreas();
+	}
 
-					// show clipping area
-					//drawBox(renderRect);
-				}
-			}
+	int32 drawListPos = processActorDrawingList(bgRedraw);
+	drawListPos = processExtraDrawingList(drawListPos);
+	sortDrawingList(drawList, drawListPos);
 
-			_engine->_interface->resetClip();
-			pos++;
-		} while (pos < drawListPos);
-	}
+	currNumOfRedrawBox = 0;
+	processDrawList(drawListPos, bgRedraw);
 
 	if (_engine->cfgfile.Debug) {
 		_engine->_debugScene->displayZones();
diff --git a/engines/twine/redraw.h b/engines/twine/redraw.h
index 116d7403a0..5690d272d8 100644
--- a/engines/twine/redraw.h
+++ b/engines/twine/redraw.h
@@ -102,6 +102,10 @@ private:
 	void sortDrawingList(DrawListStruct *list, int32 listSize);
 	void updateOverlayTypePosition(int16 x1, int16 y1, int16 x2, int16 y2);
 
+	int32 processActorDrawingList(bool bgRedraw);
+	int32 processExtraDrawingList(int32 drawListPos);
+	void processDrawList(int32 drawListPos, bool bgRedraw);
+
 public:
 	Redraw(TwinEEngine *engine) : _engine(engine) {}
 


Commit: 22d9dc3b7b9cbf480dff1d964414f01d12380ade
    https://github.com/scummvm/scummvm/commit/22d9dc3b7b9cbf480dff1d964414f01d12380ade
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: extract to method

Changed paths:
    engines/twine/redraw.cpp
    engines/twine/redraw.h


diff --git a/engines/twine/redraw.cpp b/engines/twine/redraw.cpp
index fe19ba6f33..f5d7122d1f 100644
--- a/engines/twine/redraw.cpp
+++ b/engines/twine/redraw.cpp
@@ -155,11 +155,8 @@ void Redraw::flipRedrawAreas() {
 }
 
 void Redraw::blitBackgroundAreas() {
-	const Common::Rect *currentArea = currentRedrawList;
-
 	for (int32 i = 0; i < numOfRedrawBox; i++) {
-		_engine->_interface->blitBox(*currentArea, _engine->workVideoBuffer, _engine->frontVideoBuffer);
-		currentArea++;
+		_engine->_interface->blitBox(currentRedrawList[i], _engine->workVideoBuffer, _engine->frontVideoBuffer);
 	}
 }
 
@@ -523,41 +520,7 @@ void Redraw::processDrawList(int32 drawListPos, bool bgRedraw) {
 	} while (pos < drawListPos);
 }
 
-void Redraw::redrawEngineActions(bool bgRedraw) {
-	int16 tmp_projPosX = _engine->_renderer->projPosXScreen;
-	int16 tmp_projPosY = _engine->_renderer->projPosYScreen;
-
-	_engine->_interface->resetClip();
-
-	if (bgRedraw) {
-		_engine->freezeTime();
-		if (_engine->_scene->needChangeScene != -1 && _engine->_scene->needChangeScene != -2) {
-			_engine->_screens->fadeOut(_engine->_screens->paletteRGBA);
-		}
-		_engine->_screens->clearScreen();
-		_engine->_grid->redrawGrid();
-		updateOverlayTypePosition(tmp_projPosX, tmp_projPosY, _engine->_renderer->projPosXScreen, _engine->_renderer->projPosYScreen);
-		_engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
-
-		if (_engine->_scene->needChangeScene != -1 && _engine->_scene->needChangeScene != -2) {
-			_engine->_screens->fadeIn(_engine->_screens->paletteRGBA);
-			_engine->setPalette(_engine->_screens->paletteRGBA);
-		}
-	} else {
-		blitBackgroundAreas();
-	}
-
-	int32 drawListPos = processActorDrawingList(bgRedraw);
-	drawListPos = processExtraDrawingList(drawListPos);
-	sortDrawingList(drawList, drawListPos);
-
-	currNumOfRedrawBox = 0;
-	processDrawList(drawListPos, bgRedraw);
-
-	if (_engine->cfgfile.Debug) {
-		_engine->_debugScene->displayZones();
-	}
-
+void Redraw::renderOverlays() {
 	for (int32 i = 0; i < OVERLAY_MAX_ENTRIES; i++) {
 		OverlayListStruct *overlay = &overlayList[i];
 		if (overlay->info0 != -1) {
@@ -719,6 +682,44 @@ void Redraw::redrawEngineActions(bool bgRedraw) {
 			}
 		}
 	}
+}
+
+void Redraw::redrawEngineActions(bool bgRedraw) {
+	int16 tmp_projPosX = _engine->_renderer->projPosXScreen;
+	int16 tmp_projPosY = _engine->_renderer->projPosYScreen;
+
+	_engine->_interface->resetClip();
+
+	if (bgRedraw) {
+		_engine->freezeTime();
+		if (_engine->_scene->needChangeScene != -1 && _engine->_scene->needChangeScene != -2) {
+			_engine->_screens->fadeOut(_engine->_screens->paletteRGBA);
+		}
+		_engine->_screens->clearScreen();
+		_engine->_grid->redrawGrid();
+		updateOverlayTypePosition(tmp_projPosX, tmp_projPosY, _engine->_renderer->projPosXScreen, _engine->_renderer->projPosYScreen);
+		_engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
+
+		if (_engine->_scene->needChangeScene != -1 && _engine->_scene->needChangeScene != -2) {
+			_engine->_screens->fadeIn(_engine->_screens->paletteRGBA);
+			_engine->setPalette(_engine->_screens->paletteRGBA);
+		}
+	} else {
+		blitBackgroundAreas();
+	}
+
+	int32 drawListPos = processActorDrawingList(bgRedraw);
+	drawListPos = processExtraDrawingList(drawListPos);
+	sortDrawingList(drawList, drawListPos);
+
+	currNumOfRedrawBox = 0;
+	processDrawList(drawListPos, bgRedraw);
+
+	if (_engine->cfgfile.Debug) {
+		_engine->_debugScene->displayZones();
+	}
+
+	renderOverlays();
 
 	_engine->_interface->resetClip();
 
diff --git a/engines/twine/redraw.h b/engines/twine/redraw.h
index 5690d272d8..3b36204126 100644
--- a/engines/twine/redraw.h
+++ b/engines/twine/redraw.h
@@ -105,6 +105,7 @@ private:
 	int32 processActorDrawingList(bool bgRedraw);
 	int32 processExtraDrawingList(int32 drawListPos);
 	void processDrawList(int32 drawListPos, bool bgRedraw);
+	void renderOverlays();
 
 public:
 	Redraw(TwinEEngine *engine) : _engine(engine) {}


Commit: 1f70b4776c0b7b07e31f808bbfb9c409f08e57ad
    https://github.com/scummvm/scummvm/commit/1f70b4776c0b7b07e31f808bbfb9c409f08e57ad
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: replaced magic numbers

Changed paths:
    engines/twine/interface.cpp
    engines/twine/redraw.cpp


diff --git a/engines/twine/interface.cpp b/engines/twine/interface.cpp
index 00975c0c18..dea561e8bc 100644
--- a/engines/twine/interface.cpp
+++ b/engines/twine/interface.cpp
@@ -264,7 +264,7 @@ void Interface::drawSplittedBox(const Common::Rect &rect, uint8 colorIndex) {
 
 	for (int32 x = top; x < bottom; x++) {
 		for (int32 y = left; y < right; y++) {
-			*(ptr++) = colorIndex;
+			*ptr++ = colorIndex;
 		}
 		ptr += offset;
 	}
diff --git a/engines/twine/redraw.cpp b/engines/twine/redraw.cpp
index f5d7122d1f..ea5e8ca592 100644
--- a/engines/twine/redraw.cpp
+++ b/engines/twine/redraw.cpp
@@ -219,7 +219,7 @@ int32 Redraw::processActorDrawingList(bool bgRedraw) {
 			_engine->_renderer->projectPositionOnScreen(actor->x - _engine->_grid->cameraX, actor->y - _engine->_grid->cameraY, actor->z - _engine->_grid->cameraZ);
 
 			// check if actor is visible on screen, otherwise don't display it
-			if (_engine->_renderer->projPosX > -50 && _engine->_renderer->projPosX < 680 && _engine->_renderer->projPosY > -30 && _engine->_renderer->projPosY < 580) {
+			if (_engine->_renderer->projPosX > -50 && _engine->_renderer->projPosX < SCREEN_WIDTH + 40 && _engine->_renderer->projPosY > -30 && _engine->_renderer->projPosY < SCREEN_HEIGHT + 100) {
 				actor->dynamicFlags.bIsVisible = 1;
 			}
 			continue;
@@ -231,8 +231,8 @@ int32 Redraw::processActorDrawingList(bool bgRedraw) {
 		// get actor position on screen
 		_engine->_renderer->projectPositionOnScreen(actor->x - _engine->_grid->cameraX, actor->y - _engine->_grid->cameraY, actor->z - _engine->_grid->cameraZ);
 
-		if ((actor->staticFlags.bUsesClipping && _engine->_renderer->projPosX > -112 && _engine->_renderer->projPosX < 752 && _engine->_renderer->projPosY > -50 && _engine->_renderer->projPosY < 651) ||
-			((!actor->staticFlags.bUsesClipping) && _engine->_renderer->projPosX > -50 && _engine->_renderer->projPosX < 680 && _engine->_renderer->projPosY > -30 && _engine->_renderer->projPosY < 580)) {
+		if ((actor->staticFlags.bUsesClipping && _engine->_renderer->projPosX > -112 && _engine->_renderer->projPosX < SCREEN_WIDTH + 112 && _engine->_renderer->projPosY > -50 && _engine->_renderer->projPosY < SCREEN_HEIGHT + 171) ||
+			((!actor->staticFlags.bUsesClipping) && _engine->_renderer->projPosX > -50 && _engine->_renderer->projPosX < SCREEN_WIDTH + 40 && _engine->_renderer->projPosY > -30 && _engine->_renderer->projPosY < SCREEN_HEIGHT + 100)) {
 
 			int32 tmpVal = actor->z + actor->x - _engine->_grid->cameraX - _engine->_grid->cameraZ;
 
@@ -299,7 +299,7 @@ int32 Redraw::processExtraDrawingList(int32 drawListPos) {
 		if ((extra->type & ExtraType::TIME_OUT) || (extra->type & ExtraType::FLASH) || (extra->payload.lifeTime + extra->spawnTime - 150 < _engine->lbaTime) || (!((_engine->lbaTime + extra->spawnTime) & 8))) {
 			_engine->_renderer->projectPositionOnScreen(extra->x - _engine->_grid->cameraX, extra->y - _engine->_grid->cameraY, extra->z - _engine->_grid->cameraZ);
 
-			if (_engine->_renderer->projPosX > -50 && _engine->_renderer->projPosX < 680 && _engine->_renderer->projPosY > -30 && _engine->_renderer->projPosY < 580) {
+			if (_engine->_renderer->projPosX > -50 && _engine->_renderer->projPosX < SCREEN_WIDTH + 40 && _engine->_renderer->projPosY > -30 && _engine->_renderer->projPosY < SCREEN_HEIGHT + 100) {
 				drawList[drawListPos].posValue = extra->x - _engine->_grid->cameraX + extra->z - _engine->_grid->cameraZ;
 				drawList[drawListPos].actorIdx = i;
 				drawList[drawListPos].type = DrawListType::DrawExtras;
@@ -364,12 +364,11 @@ void Redraw::processDrawList(int32 drawListPos, bool bgRedraw) {
 
 						const int32 tempX = (actor2->x + 0x100) >> 9;
 						int32 tempY = actor2->y >> 8;
+						const int32 tempZ = (actor2->z + 0x100) >> 9;
 						if (actor2->brickShape() != ShapeType::kNone) {
 							tempY++;
 						}
 
-						const int32 tempZ = (actor2->z + 0x100) >> 9;
-
 						_engine->_grid->drawOverModelActor(tempX, tempY, tempZ);
 
 						if (_engine->_actor->cropBottomScreen) {
@@ -455,14 +454,17 @@ void Redraw::processDrawList(int32 drawListPos, bool bgRedraw) {
 				actor2->dynamicFlags.bIsVisible = 1;
 
 				if (actor2->staticFlags.bUsesClipping) {
-					_engine->_grid->drawOverSpriteActor((actor2->lastX + 0x100) >> 9, actor2->lastY >> 8, (actor2->lastZ + 0x100) >> 9);
+					const int32 tmpX = (actor2->lastX + 0x100) >> 9;
+					const int32 tmpY = actor2->lastY >> 8;
+					const int32 tmpZ = (actor2->lastZ + 0x100) >> 9;
+					_engine->_grid->drawOverSpriteActor(tmpX, tmpY, tmpZ);
 				} else {
 					const int32 tmpX = (actor2->x + actor2->boudingBox.x.topRight + 0x100) >> 9;
 					int32 tmpY = actor2->y >> 8;
+					const int32 tmpZ = (actor2->z + actor2->boudingBox.z.topRight + 0x100) >> 9;
 					if (actor2->brickShape() != ShapeType::kNone) {
 						tmpY++;
 					}
-					const int32 tmpZ = (actor2->z + actor2->boudingBox.z.topRight + 0x100) >> 9;
 
 					_engine->_grid->drawOverSpriteActor(tmpX, tmpY, tmpZ);
 				}


Commit: 59ac0e304a96434c6b7257dedbe259bc3a038195
    https://github.com/scummvm/scummvm/commit/59ac0e304a96434c6b7257dedbe259bc3a038195
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: renamed variables

Changed paths:
    engines/twine/renderer.cpp


diff --git a/engines/twine/renderer.cpp b/engines/twine/renderer.cpp
index b1ae6ff238..a0314a7a18 100644
--- a/engines/twine/renderer.cpp
+++ b/engines/twine/renderer.cpp
@@ -1252,43 +1252,43 @@ int32 Renderer::renderAnimatedModel(ModelData *modelData, uint8 *bodyPtr, Render
 	// jump after the header
 	bodyPtr += 0x1A;
 
-	const int32 numOfPoints = *((const uint16 *)bodyPtr);
+	const int32 numVertices = *((const uint16 *)bodyPtr);
 	bodyPtr += 2;
 	const pointTab *pointsPtr = (const pointTab *)bodyPtr;
 
-	bodyPtr += numOfPoints * sizeof(pointTab);
+	bodyPtr += numVertices * sizeof(pointTab);
 
-	const int32 numOfElements = *((const uint16 *)bodyPtr);
+	const int32 numBones = *((const uint16 *)bodyPtr);
 	bodyPtr += 2;
-	const elementEntry *elemEntryPtr = (const elementEntry *)bodyPtr;
+	const elementEntry *bonesPtr = (const elementEntry *)bodyPtr;
 
 	Matrix *modelMatrix = &matricesTable[0];
 
-	processRotatedElement(modelMatrix, pointsPtr, renderAngleX, renderAngleY, renderAngleZ, elemEntryPtr, modelData);
+	processRotatedElement(modelMatrix, pointsPtr, renderAngleX, renderAngleY, renderAngleZ, bonesPtr, modelData);
 
-	++elemEntryPtr;
+	++bonesPtr;
 
 	int32 numOfPrimitives = 0;
 
-	if (numOfElements - 1 != 0) {
-		numOfPrimitives = numOfElements - 1;
+	if (numBones - 1 != 0) {
+		numOfPrimitives = numBones - 1;
 		modelMatrix = &matricesTable[1];
 
 		do {
-			int16 boneType = elemEntryPtr->flag;
+			int16 boneType = bonesPtr->flag;
 
 			if (boneType == 0) {
-				processRotatedElement(modelMatrix, pointsPtr, elemEntryPtr->rotateX, elemEntryPtr->rotateY, elemEntryPtr->rotateZ, elemEntryPtr, modelData);
+				processRotatedElement(modelMatrix, pointsPtr, bonesPtr->rotateX, bonesPtr->rotateY, bonesPtr->rotateZ, bonesPtr, modelData);
 			} else if (boneType == 1) {
-				processTranslatedElement(modelMatrix, pointsPtr, elemEntryPtr->rotateX, elemEntryPtr->rotateY, elemEntryPtr->rotateZ, elemEntryPtr, modelData);
+				processTranslatedElement(modelMatrix, pointsPtr, bonesPtr->rotateX, bonesPtr->rotateY, bonesPtr->rotateZ, bonesPtr, modelData);
 			}
 
 			++modelMatrix;
-			++elemEntryPtr;
+			++bonesPtr;
 		} while (--numOfPrimitives);
 	}
 
-	numOfPrimitives = numOfPoints;
+	numOfPrimitives = numVertices;
 
 	const pointTab *pointPtr = &modelData->computedPoints[0];
 	pointTab *pointPtrDest = &modelData->flattenPoints[0];
@@ -1382,7 +1382,7 @@ int32 Renderer::renderAnimatedModel(ModelData *modelData, uint8 *bodyPtr, Render
 		} while (--numOfPrimitives);
 	}
 
-	int32 *shadePtr = (int32 *)(bodyPtr + numOfElements * sizeof(elementEntry));
+	int32 *shadePtr = (int32 *)(bodyPtr + numBones * sizeof(elementEntry));
 
 	int32 numOfShades = *((const uint16 *)shadePtr);
 
@@ -1392,7 +1392,7 @@ int32 Renderer::renderAnimatedModel(ModelData *modelData, uint8 *bodyPtr, Render
 		uint8 *currentShadeDestination = (uint8 *)modelData->shadeTable;
 		Matrix *lightMatrix = &matricesTable[0];
 
-		numOfPrimitives = numOfElements;
+		numOfPrimitives = numBones;
 
 		const uint8 *tmpElemPtr = bodyPtr + 18;
 		const uint8 *pri2Ptr3 = tmpElemPtr;


Commit: 66994f008d7d4d6c11381cf16b4bb1092b953aa4
    https://github.com/scummvm/scummvm/commit/66994f008d7d4d6c11381cf16b4bb1092b953aa4
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: added model/body header methods

Changed paths:
    engines/twine/animations.cpp
    engines/twine/renderer.h


diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index 4cce032338..c01ccb00f4 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -143,7 +143,7 @@ bool Animations::setModelAnimation(int32 keyframeIdx, const uint8 *animPtr, uint
 	processLastRotationAngle = ToAngle(keyFrame->boneframes[0].y);
 
 	const int16 numBones = Model::getNumBones(bodyPtr);
-	uint8 *bonesPtr = Model::getBonesData(bodyPtr);
+	uint8 *bonesPtr = Model::getBonesStateData(bodyPtr);
 
 	int32 numOfBonesInAnim = animData.getNumBoneframes();
 	if (numOfBonesInAnim > numBones) {
@@ -238,7 +238,7 @@ void Animations::setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uint
 	animTimerDataPtr->time = _engine->lbaTime;
 
 	const int16 numBones = Model::getNumBones(bodyPtr);
-	uint8 *bonesPtr = Model::getBonesData(bodyPtr);
+	uint8 *bonesPtr = Model::getBonesStateData(bodyPtr);
 
 	int16 numOfBonesInAnim = animData.getNumBoneframes();
 	if (numOfBonesInAnim > numBones) {
@@ -266,7 +266,7 @@ void Animations::stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *animT
 	animTimerDataPtr->ptr = animBufferPos;
 
 	const int32 numBones = Model::getNumBones(bodyPtr);
-	const uint8 *ptrToData = Model::getBonesData(bodyPtr);
+	const uint8 *ptrToData = Model::getBonesStateData(bodyPtr);
 
 	uint8 *bonesPtr = animBufferPos + 8;
 
diff --git a/engines/twine/renderer.h b/engines/twine/renderer.h
index 6db0c505f4..fa944272f1 100644
--- a/engines/twine/renderer.h
+++ b/engines/twine/renderer.h
@@ -96,26 +96,83 @@ struct Model {
 		return (bodyHeader & 2) != 0;
 	}
 
-	static const uint8* getBonesData(const uint8 *bodyPtr) {
-		const uint8 *verticesBase = bodyPtr + 0x1A;
-		const int16 numVertices = READ_LE_INT16(verticesBase);
-		const uint8 *bonesBase = verticesBase + 2 + numVertices * 6;
-		return bonesBase + 2 + 8;
+	static uint8* getData(uint8 *bodyPtr) {
+		return bodyPtr + 0x1A;
+	}
+
+	static const uint8* getData(const uint8 *bodyPtr) {
+		return bodyPtr + 0x1A;
+	}
+
+	static const uint8* getVerticesBaseData(const uint8 *bodyPtr) {
+		return getData(bodyPtr) + 2;
 	}
 
 	static uint8* getBonesData(uint8 *bodyPtr) {
-		uint8 *verticesBase = bodyPtr + 0x1A;
+		uint8 *verticesBase = getData(bodyPtr);
+		const int16 numVertices = READ_LE_INT16(verticesBase);
+		return verticesBase + 2 + numVertices * 6;
+	}
+
+	static const uint8* getBonesData(const uint8 *bodyPtr) {
+		const uint8 *verticesBase = getData(bodyPtr);
 		const int16 numVertices = READ_LE_INT16(verticesBase);
-		uint8 *bonesBase = verticesBase + 2 + numVertices * 6;
-		return bonesBase + 2 + 8;
+		return verticesBase + 2 + numVertices * 6;
+	}
+
+	static const uint8* getBonesStateData(const uint8 *bodyPtr) {
+		return getBonesBaseData(bodyPtr) + 8;
+	}
+
+	static uint8* getBonesStateData(uint8 *bodyPtr) {
+		return getBonesBaseData(bodyPtr) + 8;
+	}
+
+	static uint8* getBonesBaseData(uint8 *bodyPtr) {
+		return getBonesData(bodyPtr) + 2;
+	}
+
+	static const uint8* getBonesBaseData(const uint8 *bodyPtr) {
+		return getBonesData(bodyPtr) + 2;
 	}
 
 	static int16 getNumBones(const uint8 *bodyPtr) {
-		const uint8 *verticesBase = bodyPtr + 0x1A;
+		const uint8 *verticesBase = getData(bodyPtr);
 		const int16 numVertices = READ_LE_INT16(verticesBase);
 		const uint8 *bonesBase = verticesBase + 2 + numVertices * 6;
 		return READ_LE_INT16(bonesBase);
 	}
+
+	static int16 getNumVertices(const uint8 *bodyPtr) {
+		const uint8 *verticesBase = getData(bodyPtr);
+		return READ_LE_INT16(verticesBase);
+	}
+
+	static uint8* getShadesData(uint8 *bodyPtr) {
+		uint8 *bonesBase = getBonesBaseData(bodyPtr);
+		const int16 numBones = getNumBones(bodyPtr);
+		return bonesBase + numBones * 38;
+	}
+
+	static uint8* getShadesBaseData(uint8 *bodyPtr) {
+		return getShadesData(bodyPtr) + 2;
+	}
+
+	static const uint8* getShadesData(const uint8 *bodyPtr) {
+		const uint8 *bonesBase = getBonesBaseData(bodyPtr);
+		const int16 numBones = getNumBones(bodyPtr);
+		return bonesBase + numBones * 38;
+	}
+
+	static int16 getNumShades(const uint8 *bodyPtr) {
+		const uint8 *shadesBase = getShadesData(bodyPtr);
+		return READ_LE_INT16(shadesBase);
+	}
+
+	static int16 getNumShadesBone(const uint8 *bodyPtr, int boneIdx) {
+		const uint8 *bonesBase = getBonesBaseData(bodyPtr);
+		return READ_LE_INT16(bonesBase + (boneIdx * 38) + 18);
+	}
 };
 
 #include "common/pack-start.h"


Commit: 5e589d4f88d28975cd2c67bc76474d2449828f66
    https://github.com/scummvm/scummvm/commit/5e589d4f88d28975cd2c67bc76474d2449828f66
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: use Model helper functions

Changed paths:
    engines/twine/renderer.cpp


diff --git a/engines/twine/renderer.cpp b/engines/twine/renderer.cpp
index a0314a7a18..45639fbb90 100644
--- a/engines/twine/renderer.cpp
+++ b/engines/twine/renderer.cpp
@@ -1249,18 +1249,11 @@ int32 Renderer::renderModelElements(int32 numOfPrimitives, uint8 *ptr, RenderCom
 }
 
 int32 Renderer::renderAnimatedModel(ModelData *modelData, uint8 *bodyPtr, RenderCommand *renderCmds) {
-	// jump after the header
-	bodyPtr += 0x1A;
+	const int32 numVertices = Model::getNumVertices(bodyPtr);
+	const int32 numBones = Model::getNumBones(bodyPtr);
 
-	const int32 numVertices = *((const uint16 *)bodyPtr);
-	bodyPtr += 2;
-	const pointTab *pointsPtr = (const pointTab *)bodyPtr;
-
-	bodyPtr += numVertices * sizeof(pointTab);
-
-	const int32 numBones = *((const uint16 *)bodyPtr);
-	bodyPtr += 2;
-	const elementEntry *bonesPtr = (const elementEntry *)bodyPtr;
+	const pointTab *pointsPtr = (const pointTab *)Model::getVerticesBaseData(bodyPtr);
+	const elementEntry *bonesPtr = (const elementEntry *)Model::getBonesBaseData(bodyPtr);
 
 	Matrix *modelMatrix = &matricesTable[0];
 
@@ -1382,23 +1375,18 @@ int32 Renderer::renderAnimatedModel(ModelData *modelData, uint8 *bodyPtr, Render
 		} while (--numOfPrimitives);
 	}
 
-	int32 *shadePtr = (int32 *)(bodyPtr + numBones * sizeof(elementEntry));
-
-	int32 numOfShades = *((const uint16 *)shadePtr);
-
-	shadePtr = (int32 *)(((uint8 *)shadePtr) + 2);
+	const uint8 *shadePtr = Model::getShadesBaseData(bodyPtr);
+	int32 numOfShades = Model::getNumShades(bodyPtr);
 
 	if (numOfShades) { // process normal data
-		uint8 *currentShadeDestination = (uint8 *)modelData->shadeTable;
+		uint16 *currentShadeDestination = (uint16 *)modelData->shadeTable;
 		Matrix *lightMatrix = &matricesTable[0];
 
 		numOfPrimitives = numBones;
 
-		const uint8 *tmpElemPtr = bodyPtr + 18;
-		const uint8 *pri2Ptr3 = tmpElemPtr;
-
+		int boneIdx = 0;
 		do { // for each element
-			numOfShades = *((const uint16 *)tmpElemPtr);
+			numOfShades = Model::getNumShadesBone(bodyPtr, boneIdx);
 
 			if (numOfShades) {
 				int32 numShades = numOfShades;
@@ -1436,14 +1424,13 @@ int32 Renderer::renderAnimatedModel(ModelData *modelData, uint8 *bodyPtr, Render
 						shade = (uint16)color;
 					}
 
-					*((uint16 *)currentShadeDestination) = shade;
-					currentShadeDestination += 2;
-					shadePtr += 2;
+					*currentShadeDestination = shade;
+					currentShadeDestination++;
+					shadePtr += 8;
 				} while (--numShades);
 			}
 
-			tmpElemPtr = pri2Ptr3 = pri2Ptr3 + sizeof(elementEntry); // next element
-
+			++boneIdx;
 			++lightMatrix;
 		} while (--numOfPrimitives);
 	}
@@ -1466,19 +1453,13 @@ void Renderer::prepareIsoModel(uint8 *bodyPtr) { // loadGfxSub
 		return;
 	}
 
-	uint8 *bodyDataPtr = bodyPtr + 0x1A;
-
-	int16 numVertices = *((const int16 *)bodyDataPtr);
-	uint8 *bonesBase = bodyDataPtr + 2 + numVertices * sizeof(pointTab);
-
-	int16 numBones = *((const int16 *)bonesBase);
-
-	uint8 *elementEntryBasePointer = bonesBase + 2;
+	uint8 *bonesBase = Model::getBonesBaseData(bodyPtr);
+	int16 numBones = Model::getNumBones(bodyPtr);
 
 	// set up bone indices
 	for (int32 i = 0; i < numBones; i++) {
-		elementEntryBasePointer += sizeof(elementEntry);
-		elementEntry *ee = (elementEntry*)elementEntryBasePointer;
+		bonesBase += sizeof(elementEntry);
+		elementEntry *ee = (elementEntry*)bonesBase;
 		ee->baseElement = ee->baseElement / sizeof(elementEntry);
 	}
 }


Commit: 1c7520d1c1b51c7f856a9e6579d2dff617655868
    https://github.com/scummvm/scummvm/commit/1c7520d1c1b51c7f856a9e6579d2dff617655868
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: const

Changed paths:
    engines/twine/renderer.cpp
    engines/twine/renderer.h


diff --git a/engines/twine/renderer.cpp b/engines/twine/renderer.cpp
index 45639fbb90..ed27fe3d28 100644
--- a/engines/twine/renderer.cpp
+++ b/engines/twine/renderer.cpp
@@ -1166,9 +1166,9 @@ const Renderer::RenderCommand *Renderer::depthSortRenderCommands(int32 numOfPrim
 	return _renderCmdsSortedByDepth;
 }
 
-int32 Renderer::renderModelElements(int32 numOfPrimitives, uint8 *ptr, RenderCommand **renderCmds, ModelData *modelData) {
+int32 Renderer::renderModelElements(int32 numOfPrimitives, const uint8 *polygonPtr, RenderCommand **renderCmds, ModelData *modelData) {
 	// TODO: proper size
-	Common::MemoryReadStream stream(ptr, 100000);
+	Common::MemoryReadStream stream(polygonPtr, 100000);
 
 	uint8 *renderBufferPtr = renderCoordinatesBuffer;
 	renderBufferPtr = preparePolygons(stream, numOfPrimitives, renderCmds, renderBufferPtr, modelData);
@@ -1435,7 +1435,7 @@ int32 Renderer::renderAnimatedModel(ModelData *modelData, uint8 *bodyPtr, Render
 		} while (--numOfPrimitives);
 	}
 
-	return renderModelElements(numOfPrimitives, (uint8 *)shadePtr, &renderCmds, modelData);
+	return renderModelElements(numOfPrimitives, shadePtr, &renderCmds, modelData);
 }
 
 void Renderer::prepareIsoModel(uint8 *bodyPtr) { // loadGfxSub
diff --git a/engines/twine/renderer.h b/engines/twine/renderer.h
index fa944272f1..acd03d2001 100644
--- a/engines/twine/renderer.h
+++ b/engines/twine/renderer.h
@@ -256,7 +256,7 @@ private:
 
 	int32 renderAnimatedModel(ModelData *modelData, uint8 *bodyPtr, RenderCommand *renderCmds);
 	void circleFill(int32 x, int32 y, int32 radius, uint8 color);
-	int32 renderModelElements(int32 numOfPrimitives, uint8 *pointer, RenderCommand** renderCmds, ModelData *modelData);
+	int32 renderModelElements(int32 numOfPrimitives, const uint8 *polygonPtr, RenderCommand** renderCmds, ModelData *modelData);
 	void getBaseRotationPosition(int32 x, int32 y, int32 z);
 	void getCameraAnglePositions(int32 x, int32 y, int32 z);
 	void applyRotation(Matrix *targetMatrix, const Matrix *currentMatrix);


Commit: 65a2a9fe4c06f0ca1a494861cb67a39afbfd28c7
    https://github.com/scummvm/scummvm/commit/65a2a9fe4c06f0ca1a494861cb67a39afbfd28c7
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: name unknown members

Changed paths:
    engines/twine/parser/body.cpp
    engines/twine/parser/body.h


diff --git a/engines/twine/parser/body.cpp b/engines/twine/parser/body.cpp
index bb81d5ca49..38f08ca1df 100644
--- a/engines/twine/parser/body.cpp
+++ b/engines/twine/parser/body.cpp
@@ -78,9 +78,9 @@ void BodyData::loadShades(Common::SeekableReadStream &stream) {
 	_shades.reserve(numShades);
 	for (uint16 i = 0; i < numShades; ++i) {
 		BodyShade shape;
-		shape.unk1 = stream.readSint16LE();
-		shape.unk2 = stream.readSint16LE();
-		shape.unk3 = stream.readSint16LE();
+		shape.col1 = stream.readSint16LE();
+		shape.col2 = stream.readSint16LE();
+		shape.col3 = stream.readSint16LE();
 		shape.unk4 = stream.readSint16LE();
 		_shades.push_back(shape);
 	}
diff --git a/engines/twine/parser/body.h b/engines/twine/parser/body.h
index ce0479df13..d58f68712f 100644
--- a/engines/twine/parser/body.h
+++ b/engines/twine/parser/body.h
@@ -43,9 +43,9 @@ struct BodyBone {
 };
 
 struct BodyShade {
-	int16 unk1;
-	int16 unk2;
-	int16 unk3;
+	int16 col1;
+	int16 col2;
+	int16 col3;
 	int16 unk4;
 };
 


Commit: cc1bbc5a4ab0994226fe3ca2370bad7203005542
    https://github.com/scummvm/scummvm/commit/cc1bbc5a4ab0994226fe3ca2370bad7203005542
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: const

Changed paths:
    engines/twine/renderer.cpp
    engines/twine/renderer.h


diff --git a/engines/twine/renderer.cpp b/engines/twine/renderer.cpp
index ed27fe3d28..da437f8f50 100644
--- a/engines/twine/renderer.cpp
+++ b/engines/twine/renderer.cpp
@@ -1248,7 +1248,7 @@ int32 Renderer::renderModelElements(int32 numOfPrimitives, const uint8 *polygonP
 	return 0;
 }
 
-int32 Renderer::renderAnimatedModel(ModelData *modelData, uint8 *bodyPtr, RenderCommand *renderCmds) {
+int32 Renderer::renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr, RenderCommand *renderCmds) {
 	const int32 numVertices = Model::getNumVertices(bodyPtr);
 	const int32 numBones = Model::getNumBones(bodyPtr);
 
@@ -1464,7 +1464,7 @@ void Renderer::prepareIsoModel(uint8 *bodyPtr) { // loadGfxSub
 	}
 }
 
-int32 Renderer::renderIsoModel(int32 x, int32 y, int32 z, int32 angleX, int32 angleY, int32 angleZ, uint8 *bodyPtr) {
+int32 Renderer::renderIsoModel(int32 x, int32 y, int32 z, int32 angleX, int32 angleY, int32 angleZ, const uint8 *bodyPtr) {
 	renderAngleX = angleX;
 	renderAngleY = angleY;
 	renderAngleZ = angleZ;
@@ -1495,11 +1495,11 @@ int32 Renderer::renderIsoModel(int32 x, int32 y, int32 z, int32 angleX, int32 an
 	return 0;
 }
 
-void Renderer::renderBehaviourModel(const Common::Rect &rect, int32 y, int32 angle, uint8 *entityPtr) {
-	renderBehaviourModel(rect.left, rect.top, rect.right, rect.bottom, y, angle, entityPtr);
+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(int32 boxLeft, int32 boxTop, int32 boxRight, int32 boxBottom, int32 y, int32 angle, uint8 *bodyPtr) {
+void Renderer::renderBehaviourModel(int32 boxLeft, int32 boxTop, int32 boxRight, int32 boxBottom, int32 y, int32 angle, const uint8 *bodyPtr) {
 	int32 tmpBoxRight = boxRight;
 
 	int32 ypos = boxBottom + boxTop;
@@ -1523,11 +1523,11 @@ void Renderer::renderBehaviourModel(int32 boxLeft, int32 boxTop, int32 boxRight,
 	}
 }
 
-void Renderer::renderInventoryItem(int32 x, int32 y, uint8 *itemBodyPtr, int32 angle, int32 param) {
+void Renderer::renderInventoryItem(int32 x, int32 y, const uint8 *bodyPtr, int32 angle, int32 param) {
 	setCameraPosition(x, y, 128, 200, 200);
 	setCameraAngle(0, 0, 0, 60, 0, 0, param);
 
-	renderIsoModel(0, 0, 0, 0, angle, 0, itemBodyPtr);
+	renderIsoModel(0, 0, 0, 0, angle, 0, bodyPtr);
 }
 
 } // namespace TwinE
diff --git a/engines/twine/renderer.h b/engines/twine/renderer.h
index acd03d2001..9fb819f560 100644
--- a/engines/twine/renderer.h
+++ b/engines/twine/renderer.h
@@ -154,7 +154,7 @@ struct Model {
 		return bonesBase + numBones * 38;
 	}
 
-	static uint8* getShadesBaseData(uint8 *bodyPtr) {
+	static const uint8* getShadesBaseData(const uint8 *bodyPtr) {
 		return getShadesData(bodyPtr) + 2;
 	}
 
@@ -254,7 +254,7 @@ private:
 
 	ModelData _modelData;
 
-	int32 renderAnimatedModel(ModelData *modelData, uint8 *bodyPtr, RenderCommand *renderCmds);
+	int32 renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr, RenderCommand *renderCmds);
 	void circleFill(int32 x, int32 y, int32 radius, uint8 color);
 	int32 renderModelElements(int32 numOfPrimitives, const uint8 *polygonPtr, RenderCommand** renderCmds, ModelData *modelData);
 	void getBaseRotationPosition(int32 x, int32 y, int32 z);
@@ -360,12 +360,12 @@ public:
 	void setBaseRotation(int32 x, int32 y, int32 z);
 	void setOrthoProjection(int32 x, int32 y, int32 z);
 
-	int32 renderIsoModel(int32 x, int32 y, int32 z, int32 angleX, int32 angleY, int32 angleZ, uint8 *bodyPtr);
+	int32 renderIsoModel(int32 x, int32 y, int32 z, int32 angleX, int32 angleY, int32 angleZ, const uint8 *bodyPtr);
 
-	void renderBehaviourModel(int32 boxLeft, int32 boxTop, int32 boxRight, int32 boxBottom, int32 y, int32 angle, uint8 *bodyPtr);
-	void renderBehaviourModel(const Common::Rect &rect, int32 y, int32 angle, uint8 *entityPtr);
+	void renderBehaviourModel(int32 boxLeft, int32 boxTop, int32 boxRight, int32 boxBottom, int32 y, int32 angle, const uint8 *bodyPtr);
+	void renderBehaviourModel(const Common::Rect &rect, int32 y, int32 angle, const uint8 *bodyPtr);
 
-	void renderInventoryItem(int32 x, int32 y, uint8 *itemBodyPtr, int32 angle, int32 param);
+	void renderInventoryItem(int32 x, int32 y, const uint8 *bodyPtr, int32 angle, int32 param);
 };
 
 } // namespace TwinE


Commit: 628df7be6ee4bc737063d4008d10d81d9400af4e
    https://github.com/scummvm/scummvm/commit/628df7be6ee4bc737063d4008d10d81d9400af4e
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: converted more raw byte buffer actions to the Model helper functions

Changed paths:
    engines/twine/animations.cpp
    engines/twine/renderer.h


diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index c01ccb00f4..38176bcf60 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -143,7 +143,6 @@ bool Animations::setModelAnimation(int32 keyframeIdx, const uint8 *animPtr, uint
 	processLastRotationAngle = ToAngle(keyFrame->boneframes[0].y);
 
 	const int16 numBones = Model::getNumBones(bodyPtr);
-	uint8 *bonesPtr = Model::getBonesStateData(bodyPtr);
 
 	int32 numOfBonesInAnim = animData.getNumBoneframes();
 	if (numOfBonesInAnim > numBones) {
@@ -162,6 +161,7 @@ bool Animations::setModelAnimation(int32 keyframeIdx, const uint8 *animPtr, uint
 	if (deltaTime >= keyFrameLength) {
 		for (int32 i = 0; i < numOfBonesInAnim; ++i) {
 			const BoneFrame &boneframe = keyFrame->boneframes[i];
+			uint8 *bonesPtr = Model::getBonesStateData(bodyPtr, 0);
 			WRITE_LE_UINT16(bonesPtr + 0, boneframe.type);
 			WRITE_LE_INT16(bonesPtr + 2, boneframe.x);
 			WRITE_LE_INT16(bonesPtr + 4, boneframe.y);
@@ -179,14 +179,14 @@ bool Animations::setModelAnimation(int32 keyframeIdx, const uint8 *animPtr, uint
 	lastKeyFramePtr += 16;
 	keyFramePtr += 16;
 
-	bonesPtr += 38;
-
 	if (numOfBonesInAnim <= 1) {
 		return false;
 	}
 
 	int16 tmpNumOfPoints = numOfBonesInAnim - 1;
+	int boneIdx = 1;
 	do {
+		uint8* const bonesPtr = Model::getBonesStateData(bodyPtr, boneIdx);
 		const int16 animOpcode = getAnimMode(bonesPtr + 0, keyFramePtr + 0);
 
 		switch (animOpcode) {
@@ -207,7 +207,7 @@ bool Animations::setModelAnimation(int32 keyframeIdx, const uint8 *animPtr, uint
 
 		lastKeyFramePtr += 8;
 		keyFramePtr += 8;
-		bonesPtr += 38;
+		++boneIdx;
 	} while (--tmpNumOfPoints);
 
 	return false;
@@ -238,7 +238,7 @@ void Animations::setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uint
 	animTimerDataPtr->time = _engine->lbaTime;
 
 	const int16 numBones = Model::getNumBones(bodyPtr);
-	uint8 *bonesPtr = Model::getBonesStateData(bodyPtr);
+	uint8 *bonesPtr = Model::getBonesStateData(bodyPtr, 0);
 
 	int16 numOfBonesInAnim = animData.getNumBoneframes();
 	if (numOfBonesInAnim > numBones) {
@@ -266,7 +266,7 @@ void Animations::stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *animT
 	animTimerDataPtr->ptr = animBufferPos;
 
 	const int32 numBones = Model::getNumBones(bodyPtr);
-	const uint8 *ptrToData = Model::getBonesStateData(bodyPtr);
+	const uint8 *ptrToData = Model::getBonesStateData(bodyPtr, 0);
 
 	uint8 *bonesPtr = animBufferPos + 8;
 
diff --git a/engines/twine/renderer.h b/engines/twine/renderer.h
index 9fb819f560..d89e9e966d 100644
--- a/engines/twine/renderer.h
+++ b/engines/twine/renderer.h
@@ -120,12 +120,12 @@ struct Model {
 		return verticesBase + 2 + numVertices * 6;
 	}
 
-	static const uint8* getBonesStateData(const uint8 *bodyPtr) {
-		return getBonesBaseData(bodyPtr) + 8;
+	static const uint8* getBonesStateData(const uint8 *bodyPtr, int boneIdx) {
+		return getBonesBaseData(bodyPtr) + 8 + (boneIdx * 38);
 	}
 
-	static uint8* getBonesStateData(uint8 *bodyPtr) {
-		return getBonesBaseData(bodyPtr) + 8;
+	static uint8* getBonesStateData(uint8 *bodyPtr, int boneIdx) {
+		return getBonesBaseData(bodyPtr) + 8 + (boneIdx * 38);
 	}
 
 	static uint8* getBonesBaseData(uint8 *bodyPtr) {


Commit: 7050c8225fdfaa1b79ef4fcf3f86dda31bad3586
    https://github.com/scummvm/scummvm/commit/7050c8225fdfaa1b79ef4fcf3f86dda31bad3586
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: model helper functions

Changed paths:
    engines/twine/animations.cpp
    engines/twine/animations.h


diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index 38176bcf60..3889cdb3de 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -127,7 +127,7 @@ int32 Animations::getAnimMode(uint8 *ptr, const uint8 *keyFramePtr) {
 	return opcode;
 }
 
-bool Animations::setModelAnimation(int32 keyframeIdx, const uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr) {
+bool Animations::setModelAnimation(int32 keyframeIdx, const uint8 *animPtr, uint8 *const bodyPtr, AnimTimerDataStruct *animTimerDataPtr) {
 	if (!Model::isAnimated(bodyPtr)) {
 		return false;
 	}
@@ -161,12 +161,11 @@ bool Animations::setModelAnimation(int32 keyframeIdx, const uint8 *animPtr, uint
 	if (deltaTime >= keyFrameLength) {
 		for (int32 i = 0; i < numOfBonesInAnim; ++i) {
 			const BoneFrame &boneframe = keyFrame->boneframes[i];
-			uint8 *bonesPtr = Model::getBonesStateData(bodyPtr, 0);
+			uint8 *bonesPtr = Model::getBonesStateData(bodyPtr, i);
 			WRITE_LE_UINT16(bonesPtr + 0, boneframe.type);
 			WRITE_LE_INT16(bonesPtr + 2, boneframe.x);
 			WRITE_LE_INT16(bonesPtr + 4, boneframe.y);
 			WRITE_LE_INT16(bonesPtr + 6, boneframe.z);
-			bonesPtr += 38;
 		}
 
 		animTimerDataPtr->ptr = keyFramePtr;
@@ -213,7 +212,7 @@ bool Animations::setModelAnimation(int32 keyframeIdx, const uint8 *animPtr, uint
 	return false;
 }
 
-void Animations::setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr) {
+void Animations::setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uint8 *const bodyPtr, AnimTimerDataStruct *animTimerDataPtr) {
 	if (!Model::isAnimated(bodyPtr)) {
 		return;
 	}
@@ -238,7 +237,6 @@ void Animations::setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uint
 	animTimerDataPtr->time = _engine->lbaTime;
 
 	const int16 numBones = Model::getNumBones(bodyPtr);
-	uint8 *bonesPtr = Model::getBonesStateData(bodyPtr, 0);
 
 	int16 numOfBonesInAnim = animData.getNumBoneframes();
 	if (numOfBonesInAnim > numBones) {
@@ -247,11 +245,11 @@ void Animations::setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uint
 
 	for (int32 i = 0; i < numOfBonesInAnim; ++i) {
 		const BoneFrame &boneframe = keyFrame->boneframes[i];
+		uint8 *bonesPtr = Model::getBonesStateData(bodyPtr, i);
 		WRITE_LE_UINT16(bonesPtr + 0, boneframe.type);
 		WRITE_LE_INT16(bonesPtr + 2, boneframe.x);
 		WRITE_LE_INT16(bonesPtr + 4, boneframe.y);
 		WRITE_LE_INT16(bonesPtr + 6, boneframe.z);
-		bonesPtr += 38;
 	}
 
 	return;
@@ -271,7 +269,7 @@ void Animations::stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *animT
 	uint8 *bonesPtr = animBufferPos + 8;
 
 	for (int32 i = 0; i < numBones; ++i) {
-		// these are 4 int16 values
+		// these are 4 int16 values, type, x, y and z
 		for (int32 j = 0; j < 8; j++) {
 			*bonesPtr++ = *ptrToData++;
 		}
diff --git a/engines/twine/animations.h b/engines/twine/animations.h
index 9e4203dbff..c9e369fece 100644
--- a/engines/twine/animations.h
+++ b/engines/twine/animations.h
@@ -77,7 +77,7 @@ public:
 	 * @param bodyPtr Body model poitner
 	 * @param animTimerDataPtr Animation time data
 	 */
-	void setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr);
+	void setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uint8 *const bodyPtr, AnimTimerDataStruct *animTimerDataPtr);
 
 	const uint8* getKeyFrameData(int32 frameIdx, const uint8 *animPtr);
 
@@ -100,7 +100,7 @@ public:
 	 * @param bodyPtr Body model poitner
 	 * @param animTimerDataPtr Animation time data
 	 */
-	bool setModelAnimation(int32 keyframeIdx, const uint8 *animPtr, uint8 *bodyPtr, AnimTimerDataStruct *animTimerDataPtr);
+	bool setModelAnimation(int32 keyframeIdx, const uint8 *animPtr, uint8 *const bodyPtr, AnimTimerDataStruct *animTimerDataPtr);
 
 	/**
 	 * Get entity anim index (This is taken from File3D entities)


Commit: 023114f03c4d567936a1864f5bd34f1fcf2ae770
    https://github.com/scummvm/scummvm/commit/023114f03c4d567936a1864f5bd34f1fcf2ae770
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: updated body parser

Changed paths:
    engines/twine/parser/anim.h
    engines/twine/parser/body.cpp
    engines/twine/parser/body.h


diff --git a/engines/twine/parser/anim.h b/engines/twine/parser/anim.h
index eede78f716..75471edfae 100644
--- a/engines/twine/parser/anim.h
+++ b/engines/twine/parser/anim.h
@@ -20,8 +20,8 @@
  *
  */
 
-#ifndef TWINE_BODY_H
-#define TWINE_BODY_H
+#ifndef TWINE_ANIM_H
+#define TWINE_ANIM_H
 
 #include "common/array.h"
 #include "common/stream.h"
diff --git a/engines/twine/parser/body.cpp b/engines/twine/parser/body.cpp
index 38f08ca1df..cf0a120dd7 100644
--- a/engines/twine/parser/body.cpp
+++ b/engines/twine/parser/body.cpp
@@ -48,11 +48,12 @@ void BodyData::loadBones(Common::SeekableReadStream &stream) {
 		const int16 numPoints = stream.readSint16LE();
 		const int16 basePoint = stream.readSint16LE() / 6;
 		const int16 baseElementOffset = stream.readSint16LE();
-		/*int16 type =*/ stream.readSint16LE();
-		/*int16 rotateX =*/ stream.readSint16LE();
-		/*int16 rotateY =*/ stream.readSint16LE();
-		/*int16 rotateZ =*/ stream.readSint16LE();
-		/*int32 numOfShades =*/stream.readSint32LE();
+		BoneFrame boneframe;
+		boneframe.type = stream.readSint16LE();
+		boneframe.x = stream.readSint16LE();
+		boneframe.y = stream.readSint16LE();
+		boneframe.z = stream.readSint16LE();
+		const int32 numOfShades = stream.readSint32LE();
 		/*int32 field_14 =*/ stream.readSint32LE();
 		/*int32 field_18 =*/ stream.readSint32LE();
 		/*int32 y =*/ stream.readSint32LE();
@@ -62,6 +63,8 @@ void BodyData::loadBones(Common::SeekableReadStream &stream) {
 		BodyBone bone;
 		bone.parent = baseElementOffset == -1 ? 0xffff : baseElementOffset / 38;
 		bone.vertex = basePoint;
+		bone.initalBoneState = boneframe;
+		bone.numOfShades = numOfShades;
 
 		// assign the bone index to the vertices
 		for (int j = 0; j < numPoints; ++j) {
diff --git a/engines/twine/parser/body.h b/engines/twine/parser/body.h
index d58f68712f..5b16495a63 100644
--- a/engines/twine/parser/body.h
+++ b/engines/twine/parser/body.h
@@ -26,6 +26,7 @@
 #include "common/array.h"
 #include "common/memstream.h"
 #include "common/stream.h"
+#include "twine/parser/anim.h"
 #include "twine/shared.h"
 
 namespace TwinE {
@@ -40,6 +41,8 @@ struct BodyVertex {
 struct BodyBone {
 	uint16 parent;
 	uint16 vertex;
+	int32 numOfShades;
+	BoneFrame initalBoneState;
 };
 
 struct BodyShade {
@@ -86,6 +89,8 @@ private:
 	Common::Array<BodyLine> _lines;
 	Common::Array<BodyBone> _bones;
 
+	BoneFrame _boneStates[560];
+
 public:
 	struct BodyFlags {
 		uint16 unk1 : 1;            // 1 << 0
@@ -118,18 +123,57 @@ public:
 		return bodyFlag.animated;
 	}
 
-	inline uint numBones() const {
+	inline uint getNumBones() const {
 		return _bones.size();
 	}
 
-	bool loadFromStream(Common::SeekableReadStream &stream);
+	inline uint getNumVertices() const {
+		return _vertices.size();
+	}
 
-	bool loadFromBuffer(const uint8 *buf, uint32 size);
+	BoneFrame* getBoneState(int16 boneIdx) {
+		return &_boneStates[boneIdx];
+	}
+
+	const BoneFrame* getBoneState(int16 boneIdx) const {
+		return &_boneStates[boneIdx];
+	}
+
+	const Common::Array<BodyPolygon>& getPolygons() const {
+		return _polygons;
+	}
+
+	const Common::Array<BodyVertex>& getVertices() const {
+		return _vertices;
+	}
+
+	const Common::Array<BodySphere>& getSpheres() const {
+		return _spheres;
+	}
 
-	static inline bool isAnimated(const uint8* bodyPtr) {
-		const int16 bodyHeader = READ_LE_INT16(bodyPtr);
-		return (bodyHeader & 2) != 0;
+	const Common::Array<BodyShade>& getShades() const {
+		return _shades;
 	}
+
+	const BodyShade* getShade(int16 shadeIdx) const {
+		return &_shades[shadeIdx];
+	}
+
+	const Common::Array<BodyLine>& getLines() const {
+		return _lines;
+	}
+
+	const Common::Array<BodyBone>& getBones() const {
+		return _bones;
+	}
+
+	const BodyBone* getBone(int16 boneIdx) const {
+		return &_bones[boneIdx];
+	}
+
+	bool loadFromStream(Common::SeekableReadStream &stream);
+
+	bool loadFromBuffer(const uint8 *buf, uint32 size);
 };
 
 } // End of namespace TwinE


Commit: 456801b29f234a435a46abb157ec8979e25eb10a
    https://github.com/scummvm/scummvm/commit/456801b29f234a435a46abb157ec8979e25eb10a
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: removed lineData struct

Changed paths:
    engines/twine/renderer.cpp
    engines/twine/renderer.h


diff --git a/engines/twine/renderer.cpp b/engines/twine/renderer.cpp
index da437f8f50..690717eeaf 100644
--- a/engines/twine/renderer.cpp
+++ b/engines/twine/renderer.cpp
@@ -1033,20 +1033,11 @@ uint8 *Renderer::prepareLines(Common::MemoryReadStream &stream, int32 &numOfPrim
 	numOfPrimitives += numLines;
 
 	do {
-		lineData line;
-		line.colorIndex = stream.readByte();
-		stream.skip(3);
-		line.firstPointOffset = stream.readSint16LE();
-		line.secondPointOffset = stream.readSint16LE();
 		CmdRenderLine *lineCoordinatesPtr = (CmdRenderLine *)renderBufferPtr;
-
-		if (line.firstPointOffset % 6 != 0 || line.secondPointOffset % 6 != 0) {
-			error("RENDER ERROR: lineDataPtr reference is malformed!");
-		}
-
-		const int32 point1Index = line.firstPointOffset / 6;
-		const int32 point2Index = line.secondPointOffset / 6;
-		lineCoordinatesPtr->colorIndex = line.colorIndex;
+		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;
diff --git a/engines/twine/renderer.h b/engines/twine/renderer.h
index d89e9e966d..59a8ad9472 100644
--- a/engines/twine/renderer.h
+++ b/engines/twine/renderer.h
@@ -232,15 +232,6 @@ private:
 	#include "common/pack-end.h"
 	static_assert(sizeof(pointTab) == 6, "Unexpected pointTab size");
 
-	struct lineData {
-		uint8 colorIndex = 0;
-		uint8 unk1 = 0;
-		uint8 unk2 = 0;
-		uint8 unk3 = 0;
-		int16 firstPointOffset = 0;  /**< byte offsets */
-		int16 secondPointOffset = 0; /**< byte offsets */
-	};
-
 	struct polyVertexHeader {
 		int16 shadeEntry = 0;
 		int16 dataOffset = 0;


Commit: 1aad7cd6661579d5a0bb2edb6aaf9f2b80c760b8
    https://github.com/scummvm/scummvm/commit/1aad7cd6661579d5a0bb2edb6aaf9f2b80c760b8
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: don't advance the buffer pointer, but use the helper method

Changed paths:
    engines/twine/animations.cpp


diff --git a/engines/twine/animations.cpp b/engines/twine/animations.cpp
index 3889cdb3de..27980c1bb8 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/animations.cpp
@@ -264,16 +264,15 @@ void Animations::stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *animT
 	animTimerDataPtr->ptr = animBufferPos;
 
 	const int32 numBones = Model::getNumBones(bodyPtr);
-	const uint8 *ptrToData = Model::getBonesStateData(bodyPtr, 0);
 
 	uint8 *bonesPtr = animBufferPos + 8;
 
 	for (int32 i = 0; i < numBones; ++i) {
+		const uint8 *ptrToData = Model::getBonesStateData(bodyPtr, i);
 		// these are 4 int16 values, type, x, y and z
 		for (int32 j = 0; j < 8; j++) {
 			*bonesPtr++ = *ptrToData++;
 		}
-		ptrToData += 30;
 	}
 
 	// 8 = 4xint16 - firstpoint, numpoints, basepoint, baseelement - see elementEntry


Commit: 5a1d31eb4e5e8584702e069b35098dfa6af1e3fe
    https://github.com/scummvm/scummvm/commit/5a1d31eb4e5e8584702e069b35098dfa6af1e3fe
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: reduced scope

Changed paths:
    engines/twine/renderer.cpp


diff --git a/engines/twine/renderer.cpp b/engines/twine/renderer.cpp
index 690717eeaf..5c330c4d90 100644
--- a/engines/twine/renderer.cpp
+++ b/engines/twine/renderer.cpp
@@ -239,17 +239,13 @@ void Renderer::applyPointsRotation(const pointTab *pointsPtr, int32 numPoints, p
 }
 
 void Renderer::processRotatedElement(Matrix *targetMatrix, const pointTab *pointsPtr, int32 rotZ, int32 rotY, int32 rotX, const elementEntry *elemPtr, ModelData *modelData) {
-	int32 firstPoint = elemPtr->firstPoint;
+	int32 firstPoint = elemPtr->firstPoint / sizeof(pointTab);
 	int32 numOfPoints2 = elemPtr->numOfPoints;
 
 	renderAngleX = rotX;
 	renderAngleY = rotY;
 	renderAngleZ = rotZ;
 
-	if (firstPoint % sizeof(pointTab)) {
-		error("RENDER ERROR: invalid firstPoint in process_rotated_element func");
-	}
-
 	const Matrix *currentMatrix;
 	// if its the first point
 	if (elemPtr->baseElement == -1) {
@@ -275,7 +271,7 @@ void Renderer::processRotatedElement(Matrix *targetMatrix, const pointTab *point
 		warning("RENDER WARNING: No points in this model!");
 	}
 
-	applyPointsRotation(&pointsPtr[firstPoint / sizeof(pointTab)], numOfPoints2, &modelData->computedPoints[firstPoint / sizeof(pointTab)], targetMatrix);
+	applyPointsRotation(&pointsPtr[firstPoint], numOfPoints2, &modelData->computedPoints[firstPoint], targetMatrix);
 }
 
 void Renderer::applyPointsTranslation(const pointTab *pointsPtr, int32 numPoints, pointTab *destPoints, const Matrix *translationMatrix) {
@@ -563,11 +559,7 @@ void Renderer::renderPolygonsFlat(uint8 *out, int vtop, int32 vsize, int32 color
 
 void Renderer::renderPolygonsTele(uint8 *out, int vtop, int32 vsize, int32 color) const {
 	const int16 *ptr1 = &polyTab[vtop];
-	int ax;
-	int bx;
-	unsigned short int dx;
-	unsigned short int temp;
-	bx = (unsigned short)color << 0x10;
+	int bx = (uint16)color << 16;
 	int32 renderLoop = vsize;
 	do {
 		int16 start;
@@ -601,7 +593,7 @@ void Renderer::renderPolygonsTele(uint8 *out, int vtop, int32 vsize, int32 color
 			bx = (unsigned short)(color >> 0x10);
 			uint8 *out2 = start + out;
 
-			ax = (bx & 0xF0) << 8;
+			int ax = (bx & 0xF0) << 8;
 			bx = bx << 8;
 			ax += (bx & 0x0F);
 			ax -= bx;
@@ -609,12 +601,12 @@ void Renderer::renderPolygonsTele(uint8 *out, int vtop, int32 vsize, int32 color
 			ax = ax >> 16;
 
 			ax = ax / hsize;
-			temp = (ax & 0xF0);
+			uint16 temp = (ax & 0xF0);
 			temp = temp >> 8;
 			temp += (ax & 0x0F);
 			ax = temp;
 
-			dx = ax;
+			uint16 dx = ax;
 
 			ax = (ax & 0x0F) + (bx & 0xF0);
 			hsize++;


Commit: e20cd47a3ee757820dd19367bc295cfb164d6d63
    https://github.com/scummvm/scummvm/commit/e20cd47a3ee757820dd19367bc295cfb164d6d63
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: parse into BodyData

Changed paths:
    engines/twine/actor.cpp
    engines/twine/actor.h


diff --git a/engines/twine/actor.cpp b/engines/twine/actor.cpp
index 96dc50f4c9..fc569dc10f 100644
--- a/engines/twine/actor.cpp
+++ b/engines/twine/actor.cpp
@@ -240,6 +240,7 @@ int32 Actor::initBody(int32 bodyIdx, int32 actorIdx, ActorBoundingBox &actorBoun
 					if (bodyTableSize[index] == 0) {
 						error("HQR ERROR: Loading body entities");
 					}
+					bodyData[index].loadFromBuffer(bodyTable[index], bodyTableSize[index]);
 					Renderer::prepareIsoModel(bodyTable[index]);
 					stream.seek(stream.pos() - sizeof(uint16));
 					stream.writeUint16LE(index + 0x8000);
@@ -317,27 +318,22 @@ void Actor::initModelActor(int32 bodyIdx, int16 actorIdx) {
 		bbox.z.topRight = actorBoundingBox.topRightZ;
 	} else {
 		ZVBox &bbox = localActor->boudingBox;
-		Common::MemoryReadStream stream(bodyTable[localActor->entity], bodyTableSize[localActor->entity]);
-		stream.skip(2);
-		const int16 var1 = stream.readSint16LE();
-		const int16 var2 = stream.readSint16LE();
-		bbox.y.bottomLeft = stream.readSint16LE();
-		bbox.y.topRight = stream.readSint16LE();
-		const int16 var3 = stream.readSint16LE();
-		const int16 var4 = stream.readSint16LE();
+		const BodyData& bd = bodyData[localActor->entity];
+		bbox.y.bottomLeft = bd.minsy;
+		bbox.y.topRight = bd.maxsy;
 
 		int32 result = 0;
-		const int32 result1 = var2 - var1;
-		const int32 result2 = var4 - var3;
+		const int32 distX = bd.maxsx - bd.minsx;
+		const int32 distZ = bd.maxsz - bd.minsz;
 		if (localActor->staticFlags.bUseMiniZv) {
 			// take smaller for bound
-			result = MIN(result1, result2);
+			result = MIN(distX, distZ);
 
 			result = ABS(result);
 			result >>= 1;
 		} else {
 			// take average for bound
-			result = result2 + result1;
+			result = distZ + distX;
 			result = ABS(result);
 			result >>= 2;
 		}
diff --git a/engines/twine/actor.h b/engines/twine/actor.h
index c1a2ec46fc..0e4aacd317 100644
--- a/engines/twine/actor.h
+++ b/engines/twine/actor.h
@@ -24,6 +24,7 @@
 #define TWINE_ACTOR_H
 
 #include "common/scummsys.h"
+#include "twine/parser/body.h"
 #include "twine/parser/entity.h"
 #include "twine/shared.h"
 
@@ -307,6 +308,7 @@ public:
 	/** Actors 3D body table - size of NUM_BODIES */
 	uint8 *bodyTable[NUM_BODIES]{nullptr};
 	int32 bodyTableSize[NUM_BODIES]{0};
+	BodyData bodyData[NUM_BODIES];
 
 	/** Current position in body table */
 	int32 currentPositionInBodyPtrTab;


Commit: fd94d8fc994f4d9ec251a56b47e42dc1b2b959b7
    https://github.com/scummvm/scummvm/commit/fd94d8fc994f4d9ec251a56b47e42dc1b2b959b7
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: extended Model helper functions with wrappers

Changed paths:
    engines/twine/renderer.h


diff --git a/engines/twine/renderer.h b/engines/twine/renderer.h
index 59a8ad9472..58aeeb9558 100644
--- a/engines/twine/renderer.h
+++ b/engines/twine/renderer.h
@@ -26,6 +26,7 @@
 #include "common/endian.h"
 #include "common/scummsys.h"
 #include "common/rect.h"
+#include "twine/parser/body.h"
 
 #define POLYGONTYPE_FLAT 0
 #define POLYGONTYPE_COPPER 1
@@ -96,6 +97,10 @@ struct Model {
 		return (bodyHeader & 2) != 0;
 	}
 
+	static inline bool isAnimated(const BodyData& bodyPtr) {
+		return bodyPtr.isAnimated();
+	}
+
 	static uint8* getData(uint8 *bodyPtr) {
 		return bodyPtr + 0x1A;
 	}
@@ -128,6 +133,14 @@ struct Model {
 		return getBonesBaseData(bodyPtr) + 8 + (boneIdx * 38);
 	}
 
+	static BoneFrame* getBonesStateData(BodyData &bodyPtr, int boneIdx) {
+		return bodyPtr.getBoneState(boneIdx);
+	}
+
+	static const BoneFrame* getBonesStateData(const BodyData &bodyPtr, int boneIdx) {
+		return bodyPtr.getBoneState(boneIdx);
+	}
+
 	static uint8* getBonesBaseData(uint8 *bodyPtr) {
 		return getBonesData(bodyPtr) + 2;
 	}
@@ -143,11 +156,19 @@ struct Model {
 		return READ_LE_INT16(bonesBase);
 	}
 
+	static int16 getNumBones(const BodyData &bodyPtr) {
+		return bodyPtr.getNumBones();
+	}
+
 	static int16 getNumVertices(const uint8 *bodyPtr) {
 		const uint8 *verticesBase = getData(bodyPtr);
 		return READ_LE_INT16(verticesBase);
 	}
 
+	static int16 getNumVertices(const BodyData &bodyPtr) {
+		return bodyPtr.getNumVertices();
+	}
+
 	static uint8* getShadesData(uint8 *bodyPtr) {
 		uint8 *bonesBase = getBonesBaseData(bodyPtr);
 		const int16 numBones = getNumBones(bodyPtr);
@@ -169,10 +190,18 @@ struct Model {
 		return READ_LE_INT16(shadesBase);
 	}
 
+	static int16 getNumShades(const BodyData &bodyPtr) {
+		return bodyPtr.getShades().size();
+	}
+
 	static int16 getNumShadesBone(const uint8 *bodyPtr, int boneIdx) {
 		const uint8 *bonesBase = getBonesBaseData(bodyPtr);
 		return READ_LE_INT16(bonesBase + (boneIdx * 38) + 18);
 	}
+
+	static int16 getNumShadesBone(const BodyData& bodyPtr, int boneIdx) {
+		return bodyPtr.getBone(boneIdx)->numOfShades;
+	}
 };
 
 #include "common/pack-start.h"


Commit: c95ae6684796f6a050999c557a8cd1bee7b9d897
    https://github.com/scummvm/scummvm/commit/c95ae6684796f6a050999c557a8cd1bee7b9d897
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: a new helper method for the Model class

Changed paths:
    engines/twine/renderer.cpp
    engines/twine/renderer.h


diff --git a/engines/twine/renderer.cpp b/engines/twine/renderer.cpp
index 5c330c4d90..e64bf21584 100644
--- a/engines/twine/renderer.cpp
+++ b/engines/twine/renderer.cpp
@@ -31,6 +31,7 @@
 #include "twine/movements.h"
 #include "twine/redraw.h"
 #include "twine/shadeangletab.h"
+#include "twine/shared.h"
 #include "twine/twine.h"
 
 namespace TwinE {
@@ -1358,7 +1359,6 @@ int32 Renderer::renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr,
 		} while (--numOfPrimitives);
 	}
 
-	const uint8 *shadePtr = Model::getShadesBaseData(bodyPtr);
 	int32 numOfShades = Model::getNumShades(bodyPtr);
 
 	if (numOfShades) { // process normal data
@@ -1367,6 +1367,7 @@ int32 Renderer::renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr,
 
 		numOfPrimitives = numBones;
 
+		int shadeIndex = 0;
 		int boneIdx = 0;
 		do { // for each element
 			numOfShades = Model::getNumShadesBone(bodyPtr, boneIdx);
@@ -1387,6 +1388,7 @@ int32 Renderer::renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr,
 				shadeMatrix.row3[2] = lightMatrix->row3[2] * lightZ;
 
 				do { // for each normal
+					const uint8 *shadePtr = Model::getShadesBaseData(bodyPtr, shadeIndex);
 					const int16 *colPtr = (const int16 *)shadePtr;
 
 					int16 col1 = *((const int16 *)colPtr++);
@@ -1409,7 +1411,7 @@ int32 Renderer::renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr,
 
 					*currentShadeDestination = shade;
 					currentShadeDestination++;
-					shadePtr += 8;
+					++shadeIndex;
 				} while (--numShades);
 			}
 
@@ -1418,7 +1420,7 @@ int32 Renderer::renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr,
 		} while (--numOfPrimitives);
 	}
 
-	return renderModelElements(numOfPrimitives, shadePtr, &renderCmds, modelData);
+	return renderModelElements(numOfPrimitives, Model::getPolygonData(bodyPtr), &renderCmds, modelData);
 }
 
 void Renderer::prepareIsoModel(uint8 *bodyPtr) { // loadGfxSub
diff --git a/engines/twine/renderer.h b/engines/twine/renderer.h
index 58aeeb9558..187bf69a64 100644
--- a/engines/twine/renderer.h
+++ b/engines/twine/renderer.h
@@ -175,8 +175,8 @@ struct Model {
 		return bonesBase + numBones * 38;
 	}
 
-	static const uint8* getShadesBaseData(const uint8 *bodyPtr) {
-		return getShadesData(bodyPtr) + 2;
+	static const uint8* getShadesBaseData(const uint8 *bodyPtr, int16 shadeIdx = 0) {
+		return getShadesData(bodyPtr) + 2 + (shadeIdx * 8);
 	}
 
 	static const uint8* getShadesData(const uint8 *bodyPtr) {
@@ -202,6 +202,20 @@ struct Model {
 	static int16 getNumShadesBone(const BodyData& bodyPtr, int boneIdx) {
 		return bodyPtr.getBone(boneIdx)->numOfShades;
 	}
+
+	static const uint8* getPolygonData(const uint8 *bodyPtr) {
+		const uint8* shades = getShadesBaseData(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 = Model::getNumShadesBone(bodyPtr, boneIdx);
+			shades += numOfShades * 8;
+		}
+		return shades;
+	}
 };
 
 #include "common/pack-start.h"


Commit: b6841dbc257efbdc3b2214a21b0f6ff56d706db7
    https://github.com/scummvm/scummvm/commit/b6841dbc257efbdc3b2214a21b0f6ff56d706db7
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: Model helper functions

Changed paths:
    engines/twine/renderer.h


diff --git a/engines/twine/renderer.h b/engines/twine/renderer.h
index 187bf69a64..dcdc62a734 100644
--- a/engines/twine/renderer.h
+++ b/engines/twine/renderer.h
@@ -145,8 +145,8 @@ struct Model {
 		return getBonesData(bodyPtr) + 2;
 	}
 
-	static const uint8* getBonesBaseData(const uint8 *bodyPtr) {
-		return getBonesData(bodyPtr) + 2;
+	static const uint8* getBonesBaseData(const uint8 *bodyPtr, int boneIdx = 0) {
+		return getBonesData(bodyPtr) + 2 + (boneIdx * 38);
 	}
 
 	static int16 getNumBones(const uint8 *bodyPtr) {
@@ -179,6 +179,10 @@ struct Model {
 		return getShadesData(bodyPtr) + 2 + (shadeIdx * 8);
 	}
 
+	static const BodyShade* getShadesBaseData(const BodyData &bodyPtr, int16 shadeIdx = 0) {
+		return bodyPtr.getShade(shadeIdx);
+	}
+
 	static const uint8* getShadesData(const uint8 *bodyPtr) {
 		const uint8 *bonesBase = getBonesBaseData(bodyPtr);
 		const int16 numBones = getNumBones(bodyPtr);


Commit: 5eb8ae2f26f85df9fa31a8c4c192258c7517a339
    https://github.com/scummvm/scummvm/commit/5eb8ae2f26f85df9fa31a8c4c192258c7517a339
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: use the Model helper functions

Changed paths:
    engines/twine/renderer.cpp


diff --git a/engines/twine/renderer.cpp b/engines/twine/renderer.cpp
index e64bf21584..3571f690c8 100644
--- a/engines/twine/renderer.cpp
+++ b/engines/twine/renderer.cpp
@@ -1237,13 +1237,11 @@ int32 Renderer::renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr,
 	const int32 numBones = Model::getNumBones(bodyPtr);
 
 	const pointTab *pointsPtr = (const pointTab *)Model::getVerticesBaseData(bodyPtr);
-	const elementEntry *bonesPtr = (const elementEntry *)Model::getBonesBaseData(bodyPtr);
 
 	Matrix *modelMatrix = &matricesTable[0];
 
-	processRotatedElement(modelMatrix, pointsPtr, renderAngleX, renderAngleY, renderAngleZ, bonesPtr, modelData);
-
-	++bonesPtr;
+	const elementEntry *bonesPtr0 = (const elementEntry *)Model::getBonesBaseData(bodyPtr, 0);
+	processRotatedElement(modelMatrix, pointsPtr, renderAngleX, renderAngleY, renderAngleZ, bonesPtr0, modelData);
 
 	int32 numOfPrimitives = 0;
 
@@ -1251,7 +1249,9 @@ int32 Renderer::renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr,
 		numOfPrimitives = numBones - 1;
 		modelMatrix = &matricesTable[1];
 
+		int boneIdx = 1;
 		do {
+			const elementEntry *bonesPtr = (const elementEntry *)Model::getBonesBaseData(bodyPtr, boneIdx);
 			int16 boneType = bonesPtr->flag;
 
 			if (boneType == 0) {
@@ -1261,7 +1261,7 @@ int32 Renderer::renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr,
 			}
 
 			++modelMatrix;
-			++bonesPtr;
+			++boneIdx;
 		} while (--numOfPrimitives);
 	}
 


Commit: cbac794bebfbda3eb6b9cda5283432d2e2b0dc60
    https://github.com/scummvm/scummvm/commit/cbac794bebfbda3eb6b9cda5283432d2e2b0dc60
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: more model helper

Changed paths:
    engines/twine/parser/body.cpp
    engines/twine/renderer.h


diff --git a/engines/twine/parser/body.cpp b/engines/twine/parser/body.cpp
index cf0a120dd7..2cd48e8d9d 100644
--- a/engines/twine/parser/body.cpp
+++ b/engines/twine/parser/body.cpp
@@ -103,6 +103,7 @@ void BodyData::loadPolygons(Common::SeekableReadStream &stream) {
 			poly.intensity = stream.readSint16LE();
 		}
 
+		// TODO: this is not yet correct
 		poly.indices.reserve(numVertex);
 		for (int k = 0; k < numVertex; ++k) {
 			if (poly.renderType >= 9) {
diff --git a/engines/twine/renderer.h b/engines/twine/renderer.h
index dcdc62a734..ae4dd1dcae 100644
--- a/engines/twine/renderer.h
+++ b/engines/twine/renderer.h
@@ -113,6 +113,10 @@ struct Model {
 		return getData(bodyPtr) + 2;
 	}
 
+	static const Common::Array<BodyVertex>& getVerticesBaseData(const BodyData &bodyPtr) {
+		return bodyPtr.getVertices();
+	}
+
 	static uint8* getBonesData(uint8 *bodyPtr) {
 		uint8 *verticesBase = getData(bodyPtr);
 		const int16 numVertices = READ_LE_INT16(verticesBase);
@@ -149,6 +153,10 @@ struct Model {
 		return getBonesData(bodyPtr) + 2 + (boneIdx * 38);
 	}
 
+	static const BoneFrame* getBonesBaseData(const BodyData &bodyPtr, int boneIdx = 0) {
+		return bodyPtr.getBoneState(boneIdx);
+	}
+
 	static int16 getNumBones(const uint8 *bodyPtr) {
 		const uint8 *verticesBase = getData(bodyPtr);
 		const int16 numVertices = READ_LE_INT16(verticesBase);


Commit: 01816aa8606cc8e5c86a1b329bcb4f6b6b20f380
    https://github.com/scummvm/scummvm/commit/01816aa8606cc8e5c86a1b329bcb4f6b6b20f380
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: extract to method

Changed paths:
    engines/twine/redraw.cpp
    engines/twine/redraw.h


diff --git a/engines/twine/redraw.cpp b/engines/twine/redraw.cpp
index ea5e8ca592..4dd42382b3 100644
--- a/engines/twine/redraw.cpp
+++ b/engines/twine/redraw.cpp
@@ -323,203 +323,213 @@ int32 Redraw::processExtraDrawingList(int32 drawListPos) {
 	return drawListPos;
 }
 
-void Redraw::processDrawList(int32 drawListPos, bool bgRedraw) {
-	// if has something to draw
-	if (drawListPos <= 0) {
-		return;
-	}
-	int32 pos = 0;
-
-	do {
-		int32 actorIdx = drawList[pos].actorIdx;
-		ActorStruct *actor2 = _engine->_scene->getActor(actorIdx);
-		const uint32 flags = drawList[pos].type;
-
-		// Drawing actors
-		if (flags < DrawListType::DrawShadows) {
-			if (flags == 0) {
-				_engine->_animations->setModelAnimation(actor2->animPosition, _engine->_resources->animTable[actor2->previousAnimIdx], _engine->_actor->bodyTable[actor2->entity], &actor2->animTimerData);
+void Redraw::processDrawListShadows(const DrawListStruct& drawCmd) {
+	// get actor position on screen
+	_engine->_renderer->projectPositionOnScreen(drawCmd.x - _engine->_grid->cameraX, drawCmd.y - _engine->_grid->cameraY, drawCmd.z - _engine->_grid->cameraZ);
 
-				if (!_engine->_renderer->renderIsoModel(actor2->x - _engine->_grid->cameraX, actor2->y - _engine->_grid->cameraY, actor2->z - _engine->_grid->cameraZ, 0, actor2->angle, 0, _engine->_actor->bodyTable[actor2->entity])) {
-					if (renderRect.left < SCREEN_TEXTLIMIT_LEFT) {
-						renderRect.left = SCREEN_TEXTLIMIT_LEFT;
-					}
+	int32 spriteWidth, spriteHeight;
+	_engine->_grid->getSpriteSize(drawCmd.offset, &spriteWidth, &spriteHeight, _engine->_resources->spriteShadowPtr);
 
-					if (renderRect.top < SCREEN_TEXTLIMIT_TOP) {
-						renderRect.top = SCREEN_TEXTLIMIT_TOP;
-					}
+	// calculate sprite size and position on screen
+	renderRect.left = _engine->_renderer->projPosX - (spriteWidth / 2);
+	renderRect.top = _engine->_renderer->projPosY - (spriteHeight / 2);
+	renderRect.right = _engine->_renderer->projPosX + (spriteWidth / 2);
+	renderRect.bottom = _engine->_renderer->projPosY + (spriteHeight / 2);
 
-					if (renderRect.right >= SCREEN_WIDTH) {
-						renderRect.right = SCREEN_TEXTLIMIT_RIGHT;
-					}
+	_engine->_interface->setClip(renderRect);
 
-					if (renderRect.bottom >= SCREEN_HEIGHT) {
-						renderRect.bottom = SCREEN_TEXTLIMIT_BOTTOM;
-					}
+	if (_engine->_interface->textWindow.left <= _engine->_interface->textWindow.right && _engine->_interface->textWindow.top <= _engine->_interface->textWindow.bottom) {
+		_engine->_grid->drawSprite(drawCmd.offset, renderRect.left, renderRect.top, _engine->_resources->spriteShadowPtr);
+	}
 
-					_engine->_interface->setClip(renderRect);
+	const int32 tmpX = (drawCmd.x + 0x100) >> 9;
+	const int32 tmpY = drawCmd.y >> 8;
+	const int32 tmpZ = (drawCmd.z + 0x100) >> 9;
 
-					if (_engine->_interface->textWindow.left <= _engine->_interface->textWindow.right && _engine->_interface->textWindow.top <= _engine->_interface->textWindow.bottom) {
-						actor2->dynamicFlags.bIsVisible = 1;
+	_engine->_grid->drawOverModelActor(tmpX, tmpY, tmpZ);
 
-						const int32 tempX = (actor2->x + 0x100) >> 9;
-						int32 tempY = actor2->y >> 8;
-						const int32 tempZ = (actor2->z + 0x100) >> 9;
-						if (actor2->brickShape() != ShapeType::kNone) {
-							tempY++;
-						}
+	addRedrawArea(_engine->_interface->textWindow.left, _engine->_interface->textWindow.top, renderRect.right, renderRect.bottom);
 
-						_engine->_grid->drawOverModelActor(tempX, tempY, tempZ);
+	// show clipping area
+	//drawBox(_engine->_renderer->renderRect.left, _engine->_renderer->renderRect.top, _engine->_renderer->renderRect.right, _engine->_renderer->renderRect.bottom);
+}
 
-						if (_engine->_actor->cropBottomScreen) {
-							renderRect.bottom = _engine->_interface->textWindow.bottom = _engine->_actor->cropBottomScreen + 10;
-						}
+void Redraw::processDrawListActors(const DrawListStruct& drawCmd, bool bgRedraw) {
+	int32 actorIdx = drawCmd.actorIdx;
+	ActorStruct *actor2 = _engine->_scene->getActor(actorIdx);
+	_engine->_animations->setModelAnimation(actor2->animPosition, _engine->_resources->animTable[actor2->previousAnimIdx], _engine->_actor->bodyTable[actor2->entity], &actor2->animTimerData);
 
-						const Common::Rect rect(_engine->_interface->textWindow.left, _engine->_interface->textWindow.top, renderRect.right, renderRect.bottom);
-						addRedrawArea(rect);
+	if (!_engine->_renderer->renderIsoModel(actor2->x - _engine->_grid->cameraX, actor2->y - _engine->_grid->cameraY, actor2->z - _engine->_grid->cameraZ, 0, actor2->angle, 0, _engine->_actor->bodyTable[actor2->entity])) {
+		if (renderRect.left < SCREEN_TEXTLIMIT_LEFT) {
+			renderRect.left = SCREEN_TEXTLIMIT_LEFT;
+		}
 
-						if (actor2->staticFlags.bIsBackgrounded && bgRedraw) {
-							_engine->_interface->blitBox(rect, _engine->frontVideoBuffer, _engine->workVideoBuffer);
-						}
-					}
-				}
-			}
+		if (renderRect.top < SCREEN_TEXTLIMIT_TOP) {
+			renderRect.top = SCREEN_TEXTLIMIT_TOP;
 		}
-		// Drawing shadows
-		else if (flags == DrawListType::DrawShadows && !_engine->_actor->cropBottomScreen) {
-			const DrawListStruct& shadow = drawList[pos];
 
-			// get actor position on screen
-			_engine->_renderer->projectPositionOnScreen(shadow.x - _engine->_grid->cameraX, shadow.y - _engine->_grid->cameraY, shadow.z - _engine->_grid->cameraZ);
+		if (renderRect.right >= SCREEN_WIDTH) {
+			renderRect.right = SCREEN_TEXTLIMIT_RIGHT;
+		}
 
-			int32 spriteWidth, spriteHeight;
-			_engine->_grid->getSpriteSize(shadow.offset, &spriteWidth, &spriteHeight, _engine->_resources->spriteShadowPtr);
+		if (renderRect.bottom >= SCREEN_HEIGHT) {
+			renderRect.bottom = SCREEN_TEXTLIMIT_BOTTOM;
+		}
 
-			// calculate sprite size and position on screen
-			renderRect.left = _engine->_renderer->projPosX - (spriteWidth / 2);
-			renderRect.top = _engine->_renderer->projPosY - (spriteHeight / 2);
-			renderRect.right = _engine->_renderer->projPosX + (spriteWidth / 2);
-			renderRect.bottom = _engine->_renderer->projPosY + (spriteHeight / 2);
+		_engine->_interface->setClip(renderRect);
 
-			_engine->_interface->setClip(renderRect);
+		if (_engine->_interface->textWindow.left <= _engine->_interface->textWindow.right && _engine->_interface->textWindow.top <= _engine->_interface->textWindow.bottom) {
+			actor2->dynamicFlags.bIsVisible = 1;
 
-			if (_engine->_interface->textWindow.left <= _engine->_interface->textWindow.right && _engine->_interface->textWindow.top <= _engine->_interface->textWindow.bottom) {
-				_engine->_grid->drawSprite(shadow.offset, renderRect.left, renderRect.top, _engine->_resources->spriteShadowPtr);
+			const int32 tempX = (actor2->x + 0x100) >> 9;
+			int32 tempY = actor2->y >> 8;
+			const int32 tempZ = (actor2->z + 0x100) >> 9;
+			if (actor2->brickShape() != ShapeType::kNone) {
+				tempY++;
 			}
 
-			const int32 tmpX = (shadow.x + 0x100) >> 9;
-			const int32 tmpY = shadow.y >> 8;
-			const int32 tmpZ = (shadow.z + 0x100) >> 9;
+			_engine->_grid->drawOverModelActor(tempX, tempY, tempZ);
 
-			_engine->_grid->drawOverModelActor(tmpX, tmpY, tmpZ);
+			if (_engine->_actor->cropBottomScreen) {
+				renderRect.bottom = _engine->_interface->textWindow.bottom = _engine->_actor->cropBottomScreen + 10;
+			}
 
-			addRedrawArea(_engine->_interface->textWindow.left, _engine->_interface->textWindow.top, renderRect.right, renderRect.bottom);
+			const Common::Rect rect(_engine->_interface->textWindow.left, _engine->_interface->textWindow.top, renderRect.right, renderRect.bottom);
+			addRedrawArea(rect);
 
-			// show clipping area
-			//drawBox(_engine->_renderer->renderRect.left, _engine->_renderer->renderRect.top, _engine->_renderer->renderRect.right, _engine->_renderer->renderRect.bottom);
-		}
-		// Drawing unknown
-		else if (flags < DrawListType::DrawActorSprites) {
-			// TODO reverse this part of the code
-			warning("Not yet reversed part of the rendering code");
+			if (actor2->staticFlags.bIsBackgrounded && bgRedraw) {
+				_engine->_interface->blitBox(rect, _engine->frontVideoBuffer, _engine->workVideoBuffer);
+			}
 		}
-		// Drawing sprite actors, doors and entities
-		else if (flags == DrawListType::DrawActorSprites) {
-			const uint8 *spritePtr = _engine->_resources->spriteTable[actor2->entity];
+	}
+}
 
-			// get actor position on screen
-			_engine->_renderer->projectPositionOnScreen(actor2->x - _engine->_grid->cameraX, actor2->y - _engine->_grid->cameraY, actor2->z - _engine->_grid->cameraZ);
+void Redraw::processDrawListActorSprites(const DrawListStruct& drawCmd, bool bgRedraw) {
+	int32 actorIdx = drawCmd.actorIdx;
+	ActorStruct *actor2 = _engine->_scene->getActor(actorIdx);
+	const uint8 *spritePtr = _engine->_resources->spriteTable[actor2->entity];
 
-			int32 spriteWidth, spriteHeight;
-			_engine->_grid->getSpriteSize(0, &spriteWidth, &spriteHeight, spritePtr);
+	// get actor position on screen
+	_engine->_renderer->projectPositionOnScreen(actor2->x - _engine->_grid->cameraX, actor2->y - _engine->_grid->cameraY, actor2->z - _engine->_grid->cameraZ);
 
-			// calculate sprite position on screen
-			Common::MemoryReadStream stream(_engine->_resources->spriteBoundingBoxPtr, _engine->_resources->spriteBoundingBoxSize);
-			stream.seek(actor2->entity * 16);
-			renderRect.left = _engine->_renderer->projPosX + stream.readSint16LE();
-			renderRect.top = _engine->_renderer->projPosY + stream.readSint16LE();
-			renderRect.right = renderRect.left + spriteWidth;
-			renderRect.bottom = renderRect.top + spriteHeight;
+	int32 spriteWidth, spriteHeight;
+	_engine->_grid->getSpriteSize(0, &spriteWidth, &spriteHeight, spritePtr);
 
-			if (actor2->staticFlags.bUsesClipping) {
-				const Common::Rect rect(_engine->_renderer->projPosXScreen + actor2->cropLeft, _engine->_renderer->projPosYScreen + actor2->cropTop, _engine->_renderer->projPosXScreen + actor2->cropRight, _engine->_renderer->projPosYScreen + actor2->cropBottom);
-				_engine->_interface->setClip(rect);
-			} else {
-				_engine->_interface->setClip(renderRect);
-			}
+	// calculate sprite position on screen
+	Common::MemoryReadStream stream(_engine->_resources->spriteBoundingBoxPtr, _engine->_resources->spriteBoundingBoxSize);
+	stream.seek(actor2->entity * 16);
+	renderRect.left = _engine->_renderer->projPosX + stream.readSint16LE();
+	renderRect.top = _engine->_renderer->projPosY + stream.readSint16LE();
+	renderRect.right = renderRect.left + spriteWidth;
+	renderRect.bottom = renderRect.top + spriteHeight;
+
+	if (actor2->staticFlags.bUsesClipping) {
+		const Common::Rect rect(_engine->_renderer->projPosXScreen + actor2->cropLeft, _engine->_renderer->projPosYScreen + actor2->cropTop, _engine->_renderer->projPosXScreen + actor2->cropRight, _engine->_renderer->projPosYScreen + actor2->cropBottom);
+		_engine->_interface->setClip(rect);
+	} else {
+		_engine->_interface->setClip(renderRect);
+	}
 
-			if (_engine->_interface->textWindow.left <= _engine->_interface->textWindow.right && _engine->_interface->textWindow.top <= _engine->_interface->textWindow.bottom) {
-				_engine->_grid->drawSprite(0, renderRect.left, renderRect.top, spritePtr);
+	if (_engine->_interface->textWindow.left <= _engine->_interface->textWindow.right && _engine->_interface->textWindow.top <= _engine->_interface->textWindow.bottom) {
+		_engine->_grid->drawSprite(0, renderRect.left, renderRect.top, spritePtr);
 
-				actor2->dynamicFlags.bIsVisible = 1;
+		actor2->dynamicFlags.bIsVisible = 1;
 
-				if (actor2->staticFlags.bUsesClipping) {
-					const int32 tmpX = (actor2->lastX + 0x100) >> 9;
-					const int32 tmpY = actor2->lastY >> 8;
-					const int32 tmpZ = (actor2->lastZ + 0x100) >> 9;
-					_engine->_grid->drawOverSpriteActor(tmpX, tmpY, tmpZ);
-				} else {
-					const int32 tmpX = (actor2->x + actor2->boudingBox.x.topRight + 0x100) >> 9;
-					int32 tmpY = actor2->y >> 8;
-					const int32 tmpZ = (actor2->z + actor2->boudingBox.z.topRight + 0x100) >> 9;
-					if (actor2->brickShape() != ShapeType::kNone) {
-						tmpY++;
-					}
-
-					_engine->_grid->drawOverSpriteActor(tmpX, tmpY, tmpZ);
-				}
+		if (actor2->staticFlags.bUsesClipping) {
+			const int32 tmpX = (actor2->lastX + 0x100) >> 9;
+			const int32 tmpY = actor2->lastY >> 8;
+			const int32 tmpZ = (actor2->lastZ + 0x100) >> 9;
+			_engine->_grid->drawOverSpriteActor(tmpX, tmpY, tmpZ);
+		} else {
+			const int32 tmpX = (actor2->x + actor2->boudingBox.x.topRight + 0x100) >> 9;
+			int32 tmpY = actor2->y >> 8;
+			const int32 tmpZ = (actor2->z + actor2->boudingBox.z.topRight + 0x100) >> 9;
+			if (actor2->brickShape() != ShapeType::kNone) {
+				tmpY++;
+			}
 
-				addRedrawArea(_engine->_interface->textWindow);
+			_engine->_grid->drawOverSpriteActor(tmpX, tmpY, tmpZ);
+		}
 
-				if (actor2->staticFlags.bIsBackgrounded && bgRedraw) {
-					_engine->_interface->blitBox(_engine->_interface->textWindow, _engine->frontVideoBuffer, _engine->workVideoBuffer);
-				}
+		addRedrawArea(_engine->_interface->textWindow);
 
-				// show clipping area
-				//drawBox(renderRect.left, renderRect.top, renderRect.right, renderRect.bottom);
-			}
+		if (actor2->staticFlags.bIsBackgrounded && bgRedraw) {
+			_engine->_interface->blitBox(_engine->_interface->textWindow, _engine->frontVideoBuffer, _engine->workVideoBuffer);
 		}
-		// Drawing extras
-		else if (flags == DrawListType::DrawExtras) {
-			ExtraListStruct *extra = &_engine->_extra->extraList[actorIdx];
 
-			_engine->_renderer->projectPositionOnScreen(extra->x - _engine->_grid->cameraX, extra->y - _engine->_grid->cameraY, extra->z - _engine->_grid->cameraZ);
+		// show clipping area
+		//drawBox(renderRect.left, renderRect.top, renderRect.right, renderRect.bottom);
+	}
+}
 
-			if (extra->info0 & 0x8000) {
-				_engine->_extra->drawExtraSpecial(actorIdx, _engine->_renderer->projPosX, _engine->_renderer->projPosY);
-			} else {
-				int32 spriteWidth, spriteHeight;
-				_engine->_grid->getSpriteSize(0, &spriteWidth, &spriteHeight, _engine->_resources->spriteTable[extra->info0]);
+void Redraw::processDrawListExtras(const DrawListStruct& drawCmd) {
+	int32 actorIdx = drawCmd.actorIdx;
+	ExtraListStruct *extra = &_engine->_extra->extraList[actorIdx];
 
-				// calculate sprite position on screen
-				Common::MemoryReadStream stream(_engine->_resources->spriteBoundingBoxPtr, _engine->_resources->spriteBoundingBoxSize);
-				stream.seek(extra->info0 * 16);
-				renderRect.left = _engine->_renderer->projPosX + stream.readSint16LE();
-				renderRect.top = _engine->_renderer->projPosY + stream.readSint16LE();
-				renderRect.right = renderRect.left + spriteWidth;
-				renderRect.bottom = renderRect.top + spriteHeight;
+	_engine->_renderer->projectPositionOnScreen(extra->x - _engine->_grid->cameraX, extra->y - _engine->_grid->cameraY, extra->z - _engine->_grid->cameraZ);
 
-				_engine->_grid->drawSprite(0, renderRect.left, renderRect.top, _engine->_resources->spriteTable[extra->info0]);
-			}
+	if (extra->info0 & 0x8000) {
+		_engine->_extra->drawExtraSpecial(actorIdx, _engine->_renderer->projPosX, _engine->_renderer->projPosY);
+	} else {
+		int32 spriteWidth, spriteHeight;
+		_engine->_grid->getSpriteSize(0, &spriteWidth, &spriteHeight, _engine->_resources->spriteTable[extra->info0]);
+
+		// calculate sprite position on screen
+		Common::MemoryReadStream stream(_engine->_resources->spriteBoundingBoxPtr, _engine->_resources->spriteBoundingBoxSize);
+		stream.seek(extra->info0 * 16);
+		renderRect.left = _engine->_renderer->projPosX + stream.readSint16LE();
+		renderRect.top = _engine->_renderer->projPosY + stream.readSint16LE();
+		renderRect.right = renderRect.left + spriteWidth;
+		renderRect.bottom = renderRect.top + spriteHeight;
+
+		_engine->_grid->drawSprite(0, renderRect.left, renderRect.top, _engine->_resources->spriteTable[extra->info0]);
+	}
 
-			_engine->_interface->setClip(renderRect);
+	_engine->_interface->setClip(renderRect);
 
-			if (_engine->_interface->textWindow.left <= _engine->_interface->textWindow.right && _engine->_interface->textWindow.top <= _engine->_interface->textWindow.bottom) {
-				const int32 tmpX = (drawList[pos].x + 0x100) >> 9;
-				const int32 tmpY = drawList[pos].y >> 8;
-				const int32 tmpZ = (drawList[pos].z + 0x100) >> 9;
+	if (_engine->_interface->textWindow.left <= _engine->_interface->textWindow.right && _engine->_interface->textWindow.top <= _engine->_interface->textWindow.bottom) {
+		const int32 tmpX = (drawCmd.x + 0x100) >> 9;
+		const int32 tmpY = drawCmd.y >> 8;
+		const int32 tmpZ = (drawCmd.z + 0x100) >> 9;
 
-				_engine->_grid->drawOverModelActor(tmpX, tmpY, tmpZ);
-				addRedrawArea(_engine->_interface->textWindow.left, _engine->_interface->textWindow.top, renderRect.right, renderRect.bottom);
+		_engine->_grid->drawOverModelActor(tmpX, tmpY, tmpZ);
+		addRedrawArea(_engine->_interface->textWindow.left, _engine->_interface->textWindow.top, renderRect.right, renderRect.bottom);
 
-				// show clipping area
-				//drawBox(renderRect);
+		// show clipping area
+		//drawBox(renderRect);
+	}
+}
+
+void Redraw::processDrawList(int32 drawListPos, bool bgRedraw) {
+	for (int32 pos = 0; pos < drawListPos; ++pos) {
+		const DrawListStruct& drawCmd = drawList[pos];
+		const uint32 flags = drawCmd.type;
+		// Drawing actors
+		if (flags < DrawListType::DrawShadows) {
+			if (flags == 0) {
+				processDrawListActors(drawCmd, bgRedraw);
 			}
 		}
+		// Drawing shadows
+		else if (flags == DrawListType::DrawShadows && !_engine->_actor->cropBottomScreen) {
+			processDrawListShadows(drawCmd);
+		}
+		// Drawing unknown
+		else if (flags < DrawListType::DrawActorSprites) {
+			// TODO reverse this part of the code
+			warning("Not yet reversed part of the rendering code");
+		}
+		// Drawing sprite actors, doors and entities
+		else if (flags == DrawListType::DrawActorSprites) {
+			processDrawListActorSprites(drawCmd, bgRedraw);
+		}
+		// Drawing extras
+		else if (flags == DrawListType::DrawExtras) {
+			processDrawListExtras(drawCmd);
+		}
 
 		_engine->_interface->resetClip();
-		pos++;
-	} while (pos < drawListPos);
+	}
 }
 
 void Redraw::renderOverlays() {
diff --git a/engines/twine/redraw.h b/engines/twine/redraw.h
index 3b36204126..f5f36a53d4 100644
--- a/engines/twine/redraw.h
+++ b/engines/twine/redraw.h
@@ -102,6 +102,11 @@ private:
 	void sortDrawingList(DrawListStruct *list, int32 listSize);
 	void updateOverlayTypePosition(int16 x1, int16 y1, int16 x2, int16 y2);
 
+	void processDrawListShadows(const DrawListStruct& drawCmd);
+	void processDrawListActors(const DrawListStruct& drawCmd, bool bgRedraw);
+	void processDrawListActorSprites(const DrawListStruct& drawCmd, bool bgRedraw);
+	void processDrawListExtras(const DrawListStruct& drawCmd);
+
 	int32 processActorDrawingList(bool bgRedraw);
 	int32 processExtraDrawingList(int32 drawListPos);
 	void processDrawList(int32 drawListPos, bool bgRedraw);


Commit: c7e3309b590ae8be9a6ddfab45187396ce18ef5c
    https://github.com/scummvm/scummvm/commit/c7e3309b590ae8be9a6ddfab45187396ce18ef5c
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: renamed methods

Changed paths:
    engines/twine/redraw.cpp
    engines/twine/redraw.h


diff --git a/engines/twine/redraw.cpp b/engines/twine/redraw.cpp
index 4dd42382b3..4101794c50 100644
--- a/engines/twine/redraw.cpp
+++ b/engines/twine/redraw.cpp
@@ -204,7 +204,7 @@ void Redraw::updateOverlayTypePosition(int16 x1, int16 y1, int16 x2, int16 y2) {
 	}
 }
 
-int32 Redraw::processActorDrawingList(bool bgRedraw) {
+int32 Redraw::fillActorDrawingList(bool bgRedraw) {
 	int32 drawListPos = 0;
 	for (int32 modelActorPos = 0; modelActorPos < _engine->_scene->sceneNumActors; modelActorPos++) {
 		ActorStruct *actor = _engine->_scene->getActor(modelActorPos);
@@ -282,7 +282,7 @@ int32 Redraw::processActorDrawingList(bool bgRedraw) {
 	return drawListPos;
 }
 
-int32 Redraw::processExtraDrawingList(int32 drawListPos) {
+int32 Redraw::fillExtraDrawingList(int32 drawListPos) {
 	for (int32 i = 0; i < EXTRA_MAX_ENTRIES; i++) {
 		ExtraListStruct *extra = &_engine->_extra->extraList[i];
 		if (extra->info0 == -1) {
@@ -720,8 +720,8 @@ void Redraw::redrawEngineActions(bool bgRedraw) {
 		blitBackgroundAreas();
 	}
 
-	int32 drawListPos = processActorDrawingList(bgRedraw);
-	drawListPos = processExtraDrawingList(drawListPos);
+	int32 drawListPos = fillActorDrawingList(bgRedraw);
+	drawListPos = fillExtraDrawingList(drawListPos);
 	sortDrawingList(drawList, drawListPos);
 
 	currNumOfRedrawBox = 0;
diff --git a/engines/twine/redraw.h b/engines/twine/redraw.h
index f5f36a53d4..d25d679477 100644
--- a/engines/twine/redraw.h
+++ b/engines/twine/redraw.h
@@ -107,8 +107,8 @@ private:
 	void processDrawListActorSprites(const DrawListStruct& drawCmd, bool bgRedraw);
 	void processDrawListExtras(const DrawListStruct& drawCmd);
 
-	int32 processActorDrawingList(bool bgRedraw);
-	int32 processExtraDrawingList(int32 drawListPos);
+	int32 fillActorDrawingList(bool bgRedraw);
+	int32 fillExtraDrawingList(int32 drawListPos);
 	void processDrawList(int32 drawListPos, bool bgRedraw);
 	void renderOverlays();
 


Commit: f9cce28c826bb142104fa3ec824af5aa8f766da5
    https://github.com/scummvm/scummvm/commit/f9cce28c826bb142104fa3ec824af5aa8f766da5
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: reduced cyclic complexity and extract to local vars

Changed paths:
    engines/twine/redraw.cpp
    engines/twine/renderer.cpp
    engines/twine/renderer.h


diff --git a/engines/twine/redraw.cpp b/engines/twine/redraw.cpp
index 4101794c50..970e012f40 100644
--- a/engines/twine/redraw.cpp
+++ b/engines/twine/redraw.cpp
@@ -232,7 +232,7 @@ int32 Redraw::fillActorDrawingList(bool bgRedraw) {
 		_engine->_renderer->projectPositionOnScreen(actor->x - _engine->_grid->cameraX, actor->y - _engine->_grid->cameraY, actor->z - _engine->_grid->cameraZ);
 
 		if ((actor->staticFlags.bUsesClipping && _engine->_renderer->projPosX > -112 && _engine->_renderer->projPosX < SCREEN_WIDTH + 112 && _engine->_renderer->projPosY > -50 && _engine->_renderer->projPosY < SCREEN_HEIGHT + 171) ||
-			((!actor->staticFlags.bUsesClipping) && _engine->_renderer->projPosX > -50 && _engine->_renderer->projPosX < SCREEN_WIDTH + 40 && _engine->_renderer->projPosY > -30 && _engine->_renderer->projPosY < SCREEN_HEIGHT + 100)) {
+		    ((!actor->staticFlags.bUsesClipping) && _engine->_renderer->projPosX > -50 && _engine->_renderer->projPosX < SCREEN_WIDTH + 40 && _engine->_renderer->projPosY > -30 && _engine->_renderer->projPosY < SCREEN_HEIGHT + 100)) {
 
 			int32 tmpVal = actor->z + actor->x - _engine->_grid->cameraX - _engine->_grid->cameraZ;
 
@@ -323,7 +323,7 @@ int32 Redraw::fillExtraDrawingList(int32 drawListPos) {
 	return drawListPos;
 }
 
-void Redraw::processDrawListShadows(const DrawListStruct& drawCmd) {
+void Redraw::processDrawListShadows(const DrawListStruct &drawCmd) {
 	// get actor position on screen
 	_engine->_renderer->projectPositionOnScreen(drawCmd.x - _engine->_grid->cameraX, drawCmd.y - _engine->_grid->cameraY, drawCmd.z - _engine->_grid->cameraZ);
 
@@ -354,57 +354,62 @@ void Redraw::processDrawListShadows(const DrawListStruct& drawCmd) {
 	//drawBox(_engine->_renderer->renderRect.left, _engine->_renderer->renderRect.top, _engine->_renderer->renderRect.right, _engine->_renderer->renderRect.bottom);
 }
 
-void Redraw::processDrawListActors(const DrawListStruct& drawCmd, bool bgRedraw) {
+void Redraw::processDrawListActors(const DrawListStruct &drawCmd, bool bgRedraw) {
 	int32 actorIdx = drawCmd.actorIdx;
 	ActorStruct *actor2 = _engine->_scene->getActor(actorIdx);
 	_engine->_animations->setModelAnimation(actor2->animPosition, _engine->_resources->animTable[actor2->previousAnimIdx], _engine->_actor->bodyTable[actor2->entity], &actor2->animTimerData);
 
-	if (!_engine->_renderer->renderIsoModel(actor2->x - _engine->_grid->cameraX, actor2->y - _engine->_grid->cameraY, actor2->z - _engine->_grid->cameraZ, 0, actor2->angle, 0, _engine->_actor->bodyTable[actor2->entity])) {
-		if (renderRect.left < SCREEN_TEXTLIMIT_LEFT) {
-			renderRect.left = SCREEN_TEXTLIMIT_LEFT;
-		}
+	const int32 x = actor2->x - _engine->_grid->cameraX;
+	const int32 y = actor2->y - _engine->_grid->cameraY;
+	const int32 z = actor2->z - _engine->_grid->cameraZ;
+	if (!_engine->_renderer->renderIsoModel(x, y, z, 0, actor2->angle, 0, _engine->_actor->bodyTable[actor2->entity])) {
+		return;
+	}
 
-		if (renderRect.top < SCREEN_TEXTLIMIT_TOP) {
-			renderRect.top = SCREEN_TEXTLIMIT_TOP;
-		}
+	if (renderRect.left < SCREEN_TEXTLIMIT_LEFT) {
+		renderRect.left = SCREEN_TEXTLIMIT_LEFT;
+	}
 
-		if (renderRect.right >= SCREEN_WIDTH) {
-			renderRect.right = SCREEN_TEXTLIMIT_RIGHT;
-		}
+	if (renderRect.top < SCREEN_TEXTLIMIT_TOP) {
+		renderRect.top = SCREEN_TEXTLIMIT_TOP;
+	}
 
-		if (renderRect.bottom >= SCREEN_HEIGHT) {
-			renderRect.bottom = SCREEN_TEXTLIMIT_BOTTOM;
-		}
+	if (renderRect.right >= SCREEN_WIDTH) {
+		renderRect.right = SCREEN_TEXTLIMIT_RIGHT;
+	}
 
-		_engine->_interface->setClip(renderRect);
+	if (renderRect.bottom >= SCREEN_HEIGHT) {
+		renderRect.bottom = SCREEN_TEXTLIMIT_BOTTOM;
+	}
 
-		if (_engine->_interface->textWindow.left <= _engine->_interface->textWindow.right && _engine->_interface->textWindow.top <= _engine->_interface->textWindow.bottom) {
-			actor2->dynamicFlags.bIsVisible = 1;
+	_engine->_interface->setClip(renderRect);
 
-			const int32 tempX = (actor2->x + 0x100) >> 9;
-			int32 tempY = actor2->y >> 8;
-			const int32 tempZ = (actor2->z + 0x100) >> 9;
-			if (actor2->brickShape() != ShapeType::kNone) {
-				tempY++;
-			}
+	if (_engine->_interface->textWindow.left <= _engine->_interface->textWindow.right && _engine->_interface->textWindow.top <= _engine->_interface->textWindow.bottom) {
+		actor2->dynamicFlags.bIsVisible = 1;
 
-			_engine->_grid->drawOverModelActor(tempX, tempY, tempZ);
+		const int32 tempX = (actor2->x + 0x100) >> 9;
+		int32 tempY = actor2->y >> 8;
+		const int32 tempZ = (actor2->z + 0x100) >> 9;
+		if (actor2->brickShape() != ShapeType::kNone) {
+			tempY++;
+		}
 
-			if (_engine->_actor->cropBottomScreen) {
-				renderRect.bottom = _engine->_interface->textWindow.bottom = _engine->_actor->cropBottomScreen + 10;
-			}
+		_engine->_grid->drawOverModelActor(tempX, tempY, tempZ);
 
-			const Common::Rect rect(_engine->_interface->textWindow.left, _engine->_interface->textWindow.top, renderRect.right, renderRect.bottom);
-			addRedrawArea(rect);
+		if (_engine->_actor->cropBottomScreen) {
+			renderRect.bottom = _engine->_interface->textWindow.bottom = _engine->_actor->cropBottomScreen + 10;
+		}
 
-			if (actor2->staticFlags.bIsBackgrounded && bgRedraw) {
-				_engine->_interface->blitBox(rect, _engine->frontVideoBuffer, _engine->workVideoBuffer);
-			}
+		const Common::Rect rect(_engine->_interface->textWindow.left, _engine->_interface->textWindow.top, renderRect.right, renderRect.bottom);
+		addRedrawArea(rect);
+
+		if (actor2->staticFlags.bIsBackgrounded && bgRedraw) {
+			_engine->_interface->blitBox(rect, _engine->frontVideoBuffer, _engine->workVideoBuffer);
 		}
 	}
 }
 
-void Redraw::processDrawListActorSprites(const DrawListStruct& drawCmd, bool bgRedraw) {
+void Redraw::processDrawListActorSprites(const DrawListStruct &drawCmd, bool bgRedraw) {
 	int32 actorIdx = drawCmd.actorIdx;
 	ActorStruct *actor2 = _engine->_scene->getActor(actorIdx);
 	const uint8 *spritePtr = _engine->_resources->spriteTable[actor2->entity];
@@ -462,7 +467,7 @@ void Redraw::processDrawListActorSprites(const DrawListStruct& drawCmd, bool bgR
 	}
 }
 
-void Redraw::processDrawListExtras(const DrawListStruct& drawCmd) {
+void Redraw::processDrawListExtras(const DrawListStruct &drawCmd) {
 	int32 actorIdx = drawCmd.actorIdx;
 	ExtraListStruct *extra = &_engine->_extra->extraList[actorIdx];
 
@@ -502,7 +507,7 @@ void Redraw::processDrawListExtras(const DrawListStruct& drawCmd) {
 
 void Redraw::processDrawList(int32 drawListPos, bool bgRedraw) {
 	for (int32 pos = 0; pos < drawListPos; ++pos) {
-		const DrawListStruct& drawCmd = drawList[pos];
+		const DrawListStruct &drawCmd = drawList[pos];
 		const uint32 flags = drawCmd.type;
 		// Drawing actors
 		if (flags < DrawListType::DrawShadows) {
diff --git a/engines/twine/renderer.cpp b/engines/twine/renderer.cpp
index 3571f690c8..08893231e0 100644
--- a/engines/twine/renderer.cpp
+++ b/engines/twine/renderer.cpp
@@ -1150,7 +1150,7 @@ const Renderer::RenderCommand *Renderer::depthSortRenderCommands(int32 numOfPrim
 	return _renderCmdsSortedByDepth;
 }
 
-int32 Renderer::renderModelElements(int32 numOfPrimitives, const uint8 *polygonPtr, RenderCommand **renderCmds, ModelData *modelData) {
+bool Renderer::renderModelElements(int32 numOfPrimitives, const uint8 *polygonPtr, RenderCommand **renderCmds, ModelData *modelData) {
 	// TODO: proper size
 	Common::MemoryReadStream stream(polygonPtr, 100000);
 
@@ -1164,7 +1164,7 @@ int32 Renderer::renderModelElements(int32 numOfPrimitives, const uint8 *polygonP
 		_engine->_redraw->renderRect.bottom = -1;
 		_engine->_redraw->renderRect.left = -1;
 		_engine->_redraw->renderRect.top = -1;
-		return -1;
+		return false;
 	}
 	const RenderCommand *cmds = depthSortRenderCommands(numOfPrimitives);
 
@@ -1229,10 +1229,10 @@ int32 Renderer::renderModelElements(int32 numOfPrimitives, const uint8 *polygonP
 
 		cmds++;
 	} while (--primitiveCounter);
-	return 0;
+	return true;
 }
 
-int32 Renderer::renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr, RenderCommand *renderCmds) {
+bool Renderer::renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr, RenderCommand *renderCmds) {
 	const int32 numVertices = Model::getNumVertices(bodyPtr);
 	const int32 numBones = Model::getNumBones(bodyPtr);
 
@@ -1449,7 +1449,7 @@ void Renderer::prepareIsoModel(uint8 *bodyPtr) { // loadGfxSub
 	}
 }
 
-int32 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 uint8 *bodyPtr) {
 	renderAngleX = angleX;
 	renderAngleY = angleY;
 	renderAngleZ = angleZ;
@@ -1472,12 +1472,11 @@ int32 Renderer::renderIsoModel(int32 x, int32 y, int32 z, int32 angleX, int32 an
 		renderZ = destZ - baseRotPosZ;
 	}
 
-	if (Model::isAnimated(bodyPtr)) {
-		// restart at the beginning of the renderTable
-		return renderAnimatedModel(&_modelData, bodyPtr, _renderCmds);
+	if (!Model::isAnimated(bodyPtr)) {
+		error("Unsupported unanimated model render!");
 	}
-	error("Unsupported unanimated model render!");
-	return 0;
+	// restart at the beginning of the renderTable
+	return renderAnimatedModel(&_modelData, bodyPtr, _renderCmds);
 }
 
 void Renderer::renderBehaviourModel(const Common::Rect &rect, int32 y, int32 angle, const uint8 *bodyPtr) {
diff --git a/engines/twine/renderer.h b/engines/twine/renderer.h
index ae4dd1dcae..34ef324348 100644
--- a/engines/twine/renderer.h
+++ b/engines/twine/renderer.h
@@ -24,8 +24,8 @@
 #define TWINE_RENDERER_H
 
 #include "common/endian.h"
-#include "common/scummsys.h"
 #include "common/rect.h"
+#include "common/scummsys.h"
 #include "twine/parser/body.h"
 
 #define POLYGONTYPE_FLAT 0
@@ -60,9 +60,9 @@ struct CmdRenderPolygon {
 };
 
 struct Matrix {
-	int32 row1[3] {0, 0, 0};
-	int32 row2[3] {0, 0, 0};
-	int32 row3[3] {0, 0, 0};
+	int32 row1[3]{0, 0, 0};
+	int32 row2[3]{0, 0, 0};
+	int32 row3[3]{0, 0, 0};
 };
 
 struct Model {
@@ -92,68 +92,68 @@ struct Model {
 	int16 maxsz = 0;
 	int16 offsetToData = 0;
 
-	static inline bool isAnimated(const uint8* bodyPtr) {
+	static inline bool isAnimated(const uint8 *bodyPtr) {
 		const int16 bodyHeader = READ_LE_INT16(bodyPtr);
 		return (bodyHeader & 2) != 0;
 	}
 
-	static inline bool isAnimated(const BodyData& bodyPtr) {
+	static inline bool isAnimated(const BodyData &bodyPtr) {
 		return bodyPtr.isAnimated();
 	}
 
-	static uint8* getData(uint8 *bodyPtr) {
+	static uint8 *getData(uint8 *bodyPtr) {
 		return bodyPtr + 0x1A;
 	}
 
-	static const uint8* getData(const uint8 *bodyPtr) {
+	static const uint8 *getData(const uint8 *bodyPtr) {
 		return bodyPtr + 0x1A;
 	}
 
-	static const uint8* getVerticesBaseData(const uint8 *bodyPtr) {
+	static const uint8 *getVerticesBaseData(const uint8 *bodyPtr) {
 		return getData(bodyPtr) + 2;
 	}
 
-	static const Common::Array<BodyVertex>& getVerticesBaseData(const BodyData &bodyPtr) {
+	static const Common::Array<BodyVertex> &getVerticesBaseData(const BodyData &bodyPtr) {
 		return bodyPtr.getVertices();
 	}
 
-	static uint8* getBonesData(uint8 *bodyPtr) {
+	static uint8 *getBonesData(uint8 *bodyPtr) {
 		uint8 *verticesBase = getData(bodyPtr);
 		const int16 numVertices = READ_LE_INT16(verticesBase);
 		return verticesBase + 2 + numVertices * 6;
 	}
 
-	static const uint8* getBonesData(const uint8 *bodyPtr) {
+	static const uint8 *getBonesData(const uint8 *bodyPtr) {
 		const uint8 *verticesBase = getData(bodyPtr);
 		const int16 numVertices = READ_LE_INT16(verticesBase);
 		return verticesBase + 2 + numVertices * 6;
 	}
 
-	static const uint8* getBonesStateData(const uint8 *bodyPtr, int boneIdx) {
+	static const uint8 *getBonesStateData(const uint8 *bodyPtr, int boneIdx) {
 		return getBonesBaseData(bodyPtr) + 8 + (boneIdx * 38);
 	}
 
-	static uint8* getBonesStateData(uint8 *bodyPtr, int boneIdx) {
+	static uint8 *getBonesStateData(uint8 *bodyPtr, int boneIdx) {
 		return getBonesBaseData(bodyPtr) + 8 + (boneIdx * 38);
 	}
 
-	static BoneFrame* getBonesStateData(BodyData &bodyPtr, int boneIdx) {
+	static BoneFrame *getBonesStateData(BodyData &bodyPtr, int boneIdx) {
 		return bodyPtr.getBoneState(boneIdx);
 	}
 
-	static const BoneFrame* getBonesStateData(const BodyData &bodyPtr, int boneIdx) {
+	static const BoneFrame *getBonesStateData(const BodyData &bodyPtr, int boneIdx) {
 		return bodyPtr.getBoneState(boneIdx);
 	}
 
-	static uint8* getBonesBaseData(uint8 *bodyPtr) {
+	static uint8 *getBonesBaseData(uint8 *bodyPtr) {
 		return getBonesData(bodyPtr) + 2;
 	}
 
-	static const uint8* getBonesBaseData(const uint8 *bodyPtr, int boneIdx = 0) {
+	static const uint8 *getBonesBaseData(const uint8 *bodyPtr, int boneIdx = 0) {
 		return getBonesData(bodyPtr) + 2 + (boneIdx * 38);
 	}
 
-	static const BoneFrame* getBonesBaseData(const BodyData &bodyPtr, int boneIdx = 0) {
+	static const BoneFrame *getBonesBaseData(const BodyData &bodyPtr, int boneIdx = 0) {
 		return bodyPtr.getBoneState(boneIdx);
 	}
 
@@ -177,21 +177,21 @@ struct Model {
 		return bodyPtr.getNumVertices();
 	}
 
-	static uint8* getShadesData(uint8 *bodyPtr) {
+	static uint8 *getShadesData(uint8 *bodyPtr) {
 		uint8 *bonesBase = getBonesBaseData(bodyPtr);
 		const int16 numBones = getNumBones(bodyPtr);
 		return bonesBase + numBones * 38;
 	}
 
-	static const uint8* getShadesBaseData(const uint8 *bodyPtr, int16 shadeIdx = 0) {
+	static const uint8 *getShadesBaseData(const uint8 *bodyPtr, int16 shadeIdx = 0) {
 		return getShadesData(bodyPtr) + 2 + (shadeIdx * 8);
 	}
 
-	static const BodyShade* getShadesBaseData(const BodyData &bodyPtr, int16 shadeIdx = 0) {
+	static const BodyShade *getShadesBaseData(const BodyData &bodyPtr, int16 shadeIdx = 0) {
 		return bodyPtr.getShade(shadeIdx);
 	}
 
-	static const uint8* getShadesData(const uint8 *bodyPtr) {
+	static const uint8 *getShadesData(const uint8 *bodyPtr) {
 		const uint8 *bonesBase = getBonesBaseData(bodyPtr);
 		const int16 numBones = getNumBones(bodyPtr);
 		return bonesBase + numBones * 38;
@@ -211,12 +211,12 @@ struct Model {
 		return READ_LE_INT16(bonesBase + (boneIdx * 38) + 18);
 	}
 
-	static int16 getNumShadesBone(const BodyData& bodyPtr, int boneIdx) {
+	static int16 getNumShadesBone(const BodyData &bodyPtr, int boneIdx) {
 		return bodyPtr.getBone(boneIdx)->numOfShades;
 	}
 
-	static const uint8* getPolygonData(const uint8 *bodyPtr) {
-		const uint8* shades = getShadesBaseData(bodyPtr);
+	static const uint8 *getPolygonData(const uint8 *bodyPtr) {
+		const uint8 *shades = getShadesBaseData(bodyPtr);
 		const int16 numShades = getNumShades(bodyPtr);
 		if (numShades <= 0) {
 			return shades;
@@ -278,13 +278,13 @@ private:
 		int16 radius = 0;
 	};
 
-	#include "common/pack-start.h"
+#include "common/pack-start.h"
 	struct pointTab {
 		int16 x = 0;
 		int16 y = 0;
 		int16 z = 0;
 	};
-	#include "common/pack-end.h"
+#include "common/pack-end.h"
 	static_assert(sizeof(pointTab) == 6, "Unexpected pointTab size");
 
 	struct polyVertexHeader {
@@ -295,14 +295,14 @@ private:
 	struct ModelData {
 		pointTab computedPoints[800];
 		pointTab flattenPoints[800];
-		int16 shadeTable[500] {0};
+		int16 shadeTable[500]{0};
 	};
 
 	ModelData _modelData;
 
-	int32 renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr, RenderCommand *renderCmds);
+	bool renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr, RenderCommand *renderCmds);
 	void circleFill(int32 x, int32 y, int32 radius, uint8 color);
-	int32 renderModelElements(int32 numOfPrimitives, const uint8 *polygonPtr, RenderCommand** renderCmds, ModelData *modelData);
+	bool renderModelElements(int32 numOfPrimitives, const uint8 *polygonPtr, RenderCommand **renderCmds, ModelData *modelData);
 	void getBaseRotationPosition(int32 x, int32 y, int32 z);
 	void getCameraAnglePositions(int32 x, int32 y, int32 z);
 	void applyRotation(Matrix *targetMatrix, const Matrix *currentMatrix);
@@ -347,10 +347,10 @@ private:
 
 	RenderCommand _renderCmds[1000];
 	RenderCommand _renderCmdsSortedByDepth[1000];
-	uint8 renderCoordinatesBuffer[10000] {0};
+	uint8 renderCoordinatesBuffer[10000]{0};
 
-	int16 polyTab[960] {0};
-	int16 polyTab2[960] {0};
+	int16 polyTab[960]{0};
+	int16 polyTab2[960]{0};
 	// end render polygon vars
 
 	bool isUsingOrhoProjection = false;
@@ -368,9 +368,9 @@ private:
 	void computePolygons(int16 polyRenderType, Vertex *vertices, int32 numVertices, int &vleft, int &vright, int &vtop, int &vbottom);
 
 	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(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);
 
 public:
 	Renderer(TwinEEngine *engine);
@@ -390,9 +390,9 @@ public:
 	int32 destY = 0;
 	int32 destZ = 0;
 
-	const int16 * const shadeAngleTab3;
+	const int16 *const shadeAngleTab3;
 
-	int16 vertexCoordinates[193] {0};
+	int16 vertexCoordinates[193]{0};
 
 	void setLightVector(int32 angleX, int32 angleY, int32 angleZ);
 
@@ -406,7 +406,7 @@ public:
 	void setBaseRotation(int32 x, int32 y, int32 z);
 	void setOrthoProjection(int32 x, int32 y, int32 z);
 
-	int32 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 uint8 *bodyPtr);
 
 	void renderBehaviourModel(int32 boxLeft, int32 boxTop, int32 boxRight, int32 boxBottom, int32 y, int32 angle, const uint8 *bodyPtr);
 	void renderBehaviourModel(const Common::Rect &rect, int32 y, int32 angle, const uint8 *bodyPtr);


Commit: 506f236eef9cd4d4f9a81c6ef15413216da4448c
    https://github.com/scummvm/scummvm/commit/506f236eef9cd4d4f9a81c6ef15413216da4448c
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: format the code

Changed paths:
    engines/twine/parser/body.cpp
    engines/twine/parser/body.h
    engines/twine/renderer.cpp
    engines/twine/renderer.h


diff --git a/engines/twine/parser/body.cpp b/engines/twine/parser/body.cpp
index 2cd48e8d9d..c97882ab84 100644
--- a/engines/twine/parser/body.cpp
+++ b/engines/twine/parser/body.cpp
@@ -99,17 +99,20 @@ void BodyData::loadPolygons(Common::SeekableReadStream &stream) {
 		const int8 numVertex = stream.readSByte();
 
 		poly.color = stream.readUint16LE();
+		int16 intensity = -1;
 		if (poly.renderType >= 7 && poly.renderType < 9) {
-			poly.intensity = stream.readSint16LE();
+			intensity = stream.readSint16LE();
 		}
 
-		// TODO: this is not yet correct
 		poly.indices.reserve(numVertex);
+		poly.intensities.reserve(numVertex);
 		for (int k = 0; k < numVertex; ++k) {
 			if (poly.renderType >= 9) {
-				poly.intensity = stream.readSint16LE();
+				intensity = stream.readSint16LE();
 			}
-			poly.indices.push_back(stream.readUint16LE() / 6);
+			const uint16 vertexIndex = stream.readUint16LE() / 6;
+			poly.indices.push_back(vertexIndex);
+			poly.intensities.push_back(intensity);
 		}
 
 		_polygons.push_back(poly);
diff --git a/engines/twine/parser/body.h b/engines/twine/parser/body.h
index 5b16495a63..ed6d942356 100644
--- a/engines/twine/parser/body.h
+++ b/engines/twine/parser/body.h
@@ -54,7 +54,7 @@ struct BodyShade {
 
 struct BodyPolygon {
 	Common::Array<uint16> indices;
-	int16 intensity = 0;
+	Common::Array<uint16> intensities;
 	int8 renderType = 0;
 	uint16 color = 0;
 };
diff --git a/engines/twine/renderer.cpp b/engines/twine/renderer.cpp
index 08893231e0..e7a5fe70c1 100644
--- a/engines/twine/renderer.cpp
+++ b/engines/twine/renderer.cpp
@@ -360,9 +360,9 @@ void Renderer::setLightVector(int32 angleX, int32 angleY, int32 angleZ) {
 	applyRotation(&shadeMatrix, &baseMatrix);
 	translateGroup(0, 0, 59);
 
-	lightX = destX;
-	lightY = destY;
-	lightZ = destZ;
+	lightPos.x = destX;
+	lightPos.y = destY;
+	lightPos.z = destZ;
 }
 
 FORCEINLINE int16 clamp(int16 x, int16 a, int16 b) {
@@ -1375,17 +1375,7 @@ bool Renderer::renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr, R
 			if (numOfShades) {
 				int32 numShades = numOfShades;
 
-				shadeMatrix.row1[0] = lightMatrix->row1[0] * lightX;
-				shadeMatrix.row1[1] = lightMatrix->row1[1] * lightX;
-				shadeMatrix.row1[2] = lightMatrix->row1[2] * lightX;
-
-				shadeMatrix.row2[0] = lightMatrix->row2[0] * lightY;
-				shadeMatrix.row2[1] = lightMatrix->row2[1] * lightY;
-				shadeMatrix.row2[2] = lightMatrix->row2[2] * lightY;
-
-				shadeMatrix.row3[0] = lightMatrix->row3[0] * lightZ;
-				shadeMatrix.row3[1] = lightMatrix->row3[1] * lightZ;
-				shadeMatrix.row3[2] = lightMatrix->row3[2] * lightZ;
+				shadeMatrix = *lightMatrix * lightPos;
 
 				do { // for each normal
 					const uint8 *shadePtr = Model::getShadesBaseData(bodyPtr, shadeIndex);
diff --git a/engines/twine/renderer.h b/engines/twine/renderer.h
index 34ef324348..9aa5aab8c9 100644
--- a/engines/twine/renderer.h
+++ b/engines/twine/renderer.h
@@ -59,12 +59,34 @@ struct CmdRenderPolygon {
 	// followed by Vertex array
 };
 
+struct Vec3 {
+	int32 x = 0;
+	int32 y = 0;
+	int32 z = 0;
+};
+
 struct Matrix {
 	int32 row1[3]{0, 0, 0};
 	int32 row2[3]{0, 0, 0};
 	int32 row3[3]{0, 0, 0};
 };
 
+inline Matrix operator*(const Matrix &matrix, const Vec3 &vec) {
+	Matrix out;
+	out.row1[0] = matrix.row1[0] * vec.x;
+	out.row1[1] = matrix.row1[1] * vec.x;
+	out.row1[2] = matrix.row1[2] * vec.x;
+
+	out.row2[0] = matrix.row2[0] * vec.y;
+	out.row2[1] = matrix.row2[1] * vec.y;
+	out.row2[2] = matrix.row2[2] * vec.y;
+
+	out.row3[0] = matrix.row3[0] * vec.z;
+	out.row3[1] = matrix.row3[1] * vec.z;
+	out.row3[2] = matrix.row3[2] * vec.z;
+	return out;
+}
+
 struct Model {
 	struct BodyFlags {
 		uint16 unk1 : 1;            // 1 << 0
@@ -341,9 +363,7 @@ private:
 	Matrix baseMatrix;
 	Matrix matricesTable[30 + 1];
 	Matrix shadeMatrix;
-	int32 lightX = 0;
-	int32 lightY = 0;
-	int32 lightZ = 0;
+	Vec3 lightPos;
 
 	RenderCommand _renderCmds[1000];
 	RenderCommand _renderCmdsSortedByDepth[1000];


Commit: 97dbec8cab2590ca1cd8302f2964ea1006591778
    https://github.com/scummvm/scummvm/commit/97dbec8cab2590ca1cd8302f2964ea1006591778
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: reduced code duplication

Changed paths:
    engines/twine/actor.cpp
    engines/twine/actor.h


diff --git a/engines/twine/actor.cpp b/engines/twine/actor.cpp
index fc569dc10f..2eea245dbc 100644
--- a/engines/twine/actor.cpp
+++ b/engines/twine/actor.cpp
@@ -81,62 +81,27 @@ void Actor::restartHeroScene() {
 	cropBottomScreen = 0;
 }
 
-void Actor::loadHeroEntities() {
-	ActorStruct *sceneHero = _engine->_scene->sceneHero;
-	heroEntityATHLETICSize = HQR::getAllocEntry(&heroEntityATHLETIC, Resources::HQR_FILE3D_FILE, FILE3DHQR_HEROATHLETIC);
-	if (heroEntityATHLETICSize == 0) {
-		error("Failed to load actor athletic 3d data");
-	}
-	sceneHero->entityDataPtr = heroEntityATHLETIC;
-	sceneHero->entityDataSize = heroEntityATHLETICSize;
-	heroAnimIdxATHLETIC = _engine->_animations->getBodyAnimIndex(AnimationTypes::kStanding);
-	if (heroAnimIdxATHLETIC == -1) {
-		error("Could not find athletic animation data");
-	}
-
-	heroEntityAGGRESSIVESize = HQR::getAllocEntry(&heroEntityAGGRESSIVE, Resources::HQR_FILE3D_FILE, FILE3DHQR_HEROAGGRESSIVE);
-	if (heroEntityAGGRESSIVESize == 0) {
-		error("Failed to load actor aggressive 3d data");
-	}
-	sceneHero->entityDataPtr = heroEntityAGGRESSIVE;
-	sceneHero->entityDataSize = heroEntityAGGRESSIVESize;
-	heroAnimIdxAGGRESSIVE = _engine->_animations->getBodyAnimIndex(AnimationTypes::kStanding);
-	if (heroAnimIdxAGGRESSIVE == -1) {
-		error("Could not find aggressive animation data");
-	}
-
-	heroEntityDISCRETESize = HQR::getAllocEntry(&heroEntityDISCRETE, Resources::HQR_FILE3D_FILE, FILE3DHQR_HERODISCRETE);
-	if (heroEntityDISCRETESize == 0) {
-		error("Failed to load actor discrete 3d data");
+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) {
+		error("Failed to load actor 3d data for index: %i", index);
 	}
-	sceneHero->entityDataPtr = heroEntityDISCRETE;
-	sceneHero->entityDataSize = heroEntityDISCRETESize;
-	heroAnimIdxDISCRETE = _engine->_animations->getBodyAnimIndex(AnimationTypes::kStanding);
-	if (heroAnimIdxDISCRETE == -1) {
-		error("Could not find discrete animation data");
-	}
-
-	heroEntityPROTOPACKSize = HQR::getAllocEntry(&heroEntityPROTOPACK, Resources::HQR_FILE3D_FILE, FILE3DHQR_HEROPROTOPACK);
-	if (heroEntityPROTOPACKSize == 0) {
-		error("Failed to load actor protopack 3d data");
-	}
-	sceneHero->entityDataPtr = heroEntityPROTOPACK;
-	sceneHero->entityDataSize = heroEntityPROTOPACKSize;
-	heroAnimIdxPROTOPACK = _engine->_animations->getBodyAnimIndex(AnimationTypes::kStanding);
-	if (heroAnimIdxPROTOPACK == -1) {
-		error("Could not find protopack animation data");
+	sceneHero->entityDataPtr = *ptr;
+	sceneHero->entityDataSize = size;
+	bodyAnimIndex = _engine->_animations->getBodyAnimIndex(AnimationTypes::kStanding);
+	if (bodyAnimIndex == -1) {
+		error("Could not find animation data for 3d data with index %i", index);
 	}
+	return size;
+}
 
-	heroEntityNORMALSize = HQR::getAllocEntry(&heroEntityNORMAL, Resources::HQR_FILE3D_FILE, FILE3DHQR_HERONORMAL);
-	if (heroEntityNORMALSize == 0) {
-		error("Failed to load actor normal 3d data");
-	}
-	sceneHero->entityDataPtr = heroEntityNORMAL;
-	sceneHero->entityDataSize = heroEntityNORMALSize;
-	heroAnimIdxNORMAL = _engine->_animations->getBodyAnimIndex(AnimationTypes::kStanding);
-	if (heroAnimIdxNORMAL == -1) {
-		error("Could not find normal animation data");
-	}
+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);
 
 	sceneHero->animExtraPtr = _engine->_animations->currentActorAnimExtraPtr;
 }
diff --git a/engines/twine/actor.h b/engines/twine/actor.h
index 0e4aacd317..6c144e3005 100644
--- a/engines/twine/actor.h
+++ b/engines/twine/actor.h
@@ -266,6 +266,8 @@ private:
 	 */
 	int32 initBody(int32 bodyIdx, int32 actorIdx, ActorBoundingBox &actorBoundingBox);
 
+	int32 loadBehaviourEntity(ActorStruct *sceneHero, uint8 **ptr, int16& bodyAnimIndex, int32 index);
+
 public:
 	Actor(TwinEEngine* engine);
 	~Actor();


Commit: d1aa2e3cb3de38757fe1efa1a9b12d4634f24139
    https://github.com/scummvm/scummvm/commit/d1aa2e3cb3de38757fe1efa1a9b12d4634f24139
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: started to reorganize the folder structure

Changed paths:
  A engines/twine/audio/music.cpp
  A engines/twine/audio/music.h
  A engines/twine/audio/sound.cpp
  A engines/twine/audio/sound.h
  A engines/twine/debugger/console.cpp
  A engines/twine/debugger/console.h
  A engines/twine/debugger/debug.cpp
  A engines/twine/debugger/debug.h
  A engines/twine/debugger/debug_grid.cpp
  A engines/twine/debugger/debug_grid.h
  A engines/twine/debugger/debug_scene.cpp
  A engines/twine/debugger/debug_scene.h
  A engines/twine/menu/interface.cpp
  A engines/twine/menu/interface.h
  A engines/twine/menu/menu.cpp
  A engines/twine/menu/menu.h
  A engines/twine/menu/menuoptions.cpp
  A engines/twine/menu/menuoptions.h
  A engines/twine/renderer/redraw.cpp
  A engines/twine/renderer/redraw.h
  A engines/twine/renderer/renderer.cpp
  A engines/twine/renderer/renderer.h
  A engines/twine/renderer/screens.cpp
  A engines/twine/renderer/screens.h
  A engines/twine/scene/actor.cpp
  A engines/twine/scene/actor.h
  A engines/twine/scene/animations.cpp
  A engines/twine/scene/animations.h
  A engines/twine/scene/collision.cpp
  A engines/twine/scene/collision.h
  A engines/twine/scene/extra.cpp
  A engines/twine/scene/extra.h
  A engines/twine/scene/gamestate.cpp
  A engines/twine/scene/gamestate.h
  A engines/twine/scene/grid.cpp
  A engines/twine/scene/grid.h
  A engines/twine/scene/movements.cpp
  A engines/twine/scene/movements.h
  A engines/twine/scene/scene.cpp
  A engines/twine/scene/scene.h
  A engines/twine/script/script_life_v1.cpp
  A engines/twine/script/script_life_v1.h
  A engines/twine/script/script_move_v1.cpp
  A engines/twine/script/script_move_v1.h
  R engines/twine/actor.cpp
  R engines/twine/actor.h
  R engines/twine/animations.cpp
  R engines/twine/animations.h
  R engines/twine/collision.cpp
  R engines/twine/collision.h
  R engines/twine/console.cpp
  R engines/twine/console.h
  R engines/twine/debug.cpp
  R engines/twine/debug.h
  R engines/twine/debug_grid.cpp
  R engines/twine/debug_grid.h
  R engines/twine/debug_scene.cpp
  R engines/twine/debug_scene.h
  R engines/twine/extra.cpp
  R engines/twine/extra.h
  R engines/twine/gamestate.cpp
  R engines/twine/gamestate.h
  R engines/twine/grid.cpp
  R engines/twine/grid.h
  R engines/twine/interface.cpp
  R engines/twine/interface.h
  R engines/twine/menu.cpp
  R engines/twine/menu.h
  R engines/twine/menuoptions.cpp
  R engines/twine/menuoptions.h
  R engines/twine/movements.cpp
  R engines/twine/movements.h
  R engines/twine/music.cpp
  R engines/twine/music.h
  R engines/twine/redraw.cpp
  R engines/twine/redraw.h
  R engines/twine/renderer.cpp
  R engines/twine/renderer.h
  R engines/twine/scene.cpp
  R engines/twine/scene.h
  R engines/twine/screens.cpp
  R engines/twine/screens.h
  R engines/twine/script_life_v1.cpp
  R engines/twine/script_life_v1.h
  R engines/twine/script_move_v1.cpp
  R engines/twine/script_move_v1.h
  R engines/twine/sound.cpp
  R engines/twine/sound.h
    engines/twine/flamovies.cpp
    engines/twine/holomap.cpp
    engines/twine/input.cpp
    engines/twine/module.mk
    engines/twine/parser/body.cpp
    engines/twine/resources.cpp
    engines/twine/resources.h
    engines/twine/text.cpp
    engines/twine/twine.cpp
    engines/twine/twine.h


diff --git a/engines/twine/music.cpp b/engines/twine/audio/music.cpp
similarity index 99%
rename from engines/twine/music.cpp
rename to engines/twine/audio/music.cpp
index 7f98f6f34c..9e38dc40a1 100644
--- a/engines/twine/music.cpp
+++ b/engines/twine/audio/music.cpp
@@ -20,7 +20,7 @@
  *
  */
 
-#include "twine/music.h"
+#include "twine/audio/music.h"
 #include "audio/midiparser.h"
 #include "audio/midiplayer.h"
 #include "backends/audiocd/audiocd.h"
diff --git a/engines/twine/music.h b/engines/twine/audio/music.h
similarity index 100%
rename from engines/twine/music.h
rename to engines/twine/audio/music.h
diff --git a/engines/twine/sound.cpp b/engines/twine/audio/sound.cpp
similarity index 98%
rename from engines/twine/sound.cpp
rename to engines/twine/audio/sound.cpp
index 98ef6f7890..128b5a8e89 100644
--- a/engines/twine/sound.cpp
+++ b/engines/twine/audio/sound.cpp
@@ -20,18 +20,18 @@
  *
  */
 
-#include "twine/sound.h"
+#include "twine/audio/sound.h"
 #include "audio/audiostream.h"
 #include "audio/decoders/voc.h"
 #include "common/memstream.h"
 #include "common/system.h"
 #include "common/types.h"
 #include "common/util.h"
-#include "twine/collision.h"
+#include "twine/scene/collision.h"
 #include "twine/flamovies.h"
-#include "twine/grid.h"
+#include "twine/scene/grid.h"
 #include "twine/hqr.h"
-#include "twine/movements.h"
+#include "twine/scene/movements.h"
 #include "twine/resources.h"
 #include "twine/text.h"
 #include "twine/twine.h"
diff --git a/engines/twine/sound.h b/engines/twine/audio/sound.h
similarity index 100%
rename from engines/twine/sound.h
rename to engines/twine/audio/sound.h
diff --git a/engines/twine/console.cpp b/engines/twine/debugger/console.cpp
similarity index 91%
rename from engines/twine/console.cpp
rename to engines/twine/debugger/console.cpp
index e7fa51d79e..48bad34ac7 100644
--- a/engines/twine/console.cpp
+++ b/engines/twine/debugger/console.cpp
@@ -20,14 +20,14 @@
  *
  */
 
-#include "twine/console.h"
+#include "twine/debugger/console.h"
 #include "common/scummsys.h"
-#include "twine/twine.h"
-#include "twine/gamestate.h"
-#include "twine/scene.h"
-#include "twine/debug_scene.h"
-#include "twine/debug_grid.h"
+#include "twine/debugger/debug_grid.h"
+#include "twine/debugger/debug_scene.h"
+#include "twine/scene/gamestate.h"
+#include "twine/scene/scene.h"
 #include "twine/text.h"
+#include "twine/twine.h"
 
 namespace TwinE {
 
@@ -50,16 +50,16 @@ TwinEConsole::TwinEConsole(TwinEEngine *engine) : _engine(engine), GUI::Debugger
 TwinEConsole::~TwinEConsole() {
 }
 
-#define TOGGLE_DEBUG(var, description) \
-	if ((var)) { \
+#define TOGGLE_DEBUG(var, description)         \
+	if ((var)) {                               \
 		debugPrintf("Disabling " description); \
-		(var) = false; \
-	} else { \
-		debugPrintf("Enabling " description); \
-		(var) = true; \
-	} \
-	if ((var) && !_engine->cfgfile.Debug) { \
-		doToggleDebug(0, nullptr); \
+		(var) = false;                         \
+	} else {                                   \
+		debugPrintf("Enabling " description);  \
+		(var) = true;                          \
+	}                                          \
+	if ((var) && !_engine->cfgfile.Debug) {    \
+		doToggleDebug(0, nullptr);             \
 	}
 
 bool TwinEConsole::doToggleZoneRendering(int argc, const char **argv) {
diff --git a/engines/twine/console.h b/engines/twine/debugger/console.h
similarity index 98%
rename from engines/twine/console.h
rename to engines/twine/debugger/console.h
index a945a09e3a..fc42b87073 100644
--- a/engines/twine/console.h
+++ b/engines/twine/debugger/console.h
@@ -24,7 +24,7 @@
 #define TWINE_CONSOLE_H
 
 #include "gui/debugger.h"
-#include "twine/gamestate.h"
+#include "twine/scene/gamestate.h"
 
 namespace TwinE {
 
diff --git a/engines/twine/debug.cpp b/engines/twine/debugger/debug.cpp
similarity index 98%
rename from engines/twine/debug.cpp
rename to engines/twine/debugger/debug.cpp
index bc3f1857d3..dd974a3566 100644
--- a/engines/twine/debug.cpp
+++ b/engines/twine/debugger/debug.cpp
@@ -20,16 +20,16 @@
  *
  */
 
-#include "twine/debug.h"
+#include "twine/debugger/debug.h"
 
 #include "common/system.h"
-#include "twine/debug_grid.h"
-#include "twine/debug_scene.h"
-#include "twine/interface.h"
-#include "twine/menu.h"
-#include "twine/redraw.h"
-#include "twine/scene.h"
-#include "twine/screens.h"
+#include "twine/debugger/debug_grid.h"
+#include "twine/debugger/debug_scene.h"
+#include "twine/menu/interface.h"
+#include "twine/menu/menu.h"
+#include "twine/renderer/redraw.h"
+#include "twine/renderer/screens.h"
+#include "twine/scene/scene.h"
 #include "twine/text.h"
 #include "twine/twine.h"
 
diff --git a/engines/twine/debug.h b/engines/twine/debugger/debug.h
similarity index 100%
rename from engines/twine/debug.h
rename to engines/twine/debugger/debug.h
diff --git a/engines/twine/debug_grid.cpp b/engines/twine/debugger/debug_grid.cpp
similarity index 96%
rename from engines/twine/debug_grid.cpp
rename to engines/twine/debugger/debug_grid.cpp
index 896e635b38..0fd1e062ed 100644
--- a/engines/twine/debug_grid.cpp
+++ b/engines/twine/debugger/debug_grid.cpp
@@ -20,12 +20,12 @@
  *
  */
 
-#include "twine/debug_grid.h"
+#include "twine/debugger/debug_grid.h"
 #include "common/debug.h"
-#include "twine/grid.h"
+#include "twine/scene/grid.h"
 #include "twine/input.h"
-#include "twine/redraw.h"
-#include "twine/scene.h"
+#include "twine/renderer/redraw.h"
+#include "twine/scene/scene.h"
 #include "twine/twine.h"
 
 namespace TwinE {
diff --git a/engines/twine/debug_grid.h b/engines/twine/debugger/debug_grid.h
similarity index 100%
rename from engines/twine/debug_grid.h
rename to engines/twine/debugger/debug_grid.h
diff --git a/engines/twine/debug_scene.cpp b/engines/twine/debugger/debug_scene.cpp
similarity index 97%
rename from engines/twine/debug_scene.cpp
rename to engines/twine/debugger/debug_scene.cpp
index 897d8b9735..50fe5b4c49 100644
--- a/engines/twine/debug_scene.cpp
+++ b/engines/twine/debugger/debug_scene.cpp
@@ -20,12 +20,12 @@
  *
  */
 
-#include "twine/debug_scene.h"
-#include "twine/grid.h"
-#include "twine/interface.h"
-#include "twine/redraw.h"
-#include "twine/renderer.h"
-#include "twine/scene.h"
+#include "twine/debugger/debug_scene.h"
+#include "twine/scene/grid.h"
+#include "twine/menu/interface.h"
+#include "twine/renderer/redraw.h"
+#include "twine/renderer/renderer.h"
+#include "twine/scene/scene.h"
 #include "twine/twine.h"
 
 namespace TwinE {
diff --git a/engines/twine/debug_scene.h b/engines/twine/debugger/debug_scene.h
similarity index 100%
rename from engines/twine/debug_scene.h
rename to engines/twine/debugger/debug_scene.h
diff --git a/engines/twine/flamovies.cpp b/engines/twine/flamovies.cpp
index 31ef14cb6c..7241271f61 100644
--- a/engines/twine/flamovies.cpp
+++ b/engines/twine/flamovies.cpp
@@ -23,11 +23,11 @@
 #include "twine/flamovies.h"
 #include "common/file.h"
 #include "common/system.h"
-#include "twine/grid.h"
+#include "twine/audio/music.h"
+#include "twine/audio/sound.h"
+#include "twine/scene/grid.h"
 #include "twine/input.h"
-#include "twine/music.h"
-#include "twine/screens.h"
-#include "twine/sound.h"
+#include "twine/renderer/screens.h"
 #include "twine/twine.h"
 
 namespace TwinE {
@@ -181,7 +181,7 @@ void FlaMovies::processFrame() {
 		return;
 	}
 
-	uint8 *outBuf = (uint8*)_engine->workVideoBuffer.getPixels();
+	uint8 *outBuf = (uint8 *)_engine->workVideoBuffer.getPixels();
 	file.read(outBuf, frameData.frameVar0);
 
 	if ((int32)frameData.videoSize <= 0) {
diff --git a/engines/twine/holomap.cpp b/engines/twine/holomap.cpp
index 46afaa3b50..e857851655 100644
--- a/engines/twine/holomap.cpp
+++ b/engines/twine/holomap.cpp
@@ -23,14 +23,14 @@
 #include "twine/holomap.h"
 #include "common/memstream.h"
 #include "common/types.h"
-#include "twine/gamestate.h"
+#include "twine/audio/sound.h"
+#include "twine/scene/gamestate.h"
 #include "twine/hqr.h"
-#include "twine/interface.h"
-#include "twine/renderer.h"
+#include "twine/menu/interface.h"
+#include "twine/renderer/renderer.h"
+#include "twine/renderer/screens.h"
 #include "twine/resources.h"
-#include "twine/scene.h"
-#include "twine/screens.h"
-#include "twine/sound.h"
+#include "twine/scene/scene.h"
 #include "twine/text.h"
 #include "twine/twine.h"
 
diff --git a/engines/twine/input.cpp b/engines/twine/input.cpp
index e22aa396d3..c66abda894 100644
--- a/engines/twine/input.cpp
+++ b/engines/twine/input.cpp
@@ -25,7 +25,7 @@
 #include "common/events.h"
 #include "common/keyboard.h"
 #include "common/system.h"
-#include "twine/actor.h"
+#include "twine/scene/actor.h"
 #include "twine/twine.h"
 
 namespace TwinE {
diff --git a/engines/twine/interface.cpp b/engines/twine/menu/interface.cpp
similarity index 99%
rename from engines/twine/interface.cpp
rename to engines/twine/menu/interface.cpp
index dea561e8bc..7fe272e01d 100644
--- a/engines/twine/interface.cpp
+++ b/engines/twine/menu/interface.cpp
@@ -20,7 +20,7 @@
  *
  */
 
-#include "twine/interface.h"
+#include "twine/menu/interface.h"
 #include "graphics/managed_surface.h"
 #include "twine/twine.h"
 
diff --git a/engines/twine/interface.h b/engines/twine/menu/interface.h
similarity index 100%
rename from engines/twine/interface.h
rename to engines/twine/menu/interface.h
diff --git a/engines/twine/menu.cpp b/engines/twine/menu/menu.cpp
similarity index 96%
rename from engines/twine/menu.cpp
rename to engines/twine/menu/menu.cpp
index 05e9c38a55..ba4d7f8adc 100644
--- a/engines/twine/menu.cpp
+++ b/engines/twine/menu/menu.cpp
@@ -20,7 +20,7 @@
  *
  */
 
-#include "twine/menu.h"
+#include "twine/menu/menu.h"
 #include "audio/mixer.h"
 #include "backends/audiocd/audiocd.h"
 #include "backends/keymapper/keymapper.h"
@@ -31,22 +31,22 @@
 #include "common/system.h"
 #include "common/util.h"
 #include "graphics/cursorman.h"
-#include "twine/actor.h"
-#include "twine/animations.h"
-#include "twine/gamestate.h"
-#include "twine/grid.h"
+#include "twine/scene/actor.h"
+#include "twine/scene/animations.h"
+#include "twine/audio/music.h"
+#include "twine/audio/sound.h"
+#include "twine/scene/gamestate.h"
+#include "twine/scene/grid.h"
 #include "twine/hqr.h"
 #include "twine/input.h"
-#include "twine/interface.h"
-#include "twine/menuoptions.h"
-#include "twine/movements.h"
-#include "twine/music.h"
-#include "twine/redraw.h"
-#include "twine/renderer.h"
+#include "twine/menu/interface.h"
+#include "twine/menu/menuoptions.h"
+#include "twine/scene/movements.h"
+#include "twine/renderer/redraw.h"
+#include "twine/renderer/renderer.h"
+#include "twine/renderer/screens.h"
 #include "twine/resources.h"
-#include "twine/scene.h"
-#include "twine/screens.h"
-#include "twine/sound.h"
+#include "twine/scene/scene.h"
 #include "twine/text.h"
 #include "twine/twine.h"
 
@@ -70,7 +70,10 @@ enum _MenuButtonTypes {
 };
 }
 
-#define checkMenuQuit(callMenu) if ((callMenu) == kQuitEngine) { return kQuitEngine; }
+#define checkMenuQuit(callMenu)      \
+	if ((callMenu) == kQuitEngine) { \
+		return kQuitEngine;          \
+	}
 #define kBackground 9999
 
 namespace _priv {
@@ -670,16 +673,13 @@ int32 Menu::optionsMenu() {
 			return 0;
 		}
 		case TextId::kVolumeSettings: {
-			checkMenuQuit(volumeMenu())
-			break;
+			checkMenuQuit(volumeMenu()) break;
 		}
 		case TextId::kSaveManage: {
-			checkMenuQuit(savemanageMenu())
-			break;
+			checkMenuQuit(savemanageMenu()) break;
 		}
 		case TextId::kAdvanced: {
-			checkMenuQuit(advoptionsMenu())
-			break;
+			checkMenuQuit(advoptionsMenu()) break;
 		}
 		case kQuitEngine:
 			return kQuitEngine;
@@ -692,28 +692,26 @@ int32 Menu::optionsMenu() {
 }
 
 static const byte cursorArrow[] = {
-	1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-	1, 0, 1, 3, 3, 3, 3, 3, 3, 3, 3,
-	1, 0, 0, 1, 3, 3, 3, 3, 3, 3, 3,
-	1, 0, 0, 0, 1, 3, 3, 3, 3, 3, 3,
-	1, 0, 0, 0, 0, 1, 3, 3, 3, 3, 3,
-	1, 0, 0, 0, 0, 0, 1, 3, 3, 3, 3,
-	1, 0, 0, 0, 0, 0, 0, 1, 3, 3, 3,
-	1, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3,
-	1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3,
-	1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
-	1, 0, 0, 1, 0, 0, 1, 3, 3, 3, 3,
-	1, 0, 1, 3, 1, 0, 0, 1, 3, 3, 3,
-	1, 1, 3, 3, 1, 0, 0, 1, 3, 3, 3,
-	1, 3, 3, 3, 3, 1, 0, 0, 1, 3, 3,
-	3, 3, 3, 3, 3, 1, 0, 0, 1, 3, 3,
-	3, 3, 3, 3, 3, 3, 1, 1, 1, 3, 3
-};
+    1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    1, 0, 1, 3, 3, 3, 3, 3, 3, 3, 3,
+    1, 0, 0, 1, 3, 3, 3, 3, 3, 3, 3,
+    1, 0, 0, 0, 1, 3, 3, 3, 3, 3, 3,
+    1, 0, 0, 0, 0, 1, 3, 3, 3, 3, 3,
+    1, 0, 0, 0, 0, 0, 1, 3, 3, 3, 3,
+    1, 0, 0, 0, 0, 0, 0, 1, 3, 3, 3,
+    1, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3,
+    1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3,
+    1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
+    1, 0, 0, 1, 0, 0, 1, 3, 3, 3, 3,
+    1, 0, 1, 3, 1, 0, 0, 1, 3, 3, 3,
+    1, 1, 3, 3, 1, 0, 0, 1, 3, 3, 3,
+    1, 3, 3, 3, 3, 1, 0, 0, 1, 3, 3,
+    3, 3, 3, 3, 3, 1, 0, 0, 1, 3, 3,
+    3, 3, 3, 3, 3, 3, 1, 1, 1, 3, 3};
 
 static const byte cursorPalette[] = {
-	0, 0, 0,
-	0xff, 0xff, 0xff
-};
+    0, 0, 0,
+    0xff, 0xff, 0xff};
 
 bool Menu::init() {
 	// load menu effect file only once
@@ -1104,8 +1102,8 @@ void Menu::processInventoryMenu() {
 
 	if (_engine->_gameState->inventoryNumLeafs > 0) {
 		_engine->_gameState->giveItem(InventoryItems::kiCloverLeaf);
-	// TODO: shouldn't this get reset? } else {
-	//	_engine->_gameState->removeItem(InventoryItems::kiCloverLeaf);
+		// TODO: shouldn't this get reset? } else {
+		//	_engine->_gameState->removeItem(InventoryItems::kiCloverLeaf);
 	}
 
 	drawInventoryItems();
diff --git a/engines/twine/menu.h b/engines/twine/menu/menu.h
similarity index 99%
rename from engines/twine/menu.h
rename to engines/twine/menu/menu.h
index d42afb8890..6532d15c1d 100644
--- a/engines/twine/menu.h
+++ b/engines/twine/menu/menu.h
@@ -23,7 +23,7 @@
 #ifndef TWINE_MENU_H
 #define TWINE_MENU_H
 
-#include "twine/actor.h"
+#include "twine/scene/actor.h"
 #include "twine/twine.h"
 #include "twine/text.h"
 
diff --git a/engines/twine/menuoptions.cpp b/engines/twine/menu/menuoptions.cpp
similarity index 96%
rename from engines/twine/menuoptions.cpp
rename to engines/twine/menu/menuoptions.cpp
index 1ea2956901..e36baebc54 100644
--- a/engines/twine/menuoptions.cpp
+++ b/engines/twine/menu/menuoptions.cpp
@@ -20,23 +20,23 @@
  *
  */
 
-#include "twine/menuoptions.h"
+#include "twine/menu/menuoptions.h"
 #include "common/error.h"
 #include "common/keyboard.h"
 #include "common/str-array.h"
 #include "common/system.h"
 #include "common/util.h"
 #include "savestate.h"
+#include "twine/audio/music.h"
+#include "twine/audio/sound.h"
 #include "twine/flamovies.h"
-#include "twine/gamestate.h"
+#include "twine/scene/gamestate.h"
 #include "twine/input.h"
-#include "twine/interface.h"
-#include "twine/menu.h"
-#include "twine/music.h"
+#include "twine/menu/interface.h"
+#include "twine/menu/menu.h"
+#include "twine/renderer/screens.h"
 #include "twine/resources.h"
-#include "twine/scene.h"
-#include "twine/screens.h"
-#include "twine/sound.h"
+#include "twine/scene/scene.h"
 #include "twine/text.h"
 #include "twine/twine.h"
 
@@ -145,7 +145,7 @@ void MenuOptions::drawSelectableCharacter(int32 x, int32 y) {
 
 	--_onScreenKeyboardDirty[idx];
 
-	const char buffer[] { allowedCharIndex[idx], '\0' };
+	const char buffer[]{allowedCharIndex[idx], '\0'};
 
 	const bool selected = _onScreenKeyboardX == x && _onScreenKeyboardY == y;
 	if (selected) {
@@ -225,6 +225,7 @@ class ScopedFeatureState {
 private:
 	OSystem::Feature _feature;
 	bool _changeTo;
+
 public:
 	ScopedFeatureState(OSystem::Feature feature, bool enable) : _feature(feature), _changeTo(enable) {
 		if (g_system->getFeatureState(feature) != enable) {
@@ -352,7 +353,7 @@ bool MenuOptions::newGameMenu() {
 }
 
 int MenuOptions::chooseSave(int textIdx, bool showEmptySlots) {
-	const SaveStateList& savegames = _engine->getSaveSlots();
+	const SaveStateList &savegames = _engine->getSaveSlots();
 	if (savegames.empty() && !showEmptySlots) {
 		return -1;
 	}
@@ -363,7 +364,7 @@ int MenuOptions::chooseSave(int textIdx, bool showEmptySlots) {
 	saveFiles.addButton(TextId::kReturnMenu);
 
 	const int maxButtons = _engine->getMetaEngine().getMaximumSaveSlot() + 1;
-	for (const SaveStateDescriptor& savegame : savegames) {
+	for (const SaveStateDescriptor &savegame : savegames) {
 		saveFiles.addButton(savegame.getDescription().encode().c_str(), savegame.getSaveSlot());
 		if (saveFiles.getButtonCount() >= maxButtons) {
 			break;
diff --git a/engines/twine/menuoptions.h b/engines/twine/menu/menuoptions.h
similarity index 98%
rename from engines/twine/menuoptions.h
rename to engines/twine/menu/menuoptions.h
index c0610abf58..bafe2772e4 100644
--- a/engines/twine/menuoptions.h
+++ b/engines/twine/menu/menuoptions.h
@@ -27,7 +27,7 @@
 #define ONSCREENKEYBOARD_HEIGHT 5
 
 #include "common/scummsys.h"
-#include "twine/actor.h"
+#include "twine/scene/actor.h"
 
 namespace TwinE {
 
diff --git a/engines/twine/module.mk b/engines/twine/module.mk
index 9342588444..e0816d6fe1 100644
--- a/engines/twine/module.mk
+++ b/engines/twine/module.mk
@@ -1,38 +1,45 @@
 MODULE := engines/twine
 
 MODULE_OBJS := \
+	audio/music.o \
+	audio/sound.o \
+	\
+	debugger/console.o \
+	debugger/debug.o \
+	debugger/debug_grid.o \
+	debugger/debug_scene.o \
+	\
+	menu/interface.o \
+	menu/menu.o \
+	menu/menuoptions.o \
+	\
 	parser/anim.o \
 	parser/body.o \
 	parser/entity.o \
-	actor.o \
-	animations.o \
-	collision.o \
-	console.o \
-	debug.o \
-	debug_grid.o \
-	debug_scene.o \
+	\
+	renderer/redraw.o \
+	renderer/renderer.o \
+	renderer/screens.o \
+	\
+	scene/actor.o \
+	scene/animations.o \
+	scene/collision.o \
+	scene/extra.o \
+	scene/gamestate.o \
+	scene/grid.o \
+	scene/movements.o \
+	scene/scene.o \
+	\
+	script/script_life_v1.o \
+	script/script_move_v1.o \
+	\
 	detection.o \
-	extra.o \
 	flamovies.o \
-	gamestate.o \
-	grid.o \
 	holomap.o \
 	hqr.o \
-	interface.o \
 	input.o \
-	menu.o \
-	menuoptions.o \
 	metaengine.o \
-	movements.o \
-	music.o \
-	redraw.o \
-	renderer.o \
 	resources.o \
-	scene.o \
-	screens.o \
-	script_life_v1.o \
-	script_move_v1.o \
-	sound.o \
 	text.o \
 	twine.o
 
diff --git a/engines/twine/parser/body.cpp b/engines/twine/parser/body.cpp
index c97882ab84..142cef6020 100644
--- a/engines/twine/parser/body.cpp
+++ b/engines/twine/parser/body.cpp
@@ -21,7 +21,7 @@
  */
 
 #include "twine/parser/body.h"
-#include "twine/renderer.h"
+#include "twine/renderer/renderer.h"
 #include "common/memstream.h"
 
 namespace TwinE {
diff --git a/engines/twine/redraw.cpp b/engines/twine/renderer/redraw.cpp
similarity index 98%
rename from engines/twine/redraw.cpp
rename to engines/twine/renderer/redraw.cpp
index 970e012f40..b901eba6a8 100644
--- a/engines/twine/redraw.cpp
+++ b/engines/twine/renderer/redraw.cpp
@@ -20,25 +20,25 @@
  *
  */
 
-#include "twine/redraw.h"
+#include "twine/renderer/redraw.h"
 #include "common/memstream.h"
 #include "common/textconsole.h"
 #include "graphics/surface.h"
-#include "twine/actor.h"
-#include "twine/animations.h"
-#include "twine/collision.h"
-#include "twine/debug_scene.h"
-#include "twine/grid.h"
+#include "twine/scene/actor.h"
+#include "twine/scene/animations.h"
+#include "twine/audio/sound.h"
+#include "twine/scene/collision.h"
+#include "twine/debugger/debug_scene.h"
+#include "twine/scene/grid.h"
 #include "twine/hqr.h"
 #include "twine/input.h"
-#include "twine/interface.h"
-#include "twine/menu.h"
-#include "twine/movements.h"
-#include "twine/renderer.h"
+#include "twine/menu/interface.h"
+#include "twine/menu/menu.h"
+#include "twine/scene/movements.h"
+#include "twine/renderer/renderer.h"
+#include "twine/renderer/screens.h"
 #include "twine/resources.h"
-#include "twine/scene.h"
-#include "twine/screens.h"
-#include "twine/sound.h"
+#include "twine/scene/scene.h"
 #include "twine/text.h"
 
 namespace TwinE {
diff --git a/engines/twine/redraw.h b/engines/twine/renderer/redraw.h
similarity index 100%
rename from engines/twine/redraw.h
rename to engines/twine/renderer/redraw.h
diff --git a/engines/twine/renderer.cpp b/engines/twine/renderer/renderer.cpp
similarity index 99%
rename from engines/twine/renderer.cpp
rename to engines/twine/renderer/renderer.cpp
index e7a5fe70c1..d80f0f2c8c 100644
--- a/engines/twine/renderer.cpp
+++ b/engines/twine/renderer/renderer.cpp
@@ -20,16 +20,16 @@
  *
  */
 
-#include "twine/renderer.h"
+#include "twine/renderer/renderer.h"
 #include "common/memstream.h"
 #include "common/stream.h"
 #include "common/textconsole.h"
 #include "common/util.h"
-#include "twine/actor.h"
-#include "twine/interface.h"
-#include "twine/menu.h"
-#include "twine/movements.h"
-#include "twine/redraw.h"
+#include "twine/scene/actor.h"
+#include "twine/menu/interface.h"
+#include "twine/menu/menu.h"
+#include "twine/scene/movements.h"
+#include "twine/renderer/redraw.h"
 #include "twine/shadeangletab.h"
 #include "twine/shared.h"
 #include "twine/twine.h"
@@ -1030,7 +1030,7 @@ uint8 *Renderer::prepareLines(Common::MemoryReadStream &stream, int32 &numOfPrim
 		lineCoordinatesPtr->colorIndex = stream.readByte();
 		stream.skip(3);
 		const int32 point1Index = stream.readSint16LE() / 6;
-		const int32 point2Index = 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;
@@ -1434,7 +1434,7 @@ void Renderer::prepareIsoModel(uint8 *bodyPtr) { // loadGfxSub
 	// set up bone indices
 	for (int32 i = 0; i < numBones; i++) {
 		bonesBase += sizeof(elementEntry);
-		elementEntry *ee = (elementEntry*)bonesBase;
+		elementEntry *ee = (elementEntry *)bonesBase;
 		ee->baseElement = ee->baseElement / sizeof(elementEntry);
 	}
 }
diff --git a/engines/twine/renderer.h b/engines/twine/renderer/renderer.h
similarity index 100%
rename from engines/twine/renderer.h
rename to engines/twine/renderer/renderer.h
diff --git a/engines/twine/screens.cpp b/engines/twine/renderer/screens.cpp
similarity index 89%
rename from engines/twine/screens.cpp
rename to engines/twine/renderer/screens.cpp
index 4f7291e1d5..ce19ace642 100644
--- a/engines/twine/screens.cpp
+++ b/engines/twine/renderer/screens.cpp
@@ -20,11 +20,11 @@
  *
  */
 
+#include "twine/renderer/screens.h"
 #include "common/system.h"
 #include "graphics/surface.h"
-#include "twine/screens.h"
 #include "twine/hqr.h"
-#include "twine/music.h"
+#include "twine/audio/music.h"
 #include "twine/resources.h"
 #include "twine/twine.h"
 
@@ -41,7 +41,7 @@ bool Screens::adelineLogo() {
 }
 
 void Screens::loadMenuImage(bool fade_in) {
-	if (HQR::getEntry((uint8*)_engine->workVideoBuffer.getPixels(), Resources::HQR_RESS_FILE, RESSHQR_MENUIMG) == 0) {
+	if (HQR::getEntry((uint8 *)_engine->workVideoBuffer.getPixels(), Resources::HQR_RESS_FILE, RESSHQR_MENUIMG) == 0) {
 		warning("Failed to load menu image");
 		return;
 	}
@@ -63,8 +63,8 @@ void Screens::loadCustomPalette(int32 index) {
 	convertPalToRGBA(palette, paletteRGBACustom);
 }
 
-void Screens::convertPalToRGBA(const uint8* in, uint32* out) {
-	uint8* paletteOut = (uint8*)out;
+void Screens::convertPalToRGBA(const uint8 *in, uint32 *out) {
+	uint8 *paletteOut = (uint8 *)out;
 	for (int i = 0; i < NUMOFCOLORS; i++) {
 		paletteOut[0] = in[0];
 		paletteOut[1] = in[1];
@@ -75,7 +75,7 @@ void Screens::convertPalToRGBA(const uint8* in, uint32* out) {
 }
 
 void Screens::loadImage(int32 index, bool fade_in) {
-	if (HQR::getEntry((uint8*)_engine->workVideoBuffer.getPixels(), Resources::HQR_RESS_FILE, index) == 0) {
+	if (HQR::getEntry((uint8 *)_engine->workVideoBuffer.getPixels(), Resources::HQR_RESS_FILE, index) == 0) {
 		warning("Failed to load image with index %i", index);
 		return;
 	}
@@ -133,8 +133,8 @@ void Screens::adjustPalette(uint8 R, uint8 G, uint8 B, const uint32 *rgbaPal, in
 
 	int32 counter = 0;
 
-	const uint8 *paletteIn = (const uint8*)rgbaPal;
-	uint8 *paletteOut = (uint8*)pal;
+	const uint8 *paletteIn = (const uint8 *)rgbaPal;
+	uint8 *paletteOut = (uint8 *)pal;
 	uint8 *newR = &paletteOut[0];
 	uint8 *newG = &paletteOut[1];
 	uint8 *newB = &paletteOut[2];
@@ -163,9 +163,9 @@ void Screens::adjustCrossPalette(const uint32 *pal1, const uint32 *pal2) {
 	int32 counter = 0;
 	int32 intensity = 0;
 
-	const uint8 *pal1p = (const uint8*)pal1;
-	const uint8 *pal2p = (const uint8*)pal2;
-	uint8 *paletteOut = (uint8*)pal;
+	const uint8 *pal1p = (const uint8 *)pal1;
+	const uint8 *pal2p = (const uint8 *)pal2;
+	uint8 *paletteOut = (uint8 *)pal;
 	do {
 		counter = 0;
 
@@ -252,7 +252,7 @@ void Screens::fadeRedPal(const uint32 *pal) {
 	}
 }
 
-void Screens::copyScreen(const Graphics::ManagedSurface& source, Graphics::ManagedSurface &destination) {
+void Screens::copyScreen(const Graphics::ManagedSurface &source, Graphics::ManagedSurface &destination) {
 	destination.blitFrom(source);
 }
 
diff --git a/engines/twine/screens.h b/engines/twine/renderer/screens.h
similarity index 100%
rename from engines/twine/screens.h
rename to engines/twine/renderer/screens.h
diff --git a/engines/twine/resources.cpp b/engines/twine/resources.cpp
index 12ff6143ad..45a3d3efef 100644
--- a/engines/twine/resources.cpp
+++ b/engines/twine/resources.cpp
@@ -22,10 +22,10 @@
 
 #include "twine/resources.h"
 #include "common/util.h"
-#include "twine/animations.h"
-#include "twine/scene.h"
-#include "twine/screens.h"
-#include "twine/sound.h"
+#include "twine/scene/animations.h"
+#include "twine/audio/sound.h"
+#include "twine/renderer/screens.h"
+#include "twine/scene/scene.h"
 #include "twine/text.h"
 
 namespace TwinE {
diff --git a/engines/twine/resources.h b/engines/twine/resources.h
index 023cc67621..874bf58b9d 100644
--- a/engines/twine/resources.h
+++ b/engines/twine/resources.h
@@ -24,7 +24,7 @@
 #define TWINE_RESOURCES_H
 
 #include "common/scummsys.h"
-#include "twine/gamestate.h"
+#include "twine/scene/gamestate.h"
 #include "twine/hqr.h"
 
 namespace TwinE {
diff --git a/engines/twine/actor.cpp b/engines/twine/scene/actor.cpp
similarity index 97%
rename from engines/twine/actor.cpp
rename to engines/twine/scene/actor.cpp
index 2eea245dbc..abd80c9fdc 100644
--- a/engines/twine/actor.cpp
+++ b/engines/twine/scene/actor.cpp
@@ -20,22 +20,22 @@
  *
  */
 
-#include "twine/actor.h"
+#include "twine/scene/actor.h"
 #include "common/memstream.h"
 #include "common/system.h"
 #include "common/textconsole.h"
-#include "twine/animations.h"
-#include "twine/parser/entity.h"
-#include "twine/extra.h"
-#include "twine/gamestate.h"
-#include "twine/grid.h"
+#include "twine/scene/animations.h"
+#include "twine/audio/sound.h"
+#include "twine/scene/extra.h"
+#include "twine/scene/gamestate.h"
+#include "twine/scene/grid.h"
 #include "twine/hqr.h"
-#include "twine/movements.h"
-#include "twine/renderer.h"
+#include "twine/scene/movements.h"
+#include "twine/parser/entity.h"
+#include "twine/renderer/renderer.h"
+#include "twine/renderer/screens.h"
 #include "twine/resources.h"
-#include "twine/scene.h"
-#include "twine/screens.h"
-#include "twine/sound.h"
+#include "twine/scene/scene.h"
 #include "twine/twine.h"
 
 namespace TwinE {
@@ -81,7 +81,7 @@ void Actor::restartHeroScene() {
 	cropBottomScreen = 0;
 }
 
-int32 Actor::loadBehaviourEntity(ActorStruct *sceneHero, uint8 **ptr, int16& bodyAnimIndex, int32 index) {
+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) {
 		error("Failed to load actor 3d data for index: %i", index);
@@ -283,7 +283,7 @@ void Actor::initModelActor(int32 bodyIdx, int16 actorIdx) {
 		bbox.z.topRight = actorBoundingBox.topRightZ;
 	} else {
 		ZVBox &bbox = localActor->boudingBox;
-		const BodyData& bd = bodyData[localActor->entity];
+		const BodyData &bd = bodyData[localActor->entity];
 		bbox.y.bottomLeft = bd.minsy;
 		bbox.y.topRight = bd.maxsy;
 
@@ -534,5 +534,4 @@ int32 ActorMoveStruct::getRealValue(int32 time) {
 	return tempStep + from;
 }
 
-
 } // namespace TwinE
diff --git a/engines/twine/actor.h b/engines/twine/scene/actor.h
similarity index 100%
rename from engines/twine/actor.h
rename to engines/twine/scene/actor.h
diff --git a/engines/twine/animations.cpp b/engines/twine/scene/animations.cpp
similarity index 97%
rename from engines/twine/animations.cpp
rename to engines/twine/scene/animations.cpp
index 27980c1bb8..6d327f698c 100644
--- a/engines/twine/animations.cpp
+++ b/engines/twine/scene/animations.cpp
@@ -20,25 +20,25 @@
  *
  */
 
-#include "twine/animations.h"
+#include "twine/scene/animations.h"
 #include "common/endian.h"
 #include "common/memstream.h"
 #include "common/stream.h"
 #include "common/system.h"
 #include "common/textconsole.h"
 #include "common/util.h"
-#include "twine/actor.h"
-#include "twine/collision.h"
+#include "twine/scene/actor.h"
+#include "twine/audio/sound.h"
+#include "twine/scene/collision.h"
+#include "twine/scene/gamestate.h"
+#include "twine/scene/grid.h"
+#include "twine/scene/movements.h"
 #include "twine/parser/anim.h"
 #include "twine/parser/entity.h"
-#include "twine/gamestate.h"
-#include "twine/grid.h"
-#include "twine/movements.h"
-#include "twine/renderer.h"
+#include "twine/renderer/renderer.h"
 #include "twine/resources.h"
-#include "twine/scene.h"
+#include "twine/scene/scene.h"
 #include "twine/shared.h"
-#include "twine/sound.h"
 #include "twine/twine.h"
 
 namespace TwinE {
@@ -70,7 +70,7 @@ int32 Animations::getBodyAnimIndex(AnimationTypes animIdx, int32 actorIdx) {
 	return bodyAnimIndex;
 }
 
-const uint8* Animations::getKeyFrameData(int32 frameIdx, const uint8 *animPtr) {
+const uint8 *Animations::getKeyFrameData(int32 frameIdx, const uint8 *animPtr) {
 	const int16 numOfBonesInAnim = READ_LE_INT16(animPtr + 2);
 	return (const uint8 *)((numOfBonesInAnim * 8 + 8) * frameIdx + animPtr + 8);
 }
@@ -133,7 +133,7 @@ bool Animations::setModelAnimation(int32 keyframeIdx, const uint8 *animPtr, uint
 	}
 	AnimData animData;
 	animData.loadFromBuffer(animPtr, 100000);
-	const KeyFrame* keyFrame = animData.getKeyframe(keyframeIdx);
+	const KeyFrame *keyFrame = animData.getKeyframe(keyframeIdx);
 
 	currentStepX = keyFrame->x;
 	currentStepY = keyFrame->y;
@@ -185,7 +185,7 @@ bool Animations::setModelAnimation(int32 keyframeIdx, const uint8 *animPtr, uint
 	int16 tmpNumOfPoints = numOfBonesInAnim - 1;
 	int boneIdx = 1;
 	do {
-		uint8* const bonesPtr = Model::getBonesStateData(bodyPtr, boneIdx);
+		uint8 *const bonesPtr = Model::getBonesStateData(bodyPtr, boneIdx);
 		const int16 animOpcode = getAnimMode(bonesPtr + 0, keyFramePtr + 0);
 
 		switch (animOpcode) {
@@ -224,7 +224,7 @@ void Animations::setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uint
 		return;
 	}
 
-	const KeyFrame* keyFrame = animData.getKeyframe(keyframeIdx);
+	const KeyFrame *keyFrame = animData.getKeyframe(keyframeIdx);
 
 	currentStepX = keyFrame->x;
 	currentStepY = keyFrame->y;
@@ -286,7 +286,7 @@ void Animations::stockAnimation(const uint8 *bodyPtr, AnimTimerDataStruct *animT
 bool Animations::verifyAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, AnimTimerDataStruct *animTimerDataPtr) {
 	AnimData animData;
 	animData.loadFromBuffer(animPtr, 100000);
-	const KeyFrame* keyFrame = animData.getKeyframe(keyframeIdx);
+	const KeyFrame *keyFrame = animData.getKeyframe(keyframeIdx);
 	const int32 keyFrameLength = keyFrame->length;
 
 	int32 remainingFrameTime = animTimerDataPtr->time;
@@ -300,12 +300,13 @@ bool Animations::verifyAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, A
 	currentStepY = keyFrame->y;
 	currentStepZ = keyFrame->z;
 
-	const BoneFrame& boneFrame = keyFrame->boneframes[0];
+	const BoneFrame &boneFrame = keyFrame->boneframes[0];
 	processRotationByAnim = boneFrame.type;
 	processLastRotationAngle = ToAngle(boneFrame.y);
 
 	if (deltaTime >= keyFrameLength) {
-		animTimerDataPtr->ptr = getKeyFrameData(keyframeIdx, animPtr);;
+		animTimerDataPtr->ptr = getKeyFrameData(keyframeIdx, animPtr);
+		;
 		animTimerDataPtr->time = _engine->lbaTime;
 		return true;
 	}
@@ -685,7 +686,7 @@ void Animations::processActorAnimations(int32 actorIdx) { // DoAnim
 
 	// actor standing on another actor
 	if (actor->standOn != -1) {
-		const ActorStruct* standOnActor = _engine->_scene->getActor(actor->standOn);
+		const ActorStruct *standOnActor = _engine->_scene->getActor(actor->standOn);
 		_engine->_movements->processActorX -= standOnActor->collisionX;
 		_engine->_movements->processActorY -= standOnActor->collisionY;
 		_engine->_movements->processActorZ -= standOnActor->collisionZ;
diff --git a/engines/twine/animations.h b/engines/twine/scene/animations.h
similarity index 98%
rename from engines/twine/animations.h
rename to engines/twine/scene/animations.h
index c9e369fece..c17728ded4 100644
--- a/engines/twine/animations.h
+++ b/engines/twine/scene/animations.h
@@ -24,8 +24,8 @@
 #define TWINE_ANIMATIONS_H
 
 #include "common/scummsys.h"
-#include "twine/actor.h"
-#include "twine/scene.h"
+#include "twine/scene/actor.h"
+#include "twine/scene/scene.h"
 
 namespace TwinE {
 
diff --git a/engines/twine/collision.cpp b/engines/twine/scene/collision.cpp
similarity index 98%
rename from engines/twine/collision.cpp
rename to engines/twine/scene/collision.cpp
index c98de651bf..094810b082 100644
--- a/engines/twine/collision.cpp
+++ b/engines/twine/scene/collision.cpp
@@ -20,18 +20,18 @@
  *
  */
 
-#include "common/memstream.h"
-#include "twine/actor.h"
-#include "twine/animations.h"
-#include "twine/collision.h"
+#include "twine/scene/collision.h"
 #include "common/debug.h"
+#include "common/memstream.h"
 #include "common/util.h"
-#include "twine/extra.h"
-#include "twine/grid.h"
-#include "twine/movements.h"
-#include "twine/renderer.h"
+#include "twine/scene/actor.h"
+#include "twine/scene/animations.h"
+#include "twine/scene/extra.h"
+#include "twine/scene/grid.h"
+#include "twine/scene/movements.h"
+#include "twine/renderer/renderer.h"
 #include "twine/resources.h"
-#include "twine/scene.h"
+#include "twine/scene/scene.h"
 #include "twine/shared.h"
 #include "twine/twine.h"
 
diff --git a/engines/twine/collision.h b/engines/twine/scene/collision.h
similarity index 99%
rename from engines/twine/collision.h
rename to engines/twine/scene/collision.h
index 2b0687737d..ff5ce64eaa 100644
--- a/engines/twine/collision.h
+++ b/engines/twine/scene/collision.h
@@ -24,7 +24,7 @@
 #define TWINE_COLLISION_H
 
 #include "common/scummsys.h"
-#include "twine/extra.h"
+#include "twine/scene/extra.h"
 
 namespace TwinE {
 
diff --git a/engines/twine/extra.cpp b/engines/twine/scene/extra.cpp
similarity index 98%
rename from engines/twine/extra.cpp
rename to engines/twine/scene/extra.cpp
index c3e4bc2e98..c51ee2213f 100644
--- a/engines/twine/extra.cpp
+++ b/engines/twine/scene/extra.cpp
@@ -20,21 +20,21 @@
  *
  */
 
-#include "twine/extra.h"
+#include "twine/scene/extra.h"
 #include "common/memstream.h"
 #include "common/util.h"
-#include "twine/actor.h"
-#include "twine/collision.h"
-#include "twine/gamestate.h"
-#include "twine/grid.h"
+#include "twine/scene/actor.h"
+#include "twine/audio/sound.h"
+#include "twine/scene/collision.h"
+#include "twine/scene/gamestate.h"
+#include "twine/scene/grid.h"
 #include "twine/input.h"
-#include "twine/interface.h"
-#include "twine/movements.h"
-#include "twine/redraw.h"
-#include "twine/renderer.h"
+#include "twine/menu/interface.h"
+#include "twine/scene/movements.h"
+#include "twine/renderer/redraw.h"
+#include "twine/renderer/renderer.h"
 #include "twine/resources.h"
-#include "twine/scene.h"
-#include "twine/sound.h"
+#include "twine/scene/scene.h"
 #include "twine/twine.h"
 
 namespace TwinE {
diff --git a/engines/twine/extra.h b/engines/twine/scene/extra.h
similarity index 99%
rename from engines/twine/extra.h
rename to engines/twine/scene/extra.h
index 5423fb8261..ad0737ab3c 100644
--- a/engines/twine/extra.h
+++ b/engines/twine/scene/extra.h
@@ -20,7 +20,7 @@
  *
  */
 
-#include "twine/actor.h"
+#include "twine/scene/actor.h"
 #include "common/scummsys.h"
 
 #ifndef TWINE_EXTRA_H
diff --git a/engines/twine/gamestate.cpp b/engines/twine/scene/gamestate.cpp
similarity index 97%
rename from engines/twine/gamestate.cpp
rename to engines/twine/scene/gamestate.cpp
index 58b8e3129b..e5edb72fdc 100644
--- a/engines/twine/gamestate.cpp
+++ b/engines/twine/scene/gamestate.cpp
@@ -20,30 +20,30 @@
  *
  */
 
-#include "twine/gamestate.h"
+#include "twine/scene/gamestate.h"
 #include "common/file.h"
 #include "common/rect.h"
 #include "common/str.h"
 #include "common/system.h"
 #include "common/textconsole.h"
 #include "common/util.h"
-#include "twine/actor.h"
-#include "twine/animations.h"
-#include "twine/collision.h"
-#include "twine/extra.h"
-#include "twine/grid.h"
+#include "twine/scene/actor.h"
+#include "twine/scene/animations.h"
+#include "twine/audio/music.h"
+#include "twine/audio/sound.h"
+#include "twine/scene/collision.h"
+#include "twine/scene/extra.h"
+#include "twine/scene/grid.h"
 #include "twine/input.h"
-#include "twine/interface.h"
-#include "twine/menu.h"
-#include "twine/menuoptions.h"
-#include "twine/music.h"
-#include "twine/redraw.h"
-#include "twine/renderer.h"
+#include "twine/menu/interface.h"
+#include "twine/menu/menu.h"
+#include "twine/menu/menuoptions.h"
+#include "twine/renderer/redraw.h"
+#include "twine/renderer/renderer.h"
+#include "twine/renderer/screens.h"
 #include "twine/resources.h"
-#include "twine/scene.h"
-#include "twine/screens.h"
+#include "twine/scene/scene.h"
 #include "twine/shared.h"
-#include "twine/sound.h"
 #include "twine/text.h"
 #include "twine/twine.h"
 
diff --git a/engines/twine/gamestate.h b/engines/twine/scene/gamestate.h
similarity index 98%
rename from engines/twine/gamestate.h
rename to engines/twine/scene/gamestate.h
index 6e48cecea0..b871759ef5 100644
--- a/engines/twine/gamestate.h
+++ b/engines/twine/scene/gamestate.h
@@ -25,9 +25,9 @@
 
 #include "common/savefile.h"
 #include "common/scummsys.h"
-#include "twine/actor.h"
+#include "twine/scene/actor.h"
 #include "twine/holomap.h"
-#include "twine/menu.h"
+#include "twine/menu/menu.h"
 
 namespace TwinE {
 
diff --git a/engines/twine/grid.cpp b/engines/twine/scene/grid.cpp
similarity index 97%
rename from engines/twine/grid.cpp
rename to engines/twine/scene/grid.cpp
index c9866a24dc..f04e262142 100644
--- a/engines/twine/grid.cpp
+++ b/engines/twine/scene/grid.cpp
@@ -20,18 +20,18 @@
  *
  */
 
-#include "twine/grid.h"
+#include "twine/scene/grid.h"
 #include "common/endian.h"
 #include "common/memstream.h"
 #include "common/textconsole.h"
-#include "twine/actor.h"
-#include "twine/collision.h"
-#include "twine/interface.h"
-#include "twine/redraw.h"
-#include "twine/renderer.h"
+#include "twine/scene/actor.h"
+#include "twine/scene/collision.h"
+#include "twine/menu/interface.h"
+#include "twine/renderer/redraw.h"
+#include "twine/renderer/renderer.h"
+#include "twine/renderer/screens.h"
 #include "twine/resources.h"
-#include "twine/scene.h"
-#include "twine/screens.h"
+#include "twine/scene/scene.h"
 #include "twine/twine.h"
 
 namespace TwinE {
@@ -53,7 +53,7 @@ Grid::~Grid() {
 	free(currentBll);
 }
 
-void Grid::copyGridMask(int32 index, int32 x, int32 y, const Graphics::ManagedSurface& buffer) {
+void Grid::copyGridMask(int32 index, int32 x, int32 y, const Graphics::ManagedSurface &buffer) {
 	uint8 *ptr = brickMaskTable[index];
 
 	int32 left = x + *(ptr + 2);
@@ -109,7 +109,7 @@ void Grid::copyGridMask(int32 index, int32 x, int32 y, const Graphics::ManagedSu
 	}
 
 	uint8 *outPtr = (uint8 *)_engine->frontVideoBuffer.getBasePtr(left, absY);
-	const uint8 *inPtr = (const uint8*)buffer.getBasePtr(left, absY);
+	const uint8 *inPtr = (const uint8 *)buffer.getBasePtr(left, absY);
 
 	do {
 		int32 vc3 = *(ptr++);
@@ -537,14 +537,14 @@ void Grid::drawBrickSprite(int32 index, int32 posX, int32 posY, const uint8 *ptr
 	}
 }
 
-uint8* Grid::getBlockBuffer(int32 x, int32 y, int32 z) {
+uint8 *Grid::getBlockBuffer(int32 x, int32 y, int32 z) {
 	const int32 tempX = (x + 0x100) >> 9;
 	const int32 tempY = y >> 8;
 	const int32 tempZ = (z + 0x100) >> 9;
 	return blockBuffer + tempY * 2 + tempX * GRID_SIZE_Y * 2 + (tempZ << 6) * GRID_SIZE_Y * 2;
 }
 
-const uint8* Grid::getBlockBufferGround(int32 x, int32 y, int32 z, int16 &ground) const {
+const uint8 *Grid::getBlockBufferGround(int32 x, int32 y, int32 z, int16 &ground) const {
 	_engine->_grid->updateCollisionCoordinates(x, y, z);
 	const int32 tempX = _engine->_collision->collisionX;
 	int32 tempY = _engine->_collision->collisionY;
@@ -687,7 +687,7 @@ ShapeType Grid::getBrickShape(int32 x, int32 y, int32 z) {
 
 		return (ShapeType)*blockPtr;
 	}
-	return (ShapeType)*(blockBufferPtr + 1);
+	return (ShapeType) * (blockBufferPtr + 1);
 }
 
 void Grid::updateCollisionCoordinates(int32 x, int32 y, int32 z) {
@@ -747,7 +747,7 @@ ShapeType Grid::getBrickShapeFull(int32 x, int32 y, int32 z, int32 y2) {
 
 		return brickShape;
 	}
-	const ShapeType brickShape = (ShapeType)*(blockBufferPtr + 1);
+	const ShapeType brickShape = (ShapeType) * (blockBufferPtr + 1);
 
 	const int32 newY = (y2 + 255) >> 8;
 	int32 currY = _engine->_collision->collisionY;
diff --git a/engines/twine/grid.h b/engines/twine/scene/grid.h
similarity index 100%
rename from engines/twine/grid.h
rename to engines/twine/scene/grid.h
diff --git a/engines/twine/movements.cpp b/engines/twine/scene/movements.cpp
similarity index 96%
rename from engines/twine/movements.cpp
rename to engines/twine/scene/movements.cpp
index 93115e8eb8..460dc4c981 100644
--- a/engines/twine/movements.cpp
+++ b/engines/twine/scene/movements.cpp
@@ -20,16 +20,16 @@
  *
  */
 
-#include "twine/movements.h"
+#include "twine/scene/movements.h"
 #include "common/textconsole.h"
-#include "twine/actor.h"
-#include "twine/animations.h"
-#include "twine/collision.h"
-#include "twine/gamestate.h"
-#include "twine/grid.h"
+#include "twine/scene/actor.h"
+#include "twine/scene/animations.h"
+#include "twine/scene/collision.h"
+#include "twine/scene/gamestate.h"
+#include "twine/scene/grid.h"
 #include "twine/input.h"
-#include "twine/renderer.h"
-#include "twine/scene.h"
+#include "twine/renderer/renderer.h"
+#include "twine/scene/scene.h"
 #include "twine/text.h"
 #include "twine/twine.h"
 
@@ -44,7 +44,7 @@ void Movements::getShadowPosition(int32 x, int32 y, int32 z) {
 
 	if (*ptr) {
 		const uint8 *blockPtr = _engine->_grid->getBlockLibrary(*ptr - 1) + 3 + *(ptr + 1) * 4;
-		const ShapeType brickShape = (ShapeType)*((const uint8 *)(blockPtr));
+		const ShapeType brickShape = (ShapeType) * ((const uint8 *)(blockPtr));
 		_engine->_actor->shadowCollisionType = brickShape;
 	} else {
 		_engine->_actor->shadowCollisionType = ShapeType::kNone;
@@ -172,7 +172,7 @@ void Movements::moveActor(int32 angleFrom, int32 angleTo, int32 speed, ActorMove
 	movePtr->timeOfChange = _engine->lbaTime;
 }
 
-void Movements::ChangedCursorKeys::update(TwinEEngine* engine) {
+void Movements::ChangedCursorKeys::update(TwinEEngine *engine) {
 	if (engine->_input->isActionActive(TwinEActionType::TurnLeft)) {
 		leftChange = leftDown == 0;
 		leftDown = 1;
@@ -368,7 +368,7 @@ void Movements::processManualAction(int actorIdx) {
 
 void Movements::processFollowAction(int actorIdx) {
 	ActorStruct *actor = _engine->_scene->getActor(actorIdx);
-	const ActorStruct* followedActor = _engine->_scene->getActor(actor->followedActor);
+	const ActorStruct *followedActor = _engine->_scene->getActor(actor->followedActor);
 	int32 newAngle = getAngleAndSetTargetActorDistance(actor->x, actor->z, followedActor->x, followedActor->z);
 	if (actor->staticFlags.bIsSpriteActor) {
 		actor->angle = newAngle;
@@ -407,7 +407,7 @@ void Movements::processTrackAction(int actorIdx) {
 
 void Movements::processSameXZAction(int actorIdx) {
 	ActorStruct *actor = _engine->_scene->getActor(actorIdx);
-	const ActorStruct* followedActor = _engine->_scene->getActor(actor->followedActor);
+	const ActorStruct *followedActor = _engine->_scene->getActor(actor->followedActor);
 	actor->x = followedActor->x;
 	actor->z = followedActor->z;
 }
diff --git a/engines/twine/movements.h b/engines/twine/scene/movements.h
similarity index 99%
rename from engines/twine/movements.h
rename to engines/twine/scene/movements.h
index c6bc891f87..86322bbbac 100644
--- a/engines/twine/movements.h
+++ b/engines/twine/scene/movements.h
@@ -23,7 +23,7 @@
 #ifndef TWINE_MOVEMENTS_H
 #define TWINE_MOVEMENTS_H
 
-#include "twine/actor.h"
+#include "twine/scene/actor.h"
 #include "common/scummsys.h"
 
 namespace TwinE {
diff --git a/engines/twine/scene.cpp b/engines/twine/scene/scene.cpp
similarity index 95%
rename from engines/twine/scene.cpp
rename to engines/twine/scene/scene.cpp
index fee71c2fa8..ed754254aa 100644
--- a/engines/twine/scene.cpp
+++ b/engines/twine/scene/scene.cpp
@@ -20,24 +20,24 @@
  *
  */
 
-#include "twine/scene.h"
+#include "twine/scene/scene.h"
 #include "common/memstream.h"
 #include "common/stream.h"
 #include "common/util.h"
-#include "twine/actor.h"
-#include "twine/animations.h"
-#include "twine/debug_grid.h"
-#include "twine/debug_scene.h"
-#include "twine/extra.h"
-#include "twine/gamestate.h"
-#include "twine/grid.h"
-#include "twine/movements.h"
-#include "twine/music.h"
-#include "twine/redraw.h"
-#include "twine/renderer.h"
+#include "twine/scene/actor.h"
+#include "twine/scene/animations.h"
+#include "twine/audio/music.h"
+#include "twine/audio/sound.h"
+#include "twine/debugger/debug_grid.h"
+#include "twine/debugger/debug_scene.h"
+#include "twine/scene/extra.h"
+#include "twine/scene/gamestate.h"
+#include "twine/scene/grid.h"
+#include "twine/scene/movements.h"
+#include "twine/renderer/redraw.h"
+#include "twine/renderer/renderer.h"
+#include "twine/renderer/screens.h"
 #include "twine/resources.h"
-#include "twine/screens.h"
-#include "twine/sound.h"
 #include "twine/text.h"
 #include "twine/twine.h"
 
@@ -47,7 +47,7 @@ Scene::~Scene() {
 	free(currentScene);
 }
 
-void Scene::setActorStaticFlags(ActorStruct* act, uint16 staticFlags) {
+void Scene::setActorStaticFlags(ActorStruct *act, uint16 staticFlags) {
 	if (staticFlags & 0x1) {
 		act->staticFlags.bComputeCollisionWithObj = 1;
 	}
@@ -99,7 +99,7 @@ void Scene::setActorStaticFlags(ActorStruct* act, uint16 staticFlags) {
 	}
 }
 
-void Scene::setBonusParameterFlags(ActorStruct* act, uint16 bonusFlags) {
+void Scene::setBonusParameterFlags(ActorStruct *act, uint16 bonusFlags) {
 	if (bonusFlags & 0x1) {
 		act->bonusParameter.unk1 = 1;
 	}
@@ -183,13 +183,13 @@ bool Scene::loadSceneLBA1() {
 	for (int32 i = 1; i < sceneNumActors; i++, cnt++) {
 		_engine->_actor->resetActor(i);
 
-		ActorStruct* act = &_sceneActors[i];
+		ActorStruct *act = &_sceneActors[i];
 		setActorStaticFlags(act, stream.readUint16LE());
 
 		act->loadModel(stream.readUint16LE());
 
 		act->body = stream.readByte();
-		act->anim = (AnimationTypes) stream.readByte();
+		act->anim = (AnimationTypes)stream.readByte();
 		act->sprite = stream.readUint16LE();
 		act->x = stream.readUint16LE();
 		act->collisionX = act->x;
@@ -229,7 +229,7 @@ bool Scene::loadSceneLBA1() {
 
 	sceneNumZones = stream.readUint16LE();
 	for (int32 i = 0; i < sceneNumZones; i++) {
-		ZoneStruct* zone = &sceneZones[i];
+		ZoneStruct *zone = &sceneZones[i];
 		zone->bottomLeft.x = stream.readUint16LE();
 		zone->bottomLeft.y = stream.readUint16LE();
 		zone->bottomLeft.z = stream.readUint16LE();
@@ -250,7 +250,7 @@ bool Scene::loadSceneLBA1() {
 
 	sceneNumTracks = stream.readUint16LE();
 	for (int32 i = 0; i < sceneNumTracks; i++) {
-		ScenePoint* point = &sceneTracks[i];
+		ScenePoint *point = &sceneTracks[i];
 		point->x = stream.readUint16LE();
 		point->y = stream.readUint16LE();
 		point->z = stream.readUint16LE();
diff --git a/engines/twine/scene.h b/engines/twine/scene/scene.h
similarity index 99%
rename from engines/twine/scene.h
rename to engines/twine/scene/scene.h
index e3c237723f..da5d544c9a 100644
--- a/engines/twine/scene.h
+++ b/engines/twine/scene/scene.h
@@ -25,7 +25,7 @@
 
 #include "common/scummsys.h"
 #include "common/util.h"
-#include "twine/actor.h"
+#include "twine/scene/actor.h"
 #include "twine/text.h"
 
 namespace TwinE {
diff --git a/engines/twine/script_life_v1.cpp b/engines/twine/script/script_life_v1.cpp
similarity index 93%
rename from engines/twine/script_life_v1.cpp
rename to engines/twine/script/script_life_v1.cpp
index ee3a48beee..50bf5a4252 100644
--- a/engines/twine/script_life_v1.cpp
+++ b/engines/twine/script/script_life_v1.cpp
@@ -20,27 +20,27 @@
  *
  */
 
-#include "twine/script_life_v1.h"
+#include "twine/script/script_life_v1.h"
 #include "common/memstream.h"
 #include "common/stream.h"
-#include "twine/actor.h"
-#include "twine/animations.h"
-#include "twine/collision.h"
+#include "twine/scene/actor.h"
+#include "twine/scene/animations.h"
+#include "twine/audio/music.h"
+#include "twine/audio/sound.h"
+#include "twine/scene/collision.h"
 #include "twine/flamovies.h"
-#include "twine/gamestate.h"
-#include "twine/grid.h"
+#include "twine/scene/gamestate.h"
+#include "twine/scene/grid.h"
 #include "twine/holomap.h"
 #include "twine/input.h"
-#include "twine/interface.h"
-#include "twine/menu.h"
-#include "twine/movements.h"
-#include "twine/music.h"
-#include "twine/redraw.h"
-#include "twine/renderer.h"
+#include "twine/menu/interface.h"
+#include "twine/menu/menu.h"
+#include "twine/scene/movements.h"
+#include "twine/renderer/redraw.h"
+#include "twine/renderer/renderer.h"
+#include "twine/renderer/screens.h"
 #include "twine/resources.h"
-#include "twine/scene.h"
-#include "twine/screens.h"
-#include "twine/sound.h"
+#include "twine/scene/scene.h"
 #include "twine/text.h"
 #include "twine/twine.h"
 
@@ -96,36 +96,36 @@ enum LifeScriptOperators {
 
 /** Script condition command opcodes */
 enum LifeScriptConditions {
-	/*0x00*/ kcCOL = 0,					/*<! Current actor collision with another actor. (Parameter = Actor Index) */
-	/*0x01*/ kcCOL_OBJ = 1,				/*<! Actor collision with the actor passed as parameter. (Parameter = Actor Index, Parameter = Actor Index) */
-	/*0x02*/ kcDISTANCE = 2,			/*<! Distance between the current actor and the actor passed as parameter. (Parameter = Actor Index, Parameter = Distance between) */
-	/*0x03*/ kcZONE = 3,				/*<! Current actor tread on zone passed as parameter. (Parameter = Zone Index) */
-	/*0x04*/ kcZONE_OBJ = 4,			/*<! The actor passed as parameter will tread on zone passed as parameter. (Parameter = Actor Index, Parameter = Zone Index) */
-	/*0x05*/ kcBODY = 5,				/*<! Body of the current actor. (Parameter = Body Index) */
-	/*0x06*/ kcBODY_OBJ = 6,			/*<! Body of the actor passed as parameter. (Parameter = Body Index) */
-	/*0x07*/ kcANIM = 7,				/*<! Body Animation of the current actor. (Parameter = Animation Index) */
-	/*0x08*/ kcANIM_OBJ = 8,			/*<! Body Animation of the actor passed as parameter. (Parameter = Animation Index) */
-	/*0x09*/ kcL_TRACK = 9,				/*<! Current actor track. (Parameter = Track Index) */
-	/*0x0A*/ kcL_TRACK_OBJ = 10,		/*<! Track of the actor passed as parameter. (Parameter = Track Index) */
-	/*0x0B*/ kcFLAG_CUBE = 11,			/*<! Game Cube Flags. (Parameter = Cube Flag Index, Parameter = 0 (not set), = 1 (set))k */
-	/*0x0C*/ kcCONE_VIEW = 12,			/*<! The actor passed as parameter have a "vision in circle". (Parameter = Actor Index, Parameter = Distance) */
-	/*0x0D*/ kcHIT_BY = 13,				/*<! Current actor hited by the actor passed as parameter. (Parameter = Actor Index) */
-	/*0x0E*/ kcACTION = 14,				/*<! Hero action behavior. (Parameter = Behaviour Index) */
-	/*0x0F*/ kcFLAG_GAME = 15,			/*<! Game Flags (See further list). (Parameter = Flag Index, Parameter = 0 (not set), = 1 (set)) */
-	/*0x10*/ kcLIFE_POINT = 16,			/*<! Current actor life points. (Parameter = Life points) */
-	/*0x11*/ kcLIFE_POINT_OBJ = 17,		/*<! Life points of the current actor passed as parameter. (Parameter = Life points) */
-	/*0x12*/ kcNUM_LITTLE_KEYS = 18,	/*<! Number of keys. (Parameter = Number of keys) */
-	/*0x13*/ kcNUM_GOLD_PIECES = 19,	/*<! Coins/Gold Amount. (Parameter = Coins/Gold amount) */
-	/*0x14*/ kcBEHAVIOUR = 20,			/*<! Hero behaviour. (Parameter = Behaviour Index) */
-	/*0x15*/ kcCHAPTER = 21,			/*<! Story Chapters. (Parameter = Chapter Index) */
-	/*0x16*/ kcDISTANCE_3D = 22,		/*<! Distance between the actor passed as parameter and the current actor. (Parameter = Actor Index, Parameter = Distance) */
-	/*0x17 - 23 unused */
-	/*0x18 - 24 unused */
-	/*0x19*/ kcUSE_INVENTORY = 25,		/*<! Use inventory object. (Parameter = Object Index in the inventory, Paramenter = 0 (Not in Inventory), = 1 (In the Inventory)) */
-	/*0x1A*/ kcCHOICE = 26,				/*<! Menu choice. (Parameter = Text Index in the current Text Bank) */
-	/*0x1B*/ kcFUEL = 27,				/*<! Amount of fuel gas the Hero have in his inventory. (Parameter = Gas amount) */
-	/*0x1C*/ kcCARRIED_BY = 28,			/*<! The current is carried by the actor passed as paramenter. (Parameter = Actor Index) */
-	/*0x1D*/ kcCDROM = 29				/*<! CDROM audio tracks. (Parameter = Audio Tracks Index) */
+	/*0x00*/ kcCOL = 0,              /*<! Current actor collision with another actor. (Parameter = Actor Index) */
+	/*0x01*/ kcCOL_OBJ = 1,          /*<! Actor collision with the actor passed as parameter. (Parameter = Actor Index, Parameter = Actor Index) */
+	/*0x02*/ kcDISTANCE = 2,         /*<! Distance between the current actor and the actor passed as parameter. (Parameter = Actor Index, Parameter = Distance between) */
+	/*0x03*/ kcZONE = 3,             /*<! Current actor tread on zone passed as parameter. (Parameter = Zone Index) */
+	/*0x04*/ kcZONE_OBJ = 4,         /*<! The actor passed as parameter will tread on zone passed as parameter. (Parameter = Actor Index, Parameter = Zone Index) */
+	/*0x05*/ kcBODY = 5,             /*<! Body of the current actor. (Parameter = Body Index) */
+	/*0x06*/ kcBODY_OBJ = 6,         /*<! Body of the actor passed as parameter. (Parameter = Body Index) */
+	/*0x07*/ kcANIM = 7,             /*<! Body Animation of the current actor. (Parameter = Animation Index) */
+	/*0x08*/ kcANIM_OBJ = 8,         /*<! Body Animation of the actor passed as parameter. (Parameter = Animation Index) */
+	/*0x09*/ kcL_TRACK = 9,          /*<! Current actor track. (Parameter = Track Index) */
+	/*0x0A*/ kcL_TRACK_OBJ = 10,     /*<! Track of the actor passed as parameter. (Parameter = Track Index) */
+	/*0x0B*/ kcFLAG_CUBE = 11,       /*<! Game Cube Flags. (Parameter = Cube Flag Index, Parameter = 0 (not set), = 1 (set))k */
+	/*0x0C*/ kcCONE_VIEW = 12,       /*<! The actor passed as parameter have a "vision in circle". (Parameter = Actor Index, Parameter = Distance) */
+	/*0x0D*/ kcHIT_BY = 13,          /*<! Current actor hited by the actor passed as parameter. (Parameter = Actor Index) */
+	/*0x0E*/ kcACTION = 14,          /*<! Hero action behavior. (Parameter = Behaviour Index) */
+	/*0x0F*/ kcFLAG_GAME = 15,       /*<! Game Flags (See further list). (Parameter = Flag Index, Parameter = 0 (not set), = 1 (set)) */
+	/*0x10*/ kcLIFE_POINT = 16,      /*<! Current actor life points. (Parameter = Life points) */
+	/*0x11*/ kcLIFE_POINT_OBJ = 17,  /*<! Life points of the current actor passed as parameter. (Parameter = Life points) */
+	/*0x12*/ kcNUM_LITTLE_KEYS = 18, /*<! Number of keys. (Parameter = Number of keys) */
+	/*0x13*/ kcNUM_GOLD_PIECES = 19, /*<! Coins/Gold Amount. (Parameter = Coins/Gold amount) */
+	/*0x14*/ kcBEHAVIOUR = 20,       /*<! Hero behaviour. (Parameter = Behaviour Index) */
+	/*0x15*/ kcCHAPTER = 21,         /*<! Story Chapters. (Parameter = Chapter Index) */
+	/*0x16*/ kcDISTANCE_3D = 22,     /*<! Distance between the actor passed as parameter and the current actor. (Parameter = Actor Index, Parameter = Distance) */
+	                                 /*0x17 - 23 unused */
+	                                 /*0x18 - 24 unused */
+	/*0x19*/ kcUSE_INVENTORY = 25,   /*<! Use inventory object. (Parameter = Object Index in the inventory, Paramenter = 0 (Not in Inventory), = 1 (In the Inventory)) */
+	/*0x1A*/ kcCHOICE = 26,          /*<! Menu choice. (Parameter = Text Index in the current Text Bank) */
+	/*0x1B*/ kcFUEL = 27,            /*<! Amount of fuel gas the Hero have in his inventory. (Parameter = Gas amount) */
+	/*0x1C*/ kcCARRIED_BY = 28,      /*<! The current is carried by the actor passed as paramenter. (Parameter = Actor Index) */
+	/*0x1D*/ kcCDROM = 29            /*<! CDROM audio tracks. (Parameter = Audio Tracks Index) */
 };
 
 /**
diff --git a/engines/twine/script_life_v1.h b/engines/twine/script/script_life_v1.h
similarity index 100%
rename from engines/twine/script_life_v1.h
rename to engines/twine/script/script_life_v1.h
diff --git a/engines/twine/script_move_v1.cpp b/engines/twine/script/script_move_v1.cpp
similarity index 98%
rename from engines/twine/script_move_v1.cpp
rename to engines/twine/script/script_move_v1.cpp
index a25e8dfcb8..ceff4ae9ac 100644
--- a/engines/twine/script_move_v1.cpp
+++ b/engines/twine/script/script_move_v1.cpp
@@ -20,19 +20,19 @@
  *
  */
 
-#include "twine/script_move_v1.h"
+#include "twine/script/script_move_v1.h"
+#include "common/memstream.h"
 #include "common/textconsole.h"
 #include "common/util.h"
-#include "twine/actor.h"
-#include "twine/animations.h"
+#include "twine/scene/actor.h"
+#include "twine/scene/animations.h"
+#include "twine/audio/sound.h"
 #include "twine/flamovies.h"
-#include "twine/movements.h"
-#include "twine/redraw.h"
-#include "twine/renderer.h"
-#include "twine/scene.h"
-#include "twine/screens.h"
-#include "common/memstream.h"
-#include "twine/sound.h"
+#include "twine/scene/movements.h"
+#include "twine/renderer/redraw.h"
+#include "twine/renderer/renderer.h"
+#include "twine/renderer/screens.h"
+#include "twine/scene/scene.h"
 #include "twine/twine.h"
 
 namespace TwinE {
diff --git a/engines/twine/script_move_v1.h b/engines/twine/script/script_move_v1.h
similarity index 100%
rename from engines/twine/script_move_v1.h
rename to engines/twine/script/script_move_v1.h
diff --git a/engines/twine/text.cpp b/engines/twine/text.cpp
index eb6cb17862..f638368a53 100644
--- a/engines/twine/text.cpp
+++ b/engines/twine/text.cpp
@@ -27,15 +27,15 @@
 #include "common/scummsys.h"
 #include "common/str.h"
 #include "common/system.h"
+#include "twine/audio/sound.h"
 #include "twine/hqr.h"
 #include "twine/input.h"
-#include "twine/interface.h"
-#include "twine/menu.h"
-#include "twine/renderer.h"
+#include "twine/menu/interface.h"
+#include "twine/menu/menu.h"
+#include "twine/renderer/renderer.h"
+#include "twine/renderer/screens.h"
 #include "twine/resources.h"
-#include "twine/scene.h"
-#include "twine/screens.h"
-#include "twine/sound.h"
+#include "twine/scene/scene.h"
 #include "twine/twine.h"
 
 namespace TwinE {
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index b172fb1f52..79c16d7ff4 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -36,45 +36,45 @@
 #include "engines/util.h"
 #include "graphics/colormasks.h"
 #include "graphics/cursorman.h"
-#include "graphics/fontman.h"
 #include "graphics/font.h"
+#include "graphics/fontman.h"
 #include "graphics/managed_surface.h"
 #include "graphics/palette.h"
 #include "graphics/pixelformat.h"
 #include "graphics/surface.h"
 #include "gui/debugger.h"
-#include "twine/actor.h"
-#include "twine/animations.h"
-#include "twine/collision.h"
-#include "twine/console.h"
-#include "twine/debug.h"
-#include "twine/debug_grid.h"
-#include "twine/debug_scene.h"
-#include "twine/extra.h"
+#include "twine/scene/actor.h"
+#include "twine/scene/animations.h"
+#include "twine/audio/music.h"
+#include "twine/audio/sound.h"
+#include "twine/scene/collision.h"
+#include "twine/debugger/console.h"
+#include "twine/debugger/debug.h"
+#include "twine/debugger/debug_grid.h"
+#include "twine/debugger/debug_scene.h"
+#include "twine/scene/extra.h"
 #include "twine/flamovies.h"
-#include "twine/gamestate.h"
-#include "twine/grid.h"
+#include "twine/scene/gamestate.h"
+#include "twine/scene/grid.h"
 #include "twine/holomap.h"
 #include "twine/hqr.h"
 #include "twine/input.h"
-#include "twine/interface.h"
-#include "twine/menu.h"
-#include "twine/menuoptions.h"
-#include "twine/movements.h"
-#include "twine/music.h"
-#include "twine/redraw.h"
-#include "twine/renderer.h"
+#include "twine/menu/interface.h"
+#include "twine/menu/menu.h"
+#include "twine/menu/menuoptions.h"
+#include "twine/scene/movements.h"
+#include "twine/renderer/redraw.h"
+#include "twine/renderer/renderer.h"
+#include "twine/renderer/screens.h"
 #include "twine/resources.h"
-#include "twine/scene.h"
-#include "twine/screens.h"
-#include "twine/script_life_v1.h"
-#include "twine/script_move_v1.h"
-#include "twine/sound.h"
+#include "twine/scene/scene.h"
+#include "twine/script/script_life_v1.h"
+#include "twine/script/script_move_v1.h"
 #include "twine/text.h"
 
 namespace TwinE {
 
-ScopedEngineFreeze::ScopedEngineFreeze(TwinEEngine* engine) : _engine(engine) {
+ScopedEngineFreeze::ScopedEngineFreeze(TwinEEngine *engine) : _engine(engine) {
 	_engine->freezeTime();
 }
 
@@ -82,7 +82,7 @@ ScopedEngineFreeze::~ScopedEngineFreeze() {
 	_engine->unfreezeTime();
 }
 
-ScopedCursor::ScopedCursor(TwinEEngine* engine) : _engine(engine) {
+ScopedCursor::ScopedCursor(TwinEEngine *engine) : _engine(engine) {
 	_engine->pushMouseCursorVisible();
 }
 
diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index 347a884390..e23d6ab47f 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -32,7 +32,7 @@
 #include "graphics/pixelformat.h"
 #include "graphics/surface.h"
 #include "metaengine.h"
-#include "twine/actor.h"
+#include "twine/scene/actor.h"
 #include "twine/input.h"
 #include "twine/detection.h"
 


Commit: 73fc3f05cc170b45bb2193c5bd1c16b523f78e19
    https://github.com/scummvm/scummvm/commit/73fc3f05cc170b45bb2193c5bd1c16b523f78e19
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: format the code

Changed paths:
    engines/twine/scene/actor.cpp
    engines/twine/scene/actor.h
    engines/twine/scene/animations.cpp
    engines/twine/scene/animations.h
    engines/twine/scene/collision.cpp
    engines/twine/scene/collision.h
    engines/twine/scene/extra.cpp
    engines/twine/scene/extra.h
    engines/twine/scene/gamestate.cpp
    engines/twine/scene/gamestate.h
    engines/twine/scene/grid.cpp
    engines/twine/scene/grid.h
    engines/twine/scene/movements.cpp
    engines/twine/scene/movements.h
    engines/twine/scene/scene.cpp
    engines/twine/scene/scene.h


diff --git a/engines/twine/scene/actor.cpp b/engines/twine/scene/actor.cpp
index abd80c9fdc..97c5613579 100644
--- a/engines/twine/scene/actor.cpp
+++ b/engines/twine/scene/actor.cpp
@@ -24,17 +24,17 @@
 #include "common/memstream.h"
 #include "common/system.h"
 #include "common/textconsole.h"
-#include "twine/scene/animations.h"
 #include "twine/audio/sound.h"
-#include "twine/scene/extra.h"
-#include "twine/scene/gamestate.h"
-#include "twine/scene/grid.h"
 #include "twine/hqr.h"
-#include "twine/scene/movements.h"
 #include "twine/parser/entity.h"
 #include "twine/renderer/renderer.h"
 #include "twine/renderer/screens.h"
 #include "twine/resources.h"
+#include "twine/scene/animations.h"
+#include "twine/scene/extra.h"
+#include "twine/scene/gamestate.h"
+#include "twine/scene/grid.h"
+#include "twine/scene/movements.h"
 #include "twine/scene/scene.h"
 #include "twine/twine.h"
 
diff --git a/engines/twine/scene/actor.h b/engines/twine/scene/actor.h
index 6c144e3005..a7d4f1e698 100644
--- a/engines/twine/scene/actor.h
+++ b/engines/twine/scene/actor.h
@@ -93,7 +93,7 @@ struct StaticFlagsStruct {
 	uint16 bIsBackgrounded : 1;             // 0x2000
 	uint16 bIsCarrierActor : 1;             // 0x4000
 	// take smaller value for bound, or if not set take average for bound
-	uint16 bUseMiniZv : 1;                  // 0x8000
+	uint16 bUseMiniZv : 1; // 0x8000
 };
 
 /** Actors dynamic flags structure */
@@ -148,6 +148,7 @@ class ActorStruct {
 private:
 	ShapeType _brickShape = ShapeType::kNone; // field_3
 	bool _brickCausesDamage = false;
+
 public:
 	~ActorStruct();
 
@@ -155,7 +156,10 @@ public:
 	DynamicFlagsStruct dynamicFlags;
 
 	inline ShapeType brickShape() const { return _brickShape; }
-	inline void setBrickShape(ShapeType shapeType) { _brickShape = shapeType; _brickCausesDamage = false; }
+	inline void setBrickShape(ShapeType shapeType) {
+		_brickShape = shapeType;
+		_brickCausesDamage = false;
+	}
 	inline void setBrickCausesDamage() { _brickCausesDamage = true; }
 	inline bool brickCausesDamage() { return _brickCausesDamage; }
 	void loadModel(int32 modelIndex);
@@ -172,7 +176,7 @@ public:
 	 */
 	int32 body = 0;
 	AnimationTypes anim = AnimationTypes::kAnimNone;
-	AnimationTypes animExtra = AnimationTypes::kStanding;  //field_2
+	AnimationTypes animExtra = AnimationTypes::kStanding; //field_2
 	AnimationTypes animExtraPtr = AnimationTypes::kAnimNone;
 	int32 sprite = 0; // field_8
 	uint8 *entityDataPtr = nullptr;
@@ -239,7 +243,7 @@ class TwinEEngine;
 
 class Actor {
 private:
-	TwinEEngine* _engine;
+	TwinEEngine *_engine;
 
 	/** Hero 3D entity for normal behaviour */
 	uint8 *heroEntityNORMAL = nullptr; // file3D0
@@ -266,10 +270,10 @@ private:
 	 */
 	int32 initBody(int32 bodyIdx, int32 actorIdx, ActorBoundingBox &actorBoundingBox);
 
-	int32 loadBehaviourEntity(ActorStruct *sceneHero, uint8 **ptr, int16& bodyAnimIndex, int32 index);
+	int32 loadBehaviourEntity(ActorStruct *sceneHero, uint8 **ptr, int16 &bodyAnimIndex, int32 index);
 
 public:
-	Actor(TwinEEngine* engine);
+	Actor(TwinEEngine *engine);
 	~Actor();
 
 	ActorStruct *processActorPtr = nullptr; // processActorVar1
diff --git a/engines/twine/scene/animations.cpp b/engines/twine/scene/animations.cpp
index 6d327f698c..fe46f6d858 100644
--- a/engines/twine/scene/animations.cpp
+++ b/engines/twine/scene/animations.cpp
@@ -27,16 +27,16 @@
 #include "common/system.h"
 #include "common/textconsole.h"
 #include "common/util.h"
-#include "twine/scene/actor.h"
 #include "twine/audio/sound.h"
-#include "twine/scene/collision.h"
-#include "twine/scene/gamestate.h"
-#include "twine/scene/grid.h"
-#include "twine/scene/movements.h"
 #include "twine/parser/anim.h"
 #include "twine/parser/entity.h"
 #include "twine/renderer/renderer.h"
 #include "twine/resources.h"
+#include "twine/scene/actor.h"
+#include "twine/scene/collision.h"
+#include "twine/scene/gamestate.h"
+#include "twine/scene/grid.h"
+#include "twine/scene/movements.h"
 #include "twine/scene/scene.h"
 #include "twine/shared.h"
 #include "twine/twine.h"
diff --git a/engines/twine/scene/animations.h b/engines/twine/scene/animations.h
index c17728ded4..dab05e546a 100644
--- a/engines/twine/scene/animations.h
+++ b/engines/twine/scene/animations.h
@@ -79,7 +79,7 @@ public:
 	 */
 	void setAnimAtKeyframe(int32 keyframeIdx, const uint8 *animPtr, uint8 *const bodyPtr, AnimTimerDataStruct *animTimerDataPtr);
 
-	const uint8* getKeyFrameData(int32 frameIdx, const uint8 *animPtr);
+	const uint8 *getKeyFrameData(int32 frameIdx, const uint8 *animPtr);
 
 	/**
 	 * Get total number of keyframes in animation
diff --git a/engines/twine/scene/collision.cpp b/engines/twine/scene/collision.cpp
index 094810b082..a3aaefcfe3 100644
--- a/engines/twine/scene/collision.cpp
+++ b/engines/twine/scene/collision.cpp
@@ -24,13 +24,13 @@
 #include "common/debug.h"
 #include "common/memstream.h"
 #include "common/util.h"
+#include "twine/renderer/renderer.h"
+#include "twine/resources.h"
 #include "twine/scene/actor.h"
 #include "twine/scene/animations.h"
 #include "twine/scene/extra.h"
 #include "twine/scene/grid.h"
 #include "twine/scene/movements.h"
-#include "twine/renderer/renderer.h"
-#include "twine/resources.h"
 #include "twine/scene/scene.h"
 #include "twine/shared.h"
 #include "twine/twine.h"
diff --git a/engines/twine/scene/collision.h b/engines/twine/scene/collision.h
index ff5ce64eaa..b6021584f9 100644
--- a/engines/twine/scene/collision.h
+++ b/engines/twine/scene/collision.h
@@ -33,6 +33,7 @@ class TwinEEngine;
 class Collision {
 private:
 	TwinEEngine *_engine;
+
 public:
 	Collision(TwinEEngine *engine);
 	/** Actor collition X coordinate */
diff --git a/engines/twine/scene/extra.cpp b/engines/twine/scene/extra.cpp
index c51ee2213f..2dd199fc21 100644
--- a/engines/twine/scene/extra.cpp
+++ b/engines/twine/scene/extra.cpp
@@ -23,17 +23,17 @@
 #include "twine/scene/extra.h"
 #include "common/memstream.h"
 #include "common/util.h"
-#include "twine/scene/actor.h"
 #include "twine/audio/sound.h"
-#include "twine/scene/collision.h"
-#include "twine/scene/gamestate.h"
-#include "twine/scene/grid.h"
 #include "twine/input.h"
 #include "twine/menu/interface.h"
-#include "twine/scene/movements.h"
 #include "twine/renderer/redraw.h"
 #include "twine/renderer/renderer.h"
 #include "twine/resources.h"
+#include "twine/scene/actor.h"
+#include "twine/scene/collision.h"
+#include "twine/scene/gamestate.h"
+#include "twine/scene/grid.h"
+#include "twine/scene/movements.h"
 #include "twine/scene/scene.h"
 #include "twine/twine.h"
 
diff --git a/engines/twine/scene/extra.h b/engines/twine/scene/extra.h
index ad0737ab3c..d30e6b98ba 100644
--- a/engines/twine/scene/extra.h
+++ b/engines/twine/scene/extra.h
@@ -20,8 +20,8 @@
  *
  */
 
-#include "twine/scene/actor.h"
 #include "common/scummsys.h"
+#include "twine/scene/actor.h"
 
 #ifndef TWINE_EXTRA_H
 #define TWINE_EXTRA_H
@@ -64,7 +64,7 @@ struct ExtraListStruct {
 	int16 destX = 0; // field_E
 	int16 destY = 0; // field_10
 	int16 destZ = 0; // field_12
-	uint16 type = 0;  /**< ExtraType bitmask */
+	uint16 type = 0; /**< ExtraType bitmask */
 	int16 angle = 0; // field_16
 	int32 spawnTime = 0;
 	union payload { // field_ 1C
diff --git a/engines/twine/scene/gamestate.cpp b/engines/twine/scene/gamestate.cpp
index e5edb72fdc..4592ff8147 100644
--- a/engines/twine/scene/gamestate.cpp
+++ b/engines/twine/scene/gamestate.cpp
@@ -27,13 +27,8 @@
 #include "common/system.h"
 #include "common/textconsole.h"
 #include "common/util.h"
-#include "twine/scene/actor.h"
-#include "twine/scene/animations.h"
 #include "twine/audio/music.h"
 #include "twine/audio/sound.h"
-#include "twine/scene/collision.h"
-#include "twine/scene/extra.h"
-#include "twine/scene/grid.h"
 #include "twine/input.h"
 #include "twine/menu/interface.h"
 #include "twine/menu/menu.h"
@@ -42,6 +37,11 @@
 #include "twine/renderer/renderer.h"
 #include "twine/renderer/screens.h"
 #include "twine/resources.h"
+#include "twine/scene/actor.h"
+#include "twine/scene/animations.h"
+#include "twine/scene/collision.h"
+#include "twine/scene/extra.h"
+#include "twine/scene/grid.h"
 #include "twine/scene/scene.h"
 #include "twine/shared.h"
 #include "twine/text.h"
diff --git a/engines/twine/scene/gamestate.h b/engines/twine/scene/gamestate.h
index b871759ef5..b099f5a35d 100644
--- a/engines/twine/scene/gamestate.h
+++ b/engines/twine/scene/gamestate.h
@@ -25,9 +25,9 @@
 
 #include "common/savefile.h"
 #include "common/scummsys.h"
-#include "twine/scene/actor.h"
 #include "twine/holomap.h"
 #include "twine/menu/menu.h"
+#include "twine/scene/actor.h"
 
 namespace TwinE {
 
diff --git a/engines/twine/scene/grid.cpp b/engines/twine/scene/grid.cpp
index f04e262142..4ddcf8423c 100644
--- a/engines/twine/scene/grid.cpp
+++ b/engines/twine/scene/grid.cpp
@@ -24,13 +24,13 @@
 #include "common/endian.h"
 #include "common/memstream.h"
 #include "common/textconsole.h"
-#include "twine/scene/actor.h"
-#include "twine/scene/collision.h"
 #include "twine/menu/interface.h"
 #include "twine/renderer/redraw.h"
 #include "twine/renderer/renderer.h"
 #include "twine/renderer/screens.h"
 #include "twine/resources.h"
+#include "twine/scene/actor.h"
+#include "twine/scene/collision.h"
 #include "twine/scene/scene.h"
 #include "twine/twine.h"
 
diff --git a/engines/twine/scene/grid.h b/engines/twine/scene/grid.h
index 65c2467839..734bc15a28 100644
--- a/engines/twine/scene/grid.h
+++ b/engines/twine/scene/grid.h
@@ -132,7 +132,7 @@ private:
 	 * @param y grid Y coordinate
 	 * @param buffer work video buffer
 	 */
-	void copyGridMask(int32 index, int32 x, int32 y, const Graphics::ManagedSurface& buffer);
+	void copyGridMask(int32 index, int32 x, int32 y, const Graphics::ManagedSurface &buffer);
 
 	/** Table with all loaded bricks */
 	uint8 *brickTable[NUM_BRICKS]{nullptr};
@@ -172,11 +172,11 @@ public:
 	/** Grid block entry types */
 	typedef struct BlockEntry blockMap[GRID_SIZE_X][GRID_SIZE_Z][GRID_SIZE_Y];
 
-	uint8* getBlockBuffer(int32 x, int32 y, int32 z);
+	uint8 *getBlockBuffer(int32 x, int32 y, int32 z);
 	/**
 	 * search down until either ground is found or lower border of the cube is reached
 	 */
-	const uint8* getBlockBufferGround(int32 x, int32 y, int32 z, int16 &ground) const;
+	const uint8 *getBlockBufferGround(int32 x, int32 y, int32 z, int16 &ground) const;
 
 	void updateCollisionCoordinates(int32 x, int32 y, int32 z);
 
diff --git a/engines/twine/scene/movements.cpp b/engines/twine/scene/movements.cpp
index 460dc4c981..9cdeded142 100644
--- a/engines/twine/scene/movements.cpp
+++ b/engines/twine/scene/movements.cpp
@@ -22,13 +22,13 @@
 
 #include "twine/scene/movements.h"
 #include "common/textconsole.h"
+#include "twine/input.h"
+#include "twine/renderer/renderer.h"
 #include "twine/scene/actor.h"
 #include "twine/scene/animations.h"
 #include "twine/scene/collision.h"
 #include "twine/scene/gamestate.h"
 #include "twine/scene/grid.h"
-#include "twine/input.h"
-#include "twine/renderer/renderer.h"
 #include "twine/scene/scene.h"
 #include "twine/text.h"
 #include "twine/twine.h"
diff --git a/engines/twine/scene/movements.h b/engines/twine/scene/movements.h
index 86322bbbac..138fcd144c 100644
--- a/engines/twine/scene/movements.h
+++ b/engines/twine/scene/movements.h
@@ -23,8 +23,8 @@
 #ifndef TWINE_MOVEMENTS_H
 #define TWINE_MOVEMENTS_H
 
-#include "twine/scene/actor.h"
 #include "common/scummsys.h"
+#include "twine/scene/actor.h"
 
 namespace TwinE {
 
@@ -44,17 +44,17 @@ private:
 		uint8 leftDown = 0;
 		uint8 rightDown = 0;
 
-		void update(TwinEEngine* engine);
+		void update(TwinEEngine *engine);
 
-		inline bool operator==(const ChangedCursorKeys& rhs) const {
+		inline bool operator==(const ChangedCursorKeys &rhs) const {
 			return forwardChange == rhs.forwardChange && backwardChange == rhs.backwardChange && leftChange == rhs.leftChange && rightChange == rhs.rightChange;
 		}
 
-		inline operator bool () const {
+		inline operator bool() const {
 			return forwardChange && backwardChange && leftChange && rightChange;
 		}
 
-		inline bool operator!=(const ChangedCursorKeys& rhs) const {
+		inline bool operator!=(const ChangedCursorKeys &rhs) const {
 			return forwardChange != rhs.forwardChange || backwardChange != rhs.backwardChange || leftChange != rhs.leftChange || rightChange != rhs.rightChange;
 		}
 	};
diff --git a/engines/twine/scene/scene.cpp b/engines/twine/scene/scene.cpp
index ed754254aa..6b3d8a5f74 100644
--- a/engines/twine/scene/scene.cpp
+++ b/engines/twine/scene/scene.cpp
@@ -24,20 +24,20 @@
 #include "common/memstream.h"
 #include "common/stream.h"
 #include "common/util.h"
-#include "twine/scene/actor.h"
-#include "twine/scene/animations.h"
 #include "twine/audio/music.h"
 #include "twine/audio/sound.h"
 #include "twine/debugger/debug_grid.h"
 #include "twine/debugger/debug_scene.h"
-#include "twine/scene/extra.h"
-#include "twine/scene/gamestate.h"
-#include "twine/scene/grid.h"
-#include "twine/scene/movements.h"
 #include "twine/renderer/redraw.h"
 #include "twine/renderer/renderer.h"
 #include "twine/renderer/screens.h"
 #include "twine/resources.h"
+#include "twine/scene/actor.h"
+#include "twine/scene/animations.h"
+#include "twine/scene/extra.h"
+#include "twine/scene/gamestate.h"
+#include "twine/scene/grid.h"
+#include "twine/scene/movements.h"
 #include "twine/text.h"
 #include "twine/twine.h"
 
diff --git a/engines/twine/scene/scene.h b/engines/twine/scene/scene.h
index da5d544c9a..afafacd38f 100644
--- a/engines/twine/scene/scene.h
+++ b/engines/twine/scene/scene.h
@@ -80,8 +80,8 @@ struct ZoneStruct {
 
 		/** show a text (e.g. when reading a sign) */
 		struct {
-			int16 textIdx;		/*!< text index in the current active text bank */
-			int16 textColor;	/*!< text color (see @c ActorStruct::talkColor) */
+			int16 textIdx;   /*!< text index in the current active text bank */
+			int16 textColor; /*!< text color (see @c ActorStruct::talkColor) */
 		} DisplayText;
 		struct {
 			int16 info0;
@@ -266,8 +266,8 @@ private:
 
 	/** Process zone extra bonus */
 	void processZoneExtraBonus(ZoneStruct *zone);
-	void setActorStaticFlags(ActorStruct* act, uint16 staticFlags);
-	void setBonusParameterFlags(ActorStruct* act, uint16 bonusFlags);
+	void setActorStaticFlags(ActorStruct *act, uint16 staticFlags);
+	void setBonusParameterFlags(ActorStruct *act, uint16 bonusFlags);
 	bool loadSceneLBA1();
 	/** Initialize new scene */
 	bool initScene(int32 index);
@@ -280,9 +280,9 @@ private:
 
 	/** Timer for the next sample ambience in scene */
 	int32 _sampleAmbienceTime = 0;
-	int16 _sampleAmbiance[4] {0};
-	int16 _sampleRepeat[4] {0};
-	int16 _sampleRound[4] {0};
+	int16 _sampleAmbiance[4]{0};
+	int16 _sampleRepeat[4]{0};
+	int16 _sampleRound[4]{0};
 	int16 _sampleMinDelay = 0;
 	int16 _sampleMinDelayRnd = 0;
 
@@ -326,7 +326,7 @@ public:
 	// ACTORS
 	int32 sceneNumActors = 0;
 	ActorStruct *sceneHero = nullptr;
-	ActorStruct* getActor(int32 actorIdx);
+	ActorStruct *getActor(int32 actorIdx);
 
 	/** Meca pinguin actor index */
 	int16 mecaPinguinIdx = 0; // currentPingouin
@@ -348,7 +348,7 @@ public:
 	// TODO: check what is this
 	bool changeRoomVar10 = false;
 
-	uint8 sceneFlags[NUM_SCENES_FLAGS] {0}; // cubeFlags
+	uint8 sceneFlags[NUM_SCENES_FLAGS]{0}; // cubeFlags
 
 	int32 sceneNumZones = 0;
 	ZoneStruct sceneZones[NUM_MAX_ZONES];


Commit: b5a13114dfaf8dbe136051f70cfb4d139d50be3f
    https://github.com/scummvm/scummvm/commit/b5a13114dfaf8dbe136051f70cfb4d139d50be3f
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: moved file into subdir

Changed paths:
  A engines/twine/renderer/shadeangletab.h
  R engines/twine/shadeangletab.h
    engines/twine/renderer/renderer.cpp
    engines/twine/renderer/screens.cpp


diff --git a/engines/twine/renderer/renderer.cpp b/engines/twine/renderer/renderer.cpp
index d80f0f2c8c..abca4b9093 100644
--- a/engines/twine/renderer/renderer.cpp
+++ b/engines/twine/renderer/renderer.cpp
@@ -25,12 +25,12 @@
 #include "common/stream.h"
 #include "common/textconsole.h"
 #include "common/util.h"
-#include "twine/scene/actor.h"
 #include "twine/menu/interface.h"
 #include "twine/menu/menu.h"
-#include "twine/scene/movements.h"
 #include "twine/renderer/redraw.h"
-#include "twine/shadeangletab.h"
+#include "twine/renderer/shadeangletab.h"
+#include "twine/scene/actor.h"
+#include "twine/scene/movements.h"
 #include "twine/shared.h"
 #include "twine/twine.h"
 
diff --git a/engines/twine/renderer/screens.cpp b/engines/twine/renderer/screens.cpp
index ce19ace642..f4eb8ee45e 100644
--- a/engines/twine/renderer/screens.cpp
+++ b/engines/twine/renderer/screens.cpp
@@ -23,8 +23,8 @@
 #include "twine/renderer/screens.h"
 #include "common/system.h"
 #include "graphics/surface.h"
-#include "twine/hqr.h"
 #include "twine/audio/music.h"
+#include "twine/hqr.h"
 #include "twine/resources.h"
 #include "twine/twine.h"
 
diff --git a/engines/twine/shadeangletab.h b/engines/twine/renderer/shadeangletab.h
similarity index 100%
rename from engines/twine/shadeangletab.h
rename to engines/twine/renderer/shadeangletab.h


Commit: c883e1e2e01e895332a4d70088e3a422bd6340f0
    https://github.com/scummvm/scummvm/commit/c883e1e2e01e895332a4d70088e3a422bd6340f0
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: moved struct into shared

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 9aa5aab8c9..c6c85d64c8 100644
--- a/engines/twine/renderer/renderer.h
+++ b/engines/twine/renderer/renderer.h
@@ -59,12 +59,6 @@ struct CmdRenderPolygon {
 	// followed by Vertex array
 };
 
-struct Vec3 {
-	int32 x = 0;
-	int32 y = 0;
-	int32 z = 0;
-};
-
 struct Matrix {
 	int32 row1[3]{0, 0, 0};
 	int32 row2[3]{0, 0, 0};
diff --git a/engines/twine/shared.h b/engines/twine/shared.h
index c9e0530fb7..05be1753df 100644
--- a/engines/twine/shared.h
+++ b/engines/twine/shared.h
@@ -27,6 +27,17 @@
 
 namespace TwinE {
 
+struct Vec3 {
+	int32 x = 0;
+	int32 y = 0;
+	int32 z = 0;
+};
+
+struct BoundingBox {
+	Vec3 mins;
+	Vec3 maxs;
+};
+
 struct ActorBoundingBox {
 	/** Bottom left X coordinate */
 	int16 bottomLeftX = 0;


Commit: 2317f899143a048148db391ee3e9aba9b6f26570
    https://github.com/scummvm/scummvm/commit/2317f899143a048148db391ee3e9aba9b6f26570
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: new sprite bbox parser

Changed paths:
  A engines/twine/parser/sprite.cpp
  A engines/twine/parser/sprite.h
    engines/twine/module.mk


diff --git a/engines/twine/module.mk b/engines/twine/module.mk
index e0816d6fe1..b43ffd47db 100644
--- a/engines/twine/module.mk
+++ b/engines/twine/module.mk
@@ -16,6 +16,7 @@ MODULE_OBJS := \
 	parser/anim.o \
 	parser/body.o \
 	parser/entity.o \
+	parser/sprite.o \
 	\
 	renderer/redraw.o \
 	renderer/renderer.o \
diff --git a/engines/twine/parser/sprite.cpp b/engines/twine/parser/sprite.cpp
new file mode 100644
index 0000000000..178fb75e9f
--- /dev/null
+++ b/engines/twine/parser/sprite.cpp
@@ -0,0 +1,54 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "twine/parser/sprite.h"
+#include "common/stream.h"
+#include "twine/shared.h"
+
+namespace TwinE {
+
+bool SpriteBoundingBoxData::loadFromStream(Common::SeekableReadStream &stream) {
+	const int32 size = stream.size();
+	const int32 amount = size / 16;
+	for (int32 i = 0; i < amount; ++i) {
+		stream.skip(4);
+		BoundingBox bbox;
+		bbox.mins.x = stream.readSint16LE();
+		bbox.maxs.x = stream.readSint16LE();
+		bbox.mins.y = stream.readSint16LE();
+		bbox.maxs.y = stream.readSint16LE();
+		bbox.mins.z = stream.readSint16LE();
+		bbox.maxs.z = stream.readSint16LE();
+		_boundingBoxes.push_back(bbox);
+	}
+	return !stream.err();
+}
+
+bool SpriteBoundingBoxData::loadFromBuffer(const uint8 *buf, uint32 size) {
+	if (size == 0) {
+		return false;
+	}
+	Common::MemoryReadStream stream(buf, size);
+	return loadFromStream(stream);
+}
+
+} // End of namespace TwinE
diff --git a/engines/twine/parser/sprite.h b/engines/twine/parser/sprite.h
new file mode 100644
index 0000000000..75f09259d1
--- /dev/null
+++ b/engines/twine/parser/sprite.h
@@ -0,0 +1,54 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TWINE_SPRITE_H
+#define TWINE_SPRITE_H
+
+#include "common/array.h"
+#include "common/memstream.h"
+#include "common/stream.h"
+#include "twine/shared.h"
+
+namespace TwinE {
+
+class SpriteBoundingBoxData {
+private:
+	Common::Array<BoundingBox> _boundingBoxes;
+
+public:
+	bool loadFromStream(Common::SeekableReadStream &stream);
+
+	bool loadFromBuffer(const uint8 *buf, uint32 size);
+
+	const BoundingBox *bbox(int index) const;
+};
+
+inline const BoundingBox *SpriteBoundingBoxData::bbox(int index) const {
+	if (index < 0) {
+		return nullptr;
+	}
+	return &_boundingBoxes[index];
+}
+
+} // End of namespace TwinE
+
+#endif


Commit: 28611c1cf270b8b641bedd217480fe4cfe322b98
    https://github.com/scummvm/scummvm/commit/28611c1cf270b8b641bedd217480fe4cfe322b98
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: const + reduced scope

Changed paths:
    engines/twine/renderer/renderer.cpp


diff --git a/engines/twine/renderer/renderer.cpp b/engines/twine/renderer/renderer.cpp
index abca4b9093..93b51275aa 100644
--- a/engines/twine/renderer/renderer.cpp
+++ b/engines/twine/renderer/renderer.cpp
@@ -414,11 +414,11 @@ void Renderer::computePolygons(int16 polyRenderType, Vertex *vertices, int32 num
 			continue;
 		}
 
-		int8 up = currentVertexY < oldVertexY;
+		const int8 up = currentVertexY < oldVertexY;
 		int8 direction = up ? -1 : 1;
 
-		int16 vsize = ABS(currentVertexY - oldVertexY);
-		int16 hsize = ABS(currentVertexX - oldVertexX);
+		const int16 vsize = ABS(currentVertexY - oldVertexY);
+		const int16 hsize = ABS(currentVertexX - oldVertexX);
 
 		int16 cvalue;
 		int16 cdelta;
@@ -480,14 +480,12 @@ void Renderer::renderPolygonsCopper(uint8 *out, int vtop, int32 vsize, int32 col
 
 			if (hsize >= 0) {
 				uint16 mask = 0x43DB;
-				uint16 dx;
-				int32 startCopy;
 
-				dx = (uint8)color;
+				uint16 dx = (uint8)color;
 				dx |= 0x300;
 
 				hsize++;
-				startCopy = start;
+				const int32 startCopy = start;
 
 				for (int32 j = startCopy; j < hsize + startCopy; j++) {
 					start += mask;
@@ -537,15 +535,13 @@ void Renderer::renderPolygonsFlat(uint8 *out, int vtop, int32 vsize, int32 color
 	int32 currentLine = vtop;
 	do {
 		if (currentLine >= 0 && currentLine < SCREEN_HEIGHT) {
-			int16 stop = ptr1[SCREEN_HEIGHT];
 			int16 start = ptr1[0];
-
+			int16 stop = ptr1[SCREEN_HEIGHT];
 			ptr1++;
 			int32 hsize = stop - start;
 
 			if (hsize >= 0) {
 				hsize++;
-
 				for (int32 j = start; j < hsize + start; j++) {
 					if (j >= 0 && j < SCREEN_WIDTH) {
 						out[j] = color;


Commit: 7a5f170e73dcccdfad945e843e06079eda70e9ed
    https://github.com/scummvm/scummvm/commit/7a5f170e73dcccdfad945e843e06079eda70e9ed
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: added base class for parsers

Changed paths:
  A engines/twine/parser/parser.cpp
  A engines/twine/parser/parser.h
    engines/twine/module.mk
    engines/twine/parser/anim.cpp
    engines/twine/parser/anim.h
    engines/twine/parser/body.cpp
    engines/twine/parser/body.h
    engines/twine/parser/entity.cpp
    engines/twine/parser/entity.h
    engines/twine/parser/sprite.cpp
    engines/twine/parser/sprite.h
    engines/twine/resources.cpp


diff --git a/engines/twine/module.mk b/engines/twine/module.mk
index b43ffd47db..4b1ebfca2f 100644
--- a/engines/twine/module.mk
+++ b/engines/twine/module.mk
@@ -16,6 +16,7 @@ MODULE_OBJS := \
 	parser/anim.o \
 	parser/body.o \
 	parser/entity.o \
+	parser/parser.o \
 	parser/sprite.o \
 	\
 	renderer/redraw.o \
diff --git a/engines/twine/parser/anim.cpp b/engines/twine/parser/anim.cpp
index 2fb947e9f3..f79d1f1fb8 100644
--- a/engines/twine/parser/anim.cpp
+++ b/engines/twine/parser/anim.cpp
@@ -63,14 +63,6 @@ bool AnimData::loadFromStream(Common::SeekableReadStream &stream) {
 	return !stream.err();
 }
 
-bool AnimData::loadFromBuffer(const uint8 *buf, uint32 size) {
-	if (size == 0) {
-		return false;
-	}
-	Common::MemoryReadStream stream(buf, size);
-	return loadFromStream(stream);
-}
-
 const Common::Array<KeyFrame>& AnimData::getKeyframes() const {
 	return _keyframes;
 }
diff --git a/engines/twine/parser/anim.h b/engines/twine/parser/anim.h
index 75471edfae..ac64081828 100644
--- a/engines/twine/parser/anim.h
+++ b/engines/twine/parser/anim.h
@@ -25,6 +25,7 @@
 
 #include "common/array.h"
 #include "common/stream.h"
+#include "twine/parser/parser.h"
 #include "twine/shared.h"
 
 namespace TwinE {
@@ -44,7 +45,7 @@ struct KeyFrame {
 	Common::Array<BoneFrame> boneframes;
 };
 
-class AnimData {
+class AnimData : public Parser {
 private:
 	Common::Array<KeyFrame> _keyframes;
 
@@ -56,9 +57,7 @@ private:
 	uint16 _loopFrame;
 
 public:
-	bool loadFromStream(Common::SeekableReadStream &stream);
-
-	bool loadFromBuffer(const uint8 *buf, uint32 size);
+	bool loadFromStream(Common::SeekableReadStream &stream) override;
 
 	const KeyFrame* getKeyframe(uint index) const;
 	const Common::Array<KeyFrame>& getKeyframes() const;
diff --git a/engines/twine/parser/body.cpp b/engines/twine/parser/body.cpp
index 142cef6020..cfb552af62 100644
--- a/engines/twine/parser/body.cpp
+++ b/engines/twine/parser/body.cpp
@@ -166,12 +166,4 @@ bool BodyData::loadFromStream(Common::SeekableReadStream &stream) {
 	return !stream.err();
 }
 
-bool BodyData::loadFromBuffer(const uint8 *buf, uint32 size) {
-	if (size == 0) {
-		return false;
-	}
-	Common::MemoryReadStream stream(buf, size);
-	return loadFromStream(stream);
-}
-
 } // namespace TwinE
diff --git a/engines/twine/parser/body.h b/engines/twine/parser/body.h
index ed6d942356..fa01363153 100644
--- a/engines/twine/parser/body.h
+++ b/engines/twine/parser/body.h
@@ -27,6 +27,7 @@
 #include "common/memstream.h"
 #include "common/stream.h"
 #include "twine/parser/anim.h"
+#include "twine/parser/parser.h"
 #include "twine/shared.h"
 
 namespace TwinE {
@@ -73,7 +74,7 @@ struct BodySphere {
 	uint16 vertex;
 };
 
-class BodyData {
+class BodyData : public Parser {
 private:
 	void loadVertices(Common::SeekableReadStream &stream);
 	void loadBones(Common::SeekableReadStream &stream);
@@ -171,9 +172,7 @@ public:
 		return &_bones[boneIdx];
 	}
 
-	bool loadFromStream(Common::SeekableReadStream &stream);
-
-	bool loadFromBuffer(const uint8 *buf, uint32 size);
+	bool loadFromStream(Common::SeekableReadStream &stream) override;
 };
 
 } // End of namespace TwinE
diff --git a/engines/twine/parser/entity.cpp b/engines/twine/parser/entity.cpp
index d5a1a38ffe..cc1b9988f9 100644
--- a/engines/twine/parser/entity.cpp
+++ b/engines/twine/parser/entity.cpp
@@ -165,14 +165,6 @@ bool EntityData::loadFromStream(Common::SeekableReadStream &stream) {
 	return true;
 }
 
-bool EntityData::loadFromBuffer(const uint8* buf, uint32 size) {
-	if (size == 0) {
-		return false;
-	}
-	Common::MemoryReadStream stream(buf, size);
-	return loadFromStream(stream);
-}
-
 const Common::Array<EntityAnim::Action>* EntityData::getActions(AnimationTypes animation) const {
 	for (const EntityAnim& anim : _animations) {
 		if (anim.animation == animation) {
diff --git a/engines/twine/parser/entity.h b/engines/twine/parser/entity.h
index 210928966a..14a6ad05d8 100644
--- a/engines/twine/parser/entity.h
+++ b/engines/twine/parser/entity.h
@@ -26,6 +26,7 @@
 #include "common/array.h"
 #include "common/memstream.h"
 #include "common/stream.h"
+#include "twine/parser/parser.h"
 #include "twine/shared.h"
 
 namespace TwinE {
@@ -63,7 +64,7 @@ struct EntityAnim {
 	Common::Array<Action> _actions;
 };
 
-class EntityData {
+class EntityData : public Parser {
 private:
 	Common::Array<EntityBody> _bodies;
 	Common::Array<EntityAnim> _animations;
@@ -72,9 +73,7 @@ private:
 	bool loadAnim(Common::SeekableReadStream &stream);
 
 public:
-	bool loadFromStream(Common::SeekableReadStream &stream);
-
-	bool loadFromBuffer(const uint8 *buf, uint32 size);
+	bool loadFromStream(Common::SeekableReadStream &stream) override;
 
 	const Common::Array<EntityAnim::Action> *getActions(AnimationTypes animation) const;
 	const EntityBody *getBody(const int index) const;
diff --git a/engines/twine/parser/parser.cpp b/engines/twine/parser/parser.cpp
new file mode 100644
index 0000000000..6ee2f48e52
--- /dev/null
+++ b/engines/twine/parser/parser.cpp
@@ -0,0 +1,37 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "twine/parser/parser.h"
+#include "common/stream.h"
+#include "twine/shared.h"
+
+namespace TwinE {
+
+bool Parser::loadFromBuffer(const uint8 *buf, uint32 size) {
+	if (size == 0) {
+		return false;
+	}
+	Common::MemoryReadStream stream(buf, size);
+	return loadFromStream(stream);
+}
+
+} // End of namespace TwinE
diff --git a/engines/twine/parser/parser.h b/engines/twine/parser/parser.h
new file mode 100644
index 0000000000..8c242e91fa
--- /dev/null
+++ b/engines/twine/parser/parser.h
@@ -0,0 +1,43 @@
+ /* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TWINE_PARSER_H
+#define TWINE_PARSER_H
+
+#include "common/array.h"
+#include "common/memstream.h"
+#include "common/stream.h"
+#include "twine/shared.h"
+
+namespace TwinE {
+
+class Parser {
+public:
+	virtual ~Parser() {}
+	virtual bool loadFromStream(Common::SeekableReadStream &stream) = 0;
+
+	bool loadFromBuffer(const uint8 *buf, uint32 size);
+};
+
+} // End of namespace TwinE
+
+#endif
diff --git a/engines/twine/parser/sprite.cpp b/engines/twine/parser/sprite.cpp
index 178fb75e9f..208dbc76d6 100644
--- a/engines/twine/parser/sprite.cpp
+++ b/engines/twine/parser/sprite.cpp
@@ -43,12 +43,4 @@ bool SpriteBoundingBoxData::loadFromStream(Common::SeekableReadStream &stream) {
 	return !stream.err();
 }
 
-bool SpriteBoundingBoxData::loadFromBuffer(const uint8 *buf, uint32 size) {
-	if (size == 0) {
-		return false;
-	}
-	Common::MemoryReadStream stream(buf, size);
-	return loadFromStream(stream);
-}
-
 } // End of namespace TwinE
diff --git a/engines/twine/parser/sprite.h b/engines/twine/parser/sprite.h
index 75f09259d1..a2dca2645f 100644
--- a/engines/twine/parser/sprite.h
+++ b/engines/twine/parser/sprite.h
@@ -26,18 +26,17 @@
 #include "common/array.h"
 #include "common/memstream.h"
 #include "common/stream.h"
+#include "twine/parser/parser.h"
 #include "twine/shared.h"
 
 namespace TwinE {
 
-class SpriteBoundingBoxData {
+class SpriteBoundingBoxData : public Parser {
 private:
 	Common::Array<BoundingBox> _boundingBoxes;
 
 public:
-	bool loadFromStream(Common::SeekableReadStream &stream);
-
-	bool loadFromBuffer(const uint8 *buf, uint32 size);
+	bool loadFromStream(Common::SeekableReadStream &stream) override;
 
 	const BoundingBox *bbox(int index) const;
 };
diff --git a/engines/twine/resources.cpp b/engines/twine/resources.cpp
index 45a3d3efef..47adab4692 100644
--- a/engines/twine/resources.cpp
+++ b/engines/twine/resources.cpp
@@ -22,9 +22,9 @@
 
 #include "twine/resources.h"
 #include "common/util.h"
-#include "twine/scene/animations.h"
 #include "twine/audio/sound.h"
 #include "twine/renderer/screens.h"
+#include "twine/scene/animations.h"
 #include "twine/scene/scene.h"
 #include "twine/text.h"
 


Commit: 48d71f82b310a22da44352e0e67e71eaef30eeee
    https://github.com/scummvm/scummvm/commit/48d71f82b310a22da44352e0e67e71eaef30eeee
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: extended parser to load from hqr

Changed paths:
    engines/twine/parser/parser.cpp
    engines/twine/parser/parser.h
    engines/twine/parser/sprite.cpp
    engines/twine/parser/sprite.h


diff --git a/engines/twine/parser/parser.cpp b/engines/twine/parser/parser.cpp
index 6ee2f48e52..8b20a9ae96 100644
--- a/engines/twine/parser/parser.cpp
+++ b/engines/twine/parser/parser.cpp
@@ -22,6 +22,7 @@
 
 #include "twine/parser/parser.h"
 #include "common/stream.h"
+#include "twine/hqr.h"
 #include "twine/shared.h"
 
 namespace TwinE {
@@ -34,4 +35,19 @@ bool Parser::loadFromBuffer(const uint8 *buf, uint32 size) {
 	return loadFromStream(stream);
 }
 
+bool Parser::loadFromHQR(const char *name, int index) {
+	uint8 *buf = nullptr;
+	const int32 size = HQR::getAllocEntry(&buf, name, index);
+	if (size == 0) {
+		warning("Failed to load %s with index %i", name, index);
+		return false;
+	}
+	if (!loadFromBuffer(buf, size)) {
+		free(buf);
+		return false;
+	}
+	free(buf);
+	return true;
+}
+
 } // End of namespace TwinE
diff --git a/engines/twine/parser/parser.h b/engines/twine/parser/parser.h
index 8c242e91fa..6b09b029d3 100644
--- a/engines/twine/parser/parser.h
+++ b/engines/twine/parser/parser.h
@@ -36,6 +36,7 @@ public:
 	virtual bool loadFromStream(Common::SeekableReadStream &stream) = 0;
 
 	bool loadFromBuffer(const uint8 *buf, uint32 size);
+	bool loadFromHQR(const char *name, int index);
 };
 
 } // End of namespace TwinE
diff --git a/engines/twine/parser/sprite.cpp b/engines/twine/parser/sprite.cpp
index 208dbc76d6..5ef7046ae6 100644
--- a/engines/twine/parser/sprite.cpp
+++ b/engines/twine/parser/sprite.cpp
@@ -30,15 +30,18 @@ bool SpriteBoundingBoxData::loadFromStream(Common::SeekableReadStream &stream) {
 	const int32 size = stream.size();
 	const int32 amount = size / 16;
 	for (int32 i = 0; i < amount; ++i) {
-		stream.skip(4);
-		BoundingBox bbox;
-		bbox.mins.x = stream.readSint16LE();
-		bbox.maxs.x = stream.readSint16LE();
-		bbox.mins.y = stream.readSint16LE();
-		bbox.maxs.y = stream.readSint16LE();
-		bbox.mins.z = stream.readSint16LE();
-		bbox.maxs.z = stream.readSint16LE();
-		_boundingBoxes.push_back(bbox);
+		SpriteDim spriteDim;
+		spriteDim.x = stream.readSint16LE();
+		spriteDim.y = stream.readSint16LE();
+		BoundingBox boundingBox;
+		boundingBox.mins.x = stream.readSint16LE();
+		boundingBox.maxs.x = stream.readSint16LE();
+		boundingBox.mins.y = stream.readSint16LE();
+		boundingBox.maxs.y = stream.readSint16LE();
+		boundingBox.mins.z = stream.readSint16LE();
+		boundingBox.maxs.z = stream.readSint16LE();
+		_boundingBoxes.push_back(boundingBox);
+		_dimensions.push_back(spriteDim);
 	}
 	return !stream.err();
 }
diff --git a/engines/twine/parser/sprite.h b/engines/twine/parser/sprite.h
index a2dca2645f..080abf3aed 100644
--- a/engines/twine/parser/sprite.h
+++ b/engines/twine/parser/sprite.h
@@ -31,14 +31,23 @@
 
 namespace TwinE {
 
+struct SpriteDim {
+	int16 x = 0;
+	int16 y = 0;
+	int16 w = 0;
+	int16 h = 0;
+};
+
 class SpriteBoundingBoxData : public Parser {
 private:
 	Common::Array<BoundingBox> _boundingBoxes;
+	Common::Array<SpriteDim> _dimensions;
 
 public:
 	bool loadFromStream(Common::SeekableReadStream &stream) override;
 
 	const BoundingBox *bbox(int index) const;
+	const SpriteDim *dim(int index) const;
 };
 
 inline const BoundingBox *SpriteBoundingBoxData::bbox(int index) const {
@@ -48,6 +57,13 @@ inline const BoundingBox *SpriteBoundingBoxData::bbox(int index) const {
 	return &_boundingBoxes[index];
 }
 
+inline const SpriteDim *SpriteBoundingBoxData::dim(int index) const {
+	if (index < 0) {
+		return nullptr;
+	}
+	return &_dimensions[index];
+}
+
 } // End of namespace TwinE
 
 #endif


Commit: bd5dff89126055b61531d56ab375f714c2c524f2
    https://github.com/scummvm/scummvm/commit/bd5dff89126055b61531d56ab375f714c2c524f2
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: use the SpriteBoundingBoxData class for parsing

Changed paths:
    engines/twine/renderer/redraw.cpp
    engines/twine/resources.cpp
    engines/twine/resources.h
    engines/twine/scene/actor.cpp
    engines/twine/scene/collision.cpp
    engines/twine/scene/extra.cpp


diff --git a/engines/twine/renderer/redraw.cpp b/engines/twine/renderer/redraw.cpp
index b901eba6a8..0eff179cbe 100644
--- a/engines/twine/renderer/redraw.cpp
+++ b/engines/twine/renderer/redraw.cpp
@@ -24,6 +24,7 @@
 #include "common/memstream.h"
 #include "common/textconsole.h"
 #include "graphics/surface.h"
+#include "twine/parser/sprite.h"
 #include "twine/scene/actor.h"
 #include "twine/scene/animations.h"
 #include "twine/audio/sound.h"
@@ -421,10 +422,9 @@ void Redraw::processDrawListActorSprites(const DrawListStruct &drawCmd, bool bgR
 	_engine->_grid->getSpriteSize(0, &spriteWidth, &spriteHeight, spritePtr);
 
 	// calculate sprite position on screen
-	Common::MemoryReadStream stream(_engine->_resources->spriteBoundingBoxPtr, _engine->_resources->spriteBoundingBoxSize);
-	stream.seek(actor2->entity * 16);
-	renderRect.left = _engine->_renderer->projPosX + stream.readSint16LE();
-	renderRect.top = _engine->_renderer->projPosY + stream.readSint16LE();
+	const SpriteDim* dim = _engine->_resources->spriteBoundingBox.dim(actor2->entity);
+	renderRect.left = _engine->_renderer->projPosX + dim->x;
+	renderRect.top = _engine->_renderer->projPosY + dim->y;
 	renderRect.right = renderRect.left + spriteWidth;
 	renderRect.bottom = renderRect.top + spriteHeight;
 
@@ -480,10 +480,9 @@ void Redraw::processDrawListExtras(const DrawListStruct &drawCmd) {
 		_engine->_grid->getSpriteSize(0, &spriteWidth, &spriteHeight, _engine->_resources->spriteTable[extra->info0]);
 
 		// calculate sprite position on screen
-		Common::MemoryReadStream stream(_engine->_resources->spriteBoundingBoxPtr, _engine->_resources->spriteBoundingBoxSize);
-		stream.seek(extra->info0 * 16);
-		renderRect.left = _engine->_renderer->projPosX + stream.readSint16LE();
-		renderRect.top = _engine->_renderer->projPosY + stream.readSint16LE();
+		const SpriteDim* dim = _engine->_resources->spriteBoundingBox.dim(extra->info0);
+		renderRect.left = _engine->_renderer->projPosX + dim->x;
+		renderRect.top = _engine->_renderer->projPosY + dim->y;
 		renderRect.right = renderRect.left + spriteWidth;
 		renderRect.bottom = renderRect.top + spriteHeight;
 
@@ -573,13 +572,9 @@ void Redraw::renderOverlays() {
 				int32 spriteWidth, spriteHeight;
 				_engine->_grid->getSpriteSize(0, &spriteWidth, &spriteHeight, spritePtr);
 
-				Common::MemoryReadStream stream(_engine->_resources->spriteBoundingBoxPtr, _engine->_resources->spriteBoundingBoxSize);
-				stream.seek(overlay->info0 * 16);
-				const int16 offsetX = stream.readSint16LE();
-				const int16 offsetY = stream.readSint16LE();
-
-				renderRect.left = offsetX + overlay->x;
-				renderRect.top = offsetY + overlay->y;
+				const SpriteDim* dim = _engine->_resources->spriteBoundingBox.dim(overlay->info0);
+				renderRect.left = dim->x + overlay->x;
+				renderRect.top = dim->y + overlay->y;
 				renderRect.right = renderRect.left + spriteWidth;
 				renderRect.bottom = renderRect.top + spriteHeight;
 
diff --git a/engines/twine/resources.cpp b/engines/twine/resources.cpp
index 47adab4692..93d90bccc7 100644
--- a/engines/twine/resources.cpp
+++ b/engines/twine/resources.cpp
@@ -45,7 +45,6 @@ Resources::~Resources() {
 	}
 	free(fontPtr);
 	free(spriteShadowPtr);
-	free(spriteBoundingBoxPtr);
 	free(holomapSurfacePtr);
 	free(holomapImagePtr);
 	free(holomapTwinsenModelPtr);
@@ -141,9 +140,8 @@ void Resources::initResources() {
 		error("Failed to load sprite shadow");
 	}
 
-	spriteBoundingBoxSize = HQR::getAllocEntry(&spriteBoundingBoxPtr, Resources::HQR_RESS_FILE, RESSHQR_SPRITEBOXDATA);
-	if (spriteBoundingBoxSize == 0) {
-		error("Failed to load actors bounding box data");
+	if (!spriteBoundingBox.loadFromHQR(Resources::HQR_RESS_FILE, RESSHQR_SPRITEBOXDATA)) {
+		error("Failed to load sprite bounding box data");
 	}
 
 	holomapSurfaceSize = HQR::getAllocEntry(&holomapSurfacePtr, Resources::HQR_RESS_FILE, RESSHQR_HOLOSURFACE);
diff --git a/engines/twine/resources.h b/engines/twine/resources.h
index 874bf58b9d..c5aab8b6a9 100644
--- a/engines/twine/resources.h
+++ b/engines/twine/resources.h
@@ -24,6 +24,7 @@
 #define TWINE_RESOURCES_H
 
 #include "common/scummsys.h"
+#include "twine/parser/sprite.h"
 #include "twine/scene/gamestate.h"
 #include "twine/hqr.h"
 
@@ -171,8 +172,7 @@ public:
 
 	uint32 spriteShadowSize = 0;
 	uint8 *spriteShadowPtr = nullptr;
-	uint32 spriteBoundingBoxSize = 0;
-	uint8 *spriteBoundingBoxPtr = nullptr;
+	SpriteBoundingBoxData spriteBoundingBox;
 
 	uint32 holomapSurfaceSize = 0;
 	uint8 *holomapSurfacePtr = nullptr;
diff --git a/engines/twine/scene/actor.cpp b/engines/twine/scene/actor.cpp
index 97c5613579..aa3d37a5b0 100644
--- a/engines/twine/scene/actor.cpp
+++ b/engines/twine/scene/actor.cpp
@@ -153,18 +153,15 @@ void Actor::initSpriteActor(int32 actorIdx) {
 	ActorStruct *localActor = _engine->_scene->getActor(actorIdx);
 
 	if (localActor->staticFlags.bIsSpriteActor && localActor->sprite != -1 && localActor->entity != localActor->sprite) {
-		Common::MemoryReadStream stream(_engine->_resources->spriteBoundingBoxPtr, _engine->_resources->spriteBoundingBoxSize);
-		stream.seek(localActor->sprite * 16);
-		stream.skip(4);
-
+		const BoundingBox *spritebbox = _engine->_resources->spriteBoundingBox.bbox(localActor->sprite);
 		localActor->entity = localActor->sprite;
 		ZVBox &bbox = localActor->boudingBox;
-		bbox.x.bottomLeft = stream.readSint16LE();
-		bbox.x.topRight = stream.readSint16LE();
-		bbox.y.bottomLeft = stream.readSint16LE();
-		bbox.y.topRight = stream.readSint16LE();
-		bbox.z.bottomLeft = stream.readSint16LE();
-		bbox.z.topRight = stream.readSint16LE();
+		bbox.x.bottomLeft = spritebbox->mins.x;
+		bbox.x.topRight = spritebbox->maxs.x;
+		bbox.y.bottomLeft = spritebbox->mins.y;
+		bbox.y.topRight = spritebbox->maxs.y;
+		bbox.z.bottomLeft = spritebbox->mins.z;
+		bbox.z.topRight = spritebbox->maxs.z;
 	}
 }
 
diff --git a/engines/twine/scene/collision.cpp b/engines/twine/scene/collision.cpp
index a3aaefcfe3..36f732f08a 100644
--- a/engines/twine/scene/collision.cpp
+++ b/engines/twine/scene/collision.cpp
@@ -469,16 +469,13 @@ void Collision::stopFalling() { // ReceptionObj()
 }
 
 int32 Collision::checkExtraCollisionWithActors(ExtraListStruct *extra, int32 actorIdx) {
-	Common::MemoryReadStream stream(_engine->_resources->spriteBoundingBoxPtr, _engine->_resources->spriteBoundingBoxSize);
-	stream.seek(extra->info0 * 16);
-	stream.skip(4);
-
-	const int32 xLeft = stream.readSint16LE() + extra->x;
-	const int32 xRight = stream.readSint16LE() + extra->x;
-	const int32 yLeft = stream.readSint16LE() + extra->y;
-	const int32 yRight = stream.readSint16LE() + extra->y;
-	const int32 zLeft = stream.readSint16LE() + extra->z;
-	const int32 zRight = stream.readSint16LE() + extra->z;
+	const BoundingBox *bbox = _engine->_resources->spriteBoundingBox.bbox(extra->info0);
+	const int32 xLeft = bbox->mins.x + extra->x;
+	const int32 xRight = bbox->maxs.x + extra->x;
+	const int32 yLeft = bbox->mins.y + extra->y;
+	const int32 yRight = bbox->maxs.y + extra->y;
+	const int32 zLeft = bbox->mins.z + extra->z;
+	const int32 zRight = bbox->maxs.z + extra->z;
 
 	for (int32 a = 0; a < _engine->_scene->sceneNumActors; a++) {
 		const ActorStruct *actorTest = _engine->_scene->getActor(a);
@@ -529,28 +526,26 @@ bool Collision::checkExtraCollisionWithBricks(int32 x, int32 y, int32 z, int32 o
 }
 
 int32 Collision::checkExtraCollisionWithExtra(ExtraListStruct *extra, int32 extraIdx) const {
-	Common::MemoryReadStream stream(_engine->_resources->spriteBoundingBoxPtr, _engine->_resources->spriteBoundingBoxSize);
-	stream.seek(extra->info0 * 16);
-	stream.skip(4);
-
-	const int32 xLeft = stream.readSint16LE() + extra->x;
-	const int32 xRight = stream.readSint16LE() + extra->x;
-	const int32 yLeft = stream.readSint16LE() + extra->y;
-	const int32 yRight = stream.readSint16LE() + extra->y;
-	const int32 zLeft = stream.readSint16LE() + extra->z;
-	const int32 zRight = stream.readSint16LE() + extra->z;
+	int32 index = extra->info0;
+	const BoundingBox *bbox = _engine->_resources->spriteBoundingBox.bbox(index);
+	const int32 xLeft = bbox->mins.x + extra->x;
+	const int32 xRight = bbox->maxs.x + extra->x;
+	const int32 yLeft = bbox->mins.y + extra->y;
+	const int32 yRight = bbox->maxs.y + extra->y;
+	const int32 zLeft = bbox->mins.z + extra->z;
+	const int32 zRight = bbox->maxs.z + extra->z;
 
 	for (int32 i = 0; i < EXTRA_MAX_ENTRIES; i++) {
 		const ExtraListStruct *extraTest = &_engine->_extra->extraList[i];
 		if (i != extraIdx && extraTest->info0 != -1) {
-			// const int16 * spriteBoundingTest;
-			// spriteBoundingTest = (const int16*)(_engine->_resources->spriteBoundingBoxPtr + extraTest->info0 * 16 + 4);
-			const int32 xLeftTest = stream.readSint16LE() + extraTest->x;
-			const int32 xRightTest = stream.readSint16LE() + extraTest->x;
-			const int32 yLeftTest = stream.readSint16LE() + extraTest->y;
-			const int32 yRightTest = stream.readSint16LE() + extraTest->y;
-			const int32 zLeftTest = stream.readSint16LE() + extraTest->z;
-			const int32 zRightTest = stream.readSint16LE() + extraTest->z;
+			// TODO: shouldn't this be extraTest->info0 as index?
+			const BoundingBox *testbbox = _engine->_resources->spriteBoundingBox.bbox(++index);
+			const int32 xLeftTest = testbbox->mins.x + extraTest->x;
+			const int32 xRightTest = testbbox->maxs.x + extraTest->x;
+			const int32 yLeftTest = testbbox->mins.y + extraTest->y;
+			const int32 yRightTest = testbbox->maxs.y + extraTest->y;
+			const int32 zLeftTest = testbbox->mins.z + extraTest->z;
+			const int32 zRightTest = testbbox->maxs.z + extraTest->z;
 
 			if (xLeft < xLeftTest) {
 				if (xLeft < xRightTest && xRight > xLeftTest && yLeft < yRightTest && yRight > yLeftTest && zLeft < zRightTest && zRight > zLeftTest) {
diff --git a/engines/twine/scene/extra.cpp b/engines/twine/scene/extra.cpp
index 2dd199fc21..a2f0bb5817 100644
--- a/engines/twine/scene/extra.cpp
+++ b/engines/twine/scene/extra.cpp
@@ -861,10 +861,8 @@ void Extra::processExtras() {
 			}
 
 			if (process) {
-				Common::MemoryReadStream stream(_engine->_resources->spriteBoundingBoxPtr, _engine->_resources->spriteBoundingBoxSize);
-				stream.seek(extra->info0 * 16);
-				stream.skip(8);
-				extra->y = (_engine->_collision->collisionY << 8) + 0x100 - stream.readSint16LE();
+				const BoundingBox *bbox = _engine->_resources->spriteBoundingBox.bbox(extra->info0);
+				extra->y = (_engine->_collision->collisionY << 8) + 0x100 - bbox->mins.y;
 				extra->type &= ~(ExtraType::STOP_COL | ExtraType::FLY);
 				continue;
 			}


Commit: cb39a1f648455f075d71673c5dd4943fd1b593b4
    https://github.com/scummvm/scummvm/commit/cb39a1f648455f075d71673c5dd4943fd1b593b4
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: ported code from residualvm twin code to directly use a readstream for hqr ressources

Changed paths:
  A engines/twine/lzss.cpp
  A engines/twine/lzss.h
    engines/twine/hqr.cpp
    engines/twine/hqr.h
    engines/twine/module.mk


diff --git a/engines/twine/hqr.cpp b/engines/twine/hqr.cpp
index ace857b94f..5bae085b70 100644
--- a/engines/twine/hqr.cpp
+++ b/engines/twine/hqr.cpp
@@ -21,9 +21,11 @@
  */
 
 #include "twine/hqr.h"
+#include "twine/lzss.h"
 #include "common/debug.h"
 #include "common/file.h"
 #include "common/memstream.h"
+#include "common/substream.h"
 #include "common/system.h"
 #include "common/textconsole.h"
 
@@ -197,6 +199,43 @@ int32 numEntries(const char *filename) {
 	return ((int)headerSize / 4) - 1;
 }
 
+Common::SeekableReadStream *makeReadStream(const char *filename, int index) {
+	Common::File *file = new Common::File();
+	if (!file->open(filename)) {
+		delete file;
+		return nullptr;
+	}
+
+	const uint32 headerSize = file->readUint32LE();
+	if ((uint32)index >= headerSize / 4) {
+		warning("HQR: Invalid entry index");
+		delete file;
+		return nullptr;
+	}
+
+	file->seek(index * 4);
+	const uint32 offsetToData = file->readUint32LE();
+	file->seek(offsetToData);
+
+	const uint32 realSize = file->readUint32LE();
+	const uint32 compressedSize = file->readUint32LE();
+	const uint16 mode = file->readUint16LE();
+
+	const uint32 begin = offsetToData + 10;
+	uint32 end = 0;
+	if (mode == 0) {
+		end = begin + realSize;
+	} else {
+		end = begin + compressedSize;
+	}
+	Common::SeekableReadStream *stream = new Common::SeekableSubReadStream(file, begin, end, DisposeAfterUse::YES);
+	if (mode != 0) {
+		stream = new LzssReadStream(stream, mode, realSize);
+	}
+
+	return stream;
+}
+
 int32 getAllocEntry(uint8 **ptr, const char *filename, int32 index) {
 	if (*ptr) {
 		free(*ptr);
diff --git a/engines/twine/hqr.h b/engines/twine/hqr.h
index 154b4b53fc..79a6d4416e 100644
--- a/engines/twine/hqr.h
+++ b/engines/twine/hqr.h
@@ -24,6 +24,7 @@
 #define TWINE_HQR_H
 
 #include "common/scummsys.h"
+#include "common/stream.h"
 
 namespace TwinE {
 
@@ -87,6 +88,9 @@ int32 getVoxEntry(uint8 *ptr, const char *filename, int32 index, int32 hiddenInd
  * @return entry real size
  */
 int32 getAllocVoxEntry(uint8 **ptr, const char *filename, int32 index, int32 hiddenIndex);
+
+Common::SeekableReadStream *makeReadStream(const char *filename, int index);
+
 } // namespace HQR
 
 } // namespace TwinE
diff --git a/engines/twine/lzss.cpp b/engines/twine/lzss.cpp
new file mode 100644
index 0000000000..305cef3638
--- /dev/null
+++ b/engines/twine/lzss.cpp
@@ -0,0 +1,89 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/textconsole.h"
+
+#include "engines/twine/lzss.h"
+
+namespace TwinE {
+
+LzssReadStream::LzssReadStream(Common::ReadStream *indata, uint32 mode, uint32 realsize) {
+	_outLzssBufData = new uint8[realsize];
+	memset(_outLzssBufData, 0, realsize);
+	decodeLZSS(indata, mode, realsize);
+	_size = realsize;
+	_pos = 0;
+	delete indata;
+}
+
+LzssReadStream::~LzssReadStream() {
+	delete[] _outLzssBufData;
+}
+
+void LzssReadStream::decodeLZSS(Common::ReadStream *in, uint32 mode, uint32 dataSize) {
+	uint8 *dst = _outLzssBufData;
+
+	do {
+		uint8 b = in->readByte();
+		for (int32 d = 0; d < 8; d++) {
+			int32 length;
+			if (!(b & (1 << d))) {
+				uint16 offset = in->readUint16LE();
+				length = (offset & 0x0F) + (mode + 1);
+				uint8 *ptr = dst - (offset >> 4) - 1;
+				for (int32 i = 0; i < length; i++)
+					*(dst++) = *(ptr++);
+			} else {
+				length = 1;
+				*(dst++) = in->readByte();
+			}
+			dataSize -= length;
+			if (dataSize <= 0)
+				return;
+		}
+	} while (dataSize);
+}
+
+bool LzssReadStream::eos() const {
+	return _pos >= _size;
+}
+
+uint32 LzssReadStream::read(void *buf, uint32 dataSize) {
+	if (dataSize > _size - _pos)
+		error("LzssReadStream::read past end of buffer");
+
+	memcpy(buf, &_outLzssBufData[_pos], dataSize);
+	_pos += dataSize;
+
+	return dataSize;
+}
+
+bool LzssReadStream::seek(int32 offset, int whence) {
+	if (whence == SEEK_SET) {
+		_pos = offset;
+	} else if (whence == SEEK_CUR) {
+		_pos += offset;
+	}
+	return true;
+}
+
+} // namespace TwinE
diff --git a/engines/twine/lzss.h b/engines/twine/lzss.h
new file mode 100644
index 0000000000..ff7cd34e7f
--- /dev/null
+++ b/engines/twine/lzss.h
@@ -0,0 +1,47 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/stream.h"
+
+namespace TwinE {
+
+class LzssReadStream : public Common::SeekableReadStream {
+private:
+	uint8 *_outLzssBufData;
+	uint32 _size;
+	uint32 _pos;
+
+	void decodeLZSS(Common::ReadStream *indata, uint32 mode, uint32 length);
+
+public:
+	LzssReadStream(Common::ReadStream *indata, uint32 mode, uint32 realsize);
+	~LzssReadStream();
+
+	virtual int32 pos() const { return _pos; }
+	virtual int32 size() const { return _size; }
+	virtual bool seek(int32 offset, int whence = SEEK_SET);
+
+	bool eos() const;
+	uint32 read(void *buf, uint32 size);
+};
+
+} // namespace TwinE
diff --git a/engines/twine/module.mk b/engines/twine/module.mk
index 4b1ebfca2f..c5c0ad75da 100644
--- a/engines/twine/module.mk
+++ b/engines/twine/module.mk
@@ -40,6 +40,7 @@ MODULE_OBJS := \
 	holomap.o \
 	hqr.o \
 	input.o \
+	lzss.o \
 	metaengine.o \
 	resources.o \
 	text.o \


Commit: 9ab92f832006b8a0eb5909bc28856dadad33b3c2
    https://github.com/scummvm/scummvm/commit/9ab92f832006b8a0eb5909bc28856dadad33b3c2
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: let loadFromHQR use a read stream and not a buffer

Changed paths:
    engines/twine/parser/parser.cpp


diff --git a/engines/twine/parser/parser.cpp b/engines/twine/parser/parser.cpp
index 8b20a9ae96..d4e2d58c2b 100644
--- a/engines/twine/parser/parser.cpp
+++ b/engines/twine/parser/parser.cpp
@@ -36,17 +36,16 @@ bool Parser::loadFromBuffer(const uint8 *buf, uint32 size) {
 }
 
 bool Parser::loadFromHQR(const char *name, int index) {
-	uint8 *buf = nullptr;
-	const int32 size = HQR::getAllocEntry(&buf, name, index);
-	if (size == 0) {
+	Common::SeekableReadStream *stream = HQR::makeReadStream(name, index);
+	if (stream == nullptr) {
 		warning("Failed to load %s with index %i", name, index);
 		return false;
 	}
-	if (!loadFromBuffer(buf, size)) {
-		free(buf);
+	if (!loadFromStream(*stream)) {
+		delete stream;
 		return false;
 	}
-	free(buf);
+	delete stream;
 	return true;
 }
 


Commit: 06d2a71511f25f06a8ba8b0f0db702463c2979e4
    https://github.com/scummvm/scummvm/commit/06d2a71511f25f06a8ba8b0f0db702463c2979e4
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: moved resource management files into own subdir

Changed paths:
  A engines/twine/resources/hqr.cpp
  A engines/twine/resources/hqr.h
  A engines/twine/resources/lzss.cpp
  A engines/twine/resources/lzss.h
  A engines/twine/resources/resources.cpp
  A engines/twine/resources/resources.h
  R engines/twine/hqr.cpp
  R engines/twine/hqr.h
  R engines/twine/lzss.cpp
  R engines/twine/lzss.h
  R engines/twine/resources.cpp
  R engines/twine/resources.h
    engines/twine/audio/music.cpp
    engines/twine/audio/sound.cpp
    engines/twine/holomap.cpp
    engines/twine/menu/menu.cpp
    engines/twine/menu/menuoptions.cpp
    engines/twine/module.mk
    engines/twine/parser/parser.cpp
    engines/twine/renderer/redraw.cpp
    engines/twine/renderer/screens.cpp
    engines/twine/scene/actor.cpp
    engines/twine/scene/animations.cpp
    engines/twine/scene/collision.cpp
    engines/twine/scene/extra.cpp
    engines/twine/scene/gamestate.cpp
    engines/twine/scene/grid.cpp
    engines/twine/scene/scene.cpp
    engines/twine/script/script_life_v1.cpp
    engines/twine/text.cpp
    engines/twine/twine.cpp


diff --git a/engines/twine/audio/music.cpp b/engines/twine/audio/music.cpp
index 9e38dc40a1..45e2372d61 100644
--- a/engines/twine/audio/music.cpp
+++ b/engines/twine/audio/music.cpp
@@ -27,8 +27,8 @@
 #include "common/debug.h"
 #include "common/system.h"
 #include "common/textconsole.h"
-#include "twine/hqr.h"
-#include "twine/resources.h"
+#include "twine/resources/hqr.h"
+#include "twine/resources/resources.h"
 #include "twine/twine.h"
 
 namespace TwinE {
diff --git a/engines/twine/audio/sound.cpp b/engines/twine/audio/sound.cpp
index 128b5a8e89..b92261b9bd 100644
--- a/engines/twine/audio/sound.cpp
+++ b/engines/twine/audio/sound.cpp
@@ -30,9 +30,9 @@
 #include "twine/scene/collision.h"
 #include "twine/flamovies.h"
 #include "twine/scene/grid.h"
-#include "twine/hqr.h"
+#include "twine/resources/hqr.h"
 #include "twine/scene/movements.h"
-#include "twine/resources.h"
+#include "twine/resources/resources.h"
 #include "twine/text.h"
 #include "twine/twine.h"
 
diff --git a/engines/twine/holomap.cpp b/engines/twine/holomap.cpp
index e857851655..3e8c5db9b4 100644
--- a/engines/twine/holomap.cpp
+++ b/engines/twine/holomap.cpp
@@ -25,11 +25,11 @@
 #include "common/types.h"
 #include "twine/audio/sound.h"
 #include "twine/scene/gamestate.h"
-#include "twine/hqr.h"
+#include "twine/resources/hqr.h"
 #include "twine/menu/interface.h"
 #include "twine/renderer/renderer.h"
 #include "twine/renderer/screens.h"
-#include "twine/resources.h"
+#include "twine/resources/resources.h"
 #include "twine/scene/scene.h"
 #include "twine/text.h"
 #include "twine/twine.h"
diff --git a/engines/twine/menu/menu.cpp b/engines/twine/menu/menu.cpp
index ba4d7f8adc..a544c45c03 100644
--- a/engines/twine/menu/menu.cpp
+++ b/engines/twine/menu/menu.cpp
@@ -37,7 +37,7 @@
 #include "twine/audio/sound.h"
 #include "twine/scene/gamestate.h"
 #include "twine/scene/grid.h"
-#include "twine/hqr.h"
+#include "twine/resources/hqr.h"
 #include "twine/input.h"
 #include "twine/menu/interface.h"
 #include "twine/menu/menuoptions.h"
@@ -45,7 +45,7 @@
 #include "twine/renderer/redraw.h"
 #include "twine/renderer/renderer.h"
 #include "twine/renderer/screens.h"
-#include "twine/resources.h"
+#include "twine/resources/resources.h"
 #include "twine/scene/scene.h"
 #include "twine/text.h"
 #include "twine/twine.h"
diff --git a/engines/twine/menu/menuoptions.cpp b/engines/twine/menu/menuoptions.cpp
index e36baebc54..bedb5acc8c 100644
--- a/engines/twine/menu/menuoptions.cpp
+++ b/engines/twine/menu/menuoptions.cpp
@@ -35,7 +35,7 @@
 #include "twine/menu/interface.h"
 #include "twine/menu/menu.h"
 #include "twine/renderer/screens.h"
-#include "twine/resources.h"
+#include "twine/resources/resources.h"
 #include "twine/scene/scene.h"
 #include "twine/text.h"
 #include "twine/twine.h"
diff --git a/engines/twine/module.mk b/engines/twine/module.mk
index c5c0ad75da..e605ec791d 100644
--- a/engines/twine/module.mk
+++ b/engines/twine/module.mk
@@ -35,14 +35,15 @@ MODULE_OBJS := \
 	script/script_life_v1.o \
 	script/script_move_v1.o \
 	\
+	resources/hqr.o \
+	resources/lzss.o \
+	resources/resources.o \
+	\
 	detection.o \
 	flamovies.o \
 	holomap.o \
-	hqr.o \
 	input.o \
-	lzss.o \
 	metaengine.o \
-	resources.o \
 	text.o \
 	twine.o
 
diff --git a/engines/twine/parser/parser.cpp b/engines/twine/parser/parser.cpp
index d4e2d58c2b..fac5b5b069 100644
--- a/engines/twine/parser/parser.cpp
+++ b/engines/twine/parser/parser.cpp
@@ -22,7 +22,7 @@
 
 #include "twine/parser/parser.h"
 #include "common/stream.h"
-#include "twine/hqr.h"
+#include "twine/resources/hqr.h"
 #include "twine/shared.h"
 
 namespace TwinE {
diff --git a/engines/twine/renderer/redraw.cpp b/engines/twine/renderer/redraw.cpp
index 0eff179cbe..362bec9cea 100644
--- a/engines/twine/renderer/redraw.cpp
+++ b/engines/twine/renderer/redraw.cpp
@@ -31,14 +31,14 @@
 #include "twine/scene/collision.h"
 #include "twine/debugger/debug_scene.h"
 #include "twine/scene/grid.h"
-#include "twine/hqr.h"
+#include "twine/resources/hqr.h"
 #include "twine/input.h"
 #include "twine/menu/interface.h"
 #include "twine/menu/menu.h"
 #include "twine/scene/movements.h"
 #include "twine/renderer/renderer.h"
 #include "twine/renderer/screens.h"
-#include "twine/resources.h"
+#include "twine/resources/resources.h"
 #include "twine/scene/scene.h"
 #include "twine/text.h"
 
diff --git a/engines/twine/renderer/screens.cpp b/engines/twine/renderer/screens.cpp
index f4eb8ee45e..a819a48a21 100644
--- a/engines/twine/renderer/screens.cpp
+++ b/engines/twine/renderer/screens.cpp
@@ -24,8 +24,8 @@
 #include "common/system.h"
 #include "graphics/surface.h"
 #include "twine/audio/music.h"
-#include "twine/hqr.h"
-#include "twine/resources.h"
+#include "twine/resources/hqr.h"
+#include "twine/resources/resources.h"
 #include "twine/twine.h"
 
 namespace TwinE {
diff --git a/engines/twine/hqr.cpp b/engines/twine/resources/hqr.cpp
similarity index 99%
rename from engines/twine/hqr.cpp
rename to engines/twine/resources/hqr.cpp
index 5bae085b70..836bd6ebdb 100644
--- a/engines/twine/hqr.cpp
+++ b/engines/twine/resources/hqr.cpp
@@ -20,8 +20,8 @@
  *
  */
 
-#include "twine/hqr.h"
-#include "twine/lzss.h"
+#include "twine/resources/hqr.h"
+#include "twine/resources/lzss.h"
 #include "common/debug.h"
 #include "common/file.h"
 #include "common/memstream.h"
diff --git a/engines/twine/hqr.h b/engines/twine/resources/hqr.h
similarity index 100%
rename from engines/twine/hqr.h
rename to engines/twine/resources/hqr.h
diff --git a/engines/twine/lzss.cpp b/engines/twine/resources/lzss.cpp
similarity index 98%
rename from engines/twine/lzss.cpp
rename to engines/twine/resources/lzss.cpp
index 305cef3638..c3cc9f4cff 100644
--- a/engines/twine/lzss.cpp
+++ b/engines/twine/resources/lzss.cpp
@@ -21,8 +21,7 @@
  */
 
 #include "common/textconsole.h"
-
-#include "engines/twine/lzss.h"
+#include "twine/resources/lzss.h"
 
 namespace TwinE {
 
diff --git a/engines/twine/lzss.h b/engines/twine/resources/lzss.h
similarity index 100%
rename from engines/twine/lzss.h
rename to engines/twine/resources/lzss.h
diff --git a/engines/twine/resources.cpp b/engines/twine/resources/resources.cpp
similarity index 99%
rename from engines/twine/resources.cpp
rename to engines/twine/resources/resources.cpp
index 93d90bccc7..cfec2524ab 100644
--- a/engines/twine/resources.cpp
+++ b/engines/twine/resources/resources.cpp
@@ -20,7 +20,7 @@
  *
  */
 
-#include "twine/resources.h"
+#include "twine/resources/resources.h"
 #include "common/util.h"
 #include "twine/audio/sound.h"
 #include "twine/renderer/screens.h"
diff --git a/engines/twine/resources.h b/engines/twine/resources/resources.h
similarity index 99%
rename from engines/twine/resources.h
rename to engines/twine/resources/resources.h
index c5aab8b6a9..5c838d6c33 100644
--- a/engines/twine/resources.h
+++ b/engines/twine/resources/resources.h
@@ -26,7 +26,7 @@
 #include "common/scummsys.h"
 #include "twine/parser/sprite.h"
 #include "twine/scene/gamestate.h"
-#include "twine/hqr.h"
+#include "twine/resources/hqr.h"
 
 namespace TwinE {
 
diff --git a/engines/twine/scene/actor.cpp b/engines/twine/scene/actor.cpp
index aa3d37a5b0..fa11baa808 100644
--- a/engines/twine/scene/actor.cpp
+++ b/engines/twine/scene/actor.cpp
@@ -25,11 +25,11 @@
 #include "common/system.h"
 #include "common/textconsole.h"
 #include "twine/audio/sound.h"
-#include "twine/hqr.h"
+#include "twine/resources/hqr.h"
 #include "twine/parser/entity.h"
 #include "twine/renderer/renderer.h"
 #include "twine/renderer/screens.h"
-#include "twine/resources.h"
+#include "twine/resources/resources.h"
 #include "twine/scene/animations.h"
 #include "twine/scene/extra.h"
 #include "twine/scene/gamestate.h"
diff --git a/engines/twine/scene/animations.cpp b/engines/twine/scene/animations.cpp
index fe46f6d858..dcf8e6a1f5 100644
--- a/engines/twine/scene/animations.cpp
+++ b/engines/twine/scene/animations.cpp
@@ -31,7 +31,7 @@
 #include "twine/parser/anim.h"
 #include "twine/parser/entity.h"
 #include "twine/renderer/renderer.h"
-#include "twine/resources.h"
+#include "twine/resources/resources.h"
 #include "twine/scene/actor.h"
 #include "twine/scene/collision.h"
 #include "twine/scene/gamestate.h"
diff --git a/engines/twine/scene/collision.cpp b/engines/twine/scene/collision.cpp
index 36f732f08a..32099da48e 100644
--- a/engines/twine/scene/collision.cpp
+++ b/engines/twine/scene/collision.cpp
@@ -25,7 +25,7 @@
 #include "common/memstream.h"
 #include "common/util.h"
 #include "twine/renderer/renderer.h"
-#include "twine/resources.h"
+#include "twine/resources/resources.h"
 #include "twine/scene/actor.h"
 #include "twine/scene/animations.h"
 #include "twine/scene/extra.h"
diff --git a/engines/twine/scene/extra.cpp b/engines/twine/scene/extra.cpp
index a2f0bb5817..530d09d0a8 100644
--- a/engines/twine/scene/extra.cpp
+++ b/engines/twine/scene/extra.cpp
@@ -28,7 +28,7 @@
 #include "twine/menu/interface.h"
 #include "twine/renderer/redraw.h"
 #include "twine/renderer/renderer.h"
-#include "twine/resources.h"
+#include "twine/resources/resources.h"
 #include "twine/scene/actor.h"
 #include "twine/scene/collision.h"
 #include "twine/scene/gamestate.h"
diff --git a/engines/twine/scene/gamestate.cpp b/engines/twine/scene/gamestate.cpp
index 4592ff8147..c6d2cb04eb 100644
--- a/engines/twine/scene/gamestate.cpp
+++ b/engines/twine/scene/gamestate.cpp
@@ -36,7 +36,7 @@
 #include "twine/renderer/redraw.h"
 #include "twine/renderer/renderer.h"
 #include "twine/renderer/screens.h"
-#include "twine/resources.h"
+#include "twine/resources/resources.h"
 #include "twine/scene/actor.h"
 #include "twine/scene/animations.h"
 #include "twine/scene/collision.h"
diff --git a/engines/twine/scene/grid.cpp b/engines/twine/scene/grid.cpp
index 4ddcf8423c..7af19ef610 100644
--- a/engines/twine/scene/grid.cpp
+++ b/engines/twine/scene/grid.cpp
@@ -28,7 +28,7 @@
 #include "twine/renderer/redraw.h"
 #include "twine/renderer/renderer.h"
 #include "twine/renderer/screens.h"
-#include "twine/resources.h"
+#include "twine/resources/resources.h"
 #include "twine/scene/actor.h"
 #include "twine/scene/collision.h"
 #include "twine/scene/scene.h"
diff --git a/engines/twine/scene/scene.cpp b/engines/twine/scene/scene.cpp
index 6b3d8a5f74..7ebc704551 100644
--- a/engines/twine/scene/scene.cpp
+++ b/engines/twine/scene/scene.cpp
@@ -31,7 +31,7 @@
 #include "twine/renderer/redraw.h"
 #include "twine/renderer/renderer.h"
 #include "twine/renderer/screens.h"
-#include "twine/resources.h"
+#include "twine/resources/resources.h"
 #include "twine/scene/actor.h"
 #include "twine/scene/animations.h"
 #include "twine/scene/extra.h"
diff --git a/engines/twine/script/script_life_v1.cpp b/engines/twine/script/script_life_v1.cpp
index 50bf5a4252..e65fbbb7e7 100644
--- a/engines/twine/script/script_life_v1.cpp
+++ b/engines/twine/script/script_life_v1.cpp
@@ -39,7 +39,7 @@
 #include "twine/renderer/redraw.h"
 #include "twine/renderer/renderer.h"
 #include "twine/renderer/screens.h"
-#include "twine/resources.h"
+#include "twine/resources/resources.h"
 #include "twine/scene/scene.h"
 #include "twine/text.h"
 #include "twine/twine.h"
diff --git a/engines/twine/text.cpp b/engines/twine/text.cpp
index f638368a53..e99ee7e3eb 100644
--- a/engines/twine/text.cpp
+++ b/engines/twine/text.cpp
@@ -28,13 +28,13 @@
 #include "common/str.h"
 #include "common/system.h"
 #include "twine/audio/sound.h"
-#include "twine/hqr.h"
+#include "twine/resources/hqr.h"
 #include "twine/input.h"
 #include "twine/menu/interface.h"
 #include "twine/menu/menu.h"
 #include "twine/renderer/renderer.h"
 #include "twine/renderer/screens.h"
-#include "twine/resources.h"
+#include "twine/resources/resources.h"
 #include "twine/scene/scene.h"
 #include "twine/twine.h"
 
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 79c16d7ff4..535df2a0c2 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -57,7 +57,7 @@
 #include "twine/scene/gamestate.h"
 #include "twine/scene/grid.h"
 #include "twine/holomap.h"
-#include "twine/hqr.h"
+#include "twine/resources/hqr.h"
 #include "twine/input.h"
 #include "twine/menu/interface.h"
 #include "twine/menu/menu.h"
@@ -66,7 +66,7 @@
 #include "twine/renderer/redraw.h"
 #include "twine/renderer/renderer.h"
 #include "twine/renderer/screens.h"
-#include "twine/resources.h"
+#include "twine/resources/resources.h"
 #include "twine/scene/scene.h"
 #include "twine/script/script_life_v1.h"
 #include "twine/script/script_move_v1.h"


Commit: 80181d111c931a310c5b3bf3a53bae941052e9f1
    https://github.com/scummvm/scummvm/commit/80181d111c931a310c5b3bf3a53bae941052e9f1
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: bit extraction helper

Changed paths:
    engines/twine/shared.h


diff --git a/engines/twine/shared.h b/engines/twine/shared.h
index 05be1753df..a0f5c67e86 100644
--- a/engines/twine/shared.h
+++ b/engines/twine/shared.h
@@ -215,6 +215,11 @@ inline constexpr int32 ClampAngle(int32 angle) {
 	return angle & (ANGLE_360 - 1);
 }
 
+template<typename T>
+inline constexpr T bits(T value, uint8 offset, uint8 bits) {
+	return (((1 << bits) - 1) & (value >> offset));
+}
+
 }
 
 #endif


Commit: e20d35b03ed689a35be04a23ce64879fb8e4ff3d
    https://github.com/scummvm/scummvm/commit/e20d35b03ed689a35be04a23ce64879fb8e4ff3d
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: moved sprite specific offset

Changed paths:
    engines/twine/scene/grid.cpp


diff --git a/engines/twine/scene/grid.cpp b/engines/twine/scene/grid.cpp
index 7af19ef610..0897418dce 100644
--- a/engines/twine/scene/grid.cpp
+++ b/engines/twine/scene/grid.cpp
@@ -469,15 +469,12 @@ void Grid::drawBrick(int32 index, int32 posX, int32 posY) {
 }
 
 void Grid::drawSprite(int32 index, int32 posX, int32 posY, const uint8 *ptr) {
+	ptr = ptr + READ_LE_INT32(ptr + index * 4);
 	drawBrickSprite(index, posX, posY, ptr, true);
 }
 
 // WARNING: Rewrite this function to have better performance
 void Grid::drawBrickSprite(int32 index, int32 posX, int32 posY, const uint8 *ptr, bool isSprite) {
-	if (isSprite) {
-		ptr = ptr + READ_LE_INT32(ptr + index * 4);
-	}
-
 	int32 left = posX + *(ptr + 2);
 	int32 top = posY + *(ptr + 3);
 	int32 right = *ptr + left - 1;


Commit: 30d67202bb85d7262eae5515ec0fa2a0d2f1f0ff
    https://github.com/scummvm/scummvm/commit/30d67202bb85d7262eae5515ec0fa2a0d2f1f0ff
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: const + removed unused variables

Changed paths:
    engines/twine/scene/grid.cpp


diff --git a/engines/twine/scene/grid.cpp b/engines/twine/scene/grid.cpp
index 0897418dce..fe1a28fa1a 100644
--- a/engines/twine/scene/grid.cpp
+++ b/engines/twine/scene/grid.cpp
@@ -475,26 +475,17 @@ void Grid::drawSprite(int32 index, int32 posX, int32 posY, const uint8 *ptr) {
 
 // WARNING: Rewrite this function to have better performance
 void Grid::drawBrickSprite(int32 index, int32 posX, int32 posY, const uint8 *ptr, bool isSprite) {
-	int32 left = posX + *(ptr + 2);
-	int32 top = posY + *(ptr + 3);
-	int32 right = *ptr + left - 1;
-	int32 bottom = *(ptr + 1) + top - 1;
+	const int32 left = posX + *(ptr + 2);
+	const int32 top = posY + *(ptr + 3);
+	const int32 bottom = *(ptr + 1) + top;
 
 	ptr += 4;
 
 	int32 x = left;
-	int32 y = top;
 
 	//if (left >= textWindowLeft-2 && top >= textWindowTop-2 && right <= textWindowRight-2 && bottom <= textWindowBottom-2) // crop
 	{
-		right++;
-		bottom++;
-
-		uint8 *outPtr = (uint8 *)_engine->frontVideoBuffer.getBasePtr(left, top);
-
-		int32 offset = -((right - left) - SCREEN_WIDTH);
-
-		for (int32 c1 = 0; c1 < bottom - top; c1++) {
+		for (int32 y = top; y < bottom; y++) {
 			int32 vc3 = *(ptr++);
 			for (int32 c2 = 0; c2 < vc3; c2++) {
 				int32 temp = *(ptr++);
@@ -509,7 +500,6 @@ void Grid::drawBrickSprite(int32 index, int32 posX, int32 posY, const uint8 *ptr
 							}
 
 							x++;
-							outPtr++;
 						}
 					} else {
 						for (int32 i = 0; i < iteration; i++) {
@@ -519,17 +509,13 @@ void Grid::drawBrickSprite(int32 index, int32 posX, int32 posY, const uint8 *ptr
 
 							x++;
 							ptr++;
-							outPtr++;
 						}
 					}
 				} else {
-					outPtr += iteration + 1;
 					x += iteration + 1;
 				}
 			}
-			outPtr += offset;
 			x = left;
-			y++;
 		}
 	}
 }


Commit: d0721f3586c7ce13854de180b4969a3fa4614d72
    https://github.com/scummvm/scummvm/commit/d0721f3586c7ce13854de180b4969a3fa4614d72
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: const for Grid::drawBrickSprite

Changed paths:
    engines/twine/scene/grid.cpp


diff --git a/engines/twine/scene/grid.cpp b/engines/twine/scene/grid.cpp
index fe1a28fa1a..f4f9149002 100644
--- a/engines/twine/scene/grid.cpp
+++ b/engines/twine/scene/grid.cpp
@@ -486,23 +486,22 @@ void Grid::drawBrickSprite(int32 index, int32 posX, int32 posY, const uint8 *ptr
 	//if (left >= textWindowLeft-2 && top >= textWindowTop-2 && right <= textWindowRight-2 && bottom <= textWindowBottom-2) // crop
 	{
 		for (int32 y = top; y < bottom; y++) {
-			int32 vc3 = *(ptr++);
+			uint8 vc3 = *(ptr++);
 			for (int32 c2 = 0; c2 < vc3; c2++) {
-				int32 temp = *(ptr++);
-				int32 iteration = temp & 0x3F;
+				const uint8 temp = *(ptr++);
+				const uint8 iteration = (temp & 0x3F) + 1;
 				if (temp & 0xC0) {
-					iteration++;
 					if (!(temp & 0x40)) {
-						temp = *(ptr++);
-						for (int32 i = 0; i < iteration; i++) {
+						const uint8 pixel = *ptr++;
+						for (uint8 i = 0; i < iteration; i++) {
 							if (x >= _engine->_interface->textWindow.left && x < _engine->_interface->textWindow.right && y >= _engine->_interface->textWindow.top && y < _engine->_interface->textWindow.bottom) {
-								*(uint8 *)_engine->frontVideoBuffer.getBasePtr(x, y) = temp;
+								*(uint8 *)_engine->frontVideoBuffer.getBasePtr(x, y) = pixel;
 							}
 
 							x++;
 						}
 					} else {
-						for (int32 i = 0; i < iteration; i++) {
+						for (uint8 i = 0; i < iteration; i++) {
 							if (x >= _engine->_interface->textWindow.left && x < _engine->_interface->textWindow.right && y >= _engine->_interface->textWindow.top && y < _engine->_interface->textWindow.bottom) {
 								*(uint8 *)_engine->frontVideoBuffer.getBasePtr(x, y) = *ptr;
 							}
@@ -512,7 +511,7 @@ void Grid::drawBrickSprite(int32 index, int32 posX, int32 posY, const uint8 *ptr
 						}
 					}
 				} else {
-					x += iteration + 1;
+					x += iteration;
 				}
 			}
 			x = left;


Commit: fe51a71c28fbe1f20f4a453cbd05bfb88bef2348
    https://github.com/scummvm/scummvm/commit/fe51a71c28fbe1f20f4a453cbd05bfb88bef2348
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: use bit extraction helper in Grid::drawBrickSprite

Changed paths:
    engines/twine/scene/grid.cpp


diff --git a/engines/twine/scene/grid.cpp b/engines/twine/scene/grid.cpp
index f4f9149002..ff937def94 100644
--- a/engines/twine/scene/grid.cpp
+++ b/engines/twine/scene/grid.cpp
@@ -488,30 +488,31 @@ void Grid::drawBrickSprite(int32 index, int32 posX, int32 posY, const uint8 *ptr
 		for (int32 y = top; y < bottom; y++) {
 			uint8 vc3 = *(ptr++);
 			for (int32 c2 = 0; c2 < vc3; c2++) {
-				const uint8 temp = *(ptr++);
-				const uint8 iteration = (temp & 0x3F) + 1;
-				if (temp & 0xC0) {
-					if (!(temp & 0x40)) {
-						const uint8 pixel = *ptr++;
-						for (uint8 i = 0; i < iteration; i++) {
-							if (x >= _engine->_interface->textWindow.left && x < _engine->_interface->textWindow.right && y >= _engine->_interface->textWindow.top && y < _engine->_interface->textWindow.bottom) {
-								*(uint8 *)_engine->frontVideoBuffer.getBasePtr(x, y) = pixel;
-							}
-
-							x++;
-						}
-					} else {
-						for (uint8 i = 0; i < iteration; i++) {
-							if (x >= _engine->_interface->textWindow.left && x < _engine->_interface->textWindow.right && y >= _engine->_interface->textWindow.top && y < _engine->_interface->textWindow.bottom) {
-								*(uint8 *)_engine->frontVideoBuffer.getBasePtr(x, y) = *ptr;
-							}
-
-							x++;
-							ptr++;
+				const uint8 temp = *ptr++;
+				const uint8 iterations = bits(temp, 0, 6) + 1;
+				const uint8 type = bits(temp, 6, 2);
+				if (type == 0) {
+					x += iterations;
+					continue;
+				}
+				if (type == 1) {
+					for (uint8 i = 0; i < iterations; i++) {
+						if (x >= _engine->_interface->textWindow.left && x < _engine->_interface->textWindow.right && y >= _engine->_interface->textWindow.top && y < _engine->_interface->textWindow.bottom) {
+							*(uint8 *)_engine->frontVideoBuffer.getBasePtr(x, y) = *ptr;
 						}
+
+						x++;
+						ptr++;
 					}
 				} else {
-					x += iteration;
+					const uint8 pixel = *ptr++;
+					for (uint8 i = 0; i < iterations; i++) {
+						if (x >= _engine->_interface->textWindow.left && x < _engine->_interface->textWindow.right && y >= _engine->_interface->textWindow.top && y < _engine->_interface->textWindow.bottom) {
+							*(uint8 *)_engine->frontVideoBuffer.getBasePtr(x, y) = pixel;
+						}
+
+						x++;
+					}
 				}
 			}
 			x = left;


Commit: 490dde3bd590fb88743a404a55282b677c124974
    https://github.com/scummvm/scummvm/commit/490dde3bd590fb88743a404a55282b677c124974
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: moved one of the clipping checks out of the inner loops

Changed paths:
    engines/twine/scene/grid.cpp


diff --git a/engines/twine/scene/grid.cpp b/engines/twine/scene/grid.cpp
index ff937def94..4c052d8bef 100644
--- a/engines/twine/scene/grid.cpp
+++ b/engines/twine/scene/grid.cpp
@@ -477,7 +477,10 @@ void Grid::drawSprite(int32 index, int32 posX, int32 posY, const uint8 *ptr) {
 void Grid::drawBrickSprite(int32 index, int32 posX, int32 posY, const uint8 *ptr, bool isSprite) {
 	const int32 left = posX + *(ptr + 2);
 	const int32 top = posY + *(ptr + 3);
-	const int32 bottom = *(ptr + 1) + top;
+	const int32 bottom = MIN((int32)*(ptr + 1) + top, (int32)_engine->_interface->textWindow.bottom);
+	if (top > bottom) {
+		return;
+	}
 
 	ptr += 4;
 
@@ -497,7 +500,7 @@ void Grid::drawBrickSprite(int32 index, int32 posX, int32 posY, const uint8 *ptr
 				}
 				if (type == 1) {
 					for (uint8 i = 0; i < iterations; i++) {
-						if (x >= _engine->_interface->textWindow.left && x < _engine->_interface->textWindow.right && y >= _engine->_interface->textWindow.top && y < _engine->_interface->textWindow.bottom) {
+						if (x >= _engine->_interface->textWindow.left && x < _engine->_interface->textWindow.right && y >= _engine->_interface->textWindow.top) {
 							*(uint8 *)_engine->frontVideoBuffer.getBasePtr(x, y) = *ptr;
 						}
 
@@ -507,7 +510,7 @@ void Grid::drawBrickSprite(int32 index, int32 posX, int32 posY, const uint8 *ptr
 				} else {
 					const uint8 pixel = *ptr++;
 					for (uint8 i = 0; i < iterations; i++) {
-						if (x >= _engine->_interface->textWindow.left && x < _engine->_interface->textWindow.right && y >= _engine->_interface->textWindow.top && y < _engine->_interface->textWindow.bottom) {
+						if (x >= _engine->_interface->textWindow.left && x < _engine->_interface->textWindow.right && y >= _engine->_interface->textWindow.top) {
 							*(uint8 *)_engine->frontVideoBuffer.getBasePtr(x, y) = pixel;
 						}
 


Commit: 39c3b3022ed8e5b8ab8355a1ec048d80752427a3
    https://github.com/scummvm/scummvm/commit/39c3b3022ed8e5b8ab8355a1ec048d80752427a3
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: perform some minor clipping optimizations

Changed paths:
    engines/twine/scene/grid.cpp


diff --git a/engines/twine/scene/grid.cpp b/engines/twine/scene/grid.cpp
index 4c052d8bef..d51dc7b306 100644
--- a/engines/twine/scene/grid.cpp
+++ b/engines/twine/scene/grid.cpp
@@ -476,11 +476,22 @@ void Grid::drawSprite(int32 index, int32 posX, int32 posY, const uint8 *ptr) {
 // WARNING: Rewrite this function to have better performance
 void Grid::drawBrickSprite(int32 index, int32 posX, int32 posY, const uint8 *ptr, bool isSprite) {
 	const int32 left = posX + *(ptr + 2);
+	if (left > _engine->_interface->textWindow.right) {
+		return;
+	}
+	const int32 right = *ptr + left;
+	if (right < _engine->_interface->textWindow.left) {
+		return;
+	}
 	const int32 top = posY + *(ptr + 3);
-	const int32 bottom = MIN((int32)*(ptr + 1) + top, (int32)_engine->_interface->textWindow.bottom);
-	if (top > bottom) {
+	if (top > _engine->_interface->textWindow.bottom) {
+		return;
+	}
+	const int32 bottom = (int32)*(ptr + 1) + top;
+	if (bottom < _engine->_interface->textWindow.top) {
 		return;
 	}
+	const int32 maxY = MIN(bottom, (int32)_engine->_interface->textWindow.bottom);
 
 	ptr += 4;
 
@@ -488,7 +499,7 @@ void Grid::drawBrickSprite(int32 index, int32 posX, int32 posY, const uint8 *ptr
 
 	//if (left >= textWindowLeft-2 && top >= textWindowTop-2 && right <= textWindowRight-2 && bottom <= textWindowBottom-2) // crop
 	{
-		for (int32 y = top; y < bottom; y++) {
+		for (int32 y = top; y < maxY; y++) {
 			uint8 vc3 = *(ptr++);
 			for (int32 c2 = 0; c2 < vc3; c2++) {
 				const uint8 temp = *ptr++;


Commit: 7cad24ad901a643a71de2a68e7f6af0f3b920753
    https://github.com/scummvm/scummvm/commit/7cad24ad901a643a71de2a68e7f6af0f3b920753
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: new debug command to render clip zones

Changed paths:
    engines/twine/debugger/console.cpp
    engines/twine/debugger/console.h
    engines/twine/debugger/debug_scene.cpp
    engines/twine/debugger/debug_scene.h


diff --git a/engines/twine/debugger/console.cpp b/engines/twine/debugger/console.cpp
index 48bad34ac7..1fd170a433 100644
--- a/engines/twine/debugger/console.cpp
+++ b/engines/twine/debugger/console.cpp
@@ -38,6 +38,7 @@ TwinEConsole::TwinEConsole(TwinEEngine *engine) : _engine(engine), GUI::Debugger
 	registerCmd("list_menutext", WRAP_METHOD(TwinEConsole, doListMenuText));
 	registerCmd("toggle_debug", WRAP_METHOD(TwinEConsole, doToggleDebug));
 	registerCmd("toggle_zones", WRAP_METHOD(TwinEConsole, doToggleZoneRendering));
+	registerCmd("toggle_clips", WRAP_METHOD(TwinEConsole, doToggleClipRendering));
 	registerCmd("toggle_freecamera", WRAP_METHOD(TwinEConsole, doToggleFreeCamera));
 	registerCmd("toggle_scenechanges", WRAP_METHOD(TwinEConsole, doToggleSceneChanges));
 	registerCmd("scene_actor", WRAP_METHOD(TwinEConsole, doSkipSceneActorsBut));
@@ -67,6 +68,11 @@ bool TwinEConsole::doToggleZoneRendering(int argc, const char **argv) {
 	return true;
 }
 
+bool TwinEConsole::doToggleClipRendering(int argc, const char **argv) {
+	TOGGLE_DEBUG(_engine->_debugScene->showingClips, "clip rendering\n")
+	return true;
+}
+
 bool TwinEConsole::doSkipSceneActorsBut(int argc, const char **argv) {
 	if (argc < 2) {
 		debugPrintf("Usage: give actor id of scene or -1 to disable\n");
diff --git a/engines/twine/debugger/console.h b/engines/twine/debugger/console.h
index fc42b87073..401093f319 100644
--- a/engines/twine/debugger/console.h
+++ b/engines/twine/debugger/console.h
@@ -42,6 +42,7 @@ private:
 	bool doToggleDebug(int argc, const char **argv);
 	bool doGiveKey(int argc, const char **argv);
 	bool doToggleZoneRendering(int argc, const char **argv);
+	bool doToggleClipRendering(int argc, const char **argv);
 	bool doToggleFreeCamera(int argc, const char **argv);
 	bool doToggleSceneChanges(int argc, const char **argv);
 	bool doSkipSceneActorsBut(int argc, const char **argv);
diff --git a/engines/twine/debugger/debug_scene.cpp b/engines/twine/debugger/debug_scene.cpp
index 50fe5b4c49..4fd596b945 100644
--- a/engines/twine/debugger/debug_scene.cpp
+++ b/engines/twine/debugger/debug_scene.cpp
@@ -21,10 +21,11 @@
  */
 
 #include "twine/debugger/debug_scene.h"
-#include "twine/scene/grid.h"
 #include "twine/menu/interface.h"
+#include "twine/menu/menu.h"
 #include "twine/renderer/redraw.h"
 #include "twine/renderer/renderer.h"
+#include "twine/scene/grid.h"
 #include "twine/scene/scene.h"
 #include "twine/twine.h"
 
@@ -32,6 +33,13 @@ namespace TwinE {
 
 DebugScene::DebugScene(TwinEEngine *engine) : _engine(engine) {}
 
+void DebugScene::drawClip(const Common::Rect& rect) {
+	if (!showingClips) {
+		return;
+	}
+	_engine->_menu->drawBox(rect);
+}
+
 void DebugScene::drawBoundingBoxProjectPoints(ScenePoint *pPoint3d, ScenePoint *pPoint3dProjected) {
 	_engine->_renderer->projectPositionOnScreen(pPoint3d->x, pPoint3d->y, pPoint3d->z);
 
diff --git a/engines/twine/debugger/debug_scene.h b/engines/twine/debugger/debug_scene.h
index effcbf7b80..b0cd9b7e79 100644
--- a/engines/twine/debugger/debug_scene.h
+++ b/engines/twine/debugger/debug_scene.h
@@ -23,6 +23,7 @@
 #ifndef TWINE_DEBUG_SCENE_H
 #define TWINE_DEBUG_SCENE_H
 
+#include "common/rect.h"
 #include "common/scummsys.h"
 
 namespace TwinE {
@@ -39,10 +40,13 @@ private:
 public:
 	DebugScene(TwinEEngine *engine);
 	bool showingZones = false;
+	bool showingClips = false;
 	int32 typeZones = 127; // all zones on as default
 	int16 onlyLoadActor = -1;
 
 	void displayZones();
+
+	void drawClip(const Common::Rect& rect);
 };
 
 } // namespace TwinE


Commit: d0b7676b9d7270ba782b754ab3b2e3689566ea72
    https://github.com/scummvm/scummvm/commit/d0b7676b9d7270ba782b754ab3b2e3689566ea72
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: renamed variables

Changed paths:
    engines/twine/renderer/redraw.cpp


diff --git a/engines/twine/renderer/redraw.cpp b/engines/twine/renderer/redraw.cpp
index 362bec9cea..587aa25c0d 100644
--- a/engines/twine/renderer/redraw.cpp
+++ b/engines/twine/renderer/redraw.cpp
@@ -356,14 +356,14 @@ void Redraw::processDrawListShadows(const DrawListStruct &drawCmd) {
 }
 
 void Redraw::processDrawListActors(const DrawListStruct &drawCmd, bool bgRedraw) {
-	int32 actorIdx = drawCmd.actorIdx;
-	ActorStruct *actor2 = _engine->_scene->getActor(actorIdx);
-	_engine->_animations->setModelAnimation(actor2->animPosition, _engine->_resources->animTable[actor2->previousAnimIdx], _engine->_actor->bodyTable[actor2->entity], &actor2->animTimerData);
+	const int32 actorIdx = drawCmd.actorIdx;
+	ActorStruct *actor = _engine->_scene->getActor(actorIdx);
+	_engine->_animations->setModelAnimation(actor->animPosition, _engine->_resources->animTable[actor->previousAnimIdx], _engine->_actor->bodyTable[actor->entity], &actor->animTimerData);
 
-	const int32 x = actor2->x - _engine->_grid->cameraX;
-	const int32 y = actor2->y - _engine->_grid->cameraY;
-	const int32 z = actor2->z - _engine->_grid->cameraZ;
-	if (!_engine->_renderer->renderIsoModel(x, y, z, 0, actor2->angle, 0, _engine->_actor->bodyTable[actor2->entity])) {
+	const int32 x = actor->x - _engine->_grid->cameraX;
+	const int32 y = actor->y - _engine->_grid->cameraY;
+	const int32 z = actor->z - _engine->_grid->cameraZ;
+	if (!_engine->_renderer->renderIsoModel(x, y, z, 0, actor->angle, 0, _engine->_actor->bodyTable[actor->entity])) {
 		return;
 	}
 
@@ -386,12 +386,12 @@ void Redraw::processDrawListActors(const DrawListStruct &drawCmd, bool bgRedraw)
 	_engine->_interface->setClip(renderRect);
 
 	if (_engine->_interface->textWindow.left <= _engine->_interface->textWindow.right && _engine->_interface->textWindow.top <= _engine->_interface->textWindow.bottom) {
-		actor2->dynamicFlags.bIsVisible = 1;
+		actor->dynamicFlags.bIsVisible = 1;
 
-		const int32 tempX = (actor2->x + 0x100) >> 9;
-		int32 tempY = actor2->y >> 8;
-		const int32 tempZ = (actor2->z + 0x100) >> 9;
-		if (actor2->brickShape() != ShapeType::kNone) {
+		const int32 tempX = (actor->x + 0x100) >> 9;
+		int32 tempY = actor->y >> 8;
+		const int32 tempZ = (actor->z + 0x100) >> 9;
+		if (actor->brickShape() != ShapeType::kNone) {
 			tempY++;
 		}
 
@@ -404,7 +404,7 @@ void Redraw::processDrawListActors(const DrawListStruct &drawCmd, bool bgRedraw)
 		const Common::Rect rect(_engine->_interface->textWindow.left, _engine->_interface->textWindow.top, renderRect.right, renderRect.bottom);
 		addRedrawArea(rect);
 
-		if (actor2->staticFlags.bIsBackgrounded && bgRedraw) {
+		if (actor->staticFlags.bIsBackgrounded && bgRedraw) {
 			_engine->_interface->blitBox(rect, _engine->frontVideoBuffer, _engine->workVideoBuffer);
 		}
 	}
@@ -412,24 +412,24 @@ void Redraw::processDrawListActors(const DrawListStruct &drawCmd, bool bgRedraw)
 
 void Redraw::processDrawListActorSprites(const DrawListStruct &drawCmd, bool bgRedraw) {
 	int32 actorIdx = drawCmd.actorIdx;
-	ActorStruct *actor2 = _engine->_scene->getActor(actorIdx);
-	const uint8 *spritePtr = _engine->_resources->spriteTable[actor2->entity];
+	ActorStruct *actor = _engine->_scene->getActor(actorIdx);
+	const uint8 *spritePtr = _engine->_resources->spriteTable[actor->entity];
 
 	// get actor position on screen
-	_engine->_renderer->projectPositionOnScreen(actor2->x - _engine->_grid->cameraX, actor2->y - _engine->_grid->cameraY, actor2->z - _engine->_grid->cameraZ);
+	_engine->_renderer->projectPositionOnScreen(actor->x - _engine->_grid->cameraX, actor->y - _engine->_grid->cameraY, actor->z - _engine->_grid->cameraZ);
 
 	int32 spriteWidth, spriteHeight;
 	_engine->_grid->getSpriteSize(0, &spriteWidth, &spriteHeight, spritePtr);
 
 	// calculate sprite position on screen
-	const SpriteDim* dim = _engine->_resources->spriteBoundingBox.dim(actor2->entity);
+	const SpriteDim* dim = _engine->_resources->spriteBoundingBox.dim(actor->entity);
 	renderRect.left = _engine->_renderer->projPosX + dim->x;
 	renderRect.top = _engine->_renderer->projPosY + dim->y;
 	renderRect.right = renderRect.left + spriteWidth;
 	renderRect.bottom = renderRect.top + spriteHeight;
 
-	if (actor2->staticFlags.bUsesClipping) {
-		const Common::Rect rect(_engine->_renderer->projPosXScreen + actor2->cropLeft, _engine->_renderer->projPosYScreen + actor2->cropTop, _engine->_renderer->projPosXScreen + actor2->cropRight, _engine->_renderer->projPosYScreen + actor2->cropBottom);
+	if (actor->staticFlags.bUsesClipping) {
+		const Common::Rect rect(_engine->_renderer->projPosXScreen + actor->cropLeft, _engine->_renderer->projPosYScreen + actor->cropTop, _engine->_renderer->projPosXScreen + actor->cropRight, _engine->_renderer->projPosYScreen + actor->cropBottom);
 		_engine->_interface->setClip(rect);
 	} else {
 		_engine->_interface->setClip(renderRect);
@@ -438,18 +438,18 @@ void Redraw::processDrawListActorSprites(const DrawListStruct &drawCmd, bool bgR
 	if (_engine->_interface->textWindow.left <= _engine->_interface->textWindow.right && _engine->_interface->textWindow.top <= _engine->_interface->textWindow.bottom) {
 		_engine->_grid->drawSprite(0, renderRect.left, renderRect.top, spritePtr);
 
-		actor2->dynamicFlags.bIsVisible = 1;
+		actor->dynamicFlags.bIsVisible = 1;
 
-		if (actor2->staticFlags.bUsesClipping) {
-			const int32 tmpX = (actor2->lastX + 0x100) >> 9;
-			const int32 tmpY = actor2->lastY >> 8;
-			const int32 tmpZ = (actor2->lastZ + 0x100) >> 9;
+		if (actor->staticFlags.bUsesClipping) {
+			const int32 tmpX = (actor->lastX + 0x100) >> 9;
+			const int32 tmpY = actor->lastY >> 8;
+			const int32 tmpZ = (actor->lastZ + 0x100) >> 9;
 			_engine->_grid->drawOverSpriteActor(tmpX, tmpY, tmpZ);
 		} else {
-			const int32 tmpX = (actor2->x + actor2->boudingBox.x.topRight + 0x100) >> 9;
-			int32 tmpY = actor2->y >> 8;
-			const int32 tmpZ = (actor2->z + actor2->boudingBox.z.topRight + 0x100) >> 9;
-			if (actor2->brickShape() != ShapeType::kNone) {
+			const int32 tmpX = (actor->x + actor->boudingBox.x.topRight + 0x100) >> 9;
+			int32 tmpY = actor->y >> 8;
+			const int32 tmpZ = (actor->z + actor->boudingBox.z.topRight + 0x100) >> 9;
+			if (actor->brickShape() != ShapeType::kNone) {
 				tmpY++;
 			}
 
@@ -458,7 +458,7 @@ void Redraw::processDrawListActorSprites(const DrawListStruct &drawCmd, bool bgR
 
 		addRedrawArea(_engine->_interface->textWindow);
 
-		if (actor2->staticFlags.bIsBackgrounded && bgRedraw) {
+		if (actor->staticFlags.bIsBackgrounded && bgRedraw) {
 			_engine->_interface->blitBox(_engine->_interface->textWindow, _engine->frontVideoBuffer, _engine->workVideoBuffer);
 		}
 


Commit: 42f0634d6da40aa723575aad879c89540a1b4223
    https://github.com/scummvm/scummvm/commit/42f0634d6da40aa723575aad879c89540a1b4223
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: draw actor clips

Changed paths:
    engines/twine/renderer/redraw.cpp


diff --git a/engines/twine/renderer/redraw.cpp b/engines/twine/renderer/redraw.cpp
index 587aa25c0d..513d3e3b58 100644
--- a/engines/twine/renderer/redraw.cpp
+++ b/engines/twine/renderer/redraw.cpp
@@ -407,6 +407,8 @@ void Redraw::processDrawListActors(const DrawListStruct &drawCmd, bool bgRedraw)
 		if (actor->staticFlags.bIsBackgrounded && bgRedraw) {
 			_engine->_interface->blitBox(rect, _engine->frontVideoBuffer, _engine->workVideoBuffer);
 		}
+
+		_engine->_debugScene->drawClip(renderRect);
 	}
 }
 


Commit: 02e51f0ecb0b24c70a6ec13a36ddf91535f332ae
    https://github.com/scummvm/scummvm/commit/02e51f0ecb0b24c70a6ec13a36ddf91535f332ae
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: const

Changed paths:
    engines/twine/renderer/renderer.cpp
    engines/twine/scene/grid.cpp


diff --git a/engines/twine/renderer/renderer.cpp b/engines/twine/renderer/renderer.cpp
index 93b51275aa..31d737fd18 100644
--- a/engines/twine/renderer/renderer.cpp
+++ b/engines/twine/renderer/renderer.cpp
@@ -1377,9 +1377,9 @@ bool Renderer::renderAnimatedModel(ModelData *modelData, const uint8 *bodyPtr, R
 					const uint8 *shadePtr = Model::getShadesBaseData(bodyPtr, shadeIndex);
 					const int16 *colPtr = (const int16 *)shadePtr;
 
-					int16 col1 = *((const int16 *)colPtr++);
-					int16 col2 = *((const int16 *)colPtr++);
-					int16 col3 = *((const int16 *)colPtr++);
+					const int16 col1 = *((const int16 *)colPtr++);
+					const int16 col2 = *((const int16 *)colPtr++);
+					const int16 col3 = *((const int16 *)colPtr++);
 
 					int32 color = 0;
 					color += shadeMatrix.row1[0] * col1 + shadeMatrix.row1[1] * col2 + shadeMatrix.row1[2] * col3;
@@ -1425,7 +1425,7 @@ void Renderer::prepareIsoModel(uint8 *bodyPtr) { // loadGfxSub
 	}
 
 	uint8 *bonesBase = Model::getBonesBaseData(bodyPtr);
-	int16 numBones = Model::getNumBones(bodyPtr);
+	const int16 numBones = Model::getNumBones(bodyPtr);
 
 	// set up bone indices
 	for (int32 i = 0; i < numBones; i++) {
diff --git a/engines/twine/scene/grid.cpp b/engines/twine/scene/grid.cpp
index d51dc7b306..3d2f97682a 100644
--- a/engines/twine/scene/grid.cpp
+++ b/engines/twine/scene/grid.cpp
@@ -172,11 +172,11 @@ void Grid::drawOverSpriteActor(int32 x, int32 y, int32 z) {
 			BrickEntry *currBrickEntry = &bricksDataBuffer[j][i];
 
 			if (currBrickEntry->posY + 38 > _engine->_interface->textWindow.top && currBrickEntry->posY <= _engine->_interface->textWindow.bottom && currBrickEntry->y >= y) {
-				if ((currBrickEntry->x == x) && (currBrickEntry->z == z)) {
+				if (currBrickEntry->x == x && currBrickEntry->z == z) {
 					copyGridMask(currBrickEntry->index, (j * 24) - 24, currBrickEntry->posY, _engine->workVideoBuffer);
 				}
 
-				if ((currBrickEntry->x > x) || (currBrickEntry->z > z)) {
+				if (currBrickEntry->x > x || currBrickEntry->z > z) {
 					copyGridMask(currBrickEntry->index, (j * 24) - 24, currBrickEntry->posY, _engine->workVideoBuffer);
 				}
 			}


Commit: e6bb08f6060151a80d3d3b49752d77e6ac844402
    https://github.com/scummvm/scummvm/commit/e6bb08f6060151a80d3d3b49752d77e6ac844402
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: format the code

Changed paths:
    engines/twine/resources/lzss.cpp


diff --git a/engines/twine/resources/lzss.cpp b/engines/twine/resources/lzss.cpp
index c3cc9f4cff..9266de5521 100644
--- a/engines/twine/resources/lzss.cpp
+++ b/engines/twine/resources/lzss.cpp
@@ -20,8 +20,8 @@
  *
  */
 
-#include "common/textconsole.h"
 #include "twine/resources/lzss.h"
+#include "common/textconsole.h"
 
 namespace TwinE {
 
@@ -46,18 +46,20 @@ void LzssReadStream::decodeLZSS(Common::ReadStream *in, uint32 mode, uint32 data
 		for (int32 d = 0; d < 8; d++) {
 			int32 length;
 			if (!(b & (1 << d))) {
-				uint16 offset = in->readUint16LE();
+				const uint16 offset = in->readUint16LE();
 				length = (offset & 0x0F) + (mode + 1);
-				uint8 *ptr = dst - (offset >> 4) - 1;
-				for (int32 i = 0; i < length; i++)
-					*(dst++) = *(ptr++);
+				const uint8 *ptr = dst - (offset >> 4) - 1;
+				for (int32 i = 0; i < length; i++) {
+					*dst++ = *ptr++;
+				}
 			} else {
 				length = 1;
-				*(dst++) = in->readByte();
+				*dst++ = in->readByte();
 			}
 			dataSize -= length;
-			if (dataSize <= 0)
+			if (dataSize <= 0) {
 				return;
+			}
 		}
 	} while (dataSize);
 }
@@ -67,8 +69,9 @@ bool LzssReadStream::eos() const {
 }
 
 uint32 LzssReadStream::read(void *buf, uint32 dataSize) {
-	if (dataSize > _size - _pos)
+	if (dataSize > _size - _pos) {
 		error("LzssReadStream::read past end of buffer");
+	}
 
 	memcpy(buf, &_outLzssBufData[_pos], dataSize);
 	_pos += dataSize;


Commit: 475d32380fa13259dddd315fede7ee8173783208
    https://github.com/scummvm/scummvm/commit/475d32380fa13259dddd315fede7ee8173783208
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: specify the palette index for loadImage()

Changed paths:
    engines/twine/menu/menuoptions.cpp
    engines/twine/renderer/screens.cpp
    engines/twine/renderer/screens.h
    engines/twine/resources/resources.h
    engines/twine/script/script_life_v1.cpp
    engines/twine/twine.cpp


diff --git a/engines/twine/menu/menuoptions.cpp b/engines/twine/menu/menuoptions.cpp
index bedb5acc8c..adf064306c 100644
--- a/engines/twine/menu/menuoptions.cpp
+++ b/engines/twine/menu/menuoptions.cpp
@@ -52,7 +52,7 @@ void MenuOptions::newGame() {
 	_engine->cfgfile.FlagDisplayText = true;
 
 	// intro screen 1 - twinsun
-	_engine->_screens->loadImage(RESSHQR_INTROSCREEN1IMG);
+	_engine->_screens->loadImage(RESSHQR_INTROSCREEN1IMG, RESSHQR_INTROSCREEN1PAL);
 
 	_engine->_text->drawTextBoxBackground = false;
 	_engine->_text->renderTextTriangle = true;
@@ -65,11 +65,11 @@ void MenuOptions::newGame() {
 
 	// intro screen 2
 	if (!aborted) {
-		_engine->_screens->loadImage(RESSHQR_INTROSCREEN2IMG);
+		_engine->_screens->loadImage(RESSHQR_INTROSCREEN2IMG, RESSHQR_INTROSCREEN2PAL);
 		aborted |= _engine->_text->drawTextFullscreen(151);
 
 		if (!aborted) {
-			_engine->_screens->loadImage(RESSHQR_INTROSCREEN3IMG);
+			_engine->_screens->loadImage(RESSHQR_INTROSCREEN3IMG, RESSHQR_INTROSCREEN3PAL);
 			aborted |= _engine->_text->drawTextFullscreen(152);
 		}
 	}
diff --git a/engines/twine/renderer/screens.cpp b/engines/twine/renderer/screens.cpp
index a819a48a21..7a12cf75f2 100644
--- a/engines/twine/renderer/screens.cpp
+++ b/engines/twine/renderer/screens.cpp
@@ -33,7 +33,7 @@ namespace TwinE {
 bool Screens::adelineLogo() {
 	_engine->_music->playMidiMusic(31);
 
-	if (loadImageDelay(RESSHQR_ADELINEIMG, 7)) {
+	if (loadImageDelay(RESSHQR_ADELINEIMG, RESSHQR_ADELINEPAL, 7)) {
 		return true;
 	}
 	palCustom = true;
@@ -74,14 +74,14 @@ void Screens::convertPalToRGBA(const uint8 *in, uint32 *out) {
 	}
 }
 
-void Screens::loadImage(int32 index, bool fade_in) {
+void Screens::loadImage(int32 index, int32 paletteIndex, bool fade_in) {
 	if (HQR::getEntry((uint8 *)_engine->workVideoBuffer.getPixels(), Resources::HQR_RESS_FILE, index) == 0) {
 		warning("Failed to load image with index %i", index);
 		return;
 	}
 	debug(0, "Load image: %i", index);
 	copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
-	loadCustomPalette(index + 1);
+	loadCustomPalette(paletteIndex);
 	if (fade_in) {
 		fadeToPal(paletteRGBACustom);
 	} else {
@@ -91,8 +91,8 @@ void Screens::loadImage(int32 index, bool fade_in) {
 	palCustom = true;
 }
 
-bool Screens::loadImageDelay(int32 index, int32 seconds) {
-	loadImage(index);
+bool Screens::loadImageDelay(int32 index, int32 paletteIndex, int32 seconds) {
+	loadImage(index, paletteIndex);
 	if (_engine->delaySkip(1000 * seconds)) {
 		adjustPalette(0, 0, 0, paletteRGBACustom, 100);
 		return true;
diff --git a/engines/twine/renderer/screens.h b/engines/twine/renderer/screens.h
index 3a3e0e4650..5657ac9d24 100644
--- a/engines/twine/renderer/screens.h
+++ b/engines/twine/renderer/screens.h
@@ -82,16 +82,18 @@ public:
 	/**
 	 * Load and display a particulary image on \a RESS.HQR file with cross fade effect
 	 * @param index \a RESS.HQR entry index (starting from 0)
+	 * @param paletteIndex \a RESS.HQR entry index of the palette for the given image. This is often the @c index + 1
 	 * @param fade_in if we fade in before using the palette
 	 */
-	void loadImage(int32 index, bool fade_in = true);
+	void loadImage(int32 index, int32 paletteIndex, bool fade_in = true);
 
 	/**
 	 * Load and display a particulary image on \a RESS.HQR file with cross fade effect and delay
 	 * @param index \a RESS.HQR entry index (starting from 0)
+	 * @param paletteIndex \a RESS.HQR entry index of the palette for the given image. This is often the @c index + 1
 	 * @param seconds number of seconds to delay
 	 */
-	bool loadImageDelay(int32 index, int32 seconds);
+	bool loadImageDelay(int32 index, int32 paletteIndex, int32 seconds);
 
 	/**
 	 * Fade image in
diff --git a/engines/twine/resources/resources.h b/engines/twine/resources/resources.h
index 5c838d6c33..7b61712ee4 100644
--- a/engines/twine/resources/resources.h
+++ b/engines/twine/resources/resources.h
@@ -56,8 +56,8 @@ namespace TwinE {
 
 #define RESSHQR_ALARMREDPAL 22
 #define RESSHQR_DARKPAL 24
-#define RESSHQR_TWINSEN_ZOE_SENDELL  25
-
+#define RESSHQR_TWINSEN_ZOE_SENDELLIMG  25
+#define RESSHQR_TWINSEN_ZOE_SENDELLPAL  26
 #define RESSHQR_ADELINEIMG 27
 #define RESSHQR_ADELINEPAL 28
 
diff --git a/engines/twine/script/script_life_v1.cpp b/engines/twine/script/script_life_v1.cpp
index e65fbbb7e7..a5f78226f6 100644
--- a/engines/twine/script/script_life_v1.cpp
+++ b/engines/twine/script/script_life_v1.cpp
@@ -1608,7 +1608,7 @@ static int32 lSET_NORMAL_PAL(TwinEEngine *engine, LifeScriptContext &ctx) {
 static int32 lMESSAGE_SENDELL(TwinEEngine *engine, LifeScriptContext &ctx) {
 	ScopedEngineFreeze scoped(engine);
 	engine->_screens->fadeToBlack(engine->_screens->paletteRGBA);
-	engine->_screens->loadImage(RESSHQR_TWINSEN_ZOE_SENDELL);
+	engine->_screens->loadImage(RESSHQR_TWINSEN_ZOE_SENDELLIMG, RESSHQR_TWINSEN_ZOE_SENDELLPAL);
 	engine->_text->textClipFull();
 	engine->_text->setFontCrossColor(15);
 	engine->_text->drawTextBoxBackground = false;
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index 535df2a0c2..b2aa6d82fc 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -407,21 +407,21 @@ void TwinEEngine::initEngine() {
 	// verify game version screens
 	if (!abort && cfgfile.Version == EUROPE_VERSION) {
 		// Little Big Adventure screen
-		abort |= _screens->loadImageDelay(RESSHQR_LBAIMG, 3);
+		abort |= _screens->loadImageDelay(RESSHQR_LBAIMG, RESSHQR_LBAPAL, 3);
 		if (!abort) {
 			// Electronic Arts Logo
-			abort |= _screens->loadImageDelay(RESSHQR_EAIMG, 2);
+			abort |= _screens->loadImageDelay(RESSHQR_EAIMG, RESSHQR_EAPAL, 2);
 		}
 	} else if (!abort && cfgfile.Version == USA_VERSION) {
 		// Relentless screen
-		abort |= _screens->loadImageDelay(RESSHQR_RELLENTIMG, 3);
+		abort |= _screens->loadImageDelay(RESSHQR_RELLENTIMG, RESSHQR_RELLENTPAL, 3);
 		if (!abort) {
 			// Electronic Arts Logo
-			abort |= _screens->loadImageDelay(RESSHQR_EAIMG, 2);
+			abort |= _screens->loadImageDelay(RESSHQR_EAIMG, RESSHQR_EAPAL, 2);
 		}
 	} else if (!abort && cfgfile.Version == MODIFICATION_VERSION) {
 		// Modification screen
-		abort |= _screens->loadImageDelay(RESSHQR_RELLENTIMG, 2);
+		abort |= _screens->loadImageDelay(RESSHQR_RELLENTIMG, RESSHQR_RELLENTPAL, 2);
 	}
 
 	if (!abort) {
@@ -514,7 +514,7 @@ void TwinEEngine::processInventoryAction() {
 		break;
 	case kiBookOfBu: {
 		_screens->fadeToBlack(_screens->paletteRGBA);
-		_screens->loadImage(RESSHQR_INTROSCREEN1IMG);
+		_screens->loadImage(RESSHQR_INTROSCREEN1IMG, RESSHQR_INTROSCREEN1PAL);
 		_text->initTextBank(TextBankId::Inventory_Intro_and_Holomap);
 		_text->drawTextBoxBackground = false;
 		_text->textClipFull();


Commit: b7486b22494c56e6e201c67fb3c8937ce5ec4f2a
    https://github.com/scummvm/scummvm/commit/b7486b22494c56e6e201c67fb3c8937ce5ec4f2a
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: holoamp input actions

Changed paths:
    engines/twine/input.cpp
    engines/twine/input.h
    engines/twine/metaengine.cpp


diff --git a/engines/twine/input.cpp b/engines/twine/input.cpp
index c66abda894..7e9b9baf2b 100644
--- a/engines/twine/input.cpp
+++ b/engines/twine/input.cpp
@@ -33,6 +33,7 @@ namespace TwinE {
 const char *mainKeyMapId = "mainKeyMap";
 const char *uiKeyMapId = "uiKeyMap";
 const char *cutsceneKeyMapId = "cutsceneKeyMap";
+const char *holomapKeyMapId = "holomapKeyMap";
 
 ScopedKeyMap::ScopedKeyMap(TwinEEngine* engine, const char *id) : _engine(engine) {
 	_changed = _engine->_input->enableAdditionalKeyMap(id, true);
@@ -67,6 +68,7 @@ bool Input::toggleAbortAction() {
 	abortState |= toggleActionIfActive(TwinEActionType::CutsceneAbort);
 	abortState |= toggleActionIfActive(TwinEActionType::UIAbort);
 	abortState |= toggleActionIfActive(TwinEActionType::Escape);
+	abortState |= toggleActionIfActive(TwinEActionType::HolomapAbort);
 	return abortState;
 }
 
diff --git a/engines/twine/input.h b/engines/twine/input.h
index a39a3a8bba..f135e4e512 100644
--- a/engines/twine/input.h
+++ b/engines/twine/input.h
@@ -36,6 +36,7 @@ class TwinEEngine;
 extern const char *mainKeyMapId;
 extern const char *uiKeyMapId;
 extern const char *cutsceneKeyMapId;
+extern const char *holomapKeyMapId;
 
 enum TwinEActionType {
 	Pause,
@@ -84,6 +85,12 @@ enum TwinEActionType {
 
 	CutsceneAbort,
 
+	HolomapAbort,
+	HolomapLeft,
+	HolomapRight,
+	HolomapUp,
+	HolomapDown,
+
 	Max
 };
 
diff --git a/engines/twine/metaengine.cpp b/engines/twine/metaengine.cpp
index ea66ca31d5..ad8d813702 100644
--- a/engines/twine/metaengine.cpp
+++ b/engines/twine/metaengine.cpp
@@ -160,7 +160,7 @@ Common::KeymapArray TwinEMetaEngine::initKeymaps(const char *target) const {
 	using namespace Common;
 	Action *act;
 
-	KeymapArray array(3);
+	KeymapArray array(4);
 
 	{
 		Keymap *gameKeyMap = new Keymap(Keymap::kKeymapTypeGame, mainKeyMapId, "Little Big Adventure");
@@ -419,6 +419,43 @@ Common::KeymapArray TwinEMetaEngine::initKeymaps(const char *target) const {
 		array[2] = cutsceneKeyMap;
 	}
 
+	{
+		Keymap *holomapKeyMap = new Keymap(Keymap::kKeymapTypeGame, holomapKeyMapId, "Little Big Adventure Holomap");
+
+		act = new Action("ABORT", _("Abort"));
+		act->setCustomEngineActionEvent(TwinEActionType::HolomapAbort);
+		act->addDefaultInputMapping("ESCAPE");
+		holomapKeyMap->addAction(act);
+
+		act = new Action("UP", _("Up"));
+		act->setCustomEngineActionEvent(TwinEActionType::HolomapUp);
+		act->addDefaultInputMapping("UP");
+		act->addDefaultInputMapping("KP8");
+		act->addDefaultInputMapping("MOUSE_WHEEL_UP");
+		holomapKeyMap->addAction(act);
+
+		act = new Action("DOWN", _("Down"));
+		act->setCustomEngineActionEvent(TwinEActionType::HolomapDown);
+		act->addDefaultInputMapping("DOWN");
+		act->addDefaultInputMapping("KP2");
+		act->addDefaultInputMapping("MOUSE_WHEEL_DOWN");
+		holomapKeyMap->addAction(act);
+
+		act = new Action("RIGHT", _("Right"));
+		act->setCustomEngineActionEvent(TwinEActionType::HolomapRight);
+		act->addDefaultInputMapping("RIGHT");
+		act->addDefaultInputMapping("KP6");
+		holomapKeyMap->addAction(act);
+
+		act = new Action("LEFT", _("Left"));
+		act->setCustomEngineActionEvent(TwinEActionType::HolomapLeft);
+		act->addDefaultInputMapping("LEFT");
+		act->addDefaultInputMapping("KP4");
+		holomapKeyMap->addAction(act);
+
+		array[3] = holomapKeyMap;
+	}
+
 	return array;
 }
 


Commit: ef27d139585252cd87ab13f894f520a7a5f539ac
    https://github.com/scummvm/scummvm/commit/ef27d139585252cd87ab13f894f520a7a5f539ac
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: given default value for ScopedFPS

Changed paths:
    engines/twine/twine.h


diff --git a/engines/twine/twine.h b/engines/twine/twine.h
index e23d6ab47f..bf2abd5a78 100644
--- a/engines/twine/twine.h
+++ b/engines/twine/twine.h
@@ -174,7 +174,7 @@ private:
 	uint32 _fps;
 	uint32 _start;
 public:
-	ScopedFPS(uint32 fps);
+	ScopedFPS(uint32 fps = DEFAULT_FRAMES_PER_SECOND);
 	~ScopedFPS();
 };
 


Commit: b6a854677b9cdc352a21187c69477f0095941c0c
    https://github.com/scummvm/scummvm/commit/b6a854677b9cdc352a21187c69477f0095941c0c
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: use surface method to set back the front buffer

Changed paths:
    engines/twine/renderer/screens.cpp


diff --git a/engines/twine/renderer/screens.cpp b/engines/twine/renderer/screens.cpp
index 7a12cf75f2..9ca4278f8c 100644
--- a/engines/twine/renderer/screens.cpp
+++ b/engines/twine/renderer/screens.cpp
@@ -257,7 +257,7 @@ void Screens::copyScreen(const Graphics::ManagedSurface &source, Graphics::Manag
 }
 
 void Screens::clearScreen() {
-	memset(_engine->frontVideoBuffer.getPixels(), 0, SCREEN_WIDTH * SCREEN_HEIGHT);
+	_engine->frontVideoBuffer.clear(0);
 }
 
 } // namespace TwinE


Commit: 5bb0f3b6b597a5704d0f07de1c0736780605597f
    https://github.com/scummvm/scummvm/commit/5bb0f3b6b597a5704d0f07de1c0736780605597f
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: renamed method parameters

Changed paths:
    engines/twine/holomap.cpp
    engines/twine/holomap.h


diff --git a/engines/twine/holomap.cpp b/engines/twine/holomap.cpp
index 3e8c5db9b4..ab63da2b4e 100644
--- a/engines/twine/holomap.cpp
+++ b/engines/twine/holomap.cpp
@@ -128,7 +128,10 @@ void Holomap::loadHolomapGFX() {
 	needToLoadHolomapGFX = 0;
 }
 
-void Holomap::drawHolomapTitle(int32 width, int32 height) {
+void Holomap::drawHolomapTitle(int32 centerx, int32 top) {
+	const char *title = "TODO";
+	_engine->_text->drawText(centerx - _engine->_text->getTextSize(title) / 2, top, title);
+
 	// TODO
 }
 
diff --git a/engines/twine/holomap.h b/engines/twine/holomap.h
index 7ebcad74c6..df383e8ed1 100644
--- a/engines/twine/holomap.h
+++ b/engines/twine/holomap.h
@@ -72,7 +72,7 @@ public:
 	void clearHolomapPosition(int32 locationIdx);
 
 	/** Draw Holomap Title */
-	void drawHolomapTitle(int32 width, int32 height);
+	void drawHolomapTitle(int32 centerx, int32 top);
 
 	/** Draw Holomap Trajectory */
 	void drawHolomapTrajectory(int32 trajectoryIndex);


Commit: f308252543d9348d248a78e31e9236d8e8cf1adc
    https://github.com/scummvm/scummvm/commit/f308252543d9348d248a78e31e9236d8e8cf1adc
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: holomap loop

Changed paths:
    engines/twine/holomap.cpp


diff --git a/engines/twine/holomap.cpp b/engines/twine/holomap.cpp
index ab63da2b4e..a386a856d0 100644
--- a/engines/twine/holomap.cpp
+++ b/engines/twine/holomap.cpp
@@ -162,7 +162,27 @@ void Holomap::processHolomap() {
 	_engine->_text->initTextBank(TextBankId::Inventory_Intro_and_Holomap);
 	_engine->_text->setFontCrossColor(9);
 
-	// TODO
+	ScopedKeyMap holomapKeymap(_engine, holomapKeyMapId);
+	for (;;) {
+		ScopedFPS scopedFps;
+		_engine->_input->readKeys();
+		if (_engine->shouldQuit() || _engine->_input->toggleAbortAction()) {
+			break;
+		}
+
+		if (_engine->_input->toggleActionIfActive(TwinEActionType::HolomapLeft)) {
+		} else if (_engine->_input->toggleActionIfActive(TwinEActionType::HolomapRight)) {
+		}
+
+		if (_engine->_input->toggleActionIfActive(TwinEActionType::HolomapUp)) {
+		} else if (_engine->_input->toggleActionIfActive(TwinEActionType::HolomapDown)) {
+		}
+
+		// TODO
+
+		//_engine->_screens->copyScreen(_engine->workVideoBuffer, _engine->frontVideoBuffer);
+		//_engine->flip();
+	}
 
 	_engine->_text->drawTextBoxBackground = true;
 	_engine->_screens->fadeToBlack(_engine->_screens->paletteRGBA);


Commit: 08c68151122e0aba4b63487e02e8404745bafb6e
    https://github.com/scummvm/scummvm/commit/08c68151122e0aba4b63487e02e8404745bafb6e
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: reset the proper camera projections on leaving the holomap 'menu'

Changed paths:
    engines/twine/holomap.cpp


diff --git a/engines/twine/holomap.cpp b/engines/twine/holomap.cpp
index a386a856d0..9d399d7bf2 100644
--- a/engines/twine/holomap.cpp
+++ b/engines/twine/holomap.cpp
@@ -188,7 +188,8 @@ void Holomap::processHolomap() {
 	_engine->_screens->fadeToBlack(_engine->_screens->paletteRGBA);
 	_engine->_scene->alphaLight = alphaLightTmp;
 	_engine->_scene->betaLight = betaLightTmp;
-	_engine->_gameState->initEngineVars();
+
+	_engine->_gameState->initEngineProjections();
 
 	_engine->_text->initTextBank(_engine->_scene->sceneTextBank + 3);
 


Commit: e751448b99ac035d2e56bcb451f0dc376b684388
    https://github.com/scummvm/scummvm/commit/e751448b99ac035d2e56bcb451f0dc376b684388
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: comments

Changed paths:
    engines/twine/menu/menu.cpp
    engines/twine/menu/menuoptions.cpp
    engines/twine/scene/scene.h


diff --git a/engines/twine/menu/menu.cpp b/engines/twine/menu/menu.cpp
index a544c45c03..4b0704b077 100644
--- a/engines/twine/menu/menu.cpp
+++ b/engines/twine/menu/menu.cpp
@@ -52,8 +52,6 @@
 
 namespace TwinE {
 
-/** Main menu background image number
-	Used when returning from credit sequence to redraw the main menu background image */
 static const uint32 kPlasmaEffectFilesize = 262176;
 
 namespace MenuButtonTypes {
diff --git a/engines/twine/menu/menuoptions.cpp b/engines/twine/menu/menuoptions.cpp
index adf064306c..703f239ad2 100644
--- a/engines/twine/menu/menuoptions.cpp
+++ b/engines/twine/menu/menuoptions.cpp
@@ -96,6 +96,7 @@ void MenuOptions::newGame() {
 }
 
 void MenuOptions::showCredits() {
+	// TODO: the camera settings are wrong - this results in rendering problems with e.g. circles
 	const int32 tmpShadowMode = _engine->cfgfile.ShadowMode;
 	_engine->cfgfile.ShadowMode = 0;
 	_engine->_gameState->initEngineVars();
diff --git a/engines/twine/scene/scene.h b/engines/twine/scene/scene.h
index afafacd38f..4d0478e5fd 100644
--- a/engines/twine/scene/scene.h
+++ b/engines/twine/scene/scene.h
@@ -345,7 +345,7 @@ public:
 	int32 sceneNumTracks = 0;
 	ScenePoint sceneTracks[NUM_MAX_TRACKS];
 
-	// TODO: check what is this
+	// TODO: check what is this - disables rendering of the grid tiles - used for credits only?
 	bool changeRoomVar10 = false;
 
 	uint8 sceneFlags[NUM_SCENES_FLAGS]{0}; // cubeFlags


Commit: a3be0c2c6d43bc0918ebb2c087f6231d1ef6375c
    https://github.com/scummvm/scummvm/commit/a3be0c2c6d43bc0918ebb2c087f6231d1ef6375c
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: removed unused vars from Text::drawCharacter

Changed paths:
    engines/twine/text.cpp


diff --git a/engines/twine/text.cpp b/engines/twine/text.cpp
index e99ee7e3eb..f585363216 100644
--- a/engines/twine/text.cpp
+++ b/engines/twine/text.cpp
@@ -160,7 +160,6 @@ void Text::initTextBank(int32 bankIdx) {
 }
 
 void Text::drawCharacter(int32 x, int32 y, uint8 character) { // drawCharacter
-	const uint8 sizeX = getCharWidth(character);
 	uint8 sizeY = getCharHeight(character);
 	Common::MemoryReadStream stream(_engine->_resources->fontPtr, _engine->_resources->fontBufSize);
 	stream.seek(character * 4);
@@ -171,21 +170,14 @@ void Text::drawCharacter(int32 x, int32 y, uint8 character) { // drawCharacter
 
 	const uint8 usedColor = _dialTextColor;
 
-	uint8 *screen2 = (uint8 *)_engine->frontVideoBuffer.getBasePtr(x, y);
-
 	int32 tempX = x;
 	int32 tempY = y;
 
-	const int32 toNextLine = SCREEN_WIDTH - sizeX;
-
 	do {
 		uint8 index = stream.readByte();
 		do {
 			const uint8 jump = stream.readByte();
-			screen2 += jump;
-			tempX += jump;
 			if (--index == 0) {
-				screen2 += toNextLine;
 				tempY++;
 				tempX = x;
 				sizeY--;
@@ -195,17 +187,16 @@ void Text::drawCharacter(int32 x, int32 y, uint8 character) { // drawCharacter
 				break;
 			}
 			uint8 number = stream.readByte();
+			tempX += jump;
 			for (uint8 i = 0; i < number; i++) {
 				if (tempX >= SCREEN_TEXTLIMIT_LEFT && tempX < SCREEN_TEXTLIMIT_RIGHT && tempY >= SCREEN_TEXTLIMIT_TOP && tempY < SCREEN_TEXTLIMIT_BOTTOM) {
 					*((uint8 *)_engine->frontVideoBuffer.getBasePtr(tempX, tempY)) = usedColor;
 				}
 
-				screen2++;
 				tempX++;
 			}
 
 			if (--index == 0) {
-				screen2 += toNextLine;
 				tempY++;
 				tempX = x;
 
@@ -247,8 +238,7 @@ void Text::drawText(int32 x, int32 y, const char *dialogue) {
 	}
 
 	do {
-		const uint8 currChar = (uint8) * (dialogue++); // read the next char from the string
-
+		const uint8 currChar = (uint8) *dialogue++; // read the next char from the string
 		if (currChar == '\0') {
 			break;
 		}


Commit: bfa517ae7a3c946b927fcdd4e71690e643ccf4ef
    https://github.com/scummvm/scummvm/commit/bfa517ae7a3c946b927fcdd4e71690e643ccf4ef
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: moved overlay from script code into holomap code

Changed paths:
    engines/twine/holomap.cpp
    engines/twine/script/script_life_v1.cpp


diff --git a/engines/twine/holomap.cpp b/engines/twine/holomap.cpp
index 9d399d7bf2..e1109c510b 100644
--- a/engines/twine/holomap.cpp
+++ b/engines/twine/holomap.cpp
@@ -27,6 +27,7 @@
 #include "twine/scene/gamestate.h"
 #include "twine/resources/hqr.h"
 #include "twine/menu/interface.h"
+#include "twine/renderer/redraw.h"
 #include "twine/renderer/renderer.h"
 #include "twine/renderer/screens.h"
 #include "twine/resources/resources.h"
@@ -65,6 +66,9 @@ bool Holomap::loadLocations() {
 void Holomap::setHolomapPosition(int32 locationIdx) {
 	assert(locationIdx >= 0 && locationIdx <= ARRAYSIZE(_engine->_gameState->holomapFlags));
 	_engine->_gameState->holomapFlags[locationIdx] = 0x81;
+	if (_engine->_gameState->hasItem(InventoryItems::kiHolomap)) {
+		_engine->_redraw->addOverlay(OverlayType::koInventoryItem, InventoryItems::kiHolomap, 0, 0, 0, OverlayPosType::koNormal, 3);
+	}
 }
 
 void Holomap::clearHolomapPosition(int32 locationIdx) {
diff --git a/engines/twine/script/script_life_v1.cpp b/engines/twine/script/script_life_v1.cpp
index a5f78226f6..9e25b462ea 100644
--- a/engines/twine/script/script_life_v1.cpp
+++ b/engines/twine/script/script_life_v1.cpp
@@ -1330,10 +1330,6 @@ static int32 lINIT_PINGOUIN(TwinEEngine *engine, LifeScriptContext &ctx) {
 static int32 lSET_HOLO_POS(TwinEEngine *engine, LifeScriptContext &ctx) {
 	static int32 location = ctx.stream.readByte();
 	engine->_holomap->setHolomapPosition(location);
-	if (engine->_gameState->hasItem(InventoryItems::kiHolomap)) {
-		engine->_redraw->addOverlay(OverlayType::koInventoryItem, InventoryItems::kiHolomap, 0, 0, 0, OverlayPosType::koNormal, 3);
-	}
-
 	return 0;
 }
 


Commit: 2e8f22508e07c43e3b20bfdcdd397da6397be32b
    https://github.com/scummvm/scummvm/commit/2e8f22508e07c43e3b20bfdcdd397da6397be32b
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2020-12-22T17:17:36+01:00

Commit Message:
TWINE: holomap text rendering

Changed paths:
    engines/twine/holomap.cpp
    engines/twine/holomap.h


diff --git a/engines/twine/holomap.cpp b/engines/twine/holomap.cpp
index e1109c510b..312c46dda5 100644
--- a/engines/twine/holomap.cpp
+++ b/engines/twine/holomap.cpp
@@ -21,6 +21,7 @@
  */
 
 #include "twine/holomap.h"
+#include "common/debug.h"
 #include "common/memstream.h"
 #include "common/types.h"
 #include "twine/audio/sound.h"
@@ -132,11 +133,13 @@ void Holomap::loadHolomapGFX() {
 	needToLoadHolomapGFX = 0;
 }
 
-void Holomap::drawHolomapTitle(int32 centerx, int32 top) {
-	const char *title = "TODO";
-	_engine->_text->drawText(centerx - _engine->_text->getTextSize(title) / 2, top, title);
-
-	// TODO
+void Holomap::drawHolomapText(int32 centerx, int32 top, const char *title) {
+	const int32 size = _engine->_text->getTextSize(title);
+	const int32 x = centerx - size / 2;
+	const int32 y = top;
+	_engine->_text->setFontColor(15);
+	_engine->_text->drawText(x, y, title);
+	_engine->copyBlockPhys(x, y, x + 400, y + 100);
 }
 
 void Holomap::drawHolomapTrajectory(int32 trajectoryIndex) {
@@ -144,28 +147,51 @@ void Holomap::drawHolomapTrajectory(int32 trajectoryIndex) {
 	// TODO
 }
 
+void Holomap::drawHolomapLocation() {
+	char title[256] = "";
+	for (int i = 0; i < NUM_LOCATIONS; ++i) {
+		if (!(_engine->_gameState->holomapFlags[i] & 0x81)) {
+			continue;
+		}
+		_engine->_text->getMenuText(200 + _locations[i].textIndex, title, sizeof(title));
+		break;
+	}
+	const int padding = 17;
+	Common::Rect rect;
+	rect.left = padding - 1;
+	rect.top = SCREEN_HEIGHT - 146;
+	rect.right = SCREEN_WIDTH - padding;
+	rect.bottom = SCREEN_HEIGHT - padding;
+	_engine->_menu->drawBox(rect);
+	rect.grow(-1);
+	_engine->_interface->drawTransparentBox(rect, 3);
+	const int32 height = _engine->_text->getCharWidth(title[0]);
+	drawHolomapText(rect.left + (rect.right - rect.left) / 2, rect.top + (rect.bottom - rect.top) / 2 - height / 2, title);
+}
+
 void Holomap::processHolomap() {
 	ScopedEngineFreeze freeze(_engine);
 
-	// TODO memcopy palette
-
 	const int32 alphaLightTmp = _engine->_scene->alphaLight;
 	const int32 betaLightTmp = _engine->_scene->betaLight;
 
 	_engine->_screens->fadeToBlack(_engine->_screens->paletteRGBA);
 	_engine->_sound->stopSamples();
+	_engine->_interface->saveClip();
 	_engine->_interface->resetClip();
 	_engine->_screens->clearScreen();
-	_engine->flip();
-	_engine->_screens->copyScreen(_engine->frontVideoBuffer, _engine->workVideoBuffer);
+	_engine->setPalette(_engine->_screens->paletteRGBA);
 
 	loadHolomapGFX();
-	drawHolomapTitle(SCREEN_WIDTH / 2, 25);
 	_engine->_renderer->setCameraPosition(SCREEN_WIDTH / 2, 190, 128, 1024, 1024);
 
 	_engine->_text->initTextBank(TextBankId::Inventory_Intro_and_Holomap);
 	_engine->_text->setFontCrossColor(9);
 
+	drawHolomapText(SCREEN_WIDTH / 2, 25, "Holomap"); // TODO: fix the index
+	drawHolomapLocation();
+	_engine->flip();
+
 	ScopedKeyMap holomapKeymap(_engine, holomapKeyMapId);
 	for (;;) {
 		ScopedFPS scopedFps;
@@ -194,10 +220,9 @@ void Holomap::processHolomap() {
 	_engine->_scene->betaLight = betaLightTmp;
 
 	_engine->_gameState->initEngineProjections();
+	_engine->_interface->loadClip();
 
 	_engine->_text->initTextBank(_engine->_scene->sceneTextBank + 3);
-
-	// TODO memcopy reset palette
 }
 
 } // namespace TwinE
diff --git a/engines/twine/holomap.h b/engines/twine/holomap.h
index df383e8ed1..532aabda05 100644
--- a/engines/twine/holomap.h
+++ b/engines/twine/holomap.h
@@ -54,6 +54,9 @@ private:
 	int32 needToLoadHolomapGFX = 0;
 	uint8 paletteHolomap[NUMOFCOLORS * 3]{0};
 
+	void drawHolomapText(int32 centerx, int32 top, const char *title);
+	void drawHolomapLocation();
+
 public:
 	Holomap(TwinEEngine *engine);
 
@@ -71,10 +74,6 @@ public:
 	 */
 	void clearHolomapPosition(int32 locationIdx);
 
-	/** Draw Holomap Title */
-	void drawHolomapTitle(int32 centerx, int32 top);
-
-	/** Draw Holomap Trajectory */
 	void drawHolomapTrajectory(int32 trajectoryIndex);
 
 	void loadGfxSub1();




More information about the Scummvm-git-logs mailing list