GIFpath: Set up incTag to work only in QWC. Required redoing the REGLIST mode handler a bit. This is needed for an in-progress MTGS project I'm in the middle of; so I'm hoping I did it right and don't screw anything up. (someone test Tekken 4 for me)

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3451 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2010-07-10 14:34:00 +00:00
parent fab3d1d4b7
commit 27be444efa
2 changed files with 63 additions and 42 deletions

View File

@ -715,6 +715,7 @@ void Pcsx2App::CleanupOnExit()
void Pcsx2App::CleanupResources() void Pcsx2App::CleanupResources()
{ {
ScopedBusyCursor cursor( Cursor_ReallyBusy );
delete wxConfigBase::Set( NULL ); delete wxConfigBase::Set( NULL );
while( wxGetLocale() != NULL ) while( wxGetLocale() != NULL )

View File

@ -363,8 +363,8 @@ static __forceinline void gsHandler(const u8* pMem)
} }
} }
#define incTag(x, y) do { \ #define incTag(y) do { \
pMem += (x); \ pMem += (y*16); \
size -= (y); \ size -= (y); \
} while(false) } while(false)
@ -383,7 +383,7 @@ __forceinline int GIFPath::ParseTagQuick(GIF_PATH pathidx, const u8* pMem, u32 s
if (!nloop) { if (!nloop) {
SetTag(pMem); SetTag(pMem);
incTag(16, 1); incTag(1);
} }
else else
{ {
@ -429,23 +429,33 @@ __forceinline int GIFPath::ParseTagQuick(GIF_PATH pathidx, const u8* pMem, u32 s
curreg = 0; curreg = 0;
nloop = 0; nloop = 0;
} }
incTag(16 * len, len); incTag(len);
} }
break; break;
case GIF_FLG_REGLIST: case GIF_FLG_REGLIST:
{ {
GIF_LOG("Reglist Mode EOP %x", tag.EOP); GIF_LOG("Reglist Mode EOP %x", tag.EOP);
// In reglist mode, the GIF packs 2 registers into each QWC. The nloop however
// can be an odd number, in which case the upper half of the final QWC is ignored (skipped).
numregs = ((tag.NREG-1)&0xf) + 1; numregs = ((tag.NREG-1)&0xf) + 1;
size *= 2; const u32 total_reglen = (nloop * numregs) - curreg; // total 'expected length' of this packed register list (in registers)
u32 len = aMin(size, (nloop * numregs)-curreg); const u32 total_listlen = (total_reglen+1) / 2; // total 'expected length' of the register list, in QWC! (+1 so to round it up)
if(len < ((nloop * numregs)-curreg)) u32 len;
if(size < total_listlen)
{ {
const int nloops_copied = len / numregs; //Console.Warning("GIF path %d Fragmented REGLIST! Please report if you experience problems", pathidx + 1);
const int regs_not_copied = len % numregs;
DevCon.Warning("Quick Hit it path %d Please report if you experience problems", pathidx + 1); len = size;
const u32 reglen = len * 2;
const int nloops_copied = reglen / numregs;
const int regs_not_copied = reglen % numregs;
//DevCon.Warning("Hit it path %d", pathidx + 1);
curreg += regs_not_copied; curreg += regs_not_copied;
nloop -= nloops_copied; nloop -= nloops_copied;
@ -455,16 +465,15 @@ __forceinline int GIFPath::ParseTagQuick(GIF_PATH pathidx, const u8* pMem, u32 s
curreg -= numregs; curreg -= numregs;
} }
} }
else nloop = 0; else
{
len = total_listlen;
curreg = 0;
nloop = 0;
}
incTag(len);
incTag(8 * len, len); //if(curreg != 0 || (len % numregs) > 0) DevCon.Warning("Oops c %x n %x m %x r %x", curreg, nloop, (len % numregs), numregs);
if (size & 1) { incTag(8, 1); }
size /= 2;
//if(curreg != 0 || (len % numregs) > 0) DevCon.Warning("Oops Q c %x n %x m %x r %x", curreg, nloop, (len % numregs), numregs);
if(nloop == 0) curreg = 0;
} }
break; break;
case GIF_FLG_IMAGE: case GIF_FLG_IMAGE:
@ -472,7 +481,7 @@ __forceinline int GIFPath::ParseTagQuick(GIF_PATH pathidx, const u8* pMem, u32 s
{ {
GIF_LOG("IMAGE Mode"); GIF_LOG("IMAGE Mode");
int len = aMin(size, nloop); int len = aMin(size, nloop);
incTag(( len * 16 ), len); incTag(len);
nloop -= len; nloop -= len;
} }
break; break;
@ -520,7 +529,7 @@ __forceinline int GIFPath::ParseTag(GIF_PATH pathidx, const u8* pMem, u32 size)
if (!nloop) { if (!nloop) {
SetTag(pMem); SetTag(pMem);
incTag(16, 1); incTag(1);
if(nloop > 0) if(nloop > 0)
{ {
@ -592,7 +601,7 @@ __forceinline int GIFPath::ParseTag(GIF_PATH pathidx, const u8* pMem, u32 size)
if (GetReg() == 0xe) { if (GetReg() == 0xe) {
gsHandler(pMem); gsHandler(pMem);
} }
incTag(16, 1); incTag(1);
} while(StepReg() && size > 0 && SIGNAL_IMR_Pending == false); } while(StepReg() && size > 0 && SIGNAL_IMR_Pending == false);
} }
else else
@ -635,21 +644,31 @@ __forceinline int GIFPath::ParseTag(GIF_PATH pathidx, const u8* pMem, u32 size)
curreg = 0; curreg = 0;
nloop = 0; nloop = 0;
} }
incTag(16 * len, len); incTag(len);
} }
break; break;
case GIF_FLG_REGLIST: case GIF_FLG_REGLIST:
{ {
GIF_LOG("Reglist Mode EOP %x", tag.EOP); GIF_LOG("Reglist Mode EOP %x", tag.EOP);
numregs = ((tag.NREG-1)&0xf) + 1; // In reglist mode, the GIF packs 2 registers into each QWC. The nloop however
size *= 2; // can be an odd number, in which case the upper half of the final QWC is ignored (skipped).
u32 len = aMin(size, (nloop * numregs)-curreg);
if(len < ((nloop * numregs)-curreg)) numregs = ((tag.NREG-1)&0xf) + 1;
const u32 total_reglen = (nloop * numregs) - curreg; // total 'expected length' of this packed register list (in registers)
const u32 total_listlen = (total_reglen+1) / 2; // total 'expected length' of the register list, in QWC! (+1 so to round it up)
u32 len;
if(size < total_listlen)
{ {
const int nloops_copied = len / numregs; //Console.Warning("GIF path %d Fragmented REGLIST! Please report if you experience problems", pathidx + 1);
const int regs_not_copied = len % numregs;
len = size;
const u32 reglen = len * 2;
const int nloops_copied = reglen / numregs;
const int regs_not_copied = reglen % numregs;
//DevCon.Warning("Hit it path %d", pathidx + 1); //DevCon.Warning("Hit it path %d", pathidx + 1);
curreg += regs_not_copied; curreg += regs_not_copied;
@ -661,14 +680,15 @@ __forceinline int GIFPath::ParseTag(GIF_PATH pathidx, const u8* pMem, u32 size)
curreg -= numregs; curreg -= numregs;
} }
} }
else nloop = 0; else
{
len = total_listlen;
curreg = 0;
nloop = 0;
}
incTag(8 * len, len); incTag(len);
if (size & 1) { incTag(8, 1); }
size /= 2;
//if(curreg != 0 || (len % numregs) > 0) DevCon.Warning("Oops c %x n %x m %x r %x", curreg, nloop, (len % numregs), numregs);
if(nloop == 0) curreg = 0;
} }
break; break;
case GIF_FLG_IMAGE: case GIF_FLG_IMAGE:
@ -676,7 +696,7 @@ __forceinline int GIFPath::ParseTag(GIF_PATH pathidx, const u8* pMem, u32 size)
{ {
GIF_LOG("IMAGE Mode EOP %x", tag.EOP); GIF_LOG("IMAGE Mode EOP %x", tag.EOP);
int len = aMin(size, nloop); int len = aMin(size, nloop);
incTag(( len * 16 ), len); incTag(len);
nloop -= len; nloop -= len;
} }
break; break;