Large diffs are not rendered by default.

@@ -3,35 +3,24 @@

#pragma once

#include <array>
#include <memory>

#include "Common/CommonTypes.h"

enum class FieldType;
class PointerWrap;
namespace Core
{
class System;
}
namespace MMIO
{
class Mapping;
}

namespace VideoInterface
{
class VideoInterfaceState
{
public:
VideoInterfaceState();
VideoInterfaceState(const VideoInterfaceState&) = delete;
VideoInterfaceState(VideoInterfaceState&&) = delete;
VideoInterfaceState& operator=(const VideoInterfaceState&) = delete;
VideoInterfaceState& operator=(VideoInterfaceState&&) = delete;
~VideoInterfaceState();

struct Data;
Data& GetData() { return *m_data; }

private:
std::unique_ptr<Data> m_data;
};

// VI Internal Hardware Addresses
enum
{
@@ -360,41 +349,104 @@ union UVIHorizontalStepping
};
};

// For BS2 HLE
void Preset(bool _bNTSC);
class VideoInterfaceManager
{
public:
explicit VideoInterfaceManager(Core::System& system);
VideoInterfaceManager(const VideoInterfaceManager&) = delete;
VideoInterfaceManager(VideoInterfaceManager&&) = delete;
VideoInterfaceManager& operator=(const VideoInterfaceManager&) = delete;
VideoInterfaceManager& operator=(VideoInterfaceManager&&) = delete;
~VideoInterfaceManager();

void Init();
void DoState(PointerWrap& p);
// For BS2 HLE
void Preset(bool _bNTSC);

void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
void Init();
void DoState(PointerWrap& p);

// returns a pointer to the current visible xfb
u32 GetXFBAddressTop();
u32 GetXFBAddressBottom();
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);

// Update and draw framebuffer
void Update(u64 ticks);
// returns a pointer to the current visible xfb
u32 GetXFBAddressTop() const;
u32 GetXFBAddressBottom() const;

// UpdateInterrupts: check if we have to generate a new VI Interrupt
void UpdateInterrupts();
// Update and draw framebuffer
void Update(u64 ticks);

// Change values pertaining to video mode
void UpdateParameters();
// UpdateInterrupts: check if we have to generate a new VI Interrupt
void UpdateInterrupts();

double GetTargetRefreshRate();
u32 GetTargetRefreshRateNumerator();
u32 GetTargetRefreshRateDenominator();
// Change values pertaining to video mode
void UpdateParameters();

u32 GetTicksPerSample();
u32 GetTicksPerHalfLine();
u32 GetTicksPerField();
double GetTargetRefreshRate() const;
u32 GetTargetRefreshRateNumerator() const;
u32 GetTargetRefreshRateDenominator() const;

// Get the aspect ratio of VI's active area.
// This function only deals with standard aspect ratios. For widescreen aspect ratios, multiply the
// result by 1.33333..
float GetAspectRatio();
u32 GetTicksPerSample() const;
u32 GetTicksPerHalfLine() const;
u32 GetTicksPerField() const;

// Create a fake VI mode for a fifolog
void FakeVIUpdate(u32 xfb_address, u32 fb_width, u32 fb_stride, u32 fb_height);
// Get the aspect ratio of VI's active area.
// This function only deals with standard aspect ratios. For widescreen aspect ratios, multiply
// the result by 1.33333..
float GetAspectRatio() const;

// Create a fake VI mode for a fifolog
void FakeVIUpdate(u32 xfb_address, u32 fb_width, u32 fb_stride, u32 fb_height);

private:
u32 GetHalfLinesPerEvenField() const;
u32 GetHalfLinesPerOddField() const;
u32 GetTicksPerEvenField() const;
u32 GetTicksPerOddField() const;

void LogField(FieldType field, u32 xfb_address) const;
void OutputField(FieldType field, u64 ticks);
void BeginField(FieldType field, u64 ticks);
void EndField(FieldType field, u64 ticks);

