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
|
// 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}
|
// our internal yuv444 type is not normalized, so black is {0, 0, 0} instead of {16, 128, 128}
|
||||||
yuv444 black;
|
yuv444 black;
|
||||||
|
@ -535,17 +535,17 @@ namespace EfbInterface
|
||||||
for (int i = 1, x = left; x < right; i+=2, x+=2)
|
for (int i = 1, x = left; x < right; i+=2, x+=2)
|
||||||
{
|
{
|
||||||
// YU pixel
|
// 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
|
// 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]
|
// 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);
|
xfb_in_ram[x].UV = 128 + ((scanline[i-1].U + (scanline[i].U << 1) + scanline[i+1].U) >> 2);
|
||||||
|
|
||||||
// YV pixel
|
// 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]
|
// 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[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
|
#endif
|
||||||
|
|
||||||
void SWRenderer::UpdateColorTexture(EfbInterface::yuv422_packed *xfb)
|
void SWRenderer::UpdateColorTexture(EfbInterface::yuv422_packed *xfb, u32 fbWidth, u32 fbHeight)
|
||||||
{
|
{
|
||||||
u32 offset = 0;
|
u32 offset = 0;
|
||||||
u8 *TexturePointer = s_xfbColorTexture[!s_currentColorTexture];
|
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
|
// We do this one color sample (aka 2 RGB pixles) at a time
|
||||||
int Y1 = xfb[x].Y - 16;
|
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++] = min(255.0f, max(0.0f, 1.164f * Y2 + 2.017f * U ));
|
||||||
TexturePointer[offset++] = 255;
|
TexturePointer[offset++] = 255;
|
||||||
}
|
}
|
||||||
xfb += EFB_WIDTH;
|
xfb += fbWidth;
|
||||||
}
|
}
|
||||||
s_currentColorTexture = !s_currentColorTexture;
|
s_currentColorTexture = !s_currentColorTexture;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace SWRenderer
|
||||||
void RenderText(const char* pstr, int left, int top, u32 color);
|
void RenderText(const char* pstr, int left, int top, u32 color);
|
||||||
void DrawDebugText();
|
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 DrawTexture(u8 *texture, int width, int height);
|
||||||
|
|
||||||
void Swap(u32 fbWidth, u32 fbHeight);
|
void Swap(u32 fbWidth, u32 fbHeight);
|
||||||
|
|
|
@ -225,19 +225,21 @@ void VideoSoftware::Video_EndField()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!g_SWVideoConfig.bHwRasterizer) {
|
if (!g_SWVideoConfig.bHwRasterizer) {
|
||||||
|
u32 xfbAddr = s_beginFieldArgs.xfbAddr;
|
||||||
|
if (s_beginFieldArgs.field != FIELD_PROGRESSIVE) {
|
||||||
|
// Force Progressive
|
||||||
|
xfbAddr = VideoInterface::GetXFBAddressTop();
|
||||||
|
|
||||||
// Force Progressive
|
// All drivers make an assumption that the two fields are interleaved in the framebuffer
|
||||||
u32 xfbAddr = VideoInterface::GetXFBAddressTop();
|
// Give a warning if this isn't true.
|
||||||
|
if (xfbAddr + 1280 != VideoInterface::GetXFBAddressBottom()) {
|
||||||
// All drivers make an assumption that the two fields are interleaved in the framebuffer
|
WARN_LOG(VIDEO, "Feilds are not interleaved in XFB as expected.");
|
||||||
// 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);
|
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
|
// Idealy we would just move all the opengl contex stuff to the CPU thread, but this gets
|
||||||
|
|
Loading…
Reference in New Issue