0.9.6: line hack
This commit is contained in:
parent
6f7d169123
commit
776968e0f5
|
@ -813,64 +813,6 @@ static void GL_ReadFramebuffer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// "Workaround" for line poly
|
|
||||||
static bool isLinePoly(POLY *poly)
|
|
||||||
{
|
|
||||||
int type = poly->type;
|
|
||||||
VERT *vert1, *vert2;
|
|
||||||
|
|
||||||
if (type <= 2)
|
|
||||||
return true;
|
|
||||||
else if (type > 4)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Method 1:
|
|
||||||
// Castlevania Portrait of Ruin - trajectory of ricochet
|
|
||||||
bool duplicatedVert[4] = { false, false, false, false };
|
|
||||||
for(int i = 0; i < type - 1; i++)
|
|
||||||
{
|
|
||||||
vert1 = &gfx3d.vertlist->list[poly->vertIndexes[i]];
|
|
||||||
for(int j = i + 1; j < type; j++)
|
|
||||||
{
|
|
||||||
vert2 = &gfx3d.vertlist->list[poly->vertIndexes[j]];
|
|
||||||
if (vert1->x == vert2->x && vert1->y == vert2->y)
|
|
||||||
{
|
|
||||||
duplicatedVert[j] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int vertCount = type;
|
|
||||||
for(int i = 0; i < type; i++)
|
|
||||||
{
|
|
||||||
if (duplicatedVert[i])
|
|
||||||
vertCount--;
|
|
||||||
}
|
|
||||||
if (vertCount <= 2)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// Method 2:
|
|
||||||
// Castlevania Portrait of Ruin - warp stone
|
|
||||||
bool horizontalLine = true;
|
|
||||||
bool verticalLine = true;
|
|
||||||
vert1 = &gfx3d.vertlist->list[poly->vertIndexes[0]];
|
|
||||||
for(int i = 1; i < type && (horizontalLine || verticalLine); i++)
|
|
||||||
{
|
|
||||||
vert2 = &gfx3d.vertlist->list[poly->vertIndexes[i]];
|
|
||||||
if (vert1->coord[0] != vert2->coord[0])
|
|
||||||
{
|
|
||||||
verticalLine = false;
|
|
||||||
}
|
|
||||||
if (vert1->coord[1] != vert2->coord[1])
|
|
||||||
{
|
|
||||||
horizontalLine = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (horizontalLine || verticalLine)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void OGLRender()
|
static void OGLRender()
|
||||||
{
|
{
|
||||||
if(!BEGINGL()) return;
|
if(!BEGINGL()) return;
|
||||||
|
@ -971,7 +913,7 @@ static void OGLRender()
|
||||||
lastViewport = poly->viewport;
|
lastViewport = poly->viewport;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isLinePoly(poly))
|
if (gfx3d_IsLinePoly(poly))
|
||||||
glBegin(GL_LINE_LOOP);
|
glBegin(GL_LINE_LOOP);
|
||||||
else
|
else
|
||||||
glBegin(GL_TRIANGLES);
|
glBegin(GL_TRIANGLES);
|
||||||
|
|
|
@ -2760,3 +2760,60 @@ void GFX3D_Clipper::clipPoly(POLY* poly, VERT** verts)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// "Workaround" for line poly
|
||||||
|
bool gfx3d_IsLinePoly(POLY *poly)
|
||||||
|
{
|
||||||
|
int type = poly->type;
|
||||||
|
VERT *vert1, *vert2;
|
||||||
|
|
||||||
|
if (type <= 2)
|
||||||
|
return true;
|
||||||
|
else if (type > 4)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Method 1:
|
||||||
|
// Castlevania Portrait of Ruin - trajectory of ricochet
|
||||||
|
bool duplicatedVert[4] = { false, false, false, false };
|
||||||
|
for(int i = 0; i < type - 1; i++)
|
||||||
|
{
|
||||||
|
vert1 = &gfx3d.vertlist->list[poly->vertIndexes[i]];
|
||||||
|
for(int j = i + 1; j < type; j++)
|
||||||
|
{
|
||||||
|
vert2 = &gfx3d.vertlist->list[poly->vertIndexes[j]];
|
||||||
|
if (vert1->x == vert2->x && vert1->y == vert2->y)
|
||||||
|
{
|
||||||
|
duplicatedVert[j] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int vertCount = type;
|
||||||
|
for(int i = 0; i < type; i++)
|
||||||
|
{
|
||||||
|
if (duplicatedVert[i])
|
||||||
|
vertCount--;
|
||||||
|
}
|
||||||
|
if (vertCount <= 2)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Method 2:
|
||||||
|
// Castlevania Portrait of Ruin - warp stone
|
||||||
|
bool horizontalLine = true;
|
||||||
|
bool verticalLine = true;
|
||||||
|
vert1 = &gfx3d.vertlist->list[poly->vertIndexes[0]];
|
||||||
|
for(int i = 1; i < type && (horizontalLine || verticalLine); i++)
|
||||||
|
{
|
||||||
|
vert2 = &gfx3d.vertlist->list[poly->vertIndexes[i]];
|
||||||
|
if (vert1->coord[0] != vert2->coord[0])
|
||||||
|
{
|
||||||
|
verticalLine = false;
|
||||||
|
}
|
||||||
|
if (vert1->coord[1] != vert2->coord[1])
|
||||||
|
{
|
||||||
|
horizontalLine = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (horizontalLine || verticalLine)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -446,4 +446,6 @@ bool gfx3d_loadstate(EMUFILE* is, int size);
|
||||||
|
|
||||||
void gfx3d_ClearStack();
|
void gfx3d_ClearStack();
|
||||||
|
|
||||||
|
bool gfx3d_IsLinePoly(POLY *poly);
|
||||||
|
|
||||||
#endif //_GFX3D_H_
|
#endif //_GFX3D_H_
|
||||||
|
|
|
@ -245,7 +245,6 @@ FORCEINLINE edge_fx_fl::edge_fx_fl(int Top, int Bottom, VERT** verts, bool& fail
|
||||||
Numerator = 0;
|
Numerator = 0;
|
||||||
ErrorTerm = 0;
|
ErrorTerm = 0;
|
||||||
Denominator = 1;
|
Denominator = 1;
|
||||||
failure = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float YPrestep = Fixed28_4ToFloat((fixed28_4)(Y*16 - verts[Top]->y));
|
float YPrestep = Fixed28_4ToFloat((fixed28_4)(Y*16 - verts[Top]->y));
|
||||||
|
@ -691,26 +690,22 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
//draws a single scanline
|
//draws a single scanline
|
||||||
FORCEINLINE void drawscanline(edge_fx_fl *pLeft, edge_fx_fl *pRight)
|
FORCEINLINE void drawscanline(edge_fx_fl *pLeft, edge_fx_fl *pRight, bool lineHack)
|
||||||
{
|
{
|
||||||
int XStart = pLeft->X;
|
int XStart = pLeft->X;
|
||||||
int width = pRight->X - XStart;
|
int width = pRight->X - XStart;
|
||||||
|
|
||||||
// workaround for vertical/slant line poly
|
// HACK: workaround for vertical/slant line poly
|
||||||
// it seems to cause another issue though
|
if (lineHack && width == 0)
|
||||||
//if (width == 0)
|
{
|
||||||
//{
|
int leftWidth = pLeft->XStep;
|
||||||
// int leftWidth = pLeft->XStep;
|
if (pLeft->ErrorTerm + pLeft->Numerator >= pLeft->Denominator)
|
||||||
// if (pLeft->ErrorTerm + pLeft->Numerator >= pLeft->Denominator)
|
leftWidth++;
|
||||||
// leftWidth++;
|
int rightWidth = pRight->XStep;
|
||||||
// int rightWidth = pRight->XStep;
|
if (pRight->ErrorTerm + pRight->Numerator >= pRight->Denominator)
|
||||||
// if (pRight->ErrorTerm + pRight->Numerator >= pRight->Denominator)
|
rightWidth++;
|
||||||
// rightWidth++;
|
width = max(1, max(abs(leftWidth), abs(rightWidth)));
|
||||||
// width = max(1, min(abs(leftWidth), abs(rightWidth)));
|
}
|
||||||
//
|
|
||||||
// if (XStart + width > 256)
|
|
||||||
// width = max(0, 256 - XStart);
|
|
||||||
//}
|
|
||||||
|
|
||||||
//these are the starting values, taken from the left edge
|
//these are the starting values, taken from the left edge
|
||||||
float invw = pLeft->invw.curr;
|
float invw = pLeft->invw.curr;
|
||||||
|
@ -750,15 +745,18 @@ public:
|
||||||
|
|
||||||
while(width-- > 0)
|
while(width-- > 0)
|
||||||
{
|
{
|
||||||
if(RENDERER && (x<0 || x>255)) {
|
bool outOfRange = false;
|
||||||
|
if(RENDERER && (x<0 || x>255))
|
||||||
|
outOfRange = true;
|
||||||
|
if(!RENDERER && (x<0 || x>=engine->width))
|
||||||
|
outOfRange = true;
|
||||||
|
if(!lineHack && outOfRange)
|
||||||
|
{
|
||||||
printf("rasterizer rendering at x=%d! oops!\n",x);
|
printf("rasterizer rendering at x=%d! oops!\n",x);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!RENDERER && (x<0 || x>=engine->width)) {
|
if(!outOfRange)
|
||||||
printf("rasterizer rendering at x=%d! oops!\n",x);
|
pixel(adr,color[0],color[1],color[2],u,v,1.0f/invw,z);
|
||||||
return;
|
|
||||||
}
|
|
||||||
pixel(adr,color[0],color[1],color[2],u,v,1.0f/invw,z);
|
|
||||||
adr++;
|
adr++;
|
||||||
x++;
|
x++;
|
||||||
|
|
||||||
|
@ -774,7 +772,7 @@ public:
|
||||||
|
|
||||||
//runs several scanlines, until an edge is finished
|
//runs several scanlines, until an edge is finished
|
||||||
template<bool SLI>
|
template<bool SLI>
|
||||||
void runscanlines(edge_fx_fl *left, edge_fx_fl *right,bool horizontal)
|
void runscanlines(edge_fx_fl *left, edge_fx_fl *right, bool horizontal, bool lineHack)
|
||||||
{
|
{
|
||||||
//oh lord, hack city for edge drawing
|
//oh lord, hack city for edge drawing
|
||||||
|
|
||||||
|
@ -785,16 +783,15 @@ public:
|
||||||
runctr++;
|
runctr++;
|
||||||
|
|
||||||
//HACK: special handling for horizontal line poly
|
//HACK: special handling for horizontal line poly
|
||||||
//Instead of line, this will cause other notable issue.
|
if (lineHack && left->Height == 0 && right->Height == 0)
|
||||||
//if (left->Height == 0 && right->Height == 0)
|
{
|
||||||
//{
|
bool draw = (!SLI || (left->Y & SLI_MASK) == SLI_VALUE);
|
||||||
// bool draw = (!SLI || (left->Y & SLI_MASK) == SLI_VALUE);
|
if(draw) drawscanline(left,right,lineHack);
|
||||||
// if(draw) drawscanline(left,right);
|
}
|
||||||
//}
|
|
||||||
|
|
||||||
while(Height--) {
|
while(Height--) {
|
||||||
bool draw = (!SLI || (left->Y & SLI_MASK) == SLI_VALUE);
|
bool draw = (!SLI || (left->Y & SLI_MASK) == SLI_VALUE);
|
||||||
if(draw) drawscanline(left,right);
|
if(draw) drawscanline(left,right,lineHack);
|
||||||
const int xl = left->X;
|
const int xl = left->X;
|
||||||
const int xr = right->X;
|
const int xr = right->X;
|
||||||
const int y = left->Y;
|
const int y = left->Y;
|
||||||
|
@ -897,7 +894,7 @@ public:
|
||||||
//I didnt reference anything for this algorithm but it seems like I've seen it somewhere before.
|
//I didnt reference anything for this algorithm but it seems like I've seen it somewhere before.
|
||||||
//Maybe it is like crow's algorithm
|
//Maybe it is like crow's algorithm
|
||||||
template<bool SLI>
|
template<bool SLI>
|
||||||
void shape_engine(int type, bool backwards)
|
void shape_engine(int type, bool backwards, bool lineHack)
|
||||||
{
|
{
|
||||||
bool failure = false;
|
bool failure = false;
|
||||||
|
|
||||||
|
@ -935,7 +932,7 @@ public:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool horizontal = left.Y == right.Y;
|
bool horizontal = left.Y == right.Y;
|
||||||
runscanlines<SLI>(&left,&right,horizontal);
|
runscanlines<SLI>(&left,&right,horizontal,lineHack);
|
||||||
|
|
||||||
//if we ran out of an edge, step to the next one
|
//if we ran out of an edge, step to the next one
|
||||||
if(right.Height == 0) {
|
if(right.Height == 0) {
|
||||||
|
@ -1005,7 +1002,7 @@ public:
|
||||||
|
|
||||||
polyAttr.backfacing = engine->polyBackfacing[i];
|
polyAttr.backfacing = engine->polyBackfacing[i];
|
||||||
|
|
||||||
shape_engine<SLI>(type,!polyAttr.backfacing);
|
shape_engine<SLI>(type,!polyAttr.backfacing, gfx3d_IsLinePoly(poly));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue