Skip to content

Commit 2a96468

Browse files
committed
Fix state crash due to polygons using pointers
1 parent cb7e14f commit 2a96468

File tree

4 files changed

+45
-46
lines changed

4 files changed

+45
-46
lines changed

src/gpu_3d.cpp

+9-9
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ Vertex Gpu3D::intersection(Vertex *vtx1, Vertex *vtx2, int32_t val1, int32_t val
255255
return vertex;
256256
}
257257

258-
bool Gpu3D::clipPolygon(Vertex *unclipped, Vertex *clipped, int *size)
258+
bool Gpu3D::clipPolygon(Vertex *unclipped, Vertex *clipped, uint8_t *size)
259259
{
260260
bool clip = false;
261261

@@ -464,11 +464,11 @@ void Gpu3D::swapBuffers()
464464
_Polygon *p = &polygonsIn[i];
465465

466466
// Find the polygon's greatest W value
467-
uint32_t value = p->vertices[0].w;
467+
uint32_t value = verticesIn[p->vertices].w;
468468
for (int j = 1; j < p->size; j++)
469469
{
470-
if ((uint32_t)p->vertices[j].w > value)
471-
value = p->vertices[j].w;
470+
if ((uint32_t)verticesIn[p->vertices + j].w > value)
471+
value = verticesIn[p->vertices + j].w;
472472
}
473473

474474
// Reduce precision in 4-bit increments until the value fits in a 16-bit range
@@ -564,11 +564,11 @@ void Gpu3D::addPolygon()
564564
// Set the polygon vertex information
565565
int size = 3 + (polygonType & 1);
566566
savedPolygon.size = size;
567-
savedPolygon.vertices = &verticesIn[vertexCountIn - size];
567+
savedPolygon.vertices = vertexCountIn - size;
568568

569569
// Save a copy of the unclipped vertices
570570
Vertex unclipped[4];
571-
memcpy(unclipped, savedPolygon.vertices, size * sizeof(Vertex));
571+
memcpy(unclipped, &verticesIn[savedPolygon.vertices], size * sizeof(Vertex));
572572

573573
// Rearrange quad strip vertices to be counter-clockwise
574574
if (polygonType == 3)
@@ -691,7 +691,7 @@ void Gpu3D::addPolygon()
691691
{
692692
// Remove the unclipped vertices
693693
vertexCountIn -= (vertexCount == 3) ? 3 : 1;
694-
savedPolygon.vertices = &verticesIn[vertexCountIn];
694+
savedPolygon.vertices = vertexCountIn;
695695

696696
// Add the clipped vertices
697697
for (int i = 0; i < savedPolygon.size; i++)
@@ -716,7 +716,7 @@ void Gpu3D::addPolygon()
716716
{
717717
// Remove the unclipped vertices
718718
vertexCountIn -= (vertexCount == 4) ? 4 : 2;
719-
savedPolygon.vertices = &verticesIn[vertexCountIn];
719+
savedPolygon.vertices = vertexCountIn;
720720

721721
// Add the clipped vertices
722722
for (int i = 0; i < savedPolygon.size; i++)
@@ -1602,7 +1602,7 @@ void Gpu3D::boxTestCmd(std::vector<uint32_t> &params)
16021602
// If any of the faces are in view, set the result bit
16031603
for (int i = 0; i < 6; i++)
16041604
{
1605-
int size = 4;
1605+
uint8_t size = 4;
16061606
Vertex clipped[10];
16071607
clipPolygon(faces[i], clipped, &size);
16081608

src/gpu_3d.h

+28-29
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ enum GXState
3737

3838
struct Entry
3939
{
40-
Entry(uint8_t command, uint32_t param): command(command), param(param) {}
41-
4240
uint8_t command;
4341
uint32_t param;
42+
43+
Entry(uint8_t command, uint32_t param): command(command), param(param) {}
4444
};
4545

4646
struct Matrix
@@ -61,7 +61,7 @@ struct Vector
6161
int32_t x = 0, y = 0, z = 0;
6262

6363
int32_t operator*(Vector &vtr);
64-
Vector operator*(Matrix &mtx);
64+
Vector operator*(Matrix &mtx);
6565
};
6666

6767
struct Vertex: Vector
@@ -75,46 +75,45 @@ struct Vertex: Vector
7575

7676
struct _Polygon
7777
{
78-
int size = 0;
79-
Vertex *vertices = nullptr;
80-
bool crossed = false;
81-
bool clockwise = false;
82-
83-
int mode = 0;
84-
bool transNewDepth = false;
85-
bool depthTestEqual = false;
86-
bool fog = false;
87-
uint8_t alpha = 0;
88-
int id = 0;
89-
9078
uint32_t textureAddr = 0, paletteAddr = 0;
91-
int sizeS = 0, sizeT = 0;
79+
uint16_t sizeS = 0, sizeT = 0;
80+
uint8_t textureFmt = 0;
9281
bool repeatS = false, repeatT = false;
9382
bool flipS = false, flipT = false;
94-
int textureFmt = 0;
9583
bool transparent0 = false;
9684

85+
uint16_t vertices = 0;
86+
uint8_t size = 0;
87+
uint8_t wShift = 0;
9788
bool wBuffer = false;
98-
int wShift = 0;
99-
};
89+
bool crossed = false;
90+
bool clockwise = false;
10091

92+
uint8_t mode = 0;
93+
uint8_t alpha = 0;
94+
uint8_t id = 0;
95+
bool transNewDepth = false;
96+
bool depthTestEqual = false;
97+
bool fog = false;
98+
};
10199

102100
class Gpu3D
103101
{
104102
public:
103+
_Polygon *polygonsOut = polygons2;
104+
Vertex *verticesOut = vertices2;
105+
uint16_t polygonCountOut = 0;
106+
uint16_t vertexCountOut = 0;
107+
105108
Gpu3D(Core *core): core(core) {}
106109
void saveState(FILE *file);
107110
void loadState(FILE *file);
108111

109112
void runCommand();
110113
void swapBuffers();
111-
112114
bool shouldSwap() { return state == GX_HALTED; }
113115

114-
_Polygon *getPolygons() { return polygonsOut; }
115-
int getPolygonCount() { return polygonCountOut; }
116-
117-
uint32_t readGxStat() { return gxStat; }
116+
uint32_t readGxStat() { return gxStat; }
118117
uint32_t readPosResult(int index) { return posResult[index]; }
119118
uint32_t readVecResult(int index) { return vecResult[index]; }
120119
uint32_t readRamCount();
@@ -183,13 +182,13 @@ class Gpu3D
183182
Matrix clip;
184183

185184
Vertex vertices1[6144], vertices2[6144];
186-
Vertex *verticesIn = vertices1, *verticesOut = vertices2;
187-
uint16_t vertexCountIn = 0, vertexCountOut = 0;
185+
Vertex *verticesIn = vertices1;
186+
uint16_t vertexCountIn = 0;
188187
uint16_t processCount = 0;
189188

190189
_Polygon polygons1[2048], polygons2[2048];
191-
_Polygon *polygonsIn = polygons1, *polygonsOut = polygons2;
192-
uint16_t polygonCountIn = 0, polygonCountOut = 0;
190+
_Polygon *polygonsIn = polygons1;
191+
uint16_t polygonCountIn = 0;
193192

194193
Vertex savedVertex;
195194
_Polygon savedPolygon;
@@ -223,7 +222,7 @@ class Gpu3D
223222

224223
static uint32_t rgb5ToRgb6(uint16_t color);
225224
static Vertex intersection(Vertex *vtx1, Vertex *vtx2, int32_t val1, int32_t val2);
226-
static bool clipPolygon(Vertex *unclipped, Vertex *clipped, int *size);
225+
static bool clipPolygon(Vertex *unclipped, Vertex *clipped, uint8_t *size);
227226

228227
void processVertices();
229228
void addVertex();

src/gpu_3d_renderer.cpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -132,15 +132,15 @@ void Gpu3DRenderer::drawScanline(int line)
132132
if (line == 0)
133133
{
134134
// Calculate the scanline bounds for each polygon
135-
for (int i = 0; i < core->gpu3D.getPolygonCount(); i++)
135+
for (int i = 0; i < core->gpu3D.polygonCountOut; i++)
136136
{
137137
polygonTop[i] = 192 * 2;
138138
polygonBot[i] = 0 * 2;
139139

140-
_Polygon *polygon = &core->gpu3D.getPolygons()[i];
140+
_Polygon *polygon = &core->gpu3D.polygonsOut[i];
141141
for (int j = 0; j < polygon->size; j++)
142142
{
143-
Vertex *vertex = &polygon->vertices[j];
143+
Vertex *vertex = &core->gpu3D.verticesOut[polygon->vertices + j];
144144
if (vertex->y < polygonTop[i]) polygonTop[i] = vertex->y;
145145
if (vertex->y > polygonBot[i]) polygonBot[i] = vertex->y;
146146
}
@@ -271,14 +271,14 @@ void Gpu3DRenderer::drawScanline1(int line)
271271
std::vector<int> translucent;
272272

273273
// Draw the polygons
274-
for (int i = 0; i < core->gpu3D.getPolygonCount(); i++)
274+
for (int i = 0; i < core->gpu3D.polygonCountOut; i++)
275275
{
276276
// Skip polygons that aren't on the current scanline
277277
if (line < polygonTop[i] || line >= polygonBot[i])
278278
continue;
279279

280280
// Draw solid polygons and save the translucent ones for later
281-
_Polygon *polygon = &core->gpu3D.getPolygons()[i];
281+
_Polygon *polygon = &core->gpu3D.polygonsOut[i];
282282
if (polygon->alpha < 0x3F || polygon->textureFmt == 1 || polygon->textureFmt == 6)
283283
translucent.push_back(i);
284284
else
@@ -703,12 +703,12 @@ uint32_t Gpu3DRenderer::readTexture(_Polygon *polygon, int s, int t)
703703

704704
void Gpu3DRenderer::drawPolygon(int line, int polygonIndex)
705705
{
706-
_Polygon *polygon = &core->gpu3D.getPolygons()[polygonIndex];
706+
_Polygon *polygon = &core->gpu3D.polygonsOut[polygonIndex];
707707

708708
// Get the polygon vertices
709709
Vertex *vertices[10];
710710
for (int i = 0; i < polygon->size; i++)
711-
vertices[i] = &polygon->vertices[i];
711+
vertices[i] = &core->gpu3D.verticesOut[polygon->vertices + i];
712712

713713
// Unclipped quad strip polygons have their vertices crossed, so uncross them
714714
if (polygon->crossed)

src/save_states.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#include "core.h"
2222

2323
const char *SaveStates::stateTag = "NOOD";
24-
const uint32_t SaveStates::stateVersion = 2;
24+
const uint32_t SaveStates::stateVersion = 3;
2525

2626
void SaveStates::setPath(std::string path, bool gba)
2727
{

0 commit comments

Comments
 (0)