[Scummvm-git-logs] scummvm master -> 889b4b6aeedd84772971599df9bc9098a7279e44

mgerhardy noreply at scummvm.org
Fri Jan 20 15:03:00 UTC 2023


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

Summary:
bfa8af9b94 TWINE: cleanup in return values
caa9321815 TWINE: use original line drawing algorithm
889b4b6aee TWINE: use the original render methods code


Commit: bfa8af9b94f6ebb05bf0e183136c7b1988fb96ab
    https://github.com/scummvm/scummvm/commit/bfa8af9b94f6ebb05bf0e183136c7b1988fb96ab
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2023-01-20T16:00:53+01:00

Commit Message:
TWINE: cleanup in return values

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 bdd6c5d81c1..c134f98517f 100644
--- a/engines/twine/renderer/renderer.cpp
+++ b/engines/twine/renderer/renderer.cpp
@@ -1575,7 +1575,8 @@ const Renderer::RenderCommand *Renderer::depthSortRenderCommands(int32 numOfPrim
 	return _renderCmds;
 }
 
-bool Renderer::renderObjectIso(int32 numOfPrimitives, const BodyData &bodyData, RenderCommand **renderCmds, ModelData *modelData, Common::Rect &modelRect) {
+bool Renderer::renderObjectIso(const BodyData &bodyData, RenderCommand **renderCmds, ModelData *modelData, Common::Rect &modelRect) {
+	int32 numOfPrimitives = 0;
 	uint8 *renderBufferPtr = _renderCoordinatesBuffer;
 	renderBufferPtr = preparePolygons(bodyData.getPolygons(), numOfPrimitives, renderCmds, renderBufferPtr, modelData);
 	renderBufferPtr = prepareLines(bodyData.getLines(), numOfPrimitives, renderCmds, renderBufferPtr, modelData);
@@ -1660,7 +1661,7 @@ bool Renderer::renderObjectIso(int32 numOfPrimitives, const BodyData &bodyData,
 	return true;
 }
 
-int32 Renderer::animModel(ModelData *modelData, const BodyData &bodyData, RenderCommand *renderCmds, const IVec3 &angleVec, const IVec3 &renderPos, Common::Rect &modelRect) {
+void Renderer::animModel(ModelData *modelData, const BodyData &bodyData, RenderCommand *renderCmds, const IVec3 &angleVec, const IVec3 &renderPos, Common::Rect &modelRect) {
 	const int32 numVertices = bodyData.getNumVertices();
 	const int32 numBones = bodyData.getNumBones();
 
@@ -1834,7 +1835,6 @@ int32 Renderer::animModel(ModelData *modelData, const BodyData &bodyData, Render
 			++lightMatrix;
 		} while (--numOfPrimitives);
 	}
-	return numOfPrimitives;
 }
 
 bool Renderer::affObjetIso(int32 x, int32 y, int32 z, int32 angleX, int32 angleY, int32 angleZ, const BodyData &bodyData, Common::Rect &modelRect) {
@@ -1870,8 +1870,8 @@ bool Renderer::affObjetIso(int32 x, int32 y, int32 z, int32 angleX, int32 angleY
 	}
 	// restart at the beginning of the renderTable
 	RenderCommand *renderCmds = _renderCmds;
-	const int32 numOfPrimitives = animModel(&_modelData, bodyData, renderCmds, renderAngle, renderPos, modelRect);
-	if (!renderObjectIso(numOfPrimitives, bodyData, &renderCmds, &_modelData, modelRect)) {
+	animModel(&_modelData, bodyData, renderCmds, renderAngle, renderPos, modelRect);
+	if (!renderObjectIso(bodyData, &renderCmds, &_modelData, modelRect)) {
 		modelRect.right = -1;
 		modelRect.bottom = -1;
 		modelRect.left = -1;
diff --git a/engines/twine/renderer/renderer.h b/engines/twine/renderer/renderer.h
index 89f8ea32e7e..57f420e7703 100644
--- a/engines/twine/renderer/renderer.h
+++ b/engines/twine/renderer/renderer.h
@@ -151,9 +151,9 @@ private:
 
 	ModelData _modelData;
 
-	int32 animModel(ModelData *modelData, const BodyData &bodyData, RenderCommand *renderCmds, const IVec3 &angleVec, const IVec3 &renderPos, Common::Rect &modelRect);
+	void animModel(ModelData *modelData, const BodyData &bodyData, RenderCommand *renderCmds, const IVec3 &angleVec, const IVec3 &renderPos, Common::Rect &modelRect);
 	bool computeSphere(int32 x, int32 y, int32 radius, int &vtop, int &vbottom);
-	bool renderObjectIso(int32 numOfPrimitives, const BodyData &bodyData, RenderCommand **renderCmds, ModelData *modelData, Common::Rect &modelRect); // RenderObjetIso
+	bool renderObjectIso(const BodyData &bodyData, RenderCommand **renderCmds, ModelData *modelData, Common::Rect &modelRect); // RenderObjetIso
 	IVec3 longInverseRot(int32 x, int32 y, int32 z);
 	inline IVec3 getCameraAnglePositions(const IVec3 &vec) {
 		return longInverseRot(vec.x, vec.y, vec.z);


Commit: caa932181570352d61a62a714469fc1bcecf503c
    https://github.com/scummvm/scummvm/commit/caa932181570352d61a62a714469fc1bcecf503c
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2023-01-20T16:00:53+01:00

Commit Message:
TWINE: use original line drawing algorithm

Changed paths:
    engines/twine/menu/interface.cpp
    engines/twine/menu/interface.h


diff --git a/engines/twine/menu/interface.cpp b/engines/twine/menu/interface.cpp
index a7a98bc05e0..f77ecdb40f5 100644
--- a/engines/twine/menu/interface.cpp
+++ b/engines/twine/menu/interface.cpp
@@ -28,114 +28,119 @@ namespace TwinE {
 
 Interface::Interface(TwinEEngine *engine) : _engine(engine) {}
 
-const int32 INSIDE = 0; // 0000
-const int32 LEFT = 1;   // 0001
-const int32 RIGHT = 2;  // 0010
-const int32 TOP = 4;    // 0100
-const int32 BOTTOM = 8; // 1000
-
-int32 Interface::checkClipping(int32 x, int32 y) const {
-	int32 code = INSIDE;
-	if (x < _clip.left) {
-		code |= LEFT;
-	} else if (x > _clip.right) {
-		code |= RIGHT;
+bool Interface::drawLine(int32 x0, int32 y0, int32 x1, int32 y1, uint8 color) {
+	// always from left to right
+	if (x0 > x1) {
+		SWAP(x0, x1);
+		SWAP(y0, y1);
 	}
-	if (y < _clip.top) {
-		code |= TOP;
-	} else if (y > _clip.bottom) {
-		code |= BOTTOM;
-	}
-	return code;
-}
 
-bool Interface::drawLine(int32 startWidth, int32 startHeight, int32 endWidth, int32 endHeight, uint8 lineColor) {
-	// draw line from left to right
-	if (startWidth > endWidth) {
-		SWAP(endWidth, startWidth);
-		SWAP(endHeight, startHeight);
-	}
+	const int32 cright = _clip.right;
+	const int32 cleft = _clip.left;
+	const int32 cbottom = _clip.bottom;
+	const int32 ctop = _clip.top;
+
+	uint16 clipFlags;
+	do {
+		if (x0 > cright || x1 < cleft) {
+			return false;
+		}
 
-	// Perform proper clipping (CohenSutherland algorithm)
-	int32 outcode0 = checkClipping(startWidth, startHeight);
-	int32 outcode1 = checkClipping(endWidth, endHeight);
+		int32 dx = x1 - x0;
+		int32 dy = y1 - y0;
 
-	while ((outcode0 | outcode1) != INSIDE) {
-		if ((outcode0 & outcode1) != INSIDE && outcode0 != INSIDE) {
-			return false; // Reject lines which are behind one clipping plane
+		clipFlags = 0;
+
+		if (x0 < cleft) {
+			clipFlags |= 0x100;
 		}
 
-		// At least one endpoint is outside the clip rectangle; pick it.
-		const int32 outcodeOut = outcode0 ? outcode0 : outcode1;
-
-		int32 x = 0;
-		int32 y = 0;
-		if (outcodeOut & TOP) { // point is above the clip rectangle
-			x = startWidth + (int)((endWidth - startWidth) * (float)(_clip.top - startHeight) / (float)(endHeight - startHeight));
-			y = _clip.top;
-		} else if (outcodeOut & BOTTOM) { // point is below the clip rectangle
-			x = startWidth + (int)((endWidth - startWidth) * (float)(_clip.bottom - startHeight) / (float)(endHeight - startHeight));
-			y = _clip.bottom;
-		} else if (outcodeOut & RIGHT) { // point is to the right of clip rectangle
-			y = startHeight + (int)((endHeight - startHeight) * (float)(_clip.right - startWidth) / (float)(endWidth - startWidth));
-			x = _clip.right;
-		} else if (outcodeOut & LEFT) { // point is to the left of clip rectangle
-			y = startHeight + (int)((endHeight - startHeight) * (float)(_clip.left - startWidth) / (float)(endWidth - startWidth));
-			x = _clip.left;
+		if (y0 < ctop) {
+			clipFlags |= 0x800;
+		} else if (y0 > cbottom) {
+			clipFlags |= 0x400;
 		}
 
-		// Clip the point
-		if (outcodeOut == outcode0) {
-			startWidth = x;
-			startHeight = y;
-			outcode0 = checkClipping(startWidth, startHeight);
-		} else {
-			endWidth = x;
-			endHeight = y;
-			outcode1 = checkClipping(endWidth, endHeight);
+		if (x1 > cright) {
+			clipFlags |= 0x2;
+		}
+
+		if (y1 < ctop) {
+			clipFlags |= 0x8;
+		} else if (y1 > cbottom) {
+			clipFlags |= 0x4;
 		}
-	}
 
-	int32 pitch = _engine->width();
-	endWidth -= startWidth;
-	endHeight -= startHeight;
-	if (endHeight < 0) {
-		pitch = -pitch;
-		endHeight = -endHeight;
+		if (clipFlags & (clipFlags >> 8)) {
+			return false;
+		}
+
+		if (clipFlags) {
+			if (clipFlags & 0x100) {
+				y0 += ((cleft - x0) * dy) / dx;
+				x0 = cleft;
+			} else if (clipFlags & 0x800) {
+				x0 += ((ctop - y0) * dx) / dy;
+				y0 = ctop;
+			} else if (clipFlags & 0x400) {
+				x0 += ((cbottom - y0) * dx) / dy;
+				y0 = cbottom;
+			} else if (clipFlags & 0x2) {
+				y1 = (((cright - x0) * dy) / dx) + y0;
+				x1 = cright;
+			} else if (clipFlags & 0x8) {
+				x1 = (((ctop - y0) * dx) / dy) + x0;
+				y1 = ctop;
+			} else if (clipFlags & 0x4) {
+				x1 = (((cbottom - y0) * dx) / dy) + x0;
+				y1 = cbottom;
+			}
+		}
+	} while (clipFlags);
+
+	int16 lineOffset = (int16)_engine->width();
+	x1 -= x0;
+	y1 -= y0;
+	if (y1 < 0) {
+		lineOffset = -lineOffset;
+		y1 = -y1;
 	}
 
-	uint8 *out = (uint8*)_engine->_frontVideoBuffer.getBasePtr(startWidth, startHeight);
-	_engine->_frontVideoBuffer.addDirtyRect(Common::Rect(startWidth, startHeight, startWidth + endWidth, startHeight + endHeight));
+	byte *out = (byte *)_engine->_frontVideoBuffer.getBasePtr(x0, y0);
+
+	if (x1 < y1) {
+		// vertical
+		SWAP(x1, y1);
+
+		int32 dy = x1 << 1;
+		y0 = x1;
+		y1 <<= 1;
+		x1++;
 
-	if (endWidth < endHeight) { // significant slope
-		SWAP(endWidth, endHeight);
-		const int16 var2 = endWidth << 1;
-		startHeight = endWidth;
-		endHeight <<= 1;
-		endWidth++;
 		do {
-			*out = lineColor;
-			startHeight -= endHeight;
-			if (startHeight > 0) {
-				out += pitch;
-			} else {
-				startHeight += var2;
-				out += pitch + 1;
+			*out = color;
+			y0 -= y1;
+			out += lineOffset;
+			if (y0 < 0) {
+				y0 += dy;
+				out++;
 			}
-		} while (--endWidth);
-	} else { // reduced slope
-		const int16 var2 = endWidth << 1;
-		startHeight = endWidth;
-		endHeight <<= 1;
-		endWidth++;
+		} while (--x1);
+	} else {
+		// horizontal
+		int32 dy = x1 << 1;
+		y0 = x1;
+		y1 <<= 1;
+		x1++;
+
 		do {
-			*out++ = lineColor;
-			startHeight -= endHeight;
-			if (startHeight < 0) {
-				startHeight += var2;
-				out += pitch;
+			*out++ = color;
+			y0 -= y1;
+			if (y0 < 0) {
+				y0 += dy;
+				out += lineOffset;
 			}
-		} while (--endWidth);
+		} while (--x1);
 	}
 	return true;
 }
diff --git a/engines/twine/menu/interface.h b/engines/twine/menu/interface.h
index 68e9a90b47f..748d4c8a3b7 100644
--- a/engines/twine/menu/interface.h
+++ b/engines/twine/menu/interface.h
@@ -36,7 +36,6 @@ class TwinEEngine;
 class Interface {
 private:
 	TwinEEngine *_engine;
-	int32 checkClipping(int32 x, int32 y) const;
 	Common::Rect _savedClip;
 
 public:


Commit: 889b4b6aeedd84772971599df9bc9098a7279e44
    https://github.com/scummvm/scummvm/commit/889b4b6aeedd84772971599df9bc9098a7279e44
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2023-01-20T16:02:22+01:00

Commit Message:
TWINE: use the original render methods code

fixed bug #14019 https://bugs.scummvm.org/ticket/14019

allocate single buffers to detect buffer overflows easier
removed radius modification
don't clamp vertices
use vtop and vbottom and converted them to int16

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 c134f98517f..0e5055f824a 100644
--- a/engines/twine/renderer/renderer.cpp
+++ b/engines/twine/renderer/renderer.cpp
@@ -41,24 +41,32 @@ Renderer::Renderer(TwinEEngine *engine) : _engine(engine) {
 }
 
 Renderer::~Renderer() {
-	free(_polyTab);
-	free(_colorProgressionBuffer);
+	free(_tabVerticG);
+	free(_tabVerticD);
+	free(_tabCoulG);
+	free(_tabCoulD);
+	free(_taby0);
+	free(_taby1);
 }
 
 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];
-	_tabx1 = &_polyTab[_engine->height() * 3];
-	_taby0 = &_polyTab[_engine->height() * 4];
-	_taby1 = &_polyTab[_engine->height() * 5];
+	size_t size = _engine->height() * sizeof(int16);
+
+	_tabVerticG = (int16 *)malloc(size);
+	memset(_tabVerticG, 0, size);
+	_tabVerticD = (int16 *)malloc(size);
+	memset(_tabVerticD, 0, size);
+	_tabCoulG = (int16 *)malloc(size);
+	memset(_tabCoulG, 0, size);
+	_tabCoulD = (int16 *)malloc(size);
+	memset(_tabCoulD, 0, size);
+	_taby0 = (int16 *)malloc(size);
+	memset(_taby0, 0, size);
+	_taby1 = (int16 *)malloc(size);
+	memset(_taby1, 0, size);
+
+	_tabx0 = _tabCoulG;
+	_tabx1 = _tabCoulD;
 }
 
 IVec3 &Renderer::projectPositionOnScreen(int32 cX, int32 cY, int32 cZ) { // ProjettePoint
@@ -704,12 +712,6 @@ int32 Renderer::computePolyMinMax(int16 polyRenderType, ComputedVertex **offTabP
 }
 
 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;
-	const int16 *colProgressBufEnd = &_colorProgressionBuffer[_polyTabSize - 1];
-	const int screenHeight = _engine->height();
-
 	assert(numVertices < ARRAYSIZE(_clippedPolygonVertices1));
 	for (int i = 0; i < numVertices; ++i) {
 		_clippedPolygonVertices1[i] = vertices[i];
@@ -722,103 +724,110 @@ bool Renderer::computePoly(int16 polyRenderType, const ComputedVertex *vertices,
 		return false;
 	}
 
-	const ComputedVertex *clippedVertices = offTabPoly[0];
-	uint8 vertexParam1 = clippedVertices[numVertices - 1].intensity;
-	int16 currentVertexX = clippedVertices[numVertices - 1].x;
-	int16 currentVertexY = clippedVertices[numVertices - 1].y;
+	ComputedVertex *pTabPoly = offTabPoly[0];
+	ComputedVertex *p0;
+	ComputedVertex *p1;
+	int16 *pVertic;
+	int16 *pCoul;
+	int32 incY;
+	int32 dx, dy, x, y, dc;
+	int32 step, reminder;
 
-	for (int32 nVertex = 0; nVertex < numVertices; nVertex++) {
-		const int16 oldVertexY = currentVertexY;
-		const int16 oldVertexX = currentVertexX;
-		const uint8 oldVertexParam = vertexParam1;
+	for (; numVertices > 0; --numVertices, pTabPoly++) {
+		pCoul = NULL;
+		p0 = pTabPoly;
+		p1 = p0 + 1;
 
-		vertexParam1 = clippedVertices[nVertex].intensity;
-		const uint8 vertexParam2 = vertexParam1;
-		currentVertexX = clippedVertices[nVertex].x;
-		currentVertexY = clippedVertices[nVertex].y;
+		dy = p1->y - p0->y;
+		if (dy == 0) {
+			// forget same Y points
+			continue;
+		} else if (dy > 0) {
+			// Y descend donc buffer gauche
+			if (p0->x <= p1->x) {
+				incY = 1;
+			} else {
+				p0 = p1;
+				p1 = pTabPoly;
+				incY = -1;
+			}
 
-		// drawLine(oldVertexX,oldVertexY,currentVertexX,currentVertexY,255);
+			pVertic = &_tabVerticG[p0->y];
 
-		if (currentVertexY == oldVertexY) {
-			continue;
-		}
+			if (polyRenderType >= POLYGONTYPE_GOURAUD) {
+				pCoul = &_tabCoulG[p0->y];
+			}
+		} else if (dy < 0) {
+			dy = -dy;
 
-		const int8 up = currentVertexY < oldVertexY;
-		int8 direction = up ? -1 : 1;
-
-		const int16 vsize = ABS(currentVertexY - oldVertexY);
-		const int16 hsize = ABS(currentVertexX - oldVertexX);
-
-		int16 cvalue;
-		int16 cdelta;
-		int16 ypos;
-		float xpos;
-		if (direction * oldVertexX > direction * currentVertexX) { // if we are going up right
-			xpos = currentVertexX;
-			ypos = currentVertexY;
-			cvalue = (vertexParam2 * 256) + ((oldVertexParam - vertexParam2) * 256) % vsize;
-			cdelta = ((oldVertexParam - vertexParam2) * 256) / vsize;
-			direction = -direction; // we will draw by going down the tab
-		} else {
-			xpos = oldVertexX;
-			ypos = oldVertexY;
-			cvalue = (oldVertexParam * 256) + ((vertexParam2 - oldVertexParam) * 256) % vsize;
-			cdelta = ((vertexParam2 - oldVertexParam) * 256) / vsize;
+			if (p0->x <= p1->x) {
+				p0 = p1;
+				p1 = pTabPoly;
+				incY = 1;
+			} else {
+				incY = -1;
+			}
+
+			pVertic = &_tabVerticD[p0->y];
+
+			if (polyRenderType >= POLYGONTYPE_GOURAUD) {
+				pCoul = &_tabCoulD[p0->y];
+			}
 		}
-		const int32 polyTabIndex = ypos + (up ? screenHeight : 0);
-		int16 *outPtr = &_polyTab[polyTabIndex]; // outPtr is the output ptr in the renderTab
 
-		float slope = (float)hsize / (float)vsize;
-		slope = up ? -slope : slope;
+		dx = (p1->x - p0->x) << 16;
 
-		for (int16 i = 0; i <= vsize; i++) {
-			if (outPtr >= polyTabBegin && outPtr <= polyTabEnd) {
-				*outPtr = xpos;
+		step = dx / dy;
+		reminder = ((dx % dy) >> 1) + 0x7FFF;
+
+		dx = step >> 16; // recup partie haute division (entier)
+		step &= 0xFFFF;  // conserve partie basse (mantisse)
+		x = p0->x;
+
+		for (y = dy; y >= 0; --y) {
+			*pVertic = (int16)x;
+			pVertic += incY;
+			x += dx;
+			reminder += step;
+			if (reminder & 0xFFFF0000) {
+				x += reminder >> 16;
+				reminder &= 0xFFFF;
 			}
-			outPtr += direction;
-			xpos += slope;
 		}
 
-		if (polyRenderType >= POLYGONTYPE_GOURAUD) { // we must compute the color progression
-			int16 *outPtr2 = &_colorProgressionBuffer[polyTabIndex];
+		if (pCoul) {
+			dc = (p1->intensity - p0->intensity) << 8;
+			step = dc / dy;
+			reminder = ((((dc % dy) >> 1) + 0x7F) & 0xFF) | (p0->intensity << 8);
 
-			for (int16 i = 0; i <= vsize; i++) {
-				if (outPtr2 >= colProgressBufStart && outPtr2 <= colProgressBufEnd) {
-					*outPtr2 = cvalue;
-				}
-				outPtr2 += direction;
-				cvalue += cdelta;
+			for (y = dy; y >= 0; --y) {
+				*pCoul = (int16)reminder;
+				pCoul += incY;
+				reminder += step;
 			}
 		}
 	}
+
 	return true;
 }
 
-void Renderer::svgaPolyCopper(int vtop, int32 vsize, uint16 color) const {
-	uint8 *out = (uint8 *)_engine->_frontVideoBuffer.getBasePtr(0, vtop);
-	const int16 *ptr1 = &_polyTab[vtop];
+void Renderer::svgaPolyCopper(int16 vtop, int16 Ymax, uint16 color) const {
 	const int screenWidth = _engine->width();
-	const int screenHeight = _engine->height();
-
-	int32 renderLoop = vsize;
-	if (vtop < 0) {
-		out += screenWidth * ABS(vtop);
-		renderLoop -= ABS(vtop);
-	}
-	if (renderLoop > screenHeight) {
-		renderLoop = screenHeight;
-	}
+	int16 xMin, xMax;
+	int16 y = vtop;
+	byte *pDestLine = (uint8 *)_engine->_frontVideoBuffer.getBasePtr(0, y);
+	byte *pDest;
+	int16 *pVerticG = &_tabVerticG[y];
+	int16 *pVerticD = &_tabVerticD[y];
 	int32 sens = 1;
 
-	for (int32 currentLine = 0; currentLine < renderLoop; ++currentLine) {
-		int16 xMin = ptr1[0];
-		int16 xMax = ptr1[screenHeight];
-
-		ptr1++;
-		uint8 *pDest = out + xMin;
+	for (; y <= Ymax; y++) {
+		xMin = *pVerticG++;
+		xMax = *pVerticD++;
+		pDest = pDestLine + xMin;
 
 		for (; xMin <= xMax; xMin++) {
-			*pDest++ = (uint8)color;
+			*pDest++ = (byte)color;
 		}
 
 		color += sens;
@@ -828,34 +837,29 @@ void Renderer::svgaPolyCopper(int vtop, int32 vsize, uint16 color) const {
 				color += sens;
 			}
 		}
-		out += screenWidth;
+
+		pDestLine += screenWidth;
 	}
 }
 
-void Renderer::svgaPolyBopper(int vtop, int32 vsize, uint16 color) const {
-	uint8 *out = (uint8 *)_engine->_frontVideoBuffer.getBasePtr(0, vtop);
-	const int16 *ptr1 = &_polyTab[vtop];
+void Renderer::svgaPolyBopper(int16 vtop, int16 Ymax, uint16 color) const {
 	const int screenWidth = _engine->width();
-	const int screenHeight = _engine->height();
-	int32 renderLoop = vsize;
-	if (vtop < 0) {
-		out += screenWidth * ABS(vtop);
-		renderLoop -= ABS(vtop);
-	}
-	if (renderLoop > screenHeight) {
-		renderLoop = screenHeight;
-	}
+	int16 xMin, xMax;
+	int16 y = vtop;
+	byte *pDestLine = (uint8 *)_engine->_frontVideoBuffer.getBasePtr(0, y);
+	byte *pDest;
+	int16 *pVerticG = &_tabVerticG[y];
+	int16 *pVerticD = &_tabVerticD[y];
 	int32 sens = 1;
 	int32 line = 2;
-	for (int32 currentLine = 0; currentLine < renderLoop; ++currentLine) {
-		int16 xMin = ptr1[0];
-		int16 xMax = ptr1[screenHeight];
-		ptr1++;
 
-		uint8 *pDest = out + xMin;
+	for (; y <= Ymax; y++) {
+		xMin = *pVerticG++;
+		xMax = *pVerticD++;
+		pDest = pDestLine + xMin;
 
 		for (; xMin <= xMax; xMin++) {
-			*pDest++ = (uint8)color;
+			*pDest++ = (byte)color;
 		}
 
 		line--;
@@ -869,373 +873,256 @@ void Renderer::svgaPolyBopper(int vtop, int32 vsize, uint16 color) const {
 				}
 			}
 		}
-		out += screenWidth;
+
+		pDestLine += screenWidth;
 	}
 }
 
-void Renderer::svgaPolyTriste(int vtop, int32 vsize, uint16 color) const {
-	uint8 *out = (uint8 *)_engine->_frontVideoBuffer.getBasePtr(0, vtop);
-	const int16 *ptr1 = &_polyTab[vtop];
+void Renderer::svgaPolyTriste(int16 vtop, int16 Ymax, uint16 color) const {
 	const int screenWidth = _engine->width();
-	const int screenHeight = _engine->height();
-	int32 renderLoop = vsize;
-	if (vtop < 0) {
-		out += screenWidth * ABS(vtop);
-		renderLoop -= ABS(vtop);
-	}
-	if (renderLoop > screenHeight) {
-		renderLoop = screenHeight;
-	}
-	for (int32 currentLine = 0; currentLine < renderLoop; ++currentLine) {
-		const int16 start = ptr1[0];
-		const int16 stop = ptr1[screenHeight];
-		ptr1++;
-		const int32 hsize = stop - start;
-
-		for (int32 j = start; j <= hsize + start; j++) {
-			if (j >= 0 && j < screenWidth) {
-				out[j] = color;
-			}
+	int16 xMin, xMax;
+	int16 y = vtop;
+	byte *pDestLine = (uint8 *)_engine->_frontVideoBuffer.getBasePtr(0, vtop);
+	byte *pDest;
+	int16 *pVerticG = &_tabVerticG[y];
+	int16 *pVerticD = &_tabVerticD[y];
+
+	for (; y <= Ymax; y++) {
+		xMin = *pVerticG++;
+		xMax = *pVerticD++;
+		pDest = pDestLine + xMin;
+
+		for (; xMin <= xMax; xMin++) {
+			*pDest++ = (byte)color;
 		}
-		out += screenWidth;
+
+		pDestLine += screenWidth;
 	}
 }
 
+#define ROL8(x,b) (byte)(((x) << (b)) | ((x) >> (8 - (b))))
 #define ROL16(x, b) (((x) << (b)) | ((x) >> (16 - (b))))
 
-void Renderer::svgaPolyTele(int vtop, int32 vsize, uint16 color) const {
-	uint8 *out = (uint8 *)_engine->_frontVideoBuffer.getBasePtr(0, vtop);
-	const int16 *ptr1 = &_polyTab[vtop];
+void Renderer::svgaPolyTele(int16 vtop, int16 Ymax, uint16 color) const {
 	const int screenWidth = _engine->width();
-	const int screenHeight = _engine->height();
-
-	int32 renderLoop = vsize;
-	if (vtop < 0) {
-		out += screenWidth * ABS(vtop);
-		renderLoop -= ABS(vtop);
-	}
-	if (renderLoop > screenHeight) {
-		renderLoop = screenHeight;
-	}
+	int16 xMin, xMax;
+	int16 y = vtop;
+	int16 acc = 17371;
+	byte *pDestLine = (uint8 *)_engine->_frontVideoBuffer.getBasePtr(0, vtop);
+	byte *pDest;
+	int16 *pVerticG = &_tabVerticG[y];
+	int16 *pVerticD = &_tabVerticD[y];
+	uint16 col;
 
-	uint16 acc = 17371;
 	color &= 0xFF;
-	uint16 col;
-	for (int32 currentLine = 0; currentLine < renderLoop; ++currentLine) {
-		int16 xMin = ptr1[0];
-		int16 xMax = ptr1[screenHeight];
-		++ptr1;
-		uint8 *pDest = out + xMin;
+
+	for (; y <= Ymax; y++) {
+		xMin = *pVerticG++;
+		xMax = *pVerticD++;
+		pDest = pDestLine + xMin;
 		col = xMin;
 
 		for (; xMin <= xMax; xMin++) {
 			col = ((col + acc) & 0xFF03) + (uint16)color;
 			acc = ROL16(acc, 2) + 1;
 
-			*pDest++ = (uint8)col;
+			*pDest++ = (byte)col;
 		}
-		out += screenWidth;
+
+		pDestLine += screenWidth;
 	}
 }
 
-void Renderer::svgaPolyTrans(int vtop, int32 vsize, uint16 color) const {
-	uint8 *out = (uint8 *)_engine->_frontVideoBuffer.getBasePtr(0, vtop);
-	const int16 *ptr1 = &_polyTab[vtop];
+void Renderer::svgaPolyTrans(int16 vtop, int16 Ymax, uint16 color) const {
 	const int screenWidth = _engine->width();
-	const int screenHeight = _engine->height();
+	int16 xMin, xMax;
+	int16 y = vtop;
+	byte *pDestLine = (uint8 *)_engine->_frontVideoBuffer.getBasePtr(0, vtop);
+	byte *pDest;
+	int16 *pVerticG = &_tabVerticG[y];
+	int16 *pVerticD = &_tabVerticD[y];
 
-	do {
-		int16 start = ptr1[0];
-		int16 stop = ptr1[screenHeight];
+	color &= 0xF0;
 
-		ptr1++;
-		int32 hsize = stop - start;
+	for (; y <= Ymax; y++) {
+		xMin = *pVerticG++;
+		xMax = *pVerticD++;
+		pDest = pDestLine + xMin;
 
-		if (hsize >= 0) {
-			hsize++;
-			uint8 *out2 = start + out;
-			*out2 = (*(out2)&0x0F) | color;
-			out2++;
+		for (; xMin <= xMax; xMin++) {
+			*pDest = (byte)color | (*pDest & 0x0F);
+			pDest++;
 		}
-		out += screenWidth;
-	} while (--vsize);
+
+		pDestLine += screenWidth;
+	}
 }
 
 // Used e.g for the legs of the horse or the ears of most characters
-void Renderer::svgaPolyTrame(int vtop, int32 vsize, uint16 color) const {
-	uint8 *out = (uint8 *)_engine->_frontVideoBuffer.getBasePtr(0, vtop);
-	const int16 *ptr1 = &_polyTab[vtop];
+void Renderer::svgaPolyTrame(int16 vtop, int16 Ymax, uint16 color) const {
 	const int screenWidth = _engine->width();
-	const int screenHeight = _engine->height();
-
-	int32 renderLoop = vsize;
-	if (vtop < 0) {
-		out += screenWidth * ABS(vtop);
-		renderLoop -= ABS(vtop);
-	}
-	if (renderLoop > screenHeight) {
-		renderLoop = screenHeight;
-	}
+	int16 xMin, xMax;
+	int16 y = vtop;
+	byte *pDestLine = (uint8 *)_engine->_frontVideoBuffer.getBasePtr(0, vtop);
+	byte *pDest;
+	int16 *pVerticG = &_tabVerticG[y];
+	int16 *pVerticD = &_tabVerticD[y];
 	int32 pair = 0;
-	for (int32 currentLine = 0; currentLine < renderLoop; ++currentLine) {
-		int16 start = ptr1[0];
-		int16 stop = ptr1[screenHeight];
-		ptr1++;
-		uint8 *out2 = start + out;
-		stop = ((stop - start) + 1) / 2;
-		if (stop > 0) {
+
+	for (; y <= Ymax; y++) {
+		xMin = *pVerticG++;
+		xMax = *pVerticD++;
+		pDest = pDestLine + xMin;
+
+		xMax = ((xMax - xMin) + 1) / 2;
+		if (xMax > 0) {
 			pair ^= 1; // paire/impair
-			if ((start & 1) ^ pair) {
-				out2++;
+			if ((xMin & 1) ^ pair) {
+				pDest++;
 			}
 
-			for (; stop > 0; stop--) {
-				*out2 = color;
-				out2 += 2;
+			for (; xMax > 0; xMax--) {
+				*pDest = (byte)color;
+				pDest += 2;
 			}
 		}
 
-		out += screenWidth;
+		pDestLine += screenWidth;
 	}
 }
 
-void Renderer::svgaPolyGouraud(int vtop, int32 vsize) const {
-	uint8 *out = (uint8 *)_engine->_frontVideoBuffer.getBasePtr(0, vtop);
-	const int16 *ptr1 = &_polyTab[vtop];
-	const int16 *ptr2 = &_colorProgressionBuffer[vtop];
+void Renderer::svgaPolyGouraud(int16 vtop, int16 Ymax) const {
 	const int screenWidth = _engine->width();
-	const int screenHeight = _engine->height();
-	int32 renderLoop = vsize;
-	if (vtop < 0) {
-		out += screenWidth * ABS(vtop);
-		renderLoop -= ABS(vtop);
-	}
-	if (renderLoop > screenHeight) {
-		renderLoop = screenHeight;
-	}
-	for (int32 currentLine = 0; currentLine < renderLoop; ++currentLine) {
-		uint16 startColor = ptr2[0];
-		const uint16 stopColor = ptr2[screenHeight];
-
-		int16 colorDiff = stopColor - startColor;
-
-		const int16 stop = ptr1[screenHeight];
-		const int16 start = ptr1[0];
-
-		ptr1++;
-		uint8 *out2 = start + out;
-		int32 hsize = stop - start;
-
-		ptr2++;
-
-		if (hsize == 0) {
-			if (start >= 0 && start < screenWidth) {
-				*out2 = ((startColor + stopColor) / 2) / 256; // average of the 2 colors
-			}
-		} else if (hsize == 1) {
-			if (start >= 1 && start < screenWidth - 1) {
-				*(out2 + 1) = stopColor / 256;
-			}
+	int16 xMin, xMax;
+	int16 y = vtop;
+	int16 start, end, step;
+	byte *pDestLine = (uint8 *)_engine->_frontVideoBuffer.getBasePtr(0, y);
+	byte *pDest;
+	int16 *pVerticG = &_tabVerticG[y];
+	int16 *pVerticD = &_tabVerticD[y];
+	int16 *pCoulG = &_tabCoulG[y];
+	int16 *pCoulD = &_tabCoulD[y];
+
+	for (; y <= Ymax; y++) {
+		xMin = *pVerticG++;
+		xMax = *pVerticD++;
+		start = *pCoulG++;
+		end = *pCoulD++;
+		pDest = pDestLine + xMin;
 
-			if (start >= 0 && start < screenWidth) {
-				*out2 = startColor / 256;
-			}
-		} else if (hsize == 2) {
-			if (start >= 2 && start < screenWidth - 2) {
-				*(out2 + 2) = stopColor / 256;
-			}
+		xMax -= xMin;
 
-			if (start >= 1 && start < screenWidth - 1) {
-				*(out2 + 1) = ((startColor + stopColor) / 2) / 256; // average of the 2 colors
+		if (xMax == 0) {
+			*pDest = (byte)((end + start) >> 9);
+		} else if (xMax <= 2) {
+			pDest[xMax--] = (byte)(end >> 8);
+			if (xMax) {
+				pDest[xMax--] = (byte)((end + start) >> 9);
 			}
+			*pDest = (byte)(start >> 8);
+		} else {
+			step = (end - start) / xMax;
 
-			if (start >= 0 && start < screenWidth) {
-				*out2 = startColor / 256;
-			}
-		} else if (hsize > 0) {
-			int32 currentXPos = start;
-			colorDiff /= hsize;
-			hsize++;
-
-			if (hsize % 2) {
-				if (currentXPos >= 0 && currentXPos < screenWidth) {
-					*out2 = startColor / 256;
-				}
-				++out2;
-				++currentXPos;
-				startColor += colorDiff;
+			for (; xMax >= 0; xMax--) {
+				*pDest++ = (byte)(start >> 8);
+				start += step;
 			}
-			hsize /= 2;
-
-			do {
-				for (int i = 0; i < 2; ++i) {
-					if (currentXPos >= 0 && currentXPos < screenWidth) {
-						*out2 = startColor / 256;
-					}
-					++out2;
-					++currentXPos;
-					startColor += colorDiff;
-				}
-			} while (--hsize);
 		}
-		out += screenWidth;
+
+		pDestLine += screenWidth;
 	}
 }
 
 // used for the most of the heads of the characters and the horse body
-void Renderer::svgaPolyDith(int vtop, int32 vsize) const {
-	uint8 *out = (uint8 *)_engine->_frontVideoBuffer.getBasePtr(0, vtop);
-	const int16 *ptr1 = &_polyTab[vtop];
-	const int16 *ptr2 = &_colorProgressionBuffer[vtop];
+void Renderer::svgaPolyDith(int16 vtop, int16 Ymax) const {
 	const int screenWidth = _engine->width();
-	const int screenHeight = _engine->height();
+	int16 xMin, xMax;
+	int16 y = vtop;
+	int16 start, end, step, delta, impair;
+	byte *pDestLine = (uint8 *)_engine->_frontVideoBuffer.getBasePtr(0, y);
+	byte *pDest;
+	int16 *pVerticG = &_tabVerticG[y];
+	int16 *pVerticD = &_tabVerticD[y];
+	int16 *pCoulG = &_tabCoulG[y];
+	int16 *pCoulD = &_tabCoulD[y];
+
+	for (; y <= Ymax; y++) {
+		xMin = *pVerticG++;
+		xMax = *pVerticD++;
+		start = *pCoulG++;
+		end = *pCoulD++;
+		pDest = pDestLine + xMin;
 
-	int32 renderLoop = vsize;
-	if (vtop < 0) {
-		out += screenWidth * ABS(vtop);
-		renderLoop -= ABS(vtop);
-	}
-	if (renderLoop > screenHeight) {
-		renderLoop = screenHeight;
-	}
-	for (int32 currentLine = 0; currentLine < renderLoop; ++currentLine) {
-		int16 stop = ptr1[screenHeight];
-		int16 start = ptr1[0];
-		ptr1++;
-		int32 hsize = stop - start;
-		if (hsize < 0) {
-			out += screenWidth;
-			continue;
-		}
-		uint16 startColor = ptr2[0];
-		uint16 stopColor = ptr2[screenHeight];
-		int32 currentXPos = start;
+		xMax -= xMin;
+		delta = end - start;
 
-		uint8 *out2 = start + out;
-		ptr2++;
+		if (xMax == 0) {
+			// rcr ax,1
+			*pDest = (byte)(((int32)end + start) >> 9);
+		} else if (xMax <= 2) {
+			step = start;
 
-		if (hsize == 0) {
-			if (currentXPos >= 0 && currentXPos < screenWidth) {
-				*out2 = (uint8)(((startColor + stopColor) / 2) / 256); // average of the 2 colors
+			if (xMax == 2) // if( !(xMax & 1) )
+			{
+				delta = (delta >> 1) | (delta & 0x8000); // sar ax,1
+				step &= 0xFF;
+				step = start + ROL8(step, 1);
+				*pDest++ = (byte)(step >> 8);
+				start += delta;
 			}
-		} else {
-			int16 colorSize = stopColor - startColor;
-			if (hsize == 1) {
-				uint16 currentColor = startColor;
-				hsize++;
-				hsize /= 2;
-
-				currentColor &= 0xFF;
-				currentColor += startColor;
-				if (currentXPos >= 0 && currentXPos < screenWidth) {
-					*out2 = currentColor / 256;
-				}
-
-				currentColor &= 0xFF;
-				startColor += colorSize;
-				currentColor = ((currentColor & (0xFF00)) | ((((currentColor & 0xFF) << (hsize & 0xFF))) & 0xFF));
-				currentColor += startColor;
 
-				currentXPos++;
-				if (currentXPos >= 0 && currentXPos < screenWidth) {
-					*(out2 + 1) = currentColor / 256;
-				}
-			} else if (hsize == 2) {
-				uint16 currentColor = startColor;
-				hsize++;
-				hsize /= 2;
-
-				currentColor &= 0xFF;
-				colorSize /= 2;
-				currentColor = ((currentColor & (0xFF00)) | ((((currentColor & 0xFF) << (hsize & 0xFF))) & 0xFF));
-				currentColor += startColor;
-				if (currentXPos >= 0 && currentXPos < screenWidth) {
-					*out2 = currentColor / 256;
-				}
+			step = start + (step & 0xFF);
+			*pDest++ = (byte)(step >> 8);
 
-				out2++;
-				currentXPos++;
-				startColor += colorSize;
-
-				currentColor &= 0xFF;
-				currentColor += startColor;
-
-				if (currentXPos >= 0 && currentXPos < screenWidth) {
-					*out2 = currentColor / 256;
-				}
-
-				currentColor &= 0xFF;
-				startColor += colorSize;
-				currentColor = ((currentColor & (0xFF00)) | ((((currentColor & 0xFF) << (hsize & 0xFF))) & 0xFF));
-				currentColor += startColor;
-
-				currentXPos++;
-				if (currentXPos >= 0 && currentXPos < screenWidth) {
-					*(out2 + 1) = currentColor / 256;
-				}
-			} else {
-				uint16 currentColor = startColor;
-				colorSize /= hsize;
-				hsize++;
-
-				if (hsize % 2) {
-					hsize /= 2;
-					currentColor &= 0xFF;
-					currentColor = ((currentColor & (0xFF00)) | ((((currentColor & 0xFF) << (hsize & 0xFF))) & 0xFF));
-					currentColor += startColor;
-					if (currentXPos >= 0 && currentXPos < screenWidth) {
-						*out2 = currentColor / 256;
-					}
-					out2++;
-					currentXPos++;
-				} else {
-					hsize /= 2;
-				}
+			start += delta;
+			step &= 0xFF;
+			step = start + ROL8(step, 1);
+			*pDest = (byte)(step >> 8);
+		} else {
+			delta /= xMax;
+			step = start;
+			impair = xMax & 1;
+			xMax = (xMax + 1) >> 1;
+
+			if (!impair) {
+				step &= 0xFF;
+				step = start + ROL8(step, xMax & 7);
+				*pDest++ = (byte)(step >> 8);
+				start += delta;
+			}
 
-				do {
-					currentColor &= 0xFF;
-					currentColor += startColor;
-					if (currentXPos >= 0 && currentXPos < screenWidth) {
-						*out2 = currentColor / 256;
-					}
-					currentXPos++;
-					currentColor &= 0xFF;
-					startColor += colorSize;
-					currentColor = ((currentColor & (0xFF00)) | ((((currentColor & 0xFF) << (hsize & 0xFF))) & 0xFF));
-					currentColor += startColor;
-					if (currentXPos >= 0 && currentXPos < screenWidth) {
-						*(out2 + 1) = currentColor / 256;
-					}
-					currentXPos++;
-					out2 += 2;
-					startColor += colorSize;
-				} while (--hsize);
+			for (; xMax > 0; xMax--) {
+				step &= 0xFF;
+				step += start;
+				*pDest++ = (byte)(step >> 8);
+				start += delta;
+				step &= 0xFF;
+				step = start + ROL8(step, xMax & 7);
+				*pDest++ = (byte)(step >> 8);
+				start += delta;
 			}
 		}
-		out += screenWidth;
+
+		pDestLine += screenWidth;
 	}
 }
 
-void Renderer::svgaPolyMarbre(int vtop, int32 vsize, uint16 color) const {
+void Renderer::svgaPolyMarbre(int16 vtop, int16 Ymax, uint16 color) const {
 	const int screenWidth = _engine->width();
-	const int screenHeight = _engine->height();
-
-	uint8 *out = (uint8 *)_engine->_frontVideoBuffer.getBasePtr(0, vtop);
-	int16 *ptr1 = &_polyTab[vtop];
-
 	int16 xMin, xMax;
 	int16 y = vtop;
-	uint8 *pDestLine = out;
-	uint8 *pDest;
-	int16 *pVerticG = ptr1;
-	int16 *pVerticD = &ptr1[screenHeight];
+	byte *pDestLine = (uint8 *)_engine->_frontVideoBuffer.getBasePtr(0, y);
+	byte *pDest;
+	int16 *pVerticG = &_tabVerticG[y];
+	int16 *pVerticD = &_tabVerticD[y];
 
+	// color contains 2 colors: 0xFF start, 0xFF00 end
 	uint16 start = (color & 0xFF) << 8;
 	uint16 end = color & 0xFF00;
 	uint16 delta = end - start + 1; // delta intensity
 	int32 step, dc;
 
-	for (; y <= vsize; y++) {
+	for (; y <= Ymax; y++) {
 		xMin = *pVerticG++;
 		xMax = *pVerticD++;
 		pDest = pDestLine + xMin;
@@ -1243,13 +1130,13 @@ void Renderer::svgaPolyMarbre(int vtop, int32 vsize, uint16 color) const {
 		dc = xMax - xMin;
 		if (dc == 0) {
 			// just one
-			*pDest++ = (uint8)(end >> 8);
+			*pDest++ = (byte)(end >> 8);
 		} else if (dc > 0) {
 			step = delta / (dc + 1);
 			color = start;
 
 			for (; xMin <= xMax; xMin++) {
-				*pDest++ = (uint8)(color >> 8);
+				*pDest++ = (byte)(color >> 8);
 				color += step;
 			}
 		}
@@ -1258,85 +1145,78 @@ void Renderer::svgaPolyMarbre(int vtop, int32 vsize, uint16 color) const {
 	}
 }
 
-void Renderer::svgaPolyTriche(int vtop, int32 vsize, uint16 color) const {
-	uint8 *out = (uint8 *)_engine->_frontVideoBuffer.getBasePtr(0, vtop);
-	const int16 *ptr1 = &_polyTab[vtop];
-	const int16 *ptr2 = &_colorProgressionBuffer[vtop];
+void Renderer::svgaPolyTriche(int16 vtop, int16 Ymax, uint16 color) const {
 	const int screenWidth = _engine->width();
-	const int screenHeight = _engine->height();
+	int16 xMin, xMax;
+	int16 y = vtop;
+	byte *pDestLine = (uint8 *)_engine->_frontVideoBuffer.getBasePtr(0, y);
+	byte *pDest;
+	int16 *pVerticG = &_tabVerticG[y];
+	int16 *pVerticD = &_tabVerticD[y];
+	int16 *pCoulG = &_tabCoulG[y];
 
-	int32 renderLoop = vsize;
-	if (vtop < 0) {
-		out += screenWidth * ABS(vtop);
-		renderLoop -= ABS(vtop);
-	}
-	if (renderLoop > screenHeight) {
-		renderLoop = screenHeight;
-	}
-	for (int32 currentLine = 0; currentLine < renderLoop; ++currentLine) {
-		int16 xMin = MAX<int16>(0, ptr1[0]);
-		const int16 xMax = MIN<int16>((int16)(screenWidth - 1), ptr1[screenHeight]);
-		uint8 *pDest = out + xMin;
+	for (; y <= Ymax; y++) {
+		xMin = *pVerticG++;
+		xMax = *pVerticD++;
+		pDest = pDestLine + xMin;
 
-		color = (*ptr2++) >> 8;
+		color = (*pCoulG++) >> 8;
 		for (; xMin <= xMax; xMin++) {
-			*pDest++ = color;
+			*pDest++ = (byte)color;
 		}
-		++ptr1;
 
-		out += screenWidth;
+		pDestLine += screenWidth;
 	}
 }
 
 void Renderer::renderPolygons(const CmdRenderPolygon &polygon, ComputedVertex *vertices, int vtop, int vbottom) {
 	if (computePoly(polygon.renderType, vertices, polygon.numVertices, vtop, vbottom)) {
-		const int32 vsize = vbottom - vtop + 1;
-		fillVertices(vtop, vsize, polygon.renderType, polygon.colorIndex);
+		fillVertices(vtop, vbottom, polygon.renderType, polygon.colorIndex);
 	}
 }
 
-void Renderer::fillVertices(int vtop, int32 vsize, uint8 renderType, uint16 color) {
+void Renderer::fillVertices(int16 vtop, int16 vbottom, uint8 renderType, uint16 color) {
 	switch (renderType) {
 	case POLYGONTYPE_FLAT:
-		svgaPolyTriste(vtop, vsize, color);
+		svgaPolyTriste(vtop, vbottom, color);
 		break;
 	case POLYGONTYPE_TELE:
 		if (_engine->_cfgfile.PolygonDetails == 0) {
-			svgaPolyTriste(vtop, vsize, color);
+			svgaPolyTriste(vtop, vbottom, color);
 		} else {
-			svgaPolyTele(vtop, vsize, color);
+			svgaPolyTele(vtop, vbottom, color);
 		}
 		break;
 	case POLYGONTYPE_COPPER:
-		svgaPolyCopper(vtop, vsize, color);
+		svgaPolyCopper(vtop, vbottom, color);
 		break;
 	case POLYGONTYPE_BOPPER:
-		svgaPolyBopper(vtop, vsize, color);
+		svgaPolyBopper(vtop, vbottom, color);
 		break;
 	case POLYGONTYPE_TRANS:
-		svgaPolyTrans(vtop, vsize, color);
+		svgaPolyTrans(vtop, vbottom, color);
 		break;
 	case POLYGONTYPE_TRAME: // raster
-		svgaPolyTrame(vtop, vsize, color);
+		svgaPolyTrame(vtop, vbottom, color);
 		break;
 	case POLYGONTYPE_GOURAUD:
 		if (_engine->_cfgfile.PolygonDetails == 0) {
-			svgaPolyTriche(vtop, vsize, color);
+			svgaPolyTriche(vtop, vbottom, color);
 		} else {
-			svgaPolyGouraud(vtop, vsize);
+			svgaPolyGouraud(vtop, vbottom);
 		}
 		break;
 	case POLYGONTYPE_DITHER:
 		if (_engine->_cfgfile.PolygonDetails == 0) {
-			svgaPolyTriche(vtop, vsize, color);
+			svgaPolyTriche(vtop, vbottom, color);
 		} else if (_engine->_cfgfile.PolygonDetails == 1) {
-			svgaPolyGouraud(vtop, vsize);
+			svgaPolyGouraud(vtop, vbottom);
 		} else {
-			svgaPolyDith(vtop, vsize);
+			svgaPolyDith(vtop, vbottom);
 		}
 		break;
 	case POLYGONTYPE_MARBLE:
-		svgaPolyMarbre(vtop, vsize, color);
+		svgaPolyMarbre(vtop, vbottom, color);
 		break;
 	default:
 		warning("RENDER WARNING: Unsupported render type %d", renderType);
@@ -1375,9 +1255,6 @@ bool Renderer::computeSphere(int32 x, int32 y, int32 radius, int &vtop, int &vbo
 		int32 r = 0;
 		int32 acc = -radius;
 
-		int16 *start = _polyTab;
-		int16 *end = &_polyTab[_engine->height()];
-
 		while (r <= radius) {
 			int32 x1 = x - radius;
 			if (x1 < cleft) {
@@ -1391,14 +1268,14 @@ bool Renderer::computeSphere(int32 x, int32 y, int32 radius, int &vtop, int &vbo
 
 			int32 ny = y - r;
 			if ((ny >= ctop) && (ny <= cbottom)) {
-				start[ny] = (int16)x1;
-				end[ny] = (int16)x2;
+				_tabVerticG[ny] = (int16)x1;
+				_tabVerticD[ny] = (int16)x2;
 			}
 
 			ny = y + r;
 			if ((ny >= ctop) && (ny <= cbottom)) {
-				start[ny] = (int16)x1;
-				end[ny] = (int16)x2;
+				_tabVerticG[ny] = (int16)x1;
+				_tabVerticD[ny] = (int16)x2;
 			}
 
 			if (acc < 0) {
@@ -1416,14 +1293,14 @@ bool Renderer::computeSphere(int32 x, int32 y, int32 radius, int &vtop, int &vbo
 
 					ny = y - radius;
 					if ((ny >= ctop) && (ny <= cbottom)) {
-						start[ny] = (int16)x1;
-						end[ny] = (int16)x2;
+						_tabVerticG[ny] = (int16)x1;
+						_tabVerticD[ny] = (int16)x2;
 					}
 
 					ny = y + radius;
 					if ((ny >= ctop) && (ny <= cbottom)) {
-						start[ny] = (int16)x1;
-						end[ny] = (int16)x2;
+						_tabVerticG[ny] = (int16)x1;
+						_tabVerticD[ny] = (int16)x2;
 					}
 
 					--radius;
@@ -1487,9 +1364,6 @@ uint8 *Renderer::prepareLines(const Common::Array<BodyLine> &lines, int32 &numOf
 }
 
 uint8 *Renderer::preparePolygons(const Common::Array<BodyPolygon> &polygons, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData) {
-	const int16 maxHeight = _engine->height() - 1;
-	const int16 maxWidth = _engine->width() - 1;
-
 	for (const BodyPolygon &polygon : polygons) {
 		const uint8 materialType = polygon.materialType;
 		const uint8 numVertices = polygon.indices.size();
@@ -1520,8 +1394,8 @@ uint8 *Renderer::preparePolygons(const Common::Array<BodyPolygon> &polygons, int
 				const I16Vec3 *point = &modelData->flattenPoints[vertexIndex];
 
 				vertex->intensity = shadeValue;
-				vertex->x = clamp(point->x, 0, maxWidth);
-				vertex->y = clamp(point->y, 0, maxHeight);
+				vertex->x = point->x;
+				vertex->y = point->y;
 				destinationPolygon->top = MIN<int16>(destinationPolygon->top, vertex->y);
 				destinationPolygon->bottom = MAX<int16>(destinationPolygon->bottom, vertex->y);
 				zMax = MAX(zMax, point->z);
@@ -1545,11 +1419,11 @@ uint8 *Renderer::preparePolygons(const Common::Array<BodyPolygon> &polygons, int
 				const I16Vec3 *point = &modelData->flattenPoints[vertexIndex];
 
 				vertex->intensity = destinationPolygon->colorIndex;
-				vertex->x = clamp(point->x, 0, maxWidth);
-				vertex->y = clamp(point->y, 0, maxHeight);
+				vertex->x = point->x;
+				vertex->y = point->y;
 				destinationPolygon->top = MIN<int16>(destinationPolygon->top, vertex->y);
 				destinationPolygon->bottom = MAX<int16>(destinationPolygon->bottom, vertex->y);
-				zMax = MAX(zMax, point->z);
+				zMax = MAX<int16>(zMax, point->z);
 				++vertex;
 			}
 		}
@@ -1624,8 +1498,6 @@ bool Renderer::renderObjectIso(const BodyData &bodyData, RenderCommand **renderC
 				radius = (sphere->radius * _lFactorX) / delta;
 			}
 
-			radius += 3;
-
 			if (sphere->x + radius > modelRect.right) {
 				modelRect.right = sphere->x + radius;
 			}
@@ -1642,13 +1514,10 @@ bool Renderer::renderObjectIso(const BodyData &bodyData, RenderCommand **renderC
 				modelRect.top = sphere->y - radius;
 			}
 
-			radius -= 3;
-
 			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);
+				fillVertices(vtop, vbottom, sphere->polyRenderType, sphere->color);
 			}
 			break;
 		}
diff --git a/engines/twine/renderer/renderer.h b/engines/twine/renderer/renderer.h
index 57f420e7703..ec08d1af513 100644
--- a/engines/twine/renderer/renderer.h
+++ b/engines/twine/renderer/renderer.h
@@ -186,28 +186,27 @@ private:
 	ComputedVertex _clippedPolygonVertices1[128];
 	ComputedVertex _clippedPolygonVertices2[128];
 
-	int32 _polyTabSize = 0;
-	int16 *_polyTab = nullptr; // also _tabVerticG
-	int16 *_colorProgressionBuffer = nullptr;
 	int16* _tabVerticG = nullptr;
-	int16* _tabx0 = nullptr; // also TabCoulG
-	int16* _taby0 = nullptr; // also TabCoulD
-	int16* _taby1 = nullptr;
-	int16* _tabx1 = nullptr;
 	int16* _tabVerticD = nullptr;
+	int16* _tabCoulG = nullptr;
+	int16* _tabCoulD = nullptr;
+	int16* _taby0 = nullptr;
+	int16* _taby1 = nullptr;
+	int16* _tabx0 = nullptr; // also _tabCoulG
+	int16* _tabx1 = nullptr; // also _tabCoulD
 
 	bool _isUsingIsoProjection = false;
 
-	void svgaPolyCopper(int vtop, int32 vsize, uint16 color) const;
-	void svgaPolyBopper(int vtop, int32 vsize, uint16 color) const;
-	void svgaPolyTriste(int vtop, int32 vsize, uint16 color) const;
-	void svgaPolyTele(int vtop, int32 vsize, uint16 color) const;
-	void svgaPolyTrans(int vtop, int32 vsize, uint16 color) const;
-	void svgaPolyTrame(int vtop, int32 vsize, uint16 color) const;
-	void svgaPolyGouraud(int vtop, int32 vsize) const;
-	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;
+	void svgaPolyCopper(int16 vtop, int16 vbottom, uint16 color) const;
+	void svgaPolyBopper(int16 vtop, int16 vbottom, uint16 color) const;
+	void svgaPolyTriste(int16 vtop, int16 vbottom, uint16 color) const;
+	void svgaPolyTele(int16 vtop, int16 vbottom, uint16 color) const;
+	void svgaPolyTrans(int16 vtop, int16 vbottom, uint16 color) const;
+	void svgaPolyTrame(int16 vtop, int16 vbottom, uint16 color) const;
+	void svgaPolyGouraud(int16 vtop, int16 vbottom) const;
+	void svgaPolyDith(int16 vtop, int16 vbottom) const;
+	void svgaPolyMarbre(int16 vtop, int16 vbottom, uint16 color) const;
+	void svgaPolyTriche(int16 vtop, int16 vbottom, uint16 color) const;
 	bool computePoly(int16 polyRenderType, const ComputedVertex *vertices, int32 numVertices, int &vtop, int &vbottom);
 
 	const RenderCommand *depthSortRenderCommands(int32 numOfPrimitives);
@@ -244,7 +243,7 @@ public:
 		return longWorldRot(vec.x, vec.y, vec.z);
 	}
 
-	void fillVertices(int vtop, int32 vsize, uint8 renderType, uint16 color);
+	void fillVertices(int16 vtop, int16 vbottom, uint8 renderType, uint16 color);
 	void renderPolygons(const CmdRenderPolygon &polygon, ComputedVertex *vertices, int vtop, int vbottom);
 
 	inline IVec3 &projectPositionOnScreen(const IVec3& pos) { // ProjettePoint




More information about the Scummvm-git-logs mailing list