From 4d3c41c8a2cbfe61ae4208f69e7debda3aa8bf5e Mon Sep 17 00:00:00 2001 From: Scott Mansell Date: Mon, 23 Sep 2013 16:31:27 +1200 Subject: [PATCH] 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. --- Source/Core/Core/Src/HW/VideoInterface.cpp | 30 +++++++++++++++---- .../Plugins/Plugin_VideoDX11/Src/Render.cpp | 1 - Source/Plugins/Plugin_VideoDX9/Src/Render.cpp | 1 - Source/Plugins/Plugin_VideoOGL/Src/Render.cpp | 1 - 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/Source/Core/Core/Src/HW/VideoInterface.cpp b/Source/Core/Core/Src/HW/VideoInterface.cpp index e5d32a9a8f..efff0ac71a 100644 --- a/Source/Core/Core/Src/HW/VideoInterface.cpp +++ b/Source/Core/Core/Src/HW/VideoInterface.cpp @@ -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); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp index 4e412641b8..004ee91bde 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp @@ -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) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index 44c19dcace..a040cd7a16 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -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) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index 352058c26f..e87d80ff98 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -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))