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

mgerhardy noreply at scummvm.org
Tue Jan 17 18:13:30 UTC 2023


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

Summary:
1dc1cb9ce3 TWINE: fixed loading an image with no palette
15fc0d6a4e TWINE: fixed detection entry for dotemu 2015 steam dlc
aaa7645a52 TWINE: convert the holomap releated code to be more like the original source release
4e0a29d61d TWINE: renamed stuff to match original source
ae4db01bc1 TWINE: fixed top and bottom handling of polygon and sphere rendering


Commit: 1dc1cb9ce301e1a1132e1e26f9dfeac886d3f594
    https://github.com/scummvm/scummvm/commit/1dc1cb9ce301e1a1132e1e26f9dfeac886d3f594
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2023-01-17T19:11:34+01:00

Commit Message:
TWINE: fixed loading an image with no palette

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


diff --git a/engines/twine/renderer/screens.cpp b/engines/twine/renderer/screens.cpp
index 90f9e4372bd..e9961a84806 100644
--- a/engines/twine/renderer/screens.cpp
+++ b/engines/twine/renderer/screens.cpp
@@ -24,6 +24,7 @@
 #include "common/str.h"
 #include "common/system.h"
 #include "graphics/managed_surface.h"
+#include "graphics/pixelformat.h"
 #include "graphics/surface.h"
 #include "image/bmp.h"
 #include "image/image_decoder.h"
@@ -121,8 +122,17 @@ static bool loadImageDelayViaDecoder(TwinEEngine *engine, const Common::String &
 	}
 	Graphics::ManagedSurface &target = engine->_frontVideoBuffer;
 	Common::Rect rect(src->w, src->h);
-	engine->setPalette(decoder.getPaletteStartIndex(), decoder.getPaletteColorCount(), decoder.getPalette());
-	target.transBlitFrom(*src, rect, target.getBounds(), 0, false, 0, 0xff, nullptr, true);
+	if (decoder.getPaletteColorCount() == 0) {
+		uint8 pal[PALETTE_SIZE];
+		engine->_frontVideoBuffer.getPalette(pal, 0, 256);
+		Graphics::Surface *source = decoder.getSurface()->convertTo(target.format, nullptr, 0, pal, 256);
+		target.blitFrom(*source, rect, target.getBounds());
+		source->free();
+		delete source;
+	} else {
+		engine->setPalette(decoder.getPaletteStartIndex(), decoder.getPaletteColorCount(), decoder.getPalette());
+		target.transBlitFrom(*src, rect, target.getBounds(), 0, false, 0, 0xff, nullptr, true);
+	}
 	if (engine->delaySkip(1000 * seconds)) {
 		return true;
 	}
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index e787ef88fdb..a6ba7d3b1c0 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -1159,6 +1159,10 @@ void TwinEEngine::setPalette(const uint32 *palette) {
 }
 
 void TwinEEngine::setPalette(uint startColor, uint numColors, const byte *palette) {
+	if (numColors == 0 || palette == nullptr) {
+		warning("Could not set palette");
+		return;
+	}
 	_frontVideoBuffer.setPalette(palette, startColor, numColors);
 }
 


Commit: 15fc0d6a4e98e4355698887b52e9f96b9e82215c
    https://github.com/scummvm/scummvm/commit/15fc0d6a4e98e4355698887b52e9f96b9e82215c
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2023-01-17T19:11:34+01:00

Commit Message:
TWINE: fixed detection entry for dotemu 2015 steam dlc

Changed paths:
    engines/twine/detection.cpp


