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; _polyTabSize = _engine->height() * 6;
_polyTab = (int16 *)malloc(_polyTabSize * sizeof(int16)); _polyTab = (int16 *)malloc(_polyTabSize * sizeof(int16));
_colorProgressionBuffer = (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]; _tabVerticG = &_polyTab[_engine->height() * 0];
_tabVerticD = &_polyTab[_engine->height() * 1]; _tabVerticD = &_polyTab[_engine->height() * 1];
_tabx0 = &_polyTab[_engine->height() * 2]; _tabx0 = &_polyTab[_engine->height() * 2];
@ -600,7 +604,7 @@ int16 Renderer::bottomClip(int16 polyRenderType, ComputedVertex** offTabPoly, in
return newNbPoints; 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; const Common::Rect &clip = _engine->_interface->_clip;
if (clip.isEmpty()) { if (clip.isEmpty()) {
return numVertices; return numVertices;
@ -693,10 +697,13 @@ int32 Renderer::computePolyMinMax(int16 polyRenderType, ComputedVertex **offTabP
} }
} }
vtop = minsy;
vbottom = maxsy;
return clippedNumVertices; 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 *polyTabBegin = _polyTab;
const int16 *polyTabEnd = &_polyTab[_polyTabSize - 1]; const int16 *polyTabEnd = &_polyTab[_polyTabSize - 1];
const int16 *colProgressBufStart = _colorProgressionBuffer; const int16 *colProgressBufStart = _colorProgressionBuffer;
@ -710,7 +717,7 @@ bool Renderer::computePoly(int16 polyRenderType, const ComputedVertex *vertices,
ComputedVertex *offTabPoly[] = {_clippedPolygonVertices1, _clippedPolygonVertices2}; ComputedVertex *offTabPoly[] = {_clippedPolygonVertices1, _clippedPolygonVertices2};
numVertices = computePolyMinMax(polyRenderType, offTabPoly, numVertices); numVertices = computePolyMinMax(polyRenderType, offTabPoly, numVertices, vtop, vbottom);
if (numVertices == 0) { if (numVertices == 0) {
return false; 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) { 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; const int32 vsize = vbottom - vtop + 1;
fillVertices(vtop, vsize, polygon.renderType, polygon.colorIndex); 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) { if (radius <= 0) {
return false; return false;
} }
@ -1427,6 +1434,9 @@ bool Renderer::computeSphere(int32 x, int32 y, int32 radius) {
++r; ++r;
} }
vtop = top;
vbottom = bottom;
return true; return true;
} }
@ -1633,8 +1643,10 @@ bool Renderer::renderModelElements(int32 numOfPrimitives, const BodyData &bodyDa
radius -= 3; radius -= 3;
if (computeSphere(sphere->x, sphere->y, radius)) { int vtop = -1;
const int32 vsize = 2 * radius; 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(sphere->y - radius, vsize, sphere->polyRenderType, sphere->color);
} }
break; break;

View file

@ -152,7 +152,7 @@ private:
ModelData _modelData; ModelData _modelData;
bool renderAnimatedModel(ModelData *modelData, const BodyData &bodyData, RenderCommand *renderCmds, const IVec3 &angleVec, const IVec3 &renderPos, Common::Rect &modelRect); 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); bool renderModelElements(int32 numOfPrimitives, const BodyData &bodyData, RenderCommand **renderCmds, ModelData *modelData, Common::Rect &modelRect);
IVec3 longInverseRot(int32 x, int32 y, int32 z); IVec3 longInverseRot(int32 x, int32 y, int32 z);
inline IVec3 getCameraAnglePositions(const IVec3 &vec) { inline IVec3 getCameraAnglePositions(const IVec3 &vec) {
@ -208,7 +208,7 @@ private:
void svgaPolyDith(int vtop, int32 vsize) const; void svgaPolyDith(int vtop, int32 vsize) const;
void svgaPolyMarbre(int vtop, int32 vsize, uint16 color) const; void svgaPolyMarbre(int vtop, int32 vsize, uint16 color) const;
void svgaPolyTriche(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); const RenderCommand *depthSortRenderCommands(int32 numOfPrimitives);
uint8 *preparePolygons(const Common::Array<BodyPolygon>& polygons, int32 &numOfPrimitives, RenderCommand **renderCmds, uint8 *renderBufferPtr, ModelData *modelData); 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 rightClip(int16 polyRenderType, ComputedVertex** offTabPoly, int32 numVertices);
int16 topClip(int16 polyRenderType, ComputedVertex** offTabPoly, int32 numVertices); int16 topClip(int16 polyRenderType, ComputedVertex** offTabPoly, int32 numVertices);
int16 bottomClip(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: public:
Renderer(TwinEEngine *engine); Renderer(TwinEEngine *engine);
~Renderer(); ~Renderer();