mirror of https://github.com/PCSX2/pcsx2.git
After hours of frustration getting my gifDummyTranfser() function to work the way pcsx2 wants path2/path3 transfers to occur, I decided to just rewrite it again using the old gifDummyTransfer() as a base.
Fixes GT4 corrupt textures. Again tell me if this version breaks anything... git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1868 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
8376e0a886
commit
32e8a8a260
14
pcsx2/GS.h
14
pcsx2/GS.h
|
@ -97,6 +97,20 @@ struct GIFPath
|
|||
|
||||
__forceinline void PrepRegs(bool doPrep);
|
||||
__forceinline void SetTag(const void* mem);
|
||||
__forceinline bool StepReg()
|
||||
{
|
||||
u32 numRegs = ((tag.nreg-1)&0xf)+1;
|
||||
if ((++curreg & 0xf) == numRegs) {
|
||||
curreg = 0;
|
||||
if (--tag.nloop == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
__forceinline u8 GetReg() {
|
||||
return regs[curreg&0xf];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
145
pcsx2/MTGS.cpp
145
pcsx2/MTGS.cpp
|
@ -90,6 +90,7 @@ __forceinline void GIFPath::SetTag(const void* mem)
|
|||
{
|
||||
tag = *((GIFTAG*)mem);
|
||||
curreg = 0;
|
||||
PrepRegs();
|
||||
}
|
||||
|
||||
static void _mtgsFreezeGIF( SaveStateBase& state, GIFPath (&paths)[3] )
|
||||
|
@ -242,101 +243,99 @@ void mtgsThreadObject::Reset()
|
|||
memzero_obj( s_path );
|
||||
}
|
||||
|
||||
#define incPmem(x) { \
|
||||
pMem += (x) * 16; \
|
||||
size += (x) * 16; \
|
||||
#define incTag(x, y) { \
|
||||
pMem += (x); \
|
||||
size -= (y); \
|
||||
if ((pathidx==GIF_PATH_1)&&(pMem>=vuMemEnd)) pMem -= 0x4000; \
|
||||
}
|
||||
#define subVal(x) ((x) ? (x-1) : 0)
|
||||
#define aMin(x, y) ((x < y) ? (x) : (y))
|
||||
#define subVal(x, y) ((x > y) ? (x-y) : 0 )
|
||||
|
||||
__forceinline void gsHandler(const u8* pMem) {
|
||||
const int handler = pMem[8];
|
||||
if (handler >= 0x60 && handler < 0x63) {
|
||||
//DevCon::Status("GIF Tag Interrupt");
|
||||
s_GSHandlers[handler&0x3]((const u32*)pMem);
|
||||
}
|
||||
}
|
||||
|
||||
__forceinline int mtgsThreadObject::_gifTransferDummy(GIF_PATH pathidx, const u8* pMem, u32 size)
|
||||
{
|
||||
GIFPath& path = s_path[pathidx];
|
||||
u32 finish = (pathidx == GIF_PATH_1) ? 0x4000 : (size<<4);
|
||||
u32 oldSize = 0;
|
||||
u32 numRegs = 0;
|
||||
const u8* vuMemEnd = pMem + (size<<4); // End of VU Mem
|
||||
bool pathContinue = !!path.tag.nloop; // Continue From Last Transfer
|
||||
bool EOP = 0;
|
||||
bool hasRegAD = 0;
|
||||
size = 0;
|
||||
GIFPath& path = s_path[pathidx]; // Current Path
|
||||
const u8* vuMemEnd = pMem + (size<<4); // End of VU1 Mem
|
||||
if (pathidx==GIF_PATH_1) size = 0x4000; // VU1 mem size
|
||||
u32 startSize = size; // Start Size
|
||||
|
||||
while(!EOP && size < finish) {
|
||||
while (size > 0) {
|
||||
if (!path.tag.nloop) {
|
||||
|
||||
if(!pathContinue) {
|
||||
path.SetTag(pMem);
|
||||
path.PrepRegs(!path.tag.flg);
|
||||
incPmem(1);
|
||||
incTag(16, 1);
|
||||
|
||||
if (pathidx == GIF_PATH_3) {
|
||||
if (path.tag.flg&2) Path3progress = IMAGE_MODE;
|
||||
else Path3progress = TRANSFER_MODE;
|
||||
}
|
||||
}
|
||||
pathContinue = 0;
|
||||
oldSize = size;
|
||||
numRegs = ((path.tag.nreg-1)&0xf)+1;
|
||||
EOP = ((pathidx == GIF_PATH_2) ? 0 : path.tag.eop);
|
||||
|
||||
if (!path.tag.nloop || size >= finish) continue;
|
||||
|
||||
switch(path.tag.flg) {
|
||||
case GIF_FLG_PACKED:
|
||||
for (u32 i = 0; i < path.tag.nloop; i++) {
|
||||
for (u32 j = path.curreg; j < numRegs; j++) {
|
||||
if (path.regs[j] == 0x0e) {
|
||||
const int handler = pMem[8];
|
||||
if (handler >= 0x60 && handler < 0x63) {
|
||||
//DevCon::Status("GIF Tag Interrupt");
|
||||
s_GSHandlers[handler&0x3]((const u32*)pMem);
|
||||
}
|
||||
hasRegAD = 1;
|
||||
else {
|
||||
switch(path.tag.flg) {
|
||||
case GIF_FLG_PACKED:
|
||||
do {
|
||||
if (path.GetReg() == 0xe) {
|
||||
gsHandler(pMem);
|
||||
}
|
||||
incPmem(1);
|
||||
path.curreg = 0;
|
||||
if (size >= finish) goto endLoop;
|
||||
incTag(16, 1);
|
||||
} while(path.StepReg() && size > 0);
|
||||
break;
|
||||
case GIF_FLG_REGLIST:
|
||||
{
|
||||
u32 numRegs = (((path.tag.nreg-1)&0xf)+2)/2;
|
||||
if((numRegs * path.tag.nloop) <= size) {
|
||||
u32 temp1 = (numRegs - path.curreg);
|
||||
u32 temp2 = (numRegs * subVal(path.tag.nloop, 1));
|
||||
incTag((temp1*16), temp1);
|
||||
incTag((temp2*16), temp2);
|
||||
path.tag.nloop = 0;
|
||||
}
|
||||
if (!hasRegAD) { // Optimization: No Need to Loop
|
||||
incPmem(numRegs * subVal(path.tag.nloop));
|
||||
break;
|
||||
else {
|
||||
size *= 2;
|
||||
do { incTag(8, 1); }
|
||||
while(path.StepReg() && size > 0);
|
||||
|
||||
if (size & 1) { incTag(8, 1); }
|
||||
size /= 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GIF_FLG_REGLIST:
|
||||
numRegs = (numRegs + 1) / 2;
|
||||
incPmem((numRegs - path.curreg) * path.tag.nloop);
|
||||
incPmem((numRegs * subVal(path.tag.nloop)));
|
||||
case GIF_FLG_IMAGE:
|
||||
case GIF_FLG_IMAGE2:
|
||||
{
|
||||
int len = aMin(size, path.tag.nloop);
|
||||
incTag((len * 16), len);
|
||||
path.tag.nloop -= len;
|
||||
}
|
||||
break;
|
||||
case GIF_FLG_IMAGE:
|
||||
case GIF_FLG_IMAGE2:
|
||||
incPmem(path.tag.nloop);
|
||||
}
|
||||
}
|
||||
|
||||
if (path.tag.eop && !path.tag.nloop) {
|
||||
if (pathidx != GIF_PATH_2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
endLoop:
|
||||
|
||||
// This handles cases where we skipped too far ahead because of bulky IMAGE/REGLIST tags
|
||||
// or PACKED tags w/o RegA+D (they don't compare 'size < finish' every qwc).
|
||||
if (size > finish) size = finish;
|
||||
|
||||
// Sets information to resume partial transfers
|
||||
if (!EOP && path.tag.nloop && pathidx) {
|
||||
int diff = (size - oldSize) / 16;
|
||||
if (!(path.tag.flg&2)) { // PACKED/REGLIST
|
||||
path.curreg = (diff % path.tag.nloop);
|
||||
path.tag.nloop -= (diff / numRegs);
|
||||
}
|
||||
else path.tag.nloop -= diff;
|
||||
}
|
||||
else {
|
||||
path.curreg = 0;
|
||||
path.tag.nloop = 0;
|
||||
}
|
||||
size = (startSize - size);
|
||||
|
||||
if (pathidx == GIF_PATH_3) {
|
||||
gif->madr += size;
|
||||
gif->qwc -= (size/16);
|
||||
if (EOP) Path3progress = STOPPED_MODE;
|
||||
else if (path.tag.flg&2) Path3progress = IMAGE_MODE;
|
||||
else Path3progress = TRANSFER_MODE;
|
||||
if (path.tag.eop && !path.tag.nloop) {
|
||||
Path3progress = STOPPED_MODE;
|
||||
}
|
||||
gif->madr += size * 16;
|
||||
gif->qwc -= size;
|
||||
}
|
||||
|
||||
return (size / 16);
|
||||
return size;
|
||||
}
|
||||
|
||||
// Processes a GIFtag & packet, and throws out some gsIRQs as needed.
|
||||
|
|
Loading…
Reference in New Issue