mirror of https://github.com/PCSX2/pcsx2.git
newGif: send complete gs primitive packets to the gs plugin even if eop wasn't detected. this is needed for games that do GS->EE downloads to make sure the gs plugin is up-to-date with the sent gif data.
fixes Bleach bankai problem, and probably other games (wizardry/growlancer 3) but haven't tested... Also removed a vif FlushA hack that used to be needed for tekken 4/gitaroo man but not anymore... git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4829 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
bfbf403bf4
commit
d8149fdb8b
|
@ -268,10 +268,12 @@ void __fastcall gsWrite64_page_01( u32 mem, const mem64_t* value )
|
||||||
|
|
||||||
GUNIT_LOG("GIF - busdir");
|
GUNIT_LOG("GIF - busdir");
|
||||||
gifRegs.stat.DIR = value[0] & 1;
|
gifRegs.stat.DIR = value[0] & 1;
|
||||||
|
|
||||||
if (gifRegs.stat.DIR) { // Assume will do local->host transfer?
|
if (gifRegs.stat.DIR) { // Assume will do local->host transfer?
|
||||||
gifRegs.stat.OPH = true; // Is OPH set on local->host transfers?
|
gifRegs.stat.OPH = true; // Is OPH set on local->host transfers?
|
||||||
DevCon.WriteLn("Busdir - Local->Host Transfer");
|
DevCon.WriteLn("Busdir - GS->EE Download");
|
||||||
}
|
}
|
||||||
|
else DevCon.WriteLn("Busdir - EE->GS Upload");
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
// BUSDIR INSANITY !! MTGS FLUSH NEEDED
|
// BUSDIR INSANITY !! MTGS FLUSH NEEDED
|
||||||
|
|
|
@ -28,9 +28,9 @@ bool Gif_HandlerAD(u8* pMem) {
|
||||||
u32* data = (u32*)pMem;
|
u32* data = (u32*)pMem;
|
||||||
if (reg == 0x50) vif1.BITBLTBUF._u64 = *(u64*)pMem;
|
if (reg == 0x50) vif1.BITBLTBUF._u64 = *(u64*)pMem;
|
||||||
elif (reg == 0x52) vif1.TRXREG._u64 = *(u64*)pMem;
|
elif (reg == 0x52) vif1.TRXREG._u64 = *(u64*)pMem;
|
||||||
elif (reg == 0x53) {
|
elif (reg == 0x53) { // TRXDIR
|
||||||
if ((pMem[0] & 3) == 1) { // local -> host
|
if ((pMem[0] & 3) == 1) { // local -> host
|
||||||
u8 bpp = 32;
|
u8 bpp = 32; // Onimusha does TRXDIR without BLTDIVIDE first, assume 32bit
|
||||||
switch(vif1.BITBLTBUF.SPSM & 7) {
|
switch(vif1.BITBLTBUF.SPSM & 7) {
|
||||||
case 0: bpp = 32; break;
|
case 0: bpp = 32; break;
|
||||||
case 1: bpp = 24; break;
|
case 1: bpp = 24; break;
|
||||||
|
|
|
@ -217,7 +217,7 @@ struct Gif_Path {
|
||||||
state = (GIF_PATH_STATE)(gifTag.tag.FLG + 1);
|
state = (GIF_PATH_STATE)(gifTag.tag.FLG + 1);
|
||||||
|
|
||||||
// We don't have enough data for a complete GS packet
|
// We don't have enough data for a complete GS packet
|
||||||
if (curOffset + 16 + gifTag.len > curSize) {
|
if(!gifTag.hasAD && curOffset + 16 + gifTag.len > curSize) {
|
||||||
gifTag.isValid = false; // So next time we test again
|
gifTag.isValid = false; // So next time we test again
|
||||||
return gsPack;
|
return gsPack;
|
||||||
}
|
}
|
||||||
|
@ -229,6 +229,7 @@ struct Gif_Path {
|
||||||
if (gifTag.hasAD) { // Only can be true if GIF_FLG_PACKED
|
if (gifTag.hasAD) { // Only can be true if GIF_FLG_PACKED
|
||||||
bool dblSIGNAL = false;
|
bool dblSIGNAL = false;
|
||||||
while(gifTag.nLoop && !dblSIGNAL) {
|
while(gifTag.nLoop && !dblSIGNAL) {
|
||||||
|
if (curOffset >= curSize) return gsPack; // Exit Early
|
||||||
if (gifTag.curReg() == GIF_REG_A_D) {
|
if (gifTag.curReg() == GIF_REG_A_D) {
|
||||||
dblSIGNAL = Gif_HandlerAD(&buffer[curOffset]);
|
dblSIGNAL = Gif_HandlerAD(&buffer[curOffset]);
|
||||||
}
|
}
|
||||||
|
@ -318,7 +319,7 @@ struct Gif_Unit {
|
||||||
if (size == 0) { GUNIT_WARN("Gif Unit - Size == 0"); return 0; }
|
if (size == 0) { GUNIT_WARN("Gif Unit - Size == 0"); return 0; }
|
||||||
if(!CanDoGif()) { GUNIT_WARN("Gif Unit - PSE Set or Dir = GS to EE"); }
|
if(!CanDoGif()) { GUNIT_WARN("Gif Unit - PSE Set or Dir = GS to EE"); }
|
||||||
pxAssertDev((stat.APATH==0) || checkPaths(1,1,1), "Gif Unit - APATH wasn't cleared?");
|
pxAssertDev((stat.APATH==0) || checkPaths(1,1,1), "Gif Unit - APATH wasn't cleared?");
|
||||||
lastTranType = tranType; // Used for Vif FlushA hack
|
lastTranType = tranType;
|
||||||
|
|
||||||
if (tranType == GIF_TRANS_FIFO) {
|
if (tranType == GIF_TRANS_FIFO) {
|
||||||
if(!CanDoPath3()) DevCon.Warning("Gif Unit - Path 3 FIFO transfer while !CanDoPath3()");
|
if(!CanDoPath3()) DevCon.Warning("Gif Unit - Path 3 FIFO transfer while !CanDoPath3()");
|
||||||
|
@ -368,31 +369,37 @@ struct Gif_Unit {
|
||||||
stat.OPH = 1;
|
stat.OPH = 1;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if (stat.APATH) { // Some Transfer is happening
|
if (stat.APATH) { // Some Transfer is happening
|
||||||
GS_Packet gsPack = gifPath[stat.APATH-1].ExecuteGSPacket();
|
Gif_Path& path = gifPath[stat.APATH-1];
|
||||||
|
GS_Packet gsPack = path.ExecuteGSPacket();
|
||||||
if(!gsPack.done) {
|
if(!gsPack.done) {
|
||||||
if (stat.APATH == 3 && CanDoP3Slice() && !gsSIGNAL.queued) {
|
if (stat.APATH == 3 && CanDoP3Slice() && !gsSIGNAL.queued) {
|
||||||
if(!didPath3 && checkPaths(1,1,0)) { // Path3 slicing
|
if(!didPath3 && checkPaths(1,1,0)) { // Path3 slicing
|
||||||
didPath3 = true;
|
didPath3 = true;
|
||||||
stat.APATH = 0;
|
stat.APATH = 0;
|
||||||
stat.IP3 = 1;
|
stat.IP3 = 1;
|
||||||
GUNIT_LOG(Color_Magenta, "Gif Unit - Path 3 slicing arbitration");
|
//DevCon.WriteLn(Color_Magenta, "Gif Unit - Path 3 slicing arbitration");
|
||||||
if (gsPack.size > 16) { // Packet had other tags which we already processed
|
if (gsPack.size > 16) { // Packet had other tags which we already processed
|
||||||
Gif_Path& p3 = gifPath[GIF_PATH_3];
|
u32 subOffset = path.gifTag.isValid ? 16 : 0; // if isValid, image-primitive not finished
|
||||||
u32 subOffset = p3.gifTag.isValid ? 16 : 0; // if isValid, image-primitive not finished
|
|
||||||
gsPack.size -= subOffset; // Remove the image-tag (should be last thing read)
|
gsPack.size -= subOffset; // Remove the image-tag (should be last thing read)
|
||||||
AddCompletedGSPacket(gsPack, GIF_PATH_3); // Consider current packet complete
|
AddCompletedGSPacket(gsPack, GIF_PATH_3); // Consider current packet complete
|
||||||
p3.gsPack.Reset(); // Reset gs packet info
|
path.gsPack.Reset(); // Reset gs packet info
|
||||||
p3.curOffset -= subOffset; // Start the next GS packet at the image-tag
|
path.curOffset -= subOffset; // Start the next GS packet at the image-tag
|
||||||
p3.gsPack.offset = p3.curOffset; // Set to image-tag
|
path.gsPack.offset = path.curOffset; // Set to image-tag
|
||||||
p3.gifTag.isValid = false; // Reload tag next ExecuteGSPacket()
|
path.gifTag.isValid = false; // Reload tag next ExecuteGSPacket()
|
||||||
pxAssert((s32)p3.curOffset >= 0);
|
pxAssert((s32)path.curOffset >= 0);
|
||||||
pxAssert(p3.state == GIF_PATH_IMAGE);
|
pxAssert(path.state == GIF_PATH_IMAGE);
|
||||||
GUNIT_LOG(Color_Magenta, "Gif Unit - Sending path 3 sliced gs packet!");
|
DevCon.WriteLn(Color_Magenta, "Gif Unit - Sending path 3 sliced gs packet!");
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//DevCon.WriteLn("Incomplete GS Packet for path %d", stat.APATH);
|
// Send complete gs primitive packet(s)
|
||||||
|
if (gsPack.size && !path.gifTag.isValid) {
|
||||||
|
AddCompletedGSPacket(gsPack, (GIF_PATH)(stat.APATH-1));
|
||||||
|
path.gsPack.size = 0;
|
||||||
|
path.gsPack.offset = path.curOffset;
|
||||||
|
}
|
||||||
|
//DevCon.WriteLn("Incomplete GS Packet for path %d, size=%d", stat.APATH, gsPack.size);
|
||||||
break; // Not finished with GS packet
|
break; // Not finished with GS packet
|
||||||
}
|
}
|
||||||
//DevCon.WriteLn("Adding GS Packet for path %d", stat.APATH);
|
//DevCon.WriteLn("Adding GS Packet for path %d", stat.APATH);
|
||||||
|
|
|
@ -74,9 +74,20 @@ void vif1TransferToMemory()
|
||||||
size = min((u32)vif1ch.qwc, vif1.GSLastDownloadSize);
|
size = min((u32)vif1ch.qwc, vif1.GSLastDownloadSize);
|
||||||
const u128* pMemEnd = pMem + vif1.GSLastDownloadSize;
|
const u128* pMemEnd = pMem + vif1.GSLastDownloadSize;
|
||||||
|
|
||||||
|
if (size) {
|
||||||
|
// Checking if any crazy game does a partial
|
||||||
|
// gs primitive and then does a gs download...
|
||||||
|
Gif_Path& p1 = gifUnit.gifPath[GIF_PATH_1];
|
||||||
|
Gif_Path& p2 = gifUnit.gifPath[GIF_PATH_2];
|
||||||
|
Gif_Path& p3 = gifUnit.gifPath[GIF_PATH_3];
|
||||||
|
pxAssert(p1.isDone() || !p1.gifTag.isValid);
|
||||||
|
pxAssert(p2.isDone() || !p2.gifTag.isValid);
|
||||||
|
pxAssert(p3.isDone() || !p3.gifTag.isValid);
|
||||||
|
}
|
||||||
|
|
||||||
if (GSreadFIFO2 == NULL)
|
if (GSreadFIFO2 == NULL)
|
||||||
{
|
{
|
||||||
for (;size > 0; --size)
|
for ( ; size > 0; --size)
|
||||||
{
|
{
|
||||||
GetMTGS().WaitGS();
|
GetMTGS().WaitGS();
|
||||||
GSreadFIFO((u64*)pMem);
|
GSreadFIFO((u64*)pMem);
|
||||||
|
|
|
@ -169,7 +169,7 @@ vifOp(vifCode_FlushA) {
|
||||||
GUNIT_WARN("Vif FlushA - Getting path3 to finish!");
|
GUNIT_WARN("Vif FlushA - Getting path3 to finish!");
|
||||||
if (gifUnit.lastTranType == GIF_TRANS_FIFO
|
if (gifUnit.lastTranType == GIF_TRANS_FIFO
|
||||||
&& p3.state != GIF_PATH_IDLE && !p3.hasDataRemaining()) {
|
&& p3.state != GIF_PATH_IDLE && !p3.hasDataRemaining()) {
|
||||||
p3.state = GIF_PATH_IDLE; // Hack: Tekken 4 and Gitaroo Man need this to boot...
|
//p3.state= GIF_PATH_IDLE; // Does any game need this anymore?
|
||||||
DevCon.Warning("Vif FlushA - path3 has no more data, but didn't EOP");
|
DevCon.Warning("Vif FlushA - path3 has no more data, but didn't EOP");
|
||||||
}
|
}
|
||||||
else { // Path 3 hasn't finished its current gs packet
|
else { // Path 3 hasn't finished its current gs packet
|
||||||
|
|
Loading…
Reference in New Issue