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()
|
||||
{
|
||||
if(!BEGINGL()) return;
|
||||
|
@ -971,7 +913,7 @@ static void OGLRender()
|
|||
lastViewport = poly->viewport;
|
||||
}
|
||||
|
||||
if (isLinePoly(poly))
|
||||
if (gfx3d_IsLinePoly(poly))
|
||||
glBegin(GL_LINE_LOOP);
|
||||
else
|
||||
glBegin(GL_TRIANGLES);
|
||||
|
|
|
@ -2760,3 +2760,60 @@ void GFX3D_Clipper::clipPoly(POLY* poly, VERT** verts)
|
|||
}
|
||||
#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();
|
||||
|
||||
bool gfx3d_IsLinePoly(POLY *poly);
|
||||
|
||||
#endif //_GFX3D_H_
|
||||
|
|
|
@ -245,7 +245,6 @@ FORCEINLINE edge_fx_fl::edge_fx_fl(int Top, int Bottom, VERT** verts, bool& fail
|
|||
Numerator = 0;
|
||||
ErrorTerm = 0;
|
||||
Denominator = 1;
|
||||
failure = false;
|
||||
}
|
||||
|
||||
float YPrestep = Fixed28_4ToFloat((fixed28_4)(Y*16 - verts[Top]->y));
|
||||
|
@ -691,26 +690,22 @@ public:
|
|||
}
|
||||
|
||||
//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 width = pRight->X - XStart;
|
||||
|
||||
// workaround for vertical/slant line poly
|
||||
// it seems to cause another issue though
|
||||
//if (width == 0)
|
||||
//{
|
||||
// int leftWidth = pLeft->XStep;
|
||||
// if (pLeft->ErrorTerm + pLeft->Numerator >= pLeft->Denominator)
|
||||
// leftWidth++;
|
||||
// int rightWidth = pRight->XStep;
|
||||
// if (pRight->ErrorTerm + pRight->Numerator >= pRight->Denominator)
|
||||
// rightWidth++;
|
||||
// width = max(1, min(abs(leftWidth), abs(rightWidth)));
|
||||
//
|
||||
// if (XStart + width > 256)
|
||||
// width = max(0, 256 - XStart);
|
||||
//}
|
||||
// HACK: workaround for vertical/slant line poly
|
||||
if (lineHack && width == 0)
|
||||
{
|
||||
int leftWidth = pLeft->XStep;
|
||||
if (pLeft->ErrorTerm + pLeft->Numerator >= pLeft->Denominator)
|
||||
leftWidth++;
|
||||
int rightWidth = pRight->XStep;
|
||||
if (pRight->ErrorTerm + pRight->Numerator >= pRight->Denominator)
|
||||
rightWidth++;
|
||||
width = max(1, max(abs(leftWidth), abs(rightWidth)));
|
||||
}
|
||||
|
||||
//these are the starting values, taken from the left edge
|
||||
float invw = pLeft->invw.curr;
|
||||
|
@ -750,15 +745,18 @@ public:
|
|||
|
||||
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);
|
||||
return;
|
||||
}
|
||||
if(!RENDERER && (x<0 || x>=engine->width)) {
|
||||
printf("rasterizer rendering at x=%d! oops!\n",x);
|
||||
return;
|
||||
}
|
||||
pixel(adr,color[0],color[1],color[2],u,v,1.0f/invw,z);
|
||||
if(!outOfRange)
|
||||
pixel(adr,color[0],color[1],color[2],u,v,1.0f/invw,z);
|
||||
adr++;
|
||||
x++;
|
||||
|
||||
|
@ -774,7 +772,7 @@ public:
|
|||
|
||||
//runs several scanlines, until an edge is finished
|
||||
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
|
||||
|
||||
|
@ -785,16 +783,15 @@ public:
|
|||
runctr++;
|
||||
|
||||
//HACK: special handling for horizontal line poly
|
||||
//Instead of line, this will cause other notable issue.
|
||||
//if (left->Height == 0 && right->Height == 0)
|
||||
//{
|
||||
// bool draw = (!SLI || (left->Y & SLI_MASK) == SLI_VALUE);
|
||||
// if(draw) drawscanline(left,right);
|
||||
//}
|
||||
if (lineHack && left->Height == 0 && right->Height == 0)
|
||||
{
|
||||
bool draw = (!SLI || (left->Y & SLI_MASK) == SLI_VALUE);
|
||||
if(draw) drawscanline(left,right,lineHack);
|
||||
}
|
||||
|
||||
while(Height--) {
|
||||
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 xr = right->X;
|
||||
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.
|
||||
//Maybe it is like crow's algorithm
|
||||
template<bool SLI>
|
||||
void shape_engine(int type, bool backwards)
|
||||
void shape_engine(int type, bool backwards, bool lineHack)
|
||||
{
|
||||
bool failure = false;
|
||||
|
||||
|
@ -935,7 +932,7 @@ public:
|
|||
return;
|
||||
|
||||
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(right.Height == 0) {
|
||||
|
@ -1005,7 +1002,7 @@ public:
|
|||
|
||||
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