0.9.6: line hack

This commit is contained in:
gocha 2010-12-24 13:59:19 +00:00
parent 6f7d169123
commit 776968e0f5
4 changed files with 91 additions and 93 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -446,4 +446,6 @@ bool gfx3d_loadstate(EMUFILE* is, int size);
void gfx3d_ClearStack();
bool gfx3d_IsLinePoly(POLY *poly);
#endif //_GFX3D_H_

View File

@ -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,14 +745,17 @@ public:
while(width-- > 0)
{
if(RENDERER && (x<0 || x>255)) {
printf("rasterizer rendering at x=%d! oops!\n",x);
return;
}
if(!RENDERER && (x<0 || x>=engine->width)) {
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(!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));
}
}