mirror of
https://github.com/libretro/pcsx2.git
synced 2024-11-28 20:00:44 +00:00
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:
parent
3a569dba23
commit
3599acc618
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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) {}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user