From a94940edd365ac4ec9334c8e696bc5466fe02cb1 Mon Sep 17 00:00:00 2001 From: Scott Mansell Date: Sat, 23 Nov 2013 18:38:15 +1300 Subject: [PATCH] Videosoftware realxfb: Fixed a few bugs while testing Zelda: Collectors Edition * Don't force a frame to be progressive if it's already progressive. * Don't assume the framebuffer will be 640 pixels wide * Remember to offset the Luma channel by 16. --- .../Plugin_VideoSoftware/Src/EfbInterface.cpp | 8 ++++---- .../Plugin_VideoSoftware/Src/SWRenderer.cpp | 8 ++++---- .../Plugin_VideoSoftware/Src/SWRenderer.h | 2 +- .../Plugin_VideoSoftware/Src/SWmain.cpp | 18 ++++++++++-------- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/EfbInterface.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/EfbInterface.cpp index 446d9d8495..d20ea39b96 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/EfbInterface.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/EfbInterface.cpp @@ -511,7 +511,7 @@ namespace EfbInterface } // Scanline buffer, leave room for borders - yuv444 scanline[640+2]; + yuv444 scanline[fbWidth+2]; // our internal yuv444 type is not normalized, so black is {0, 0, 0} instead of {16, 128, 128} yuv444 black; @@ -535,17 +535,17 @@ namespace EfbInterface for (int i = 1, x = left; x < right; i+=2, x+=2) { // YU pixel - xfb_in_ram[x].Y = scanline[i].Y; + xfb_in_ram[x].Y = scanline[i].Y + 16; // we mix our color difrences in 10 bit space so it will round more accurately // U[i] = 1/4 * U[i-1] + 1/2 * U[i] + 1/4 * U[i+1] xfb_in_ram[x].UV = 128 + ((scanline[i-1].U + (scanline[i].U << 1) + scanline[i+1].U) >> 2); // YV pixel - xfb_in_ram[x+1].Y = scanline[i+1].Y; + xfb_in_ram[x+1].Y = scanline[i+1].Y + 16; // V[i] = 1/4 * V[i-1] + 1/2 * V[i] + 1/4 * V[i+1] xfb_in_ram[x+1].UV = 128 + ((scanline[i].V + (scanline[i+1].V << 1) + scanline[i+2].V) >> 2); } - xfb_in_ram += 640; + xfb_in_ram += fbWidth; } } diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWRenderer.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWRenderer.cpp index 2ca459e886..23ff15d883 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWRenderer.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWRenderer.cpp @@ -172,14 +172,14 @@ void DrawButton(GLuint tex, float *coords) } #endif -void SWRenderer::UpdateColorTexture(EfbInterface::yuv422_packed *xfb) +void SWRenderer::UpdateColorTexture(EfbInterface::yuv422_packed *xfb, u32 fbWidth, u32 fbHeight) { u32 offset = 0; u8 *TexturePointer = s_xfbColorTexture[!s_currentColorTexture]; - for (u16 y = 0; y < EFB_HEIGHT; y++) + for (u16 y = 0; y < fbHeight; y++) { - for (u16 x = 0; x < EFB_WIDTH; x+=2) + for (u16 x = 0; x < fbWidth; x+=2) { // We do this one color sample (aka 2 RGB pixles) at a time int Y1 = xfb[x].Y - 16; @@ -199,7 +199,7 @@ void SWRenderer::UpdateColorTexture(EfbInterface::yuv422_packed *xfb) TexturePointer[offset++] = min(255.0f, max(0.0f, 1.164f * Y2 + 2.017f * U )); TexturePointer[offset++] = 255; } - xfb += EFB_WIDTH; + xfb += fbWidth; } s_currentColorTexture = !s_currentColorTexture; } diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWRenderer.h b/Source/Plugins/Plugin_VideoSoftware/Src/SWRenderer.h index 44fc111c9e..6b75dbd1b9 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWRenderer.h +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWRenderer.h @@ -17,7 +17,7 @@ namespace SWRenderer void RenderText(const char* pstr, int left, int top, u32 color); void DrawDebugText(); - void UpdateColorTexture(EfbInterface::yuv422_packed *xfb); + void UpdateColorTexture(EfbInterface::yuv422_packed *xfb, u32 fbWidth, u32 fbHeight); void DrawTexture(u8 *texture, int width, int height); void Swap(u32 fbWidth, u32 fbHeight); diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp index 3f37d58f2f..6773fd9e0e 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp @@ -225,19 +225,21 @@ void VideoSoftware::Video_EndField() return; } if (!g_SWVideoConfig.bHwRasterizer) { + u32 xfbAddr = s_beginFieldArgs.xfbAddr; + if (s_beginFieldArgs.field != FIELD_PROGRESSIVE) { + // Force Progressive + xfbAddr = VideoInterface::GetXFBAddressTop(); - // Force Progressive - u32 xfbAddr = VideoInterface::GetXFBAddressTop(); - - // All drivers make an assumption that the two fields are interleaved in the framebuffer - // Give a warning if this isn't true. - if (xfbAddr + 1280 != VideoInterface::GetXFBAddressBottom()) { - WARN_LOG(VIDEO, "Feilds are not interleaved in XFB as expected."); + // All drivers make an assumption that the two fields are interleaved in the framebuffer + // Give a warning if this isn't true. + if (xfbAddr + 1280 != VideoInterface::GetXFBAddressBottom()) { + WARN_LOG(VIDEO, "Feilds are not interleaved in XFB as expected."); + } } EfbInterface::yuv422_packed *xfb = (EfbInterface::yuv422_packed *) Memory::GetPointer(xfbAddr); - SWRenderer::UpdateColorTexture(xfb); + SWRenderer::UpdateColorTexture(xfb, s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight); } // Idealy we would just move all the opengl contex stuff to the CPU thread, but this gets