diff --git a/Source/Core/Core/Src/HW/VideoInterface.cpp b/Source/Core/Core/Src/HW/VideoInterface.cpp index e5d32a9a8f..a3d5f41d35 100644 --- a/Source/Core/Core/Src/HW/VideoInterface.cpp +++ b/Source/Core/Core/Src/HW/VideoInterface.cpp @@ -803,20 +803,38 @@ 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); + g_video_backend->Video_BeginField(xfbAddr, fbWidth, fbHeight); } static void EndField() diff --git a/Source/Core/Core/Src/HW/VideoInterface.h b/Source/Core/Core/Src/HW/VideoInterface.h index 325d43f080..59f21a6b82 100644 --- a/Source/Core/Core/Src/HW/VideoInterface.h +++ b/Source/Core/Core/Src/HW/VideoInterface.h @@ -333,8 +333,8 @@ union UVIDTVStatus void Write32(const u32 _uValue, const u32 _uAddress); // returns a pointer to the current visible xfb - u8* GetXFBPointerTop(); - u8* GetXFBPointerBottom(); + u32 GetXFBAddressTop(); + u32 GetXFBAddressBottom(); // Update and draw framebuffer void Update(); diff --git a/Source/Core/VideoCommon/Src/MainBase.cpp b/Source/Core/VideoCommon/Src/MainBase.cpp index 1739683562..9df7ba9325 100644 --- a/Source/Core/VideoCommon/Src/MainBase.cpp +++ b/Source/Core/VideoCommon/Src/MainBase.cpp @@ -28,7 +28,6 @@ static volatile bool s_perf_query_requested; static volatile struct { u32 xfbAddr; - FieldType field; u32 fbWidth; u32 fbHeight; } s_beginFieldArgs; @@ -73,7 +72,7 @@ void VideoFifo_CheckSwapRequest() if (Common::AtomicLoadAcquire(s_swapRequested)) { EFBRectangle rc; - g_renderer->Swap(s_beginFieldArgs.xfbAddr, s_beginFieldArgs.field, s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight,rc); + g_renderer->Swap(s_beginFieldArgs.xfbAddr, s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight,rc); Common::AtomicStoreRelease(s_swapRequested, false); } } @@ -98,14 +97,13 @@ void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight) } // Run from the CPU thread (from VideoInterface.cpp) -void VideoBackendHardware::Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight) +void VideoBackendHardware::Video_BeginField(u32 xfbAddr, u32 fbWidth, u32 fbHeight) { if (s_BackendInitialized && g_ActiveConfig.bUseXFB) { if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread) VideoFifo_CheckSwapRequest(); s_beginFieldArgs.xfbAddr = xfbAddr; - s_beginFieldArgs.field = field; s_beginFieldArgs.fbWidth = fbWidth; s_beginFieldArgs.fbHeight = fbHeight; } diff --git a/Source/Core/VideoCommon/Src/RenderBase.cpp b/Source/Core/VideoCommon/Src/RenderBase.cpp index e4e330d6f5..e06b00cdea 100644 --- a/Source/Core/VideoCommon/Src/RenderBase.cpp +++ b/Source/Core/VideoCommon/Src/RenderBase.cpp @@ -120,9 +120,7 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect } else { - // XXX: Without the VI, how would we know what kind of field this is? So - // just use progressive. - g_renderer->Swap(xfbAddr, FIELD_PROGRESSIVE, fbWidth, fbHeight,sourceRc,Gamma); + g_renderer->Swap(xfbAddr, fbWidth, fbHeight,sourceRc,Gamma); Common::AtomicStoreRelease(s_swapRequested, false); } } diff --git a/Source/Core/VideoCommon/Src/RenderBase.h b/Source/Core/VideoCommon/Src/RenderBase.h index 84849f476e..7d9f3f857c 100644 --- a/Source/Core/VideoCommon/Src/RenderBase.h +++ b/Source/Core/VideoCommon/Src/RenderBase.h @@ -106,7 +106,7 @@ public: virtual void RestoreAPIState() = 0; // Finish up the current frame, print some stats - virtual void Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc,float Gamma = 1.0f) = 0; + virtual void Swap(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc,float Gamma = 1.0f) = 0; virtual void UpdateViewport(Matrix44& vpCorrection) = 0; diff --git a/Source/Core/VideoCommon/Src/VideoBackendBase.h b/Source/Core/VideoCommon/Src/VideoBackendBase.h index 9c591d05a5..cc4ff15416 100644 --- a/Source/Core/VideoCommon/Src/VideoBackendBase.h +++ b/Source/Core/VideoCommon/Src/VideoBackendBase.h @@ -93,7 +93,7 @@ public: virtual void Video_ExitLoop() = 0; virtual void Video_Cleanup() = 0; // called from gl/d3d thread - virtual void Video_BeginField(u32, FieldType, u32, u32) = 0; + virtual void Video_BeginField(u32, u32, u32) = 0; virtual void Video_EndField() = 0; virtual u32 Video_AccessEFB(EFBAccessType, u32, u32, u32) = 0; @@ -145,7 +145,7 @@ class VideoBackendHardware : public VideoBackend void Video_EnterLoop(); void Video_ExitLoop(); - void Video_BeginField(u32, FieldType, u32, u32); + void Video_BeginField(u32, u32, u32); void Video_EndField(); u32 Video_AccessEFB(EFBAccessType, u32, u32, u32); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp index 4e412641b8..d58cc59e98 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp @@ -776,7 +776,7 @@ void formatBufferDump(const u8* in, u8* out, int w, int h, int p) } // This function has the final picture. We adjust the aspect ratio here. -void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma) +void Renderer::Swap(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma) { if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) || !fbWidth || !fbHeight) { @@ -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_VideoDX11/Src/Render.h b/Source/Plugins/Plugin_VideoDX11/Src/Render.h index 8f6c78fae1..1fddfdb244 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.h @@ -40,7 +40,7 @@ public: TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc); - void Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc,float Gamma); + void Swap(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc,float Gamma); void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index 44c19dcace..b70ed2d48b 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -748,7 +748,7 @@ bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle } // This function has the final picture. We adjust the aspect ratio here. -void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma) +void Renderer::Swap(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma) { if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) || !fbWidth || !fbHeight) { @@ -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_VideoDX9/Src/Render.h b/Source/Plugins/Plugin_VideoDX9/Src/Render.h index 6e5198b3cd..cc53d36e89 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.h @@ -36,7 +36,7 @@ public: TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc); - void Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc,float Gamma); + void Swap(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc,float Gamma); void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index 3e5862dbe9..22a58dd9ab 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -1283,7 +1283,7 @@ void DumpFrame(const std::vector& data, int w, int h) } // This function has the final picture. We adjust the aspect ratio here. -void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma) +void Renderer::Swap(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma) { static int w = 0, h = 0; if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) || !fbWidth || !fbHeight) @@ -1293,7 +1293,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)) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.h b/Source/Plugins/Plugin_VideoOGL/Src/Render.h index 7f7ae6233c..bf33f015e6 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.h @@ -70,7 +70,7 @@ public: TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc); - void Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc,float Gamma); + void Swap(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& rc,float Gamma); void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z); diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp index 7fd384afa3..7f6792fc1c 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp @@ -187,7 +187,7 @@ void VideoSoftware::Video_Prepare() } // Run from the CPU thread (from VideoInterface.cpp) -void VideoSoftware::Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight) +void VideoSoftware::Video_BeginField(u32 xfbAddr, u32 fbWidth, u32 fbHeight) { } diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/VideoBackend.h b/Source/Plugins/Plugin_VideoSoftware/Src/VideoBackend.h index a105e66eba..6c382aa0b2 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/VideoBackend.h +++ b/Source/Plugins/Plugin_VideoSoftware/Src/VideoBackend.h @@ -25,7 +25,7 @@ class VideoSoftware : public VideoBackend void Video_EnterLoop(); void Video_ExitLoop(); - void Video_BeginField(u32, FieldType, u32, u32); + void Video_BeginField(u32, u32, u32); void Video_EndField(); u32 Video_AccessEFB(EFBAccessType, u32, u32, u32);