GSdx: 4 bit local-local transfer crash fixed (shadow hearts)

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1476 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gabest11 2009-07-07 13:04:56 +00:00
parent a7ce451167
commit af643a38b2
3 changed files with 70 additions and 47 deletions

View File

@ -465,20 +465,9 @@ GSLocalMemory::~GSLocalMemory()
{ {
VirtualFree(m_vm8, 0, MEM_RELEASE); VirtualFree(m_vm8, 0, MEM_RELEASE);
for(hash_map<uint32, BlockOffset*>::iterator i = m_bomap.begin(); i != m_bomap.end(); i++) for_each(m_bomap.begin(), m_bomap.end(), aligned_free_second());
{ for_each(m_pomap.begin(), m_pomap.end(), aligned_free_second());
_aligned_free(i->second); for_each(m_po4map.begin(), m_po4map.end(), aligned_free_second());
}
for(hash_map<uint32, PixelOffset*>::iterator i = m_pomap.begin(); i != m_pomap.end(); i++)
{
_aligned_free(i->second);
}
for(hash_map<uint32, PixelOffset4*>::iterator i = m_po4map.begin(); i != m_po4map.end(); i++)
{
_aligned_free(i->second);
}
} }
GSLocalMemory::BlockOffset* GSLocalMemory::GetBlockOffset(uint32 bp, uint32 bw, uint32 psm) GSLocalMemory::BlockOffset* GSLocalMemory::GetBlockOffset(uint32 bp, uint32 bw, uint32 psm)

View File

