diff --git a/bin/resources/GameIndex.yaml b/bin/resources/GameIndex.yaml index bcb8e57b9a..793564c964 100644 --- a/bin/resources/GameIndex.yaml +++ b/bin/resources/GameIndex.yaml @@ -18004,12 +18004,20 @@ SLES-53729: name: "Battlefield 2 - Modern Combat" region: "PAL-M4" gsHWFixes: - autoFlush: 1 + autoFlush: 1 # Post-processing. + halfPixelOffset: 2 # Offset post-processing. + texturePreloading: 1 # Spikes all over the place otherwise. + getSkipCount: "GSC_Battlefield2" # Depth clear. + beforeDraw: "OI_Battlefield2" # Framebuffer copy, fixes rendering for bottom part of screen. SLES-53730: name: "Battlefield 2 - Modern Combat" region: "PAL-M3" gsHWFixes: - autoFlush: 1 + autoFlush: 1 # Post-processing. + halfPixelOffset: 2 # Offset post-processing. + texturePreloading: 1 # Spikes all over the place otherwise. + getSkipCount: "GSC_Battlefield2" # Depth clear. + beforeDraw: "OI_Battlefield2" # Framebuffer copy, fixes rendering for bottom part of screen. SLES-53734: name: "50 Cent - Bulletproof" region: "PAL-E" @@ -31447,7 +31455,11 @@ SLPM-66206: name: "Battlefield 2 - Modern Combat" region: "NTSC-J" gsHWFixes: - autoFlush: 1 + autoFlush: 1 # Post-processing. + halfPixelOffset: 2 # Offset post-processing. + texturePreloading: 1 # Spikes all over the place otherwise. + getSkipCount: "GSC_Battlefield2" # Depth clear. + beforeDraw: "OI_Battlefield2" # Framebuffer copy, fixes rendering for bottom part of screen. SLPM-66207: name: "Dororo [Sega the Best 2800]" region: "NTSC-J" @@ -33126,7 +33138,11 @@ SLPM-66651: name: "Battlefield 2 - Modern Combat [EA Best Hits]" region: "NTSC-J" gsHWFixes: - autoFlush: 1 + autoFlush: 1 # Post-processing. + halfPixelOffset: 2 # Offset post-processing. + texturePreloading: 1 # Spikes all over the place otherwise. + getSkipCount: "GSC_Battlefield2" # Depth clear. + beforeDraw: "OI_Battlefield2" # Framebuffer copy, fixes rendering for bottom part of screen. SLPM-66652: name: "Burnout Revenge [EA Best Hits]" region: "NTSC-J" @@ -45062,7 +45078,11 @@ SLUS-21026: region: "NTSC-U" compat: 5 gsHWFixes: - autoFlush: 1 + autoFlush: 1 # Post-processing. + halfPixelOffset: 2 # Offset post-processing. + texturePreloading: 1 # Spikes all over the place otherwise. + getSkipCount: "GSC_Battlefield2" # Depth clear. + beforeDraw: "OI_Battlefield2" # Framebuffer copy, fixes rendering for bottom part of screen. SLUS-21027: name: "Lord of the Rings, The - The Third Age" region: "NTSC-U" @@ -50163,7 +50183,11 @@ SLUS-29117: name: "Battlefield 2 - Modern Combat [Public Beta Vol.1.0]" region: "NTSC-U" gsHWFixes: - autoFlush: 1 + autoFlush: 1 # Post-processing. + halfPixelOffset: 2 # Offset post-processing. + texturePreloading: 1 # Spikes all over the place otherwise. + getSkipCount: "GSC_Battlefield2" # Depth clear. + beforeDraw: "OI_Battlefield2" # Framebuffer copy, fixes rendering for bottom part of screen. SLUS-29118: name: "Need for Speed - Underground 2 [Demo]" region: "NTSC-U" @@ -50256,7 +50280,11 @@ SLUS-29152: name: "Battlefield 2 - Modern Combat [Regular Demo]" region: "NTSC-U" gsHWFixes: - autoFlush: 1 + autoFlush: 1 # Post-processing. + halfPixelOffset: 2 # Offset post-processing. + texturePreloading: 1 # Spikes all over the place otherwise. + getSkipCount: "GSC_Battlefield2" # Depth clear. + beforeDraw: "OI_Battlefield2" # Framebuffer copy, fixes rendering for bottom part of screen. SLUS-29153: name: "Burnout Revenge [Demo]" region: "NTSC-U" @@ -50342,7 +50370,11 @@ SLUS-29172: name: "Battlefield 2 - Modern Combat [Demo]" region: "NTSC-U" gsHWFixes: - autoFlush: 1 + autoFlush: 1 # Post-processing. + halfPixelOffset: 2 # Offset post-processing. + texturePreloading: 1 # Spikes all over the place otherwise. + getSkipCount: "GSC_Battlefield2" # Depth clear. + beforeDraw: "OI_Battlefield2" # Framebuffer copy, fixes rendering for bottom part of screen. SLUS-29173: name: "Sims 2, The [Demo]" region: "NTSC-U" diff --git a/pcsx2/GS/Renderers/HW/GSHwHack.cpp b/pcsx2/GS/Renderers/HW/GSHwHack.cpp index f8c39f6a04..baec67f8c7 100644 --- a/pcsx2/GS/Renderers/HW/GSHwHack.cpp +++ b/pcsx2/GS/Renderers/HW/GSHwHack.cpp @@ -1209,6 +1209,43 @@ bool GSHwHack::OI_BurnoutGames(GSRendererHW& r, GSTexture* rt, GSTexture* ds, GS return false; } +bool GSHwHack::GSC_Battlefield2(GSRendererHW& r, const GSFrameInfo& fi, int& skip) +{ + if (skip == 0) + { + if (fi.ZBP >= fi.FBP && fi.FBP >= 0x2000 && fi.ZBP >= 0x2700 && ((fi.ZBP - fi.FBP) == 0x700)) + { + skip = 7; + + GIFRegTEX0 TEX0 = {}; + TEX0.TBP0 = fi.FBP; + TEX0.TBW = 8; + GSTextureCache::Target* dst = r.m_tc->LookupTarget(TEX0, GSRendererHW::GetInstance()->GetTargetSize(), GSTextureCache::DepthStencil, true); + if (dst) + { + g_gs_device->ClearDepth(dst->m_texture); + } + } + } + + return true; +} + +bool GSHwHack::OI_Battlefield2(GSRendererHW& r, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t) +{ + if (!RPRIM->TME || RCONTEXT->FRAME.Block() > 0xD00 || RCONTEXT->TEX0.TBP0 > 0x1D00) + return true; + + if (rt && t && RCONTEXT->FRAME.Block() == 0 && RCONTEXT->TEX0.TBP0 == 0x1000) + { + const GSVector4i rc(0, 0, std::min(rt->GetWidth(), t->m_texture->GetWidth()), std::min(rt->GetHeight(), t->m_texture->GetHeight())); + g_gs_device->CopyRect(t->m_texture, rt, rc, 0, 0); + } + + r.m_tc->InvalidateTemporarySource(); + return false; +} + #undef RCONTEXT #undef RPRIM @@ -1240,6 +1277,7 @@ const GSHwHack::Entry GSHwHack::s_get_skip_count_function CRC_F(GSC_ZettaiZetsumeiToshi2, CRCHackLevel::Partial), CRC_F(GSC_BlackAndBurnoutSky, CRCHackLevel::Partial), CRC_F(GSC_Barnyard, CRCHackLevel::Partial), + CRC_F(GSC_Battlefield2, CRCHackLevel::Partial), // Channel Effect CRC_F(GSC_CrashBandicootWoC, CRCHackLevel::Partial), @@ -1290,6 +1328,7 @@ const GSHwHack::Entry GSHwHack::s_before_draw_functions[] CRC_F(OI_ArTonelico2, CRCHackLevel::Minimum), CRC_F(OI_JakGames, CRCHackLevel::Minimum), CRC_F(OI_BurnoutGames, CRCHackLevel::Minimum), + CRC_F(OI_Battlefield2, CRCHackLevel::Minimum), }; #undef CRC_F diff --git a/pcsx2/GS/Renderers/HW/GSHwHack.h b/pcsx2/GS/Renderers/HW/GSHwHack.h index d337bdd0cf..dcd79acfbc 100644 --- a/pcsx2/GS/Renderers/HW/GSHwHack.h +++ b/pcsx2/GS/Renderers/HW/GSHwHack.h @@ -56,6 +56,7 @@ public: static bool GSC_ShinOnimusha(GSRendererHW& r, const GSFrameInfo& fi, int& skip); static bool GSC_XenosagaE3(GSRendererHW& r, const GSFrameInfo& fi, int& skip); static bool GSC_Barnyard(GSRendererHW& r, const GSFrameInfo& fi, int& skip); + static bool GSC_Battlefield2(GSRendererHW& r, const GSFrameInfo& fi, int& skip); static bool OI_PointListPalette(GSRendererHW& r, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); static bool OI_BigMuthaTruckers(GSRendererHW& r, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); @@ -69,6 +70,8 @@ public: static bool OI_JakGames(GSRendererHW& r, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); static bool OI_BurnoutGames(GSRendererHW& r, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); + static bool OI_Battlefield2(GSRendererHW& r, GSTexture* rt, GSTexture* ds, GSTextureCache::Source* t); + template struct Entry {