FifoPlayer: Generate fake VideoInterface updates

This commit is contained in:
iwubcode 2017-06-26 14:49:32 -05:00
parent 2cd9565b18
commit 5a372020ea
7 changed files with 72 additions and 2 deletions

View File

@ -72,6 +72,11 @@ FifoDataFile::FifoDataFile() = default;
FifoDataFile::~FifoDataFile() = default;
bool FifoDataFile::ShouldGenerateFakeVIUpdates() const
{
return true;
}
bool FifoDataFile::HasBrokenEFBCopies() const
{
return m_Version < 2;

View File

@ -60,6 +60,7 @@ public:
void SetIsWii(bool isWii);
bool GetIsWii() const;
bool HasBrokenEFBCopies() const;
bool ShouldGenerateFakeVIUpdates() const;
u32* GetBPMem() { return m_BPMem; }
u32* GetCPMem() { return m_CPMem; }

View File

@ -162,6 +162,16 @@ std::unique_ptr<CPUCoreBase> FifoPlayer::GetCPUCore()
return std::make_unique<CPUCore>(this);
}
bool FifoPlayer::IsRunningWithFakeVideoInterfaceUpdates() const
{
if (!m_File || m_File->GetFrameCount() == 0)
{
return false;
}
return m_File->ShouldGenerateFakeVIUpdates();
}
u32 FifoPlayer::GetFrameObjectCount() const
{
if (m_CurrentFrame < m_FrameInfo.size())

View File

@ -94,6 +94,8 @@ public:
void SetFrameWrittenCallback(CallbackFunc callback) { m_FrameWrittenCb = callback; }
static FifoPlayer& GetInstance();
bool IsRunningWithFakeVideoInterfaceUpdates() const;
private:
class CPUCore;

View File

@ -18,6 +18,7 @@
#include "Core/ConfigManager.h"
#include "Core/Core.h"
#include "Core/CoreTiming.h"
#include "Core/FifoPlayer/FifoPlayer.h"
#include "Core/HW/MMIO.h"
#include "Core/HW/ProcessorInterface.h"
#include "Core/HW/SI/SI.h"
@ -549,8 +550,9 @@ float GetAspectRatio()
// 5. Calculate the final ratio and scale to 4:3
float ratio = horizontal_active_ratio / vertical_active_ratio;
if (std::isnormal(
ratio)) // Check we have a sane ratio and haven't propagated any infs/nans/zeros
bool running_fifo_log = FifoPlayer::GetInstance().IsRunningWithFakeVideoInterfaceUpdates();
if (std::isnormal(ratio) && // Check we have a sane ratio without any infs/nans/zeros
!running_fifo_log) // we don't know the correct ratio for fifos
return ratio * (4.0f / 3.0f); // Scale to 4:3
else
return (4.0f / 3.0f); // VI isn't initialized correctly, just return 4:3 instead
@ -775,4 +777,44 @@ void Update(u64 ticks)
UpdateInterrupts();
}
// Create a fake VI mode for a fifolog
void FakeVIUpdate(u32 xfb_address, u32 fb_width, u32 fb_height)
{
u32 fb_stride = fb_width;
bool interlaced = fb_height > 480 / 2;
if (interlaced)
{
fb_height = fb_height / 2;
fb_stride = fb_stride * 2;
}
m_XFBInfoTop.POFF = 1;
m_XFBInfoBottom.POFF = 1;
m_VerticalTimingRegister.ACV = fb_height;
m_VerticalTimingRegister.EQU = 6;
m_VBlankTimingOdd.PRB = 502 - fb_height * 2;
m_VBlankTimingOdd.PSB = 5;
m_VBlankTimingEven.PRB = 503 - fb_height * 2;
m_VBlankTimingEven.PSB = 4;
m_PictureConfiguration.WPL = fb_width / 16;
m_PictureConfiguration.STD = fb_stride / 16;
UpdateParameters();
u32 total_halflines = GetHalfLinesPerEvenField() + GetHalfLinesPerOddField();
if ((s_half_line_count - s_even_field_first_hl) % total_halflines <
(s_half_line_count - s_odd_field_first_hl) % total_halflines)
{
// Even/Bottom field is next.
m_XFBInfoBottom.FBB = interlaced ? (xfb_address + fb_width * 2) >> 5 : xfb_address >> 5;
}
else
{
// Odd/Top field is next
m_XFBInfoTop.FBB = (xfb_address >> 5);
}
}
} // namespace

View File

@ -373,4 +373,7 @@ u32 GetTicksPerField();
// result by 1.33333..
float GetAspectRatio();
// Create a fake VI mode for a fifolog
void FakeVIUpdate(u32 xfb_address, u32 fb_width, u32 fb_height);
} // namespace VideoInterface

View File

@ -12,8 +12,10 @@
#include "Common/StringUtil.h"
#include "Common/Thread.h"
#include "Core/ConfigManager.h"
#include "Core/FifoPlayer/FifoPlayer.h"
#include "Core/FifoPlayer/FifoRecorder.h"
#include "Core/HW/Memmap.h"
#include "Core/HW/VideoInterface.h"
#include "VideoCommon/BPFunctions.h"
#include "VideoCommon/BPMemory.h"
@ -263,6 +265,11 @@ static void BPWritten(const BPCmd& bp)
// This stays in to signal end of a "frame"
g_renderer->RenderToXFB(destAddr, srcRect, destStride, height, s_gammaLUT[PE_copy.gamma]);
if (FifoPlayer::GetInstance().IsRunningWithFakeVideoInterfaceUpdates())
{
VideoInterface::FakeVIUpdate(destAddr, srcRect.GetWidth(), height);
}
}
// Clear the rectangular region after copying it.