From fa8a4cdbb57e6036570088ad2b505d2dff6f7ec9 Mon Sep 17 00:00:00 2001 From: Scott Mansell Date: Tue, 20 Aug 2013 23:25:24 +1200 Subject: [PATCH 1/3] Corrected names of GetXFBAddress* functions in header. They were named incorrectly in VideoInterface.h, but because nobody used them outside of VideoInterface.cpp where they were decleared until now, this hasn't been an issue. --- Source/Core/Core/Src/HW/VideoInterface.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/Src/HW/VideoInterface.h b/Source/Core/Core/Src/HW/VideoInterface.h index 325d43f0800..59f21a6b82e 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(); From 4d3c41c8a2cbfe61ae4208f69e7debda3aa8bf5e Mon Sep 17 00:00:00 2001 From: Scott Mansell Date: Mon, 23 Sep 2013 16:31:27 +1200 Subject: [PATCH 2/3] 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 e5d32a9a8fc..efff0ac71a4 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 4e412641b8c..004ee91bde0 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 44c19dcaceb..a040cd7a16e 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 352058c26fd..e87d80ff98b 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)) From 440353a3a1b5b9bc0f990de8ac7e3a87df2d0987 Mon Sep 17 00:00:00 2001 From: Scott Mansell Date: Mon, 23 Sep 2013 18:29:31 +1200 Subject: [PATCH 3/3] Remove all refrences of field ordering from video backends. They were unused. --- Source/Core/Core/Src/HW/VideoInterface.cpp | 2 +- Source/Core/VideoCommon/Src/MainBase.cpp | 6 ++---- Source/Core/VideoCommon/Src/RenderBase.cpp | 4 +--- Source/Core/VideoCommon/Src/RenderBase.h | 2 +- Source/Core/VideoCommon/Src/VideoBackendBase.h | 4 ++-- Source/Plugins/Plugin_VideoDX11/Src/Render.cpp | 2 +- Source/Plugins/Plugin_VideoDX11/Src/Render.h | 2 +- Source/Plugins/Plugin_VideoDX9/Src/Render.cpp | 2 +- Source/Plugins/Plugin_VideoDX9/Src/Render.h | 2 +- Source/Plugins/Plugin_VideoOGL/Src/Render.cpp | 2 +- Source/Plugins/Plugin_VideoOGL/Src/Render.h | 2 +- Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp | 2 +- Source/Plugins/Plugin_VideoSoftware/Src/VideoBackend.h | 2 +- 13 files changed, 15 insertions(+), 19 deletions(-) diff --git a/Source/Core/Core/Src/HW/VideoInterface.cpp b/Source/Core/Core/Src/HW/VideoInterface.cpp index efff0ac71a4..a3d5f41d358 100644 --- a/Source/Core/Core/Src/HW/VideoInterface.cpp +++ b/Source/Core/Core/Src/HW/VideoInterface.cpp @@ -834,7 +834,7 @@ static void BeginField(FieldType field) 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/VideoCommon/Src/MainBase.cpp b/Source/Core/VideoCommon/Src/MainBase.cpp index 17396835625..9df7ba93258 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 e4e330d6f5a..e06b00cdea4 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 84849f476e4..7d9f3f857cf 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 9c591d05a5b..cc4ff15416f 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 004ee91bde0..d58cc59e982 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) { diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.h b/Source/Plugins/Plugin_VideoDX11/Src/Render.h index 8f6c78fae1b..1fddfdb2445 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 a040cd7a16e..b70ed2d48b8 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) { diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.h b/Source/Plugins/Plugin_VideoDX9/Src/Render.h index 6e5198b3cdb..cc53d36e89f 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 e87d80ff98b..37b22b3e6fe 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -1289,7 +1289,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) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.h b/Source/Plugins/Plugin_VideoOGL/Src/Render.h index a570faab85e..0235b3b24f7 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.h @@ -71,7 +71,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 7fd384afa3d..7f6792fc1ce 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 a105e66eba0..6c382aa0b29 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);