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

this fixes invalid memory access
This commit is contained in:
Martin Gerhardy 2023-01-17 19:07:04 +01:00
parent 4e0a29d61d
commit ae4db01bc1
2 changed files with 22 additions and 10 deletions

View file

@ -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;

View file

@ -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();