This commit is contained in:
gabest
2008-12-06 10:35:31 +00:00
parent 8a125c0ee0
commit d1b7b97774
6 changed files with 55 additions and 18 deletions

View File

@@ -93,22 +93,45 @@ void GPUDrawScanline::SetupDraw(Vertex* vertices, int count, const void* texture
m_slenv.md = GSVector4i(env.STATUS.MD ? 0x80008000 : 0);
}
void GPUDrawScanline::SetupScanline(const Vertex& dv)
void GPUDrawScanline::SetupPrim(PrimitiveType type, const Vertex* vertices, const Vertex& dscan)
{
if(m_sel.tme && !m_sel.twin)
{
GSVector4i t;
switch(type)
{
case Sprite:
t = (GSVector4i(vertices[1].t) >> 8) - GSVector4i::x00000001();
t = t.ps32(t);
t = t.upl16(t);
m_slenv.u[2] = t.xxxx();
m_slenv.v[2] = t.yyyy();
break;
default:
m_slenv.u[2] = GSVector4i::x00ff();
m_slenv.v[2] = GSVector4i::x00ff();
break;
}
}
// we could use integers here but it's more accurate to multiply a float than a 8.8 fixed point number
GSVector4 ps0123 = GSVector4::ps0123();
GSVector4 ps4567 = GSVector4::ps4567();
GSVector4i dtc8 = GSVector4i(dv.t * 8.0f).ps32(GSVector4i(dv.c * 8.0f));
GSVector4 dt = dscan.t;
GSVector4 dc = dscan.c;
m_slenv.ds = GSVector4i(dv.t.xxxx() * ps0123).ps32(GSVector4i(dv.t.xxxx() * ps4567));
m_slenv.dt = GSVector4i(dv.t.yyyy() * ps0123).ps32(GSVector4i(dv.t.yyyy() * ps4567));
GSVector4i dtc8 = GSVector4i(dt * 8.0f).ps32(GSVector4i(dc * 8.0f));
m_slenv.ds = GSVector4i(dt.xxxx() * ps0123).ps32(GSVector4i(dt.xxxx() * ps4567));
m_slenv.dt = GSVector4i(dt.yyyy() * ps0123).ps32(GSVector4i(dt.yyyy() * ps4567));
m_slenv.dst8 = dtc8.upl16(dtc8);
m_slenv.dr = GSVector4i(dv.c.xxxx() * ps0123).ps32(GSVector4i(dv.c.xxxx() * ps4567));
m_slenv.dg = GSVector4i(dv.c.yyyy() * ps0123).ps32(GSVector4i(dv.c.yyyy() * ps4567));
m_slenv.db = GSVector4i(dv.c.zzzz() * ps0123).ps32(GSVector4i(dv.c.zzzz() * ps4567));
m_slenv.dr = GSVector4i(dc.xxxx() * ps0123).ps32(GSVector4i(dc.xxxx() * ps4567));
m_slenv.dg = GSVector4i(dc.yyyy() * ps0123).ps32(GSVector4i(dc.yyyy() * ps4567));
m_slenv.db = GSVector4i(dc.zzzz() * ps0123).ps32(GSVector4i(dc.zzzz() * ps4567));
m_slenv.dc8 = dtc8.uph16(dtc8);
}
@@ -153,6 +176,13 @@ void GPUDrawScanline::SampleTexture(int pixels, DWORD ltf, DWORD tlu, DWORD twin
u1 = (u1 & m_slenv.u[0]).add16(m_slenv.u[1]);
v1 = (v1 & m_slenv.v[0]).add16(m_slenv.v[1]);
}
else
{
u0 = u0.min_i16(m_slenv.u[2]);
v0 = v0.min_i16(m_slenv.v[2]);
u1 = u1.min_i16(m_slenv.u[2]);
v1 = v1.min_i16(m_slenv.v[2]);
}
GSVector4i addr00 = v0.sll16(8) | u0;
GSVector4i addr01 = v0.sll16(8) | u1;
@@ -271,6 +301,11 @@ void GPUDrawScanline::SampleTexture(int pixels, DWORD ltf, DWORD tlu, DWORD twin
u = (u & m_slenv.u[0]).add16(m_slenv.u[1]);
v = (v & m_slenv.v[0]).add16(m_slenv.v[1]);
}
else
{
u = u.min_i16(m_slenv.u[2]);
v = v.min_i16(m_slenv.v[2]);
}
GSVector4i addr = v.sll16(8) | u;

View File

@@ -64,8 +64,8 @@ class GPUDrawScanline : public GSAlignedClass<16>, public IDrawScanline
const void* tex;
const WORD* clut;
GSVector4i u[2];
GSVector4i v[2];
GSVector4i u[3];
GSVector4i v[3];
GSVector4i a;
GSVector4i md; // similar to gs fba
@@ -105,7 +105,7 @@ public:
// IDrawScanline
void SetupDraw(Vertex* vertices, int count, const void* texture);
void SetupScanline(const Vertex& dv);
void SetupPrim(PrimitiveType type, const Vertex* vertices, const Vertex& dscan);
void DrawScanline(int top, int left, int right, const Vertex& v);
void FillRect(const GSVector4i& r, const Vertex& v);
DrawScanlinePtr GetDrawScanlinePtr();

View File

@@ -250,7 +250,7 @@ void GSDrawScanline::SetupDraw(Vertex* vertices, int count, const void* texture)
}
}
void GSDrawScanline::SetupScanline(const Vertex& dv)
void GSDrawScanline::SetupPrim(PrimitiveType type, const Vertex* vertices, const Vertex& dv)
{
GSVector4 ps0123 = GSVector4::ps0123();

View File

@@ -151,7 +151,7 @@ public:
// IDrawScanline
void SetupDraw(Vertex* vertices, int count, const void* texture);
void SetupScanline(const Vertex& dv);
void SetupPrim(PrimitiveType type, const Vertex* vertices, const Vertex& dv);
void DrawScanline(int top, int left, int right, const Vertex& v);
void FillRect(const GSVector4i& r, const Vertex& v);
DrawScanlinePtr GetDrawScanlinePtr();

View File

@@ -168,7 +168,7 @@ void GSRasterizer::DrawTriangleTop(Vertex* v, const GSVector4i& scissor)
r += dr * dy;
}
m_ds->SetupScanline(dscan);
m_ds->SetupPrim(IDrawScanline::Triangle, v, dscan);
DrawTriangleSection(top, bottom, l, dl, r, dr, dscan, scissor);
}
@@ -215,8 +215,8 @@ void GSRasterizer::DrawTriangleBottom(Vertex* v, const GSVector4i& scissor)
l += dl * dy;
r += dr * dy;
}
m_ds->SetupScanline(dscan);
m_ds->SetupPrim(IDrawScanline::Triangle, v, dscan);
DrawTriangleSection(top, bottom, l, dl, r, dr, dscan, scissor);
}
@@ -238,7 +238,7 @@ void GSRasterizer::DrawTriangleTopBottom(Vertex* v, const GSVector4i& scissor)
Vertex dscan = longest * longest.p.xxxx().rcp();
m_ds->SetupScanline(dscan);
m_ds->SetupPrim(IDrawScanline::Triangle, v, dscan);
Vertex& l = v[0];
GSVector4 r = v[0].p;
@@ -446,7 +446,7 @@ void GSRasterizer::DrawSprite(Vertex* vertices, const GSVector4i& scissor, bool
if(scan.p.y < (float)top) scan.t += dedge.t * ((float)top - scan.p.y);
if(scan.p.x < (float)left) scan.t += dscan.t * ((float)left - scan.p.x);
m_ds->SetupScanline(dscan);
m_ds->SetupPrim(IDrawScanline::Sprite, v, dscan);
IDrawScanline::DrawScanlinePtr dsf = m_ds->GetDrawScanlinePtr();

View File

@@ -31,10 +31,12 @@ public:
typedef GSVertexSW Vertex;
typedef void (IDrawScanline::*DrawScanlinePtr)(int top, int left, int right, const Vertex& v);
enum PrimitiveType {Point, Line, Triangle, Sprite};
virtual ~IDrawScanline() {}
virtual void SetupDraw(Vertex* vertices, int count, const void* texture) = 0;
virtual void SetupScanline(const Vertex& dv) = 0;
virtual void SetupPrim(PrimitiveType type, const Vertex* vertices, const Vertex& dscan) = 0;
virtual void DrawScanline(int top, int left, int right, const Vertex& v) = 0;
virtual void FillRect(const GSVector4i& r, const Vertex& v) = 0;
virtual DrawScanlinePtr GetDrawScanlinePtr() = 0;