GSdx: adapted to ref's changes to the image transfer, it was a bug in GSdx but not triggered by the old way, also the data overflow is now ignored, no idea what it may cause, look out for missing or fixed textures.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1005 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gabest11 2009-04-18 09:34:25 +00:00
parent f51e6b7d91
commit 94e2bd9409
4 changed files with 149 additions and 156 deletions

View File

@ -43,7 +43,6 @@ public:
GIFRegTRXDIR TRXDIR;
GIFRegTRXPOS TRXPOS;
GIFRegTRXREG TRXREG;
GIFRegTRXREG TRXREG2;
GSDrawingContext CTXT[2];
GSDrawingEnvironment()
@ -67,7 +66,6 @@ public:
memset(&TRXDIR, 0, sizeof(TRXDIR));
memset(&TRXPOS, 0, sizeof(TRXPOS));
memset(&TRXREG, 0, sizeof(TRXREG));
memset(&TRXREG2, 0, sizeof(TRXREG2));
CTXT[0].Reset();
CTXT[1].Reset();

View File

@ -896,7 +896,7 @@ void GSLocalMemory::WriteImage(int& tx, int& ty, BYTE* src, int len, GIFRegBITBL
if(TRXREG.RRW == 0) return;
int l = (int)TRXPOS.DSAX;
int r = (int)TRXREG.RRW;
int r = l + (int)TRXREG.RRW;
// finish the incomplete row first
@ -913,9 +913,7 @@ void GSLocalMemory::WriteImage(int& tx, int& ty, BYTE* src, int len, GIFRegBITBL
int srcpitch = (r - l) * trbpp >> 3;
int h = len / srcpitch;
// transfer width >= block width, and there is at least one full row
if(ra - la >= bsx && h > 0)
if(ra - la >= bsx && h > 0) // "transfer width" >= "block width" && there is at least one full row
{
BYTE* s = &src[-l * trbpp >> 3];
@ -1009,7 +1007,7 @@ void GSLocalMemory::WriteImage24(int& tx, int& ty, BYTE* src, int len, GIFRegBIT
DWORD bp = BITBLTBUF.DBP;
DWORD bw = BITBLTBUF.DBW;
int tw = TRXREG.RRW, srcpitch = (TRXREG.RRW - TRXPOS.DSAX) * 3;
int tw = TRXPOS.DSAX + TRXREG.RRW, srcpitch = TRXREG.RRW * 3;
int th = len / srcpitch;
bool aligned = IsTopLeftAligned(TRXPOS.DSAX, tx, ty, 8, 8);
@ -1035,6 +1033,7 @@ void GSLocalMemory::WriteImage24(int& tx, int& ty, BYTE* src, int len, GIFRegBIT
ty = th;
}
}
void GSLocalMemory::WriteImage8H(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG)
{
if(TRXREG.RRW == 0) return;
@ -1042,7 +1041,7 @@ void GSLocalMemory::WriteImage8H(int& tx, int& ty, BYTE* src, int len, GIFRegBIT
DWORD bp = BITBLTBUF.DBP;
DWORD bw = BITBLTBUF.DBW;
int tw = TRXREG.RRW, srcpitch = TRXREG.RRW - TRXPOS.DSAX;
int tw = TRXPOS.DSAX + TRXREG.RRW, srcpitch = TRXREG.RRW;
int th = len / srcpitch;
bool aligned = IsTopLeftAligned(TRXPOS.DSAX, tx, ty, 8, 8);
@ -1076,7 +1075,7 @@ void GSLocalMemory::WriteImage4HL(int& tx, int& ty, BYTE* src, int len, GIFRegBI
DWORD bp = BITBLTBUF.DBP;
DWORD bw = BITBLTBUF.DBW;
int tw = TRXREG.RRW, srcpitch = (TRXREG.RRW - TRXPOS.DSAX) / 2;
int tw = TRXPOS.DSAX + TRXREG.RRW, srcpitch = TRXREG.RRW / 2;
int th = len / srcpitch;
bool aligned = IsTopLeftAligned(TRXPOS.DSAX, tx, ty, 8, 8);
@ -1110,7 +1109,7 @@ void GSLocalMemory::WriteImage4HH(int& tx, int& ty, BYTE* src, int len, GIFRegBI
DWORD bp = BITBLTBUF.DBP;
DWORD bw = BITBLTBUF.DBW;
int tw = TRXREG.RRW, srcpitch = (TRXREG.RRW - TRXPOS.DSAX) / 2;
int tw = TRXPOS.DSAX + TRXREG.RRW, srcpitch = TRXREG.RRW / 2;
int th = len / srcpitch;
bool aligned = IsTopLeftAligned(TRXPOS.DSAX, tx, ty, 8, 8);
@ -1143,7 +1142,7 @@ void GSLocalMemory::WriteImage24Z(int& tx, int& ty, BYTE* src, int len, GIFRegBI
DWORD bp = BITBLTBUF.DBP;
DWORD bw = BITBLTBUF.DBW;
int tw = TRXREG.RRW, srcpitch = (TRXREG.RRW - TRXPOS.DSAX) * 3;
int tw = TRXPOS.DSAX + TRXREG.RRW, srcpitch = TRXREG.RRW * 3;
int th = len / srcpitch;
bool aligned = IsTopLeftAligned(TRXPOS.DSAX, tx, ty, 8, 8);
@ -1173,8 +1172,6 @@ void GSLocalMemory::WriteImageX(int& tx, int& ty, BYTE* src, int len, GIFRegBITB
{
if(len <= 0) return;
// if(ty >= (int)TRXREG.RRH) {ASSERT(0); return;}
BYTE* pb = (BYTE*)src;
WORD* pw = (WORD*)src;
DWORD* pd = (DWORD*)src;
@ -1186,7 +1183,7 @@ void GSLocalMemory::WriteImageX(int& tx, int& ty, BYTE* src, int len, GIFRegBITB
int x = tx;
int y = ty;
int sx = (int)TRXPOS.DSAX;
int ex = (int)TRXREG.RRW;
int ex = sx + (int)TRXREG.RRW;
switch(BITBLTBUF.DPSM)
{
@ -1351,8 +1348,6 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, BYTE* dst, int len, GIFRegBITBL
{
if(len <= 0) return;
// if(ty >= (int)TRXREG.RRH) {ASSERT(0); return;}
BYTE* pb = (BYTE*)dst;
WORD* pw = (WORD*)dst;
DWORD* pd = (DWORD*)dst;
@ -1364,7 +1359,7 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, BYTE* dst, int len, GIFRegBITBL
int x = tx;
int y = ty;
int sx = (int)TRXPOS.SSAX;
int ex = (int)TRXREG.RRW;
int ex = sx + (int)TRXREG.RRW;
switch(BITBLTBUF.SPSM)
{

View File

@ -52,7 +52,7 @@ GSState::GSState(BYTE* base, bool mt, void (*irq)())
m_sssize += sizeof(m_env.TRXDIR);
m_sssize += sizeof(m_env.TRXPOS);
m_sssize += sizeof(m_env.TRXREG);
m_sssize += sizeof(m_env.TRXREG2);
m_sssize += sizeof(m_env.TRXREG); // obsolete
for(int i = 0; i < 2; i++)
{
@ -77,8 +77,8 @@ GSState::GSState(BYTE* base, bool mt, void (*irq)())
m_sssize += sizeof(m_v.XYZ);
m_sssize += sizeof(m_v.FOG);
m_sssize += sizeof(m_x);
m_sssize += sizeof(m_y);
m_sssize += sizeof(m_tr.x);
m_sssize += sizeof(m_tr.y);
m_sssize += m_mem.m_vmsize;
m_sssize += (sizeof(m_path[0].tag) + sizeof(m_path[0].nreg)) * 3;
m_sssize += sizeof(m_q);
@ -93,11 +93,6 @@ GSState::GSState(BYTE* base, bool mt, void (*irq)())
// CSR->rREV = 0x20;
m_env.PRMODECONT.AC = 1;
m_x = m_y = 0;
m_bytes = 0;
m_maxbytes = 1024 * 1024 * 4;
m_buff = (BYTE*)_aligned_malloc(m_maxbytes, 16);
Reset();
ResetHandlers();
@ -105,7 +100,6 @@ GSState::GSState(BYTE* base, bool mt, void (*irq)())
GSState::~GSState()
{
_aligned_free(m_buff);
}
void GSState::Reset()
@ -916,13 +910,12 @@ void GSState::GIFRegHandlerTRXPOS(GIFReg* r)
void GSState::GIFRegHandlerTRXREG(GIFReg* r)
{
if(!(m_env.TRXREG == (GSVector4i)r->TRXREG).alltrue() || !(m_env.TRXREG2 == (GSVector4i)r->TRXREG).alltrue())
if(!(m_env.TRXREG == (GSVector4i)r->TRXREG).alltrue())
{
FlushWrite();
}
m_env.TRXREG = (GSVector4i)r->TRXREG;
m_env.TRXREG2 = (GSVector4i)r->TRXREG;
}
void GSState::GIFRegHandlerTRXDIR(GIFReg* r)
@ -934,16 +927,10 @@ void GSState::GIFRegHandlerTRXDIR(GIFReg* r)
switch(m_env.TRXDIR.XDIR)
{
case 0: // host -> local
m_x = m_env.TRXPOS.DSAX;
m_y = m_env.TRXPOS.DSAY;
m_env.TRXREG.RRW = m_x + m_env.TRXREG2.RRW;
m_env.TRXREG.RRH = m_y + m_env.TRXREG2.RRH;
m_tr.Init(m_env.TRXPOS.DSAX, m_env.TRXPOS.DSAY);
break;
case 1: // local -> host
m_x = m_env.TRXPOS.SSAX;
m_y = m_env.TRXPOS.SSAY;
m_env.TRXREG.RRW = m_x + m_env.TRXREG2.RRW;
m_env.TRXREG.RRH = m_y + m_env.TRXREG2.RRH;
m_tr.Init(m_env.TRXPOS.SSAX, m_env.TRXPOS.SSAY);
break;
case 2: // local -> local
Move();
@ -997,113 +984,66 @@ void GSState::Flush()
void GSState::FlushWrite()
{
FlushWrite(m_buff, m_bytes);
int len = m_tr.end - m_tr.start;
m_bytes = 0;
}
if(len <= 0) return;
void GSState::FlushWrite(BYTE* mem, int len)
{
if(len > 0)
{
int y = m_tr.y;
GSLocalMemory::writeImage wi = GSLocalMemory::m_psm[m_env.BITBLTBUF.DPSM].wi;
(m_mem.*wi)(m_tr.x, m_tr.y, &m_tr.buff[m_tr.start], len, m_env.BITBLTBUF, m_env.TRXPOS, m_env.TRXREG);
m_tr.start += len;
m_perfmon.Put(GSPerfMon::Swizzle, len);
CRect r;
r.left = m_env.TRXPOS.DSAX;
r.top = y;
r.right = r.left + m_env.TRXREG.RRW;
r.bottom = min(r.top + m_env.TRXREG.RRH, m_tr.x == r.left ? m_tr.y : m_tr.y + 1);
InvalidateVideoMem(m_env.BITBLTBUF, r);
/*
CSize bs = GSLocalMemory::m_psm[m_env.BITBLTBUF.DPSM].bs;
if((m_x & (bs.cx - 1)) || (m_env.TRXREG.RRW & (bs.cx - 1))
|| (m_y & (bs.cy - 1)) || (m_env.TRXREG.RRH & (bs.cy - 1))
|| m_x != m_env.TRXPOS.DSAX)
{
printf("*** [%d]: %d %d, %d %d %d %d\n", m_env.BITBLTBUF.DPSM, m_env.TRXPOS.DSAX, m_env.TRXPOS.DSAY, m_x, m_y, m_env.TRXREG.RRW, m_env.TRXREG.RRH);
}
if((len % ((m_env.TRXREG.RRW - m_x) * GSLocalMemory::m_psm[m_env.BITBLTBUF.DPSM].trbpp / 8)) != 0)
{
printf("*** [%d]: %d %d\n", m_env.BITBLTBUF.DPSM, len, ((m_env.TRXREG.RRW - m_x) * GSLocalMemory::m_psm[m_env.BITBLTBUF.DPSM].trbpp / 8));
}
static int n = 0;
CString str;
str.Format(_T("c:\\temp1\\[%04d]_%05x_%d_%d_%d_%d_%d_%d.bmp"),
n++, (int)m_env.BITBLTBUF.DBP, (int)m_env.BITBLTBUF.DBW, (int)m_env.BITBLTBUF.DPSM,
r.left, r.top, r.right, r.bottom);
m_mem.SaveBMP(str, m_env.BITBLTBUF.DBP, m_env.BITBLTBUF.DBW, m_env.BITBLTBUF.DPSM, r.right, r.bottom);
*/
int y = m_y;
GSLocalMemory::writeImage wi = GSLocalMemory::m_psm[m_env.BITBLTBUF.DPSM].wi;
(m_mem.*wi)(m_x, m_y, mem, len, m_env.BITBLTBUF, m_env.TRXPOS, m_env.TRXREG);
m_perfmon.Put(GSPerfMon::Swizzle, len);
//ASSERT(m_env.TRXREG.RRH >= m_y - y);
CRect r;
r.left = m_env.TRXPOS.DSAX;
r.top = y;
r.right = m_env.TRXREG.RRW;
r.bottom = min(m_x == m_env.TRXPOS.DSAX ? m_y : m_y + 1, m_env.TRXREG.RRH);
InvalidateVideoMem(m_env.BITBLTBUF, r);
/*
static int n = 0;
CString str;
str.Format(_T("c:\\temp1\\[%04d]_%05x_%d_%d_%d_%d_%d_%d.bmp"),
n++, (int)m_env.BITBLTBUF.DBP, (int)m_env.BITBLTBUF.DBW, (int)m_env.BITBLTBUF.DPSM,
r.left, r.top, r.right, r.bottom);
m_mem.SaveBMP(str, m_env.BITBLTBUF.DBP, m_env.BITBLTBUF.DBW, m_env.BITBLTBUF.DPSM, r.right, r.bottom);
*/
}
}
//
void GSState::Write(BYTE* mem, int len)
{
/*
TRACE(_T("Write len=%d DBP=%05x DBW=%d DPSM=%d DSAX=%d DSAY=%d RRW=%d RRH=%d\n"),
len, (int)m_env.BITBLTBUF.DBP, (int)m_env.BITBLTBUF.DBW, (int)m_env.BITBLTBUF.DPSM,
(int)m_env.TRXPOS.DSAX, (int)m_env.TRXPOS.DSAY,
(int)m_env.TRXREG.RRW, (int)m_env.TRXREG.RRH);
*/
if(len == 0) return;
int dx = m_env.TRXPOS.DSAX;
int dy = m_env.TRXPOS.DSAY;
int w = m_env.TRXREG.RRW;
int h = m_env.TRXREG.RRH;
if(m_y >= m_env.TRXREG.RRH) return; // TODO: handle overflow during writing data too (just chop len below somewhere)
// TRACE(_T("Write len=%d DBP=%05x DBW=%d DPSM=%d DSAX=%d DSAY=%d RRW=%d RRH=%d\n"), len, (int)m_env.BITBLTBUF.DBP, (int)m_env.BITBLTBUF.DBW, (int)m_env.BITBLTBUF.DPSM, dx, dy, w, h);
// TODO: hmmmm
if(!m_tr.Update(w, h, GSLocalMemory::m_psm[m_env.BITBLTBUF.DPSM].trbpp, len))
{
return;
}
if(PRIM->TME && (m_env.BITBLTBUF.DBP == m_context->TEX0.TBP0 || m_env.BITBLTBUF.DBP == m_context->TEX0.CBP))
memcpy(&m_tr.buff[m_tr.end], mem, len);
m_tr.end += len;
if(PRIM->TME && (m_env.BITBLTBUF.DBP == m_context->TEX0.TBP0 || m_env.BITBLTBUF.DBP == m_context->TEX0.CBP)) // TODO: hmmmm
{
FlushPrim();
}
int bpp = GSLocalMemory::m_psm[m_env.BITBLTBUF.DPSM].trbpp;
int pitch = (m_env.TRXREG.RRW - m_env.TRXPOS.DSAX) * bpp >> 3;
if(pitch <= 0) {ASSERT(0); return;}
int height = len / pitch;
if(height > m_env.TRXREG.RRH - m_env.TRXPOS.DSAY)
if(m_tr.end >= m_tr.total)
{
height = m_env.TRXREG.RRH - m_env.TRXPOS.DSAY;
len = height * pitch;
}
if(m_bytes > 0 || height < m_env.TRXREG.RRH - m_env.TRXPOS.DSAY)
{
ASSERT(len <= m_maxbytes); // more than 4mb into a 4mb local mem doesn't make sense
len = min(m_maxbytes, len);
if(m_bytes + len > m_maxbytes)
{
FlushWrite();
}
memcpy(&m_buff[m_bytes], mem, len);
m_bytes += len;
}
else
{
FlushWrite(mem, len);
FlushWrite();
}
m_mem.m_clut.Invalidate();
@ -1111,25 +1051,26 @@ void GSState::Write(BYTE* mem, int len)
void GSState::Read(BYTE* mem, int len)
{
/*
TRACE(_T("Read len=%d SBP=%05x SBW=%d SPSM=%d SSAX=%d SSAY=%d RRW=%d RRH=%d\n"),
len, (int)m_env.BITBLTBUF.SBP, (int)m_env.BITBLTBUF.SBW, (int)m_env.BITBLTBUF.SPSM,
(int)m_env.TRXPOS.SSAX, (int)m_env.TRXPOS.SSAY,
(int)m_env.TRXREG.RRW, (int)m_env.TRXREG.RRH);
*/
if(len <= 0) return;
if(m_y >= (int)m_env.TRXREG.RRH) {ASSERT(0); return;}
int sx = m_env.TRXPOS.SSAX;
int sy = m_env.TRXPOS.SSAY;
int w = m_env.TRXREG.RRW;
int h = m_env.TRXREG.RRH;
if(m_x == m_env.TRXPOS.SSAX && m_y == m_env.TRXPOS.SSAY)
// TRACE(_T("Read len=%d SBP=%05x SBW=%d SPSM=%d SSAX=%d SSAY=%d RRW=%d RRH=%d\n"), len, (int)m_env.BITBLTBUF.SBP, (int)m_env.BITBLTBUF.SBW, (int)m_env.BITBLTBUF.SPSM, sx, sy, w, h);
if(!m_tr.Update(w, h, GSLocalMemory::m_psm[m_env.BITBLTBUF.SPSM].trbpp, len))
{
CRect r(m_env.TRXPOS.SSAX, m_env.TRXPOS.SSAY, m_env.TRXREG.RRW, m_env.TRXREG.RRH);
InvalidateLocalMem(m_env.BITBLTBUF, r);
return;
}
// TODO
if(m_tr.x == sx && m_tr.y == sy)
{
InvalidateLocalMem(m_env.BITBLTBUF, CRect(CPoint(sx, sy), CSize(w, h)));
}
m_mem.ReadImageX(m_x, m_y, mem, len, m_env.BITBLTBUF, m_env.TRXPOS, m_env.TRXREG);
m_mem.ReadImageX(m_tr.x, m_tr.y, mem, len, m_env.BITBLTBUF, m_env.TRXPOS, m_env.TRXREG);
}
void GSState::Move()
@ -1138,19 +1079,20 @@ void GSState::Move()
// guitar hero copies the far end of the board to do a similar blend too
int sx = m_env.TRXPOS.SSAX;
int dx = m_env.TRXPOS.DSAX;
int sy = m_env.TRXPOS.SSAY;
int dx = m_env.TRXPOS.DSAX;
int dy = m_env.TRXPOS.DSAY;
int w = m_env.TRXREG.RRW;
int h = m_env.TRXREG.RRH;
int xinc = 1;
int yinc = 1;
InvalidateLocalMem(m_env.BITBLTBUF, CRect(CPoint(sx, sy), CSize(w, h)));
InvalidateVideoMem(m_env.BITBLTBUF, CRect(CPoint(dx, dy), CSize(w, h)));
if(sx < dx) sx += w-1, dx += w-1, xinc = -1;
if(sy < dy) sy += h-1, dy += h-1, yinc = -1;
int xinc = 1;
int yinc = 1;
if(sx < dx) {sx += w - 1; dx += w - 1; xinc = -1;}
if(sy < dy) {sy += h - 1; dy += h - 1; yinc = -1;}
/*
GSLocalMemory::readPixel rp = GSLocalMemory::m_psm[m_env.BITBLTBUF.SPSM].rp;
@ -1166,7 +1108,7 @@ void GSState::Move()
if(m_env.BITBLTBUF.SPSM == PSM_PSMCT32 && m_env.BITBLTBUF.DPSM == PSM_PSMCT32)
{
for(int y = 0; y < h; y++, sy += yinc, dy += yinc, sx -= xinc*w, dx -= xinc*w)
for(int y = 0; y < h; y++, sy += yinc, dy += yinc, sx -= xinc * w, dx -= xinc * w)
{
DWORD sbase = spsm.pa(0, sy, m_env.BITBLTBUF.SBP, m_env.BITBLTBUF.SBW);
int* soffset = spsm.rowOffset[sy & 7];
@ -1182,7 +1124,7 @@ void GSState::Move()
}
else
{
for(int y = 0; y < h; y++, sy += yinc, dy += yinc, sx -= xinc*w, dx -= xinc*w)
for(int y = 0; y < h; y++, sy += yinc, dy += yinc, sx -= xinc * w, dx -= xinc * w)
{
DWORD sbase = spsm.pa(0, sy, m_env.BITBLTBUF.SBP, m_env.BITBLTBUF.SBW);
int* soffset = spsm.rowOffset[sy & 7];
@ -1461,7 +1403,7 @@ int GSState::Freeze(GSFreezeData* fd, bool sizeonly)
WriteState(data, &m_env.TRXDIR);
WriteState(data, &m_env.TRXPOS);
WriteState(data, &m_env.TRXREG);
WriteState(data, &m_env.TRXREG2);
WriteState(data, &m_env.TRXREG); // obsolete
for(int i = 0; i < 2; i++)
{
@ -1485,8 +1427,8 @@ int GSState::Freeze(GSFreezeData* fd, bool sizeonly)
WriteState(data, &m_v.UV);
WriteState(data, &m_v.XYZ);
WriteState(data, &m_v.FOG);
WriteState(data, &m_x);
WriteState(data, &m_y);
WriteState(data, &m_tr.x);
WriteState(data, &m_tr.y);
WriteState(data, m_mem.m_vm8, m_mem.m_vmsize);
for(int i = 0; i < 3; i++)
@ -1542,7 +1484,7 @@ int GSState::Defrost(const GSFreezeData* fd)
ReadState(&m_env.TRXDIR, data);
ReadState(&m_env.TRXPOS, data);
ReadState(&m_env.TRXREG, data);
ReadState(&m_env.TRXREG2, data);
ReadState(&m_env.TRXREG, data); // obsolete
for(int i = 0; i < 2; i++)
{
@ -1574,10 +1516,12 @@ int GSState::Defrost(const GSFreezeData* fd)
ReadState(&m_v.UV, data);
ReadState(&m_v.XYZ, data);
ReadState(&m_v.FOG, data);
ReadState(&m_x, data);
ReadState(&m_y, data);
ReadState(&m_tr.x, data);
ReadState(&m_tr.y, data);
ReadState(m_mem.m_vm8, data, m_mem.m_vmsize);
m_tr.total = 0; // TODO: restore transfer state
for(int i = 0; i < 3; i++)
{
ReadState(&m_path[i].tag, data);
@ -1670,6 +1614,53 @@ void GSState::SetFrameSkip(int frameskip)
}
}
// GSTransferBuffer
GSState::GSTransferBuffer::GSTransferBuffer()
{
x = y = 0;
start = end = total = 0;
buff = (BYTE*)_aligned_malloc(1024 * 1024 * 4, 16);
}
GSState::GSTransferBuffer::~GSTransferBuffer()
{
_aligned_free(buff);
}
void GSState::GSTransferBuffer::Init(int tx, int ty)
{
x = tx;
y = ty;
total = 0;
}
bool GSState::GSTransferBuffer::Update(int tw, int th, int bpp, int& len)
{
if(total == 0)
{
start = end = 0;
total = min((tw * bpp >> 3) * th, 1024 * 1024 * 4);
overflow = false;
}
int remaining = total - end;
if(len > remaining)
{
if(!overflow)
{
overflow = true;
// printf("GS transfer overflow\n");
}
len = remaining;
}
return len > 0;
}
// hacks
struct GSFrameInfo

View File

@ -113,13 +113,22 @@ class GSState : public GSAlignedClass<16>
void (*m_irq)();
bool m_path3hack;
int m_x, m_y;
int m_bytes;
int m_maxbytes;
BYTE* m_buff;
struct GSTransferBuffer
{
int x, y;
int start, end, total;
bool overflow;
BYTE* buff;
GSTransferBuffer();
virtual ~GSTransferBuffer();
void Init(int tx, int ty);
bool Update(int tw, int th, int bpp, int& len);
} m_tr;
void FlushWrite();
void FlushWrite(BYTE* mem, int len);
protected:
bool IsBadFrame(int& skip);