// Registers listed in order:
UVIVerticalTimingRegister m_vertical_timing_register;
UVIDisplayControlRegister m_display_control_register;
UVIHorizontalTiming0 m_h_timing_0;
UVIHorizontalTiming1 m_h_timing_1;
UVIVBlankTimingRegister m_vblank_timing_odd;
UVIVBlankTimingRegister m_vblank_timing_even;
UVIBurstBlankingRegister m_burst_blanking_odd;
UVIBurstBlankingRegister m_burst_blanking_even;
UVIFBInfoRegister m_xfb_info_top;
UVIFBInfoRegister m_xfb_info_bottom;
UVIFBInfoRegister m_xfb_3d_info_top; // Start making your stereoscopic demos! :p
UVIFBInfoRegister m_xfb_3d_info_bottom;
std::array<UVIInterruptRegister, 4> m_interrupt_register{};
std::array<UVILatchRegister, 2> m_latch_register{};
PictureConfigurationRegister m_picture_configuration;
UVIHorizontalScaling m_horizontal_scaling;
SVIFilterCoefTables m_filter_coef_tables;
u32 m_unknown_aa_register = 0; // ??? 0x00FF0000
u16 m_clock = 0; // 0: 27MHz, 1: 54MHz
UVIDTVStatus m_dtv_status;
UVIHorizontalStepping m_fb_width; // Only correct when scaling is enabled?
UVIBorderBlankRegister m_border_hblank;
// 0xcc002076 - 0xcc00207f is full of 0x00FF: unknown
// 0xcc002080 - 0xcc002100 even more unknown

double m_target_refresh_rate = 0;
u32 m_target_refresh_rate_numerator = 0;
u32 m_target_refresh_rate_denominator = 1;

u64 m_ticks_last_line_start = 0; // number of ticks when the current full scanline started
u32 m_half_line_count = 0; // number of halflines that have occurred for this full frame
u32 m_half_line_of_next_si_poll = 0; // halfline when next SI poll results should be available

// below indexes are 0-based
u32 m_even_field_first_hl = 0; // index first halfline of the even field
u32 m_odd_field_first_hl = 0; // index first halfline of the odd field
u32 m_even_field_last_hl = 0; // index last halfline of the even field
u32 m_odd_field_last_hl = 0; // index last halfline of the odd field

Core::System& m_system;
};
} // namespace VideoInterface
@@ -96,7 +96,7 @@ static size_t s_state_writes_in_queue;
static std::condition_variable s_state_write_queue_is_empty;

// Don't forget to increase this after doing changes on the savestate system
constexpr u32 STATE_VERSION = 158; // Last changed in PR 11522
constexpr u32 STATE_VERSION = 159; // Last changed in PR 11640

// Maps savestate versions to Dolphin versions.
// Versions after 42 don't need to be added to this list,
@@ -38,7 +38,7 @@ struct System::Impl
explicit Impl(System& system)
: m_audio_interface(system), m_core_timing(system), m_dsp(system), m_dvd_interface(system),
m_dvd_thread(system), m_expansion_interface(system), m_gp_fifo(system),
m_ppc_state(PowerPC::ppcState)
m_ppc_state(PowerPC::ppcState), m_video_interface(system)
{
}

@@ -68,7 +68,7 @@ struct System::Impl
SerialInterface::SerialInterfaceState m_serial_interface_state;
Sram m_sram;
VertexShaderManager m_vertex_shader_manager;
VideoInterface::VideoInterfaceState m_video_interface_state;
VideoInterface::VideoInterfaceManager m_video_interface;
};

System::System() : m_impl{std::make_unique<Impl>(*this)}
@@ -224,8 +224,8 @@ VertexShaderManager& System::GetVertexShaderManager() const
return m_impl->m_vertex_shader_manager;
}

VideoInterface::VideoInterfaceState& System::GetVideoInterfaceState() const
VideoInterface::VideoInterfaceManager& System::GetVideoInterface() const
{
return m_impl->m_video_interface_state;
return m_impl->m_video_interface;
}
} // namespace Core
@@ -82,7 +82,7 @@ class SerialInterfaceState;
};
namespace VideoInterface
{
class VideoInterfaceState;
class VideoInterfaceManager;
};

