Fixed issues with feild ordering.

This commit fixes issues with PAL games which use the incorrect feild
ordering.
We move all code that deals with indivudal fields from the indivudal
video plugins and VideoCommon and make VideoInterface always pass in
the start address of the whole XFB into VideoCommon.
This commit is contained in:
Scott Mansell 2013-09-23 16:31:27 +12:00
parent 4758ef9a9e
commit 4d3c41c8a2
4 changed files with 24 additions and 9 deletions

View File

@ -803,17 +803,35 @@ static void BeginField(FieldType field)
{
u32 fbWidth = m_HorizontalStepping.FieldSteps * 16;
u32 fbHeight = (m_HorizontalStepping.FbSteps / m_HorizontalStepping.FieldSteps) * m_VerticalTimingRegister.ACV;
u32 xfbAddr;
// NTSC and PAL have opposite field orders.
FieldType order = (m_DisplayControlRegister.FMT == 0) ? FIELD_LOWER : FIELD_UPPER;
u32 xfbAddr = (field == order) ? GetXFBAddressBottom() : GetXFBAddressTop();
if (m_DisplayControlRegister.FMT == 1) // PAL
{
// But the PAL ports of some games are poorly programmed and don't use correct ordering.
// Zelda: Wind Waker and Simpsons Hit & Run are exampes of this, there are probally more.
// PAL Wind Waker also runs at 30fps instead of 25.
if(field == FieldType::FIELD_PROGRESSIVE || GetXFBAddressBottom() != (GetXFBAddressTop() - 1280))
{
WARN_LOG(VIDEOINTERFACE, "PAL game is trying to use incorrect (NTSC) field ordering");
// Lets kindly fix this for them.
xfbAddr = GetXFBAddressTop();
// TODO: PAL Simpsons Hit & Run now has a green line at the bottom when Real XFB is used.
// Might be a bug later on in our code, or a bug in the actual game.
} else {
xfbAddr = GetXFBAddressBottom();
}
} else {
xfbAddr = GetXFBAddressTop();
}
static const char* const fieldTypeNames[] = { "Progressive", "Upper", "Lower" };
DEBUG_LOG(VIDEOINTERFACE, "(VI->BeginField): Address: %.08X | FieldSteps %u | FbSteps %u | ACV %u | Field %s",
xfbAddr, m_HorizontalStepping.FieldSteps, m_HorizontalStepping.FbSteps, m_VerticalTimingRegister.ACV,
fieldTypeNames[field]
);
DEBUG_LOG(VIDEOINTERFACE,
"(VI->BeginField): Address: %.08X | FieldSteps %u | FbSteps %u | ACV %u | Field %s",
xfbAddr, m_HorizontalStepping.FieldSteps,m_HorizontalStepping.FbSteps,
m_VerticalTimingRegister.ACV, fieldTypeNames[field]);
if (xfbAddr)
g_video_backend->Video_BeginField(xfbAddr, field, fbWidth, fbHeight);

View File

@ -787,7 +787,6 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
return;
}
if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2;
u32 xfbCount = 0;
const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)

View File

@ -759,7 +759,6 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
return;
}
if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2;
u32 xfbCount = 0;
const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)

View File

@ -1299,7 +1299,6 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
return;
}
if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2;
u32 xfbCount = 0;
const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
if (g_ActiveConfig.VirtualXFBEnabled() && (!xfbSourceList || xfbCount == 0))