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 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(); 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 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)) 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 efff0ac71a..a3d5f41d35 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 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 004ee91bde..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) { 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 a040cd7a16..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) { 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 e87d80ff98..37b22b3e6f 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 a570faab85..0235b3b24f 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 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);