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;
|
GIFRegTRXDIR TRXDIR;
|
||||||
GIFRegTRXPOS TRXPOS;
|
GIFRegTRXPOS TRXPOS;
|
||||||
GIFRegTRXREG TRXREG;
|
GIFRegTRXREG TRXREG;
|
||||||
GIFRegTRXREG TRXREG2;
|
|
||||||
GSDrawingContext CTXT[2];
|
GSDrawingContext CTXT[2];
|
||||||
|
|
||||||
GSDrawingEnvironment()
|
GSDrawingEnvironment()
|
||||||
|
@ -67,7 +66,6 @@ public:
|
||||||
memset(&TRXDIR, 0, sizeof(TRXDIR));
|
memset(&TRXDIR, 0, sizeof(TRXDIR));
|
||||||
memset(&TRXPOS, 0, sizeof(TRXPOS));
|
memset(&TRXPOS, 0, sizeof(TRXPOS));
|
||||||
memset(&TRXREG, 0, sizeof(TRXREG));
|
memset(&TRXREG, 0, sizeof(TRXREG));
|
||||||
memset(&TRXREG2, 0, sizeof(TRXREG2));
|
|
||||||
|
|
||||||
CTXT[0].Reset();
|
CTXT[0].Reset();
|
||||||
CTXT[1].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;
|
if(TRXREG.RRW == 0) return;
|
||||||
|
|
||||||
int l = (int)TRXPOS.DSAX;
|
int l = (int)TRXPOS.DSAX;
|
||||||
int r = (int)TRXREG.RRW;
|
int r = l + (int)TRXREG.RRW;
|
||||||
|
|
||||||
// finish the incomplete row first
|
// 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 srcpitch = (r - l) * trbpp >> 3;
|
||||||
int h = len / srcpitch;
|
int h = len / srcpitch;
|
||||||
|
|
||||||
// transfer width >= block width, and there is at least one full row
|
if(ra - la >= bsx && h > 0) // "transfer width" >= "block width" && there is at least one full row
|
||||||
|
|
||||||
if(ra - la >= bsx && h > 0)
|
|
||||||
{
|
{
|
||||||
BYTE* s = &src[-l * trbpp >> 3];
|
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 bp = BITBLTBUF.DBP;
|
||||||
DWORD bw = BITBLTBUF.DBW;
|
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;
|
int th = len / srcpitch;
|
||||||
|
|
||||||
bool aligned = IsTopLeftAligned(TRXPOS.DSAX, tx, ty, 8, 8);
|
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;
|
ty = th;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSLocalMemory::WriteImage8H(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG)
|
void GSLocalMemory::WriteImage8H(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG)
|
||||||
{
|
{
|
||||||
if(TRXREG.RRW == 0) return;
|
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 bp = BITBLTBUF.DBP;
|
||||||
DWORD bw = BITBLTBUF.DBW;
|
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;
|
int th = len / srcpitch;
|
||||||
|
|
||||||
bool aligned = IsTopLeftAligned(TRXPOS.DSAX, tx, ty, 8, 8);
|
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 bp = BITBLTBUF.DBP;
|
||||||
DWORD bw = BITBLTBUF.DBW;
|
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;
|
int th = len / srcpitch;
|
||||||
|
|
||||||
bool aligned = IsTopLeftAligned(TRXPOS.DSAX, tx, ty, 8, 8);
|
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 bp = BITBLTBUF.DBP;
|
||||||
DWORD bw = BITBLTBUF.DBW;
|
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;
|
int th = len / srcpitch;
|
||||||
|
|
||||||
bool aligned = IsTopLeftAligned(TRXPOS.DSAX, tx, ty, 8, 8);
|
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 bp = BITBLTBUF.DBP;
|
||||||
DWORD bw = BITBLTBUF.DBW;
|
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;
|
int th = len / srcpitch;
|
||||||
|
|
||||||
bool aligned = IsTopLeftAligned(TRXPOS.DSAX, tx, ty, 8, 8);
|
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(len <= 0) return;
|
||||||
|
|
||||||
// if(ty >= (int)TRXREG.RRH) {ASSERT(0); return;}
|
|
||||||
|
|
||||||
BYTE* pb = (BYTE*)src;
|
BYTE* pb = (BYTE*)src;
|
||||||
WORD* pw = (WORD*)src;
|
WORD* pw = (WORD*)src;
|
||||||
DWORD* pd = (DWORD*)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 x = tx;
|
||||||
int y = ty;
|
int y = ty;
|
||||||
int sx = (int)TRXPOS.DSAX;
|
int sx = (int)TRXPOS.DSAX;
|
||||||
int ex = (int)TRXREG.RRW;
|
int ex = sx + (int)TRXREG.RRW;
|
||||||
|
|
||||||
switch(BITBLTBUF.DPSM)
|
switch(BITBLTBUF.DPSM)
|
||||||
{
|
{
|
||||||
|
@ -1351,8 +1348,6 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, BYTE* dst, int len, GIFRegBITBL
|
||||||
{
|
{
|
||||||
if(len <= 0) return;
|
if(len <= 0) return;
|
||||||
|
|
||||||
// if(ty >= (int)TRXREG.RRH) {ASSERT(0); return;}
|
|
||||||
|
|
||||||
BYTE* pb = (BYTE*)dst;
|
BYTE* pb = (BYTE*)dst;
|
||||||
WORD* pw = (WORD*)dst;
|
WORD* pw = (WORD*)dst;
|
||||||
DWORD* pd = (DWORD*)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 x = tx;
|
||||||
int y = ty;
|
int y = ty;
|
||||||
int sx = (int)TRXPOS.SSAX;
|
int sx = (int)TRXPOS.SSAX;
|
||||||
int ex = (int)TRXREG.RRW;
|
int ex = sx + (int)TRXREG.RRW;
|
||||||
|
|
||||||
switch(BITBLTBUF.SPSM)
|
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.TRXDIR);
|
||||||
m_sssize += sizeof(m_env.TRXPOS);
|
m_sssize += sizeof(m_env.TRXPOS);
|
||||||
m_sssize += sizeof(m_env.TRXREG);
|
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++)
|
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.XYZ);
|
||||||
m_sssize += sizeof(m_v.FOG);
|
m_sssize += sizeof(m_v.FOG);
|
||||||
|
|
||||||
m_sssize += sizeof(m_x);
|
m_sssize += sizeof(m_tr.x);
|
||||||
m_sssize += sizeof(m_y);
|
m_sssize += sizeof(m_tr.y);
|
||||||
m_sssize += m_mem.m_vmsize;
|
m_sssize += m_mem.m_vmsize;
|
||||||
m_sssize += (sizeof(m_path[0].tag) + sizeof(m_path[0].nreg)) * 3;
|
m_sssize += (sizeof(m_path[0].tag) + sizeof(m_path[0].nreg)) * 3;
|
||||||
m_sssize += sizeof(m_q);
|
m_sssize += sizeof(m_q);
|
||||||
|
@ -93,11 +93,6 @@ GSState::GSState(BYTE* base, bool mt, void (*irq)())
|
||||||
// CSR->rREV = 0x20;
|
// CSR->rREV = 0x20;
|
||||||
m_env.PRMODECONT.AC = 1;
|
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();
|
Reset();
|
||||||
|
|
||||||
ResetHandlers();
|
ResetHandlers();
|
||||||
|
@ -105,7 +100,6 @@ GSState::GSState(BYTE* base, bool mt, void (*irq)())
|
||||||
|
|
||||||
GSState::~GSState()
|
GSState::~GSState()
|
||||||
{
|
{
|
||||||
_aligned_free(m_buff);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSState::Reset()
|
void GSState::Reset()
|
||||||
|
@ -916,13 +910,12 @@ void GSState::GIFRegHandlerTRXPOS(GIFReg* r)
|
||||||
|
|
||||||
void GSState::GIFRegHandlerTRXREG(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();
|
FlushWrite();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_env.TRXREG = (GSVector4i)r->TRXREG;
|
m_env.TRXREG = (GSVector4i)r->TRXREG;
|
||||||
m_env.TRXREG2 = (GSVector4i)r->TRXREG;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSState::GIFRegHandlerTRXDIR(GIFReg* r)
|
void GSState::GIFRegHandlerTRXDIR(GIFReg* r)
|
||||||
|
@ -934,16 +927,10 @@ void GSState::GIFRegHandlerTRXDIR(GIFReg* r)
|
||||||
switch(m_env.TRXDIR.XDIR)
|
switch(m_env.TRXDIR.XDIR)
|
||||||
{
|
{
|
||||||
case 0: // host -> local
|
case 0: // host -> local
|
||||||
m_x = m_env.TRXPOS.DSAX;
|
m_tr.Init(m_env.TRXPOS.DSAX, m_env.TRXPOS.DSAY);
|
||||||
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;
|
|
||||||
break;
|
break;
|
||||||
case 1: // local -> host
|
case 1: // local -> host
|
||||||
m_x = m_env.TRXPOS.SSAX;
|
m_tr.Init(m_env.TRXPOS.SSAX, m_env.TRXPOS.SSAY);
|
||||||
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;
|
|
||||||
break;
|
break;
|
||||||
case 2: // local -> local
|
case 2: // local -> local
|
||||||
Move();
|
Move();
|
||||||
|
@ -997,113 +984,66 @@ void GSState::Flush()
|
||||||
|
|
||||||
void GSState::FlushWrite()
|
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)
|
int y = m_tr.y;
|
||||||
{
|
|
||||||
if(len > 0)
|
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;
|
static int n = 0;
|
||||||
|
CString str;
|
||||||
if((m_x & (bs.cx - 1)) || (m_env.TRXREG.RRW & (bs.cx - 1))
|
str.Format(_T("c:\\temp1\\[%04d]_%05x_%d_%d_%d_%d_%d_%d.bmp"),
|
||||||
|| (m_y & (bs.cy - 1)) || (m_env.TRXREG.RRH & (bs.cy - 1))
|
n++, (int)m_env.BITBLTBUF.DBP, (int)m_env.BITBLTBUF.DBW, (int)m_env.BITBLTBUF.DPSM,
|
||||||
|| m_x != m_env.TRXPOS.DSAX)
|
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);
|
||||||
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));
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
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)
|
void GSState::Write(BYTE* mem, int len)
|
||||||
{
|
{
|
||||||
/*
|
int dx = m_env.TRXPOS.DSAX;
|
||||||
TRACE(_T("Write len=%d DBP=%05x DBW=%d DPSM=%d DSAX=%d DSAY=%d RRW=%d RRH=%d\n"),
|
int dy = m_env.TRXPOS.DSAY;
|
||||||
len, (int)m_env.BITBLTBUF.DBP, (int)m_env.BITBLTBUF.DBW, (int)m_env.BITBLTBUF.DPSM,
|
int w = m_env.TRXREG.RRW;
|
||||||
(int)m_env.TRXPOS.DSAX, (int)m_env.TRXPOS.DSAY,
|
int h = m_env.TRXREG.RRH;
|
||||||
(int)m_env.TRXREG.RRW, (int)m_env.TRXREG.RRH);
|
|
||||||
*/
|
|
||||||
if(len == 0) return;
|
|
||||||
|
|
||||||
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();
|
FlushPrim();
|
||||||
}
|
}
|
||||||
|
|
||||||
int bpp = GSLocalMemory::m_psm[m_env.BITBLTBUF.DPSM].trbpp;
|
if(m_tr.end >= m_tr.total)
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
height = m_env.TRXREG.RRH - m_env.TRXPOS.DSAY;
|
FlushWrite();
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_mem.m_clut.Invalidate();
|
m_mem.m_clut.Invalidate();
|
||||||
|
@ -1111,25 +1051,26 @@ void GSState::Write(BYTE* mem, int len)
|
||||||
|
|
||||||
void GSState::Read(BYTE* mem, int len)
|
void GSState::Read(BYTE* mem, int len)
|
||||||
{
|
{
|
||||||
/*
|
if(len <= 0) return;
|
||||||
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(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);
|
return;
|
||||||
|
|
||||||
InvalidateLocalMem(m_env.BITBLTBUF, r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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()
|
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
|
// guitar hero copies the far end of the board to do a similar blend too
|
||||||
|
|
||||||
int sx = m_env.TRXPOS.SSAX;
|
int sx = m_env.TRXPOS.SSAX;
|
||||||
int dx = m_env.TRXPOS.DSAX;
|
|
||||||
int sy = m_env.TRXPOS.SSAY;
|
int sy = m_env.TRXPOS.SSAY;
|
||||||
|
int dx = m_env.TRXPOS.DSAX;
|
||||||
int dy = m_env.TRXPOS.DSAY;
|
int dy = m_env.TRXPOS.DSAY;
|
||||||
int w = m_env.TRXREG.RRW;
|
int w = m_env.TRXREG.RRW;
|
||||||
int h = m_env.TRXREG.RRH;
|
int h = m_env.TRXREG.RRH;
|
||||||
int xinc = 1;
|
|
||||||
int yinc = 1;
|
|
||||||
|
|
||||||
InvalidateLocalMem(m_env.BITBLTBUF, CRect(CPoint(sx, sy), CSize(w, h)));
|
InvalidateLocalMem(m_env.BITBLTBUF, CRect(CPoint(sx, sy), CSize(w, h)));
|
||||||
InvalidateVideoMem(m_env.BITBLTBUF, CRect(CPoint(dx, dy), 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;
|
int xinc = 1;
|
||||||
if(sy < dy) sy += h-1, dy += h-1, yinc = -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;
|
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)
|
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);
|
DWORD sbase = spsm.pa(0, sy, m_env.BITBLTBUF.SBP, m_env.BITBLTBUF.SBW);
|
||||||
int* soffset = spsm.rowOffset[sy & 7];
|
int* soffset = spsm.rowOffset[sy & 7];
|
||||||
|
@ -1182,7 +1124,7 @@ void GSState::Move()
|
||||||
}
|
}
|
||||||
else
|
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);
|
DWORD sbase = spsm.pa(0, sy, m_env.BITBLTBUF.SBP, m_env.BITBLTBUF.SBW);
|
||||||
int* soffset = spsm.rowOffset[sy & 7];
|
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.TRXDIR);
|
||||||
WriteState(data, &m_env.TRXPOS);
|
WriteState(data, &m_env.TRXPOS);
|
||||||
WriteState(data, &m_env.TRXREG);
|
WriteState(data, &m_env.TRXREG);
|
||||||
WriteState(data, &m_env.TRXREG2);
|
WriteState(data, &m_env.TRXREG); // obsolete
|
||||||
|
|
||||||
for(int i = 0; i < 2; i++)
|
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.UV);
|
||||||
WriteState(data, &m_v.XYZ);
|
WriteState(data, &m_v.XYZ);
|
||||||
WriteState(data, &m_v.FOG);
|
WriteState(data, &m_v.FOG);
|
||||||
WriteState(data, &m_x);
|
WriteState(data, &m_tr.x);
|
||||||
WriteState(data, &m_y);
|
WriteState(data, &m_tr.y);
|
||||||
WriteState(data, m_mem.m_vm8, m_mem.m_vmsize);
|
WriteState(data, m_mem.m_vm8, m_mem.m_vmsize);
|
||||||
|
|
||||||
for(int i = 0; i < 3; i++)
|
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.TRXDIR, data);
|
||||||
ReadState(&m_env.TRXPOS, data);
|
ReadState(&m_env.TRXPOS, data);
|
||||||
ReadState(&m_env.TRXREG, data);
|
ReadState(&m_env.TRXREG, data);
|
||||||
ReadState(&m_env.TRXREG2, data);
|
ReadState(&m_env.TRXREG, data); // obsolete
|
||||||
|
|
||||||
for(int i = 0; i < 2; i++)
|
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.UV, data);
|
||||||
ReadState(&m_v.XYZ, data);
|
ReadState(&m_v.XYZ, data);
|
||||||
ReadState(&m_v.FOG, data);
|
ReadState(&m_v.FOG, data);
|
||||||
ReadState(&m_x, data);
|
ReadState(&m_tr.x, data);
|
||||||
ReadState(&m_y, data);
|
ReadState(&m_tr.y, data);
|
||||||
ReadState(m_mem.m_vm8, data, m_mem.m_vmsize);
|
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++)
|
for(int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
ReadState(&m_path[i].tag, data);
|
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
|
// hacks
|
||||||
|
|
||||||
struct GSFrameInfo
|
struct GSFrameInfo
|
||||||
|
|
|
@ -113,13 +113,22 @@ class GSState : public GSAlignedClass<16>
|
||||||
void (*m_irq)();
|
void (*m_irq)();
|
||||||
bool m_path3hack;
|
bool m_path3hack;
|
||||||
|
|
||||||
int m_x, m_y;
|
struct GSTransferBuffer
|
||||||
int m_bytes;
|
{
|
||||||
int m_maxbytes;
|
int x, y;
|
||||||
BYTE* m_buff;
|
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();
|
||||||
void FlushWrite(BYTE* mem, int len);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool IsBadFrame(int& skip);
|
bool IsBadFrame(int& skip);
|
||||||
|
|
Loading…
Reference in New Issue