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:
parent
2abcc32bbd
commit
a94940edd3
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
u32 xfbAddr = VideoInterface::GetXFBAddressTop();
|
||||
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.");
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue