GSdx: ffxii fmv works again and even less bogus

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1552 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gabest11 2009-07-22 14:28:14 +00:00
parent 3a569dba23
commit 3599acc618
5 changed files with 103 additions and 68 deletions

View File

@ -26,6 +26,7 @@ GSRenderer::GSRenderer(uint8* base, bool mt, void (*irq)(), GSDevice* dev)
: GSState(base, mt, irq)
, m_dev(dev)
, m_shader(0)
, m_vt(this)
{
m_interlace = theApp.GetConfig("interlace", 0);
m_aspectratio = theApp.GetConfig("aspectratio", 1);

View File

@ -115,7 +115,7 @@ protected:
if(!m_dev->IsLost())
{
m_vt.Update(m_vertices, m_count, PRIM, m_context);
m_vt.Update(m_vertices, m_count, GSUtil::GetPrimClass(PRIM->PRIM));
Draw();
}

View File

@ -37,68 +37,86 @@ class GSRendererHW : public GSRendererT<Vertex>
#pragma region hacks
typedef bool (GSRendererHW::*OI_Ptr)(int& prim, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t);
typedef bool (GSRendererHW::*OI_Ptr)(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t);
typedef void (GSRendererHW::*OO_Ptr)();
typedef bool (GSRendererHW::*CU_Ptr)();
bool OI_FFXII(int& prim, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t)
bool OI_FFXII(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t)
{
static uint32* video = NULL;
static bool ok = false;
static int lines = 0;
if(prim == GS_POINTLIST && m_count >= 448 * 448 && m_count <= 448 * 512)
if(lines == 0)
{
// incoming pixels are stored in columns, one column is 16x512, total res 448x512 or 448x454
if(!video) video = new uint32[512 * 512];
for(int x = 0, i = 0, rows = m_count / 448; x < 448; x += 16)
if(m_vt.m_primclass == GS_LINE_CLASS && (m_count == 448 * 2 || m_count == 512 * 2))
{
uint32* dst = &video[x];
for(int y = 0; y < rows; y++, dst += 512)
lines = m_count / 2;
}
}
else
{
if(m_vt.m_primclass == GS_POINT_CLASS)
{
if(m_count >= 16 * 512)
{
for(int j = 0; j < 16; j++, i++)
// incoming pixels are stored in columns, one column is 16x512, total res 448x512 or 448x454
if(!video) video = new uint32[512 * 512];
int ox = m_context->XYOFFSET.OFX;
int oy = m_context->XYOFFSET.OFY;
for(int i = 0; i < m_count; i++)
{
dst[j] = m_vertices[i].c0;
int x = ((int)m_vertices[i].p.x - ox) >> 4;
int y = ((int)m_vertices[i].p.y - oy) >> 4;
// video[y * 448 + x] = m_vertices[i].c0;
video[(y << 8) + (y << 7) + (y << 6) + x] = m_vertices[i].c0;
}
return false;
}
else
{
lines = 0;
}
}
else if(m_vt.m_primclass == GS_LINE_CLASS)
{
if(m_count == lines * 2)
{
// normally, this step would copy the video onto screen with 512 texture mapped horizontal lines,
// but we use the stored video data to create a new texture, and replace the lines with two triangles
ok = true;
m_dev->Recycle(t->m_texture);
return false;
}
else if(prim == GS_LINELIST && m_count == 512 * 2 && ok)
{
// normally, this step would copy the video onto screen with 512 texture mapped horizontal lines,
// but we use the stored video data to create a new texture, and replace the lines with two triangles
t->m_texture = m_dev->CreateTexture(512, 512);
ok = false;
t->m_texture->Update(GSVector4i(0, 0, 448, lines), video, 448 * 4);
m_dev->Recycle(t->m_texture);
m_vertices[0] = m_vertices[0];
m_vertices[1] = m_vertices[1];
m_vertices[2] = m_vertices[m_count - 2];
m_vertices[3] = m_vertices[1];
m_vertices[4] = m_vertices[2];
m_vertices[5] = m_vertices[m_count - 1];
t->m_texture = m_dev->CreateTexture(512, 512);
m_count = 6;
t->m_texture->Update(GSVector4i(0, 0, 448, 512), video, 512 * 4);
m_vertices[0] = m_vertices[0];
m_vertices[1] = m_vertices[1];
m_vertices[2] = m_vertices[m_count - 2];
m_vertices[3] = m_vertices[1];
m_vertices[4] = m_vertices[2];
m_vertices[5] = m_vertices[m_count - 1];
prim = GS_TRIANGLELIST;
m_count = 6;
return true;
m_vt.Update(m_vertices, m_count, GS_TRIANGLE_CLASS);
}
else
{
lines = 0;
}
}
}
return true;
}
bool OI_FFX(int& prim, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t)
bool OI_FFX(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t)
{
uint32 FBP = m_context->FRAME.Block();
uint32 ZBP = m_context->ZBUF.Block();
@ -114,7 +132,7 @@ class GSRendererHW : public GSRendererT<Vertex>
return true;
}
bool OI_MetalSlug6(int& prim, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t)
bool OI_MetalSlug6(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t)
{
// missing red channel fix
@ -126,10 +144,12 @@ class GSRendererHW : public GSRendererT<Vertex>
}
}
m_vt.Update(m_vertices, m_count, m_vt.m_primclass);
return true;
}
bool OI_GodOfWar2(int& prim, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t)
bool OI_GodOfWar2(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t)
{
uint32 FBP = m_context->FRAME.Block();
uint32 FBW = m_context->FRAME.FBW;
@ -156,7 +176,7 @@ class GSRendererHW : public GSRendererT<Vertex>
return true;
}
bool OI_SimpsonsGame(int& prim, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t)
bool OI_SimpsonsGame(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t)
{
uint32 FBP = m_context->FRAME.Block();
uint32 FBW = m_context->FRAME.FBW;
@ -176,7 +196,7 @@ class GSRendererHW : public GSRendererT<Vertex>
return true;
}
bool OI_RozenMaidenGebetGarden(int& prim, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t)
bool OI_RozenMaidenGebetGarden(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t)
{
if(!PRIM->TME)
{
@ -222,9 +242,9 @@ class GSRendererHW : public GSRendererT<Vertex>
return true;
}
bool OI_PointListPalette(int& prim, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t)
bool OI_PointListPalette(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t)
{
if(prim == GS_POINTLIST && !PRIM->TME)
if(m_vt.m_primclass == GS_POINT_CLASS && !PRIM->TME)
{
uint32 FBP = m_context->FRAME.Block();
uint32 FBW = m_context->FRAME.FBW;
@ -586,9 +606,7 @@ protected:
s_n++;
}
int prim = PRIM->PRIM;
if(m_hacks.m_oi && !(this->*m_hacks.m_oi)(prim, rt->m_texture, ds->m_texture, tex))
if(m_hacks.m_oi && !(this->*m_hacks.m_oi)(rt->m_texture, ds->m_texture, tex))
{
return;
}

View File

@ -24,14 +24,20 @@
#include "stdafx.h"
#include "GSVertexTrace.h"
#include "GSUtil.h"
#include "GSState.h"
uint32 GSVertexTrace::Hash(const GIFRegPRIM* PRIM, const GSDrawingContext* context)
GSVertexTrace::GSVertexTrace(const GSState* state)
: m_state(state)
{
m_primclass = GSUtil::GetPrimClass(PRIM->PRIM);
}
uint32 hash = m_primclass | (PRIM->IIP << 2) | (PRIM->TME << 3) | (PRIM->FST << 4);
uint32 GSVertexTrace::Hash(GS_PRIM_CLASS primclass)
{
m_primclass = primclass;
if(!(PRIM->TME && context->TEX0.TFX == TFX_DECAL && context->TEX0.TCC))
uint32 hash = m_primclass | (m_state->PRIM->IIP << 2) | (m_state->PRIM->TME << 3) | (m_state->PRIM->FST << 4);
if(!(m_state->PRIM->TME && m_state->m_context->TEX0.TFX == TFX_DECAL && m_state->m_context->TEX0.TCC))
{
hash |= 1 << 5;
}
@ -39,18 +45,20 @@ uint32 GSVertexTrace::Hash(const GIFRegPRIM* PRIM, const GSDrawingContext* conte
return hash;
}
void GSVertexTrace::Update(const GSVertexSW* v, int count, const GIFRegPRIM* PRIM, const GSDrawingContext* context)
void GSVertexTrace::Update(const GSVertexSW* v, int count, GS_PRIM_CLASS primclass)
{
m_map_sw[Hash(PRIM, context)](v, count, m_min, m_max);
m_map_sw[Hash(primclass)](v, count, m_min, m_max);
m_eq.value = (m_min.c == m_max.c).mask() | ((m_min.p == m_max.p).mask() << 16) | ((m_min.t == m_max.t).mask() << 20);
m_alpha.valid = false;
}
void GSVertexTrace::Update(const GSVertexHW9* v, int count, const GIFRegPRIM* PRIM, const GSDrawingContext* context)
{
m_map_hw9[Hash(PRIM, context)](v, count, m_min, m_max);
void GSVertexTrace::Update(const GSVertexHW9* v, int count, GS_PRIM_CLASS primclass)
{
m_map_hw9[Hash(primclass)](v, count, m_min, m_max);
const GSDrawingContext* context = m_state->m_context;
GSVector4 o(context->XYOFFSET);
GSVector4 s(1.0f / 16, 1.0f / 16, 1.0f, 1.0f);
@ -58,9 +66,9 @@ void GSVertexTrace::Update(const GSVertexHW9* v, int count, const GIFRegPRIM* PR
m_min.p = (m_min.p - o) * s;
m_max.p = (m_max.p - o) * s;
if(PRIM->TME)
if(m_state->PRIM->TME)
{
if(PRIM->FST)
if(m_state->PRIM->FST)
{
s = GSVector4(1 << (16 - 4), 1).xxyy();
}
@ -78,9 +86,11 @@ void GSVertexTrace::Update(const GSVertexHW9* v, int count, const GIFRegPRIM* PR
m_alpha.valid = false;
}
void GSVertexTrace::Update(const GSVertexHW10* v, int count, const GIFRegPRIM* PRIM, const GSDrawingContext* context)
void GSVertexTrace::Update(const GSVertexHW10* v, int count, GS_PRIM_CLASS primclass)
{
m_map_hw10[Hash(PRIM, context)](v, count, m_min, m_max);
m_map_hw10[Hash(primclass)](v, count, m_min, m_max);
const GSDrawingContext* context = m_state->m_context;
GSVector4 o(context->XYOFFSET);
GSVector4 s(1.0f / 16, 1.0f / 16, 2.0f, 1.0f);
@ -88,9 +98,9 @@ void GSVertexTrace::Update(const GSVertexHW10* v, int count, const GIFRegPRIM* P
m_min.p = (m_min.p - o) * s;
m_max.p = (m_max.p - o) * s;
if(PRIM->TME)
if(m_state->PRIM->TME)
{
if(PRIM->FST)
if(m_state->PRIM->FST)
{
s = GSVector4(1 << (16 - 4), 1).xxyy();
}

View File

@ -29,6 +29,8 @@
#include "xbyak/xbyak.h"
#include "xbyak/xbyak_util.h"
class GSState;
__declspec(align(16)) class GSVertexTrace
{
struct Vertex {GSVector4i c; GSVector4 p, t;};
@ -83,7 +85,9 @@ __declspec(align(16)) class GSVertexTrace
GSVertexTraceMapHW9 m_map_hw9;
GSVertexTraceMapHW10 m_map_hw10;
uint32 Hash(const GIFRegPRIM* PRIM, const GSDrawingContext* context);
uint32 Hash(GS_PRIM_CLASS primclass);
const GSState* m_state;
public:
GS_PRIM_CLASS m_primclass;
@ -97,8 +101,10 @@ public:
struct {uint32 rgba:16, xyzf:4, stq:4;};
} m_eq;
void Update(const GSVertexSW* v, int count, const GIFRegPRIM* PRIM, const GSDrawingContext* context);
void Update(const GSVertexHW9* v, int count, const GIFRegPRIM* PRIM, const GSDrawingContext* context);
void Update(const GSVertexHW10* v, int count, const GIFRegPRIM* PRIM, const GSDrawingContext* context);
void Update(const GSVertexNull* v, int count, const GIFRegPRIM* PRIM, const GSDrawingContext* context) {}
GSVertexTrace(const GSState* state);
void Update(const GSVertexSW* v, int count, GS_PRIM_CLASS primclass);
void Update(const GSVertexHW9* v, int count, GS_PRIM_CLASS primclass);
void Update(const GSVertexHW10* v, int count, GS_PRIM_CLASS primclass);
void Update(const GSVertexNull* v, int count, GS_PRIM_CLASS primclass) {}
};