GS-HW: Fix annoying NASCAR offsets in PCRTC

This commit is contained in:
refractionpcsx2 2023-05-13 02:01:48 +01:00
parent 041abd8abc
commit 0ae91cbf64
2 changed files with 11 additions and 20 deletions

View File

@ -542,16 +542,10 @@ public:
GSVector4i out_rect = PCRTCDisplays[display].framebufferRect;
if (out_rect.z >= 2048)
{
out_rect.z -= GSConfig.UseHardwareRenderer() ? 2048 : out_rect.x;
out_rect.x = 0;
}
out_rect.z -= out_rect.x;
if (out_rect.w >= 2048)
{
out_rect.w -= GSConfig.UseHardwareRenderer() ? 2048 : out_rect.y;
out_rect.y = 0;
}
out_rect.w -= out_rect.y;
// Cap the framebuffer read to the maximum display height, otherwise the hardware renderer gets messy.
const int min_mag = std::max(1, PCRTCDisplays[display].magnification.y);
@ -565,12 +559,6 @@ public:
offset = (max_height / min_mag) - offset;
out_rect.w = std::min(out_rect.w, offset);
// Hardware mode needs a wider framebuffer as it can't offset the read.
if (GSConfig.UseHardwareRenderer())
{
out_rect.z += PCRTCDisplays[display].framebufferOffsets.x;
out_rect.w += PCRTCDisplays[display].framebufferOffsets.y;
}
return GSVector2i(out_rect.z, out_rect.w);
}
}
@ -685,11 +673,15 @@ public:
{
if (PCRTCDisplays[display].framebufferRect.z >= 2048)
{
PCRTCDisplays[display].displayRect.x += 2048 - PCRTCDisplays[display].framebufferRect.x;
PCRTCDisplays[display].displayRect.z += 2048 - PCRTCDisplays[display].framebufferRect.x;
PCRTCDisplays[display].framebufferRect.x = 0;
PCRTCDisplays[display].framebufferRect.z -= 2048;
}
if (PCRTCDisplays[display].framebufferRect.w >= 2048)
{
PCRTCDisplays[display].displayRect.y += 2048 - PCRTCDisplays[display].framebufferRect.y;
PCRTCDisplays[display].displayRect.w += 2048 - PCRTCDisplays[display].framebufferRect.y;
PCRTCDisplays[display].framebufferRect.y = 0;
PCRTCDisplays[display].framebufferRect.w -= 2048;
}

View File

@ -124,11 +124,13 @@ GSTexture* GSRendererSW::GetOutput(int i, float& scale, int& y_offset)
constexpr int pitch = 1024 * 4;
// Should really be framebufferOffsets rather than framebufferRect but this might be compensated with anti-blur in some games.
const int off_x = (framebufferRect.x & 0x7ff) & ~(psm.bs.x-1);
const int off_x_end = ((framebufferRect.x & 0x7ff) + (psm.bs.x - 1)) & ~(psm.bs.x - 1);
const int off_y = (framebufferRect.y & 0x7ff) & ~(psm.bs.y-1);
const int off_y_end = ((framebufferRect.y & 0x7ff) + (psm.bs.y - 1)) & ~(psm.bs.y - 1);
const GSVector4i out_r(0, 0, w, h);
GSVector4i r(off_x, off_y, w + off_x, h + off_y);
GSVector4i rh(off_x, off_y, w + off_x, (h + off_y) & 0x7FF);
GSVector4i rw(off_x, off_y, (w + off_x) & 0x7FF, h + off_y);
GSVector4i r(off_x, off_y, w + off_x_end, h + off_y_end);
GSVector4i rh(off_x, off_y, w + off_x_end, (h + off_y_end) & 0x7FF);
GSVector4i rw(off_x, off_y, (w + off_x_end) & 0x7FF, h + off_y_end);
bool h_wrap = false;
bool w_wrap = false;
@ -159,9 +161,6 @@ GSTexture* GSRendererSW::GetOutput(int i, float& scale, int& y_offset)
// Top left rect
psm.rtx(m_mem, m_mem.GetOffset(curFramebuffer.Block(), curFramebuffer.FBW, curFramebuffer.PSM), r.ralign<Align_Outside>(psm.bs), m_output, pitch, texa);
// Top left rect
psm.rtx(m_mem, m_mem.GetOffset(curFramebuffer.Block(), curFramebuffer.FBW, curFramebuffer.PSM), r.ralign<Align_Outside>(psm.bs), m_output, pitch, texa);
int top = (h_wrap) ? ((r.bottom - r.top) * pitch) : 0;
int left = (w_wrap) ? (r.right - r.left) * (GSLocalMemory::m_psm[curFramebuffer.PSM].bpp / 8) : 0;