diff --git a/plugins/GSdx/Renderers/HW/GSRendererHW.cpp b/plugins/GSdx/Renderers/HW/GSRendererHW.cpp index aea4560224..d1eb19be95 100644 --- a/plugins/GSdx/Renderers/HW/GSRendererHW.cpp +++ b/plugins/GSdx/Renderers/HW/GSRendererHW.cpp @@ -1273,6 +1273,7 @@ GSRendererHW::Hacks::Hacks() m_oi_list.push_back(HackEntry(CRC::FFX, CRC::RegionCount, &GSRendererHW::OI_FFX)); m_oi_list.push_back(HackEntry(CRC::MetalSlug6, CRC::RegionCount, &GSRendererHW::OI_MetalSlug6)); m_oi_list.push_back(HackEntry(CRC::RozenMaidenGebetGarden, CRC::RegionCount, &GSRendererHW::OI_RozenMaidenGebetGarden)); + m_oi_list.push_back(HackEntry(CRC::SonicUnleashed, CRC::RegionCount, &GSRendererHW::OI_SonicUnleashed)); m_oi_list.push_back(HackEntry(CRC::StarWarsForceUnleashed, CRC::RegionCount, &GSRendererHW::OI_StarWarsForceUnleashed)); m_oi_list.push_back(HackEntry(CRC::SuperManReturns, CRC::RegionCount, &GSRendererHW::OI_SuperManReturns)); m_oi_list.push_back(HackEntry(CRC::ArTonelico2, CRC::RegionCount, &GSRendererHW::OI_ArTonelico2)); @@ -1665,6 +1666,38 @@ bool GSRendererHW::OI_RozenMaidenGebetGarden(GSTexture* rt, GSTexture* ds, GSTex return true; } +bool GSRendererHW::OI_SonicUnleashed(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) +{ + // Rendering pattern is: + // Save RG channel with a kind of a TS (replaced by a copy in this hack), + // compute shadow in RG, + // save result in alpha with a TS, + // Restore RG channel that we previously copied to render shadows. + + GIFRegTEX0 Texture = m_context->TEX0; + + GIFRegTEX0 Frame; + Frame.TBW = m_context->FRAME.FBW; + Frame.TBP0 = m_context->FRAME.FBP; + Frame.TBP0 = m_context->FRAME.Block(); + Frame.PSM = m_context->FRAME.PSM; + + if ((!PRIM->TME) || (GSLocalMemory::m_psm[Texture.PSM].bpp != 16) || (GSLocalMemory::m_psm[Frame.PSM].bpp != 16)) + return true; + + if ((Texture.TBP0 == Frame.TBP0) || (Frame.TBW != 16 && Texture.TBW != 16)) + return true; + + GSTextureCache::Target* src = m_tc->LookupTarget(Texture, m_width, m_height, GSTextureCache::RenderTarget, true); + GSVector4 sRect(0, 0, 1, 1); + GSVector4 dRect(0, 0, m_width, m_height); + + m_dev->StretchRect(src->m_texture, sRect, rt, dRect, true, true, true, false); + GL_INS("OI_SonicUnleashed replace draw by a copy"); + + return false; +} + bool GSRendererHW::OI_StarWarsForceUnleashed(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) { uint32 FBP = m_context->FRAME.Block(); diff --git a/plugins/GSdx/Renderers/HW/GSRendererHW.h b/plugins/GSdx/Renderers/HW/GSRendererHW.h index dd146adf42..e307fb7bcd 100644 --- a/plugins/GSdx/Renderers/HW/GSRendererHW.h +++ b/plugins/GSdx/Renderers/HW/GSRendererHW.h @@ -56,6 +56,7 @@ private: bool OI_FFX(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); bool OI_MetalSlug6(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); bool OI_RozenMaidenGebetGarden(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); + bool OI_SonicUnleashed(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); bool OI_StarWarsForceUnleashed(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); bool OI_PointListPalette(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); bool OI_SuperManReturns(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t);