diff --git a/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp b/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp index 6d15c8226a..7c4d2fd320 100644 --- a/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp +++ b/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp @@ -29,6 +29,7 @@ #include "ConfigManager.h" #include "Core.h" #include "HW/SystemTimers.h" +#include "HW/VideoInterface.h" DSPHLE::DSPHLE() { m_InitMixer = false; @@ -91,7 +92,7 @@ void DSPHLE::DSP_Update(int cycles) u32 DSPHLE::DSP_UpdateRate() { // AX HLE uses 3ms (Wii) or 5ms (GC) timing period - int fields = SConfig::GetInstance().m_LocalCoreStartupParameter.bVBeam ? 2 : 1; + int fields = VideoInterface::GetNumFields(); if (m_pUCode != NULL) return (SystemTimers::GetTicksPerSecond() / 1000) * m_pUCode->GetUpdateMs() / fields; else diff --git a/Source/Core/Core/Src/HW/SystemTimers.cpp b/Source/Core/Core/Src/HW/SystemTimers.cpp index 134d286d78..dda8ca4882 100644 --- a/Source/Core/Core/Src/HW/SystemTimers.cpp +++ b/Source/Core/Core/Src/HW/SystemTimers.cpp @@ -152,7 +152,7 @@ void DSPCallback(u64 userdata, int cyclesLate) void AudioDMACallback(u64 userdata, int cyclesLate) { - int fields = SConfig::GetInstance().m_LocalCoreStartupParameter.bVBeam?2:1; + int fields = VideoInterface::GetNumFields(); int period = CPU_CORE_CLOCK / (AudioInterface::GetAIDSampleRate() * 4 / 32 * fields); DSP::UpdateAudioDMA(); // Push audio to speakers. CoreTiming::ScheduleEvent(period - cyclesLate, et_AudioDMA); diff --git a/Source/Core/Core/Src/HW/VideoInterface.cpp b/Source/Core/Core/Src/HW/VideoInterface.cpp index f1829360db..3e18f6eab6 100644 --- a/Source/Core/Core/Src/HW/VideoInterface.cpp +++ b/Source/Core/Core/Src/HW/VideoInterface.cpp @@ -68,7 +68,7 @@ static u32 TicksPerFrame = 0; static u32 s_lineCount = 0; static u32 s_upperFieldBegin = 0; static u32 s_lowerFieldBegin = 0; -static int fields = 2; +static int fields = 1; void DoState(PointerWrap &p) { @@ -181,7 +181,7 @@ void Init() m_BorderHBlank.Hex = 0; memset(&m_FilterCoefTables, 0, sizeof(m_FilterCoefTables)); - fields = Core::g_CoreStartupParameter.bVBeam ? 1 : 2; + fields = 1; m_DTVStatus.ntsc_j = Core::g_CoreStartupParameter.bForceNTSCJ; @@ -746,11 +746,13 @@ u32 GetXFBAddressBottom() void UpdateParameters() { + fields = m_DisplayControlRegister.NIN ? 2 : 1; + switch (m_DisplayControlRegister.FMT) { case 0: // NTSC TargetRefreshRate = NTSC_FIELD_RATE; - TicksPerFrame = SystemTimers::GetTicksPerSecond() / (NTSC_FIELD_RATE / fields); + TicksPerFrame = SystemTimers::GetTicksPerSecond() / NTSC_FIELD_RATE; s_lineCount = NTSC_LINE_COUNT; s_upperFieldBegin = NTSC_UPPER_BEGIN; s_lowerFieldBegin = NTSC_LOWER_BEGIN; @@ -758,7 +760,7 @@ void UpdateParameters() case 2: // PAL-M TargetRefreshRate = NTSC_FIELD_RATE; - TicksPerFrame = SystemTimers::GetTicksPerSecond() / (NTSC_FIELD_RATE / fields); + TicksPerFrame = SystemTimers::GetTicksPerSecond() / NTSC_FIELD_RATE; s_lineCount = PAL_LINE_COUNT; s_upperFieldBegin = PAL_UPPER_BEGIN; s_lowerFieldBegin = PAL_LOWER_BEGIN; @@ -766,7 +768,7 @@ void UpdateParameters() case 1: // PAL TargetRefreshRate = PAL_FIELD_RATE; - TicksPerFrame = SystemTimers::GetTicksPerSecond() / (PAL_FIELD_RATE / fields); + TicksPerFrame = SystemTimers::GetTicksPerSecond() / PAL_FIELD_RATE; s_lineCount = PAL_LINE_COUNT; s_upperFieldBegin = PAL_UPPER_BEGIN; s_lowerFieldBegin = PAL_LOWER_BEGIN; @@ -782,6 +784,14 @@ void UpdateParameters() } } +int GetNumFields() +{ + if (Core::g_CoreStartupParameter.bVBeam) + return (2 / fields); + else + return 1; +} + unsigned int GetTicksPerLine() { if (s_lineCount == 0) @@ -790,7 +800,10 @@ unsigned int GetTicksPerLine() } else { - return TicksPerFrame / (s_lineCount * fields); + if (Core::g_CoreStartupParameter.bVBeam) + return TicksPerFrame / s_lineCount; + else + return TicksPerFrame / (s_lineCount / (2 / fields)) ; } } @@ -831,39 +844,27 @@ static void EndField() // Run when: When a frame is scanned (progressive/interlace) void Update() { - u16 NewVBeamPos = 0; - if (m_DisplayControlRegister.NIN) { // Progressive - NewVBeamPos = s_lineCount + 1; if (m_VBeamPos == 1) BeginField(FIELD_PROGRESSIVE); } else if (m_VBeamPos == s_upperFieldBegin) { // Interlace Upper - NewVBeamPos = s_lineCount * 2; BeginField(FIELD_UPPER); } else if (m_VBeamPos == s_lowerFieldBegin) { // Interlace Lower - NewVBeamPos = s_lineCount; BeginField(FIELD_LOWER); } - if (m_DisplayControlRegister.NIN) + if (m_VBeamPos == s_upperFieldBegin + m_VerticalTimingRegister.ACV) { - // Progressive - if (m_VBeamPos == s_lineCount) - EndField(); - } - else if (m_VBeamPos == s_upperFieldBegin + m_VerticalTimingRegister.ACV) - { - // Interlace Upper. Do not EndField (swapBuffer) at the end of the upper field. - if (Core::g_CoreStartupParameter.bVBeam) - EndField(); + // Interlace Upper. + EndField(); } else if (m_VBeamPos == s_lowerFieldBegin + m_VerticalTimingRegister.ACV) { @@ -871,8 +872,8 @@ void Update() EndField(); } - if (++m_VBeamPos > s_lineCount) - m_VBeamPos = (NewVBeamPos > s_lineCount || Core::g_CoreStartupParameter.bVBeam) ? 1 : NewVBeamPos; + if (++m_VBeamPos > s_lineCount * fields) + m_VBeamPos = 1; for (int i = 0; i < 4; i++) { diff --git a/Source/Core/Core/Src/HW/VideoInterface.h b/Source/Core/Core/Src/HW/VideoInterface.h index 0eba189851..a11e8d6457 100644 --- a/Source/Core/Core/Src/HW/VideoInterface.h +++ b/Source/Core/Core/Src/HW/VideoInterface.h @@ -359,6 +359,8 @@ union UVIDTVStatus unsigned int GetTicksPerLine(); unsigned int GetTicksPerFrame(); + + int GetNumFields(); }; #endif // _VIDEOINTERFACE_H diff --git a/Source/Core/DolphinWX/Src/ISOProperties.cpp b/Source/Core/DolphinWX/Src/ISOProperties.cpp index bda1da7172..5813b4b8b2 100644 --- a/Source/Core/DolphinWX/Src/ISOProperties.cpp +++ b/Source/Core/DolphinWX/Src/ISOProperties.cpp @@ -327,8 +327,8 @@ void CISOProperties::CreateGUIControls(bool IsWad) TLBHack->SetToolTip(_("Fast version of the MMU. Does not work for every game.")); DCBZOFF = new wxCheckBox(m_GameConfig, ID_DCBZOFF, _("Skip DCBZ clearing"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator); DCBZOFF->SetToolTip(_("Bypass the clearing of the data cache by the DCBZ instruction. Usually leave this option disabled.")); - VBeam = new wxCheckBox(m_GameConfig, ID_VBEAM, _("Accurate VBeam emulation"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator); - VBeam->SetToolTip(_("If the FPS is erratic, this option may help. (ON = Compatible, OFF = Fast)")); + VBeam = new wxCheckBox(m_GameConfig, ID_VBEAM, _("VBeam Speed Hack"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator); + VBeam->SetToolTip(_("Doubles the emulated GPU clock rate. May speed up some games (ON = Fast, OFF = Compatible)")); SyncGPU = new wxCheckBox(m_GameConfig, ID_SYNCGPU, _("Synchronize GPU thread"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator); SyncGPU->SetToolTip(_("Synchronizes the GPU and CPU threads to help prevent random freezes in Dual Core mode. (ON = Compatible, OFF = Fast)")); FastDiscSpeed = new wxCheckBox(m_GameConfig, ID_DISCSPEED, _("Speed up Disc Transfer Rate"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);