diff --git a/pcsx2/GS/Renderers/HW/GSHwHack.cpp b/pcsx2/GS/Renderers/HW/GSHwHack.cpp index 01e1baab80..5bbd8cf535 100644 --- a/pcsx2/GS/Renderers/HW/GSHwHack.cpp +++ b/pcsx2/GS/Renderers/HW/GSHwHack.cpp @@ -722,6 +722,48 @@ bool GSHwHack::GSC_BlueTongueGames(GSRendererHW& r, int& skip) { GSDrawingContext* context = r.m_context; + // Nicktoons does its weird dithered depth pattern during FMV's also, which really screws the frame width up, which is wider for FMV's + // and so fails to work correctly in the HW renderer and makes a mess of the width, so let's expand the draw to match the proper width. + if (RPRIM->TME && RTEX0.TW == 3 && RTEX0.TH == 3 && RTEX0.PSM == 0 && RFRAME.FBMSK == 0x00FFFFFF && RFRAME.FBW == 8 && r.PCRTCDisplays.GetResolution().x > 512) + { + // Check we are drawing stripes + for (int i = 1; i < r.m_vertex.tail; i+=2) + { + int value = (((r.m_vertex.buff[i].XYZ.X - r.m_vertex.buff[i - 1].XYZ.X) + 8) >> 4); + if (value != 32) + return false; + } + + r.m_r.x = r.m_vt.m_min.p.x; + r.m_r.y = r.m_vt.m_min.p.y; + r.m_r.z = r.PCRTCDisplays.GetResolution().x; + r.m_r.w = r.m_vt.m_max.p.y; + + for (int vert = 32; vert < 40; vert+=2) + { + r.m_vertex.buff[vert].XYZ.X = context->XYOFFSET.OFX + (((vert * 16) << 4) - 8); + r.m_vertex.buff[vert].XYZ.Y = context->XYOFFSET.OFY; + r.m_vertex.buff[vert].U = (vert * 16) << 4; + r.m_vertex.buff[vert].V = 0; + r.m_vertex.buff[vert+1].XYZ.X = context->XYOFFSET.OFX + ((((vert * 16) + 32) << 4) - 8); + r.m_vertex.buff[vert+1].XYZ.Y = context->XYOFFSET.OFY + 8184; //511.5 + r.m_vertex.buff[vert+1].U = ((vert * 16) + 32) << 4; + r.m_vertex.buff[vert+1].V = 512 << 4; + } + + /*r.m_vertex.head = r.m_vertex.tail = r.m_vertex.next = 2; + r.m_index.tail = 2;*/ + + r.m_vt.m_max.p.x = r.m_r.z; + r.m_vt.m_max.p.y = r.m_r.w; + r.m_vt.m_max.t.x = r.m_r.z; + r.m_vt.m_max.t.y = r.m_r.w; + context->scissor.in.z = r.m_r.z; + context->scissor.in.w = r.m_r.w; + + RFRAME.FBW = 10; + } + // Whoever wrote this was kinda nuts. They draw a stipple/dither pattern to a framebuffer, then reuse that as // the depth buffer. Textures are then drawn repeatedly on top of one another, each with a slight offset. // Depth testing is enabled, and that determines which pixels make it into the final texture. Kinda like an diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index 52e4a4e40f..8918d08ec7 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -2381,25 +2381,12 @@ void GSRendererHW::Draw() const bool can_update_size = !is_possible_mem_clear && !m_texture_shuffle && !m_channel_shuffle; if (!m_texture_shuffle && !m_channel_shuffle) { - if (rt) + if (rt && (!is_possible_mem_clear || rt->m_TEX0.PSM != FRAME_TEX0.PSM)) { - // Nicktoons Unite tries to change the width from 640 to 512 and breaks FMVs. - // Haunting ground has some messed textures if you don't modify the rest. - // Champions of Norrath expands the width from 512 to 1024, picture cut in half if you don't. - // The safest option is to probably let it expand but not retract. - if (!rt->m_is_frame || rt->m_TEX0.TBW < FRAME_TEX0.TBW) - { - rt->m_TEX0 = FRAME_TEX0; - } - else - { - const u32 width = rt->m_TEX0.TBW; - rt->m_TEX0 = FRAME_TEX0; - rt->m_TEX0.TBW = std::max(width, FRAME_TEX0.TBW); - } + rt->m_TEX0 = FRAME_TEX0; } - if (ds) + if (ds && (!is_possible_mem_clear || ds->m_TEX0.PSM != ZBUF_TEX0.PSM)) ds->m_TEX0 = ZBUF_TEX0; } else if (!m_texture_shuffle) diff --git a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp index 0d28ced8a7..3ac31877e0 100644 --- a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp +++ b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp @@ -1353,12 +1353,6 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe } } } - - if (dst) - { - dst->m_TEX0.TBW = TEX0.TBW; // Fix Jurassic Park - Operation Genesis loading disk logo. - dst->m_is_frame |= is_frame; // Nicktoons Unite tries to change the width from 10 to 8 and breaks FMVs. - } } if (dst)