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.
This commit is contained in:
Scott Mansell 2013-11-23 18:38:15 +13:00
parent 2abcc32bbd
commit a94940edd3
4 changed files with 19 additions and 17 deletions

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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