namespace Core
@@ -141,7 +141,7 @@ class System
SerialInterface::SerialInterfaceState& GetSerialInterfaceState() const;
Sram& GetSRAM() const;
VertexShaderManager& GetVertexShaderManager() const;
VideoInterface::VideoInterfaceState& GetVideoInterfaceState() const;
VideoInterface::VideoInterfaceManager& GetVideoInterface() const;

private:
System();
@@ -366,7 +366,8 @@ static void BPWritten(PixelShaderManager& pixel_shader_manager,
{
if (FifoPlayer::GetInstance().IsRunningWithFakeVideoInterfaceUpdates())
{
VideoInterface::FakeVIUpdate(destAddr, srcRect.GetWidth(), destStride, height);
auto& vi = Core::System::GetInstance().GetVideoInterface();
vi.FakeVIUpdate(destAddr, srcRect.GetWidth(), destStride, height);
}
}
}
@@ -36,6 +36,7 @@ extern "C" {
#include "Core/ConfigManager.h"
#include "Core/HW/SystemTimers.h"
#include "Core/HW/VideoInterface.h"
#include "Core/System.h"

#include "VideoCommon/FrameDumper.h"
#include "VideoCommon/OnScreenDisplay.h"
@@ -65,10 +66,11 @@ namespace
{
AVRational GetTimeBaseForCurrentRefreshRate()
{
auto& vi = Core::System::GetInstance().GetVideoInterface();
int num;
int den;
av_reduce(&num, &den, int(VideoInterface::GetTargetRefreshRateDenominator()),
int(VideoInterface::GetTargetRefreshRateNumerator()), std::numeric_limits<int>::max());
av_reduce(&num, &den, int(vi.GetTargetRefreshRateDenominator()),
int(vi.GetTargetRefreshRateNumerator()), std::numeric_limits<int>::max());
return AVRational{num, den};
}

@@ -76,7 +76,8 @@ double PerformanceMetrics::GetMaxSpeed() const

double PerformanceMetrics::GetLastSpeedDenominator() const
{
return DT_s(m_speed_counter.GetLastRawDt()).count() * VideoInterface::GetTargetRefreshRate();
return DT_s(m_speed_counter.GetLastRawDt()).count() *
Core::System::GetInstance().GetVideoInterface().GetTargetRefreshRate();
}

void PerformanceMetrics::DrawImGuiStats(const float backbuffer_scale)
@@ -6,6 +6,7 @@
#include "Common/ChunkFile.h"
#include "Core/HW/VideoInterface.h"
#include "Core/Host.h"
#include "Core/System.h"

#include "InputCommon/ControllerInterface/ControllerInterface.h"

@@ -249,7 +250,8 @@ float Presenter::CalculateDrawAspectRatio() const
if (aspect_mode == AspectMode::Stretch)
return (static_cast<float>(m_backbuffer_width) / static_cast<float>(m_backbuffer_height));

const float aspect_ratio = VideoInterface::GetAspectRatio();
auto& vi = Core::System::GetInstance().GetVideoInterface();
const float aspect_ratio = vi.GetAspectRatio();

if (aspect_mode == AspectMode::AnalogWide ||
(aspect_mode == AspectMode::Auto && g_widescreen->IsGameWidescreen()))
@@ -378,7 +380,8 @@ void Presenter::UpdateDrawRectangle()
// Don't know if there is a better place for this code so there isn't a 1 frame delay
if (g_ActiveConfig.bWidescreenHack)
{
float source_aspect = VideoInterface::GetAspectRatio();
auto& vi = Core::System::GetInstance().GetVideoInterface();
float source_aspect = vi.GetAspectRatio();
if (g_widescreen->IsGameWidescreen())
source_aspect = AspectToWidescreen(source_aspect);