Skip to content

Commit

Permalink
Fix state crash due to polygons using pointers
Browse files Browse the repository at this point in the history
  • Loading branch information
Hydr8gon committed Jul 20, 2024
1 parent cb7e14f commit 2a96468
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 46 deletions.
18 changes: 9 additions & 9 deletions src/gpu_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ Vertex Gpu3D::intersection(Vertex *vtx1, Vertex *vtx2, int32_t val1, int32_t val
return vertex;
}

bool Gpu3D::clipPolygon(Vertex *unclipped, Vertex *clipped, int *size)
bool Gpu3D::clipPolygon(Vertex *unclipped, Vertex *clipped, uint8_t *size)
{
bool clip = false;

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

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

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

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

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

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

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

Expand Down
57 changes: 28 additions & 29 deletions src/gpu_3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ enum GXState

struct Entry
{
Entry(uint8_t command, uint32_t param): command(command), param(param) {}

uint8_t command;
uint32_t param;

Entry(uint8_t command, uint32_t param): command(command), param(param) {}
};

struct Matrix
Expand All @@ -61,7 +61,7 @@ struct Vector
int32_t x = 0, y = 0, z = 0;

int32_t operator*(Vector &vtr);
Vector operator*(Matrix &mtx);
Vector operator*(Matrix &mtx);
};

struct Vertex: Vector
Expand All @@ -75,46 +75,45 @@ struct Vertex: Vector

struct _Polygon
{
int size = 0;
Vertex *vertices = nullptr;
bool crossed = false;
bool clockwise = false;

int mode = 0;
bool transNewDepth = false;
bool depthTestEqual = false;
bool fog = false;
uint8_t alpha = 0;
int id = 0;

uint32_t textureAddr = 0, paletteAddr = 0;
int sizeS = 0, sizeT = 0;
uint16_t sizeS = 0, sizeT = 0;
uint8_t textureFmt = 0;
bool repeatS = false, repeatT = false;
bool flipS = false, flipT = false;
int textureFmt = 0;
bool transparent0 = false;

uint16_t vertices = 0;
uint8_t size = 0;
uint8_t wShift = 0;
bool wBuffer = false;
int wShift = 0;
};
bool crossed = false;
bool clockwise = false;

uint8_t mode = 0;
uint8_t alpha = 0;
uint8_t id = 0;
bool transNewDepth = false;
bool depthTestEqual = false;
bool fog = false;
};

class Gpu3D
{
public:
_Polygon *polygonsOut = polygons2;
Vertex *verticesOut = vertices2;
uint16_t polygonCountOut = 0;
uint16_t vertexCountOut = 0;

Gpu3D(Core *core): core(core) {}
void saveState(FILE *file);
void loadState(FILE *file);

void runCommand();
void swapBuffers();

bool shouldSwap() { return state == GX_HALTED; }

_Polygon *getPolygons() { return polygonsOut; }
int getPolygonCount() { return polygonCountOut; }

uint32_t readGxStat() { return gxStat; }
uint32_t readGxStat() { return gxStat; }
uint32_t readPosResult(int index) { return posResult[index]; }
uint32_t readVecResult(int index) { return vecResult[index]; }
uint32_t readRamCount();
Expand Down Expand Up @@ -183,13 +182,13 @@ class Gpu3D
Matrix clip;

Vertex vertices1[6144], vertices2[6144];
Vertex *verticesIn = vertices1, *verticesOut = vertices2;
uint16_t vertexCountIn = 0, vertexCountOut = 0;
Vertex *verticesIn = vertices1;
uint16_t vertexCountIn = 0;
uint16_t processCount = 0;

_Polygon polygons1[2048], polygons2[2048];
_Polygon *polygonsIn = polygons1, *polygonsOut = polygons2;
uint16_t polygonCountIn = 0, polygonCountOut = 0;
_Polygon *polygonsIn = polygons1;
uint16_t polygonCountIn = 0;

Vertex savedVertex;
_Polygon savedPolygon;
Expand Down Expand Up @@ -223,7 +222,7 @@ class Gpu3D

static uint32_t rgb5ToRgb6(uint16_t color);
static Vertex intersection(Vertex *vtx1, Vertex *vtx2, int32_t val1, int32_t val2);
static bool clipPolygon(Vertex *unclipped, Vertex *clipped, int *size);
static bool clipPolygon(Vertex *unclipped, Vertex *clipped, uint8_t *size);

void processVertices();
void addVertex();
Expand Down
14 changes: 7 additions & 7 deletions src/gpu_3d_renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,15 +132,15 @@ void Gpu3DRenderer::drawScanline(int line)
if (line == 0)
{
// Calculate the scanline bounds for each polygon
for (int i = 0; i < core->gpu3D.getPolygonCount(); i++)
for (int i = 0; i < core->gpu3D.polygonCountOut; i++)
{
polygonTop[i] = 192 * 2;
polygonBot[i] = 0 * 2;

_Polygon *polygon = &core->gpu3D.getPolygons()[i];
_Polygon *polygon = &core->gpu3D.polygonsOut[i];
for (int j = 0; j < polygon->size; j++)
{
Vertex *vertex = &polygon->vertices[j];
Vertex *vertex = &core->gpu3D.verticesOut[polygon->vertices + j];
if (vertex->y < polygonTop[i]) polygonTop[i] = vertex->y;
if (vertex->y > polygonBot[i]) polygonBot[i] = vertex->y;
}
Expand Down Expand Up @@ -271,14 +271,14 @@ void Gpu3DRenderer::drawScanline1(int line)
std::vector<int> translucent;

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

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

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

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

// Unclipped quad strip polygons have their vertices crossed, so uncross them
if (polygon->crossed)
Expand Down
2 changes: 1 addition & 1 deletion src/save_states.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include "core.h"

const char *SaveStates::stateTag = "NOOD";
const uint32_t SaveStates::stateVersion = 2;
const uint32_t SaveStates::stateVersion = 3;

void SaveStates::setPath(std::string path, bool gba)
{
Expand Down

0 comments on commit 2a96468

Please sign in to comment.