diff --git a/engines/twine/detection.cpp b/engines/twine/detection.cpp
index 360826518e2..a5af5358711 100644
--- a/engines/twine/detection.cpp
+++ b/engines/twine/detection.cpp
@@ -222,9 +222,8 @@ static const ADGameDescription twineGameDescriptions[] = {
 	// 8 Sep 2014 at 15:56
 	TWINE_DETECTION_ENTRY("lba", "DotEmu", AD_ENTRY1s("text.hqr", "a374c93450dd2bb874b7167a63974e8d", 377224), Common::kPlatformAndroid, TwinE::TF_DOTEMU_ENHANCED),
 
-	// Potentially the DotEmu release for windows from steam
-	// see https://bugs.scummvm.org/ticket/13885
-	TWINE_DETECTION_ENTRY("lba", "DotEmu", AD_ENTRY1s("LBA.EXE", "615a9a0c3dae2c3b5fca0dee4d84dc72", 931328), Common::kPlatformWindows, TwinE::TF_DOTEMU_ENHANCED),
+	// Twinsen's Little Big Adventure Classic - 2015 Edition (Steam)
+	TWINE_DETECTION_ENTRY("lba", "DotEmu (Steam)", AD_ENTRY1s("LBA.EXE", "615a9a0c3dae2c3b5fca0dee4d84dc72", 931328), Common::kPlatformWindows, TwinE::TF_DOTEMU_ENHANCED),
 
 	// Little Big Adventure - GOG Version
 	// LBA.GOG


Commit: aaa7645a529cd7a933cd969359b270d877d9239f
    https://github.com/scummvm/scummvm/commit/aaa7645a529cd7a933cd969359b270d877d9239f
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2023-01-17T19:11:34+01:00

Commit Message:
TWINE: convert the holomap releated code to be more like the original source release

Changed paths:
    engines/twine/holomap.cpp
    engines/twine/holomap.h
    engines/twine/menu/menu.cpp
    engines/twine/renderer/redraw.cpp
    engines/twine/renderer/renderer.cpp
    engines/twine/renderer/renderer.h
    engines/twine/scene/gamestate.cpp
    engines/twine/scene/gamestate.h
    engines/twine/script/script_life.cpp
    engines/twine/twine.cpp


diff --git a/engines/twine/holomap.cpp b/engines/twine/holomap.cpp
index 5b34fef73bf..e94698a3384 100644
--- a/engines/twine/holomap.cpp
+++ b/engines/twine/holomap.cpp
@@ -56,8 +56,9 @@ namespace TwinE {
 #define HOLOMAP_RESET		(HOLOMAP_VISITED | HOLOMAP_UNK3 | HOLOMAP_UNK4 | HOLOMAP_UNK5 | HOLOMAP_UNK6 | HOLOMAP_UNK7)
 #define HOLOMAP_ACTIVE		(HOLOMAP_CAN_FOCUS | HOLOMAP_ARROW)
 
-static const float zDistanceHolomap = 9500.0f;
+static const float ZOOM_BIG_HOLO = 9500.0f;
 static const float zDistanceTrajectory = 5300.0f;
+static const int SIZE_CURSOR = 20;
 
 Holomap::Holomap(TwinEEngine *engine) : _engine(engine) {}
 
@@ -157,17 +158,23 @@ void Holomap::computeCoorGlobe(Common::SeekableReadStream *holomapSurfaceStream)
 		const int32 rot = holomapSurfaceStream->readByte();
 		holomapSurfaceStream->seek(-1, SEEK_CUR);
 		for (int beta = 0; beta < LBAAngles::ANGLE_360; beta += LBAAngles::ANGLE_11_25) {
-			const int32 rotX = holomapSurfaceStream->readByte();
-			const IVec3 &rotVec = _engine->_renderer->getHolomapRotation(rotX, alpha, beta);
-			_holomapSurface[holomapSurfaceArrayIdx].x = rotVec.x;
-			_holomapSurface[holomapSurfaceArrayIdx].y = rotVec.y;
-			_holomapSurface[holomapSurfaceArrayIdx].z = rotVec.z;
+			const int32 normal = 1000 + holomapSurfaceStream->readByte() * 2;
+			const IVec3 &rotVec = _engine->_renderer->getHolomapRotation(normal, 0, alpha);
+			const IVec3 &rotVec2 = _engine->_renderer->getHolomapRotation(rotVec.x, 0, beta);
+			const IVec3 &rotVec3 = _engine->_renderer->worldRotatePoint(IVec3(rotVec2.x, rotVec.y, rotVec2.y));
+
+			_holomapSurface[holomapSurfaceArrayIdx].x = rotVec3.x;
+			_holomapSurface[holomapSurfaceArrayIdx].y = rotVec3.y;
+			_holomapSurface[holomapSurfaceArrayIdx].z = rotVec3.z;
 			++holomapSurfaceArrayIdx;
 		}
-		const IVec3 &rotVec = _engine->_renderer->getHolomapRotation(rot, alpha, 0);
-		_holomapSurface[holomapSurfaceArrayIdx].x = rotVec.x;
-		_holomapSurface[holomapSurfaceArrayIdx].y = rotVec.y;
-		_holomapSurface[holomapSurfaceArrayIdx].z = rotVec.z;
+		const int32 normal = 1000 + rot * 2;
+		const IVec3 &rotVec = _engine->_renderer->getHolomapRotation(normal, 0, alpha);
+		const IVec3 &rotVec2 = _engine->_renderer->getHolomapRotation(rotVec.x, 0, 0);
+		const IVec3 &rotVec3 = _engine->_renderer->worldRotatePoint(IVec3(rotVec2.x, rotVec.y, rotVec2.y));
+		_holomapSurface[holomapSurfaceArrayIdx].x = rotVec3.x;
+		_holomapSurface[holomapSurfaceArrayIdx].y = rotVec3.y;
+		_holomapSurface[holomapSurfaceArrayIdx].z = rotVec3.z;
 		++holomapSurfaceArrayIdx;
 	}
 	assert(holomapSurfaceStream->eos());
@@ -202,7 +209,7 @@ void Holomap::computeGlobeProj() {
 	for (int32 alpha = -LBAAngles::ANGLE_90; alpha <= LBAAngles::ANGLE_90; alpha += LBAAngles::ANGLE_11_25) {
 		for (int32 beta = 0; beta < LBAAngles::ANGLE_11_25; ++beta) {
 			IVec3 *vec = &_holomapSurface[holomapSurfaceArrayIdx++];
-			const IVec3 &destPos = _engine->_renderer->getBaseRotationPosition(vec->x, vec->y, vec->z);
+			const IVec3 &destPos = _engine->_renderer->longWorldRot(vec->x, vec->y, vec->z);
 			if (alpha != LBAAngles::ANGLE_90) {
 				_holomapSort[holomapSortArrayIdx].z = (int16)destPos.z;
 				_holomapSort[holomapSortArrayIdx].projectedPosIdx = _projectedSurfaceIndex;
@@ -214,7 +221,7 @@ void Holomap::computeGlobeProj() {
 			++_projectedSurfaceIndex;
 		}
 		IVec3 *vec = &_holomapSurface[holomapSurfaceArrayIdx++];
-		const IVec3 &destPos = _engine->_renderer->getBaseRotationPosition(vec->x, vec->y, vec->z);
+		const IVec3 &destPos = _engine->_renderer->longWorldRot(vec->x, vec->y, vec->z);
 		const IVec3 &projPos = _engine->_renderer->projectPositionOnScreen(destPos);
 		_projectedSurfacePositions[_projectedSurfaceIndex].x1 = projPos.x;
 		_projectedSurfacePositions[_projectedSurfaceIndex].y1 = projPos.y;
@@ -283,8 +290,8 @@ void Holomap::drawHolomapText(int32 centerx, int32 top, const char *title) {
 
 void Holomap::drawHoloObj(const IVec3 &angle, int32 x, int32 y) {
 	_engine->_renderer->setAngleCamera(x, y, 0);
-	const IVec3 &destPos = _engine->_renderer->getBaseRotationPosition(0, 0, 1000);
-	_engine->_renderer->setBaseTranslation(0, 0, 0);
+	const IVec3 &destPos = _engine->_renderer->longWorldRot(0, 0, 1000);
+	_engine->_renderer->setPosCamera(0, 0, 0);
 	_engine->_renderer->setBaseRotation(angle);
 	_engine->_renderer->setBaseRotationPos(0, 0, distance(zDistanceTrajectory));
 	_engine->_interface->resetClip();
@@ -307,12 +314,12 @@ void Holomap::renderHolomapVehicle(uint &frameNumber, ActorMoveStruct &move, Ani
 	}
 	const Common::Rect rect(0, _engine->height() - 280, 200, _engine->height() - 1);
 	_engine->_renderer->setProjection(rect.width() / 2, _engine->height() - 80, 128, 900, 900);
-	_engine->_renderer->setCameraAngle(0, 0, 0, 60, 128, 0, distance(30000));
+	_engine->_renderer->setFollowCamera(0, 0, 0, 60, 128, 0, distance(30000));
 	_engine->_renderer->setLightVector(-60, 128, 0);
 	// background of the vehicle
 	_engine->_interface->drawFilledRect(rect, COLOR_BLACK);
 	Common::Rect dummy;
-	_engine->_renderer->renderIsoModel(0, 0, 0, LBAAngles::ANGLE_0, newAngle, LBAAngles::ANGLE_0, bodyData, dummy);
+	_engine->_renderer->affObjetIso(0, 0, 0, LBAAngles::ANGLE_0, newAngle, LBAAngles::ANGLE_0, bodyData, dummy);
 	_engine->copyBlockPhys(rect);
 }
 
@@ -339,7 +346,7 @@ void Holomap::drawHolomapTrajectory(int32 trajectoryIndex) {
 	const int32 cameraPosX = _engine->width() / 2 + 80;
 	const int32 cameraPosY = _engine->height() / 2;
 	_engine->_renderer->setProjection(cameraPosX, cameraPosY, 128, 1024, 1024);
-	_engine->_renderer->setCameraAngle(0, 0, 0, data->pos.x, data->pos.y, data->pos.z, distance(zDistanceTrajectory));
+	_engine->_renderer->setFollowCamera(0, 0, 0, data->pos.x, data->pos.y, data->pos.z, distance(zDistanceTrajectory));
 
 	constexpr TwineResource holomapImageRes(Resources::HQR_RESS_FILE, RESSHQR_HOLOIMG);
 	uint8 *holomapImagePtr = nullptr;
@@ -385,7 +392,7 @@ void Holomap::drawHolomapTrajectory(int32 trajectoryIndex) {
 
 		// now render the holomap path
 		_engine->_renderer->setProjection(cameraPosX, cameraPosY, 128, 1024, 1024);
-		_engine->_renderer->setCameraAngle(0, 0, 0, data->pos.x, data->pos.y, data->pos.z, distance(zDistanceTrajectory));
+		_engine->_renderer->setFollowCamera(0, 0, 0, data->pos.x, data->pos.y, data->pos.z, distance(zDistanceTrajectory));
 		_engine->_renderer->setLightVector(data->pos.x, data->pos.y, 0);
 
 		// animate the path from point 1 to point 2 by rendering a point model on each position
@@ -417,7 +424,7 @@ void Holomap::drawHolomapTrajectory(int32 trajectoryIndex) {
 
 	_engine->_screens->clearScreen();
 	_engine->setPalette(_engine->_screens->_paletteRGBA);
-	_engine->_gameState->initEngineProjections();
+	_engine->_gameState->init3DGame();
 	_engine->_interface->loadClip();
 
 	_engine->_text->initSceneTextBank();
@@ -426,7 +433,7 @@ void Holomap::drawHolomapTrajectory(int32 trajectoryIndex) {
 	free(holomapImagePtr);
 }
 
-int32 Holomap::getNextHolomapLocation(int32 currentLocation, int32 dir) const {
+int32 Holomap::searchNextArrow(int32 currentLocation, int32 dir) const {
 	const int32 idx = currentLocation;
 	for (int32 i = currentLocation + dir; i != idx; i += dir) {
 		if (i < 0) {
@@ -441,41 +448,42 @@ int32 Holomap::getNextHolomapLocation(int32 currentLocation, int32 dir) const {
 	return -1;
 }
 
-void Holomap::renderLocations(int xRot, int yRot, int zRot, bool lower) {
+void Holomap::drawListPos(int xRot, int yRot, int zRot, bool lower) {
 	int n = 0;
 	DrawListStruct drawListArray[NUM_LOCATIONS];
 	for (int locationIdx = 0; locationIdx < NUM_LOCATIONS; ++locationIdx) {
-		if ((_engine->_gameState->_holomapFlags[locationIdx] & HOLOMAP_CAN_FOCUS) || locationIdx == _engine->_scene->_currentSceneIdx) {
-			const Location &loc = _locations[locationIdx];
-			_engine->_renderer->setAngleCamera(loc.angleX, loc.angleY, 0);
-			const IVec3 &destPos = _engine->_renderer->getBaseRotationPosition(0, 0, loc.size + 1000);
-			const IVec3 &destPos2 = _engine->_renderer->getBaseRotationPosition(0, 0, 1500);
-			_engine->_renderer->setAngleCamera(xRot, yRot, zRot, true);
-			_engine->_renderer->setBaseRotationPos(0, 0, distance(zDistanceHolomap));
-			const IVec3 &destPos3 = _engine->_renderer->getBaseRotationPosition(destPos);
-			const IVec3 &destPos4 = _engine->_renderer->getBaseRotationPosition(destPos2);
-			bool visible;
-			if (lower) {
-				visible = destPos3.z <= destPos4.z;
-			} else {
-				visible = destPos4.z <= destPos3.z;
-			}
-			if (!visible) {
-				continue;
-			}
-			uint8 flags = _engine->_gameState->_holomapFlags[locationIdx] & HOLOMAP_ARROW;
-			if (locationIdx == _engine->_scene->_currentSceneIdx) {
-				flags |= 2u; // model type
-			}
-			DrawListStruct &drawList = drawListArray[n];
-			drawList.posValue = destPos3.z;
-			drawList.actorIdx = locationIdx;
-			drawList.type = flags;
-			drawList.x = destPos.x;
-			drawList.y = destPos.y;
-			drawList.z = destPos.z;
-			++n;
+		if (!(_engine->_gameState->_holomapFlags[locationIdx] & HOLOMAP_CAN_FOCUS) && locationIdx != _engine->_scene->_currentSceneIdx) {
+			continue;
+		}
+		const Location &loc = _locations[locationIdx];
+		_engine->_renderer->setAngleCamera(loc.angleX, loc.angleY, 0);
+		const IVec3 &destPos = _engine->_renderer->longWorldRot(0, 0, loc.size + 1000);
+		const IVec3 &destPos2 = _engine->_renderer->longWorldRot(0, 0, 1500);
+		_engine->_renderer->setInverseAngleCamera(xRot, yRot, zRot);
+		_engine->_renderer->setBaseRotationPos(0, 0, distance(ZOOM_BIG_HOLO));
+		const IVec3 &destPos3 = _engine->_renderer->worldRotatePoint(destPos);
+		const IVec3 &destPos4 = _engine->_renderer->worldRotatePoint(destPos2);
+		bool visible;
+		if (lower) {
+			visible = destPos3.z <= destPos4.z;
+		} else {
+			visible = destPos4.z <= destPos3.z;
 		}
+		if (!visible) {
+			continue;
+		}
+		uint8 flags = _engine->_gameState->_holomapFlags[locationIdx] & HOLOMAP_ARROW;
+		if (locationIdx == _engine->_scene->_currentSceneIdx) {
+			flags |= 2u; // model type
+		}
+		DrawListStruct &drawList = drawListArray[n];
+		drawList.posValue = destPos3.z;
+		drawList.actorIdx = locationIdx;
+		drawList.type = flags;
+		drawList.x = destPos.x;
+		drawList.y = destPos.y;
+		drawList.z = destPos.z;
+		++n;
 	}
 	_engine->_redraw->sortDrawingList(drawListArray, n);
 	for (int i = 0; i < n; ++i) {
@@ -493,35 +501,35 @@ void Holomap::renderLocations(int xRot, int yRot, int zRot, bool lower) {
 			const int32 angleX = _locations[drawList.actorIdx].angleX;
 			const int32 angleY = _locations[drawList.actorIdx].angleY;
 			Common::Rect dummy;
-			_engine->_renderer->renderIsoModel(drawList.x, drawList.y, drawList.z, angleX, angleY, LBAAngles::ANGLE_0, *bodyData, dummy);
+			_engine->_renderer->affObjetIso(drawList.x, drawList.y, drawList.z, angleX, angleY, LBAAngles::ANGLE_0, *bodyData, dummy);
 		}
 	}
 }
 
-void Holomap::processHolomap() {
+void Holomap::holoMap() {
 	ScopedEngineFreeze freeze(_engine);
 
 	const int32 alphaLightTmp = _engine->_scene->_alphaLight;
 	const int32 betaLightTmp = _engine->_scene->_betaLight;
 
 	_engine->exitSceneryView();
-	_engine->_gameState->initEngineProjections();
+	_engine->_gameState->init3DGame();
 
 	_engine->_screens->fadeToBlack(_engine->_screens->_paletteRGBA);
 	_engine->_sound->stopSamples();
-	_engine->_interface->saveClip();
 	_engine->_interface->resetClip();
 	_engine->_screens->clearScreen();
 	_engine->_screens->fadeToBlack(_engine->_screens->_paletteRGBA);
 
 	initHoloDatas();
 
-	_engine->_text->initDial(TextBankId::Inventory_Intro_and_Holomap);
-	_engine->_text->setFontCrossColor(COLOR_9);
 	const int32 cameraPosX = _engine->width() / 2;
 	const int32 cameraPosY = scale(190);
 	_engine->_renderer->setProjection(cameraPosX, cameraPosY, 128, 1024, 1024);
 
+	_engine->_text->initDial(TextBankId::Inventory_Intro_and_Holomap);
+	_engine->_text->setFontCrossColor(COLOR_9);
+
 	constexpr TwineResource holomapImageRes(Resources::HQR_RESS_FILE, RESSHQR_HOLOIMG);
 	uint8 *holomapImagePtr = nullptr;
 	const int32 holomapImageSize = HQR::getAllocEntry(&holomapImagePtr, holomapImageRes);
@@ -548,7 +556,7 @@ void Holomap::processHolomap() {
 		}
 
 		if (_engine->_input->toggleActionIfActive(TwinEActionType::HolomapPrev)) {
-			const int32 nextLocation = getNextHolomapLocation(currentLocation, -1);
+			const int32 nextLocation = searchNextArrow(currentLocation, -1);
 			if (nextLocation != -1 && currentLocation != nextLocation) {
 				currentLocation = nextLocation;
 				_engine->_text->drawHolomapLocation(_locations[currentLocation].textIndex);
@@ -556,7 +564,7 @@ void Holomap::processHolomap() {
 				automove = true;
 			}
 		} else if (_engine->_input->toggleActionIfActive(TwinEActionType::HolomapNext)) {
-			const int32 nextLocation = getNextHolomapLocation(currentLocation, 1);
+			const int32 nextLocation = searchNextArrow(currentLocation, 1);
 			if (nextLocation != -1 && currentLocation != nextLocation) {
 				currentLocation = nextLocation;
 				_engine->_text->drawHolomapLocation(_locations[currentLocation].textIndex);
@@ -606,17 +614,17 @@ void Holomap::processHolomap() {
 			redraw = false;
 			const Common::Rect &rect = _engine->centerOnScreenX(scale(300), 0, scale(330));
 			_engine->_interface->drawFilledRect(rect, COLOR_BLACK);
-			_engine->_renderer->setAngleCamera(xRot, yRot, 0, true);
+			_engine->_renderer->setInverseAngleCamera(xRot, yRot, 0);
 			_engine->_renderer->setLightVector(xRot, yRot, 0);
-			renderLocations(xRot, yRot, 0, false);
-			_engine->_renderer->setAngleCamera(xRot, yRot, 0, true);
-			_engine->_renderer->setBaseRotationPos(0, 0, distance(zDistanceHolomap));
+			drawListPos(xRot, yRot, 0, false);
+			_engine->_renderer->setInverseAngleCamera(xRot, yRot, 0);
+			_engine->_renderer->setBaseRotationPos(0, 0, distance(ZOOM_BIG_HOLO));
 			drawHoloMap(holomapImagePtr, holomapImageSize);
-			renderLocations(xRot, yRot, 0, true);
+			drawListPos(xRot, yRot, 0, true);
 			drawHolomapText(_engine->width() / 2, 25, "HoloMap");
 			if (automove) {
 				// draw cursor
-				const Common::Rect &targetRect = _engine->centerOnScreen(40, 40);
+				const Common::Rect &targetRect = _engine->centerOnScreen(SIZE_CURSOR * 2, SIZE_CURSOR * 2);
 				_engine->_menu->drawRectBorders(targetRect.left, cameraPosY - 20, targetRect.right, cameraPosY + 20, 15, 15);
 			}
 		}
@@ -639,7 +647,7 @@ void Holomap::processHolomap() {
 	_engine->_scene->_alphaLight = alphaLightTmp;
 	_engine->_scene->_betaLight = betaLightTmp;
 
-	_engine->_gameState->initEngineProjections();
+	_engine->_gameState->init3DGame();
 	_engine->_interface->loadClip();
 
 	_engine->_input->enableKeyMap(mainKeyMapId);
diff --git a/engines/twine/holomap.h b/engines/twine/holomap.h
index 1038f89f59a..7426f20ba81 100644
--- a/engines/twine/holomap.h
+++ b/engines/twine/holomap.h
@@ -84,9 +84,9 @@ private:
 	uint8 _paletteHolomap[NUMOFCOLORS * 3]{0};
 
 	void drawHolomapText(int32 centerx, int32 top, const char *title);
-	int32 getNextHolomapLocation(int32 currentLocation, int32 dir) const;
+	int32 searchNextArrow(int32 currentLocation, int32 dir) const;
 
-	void renderLocations(int xRot, int yRot, int zRot, bool lower);
+	void drawListPos(int xRot, int yRot, int zRot, bool lower);
 
 	/**
 	 * Renders a holomap path with single path points appearing slowly one after another
@@ -129,7 +129,7 @@ public:
 	void initHoloDatas();
 
 	/** Main holomap process loop */
-	void processHolomap();
+	void holoMap();
 };
 
 } // namespace TwinE
diff --git a/engines/twine/menu/menu.cpp b/engines/twine/menu/menu.cpp
index f82a60db2c2..514d01ea1c5 100644
--- a/engines/twine/menu/menu.cpp
+++ b/engines/twine/menu/menu.cpp
@@ -1192,7 +1192,7 @@ void Menu::processBehaviourMenu(bool behaviourMenu) {
 
 		_engine->_lbaTime = tmpTime;
 
-		_engine->_gameState->initEngineProjections();
+		_engine->_gameState->init3DGame();
 	}
 	_engine->_actor->setBehaviour(_engine->_actor->_heroBehaviour);
 
@@ -1216,7 +1216,7 @@ void Menu::drawItem(int32 left, int32 top, int32 item) {
 	if (item < NUM_INVENTORY_ITEMS && _engine->_gameState->hasItem((InventoryItems)item) && (!_engine->_gameState->inventoryDisabled() || item == InventoryItems::kiCloverLeaf)) {
 		_itemAngle[item] += LBAAngles::ANGLE_2;
 		_engine->_interface->setClip(rect);
-		_engine->_renderer->renderInventoryItem(itemX, itemY, _engine->_resources->_inventoryTable[item], _itemAngle[item], 15000);
+		_engine->_renderer->draw3dObject(itemX, itemY, _engine->_resources->_inventoryTable[item], _itemAngle[item], 15000);
 		_engine->_interface->resetClip();
 		if (item == InventoryItems::kGasItem) {
 			_engine->_text->setFontColor(COLOR_WHITE);
@@ -1356,7 +1356,7 @@ void Menu::processInventoryMenu() {
 	_engine->_scene->_alphaLight = tmpAlphaLight;
 	_engine->_scene->_betaLight = tmpBetaLight;
 
-	_engine->_gameState->initEngineProjections();
+	_engine->_gameState->init3DGame();
 
 	_engine->_text->initSceneTextBank();
 
diff --git a/engines/twine/renderer/redraw.cpp b/engines/twine/renderer/redraw.cpp
index 4eeb1859d83..a40581bd246 100644
--- a/engines/twine/renderer/redraw.cpp
+++ b/engines/twine/renderer/redraw.cpp
@@ -359,7 +359,7 @@ void Redraw::processDrawListActors(const DrawListStruct &drawCmd, bool bgRedraw)
 		}
 	}
 
-	if (!_engine->_renderer->renderIsoModel(delta.x, delta.y, delta.z, LBAAngles::ANGLE_0, actor->_beta, LBAAngles::ANGLE_0, _engine->_resources->_bodyData[actor->_body], renderRect)) {
+	if (!_engine->_renderer->affObjetIso(delta.x, delta.y, delta.z, LBAAngles::ANGLE_0, actor->_beta, LBAAngles::ANGLE_0, _engine->_resources->_bodyData[actor->_body], renderRect)) {
 		_engine->_interface->resetClip();
 		return;
 	}
@@ -726,10 +726,10 @@ void Redraw::renderOverlays() {
 
 				const BodyData &bodyPtr = _engine->_resources->_inventoryTable[item];
 				_overlayRotation += 1; // overlayRotation += 8;
-				_engine->_renderer->renderInventoryItem(40, 40, bodyPtr, _overlayRotation, 16000);
+				_engine->_renderer->draw3dObject(40, 40, bodyPtr, _overlayRotation, 16000);
 				_engine->_menu->drawRectBorders(rect);
 				addRedrawArea(rect);
-				_engine->_gameState->initEngineProjections();
+				_engine->_gameState->init3DGame();
 				_engine->_interface->resetClip();
 				break;
 			}
diff --git a/engines/twine/renderer/renderer.cpp b/engines/twine/renderer/renderer.cpp
index 609a09693cd..0c55fd1b0d3 100644
--- a/engines/twine/renderer/renderer.cpp
+++ b/engines/twine/renderer/renderer.cpp
@@ -65,16 +65,16 @@ IVec3 &Renderer::projectPositionOnScreen(int32 cX, int32 cY, int32 cZ) { // Proj
 		return _projPos;
 	}
 
-	if (_baseRotPos.z - cZ < 0) {
+	if (_cameraRot.z - cZ < 0) {
 		_projPos.x = 0;
 		_projPos.y = 0;
 		_projPos.z = 0;
 		return _projPos;
 	}
 
-	cX -= _baseRotPos.x;
-	cY -= _baseRotPos.y;
-	cZ = _baseRotPos.z - cZ;
+	cX -= _cameraRot.x;
+	cY -= _cameraRot.y;
+	cZ = _cameraRot.z - cZ;
 
 	int32 posZ = cZ + _kFactor;
 	if (posZ <= 0) {
@@ -98,10 +98,10 @@ void Renderer::setProjection(int32 x, int32 y, int32 kfact, int32 lfactx, int32
 	_isUsingIsoProjection = false;
 }
 
-void Renderer::setBaseTranslation(int32 x, int32 y, int32 z) {
-	_baseTransPos.x = x;
-	_baseTransPos.y = y;
-	_baseTransPos.z = z;
+void Renderer::setPosCamera(int32 x, int32 y, int32 z) {
+	_cameraPos.x = x;
+	_cameraPos.y = y;
+	_cameraPos.z = z;
 }
 
 void Renderer::setIsoProjection(int32 x, int32 y, int32 scale) {
@@ -112,116 +112,92 @@ void Renderer::setIsoProjection(int32 x, int32 y, int32 scale) {
 	_isUsingIsoProjection = true;
 }
 
-void Renderer::baseMatrixTranspose() {
-	SWAP(_baseMatrix.row1.y, _baseMatrix.row2.x);
-	SWAP(_baseMatrix.row1.z, _baseMatrix.row3.x);
-	SWAP(_baseMatrix.row2.z, _baseMatrix.row3.y);
+void Renderer::flipMatrix() {
+	SWAP(_matrixWorld.row1.y, _matrixWorld.row2.x);
+	SWAP(_matrixWorld.row1.z, _matrixWorld.row3.x);
+	SWAP(_matrixWorld.row2.z, _matrixWorld.row3.y);
 }
 
-IVec3 Renderer::setAngleCamera(int32 x, int32 y, int32 z, bool transpose) {
+IVec3 Renderer::setInverseAngleCamera(int32 x, int32 y, int32 z) {
+	setAngleCamera(x, y, z);
+	flipMatrix();
+	_cameraRot = longWorldRot(_cameraPos.x, _cameraPos.y, _cameraPos.z);
+	return _cameraRot;
+}
+
+IVec3 Renderer::setAngleCamera(int32 x, int32 y, int32 z) {
 	const double Xradians = (double)((LBAAngles::ANGLE_90 - x) % LBAAngles::ANGLE_360) * 2 * M_PI / LBAAngles::ANGLE_360;
 	const double Yradians = (double)((LBAAngles::ANGLE_90 - y) % LBAAngles::ANGLE_360) * 2 * M_PI / LBAAngles::ANGLE_360;
 	const double Zradians = (double)((LBAAngles::ANGLE_90 - z) % LBAAngles::ANGLE_360) * 2 * M_PI / LBAAngles::ANGLE_360;
 
-	_baseMatrix.row1.x = (int32)(sin(Zradians) * sin(Yradians) * SCENE_SIZE_HALFF);
-	_baseMatrix.row1.y = (int32)(-cos(Zradians) * SCENE_SIZE_HALFF);
-	_baseMatrix.row1.z = (int32)(sin(Zradians) * cos(Yradians) * SCENE_SIZE_HALFF);
-	_baseMatrix.row2.x = (int32)(cos(Zradians) * sin(Xradians) * SCENE_SIZE_HALFF);
-	_baseMatrix.row2.y = (int32)(sin(Zradians) * sin(Xradians) * SCENE_SIZE_HALFF);
-	_baseMatrix.row3.x = (int32)(cos(Zradians) * cos(Xradians) * SCENE_SIZE_HALFF);
-	_baseMatrix.row3.y = (int32)(sin(Zradians) * cos(Xradians) * SCENE_SIZE_HALFF);
+	_matrixWorld.row1.x = (int32)(sin(Zradians) * sin(Yradians) * SCENE_SIZE_HALFF);
+	_matrixWorld.row1.y = (int32)(-cos(Zradians) * SCENE_SIZE_HALFF);
+	_matrixWorld.row1.z = (int32)(sin(Zradians) * cos(Yradians) * SCENE_SIZE_HALFF);
+	_matrixWorld.row2.x = (int32)(cos(Zradians) * sin(Xradians) * SCENE_SIZE_HALFF);
+	_matrixWorld.row2.y = (int32)(sin(Zradians) * sin(Xradians) * SCENE_SIZE_HALFF);
+	_matrixWorld.row3.x = (int32)(cos(Zradians) * cos(Xradians) * SCENE_SIZE_HALFF);
+	_matrixWorld.row3.y = (int32)(sin(Zradians) * cos(Xradians) * SCENE_SIZE_HALFF);
 
-	int32 matrixElem = _baseMatrix.row2.x;
+	int32 matrixElem = _matrixWorld.row2.x;
 
-	_baseMatrix.row2.x = (int32)(sin(Yradians) * matrixElem + SCENE_SIZE_HALFF * cos(Yradians) * cos(Xradians));
-	_baseMatrix.row2.z = (int32)(cos(Yradians) * matrixElem - SCENE_SIZE_HALFF * sin(Yradians) * cos(Xradians));
+	_matrixWorld.row2.x = (int32)(sin(Yradians) * matrixElem + SCENE_SIZE_HALFF * cos(Yradians) * cos(Xradians));
+	_matrixWorld.row2.z = (int32)(cos(Yradians) * matrixElem - SCENE_SIZE_HALFF * sin(Yradians) * cos(Xradians));
 
-	matrixElem = _baseMatrix.row3.x;
+	matrixElem = _matrixWorld.row3.x;
 
-	_baseMatrix.row3.x = (int32)(sin(Yradians) * matrixElem - SCENE_SIZE_HALFF * sin(Xradians) * cos(Yradians));
-	_baseMatrix.row3.z = (int32)(cos(Yradians) * matrixElem + SCENE_SIZE_HALFF * sin(Xradians) * sin(Yradians));
+	_matrixWorld.row3.x = (int32)(sin(Yradians) * matrixElem - SCENE_SIZE_HALFF * sin(Xradians) * cos(Yradians));
+	_matrixWorld.row3.z = (int32)(cos(Yradians) * matrixElem + SCENE_SIZE_HALFF * sin(Xradians) * sin(Yradians));
 
-	if (transpose) {
-		baseMatrixTranspose();
-	}
-	_baseRotPos = getBaseRotationPosition(_baseTransPos.x, _baseTransPos.y, _baseTransPos.z);
+	_cameraRot = longWorldRot(_cameraPos.x, _cameraPos.y, _cameraPos.z);
 
-	return _baseRotPos;
+	return _cameraRot;
 }
 
-IVec3 Renderer::getBaseRotationPosition(int32 x, int32 y, int32 z) {
-	const int32 vx = (_baseMatrix.row1.x * x + _baseMatrix.row1.y * y + _baseMatrix.row1.z * z) / SCENE_SIZE_HALF;
-	const int32 vy = (_baseMatrix.row2.x * x + _baseMatrix.row2.y * y + _baseMatrix.row2.z * z) / SCENE_SIZE_HALF;
-	const int32 vz = (_baseMatrix.row3.x * x + _baseMatrix.row3.y * y + _baseMatrix.row3.z * z) / SCENE_SIZE_HALF;
+IVec3 Renderer::longWorldRot(int32 x, int32 y, int32 z) {
+	const int32 vx = (_matrixWorld.row1.x * x + _matrixWorld.row1.y * y + _matrixWorld.row1.z * z) / SCENE_SIZE_HALF;
+	const int32 vy = (_matrixWorld.row2.x * x + _matrixWorld.row2.y * y + _matrixWorld.row2.z * z) / SCENE_SIZE_HALF;
+	const int32 vz = (_matrixWorld.row3.x * x + _matrixWorld.row3.y * y + _matrixWorld.row3.z * z) / SCENE_SIZE_HALF;
 	return IVec3(vx, vy, vz);
 }
 
-IVec3 Renderer::getCameraAnglePositions(int32 x, int32 y, int32 z) {
-	const int32 vx = (_baseMatrix.row1.x * x + _baseMatrix.row2.x * y + _baseMatrix.row3.x * z) / SCENE_SIZE_HALF;
-	const int32 vy = (_baseMatrix.row1.y * x + _baseMatrix.row2.y * y + _baseMatrix.row3.y * z) / SCENE_SIZE_HALF;
-	const int32 vz = (_baseMatrix.row1.z * x + _baseMatrix.row2.z * y + _baseMatrix.row3.z * z) / SCENE_SIZE_HALF;
+IVec3 Renderer::longInverseRot(int32 x, int32 y, int32 z) {
+	const int32 vx = (_matrixWorld.row1.x * x + _matrixWorld.row2.x * y + _matrixWorld.row3.x * z) / SCENE_SIZE_HALF;
+	const int32 vy = (_matrixWorld.row1.y * x + _matrixWorld.row2.y * y + _matrixWorld.row3.y * z) / SCENE_SIZE_HALF;
+	const int32 vz = (_matrixWorld.row1.z * x + _matrixWorld.row2.z * y + _matrixWorld.row3.z * z) / SCENE_SIZE_HALF;
 	return IVec3(vx, vy, vz);
 }
 
-IVec3 Renderer::translateGroup(const IMatrix3x3 &matrix, int32 x, int32 y, int32 z) {
+IVec3 Renderer::rot(const IMatrix3x3 &matrix, int32 x, int32 y, int32 z) {
 	const int32 vx = (matrix.row1.x * x + matrix.row1.y * y + matrix.row1.z * z) / SCENE_SIZE_HALF;
 	const int32 vy = (matrix.row2.x * x + matrix.row2.y * y + matrix.row2.z * z) / SCENE_SIZE_HALF;
 	const int32 vz = (matrix.row3.x * x + matrix.row3.y * y + matrix.row3.z * z) / SCENE_SIZE_HALF;
 	return IVec3(vx, vy, vz);
 }
 
-void Renderer::setCameraAngle(int32 transPosX, int32 transPosY, int32 transPosZ, int32 rotPosX, int32 rotPosY, int32 rotPosZ, int32 param6) {
-	_baseTransPos.x = transPosX;
-	_baseTransPos.y = transPosY;
-	_baseTransPos.z = transPosZ;
+void Renderer::setFollowCamera(int32 transPosX, int32 transPosY, int32 transPosZ, int32 cameraAlpha, int32 cameraBeta, int32 cameraGamma, int32 cameraZoom) {
+	_cameraPos.x = transPosX;
+	_cameraPos.y = transPosY;
+	_cameraPos.z = transPosZ;
 
-	setAngleCamera(rotPosX, rotPosY, rotPosZ);
+	setAngleCamera(cameraAlpha, cameraBeta, cameraGamma);
+	_cameraRot.z += cameraZoom;
 
-	_baseRotPos.z += param6;
-
-	_baseTransPos = updateCameraAnglePositions();
+	_cameraPos = longInverseRot(_cameraRot.x, _cameraRot.y, _cameraRot.z);
 }
 
-IVec3 Renderer::updateCameraAnglePositions(int zShift) {
-	return getCameraAnglePositions(_baseRotPos.x, _baseRotPos.y, _baseRotPos.z + zShift);
-}
+IVec3 Renderer::getHolomapRotation(const int32 x, const int32 y, const int32 angle) const {
+	if (angle) {
+		const int32 nSin = lba1ShadeAngleTable[ClampAngle(angle)];
+		const int32 nCos = lba1ShadeAngleTable[ClampAngle((angle + LBAAngles::ANGLE_90))];
 
-IVec3 Renderer::getHolomapRotation(const int32 angleX, const int32 angleY, const int32 angleZ) const {
-	int32 rotX = angleX * 2 + 1000;
-
-	int32 rotY;
-	if (angleY == LBAAngles::ANGLE_0) {
-		rotY = LBAAngles::ANGLE_0;
-	} else {
-		rotY = -lba1ShadeAngleTable[ClampAngle(angleY)] * rotX / SCENE_SIZE_HALF;
-		rotX = lba1ShadeAngleTable[ClampAngle(angleY + LBAAngles::ANGLE_90)] * rotX / SCENE_SIZE_HALF;
+		const int32 x0 = ((x * nCos) + (y * nSin)) >> 14;
+		const int32 y0 = ((y * nCos) - (x * nSin)) >> 14;
+		return IVec3(x0, y0, 0);
 	}
-
-	int32 rotZ;
-	if (angleZ == LBAAngles::ANGLE_0) {
-		rotZ = LBAAngles::ANGLE_0;
-	} else {
-		rotZ = -lba1ShadeAngleTable[ClampAngle(angleZ)] * rotX / SCENE_SIZE_HALF;
-		rotX = lba1ShadeAngleTable[ClampAngle(angleZ + LBAAngles::ANGLE_90)] * rotX / SCENE_SIZE_HALF;
-	}
-
-	const int32 row1X = _baseMatrix.row1.x * rotX;
-	const int32 row1Y = _baseMatrix.row1.y * rotY;
-	const int32 row1Z = _baseMatrix.row1.z * rotZ;
-	const int32 row2X = _baseMatrix.row2.x * rotX;
-	const int32 row2Y = _baseMatrix.row2.y * rotY;
-	const int32 row2Z = _baseMatrix.row2.z * rotZ;
-	const int32 row3X = _baseMatrix.row3.x * rotX;
-	const int32 row3Y = _baseMatrix.row3.y * rotY;
-	const int32 row3Z = _baseMatrix.row3.z * rotZ;
-	IVec3 vec;
-	vec.x = (row1X + row1Y + row1Z) / SCENE_SIZE_HALF;
-	vec.y = (row2X + row2Y + row2Z) / SCENE_SIZE_HALF;
-	vec.z = (row3X + row3Y + row3Z) / SCENE_SIZE_HALF;
-	return vec;
+	return IVec3(x, y, 0);
 }
 
-void Renderer::applyRotation(IMatrix3x3 *targetMatrix, const IMatrix3x3 *currentMatrix, const IVec3 &angleVec) {
+void Renderer::rotMatIndex2(IMatrix3x3 *targetMatrix, const IMatrix3x3 *currentMatrix, const IVec3 &angleVec) {
 	IMatrix3x3 matrix1;
 	IMatrix3x3 matrix2;
 
@@ -316,7 +292,7 @@ void Renderer::processRotatedElement(IMatrix3x3 *targetMatrix, const Common::Arr
 	IVec3 destPos;
 	// if its the first point
 	if (bone.isRoot()) {
-		currentMatrix = &_baseMatrix;
+		currentMatrix = &_matrixWorld;
 	} else {
 		const int32 pointIdx = bone.vertex;
 		const int32 matrixIndex = bone.parent;
@@ -326,7 +302,7 @@ void Renderer::processRotatedElement(IMatrix3x3 *targetMatrix, const Common::Arr
 		destPos = modelData->computedPoints[pointIdx];
 	}
 
-	applyRotation(targetMatrix, currentMatrix, renderAngle);
+	rotMatIndex2(targetMatrix, currentMatrix, renderAngle);
 
 	if (!numOfPoints) {
 		warning("RENDER WARNING: No points in this model!");
@@ -359,7 +335,7 @@ void Renderer::processTranslatedElement(IMatrix3x3 *targetMatrix, const Common::
 	IVec3 destPos;
 
 	if (bone.isRoot()) { // base point
-		*targetMatrix = _baseMatrix;
+		*targetMatrix = _matrixWorld;
 	} else { // dependent
 		const int32 pointsIdx = bone.vertex;
 		destPos = modelData->computedPoints[pointsIdx];
@@ -373,15 +349,11 @@ void Renderer::processTranslatedElement(IMatrix3x3 *targetMatrix, const Common::
 }
 
 void Renderer::setLightVector(int32 angleX, int32 angleY, int32 angleZ) {
-	// TODO: RECHECK THIS
-	/*_cameraAngleX = angleX;
-	_cameraAngleY = angleY;
-	_cameraAngleZ = angleZ;*/
 	const int32 normalUnit = 64;
 	const IVec3 renderAngle(angleX, angleY, angleZ);
 	IMatrix3x3 matrix;
-	applyRotation(&matrix, &_baseMatrix, renderAngle);
-	_lightNorm = translateGroup(matrix, 0, 0, normalUnit - 5);
+	rotMatIndex2(&matrix, &_matrixWorld, renderAngle);
+	_normalLight = rot(matrix, 0, 0, normalUnit - 5);
 }
 
 static FORCEINLINE int16 clamp(int16 x, int16 a, int16 b) {
@@ -1820,7 +1792,7 @@ bool Renderer::renderAnimatedModel(ModelData *modelData, const BodyData &bodyDat
 			numNormals = bodyData.getBone(boneIdx).numNormals;
 
 			if (numNormals) {
-				const IMatrix3x3 matrix = *lightMatrix * _lightNorm;
+				const IMatrix3x3 matrix = *lightMatrix * _normalLight;
 
 				for (int32 i = 0; i < numNormals; ++i) { // for each normal
 					const BodyNormal &normalPtr = bodyData.getNormal(shadeIndex);
@@ -1854,7 +1826,7 @@ bool Renderer::renderAnimatedModel(ModelData *modelData, const BodyData &bodyDat
 	return renderModelElements(numOfPrimitives, bodyData, &renderCmds, modelData, modelRect);
 }
 
-bool Renderer::renderIsoModel(int32 x, int32 y, int32 z, int32 angleX, int32 angleY, int32 angleZ, const BodyData &bodyData, Common::Rect &modelRect) {
+bool Renderer::affObjetIso(int32 x, int32 y, int32 z, int32 angleX, int32 angleY, int32 angleZ, const BodyData &bodyData, Common::Rect &modelRect) {
 	IVec3 renderAngle;
 	renderAngle.x = angleX;
 	renderAngle.y = angleY;
@@ -1872,7 +1844,7 @@ bool Renderer::renderIsoModel(int32 x, int32 y, int32 z, int32 angleX, int32 ang
 		renderPos.y = y;
 		renderPos.z = z;
 	} else {
-		renderPos = getBaseRotationPosition(x, y, z) - _baseRotPos;
+		renderPos = longWorldRot(x, y, z) - _cameraRot;
 	}
 
 	if (!bodyData.isAnimated()) {
@@ -1913,19 +1885,19 @@ void Renderer::renderBehaviourModel(const Common::Rect &rect, int32 y, int32 ang
 		if (move.numOfStep == 0) {
 			_engine->_movements->initRealAngle(newAngle, newAngle - LBAAngles::ANGLE_90, LBAAngles::ANGLE_17, &move);
 		}
-		renderIsoModel(0, y, 0, LBAAngles::ANGLE_0, newAngle, LBAAngles::ANGLE_0, bodyData, dummy);
+		affObjetIso(0, y, 0, LBAAngles::ANGLE_0, newAngle, LBAAngles::ANGLE_0, bodyData, dummy);
 	} else {
-		renderIsoModel(0, y, 0, LBAAngles::ANGLE_0, angle, LBAAngles::ANGLE_0, bodyData, dummy);
+		affObjetIso(0, y, 0, LBAAngles::ANGLE_0, angle, LBAAngles::ANGLE_0, bodyData, dummy);
 	}
 	_engine->_interface->resetClip();
 }
 
-void Renderer::renderInventoryItem(int32 x, int32 y, const BodyData &bodyData, int32 angle, int32 param) {
+void Renderer::draw3dObject(int32 x, int32 y, const BodyData &bodyData, int32 angle, int32 cameraZoom) {
 	setProjection(x, y, 128, 200, 200);
-	setCameraAngle(0, 0, 0, 60, 0, 0, param);
+	setFollowCamera(0, 0, 0, 60, 0, 0, cameraZoom);
 
 	Common::Rect dummy;
-	renderIsoModel(0, 0, 0, LBAAngles::ANGLE_0, angle, LBAAngles::ANGLE_0, bodyData, dummy);
+	affObjetIso(0, 0, 0, LBAAngles::ANGLE_0, angle, LBAAngles::ANGLE_0, bodyData, dummy);
 }
 
 void Renderer::fillHolomapTriangle(int16 *pDest, int32 x0, int32 y0, int32 x1, int32 y1) {
diff --git a/engines/twine/renderer/renderer.h b/engines/twine/renderer/renderer.h
index 79756fc7fef..69dc1974812 100644
--- a/engines/twine/renderer/renderer.h
+++ b/engines/twine/renderer/renderer.h
@@ -154,28 +154,28 @@ private:
 	bool renderAnimatedModel(ModelData *modelData, const BodyData &bodyData, RenderCommand *renderCmds, const IVec3 &angleVec, const IVec3 &renderPos, Common::Rect &modelRect);
 	bool computeSphere(int32 x, int32 y, int32 radius);
 	bool renderModelElements(int32 numOfPrimitives, const BodyData &bodyData, RenderCommand **renderCmds, ModelData *modelData, Common::Rect &modelRect);
-	IVec3 getCameraAnglePositions(int32 x, int32 y, int32 z);
+	IVec3 longInverseRot(int32 x, int32 y, int32 z);
 	inline IVec3 getCameraAnglePositions(const IVec3 &vec) {
-		return getCameraAnglePositions(vec.x, vec.y, vec.z);
+		return longInverseRot(vec.x, vec.y, vec.z);
 	}
-	void applyRotation(IMatrix3x3 *targetMatrix, const IMatrix3x3 *currentMatrix, const IVec3 &angleVec);
+	void rotMatIndex2(IMatrix3x3 *targetMatrix, const IMatrix3x3 *currentMatrix, const IVec3 &angleVec);
 	void applyPointsRotation(const Common::Array<BodyVertex>& vertices, int32 firstPoint, int32 numPoints, I16Vec3 *destPoints, const IMatrix3x3 *rotationMatrix, const IVec3 &destPos);
 	void processRotatedElement(IMatrix3x3 *targetMatrix, const Common::Array<BodyVertex>& vertices, int32 rotX, int32 rotY, int32 rotZ, const BodyBone &bone, ModelData *modelData);
 	void applyPointsTranslation(const Common::Array<BodyVertex>& vertices, int32 firstPoint, int32 numPoints, I16Vec3 *destPoints, const IMatrix3x3 *translationMatrix, const IVec3 &angleVec, const IVec3 &destPos);
 	void processTranslatedElement(IMatrix3x3 *targetMatrix, const Common::Array<BodyVertex>& vertices, int32 rotX, int32 rotY, int32 rotZ, const BodyBone &bone, ModelData *modelData);
-	IVec3 translateGroup(const IMatrix3x3 &matrix, int32 x, int32 y, int32 z);
+	IVec3 rot(const IMatrix3x3 &matrix, int32 x, int32 y, int32 z);
 
-	IVec3 _baseTransPos;
+	IVec3 _cameraPos;
 	IVec3 _projectionCenter{320, 200, 0};
 
 	int32 _kFactor = 128;
 	int32 _lFactorX = 1024;
 	int32 _lFactorY = 840;
 
-	IMatrix3x3 _baseMatrix;
+	IMatrix3x3 _matrixWorld;
 	IMatrix3x3 _matricesTable[30 + 1];
-	IVec3 _lightNorm;
-	IVec3 _baseRotPos;
+	IVec3 _normalLight; // NormalXLight
+	IVec3 _cameraRot;
 
 	RenderCommand _renderCmds[1000];
 	/**
@@ -215,7 +215,7 @@ private:
 	uint8 *prepareSpheres(const Common::Array<BodySphere>& spheres, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData);
 	uint8 *prepareLines(const Common::Array<BodyLine>& lines, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData);
 
-	void baseMatrixTranspose();
+	void flipMatrix();
 
 	void renderHolomapPolygons(int32 top, int32 bottom, uint8 *holomapImage, uint32 holomapImageSize);
 	void fillHolomapTriangle(int16 *pDest, int32 x1, int32 y1, int32 x2, int32 y2);
@@ -238,10 +238,10 @@ public:
 	IVec3 getHolomapRotation(const int32 angleX, const int32 angleY, const int32 angleZ) const;
 
 	void setLightVector(int32 angleX, int32 angleY, int32 angleZ);
-	IVec3 getBaseRotationPosition(int32 x, int32 y, int32 z);
+	IVec3 longWorldRot(int32 x, int32 y, int32 z);
 
-	inline IVec3 getBaseRotationPosition(const IVec3& vec) {
-		return getBaseRotationPosition(vec.x, vec.y, vec.z);
+	inline IVec3 worldRotatePoint(const IVec3& vec) {
+		return longWorldRot(vec.x, vec.y, vec.z);
 	}
 
 	void fillVertices(int vtop, int32 vsize, uint8 renderType, uint16 color);
@@ -253,22 +253,22 @@ public:
 
 	IVec3 &projectPositionOnScreen(int32 cX, int32 cY, int32 cZ);
 
-	void setCameraAngle(int32 transPosX, int32 transPosY, int32 transPosZ, int32 rotPosX, int32 rotPosY, int32 rotPosZ, int32 param6);
-	IVec3 updateCameraAnglePositions(int zShift = 0);
-	void setBaseTranslation(int32 x, int32 y, int32 z);
-	IVec3 setAngleCamera(int32 x, int32 y, int32 z, bool transpose = false);
+	void setFollowCamera(int32 transPosX, int32 transPosY, int32 transPosZ, int32 cameraAlpha, int32 cameraBeta, int32 cameraGamma, int32 cameraZoom);
+	void setPosCamera(int32 x, int32 y, int32 z);
+	IVec3 setAngleCamera(int32 x, int32 y, int32 z);
+	IVec3 setInverseAngleCamera(int32 x, int32 y, int32 z);
 
-	inline IVec3 setBaseRotation(const IVec3 &rot, bool transpose = false) {
-		return setAngleCamera(rot.x, rot.y, rot.z, transpose);
+	inline IVec3 setBaseRotation(const IVec3 &rot) {
+		return setAngleCamera(rot.x, rot.y, rot.z);
 	}
 
 	void setProjection(int32 x, int32 y, int32 depthOffset, int32 scaleX, int32 scaleY);
 	void setIsoProjection(int32 x, int32 y, int32 scale);
 
-	bool renderIsoModel(int32 x, int32 y, int32 z, int32 angleX, int32 angleY, int32 angleZ, const BodyData &bodyData, Common::Rect &modelRect);
+	bool affObjetIso(int32 x, int32 y, int32 z, int32 angleX, int32 angleY, int32 angleZ, const BodyData &bodyData, Common::Rect &modelRect);
 
 	inline bool renderIsoModel(const IVec3 &pos, int32 angleX, int32 angleY, int32 angleZ, const BodyData &bodyData, Common::Rect &modelRect) {
-		return renderIsoModel(pos.x, pos.y, pos.z, angleX, angleY, angleZ, bodyData, modelRect);
+		return affObjetIso(pos.x, pos.y, pos.z, angleX, angleY, angleZ, bodyData, modelRect);
 	}
 
 	/**
@@ -280,15 +280,18 @@ public:
 	 */
 	void renderBehaviourModel(const Common::Rect &rect, int32 y, int32 angle, const BodyData &bodyData, ActorMoveStruct &move);
 
-	void renderInventoryItem(int32 x, int32 y, const BodyData &bodyData, int32 angle, int32 param);
+	/**
+	 * @brief Render an inventory item
+	 */
+	void draw3dObject(int32 x, int32 y, const BodyData &bodyData, int32 angle, int32 cameraZoom);
 
 	void renderHolomapVertices(const ComputedVertex vertexCoordinates[3], const ComputedVertex textureCoordinates[3], uint8 *holomapImage, uint32 holomapImageSize);
 };
 
 inline void Renderer::setBaseRotationPos(int32 x, int32 y, int32 z) {
-	_baseRotPos.x = x;
-	_baseRotPos.y = y;
-	_baseRotPos.z = z;
+	_cameraRot.x = x;
+	_cameraRot.y = y;
+	_cameraRot.z = z;
 }
 
 } // namespace TwinE
diff --git a/engines/twine/scene/gamestate.cpp b/engines/twine/scene/gamestate.cpp
index 4cfbd9612f4..ca796e6c262 100644
--- a/engines/twine/scene/gamestate.cpp
+++ b/engines/twine/scene/gamestate.cpp
@@ -55,9 +55,9 @@ GameState::GameState(TwinEEngine *engine) : _engine(engine) {
 	Common::fill(&_gameChoices[0], &_gameChoices[10], TextId::kNone);
 }
 
-void GameState::initEngineProjections() {
-	_engine->_renderer->setIsoProjection(_engine->width() / 2 - 9, _engine->height() / 2, 512);
-	_engine->_renderer->setBaseTranslation(0, 0, 0);
+void GameState::init3DGame() {
+	_engine->_renderer->setIsoProjection(_engine->width() / 2 - 8 - 1, _engine->height() / 2, SIZE_BRICK_XZ);
+	_engine->_renderer->setPosCamera(0, 0, 0);
 	_engine->_renderer->setAngleCamera(LBAAngles::ANGLE_0, LBAAngles::ANGLE_0, LBAAngles::ANGLE_0);
 	_engine->_renderer->setLightVector(_engine->_scene->_alphaLight, _engine->_scene->_betaLight, LBAAngles::ANGLE_0);
 }
@@ -106,7 +106,7 @@ void GameState::initEngineVars() {
 
 	_engine->_scene->_alphaLight = LBAAngles::ANGLE_315;
 	_engine->_scene->_betaLight = LBAAngles::ANGLE_334;
-	initEngineProjections();
+	init3DGame();
 	initGameStateVars();
 	initHeroVars();
 
@@ -381,12 +381,12 @@ void GameState::doFoundObj(InventoryItems item) {
 
 		itemAngle += LBAAngles::ANGLE_2;
 
-		_engine->_renderer->renderInventoryItem(_engine->_renderer->_projPos.x, _engine->_renderer->_projPos.y, _engine->_resources->_inventoryTable[item], itemAngle, 10000);
+		_engine->_renderer->draw3dObject(_engine->_renderer->_projPos.x, _engine->_renderer->_projPos.y, _engine->_resources->_inventoryTable[item], itemAngle, 10000);
 
 		_engine->_menu->drawRectBorders(boxRect);
 		_engine->_redraw->addRedrawArea(boxRect);
 		_engine->_interface->resetClip();
-		initEngineProjections();
+		init3DGame();
 
 		if (_engine->_animations->setModelAnimation(currentAnimState, currentAnimData, bodyData, &_engine->_scene->_sceneHero->_animTimerData)) {
 			currentAnimState++; // keyframe
@@ -438,7 +438,7 @@ void GameState::doFoundObj(InventoryItems item) {
 		}
 	}
 
-	initEngineProjections();
+	init3DGame();
 	_engine->_text->initSceneTextBank();
 	_engine->_text->stopVox(_engine->_text->_currDialTextEntry);
 
@@ -502,6 +502,7 @@ void GameState::processGameoverAnimation() {
 	const Common::Rect &rect = _engine->centerOnScreen(_engine->width() / 2, _engine->height() / 2);
 	_engine->_interface->setClip(rect);
 
+	int32 zoom = 50000;
 	Common::Rect dummy;
 	while (!_engine->_input->toggleAbortAction() && (_engine->_lbaTime - startLbaTime) <= _engine->toSeconds(10)) {
 		FrameMarker frame(_engine, 66);
@@ -510,26 +511,26 @@ void GameState::processGameoverAnimation() {
 			return;
 		}
 
-		const int32 zoom = _engine->_collision->clampedLerp(40000, 3200, _engine->toSeconds(10), _engine->_lbaTime - startLbaTime);
+		zoom = _engine->_collision->clampedLerp(40000, 3200, _engine->toSeconds(10), _engine->_lbaTime - startLbaTime);
 		const int32 angle = _engine->_screens->lerp(1, LBAAngles::ANGLE_360, _engine->toSeconds(2), (_engine->_lbaTime - startLbaTime) % _engine->toSeconds(2));
 
 		_engine->blitWorkToFront(rect);
-		_engine->_renderer->setCameraAngle(0, 0, 0, 0, -angle, 0, zoom);
-		_engine->_renderer->renderIsoModel(0, 0, 0, LBAAngles::ANGLE_0, LBAAngles::ANGLE_0, LBAAngles::ANGLE_0, gameOverPtr, dummy);
+		_engine->_renderer->setFollowCamera(0, 0, 0, 0, -angle, 0, zoom);
+		_engine->_renderer->affObjetIso(0, 0, 0, LBAAngles::ANGLE_0, LBAAngles::ANGLE_0, LBAAngles::ANGLE_0, gameOverPtr, dummy);
 
 		_engine->_lbaTime++;
 	}
 
 	_engine->_sound->playSample(Samples::Explode);
 	_engine->blitWorkToFront(rect);
-	_engine->_renderer->setCameraAngle(0, 0, 0, 0, 0, 0, 3200);
-	_engine->_renderer->renderIsoModel(0, 0, 0, LBAAngles::ANGLE_0, LBAAngles::ANGLE_0, LBAAngles::ANGLE_0, gameOverPtr, dummy);
+	_engine->_renderer->setFollowCamera(0, 0, 0, 0, 0, 0, zoom);
+	_engine->_renderer->affObjetIso(0, 0, 0, LBAAngles::ANGLE_0, LBAAngles::ANGLE_0, LBAAngles::ANGLE_0, gameOverPtr, dummy);
 
 	_engine->delaySkip(2000);
 
 	_engine->_interface->resetClip();
 	_engine->restoreFrontBuffer();
-	initEngineProjections();
+	init3DGame();
 
 	_engine->_lbaTime = tmpLbaTime;
 }
diff --git a/engines/twine/scene/gamestate.h b/engines/twine/scene/gamestate.h
index a0cd63a64f0..95bb78c4d0f 100644
--- a/engines/twine/scene/gamestate.h
+++ b/engines/twine/scene/gamestate.h
@@ -188,7 +188,7 @@ public:
 	void initEngineVars();
 
 	/** Initialize engine 3D projections */
-	void initEngineProjections();
+	void init3DGame();
 
 	void doFoundObj(InventoryItems item);
 
diff --git a/engines/twine/script/script_life.cpp b/engines/twine/script/script_life.cpp
index 5d989b244c0..762602f7562 100644
--- a/engines/twine/script/script_life.cpp
+++ b/engines/twine/script/script_life.cpp
@@ -2024,7 +2024,7 @@ int32 ScriptLife::lPLAY_CD_TRACK(TwinEEngine *engine, LifeScriptContext &ctx) {
  */
 int32 ScriptLife::lPROJ_ISO(TwinEEngine *engine, LifeScriptContext &ctx) {
 	debugC(3, kDebugLevels::kDebugScripts, "LIFE::PROJ_ISO()");
-	engine->_gameState->initEngineProjections();
+	engine->_gameState->init3DGame();
 	return 0;
 }
 
@@ -2039,7 +2039,7 @@ int32 ScriptLife::lPROJ_3D(TwinEEngine *engine, LifeScriptContext &ctx) {
 	engine->_scene->_enableGridTileRendering = false;
 
 	engine->_renderer->setProjection(engine->width() / 2, engine->height() / 2, 128, 1024, 1024);
-	engine->_renderer->setCameraAngle(0, 1500, 0, 25, -128, 0, 13000);
+	engine->_renderer->setFollowCamera(0, 1500, 0, 25, -128, 0, 13000);
 	engine->_renderer->setLightVector(LBAAngles::ANGLE_315, LBAAngles::ANGLE_334, LBAAngles::ANGLE_0);
 
 	engine->_text->initDial(TextBankId::Credits);
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index a6ba7d3b1c0..571f4cd9020 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -684,7 +684,7 @@ void TwinEEngine::processInventoryAction() {
 
 	switch (_loopInventoryItem) {
 	case kiHolomap:
-		_holomap->processHolomap();
+		_holomap->holoMap();
 		_screens->_fadePalette = true;
 		break;
 	case kiMagicBall:
@@ -898,7 +898,7 @@ bool TwinEEngine::runGameEngine() { // mainLoopInteration
 
 		// Draw holomap
 		if (_input->toggleActionIfActive(TwinEActionType::OpenHolomap) && _gameState->hasItem(InventoryItems::kiHolomap) && !_gameState->inventoryDisabled()) {
-			_holomap->processHolomap();
+			_holomap->holoMap();
 			_screens->_fadePalette = true;
 			_redraw->redrawEngineActions(true);
 		}


Commit: 4e0a29d61d857abc5019281756794a9ce6eafa84
    https://github.com/scummvm/scummvm/commit/4e0a29d61d857abc5019281756794a9ce6eafa84
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2023-01-17T19:11:35+01:00

Commit Message:
TWINE: renamed stuff to match original source

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


diff --git a/engines/twine/holomap.cpp b/engines/twine/holomap.cpp
index e94698a3384..8fc6f76aaa1 100644
--- a/engines/twine/holomap.cpp
+++ b/engines/twine/holomap.cpp
@@ -293,7 +293,7 @@ void Holomap::drawHoloObj(const IVec3 &angle, int32 x, int32 y) {
 	const IVec3 &destPos = _engine->_renderer->longWorldRot(0, 0, 1000);
 	_engine->_renderer->setPosCamera(0, 0, 0);
 	_engine->_renderer->setBaseRotation(angle);
-	_engine->_renderer->setBaseRotationPos(0, 0, distance(zDistanceTrajectory));
+	_engine->_renderer->setCameraRotation(0, 0, distance(zDistanceTrajectory));
 	_engine->_interface->resetClip();
 	Common::Rect dirtyRect;
 	_engine->_renderer->renderIsoModel(destPos, x, y, LBAAngles::ANGLE_0, _engine->_resources->_holomapPointModelPtr, dirtyRect);
@@ -456,13 +456,16 @@ void Holomap::drawListPos(int xRot, int yRot, int zRot, bool lower) {
 			continue;
 		}
 		const Location &loc = _locations[locationIdx];
-		_engine->_renderer->setAngleCamera(loc.angleX, loc.angleY, 0);
-		const IVec3 &destPos = _engine->_renderer->longWorldRot(0, 0, loc.size + 1000);
-		const IVec3 &destPos2 = _engine->_renderer->longWorldRot(0, 0, 1500);
+		const IVec3 &cameraRot = _engine->_renderer->setAngleCamera(loc.angleX, loc.angleY, 0);
+		IVec3 m = _engine->_renderer->worldRotatePoint(IVec3(0, 0, 1000 + loc.size));
+		m.x = cameraRot.x;
+		const IVec3 &m1 = _engine->_renderer->worldRotatePoint(IVec3(0, 0, 1500));
 		_engine->_renderer->setInverseAngleCamera(xRot, yRot, zRot);
-		_engine->_renderer->setBaseRotationPos(0, 0, distance(ZOOM_BIG_HOLO));
-		const IVec3 &destPos3 = _engine->_renderer->worldRotatePoint(destPos);
-		const IVec3 &destPos4 = _engine->_renderer->worldRotatePoint(destPos2);
+		_engine->_renderer->setCameraRotation(0, 0, distance(ZOOM_BIG_HOLO));
+
+		const IVec3 &destPos3 = _engine->_renderer->worldRotatePoint(m);
+		const IVec3 &destPos4 = _engine->_renderer->worldRotatePoint(m1);
+
 		bool visible;
 		if (lower) {
 			visible = destPos3.z <= destPos4.z;
@@ -480,9 +483,9 @@ void Holomap::drawListPos(int xRot, int yRot, int zRot, bool lower) {
 		drawList.posValue = destPos3.z;
 		drawList.actorIdx = locationIdx;
 		drawList.type = flags;
-		drawList.x = destPos.x;
-		drawList.y = destPos.y;
-		drawList.z = destPos.z;
+		drawList.x = m.x;
+		drawList.y = m.y;
+		drawList.z = m.z;
 		++n;
 	}
 	_engine->_redraw->sortDrawingList(drawListArray, n);
@@ -618,7 +621,7 @@ void Holomap::holoMap() {
 			_engine->_renderer->setLightVector(xRot, yRot, 0);
 			drawListPos(xRot, yRot, 0, false);
 			_engine->_renderer->setInverseAngleCamera(xRot, yRot, 0);
-			_engine->_renderer->setBaseRotationPos(0, 0, distance(ZOOM_BIG_HOLO));
+			_engine->_renderer->setCameraRotation(0, 0, distance(ZOOM_BIG_HOLO));
 			drawHoloMap(holomapImagePtr, holomapImageSize);
 			drawListPos(xRot, yRot, 0, true);
 			drawHolomapText(_engine->width() / 2, 25, "HoloMap");
diff --git a/engines/twine/renderer/renderer.h b/engines/twine/renderer/renderer.h
index 69dc1974812..0e0e1a3c5a6 100644
--- a/engines/twine/renderer/renderer.h
+++ b/engines/twine/renderer/renderer.h
@@ -234,7 +234,7 @@ public:
 
 	IVec3 _projPos;
 
-	void setBaseRotationPos(int32 x, int32 y, int32 z);
+	void setCameraRotation(int32 x, int32 y, int32 z);
 	IVec3 getHolomapRotation(const int32 angleX, const int32 angleY, const int32 angleZ) const;
 
 	void setLightVector(int32 angleX, int32 angleY, int32 angleZ);
@@ -288,7 +288,7 @@ public:
 	void renderHolomapVertices(const ComputedVertex vertexCoordinates[3], const ComputedVertex textureCoordinates[3], uint8 *holomapImage, uint32 holomapImageSize);
 };
 
-inline void Renderer::setBaseRotationPos(int32 x, int32 y, int32 z) {
+inline void Renderer::setCameraRotation(int32 x, int32 y, int32 z) {
 	_cameraRot.x = x;
 	_cameraRot.y = y;
 	_cameraRot.z = z;


Commit: ae4db01bc112a5f7c9151954e8751ba9a643c95c
    https://github.com/scummvm/scummvm/commit/ae4db01bc112a5f7c9151954e8751ba9a643c95c
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2023-01-17T19:12:55+01:00

Commit Message:
TWINE: fixed top and bottom handling of polygon and sphere rendering

this fixes invalid memory access

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


diff --git a/engines/twine/renderer/renderer.cpp b/engines/twine/renderer/renderer.cpp
index 0c55fd1b0d3..dd9a1b933e5 100644
--- a/engines/twine/renderer/renderer.cpp
+++ b/engines/twine/renderer/renderer.cpp
@@ -49,6 +49,10 @@ void Renderer::init(int32 w, int32 h) {
 	_polyTabSize = _engine->height() * 6;
 	_polyTab = (int16 *)malloc(_polyTabSize * sizeof(int16));
 	_colorProgressionBuffer = (int16 *)malloc(_polyTabSize * sizeof(int16));
+
+	memset(_polyTab, 0, sizeof(_polyTabSize * sizeof(int16)));
+	memset(_colorProgressionBuffer, 0, sizeof(_polyTabSize * sizeof(int16)));
+
 	_tabVerticG = &_polyTab[_engine->height() * 0];
 	_tabVerticD = &_polyTab[_engine->height() * 1];
 	_tabx0 = &_polyTab[_engine->height() * 2];
@@ -600,7 +604,7 @@ int16 Renderer::bottomClip(int16 polyRenderType, ComputedVertex** offTabPoly, in
 	return newNbPoints;
 }
 
-int32 Renderer::computePolyMinMax(int16 polyRenderType, ComputedVertex **offTabPoly, int32 numVertices) {
+int32 Renderer::computePolyMinMax(int16 polyRenderType, ComputedVertex **offTabPoly, int32 numVertices, int &vtop, int &vbottom) {
 	const Common::Rect &clip = _engine->_interface->_clip;
 	if (clip.isEmpty()) {
 		return numVertices;
@@ -693,10 +697,13 @@ int32 Renderer::computePolyMinMax(int16 polyRenderType, ComputedVertex **offTabP
 		}
 	}
 
+	vtop = minsy;
+	vbottom = maxsy;
+
 	return clippedNumVertices;
 }
 
-bool Renderer::computePoly(int16 polyRenderType, const ComputedVertex *vertices, int32 numVertices) {
+bool Renderer::computePoly(int16 polyRenderType, const ComputedVertex *vertices, int32 numVertices, int &vtop, int &vbottom) {
 	const int16 *polyTabBegin = _polyTab;
 	const int16 *polyTabEnd = &_polyTab[_polyTabSize - 1];
 	const int16 *colProgressBufStart = _colorProgressionBuffer;
@@ -710,7 +717,7 @@ bool Renderer::computePoly(int16 polyRenderType, const ComputedVertex *vertices,
 
 	ComputedVertex *offTabPoly[] = {_clippedPolygonVertices1, _clippedPolygonVertices2};
 
-	numVertices = computePolyMinMax(polyRenderType, offTabPoly, numVertices);
+	numVertices = computePolyMinMax(polyRenderType, offTabPoly, numVertices, vtop, vbottom);
 	if (numVertices == 0) {
 		return false;
 	}
@@ -1282,7 +1289,7 @@ void Renderer::svgaPolyTriche(int vtop, int32 vsize, uint16 color) const {
 }
 
 void Renderer::renderPolygons(const CmdRenderPolygon &polygon, ComputedVertex *vertices, int vtop, int vbottom) {
-	if (computePoly(polygon.renderType, vertices, polygon.numVertices)) {
+	if (computePoly(polygon.renderType, vertices, polygon.numVertices, vtop, vbottom)) {
 		const int32 vsize = vbottom - vtop + 1;
 		fillVertices(vtop, vsize, polygon.renderType, polygon.colorIndex);
 	}
@@ -1337,7 +1344,7 @@ void Renderer::fillVertices(int vtop, int32 vsize, uint8 renderType, uint16 colo
 	}
 }
 
-bool Renderer::computeSphere(int32 x, int32 y, int32 radius) {
+bool Renderer::computeSphere(int32 x, int32 y, int32 radius, int &vtop, int &vbottom) {
 	if (radius <= 0) {
 		return false;
 	}
@@ -1427,6 +1434,9 @@ bool Renderer::computeSphere(int32 x, int32 y, int32 radius) {
 			++r;
 		}
 
+		vtop = top;
+		vbottom = bottom;
+
 		return true;
 	}
 
@@ -1633,8 +1643,10 @@ bool Renderer::renderModelElements(int32 numOfPrimitives, const BodyData &bodyDa
 
 			radius -= 3;
 
-			if (computeSphere(sphere->x, sphere->y, radius)) {
-				const int32 vsize = 2 * radius;
+			int vtop = -1;
+			int vbottom = -1;
+			if (computeSphere(sphere->x, sphere->y, radius, vtop, vbottom)) {
+				const int32 vsize = vbottom - vtop;
 				fillVertices(sphere->y - radius, vsize, sphere->polyRenderType, sphere->color);
 			}
 			break;
diff --git a/engines/twine/renderer/renderer.h b/engines/twine/renderer/renderer.h
index 0e0e1a3c5a6..e8304c464f6 100644
--- a/engines/twine/renderer/renderer.h
+++ b/engines/twine/renderer/renderer.h
@@ -152,7 +152,7 @@ private:
 	ModelData _modelData;
 
 	bool renderAnimatedModel(ModelData *modelData, const BodyData &bodyData, RenderCommand *renderCmds, const IVec3 &angleVec, const IVec3 &renderPos, Common::Rect &modelRect);
-	bool computeSphere(int32 x, int32 y, int32 radius);
+	bool computeSphere(int32 x, int32 y, int32 radius, int &vtop, int &vbottom);
 	bool renderModelElements(int32 numOfPrimitives, const BodyData &bodyData, RenderCommand **renderCmds, ModelData *modelData, Common::Rect &modelRect);
 	IVec3 longInverseRot(int32 x, int32 y, int32 z);
 	inline IVec3 getCameraAnglePositions(const IVec3 &vec) {
@@ -208,7 +208,7 @@ private:
 	void svgaPolyDith(int vtop, int32 vsize) const;
 	void svgaPolyMarbre(int vtop, int32 vsize, uint16 color) const;
 	void svgaPolyTriche(int vtop, int32 vsize, uint16 color) const;
-	bool computePoly(int16 polyRenderType, const ComputedVertex *vertices, int32 numVertices);
+	bool computePoly(int16 polyRenderType, const ComputedVertex *vertices, int32 numVertices, int &vtop, int &vbottom);
 
 	const RenderCommand *depthSortRenderCommands(int32 numOfPrimitives);
 	uint8 *preparePolygons(const Common::Array<BodyPolygon>& polygons, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData);
@@ -225,7 +225,7 @@ private:
 	int16 rightClip(int16 polyRenderType, ComputedVertex** offTabPoly, int32 numVertices);
 	int16 topClip(int16 polyRenderType, ComputedVertex** offTabPoly, int32 numVertices);
 	int16 bottomClip(int16 polyRenderType, ComputedVertex** offTabPoly, int32 numVertices);
-	int32 computePolyMinMax(int16 polyRenderType, ComputedVertex **offTabPoly, int32 numVertices);
+	int32 computePolyMinMax(int16 polyRenderType, ComputedVertex **offTabPoly, int32 numVertices, int &vtop, int &vbottom);
 public:
 	Renderer(TwinEEngine *engine);
 	~Renderer();




More information about the Scummvm-git-logs mailing list