commit
0696fc93b2
|
@ -803,20 +803,38 @@ static void BeginField(FieldType field)
|
||||||
{
|
{
|
||||||
u32 fbWidth = m_HorizontalStepping.FieldSteps * 16;
|
u32 fbWidth = m_HorizontalStepping.FieldSteps * 16;
|
||||||
u32 fbHeight = (m_HorizontalStepping.FbSteps / m_HorizontalStepping.FieldSteps) * m_VerticalTimingRegister.ACV;
|
u32 fbHeight = (m_HorizontalStepping.FbSteps / m_HorizontalStepping.FieldSteps) * m_VerticalTimingRegister.ACV;
|
||||||
|
u32 xfbAddr;
|
||||||
|
|
||||||
// NTSC and PAL have opposite field orders.
|
// NTSC and PAL have opposite field orders.
|
||||||
FieldType order = (m_DisplayControlRegister.FMT == 0) ? FIELD_LOWER : FIELD_UPPER;
|
if (m_DisplayControlRegister.FMT == 1) // PAL
|
||||||
u32 xfbAddr = (field == order) ? GetXFBAddressBottom() : GetXFBAddressTop();
|
{
|
||||||
|
// 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" };
|
static const char* const fieldTypeNames[] = { "Progressive", "Upper", "Lower" };
|
||||||
|
|
||||||
DEBUG_LOG(VIDEOINTERFACE, "(VI->BeginField): Address: %.08X | FieldSteps %u | FbSteps %u | ACV %u | Field %s",
|
DEBUG_LOG(VIDEOINTERFACE,
|
||||||
xfbAddr, m_HorizontalStepping.FieldSteps, m_HorizontalStepping.FbSteps, m_VerticalTimingRegister.ACV,
|
"(VI->BeginField): Address: %.08X | FieldSteps %u | FbSteps %u | ACV %u | Field %s",
|
||||||
fieldTypeNames[field]
|
xfbAddr, m_HorizontalStepping.FieldSteps,m_HorizontalStepping.FbSteps,
|
||||||
);
|
m_VerticalTimingRegister.ACV, fieldTypeNames[field]);
|
||||||
|
|
||||||
if (xfbAddr)
|
if (xfbAddr)
|
||||||
g_video_backend->Video_BeginField(xfbAddr, field, fbWidth, fbHeight);
|
g_video_backend->Video_BeginField(xfbAddr, fbWidth, fbHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EndField()
|
static void EndField()
|
||||||
|
|
|
@ -333,8 +333,8 @@ union UVIDTVStatus
|
||||||
void Write32(const u32 _uValue, const u32 _uAddress);
|
void Write32(const u32 _uValue, const u32 _uAddress);
|
||||||
|
|
||||||
// returns a pointer to the current visible xfb
|
// returns a pointer to the current visible xfb
|
||||||
u8* GetXFBPointerTop();
|
u32 GetXFBAddressTop();
|
||||||
u8* GetXFBPointerBottom();
|
u32 GetXFBAddressBottom();
|
||||||
|
|
||||||
// Update and draw framebuffer
|
// Update and draw framebuffer
|
||||||
void Update();
|
void Update();
|
||||||
|
|
|
@ -28,7 +28,6 @@ static volatile bool s_perf_query_requested;
|
||||||
static volatile struct
|
static volatile struct
|
||||||
{
|
{
|
||||||
u32 xfbAddr;
|
u32 xfbAddr;
|
||||||
FieldType field;
|
|
||||||
u32 fbWidth;
|
u32 fbWidth;
|
||||||
u32 fbHeight;
|
u32 fbHeight;
|
||||||
} s_beginFieldArgs;
|
} s_beginFieldArgs;
|
||||||
|
@ -73,7 +72,7 @@ void VideoFifo_CheckSwapRequest()
|
||||||
if (Common::AtomicLoadAcquire(s_swapRequested))
|
if (Common::AtomicLoadAcquire(s_swapRequested))
|
||||||
{
|
{
|
||||||
EFBRectangle rc;
|
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);
|
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)
|
// 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 (s_BackendInitialized && g_ActiveConfig.bUseXFB)
|
||||||
{
|
{
|
||||||
if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread)
|
if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread)
|
||||||
VideoFifo_CheckSwapRequest();
|
VideoFifo_CheckSwapRequest();
|
||||||
s_beginFieldArgs.xfbAddr = xfbAddr;
|
s_beginFieldArgs.xfbAddr = xfbAddr;
|
||||||
s_beginFieldArgs.field = field;
|
|
||||||
s_beginFieldArgs.fbWidth = fbWidth;
|
s_beginFieldArgs.fbWidth = fbWidth;
|
||||||
s_beginFieldArgs.fbHeight = fbHeight;
|
s_beginFieldArgs.fbHeight = fbHeight;
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,9 +120,7 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// XXX: Without the VI, how would we know what kind of field this is? So
|
g_renderer->Swap(xfbAddr, fbWidth, fbHeight,sourceRc,Gamma);
|
||||||
// just use progressive.
|
|
||||||
g_renderer->Swap(xfbAddr, FIELD_PROGRESSIVE, fbWidth, fbHeight,sourceRc,Gamma);
|
|
||||||
Common::AtomicStoreRelease(s_swapRequested, false);
|
Common::AtomicStoreRelease(s_swapRequested, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@ public:
|
||||||
virtual void RestoreAPIState() = 0;
|
virtual void RestoreAPIState() = 0;
|
||||||
|
|
||||||
// Finish up the current frame, print some stats
|
// 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;
|
virtual void UpdateViewport(Matrix44& vpCorrection) = 0;
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ public:
|
||||||
virtual void Video_ExitLoop() = 0;
|
virtual void Video_ExitLoop() = 0;
|
||||||
virtual void Video_Cleanup() = 0; // called from gl/d3d thread
|
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 void Video_EndField() = 0;
|
||||||
|
|
||||||
virtual u32 Video_AccessEFB(EFBAccessType, u32, u32, u32) = 0;
|
virtual u32 Video_AccessEFB(EFBAccessType, u32, u32, u32) = 0;
|
||||||
|
@ -145,7 +145,7 @@ class VideoBackendHardware : public VideoBackend
|
||||||
|
|
||||||
void Video_EnterLoop();
|
void Video_EnterLoop();
|
||||||
void Video_ExitLoop();
|
void Video_ExitLoop();
|
||||||
void Video_BeginField(u32, FieldType, u32, u32);
|
void Video_BeginField(u32, u32, u32);
|
||||||
void Video_EndField();
|
void Video_EndField();
|
||||||
|
|
||||||
u32 Video_AccessEFB(EFBAccessType, u32, u32, u32);
|
u32 Video_AccessEFB(EFBAccessType, u32, u32, u32);
|
||||||
|
|
|
@ -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.
|
// 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)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2;
|
|
||||||
u32 xfbCount = 0;
|
u32 xfbCount = 0;
|
||||||
const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
||||||
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
|
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
|
||||||
|
|
|
@ -40,7 +40,7 @@ public:
|
||||||
|
|
||||||
TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc);
|
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);
|
void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z);
|
||||||
|
|
||||||
|
|
|
@ -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.
|
// 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)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2;
|
|
||||||
u32 xfbCount = 0;
|
u32 xfbCount = 0;
|
||||||
const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
||||||
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
|
if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB)
|
||||||
|
|
|
@ -36,7 +36,7 @@ public:
|
||||||
|
|
||||||
TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc);
|
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);
|
void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z);
|
||||||
|
|
||||||
|
|
|
@ -1283,7 +1283,7 @@ void DumpFrame(const std::vector<u8>& data, int w, int h)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function has the final picture. We adjust the aspect ratio here.
|
// 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;
|
static int w = 0, h = 0;
|
||||||
if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) || !fbWidth || !fbHeight)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field == FIELD_LOWER) xfbAddr -= fbWidth * 2;
|
|
||||||
u32 xfbCount = 0;
|
u32 xfbCount = 0;
|
||||||
const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount);
|
||||||
if (g_ActiveConfig.VirtualXFBEnabled() && (!xfbSourceList || xfbCount == 0))
|
if (g_ActiveConfig.VirtualXFBEnabled() && (!xfbSourceList || xfbCount == 0))
|
||||||
|
|
|
@ -70,7 +70,7 @@ public:
|
||||||
|
|
||||||
TargetRectangle ConvertEFBRectangle(const EFBRectangle& rc);
|
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);
|
void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z);
|
||||||
|
|
||||||
|
|
|
@ -187,7 +187,7 @@ void VideoSoftware::Video_Prepare()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run from the CPU thread (from VideoInterface.cpp)
|
// 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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ class VideoSoftware : public VideoBackend
|
||||||
|
|
||||||
void Video_EnterLoop();
|
void Video_EnterLoop();
|
||||||
void Video_ExitLoop();
|
void Video_ExitLoop();
|
||||||
void Video_BeginField(u32, FieldType, u32, u32);
|
void Video_BeginField(u32, u32, u32);
|
||||||
void Video_EndField();
|
void Video_EndField();
|
||||||
|
|
||||||
u32 Video_AccessEFB(EFBAccessType, u32, u32, u32);
|
u32 Video_AccessEFB(EFBAccessType, u32, u32, u32);
|
||||||
|
|
Loading…
Reference in New Issue