diff --git a/Source/Core/Core/Src/BootManager.cpp b/Source/Core/Core/Src/BootManager.cpp index 88e0cebcb6..f4322c30c2 100644 --- a/Source/Core/Core/Src/BootManager.cpp +++ b/Source/Core/Core/Src/BootManager.cpp @@ -55,7 +55,7 @@ namespace BootManager struct ConfigCache { bool valid, bCPUThread, bSkipIdle, bEnableFPRF, bMMU, bDCBZOFF, - bVBeam, bSyncGPU, bFastDiscSpeed, bMergeBlocks, bDSPHLE, bHLE_BS2; + bVBeamSpeedHack, bSyncGPU, bFastDiscSpeed, bMergeBlocks, bDSPHLE, bHLE_BS2; int iTLBHack, iCPUCore; std::string strBackend; }; @@ -94,7 +94,7 @@ bool BootCore(const std::string& _rFilename) config_cache.bMMU = StartUp.bMMU; config_cache.bDCBZOFF = StartUp.bDCBZOFF; config_cache.iTLBHack = StartUp.iTLBHack; - config_cache.bVBeam = StartUp.bVBeam; + config_cache.bVBeamSpeedHack = StartUp.bVBeamSpeedHack; config_cache.bSyncGPU = StartUp.bSyncGPU; config_cache.bFastDiscSpeed = StartUp.bFastDiscSpeed; config_cache.bMergeBlocks = StartUp.bMergeBlocks; @@ -109,7 +109,7 @@ bool BootCore(const std::string& _rFilename) game_ini.Get("Core", "MMU", &StartUp.bMMU, StartUp.bMMU); game_ini.Get("Core", "TLBHack", &StartUp.iTLBHack, StartUp.iTLBHack); game_ini.Get("Core", "DCBZ", &StartUp.bDCBZOFF, StartUp.bDCBZOFF); - game_ini.Get("Core", "VBeam", &StartUp.bVBeam, StartUp.bVBeam); + game_ini.Get("Core", "VBeam", &StartUp.bVBeamSpeedHack, StartUp.bVBeamSpeedHack); game_ini.Get("Core", "SyncGPU", &StartUp.bSyncGPU, StartUp.bSyncGPU); game_ini.Get("Core", "FastDiscSpeed", &StartUp.bFastDiscSpeed, StartUp.bFastDiscSpeed); game_ini.Get("Core", "BlockMerging", &StartUp.bMergeBlocks, StartUp.bMergeBlocks); @@ -169,7 +169,7 @@ void Stop() StartUp.bMMU = config_cache.bMMU; StartUp.bDCBZOFF = config_cache.bDCBZOFF; StartUp.iTLBHack = config_cache.iTLBHack; - StartUp.bVBeam = config_cache.bVBeam; + StartUp.bVBeamSpeedHack = config_cache.bVBeamSpeedHack; StartUp.bSyncGPU = config_cache.bSyncGPU; StartUp.bFastDiscSpeed = config_cache.bFastDiscSpeed; StartUp.bMergeBlocks = config_cache.bMergeBlocks; diff --git a/Source/Core/Core/Src/ConfigManager.cpp b/Source/Core/Core/Src/ConfigManager.cpp index e2f01150b2..fa322d9205 100644 --- a/Source/Core/Core/Src/ConfigManager.cpp +++ b/Source/Core/Core/Src/ConfigManager.cpp @@ -403,7 +403,7 @@ void SConfig::LoadSettings() ini.Get("Core", "RunCompareClient", &m_LocalCoreStartupParameter.bRunCompareClient, false); ini.Get("Core", "MMU", &m_LocalCoreStartupParameter.bMMU, false); ini.Get("Core", "TLBHack", &m_LocalCoreStartupParameter.iTLBHack, 0); - ini.Get("Core", "VBeam", &m_LocalCoreStartupParameter.bVBeam, false); + ini.Get("Core", "VBeam", &m_LocalCoreStartupParameter.bVBeamSpeedHack, false); ini.Get("Core", "SyncGPU", &m_LocalCoreStartupParameter.bSyncGPU, false); ini.Get("Core", "FastDiscSpeed", &m_LocalCoreStartupParameter.bFastDiscSpeed, false); ini.Get("Core", "DCBZ", &m_LocalCoreStartupParameter.bDCBZOFF, false); diff --git a/Source/Core/Core/Src/CoreParameter.cpp b/Source/Core/Core/Src/CoreParameter.cpp index fcb35eccc3..6a06f13661 100644 --- a/Source/Core/Core/Src/CoreParameter.cpp +++ b/Source/Core/Core/Src/CoreParameter.cpp @@ -49,7 +49,7 @@ SCoreStartupParameter::SCoreStartupParameter() bMergeBlocks(false), bEnableMemcardSaving(true), bDPL2Decoder(false), iLatency(14), bRunCompareServer(false), bRunCompareClient(false), - bMMU(false), bDCBZOFF(false), iTLBHack(0), bVBeam(false), + bMMU(false), bDCBZOFF(false), iTLBHack(0), bVBeamSpeedHack(false), bSyncGPU(false), bFastDiscSpeed(false), SelectedLanguage(0), bWii(false), bConfirmStop(false), bHideCursor(false), @@ -77,7 +77,7 @@ void SCoreStartupParameter::LoadDefaults() bMMU = false; bDCBZOFF = false; iTLBHack = 0; - bVBeam = false; + bVBeamSpeedHack = false; bSyncGPU = false; bFastDiscSpeed = false; bMergeBlocks = false; diff --git a/Source/Core/Core/Src/CoreParameter.h b/Source/Core/Core/Src/CoreParameter.h index 3a1dc2ba3a..6cd9b4a8be 100644 --- a/Source/Core/Core/Src/CoreParameter.h +++ b/Source/Core/Core/Src/CoreParameter.h @@ -116,7 +116,7 @@ struct SCoreStartupParameter bool bMMU; bool bDCBZOFF; int iTLBHack; - bool bVBeam; + bool bVBeamSpeedHack; bool bSyncGPU; bool bFastDiscSpeed; 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..cebf4267d8 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); @@ -240,8 +240,6 @@ void PreInit() void Init() { - const int fields = SConfig::GetInstance().m_LocalCoreStartupParameter.bVBeam ? 2 : 1; - if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii) { // AyuanX: TO BE TWEAKED @@ -250,7 +248,7 @@ void Init() // FYI, WII_IPC_HLE_Interface::Update is also called in WII_IPCInterface::Write32 const int freq = 1500; - IPC_HLE_PERIOD = GetTicksPerSecond() / (freq * fields); + IPC_HLE_PERIOD = GetTicksPerSecond() / (freq * VideoInterface::GetNumFields()); } // System internal sample rate is fixed at 32KHz * 4 (16bit Stereo) / 32 bytes DMA diff --git a/Source/Core/Core/Src/HW/VideoInterface.cpp b/Source/Core/Core/Src/HW/VideoInterface.cpp index f1829360db..9d025edb06 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.bVBeamSpeedHack) + 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.bVBeamSpeedHack) + 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 29d8b9616a..3385a75cd9 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);