@ -1163,57 +1163,88 @@ void GSState::Move()
} }
else if(m_env.BITBLTBUF.SPSM == PSM_PSMT8 && m_env.BITBLTBUF.DPSM == PSM_PSMT8) else if(m_env.BITBLTBUF.SPSM == PSM_PSMT8 && m_env.BITBLTBUF.DPSM == PSM_PSMT8)
{ {
for(int y = 0; y < h; y++, sy += yinc, dy += yinc) if(xinc > 0)
{ {
uint8* RESTRICT s = &m_mem.m_vm8[spo->row[sy]]; for(int y = 0; y < h; y++, sy += yinc, dy += yinc)
uint8* RESTRICT d = &m_mem.m_vm8[dpo->row[dy]];
int* RESTRICT scol = &spo->col[sy & 7][sx];
int* RESTRICT dcol = &dpo->col[dy & 7][dx];
for(int x = 0; x < w; x++, scol += xinc, dcol += xinc)
{ {
d[*dcol] = s[*scol]; uint8* RESTRICT s = &m_mem.m_vm8[spo->row[sy]];
uint8* RESTRICT d = &m_mem.m_vm8[dpo->row[dy]];
int* RESTRICT scol = &spo->col[sy & 7][sx];
int* RESTRICT dcol = &dpo->col[dy & 7][dx];
for(int x = 0; x < w; x++) d[dcol[x]] = s[scol[x]];
}
}
else
{
for(int y = 0; y < h; y++, sy += yinc, dy += yinc)
{
uint8* RESTRICT s = &m_mem.m_vm8[spo->row[sy]];
uint8* RESTRICT d = &m_mem.m_vm8[dpo->row[dy]];
int* RESTRICT scol = &spo->col[sy & 7][sx];
int* RESTRICT dcol = &dpo->col[dy & 7][dx];
for(int x = 0; x > -w; x--) d[dcol[x]] = s[scol[x]];
} }
} }
} }
else if(m_env.BITBLTBUF.SPSM == PSM_PSMT4 && m_env.BITBLTBUF.DPSM == PSM_PSMT4) else if(m_env.BITBLTBUF.SPSM == PSM_PSMT4 && m_env.BITBLTBUF.DPSM == PSM_PSMT4)
{ {
for(int y = 0; y < h; y++, sy += yinc, dy += yinc, sx -= xinc * w, dx -= xinc * w) if(xinc > 0)
{ {
uint8* RESTRICT s = &m_mem.m_vm8[spo->row[sy] >> 1]; for(int y = 0; y < h; y++, sy += yinc, dy += yinc)
uint8* RESTRICT d = &m_mem.m_vm8[dpo->row[dy] >> 1];
int* RESTRICT scol = &spo->col[sy & 7][sx];
int* RESTRICT dcol = &dpo->col[dy & 7][dx];
for(int x = 0; x < w; x += 2)
{ {
d[*dcol >> 1] = (d[*dcol >> 1] & 0xf0) | (s[*scol >> 1] & 0x0f); uint32 sbase = spo->row[sy];
uint32 dbase = dpo->row[dy];
scol += xinc; int* RESTRICT scol = &spo->col[sy & 7][sx];
dcol += xinc; int* RESTRICT dcol = &dpo->col[dy & 7][dx];
for(int x = 0; x < w; x++) m_mem.WritePixel4(dbase + dcol[x], m_mem.ReadPixel4(sbase + scol[x]));
}
}
else
{
for(int y = 0; y < h; y++, sy += yinc, dy += yinc)
{
uint32 sbase = spo->row[sy];
uint32 dbase = dpo->row[dy];
d[*dcol >> 1] = (d[*dcol >> 1] & 0x0f) | (s[*scol >> 1] & 0xf0); int* RESTRICT scol = &spo->col[sy & 7][sx];
int* RESTRICT dcol = &dpo->col[dy & 7][dx];
scol += xinc;
dcol += xinc; for(int x = 0; x > -w; x--) m_mem.WritePixel4(dbase + dcol[x], m_mem.ReadPixel4(sbase + scol[x]));
} }
} }
} }
else else
{ {
for(int y = 0; y < h; y++, sy += yinc, dy += yinc, sx -= xinc * w, dx -= xinc * w) if(xinc > 0)
{ {
uint32 sbase = spo->row[sy]; for(int y = 0; y < h; y++, sy += yinc, dy += yinc)
uint32 dbase = dpo->row[dy];
int* RESTRICT scol = spo->col[sy & 7];
int* RESTRICT dcol = dpo->col[dy & 7];
for(int x = 0; x < w; x++, sx += xinc, dx += xinc)
{ {
(m_mem.*dpsm.wpa)(dbase + dcol[dx], (m_mem.*spsm.rpa)(sbase + scol[sx])); uint32 sbase = spo->row[sy];
uint32 dbase = dpo->row[dy];
int* RESTRICT scol = &spo->col[sy & 7][sx];
int* RESTRICT dcol = &dpo->col[dy & 7][dx];
for(int x = 0; x < w; x++) (m_mem.*dpsm.wpa)(dbase + dcol[x], (m_mem.*spsm.rpa)(sbase + scol[x]));
}
}
else
{
for(int y = 0; y < h; y++, sy += yinc, dy += yinc)
{
uint32 sbase = spo->row[sy];
uint32 dbase = dpo->row[dy];
int* RESTRICT scol = &spo->col[sy & 7][sx];
int* RESTRICT dcol = &dpo->col[dy & 7][dx];
for(int x = 0; x > -w; x--) (m_mem.*dpsm.wpa)(dbase + dcol[x], (m_mem.*spsm.rpa)(sbase + scol[x]));
} }
} }
} }

View File

@ -63,6 +63,9 @@ extern string format(const char* fmt, ...);
struct delete_object {template<class T> void operator()(T& p) {delete p;}}; struct delete_object {template<class T> void operator()(T& p) {delete p;}};
struct delete_first {template<class T> void operator()(T& p) {delete p.first;}}; struct delete_first {template<class T> void operator()(T& p) {delete p.first;}};
struct delete_second {template<class T> void operator()(T& p) {delete p.second;}}; struct delete_second {template<class T> void operator()(T& p) {delete p.second;}};
struct aligned_free_object {template<class T> void operator()(T& p) {_aligned_free(p);}};
struct aligned_free_first {template<class T> void operator()(T& p) {_aligned_free(p.first);}};
struct aligned_free_second {template<class T> void operator()(T& p) {_aligned_free(p.second);}};
// syntactic sugar // syntactic sugar