mirror of https://github.com/PCSX2/pcsx2.git
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:
parent
f51e6b7d91
commit
94e2bd9409
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue