diff --git a/plugins/GSdx/GSCrc.cpp b/plugins/GSdx/GSCrc.cpp index b6b98060dc..a23939aeda 100644 --- a/plugins/GSdx/GSCrc.cpp +++ b/plugins/GSdx/GSCrc.cpp @@ -130,6 +130,7 @@ CRC::Game CRC::m_games[] = {0x045D77E9, TalesOfAbyss, US}, // undub {0xAA5EC3A3, TalesOfAbyss, JP}, {0xFB236A46, SonicUnleashed, US}, + {0x4C7BB3C8, SimpsonsGame, Unknown}, }; hash_map CRC::m_map; diff --git a/plugins/GSdx/GSCrc.h b/plugins/GSdx/GSCrc.h index 731e495a09..1d68f1dc09 100644 --- a/plugins/GSdx/GSCrc.h +++ b/plugins/GSdx/GSCrc.h @@ -64,6 +64,7 @@ public: MajokkoALaMode2, TalesOfAbyss, SonicUnleashed, + SimpsonsGame, TitleCount, }; diff --git a/plugins/GSdx/GSDevice9.cpp b/plugins/GSdx/GSDevice9.cpp index 7d4f12a940..8ccafc6a27 100644 --- a/plugins/GSdx/GSDevice9.cpp +++ b/plugins/GSdx/GSDevice9.cpp @@ -407,31 +407,55 @@ void GSDevice9::ClearRenderTarget(GSTexture* t, const GSVector4& c) ClearRenderTarget(t, (c * 255 + 0.5f).zyxw().rgba32()); } -void GSDevice9::ClearRenderTarget(GSTexture* t, uint32 c) +void GSDevice9::ClearRenderTarget(GSTexture* rt, uint32 c) { CComPtr surface; m_dev->GetRenderTarget(0, &surface); - m_dev->SetRenderTarget(0, *(GSTexture9*)t); + m_dev->SetRenderTarget(0, *(GSTexture9*)rt); m_dev->Clear(0, NULL, D3DCLEAR_TARGET, c, 0, 0); m_dev->SetRenderTarget(0, surface); } void GSDevice9::ClearDepth(GSTexture* t, float c) { - CComPtr surface; - m_dev->GetDepthStencilSurface(&surface); + GSTexture* rt = CreateRenderTarget(t->GetWidth(), t->GetHeight()); + + CComPtr rtsurface; + CComPtr dssurface; + + m_dev->GetRenderTarget(0, &rtsurface); + m_dev->GetDepthStencilSurface(&dssurface); + + m_dev->SetRenderTarget(0, *(GSTexture9*)rt); m_dev->SetDepthStencilSurface(*(GSTexture9*)t); + m_dev->Clear(0, NULL, D3DCLEAR_ZBUFFER, 0, c, 0); - m_dev->SetDepthStencilSurface(surface); + + m_dev->SetRenderTarget(0, rtsurface); + m_dev->SetDepthStencilSurface(dssurface); + + Recycle(rt); } void GSDevice9::ClearStencil(GSTexture* t, uint8 c) { - CComPtr surface; - m_dev->GetDepthStencilSurface(&surface); + GSTexture* rt = CreateRenderTarget(t->GetWidth(), t->GetHeight()); + + CComPtr rtsurface; + CComPtr dssurface; + + m_dev->GetRenderTarget(0, &rtsurface); + m_dev->GetDepthStencilSurface(&dssurface); + + m_dev->SetRenderTarget(0, *(GSTexture9*)rt); m_dev->SetDepthStencilSurface(*(GSTexture9*)t); + m_dev->Clear(0, NULL, D3DCLEAR_STENCIL, 0, 0, c); - m_dev->SetDepthStencilSurface(surface); + + m_dev->SetRenderTarget(0, rtsurface); + m_dev->SetDepthStencilSurface(dssurface); + + Recycle(rt); } GSTexture* GSDevice9::Create(int type, int w, int h, int format) @@ -492,7 +516,7 @@ GSTexture* GSDevice9::CreateRenderTarget(int w, int h, int format) GSTexture* GSDevice9::CreateDepthStencil(int w, int h, int format) { - return __super::CreateDepthStencil(w, h, format ? format : D3DFMT_D24S8); + return __super::CreateDepthStencil(w, h, format ? format : D3DFMT_D24S8); // D3DFMT_D32F_LOCKABLE } GSTexture* GSDevice9::CreateTexture(int w, int h, int format) @@ -661,7 +685,7 @@ void GSDevice9::IASetVertexBuffer(const void* vertices, size_t stride, size_t co { HRESULT hr; - hr = m_dev->CreateVertexBuffer(m_vertices.limit * stride, D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &m_vertices.vb, NULL); + hr = m_dev->CreateVertexBuffer(m_vertices.limit * stride, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &m_vertices.vb, NULL); if(FAILED(hr)) return; } diff --git a/plugins/GSdx/GSLocalMemory.cpp b/plugins/GSdx/GSLocalMemory.cpp index 54346dabbe..31567fa8e3 100644 --- a/plugins/GSdx/GSLocalMemory.cpp +++ b/plugins/GSdx/GSLocalMemory.cpp @@ -813,12 +813,12 @@ void GSLocalMemory::WriteImageTopBottom(int l, int r, int y, int h, uint8* src, break; case PSM_PSMT8: ReadColumn8(y, dst, buff, 16); - memcpy(&buff[y2 * 16], &src[x], h2 * 16); + for(int i = 0, j = y2; i < h2; i++, j++) memcpy(&buff[j * 16], &src[i * srcpitch + x], 16); WriteColumn8(y, dst, buff, 16); break; case PSM_PSMT4: ReadColumn4(y, dst, buff, 16); - memcpy(&buff[y2 * 16], &src[x >> 1], h2 * 16); + for(int i = 0, j = y2; i < h2; i++, j++) memcpy(&buff[j * 16], &src[i * srcpitch + (x >> 1)], 16); WriteColumn4(y, dst, buff, 16); break; // TODO @@ -894,12 +894,12 @@ void GSLocalMemory::WriteImageTopBottom(int l, int r, int y, int h, uint8* src, break; case PSM_PSMT8: ReadColumn8(y, dst, buff, 16); - memcpy(&buff[0], &src[x], h * 16); + for(int i = 0; i < h; i++) memcpy(&buff[i * 16], &src[i * srcpitch + x], 16); WriteColumn8(y, dst, buff, 16); break; case PSM_PSMT4: ReadColumn4(y, dst, buff, 16); - memcpy(&buff[0], &src[x >> 1], h * 16); + for(int i = 0; i < h; i++) memcpy(&buff[i * 16], &src[i * srcpitch + (x >> 1)], 16); WriteColumn4(y, dst, buff, 16); break; // TODO @@ -2523,8 +2523,6 @@ HRESULT GSLocalMemory::SaveBMP(const string& fn, uint32 bp, uint32 bw, uint32 ps TEXA.TA0 = 0; TEXA.TA1 = 0x80; - // (this->*m_psm[TEX0.PSM].rtx)(GSVector4i(0, 0, w, h), bits, pitch, TEX0, TEXA); - readPixel rp = m_psm[psm].rp; uint8* p = (uint8*)bits; diff --git a/plugins/GSdx/GSRendererHW.h b/plugins/GSdx/GSRendererHW.h index 98bcb59d65..d1e95de50d 100644 --- a/plugins/GSdx/GSRendererHW.h +++ b/plugins/GSdx/GSRendererHW.h @@ -572,6 +572,30 @@ protected: #pragma endregion + #pragma region Simpsons Game z buffer clear + + if(m_game.title == CRC::SimpsonsGame) + { + uint32 FBP = m_context->FRAME.Block(); + uint32 FBW = m_context->FRAME.FBW; + uint32 FPSM = m_context->FRAME.PSM; + + if(FBP == 0x01800 && FPSM == PSM_PSMZ24) + { + // instead of just simply drawing a full height 512x512 sprite to clear the z buffer, + // it uses a 512x256 sprite only, yet it is still able to fill the whole surface with zeros, + // how? by using a render target that overlaps with the lower half of the z buffer... + + m_dev->ClearDepth(ds, 0); + + return false; + } + + return true; + } + + #pragma endregion + return true; } diff --git a/plugins/GSdx/GSState.cpp b/plugins/GSdx/GSState.cpp index 65f7a6cf77..d1d3ccad62 100644 --- a/plugins/GSdx/GSState.cpp +++ b/plugins/GSdx/GSState.cpp @@ -968,7 +968,7 @@ void GSState::Write(uint8* mem, int len) int w = m_env.TRXREG.RRW; int h = m_env.TRXREG.RRH; - // 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); + // TRACE(_T("Write len=%d DBP=%05x DBW=%d DPSM=%d DSAX=%d DSAY=%d RRW=%d RRH=%d\n"), len, m_env.BITBLTBUF.DBP, m_env.BITBLTBUF.DBW, m_env.BITBLTBUF.DPSM, m_env.TRXPOS.DSAX, m_env.TRXPOS.DSAY, m_env.TRXREG.RRW, m_env.TRXREG.RRH); if(!m_tr.Update(w, h, GSLocalMemory::m_psm[m_env.BITBLTBUF.DPSM].trbpp, len)) { @@ -1209,7 +1209,9 @@ template void GSState::Transfer(uint8* mem, uint32 size) { m_q = 1.0f; - if(path.tag.PRE && (path.tag.FLG & 2) == 0) + ASSERT(!(path.tag.PRE && path.tag.FLG == GIF_FLG_REGLIST)); + + if(path.tag.PRE && path.tag.FLG == GIF_FLG_PACKED) { GIFReg r; r.u64 = path.tag.PRIM;