Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge branch 'VBeam-fix'
* VBeam-fix:
  Renamed the VBeam variable for clarity.
  Fixed VBeam emulation in interlaced mode, removing the hacks in the audio timing. Fixed VBeam emulation in progressive scan mode. Retained the old VBeam speed hack.  This option has now been switched so that the accurate behaviour is on by default and the speed hack (inaccurate behaviour) is enabled when the option is checked.
  • Loading branch information
skidau committed Apr 16, 2013
2 parents 8bb845e + 71828e0 commit f498686
Show file tree
Hide file tree
Showing 9 changed files with 40 additions and 38 deletions.
8 changes: 4 additions & 4 deletions Source/Core/Core/Src/BootManager.cpp
Expand Up @@ -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;
};
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/Src/ConfigManager.cpp
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions Source/Core/Core/Src/CoreParameter.cpp
Expand Up @@ -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),
Expand Down Expand Up @@ -77,7 +77,7 @@ void SCoreStartupParameter::LoadDefaults()
bMMU = false;
bDCBZOFF = false;
iTLBHack = 0;
bVBeam = false;
bVBeamSpeedHack = false;
bSyncGPU = false;
bFastDiscSpeed = false;
bMergeBlocks = false;
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/Src/CoreParameter.h
Expand Up @@ -116,7 +116,7 @@ struct SCoreStartupParameter
bool bMMU;
bool bDCBZOFF;
int iTLBHack;
bool bVBeam;
bool bVBeamSpeedHack;
bool bSyncGPU;
bool bFastDiscSpeed;

Expand Down
3 changes: 2 additions & 1 deletion Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp
Expand Up @@ -29,6 +29,7 @@
#include "ConfigManager.h"
#include "Core.h"
#include "HW/SystemTimers.h"
#include "HW/VideoInterface.h"

DSPHLE::DSPHLE() {
m_InitMixer = false;
Expand Down Expand Up @@ -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
Expand Down
6 changes: 2 additions & 4 deletions Source/Core/Core/Src/HW/SystemTimers.cpp
Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
47 changes: 24 additions & 23 deletions Source/Core/Core/Src/HW/VideoInterface.cpp
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -746,27 +746,29 @@ 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;
break;

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;
break;

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;
Expand All @@ -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)
Expand All @@ -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)) ;
}
}

Expand Down Expand Up @@ -831,48 +844,36 @@ 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)
{
// Progressive
if (m_VBeamPos == s_lineCount)
EndField();
}
else if (m_VBeamPos == s_upperFieldBegin + m_VerticalTimingRegister.ACV)
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)
{
// Interlace Lower
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++)
{
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/Core/Src/HW/VideoInterface.h
Expand Up @@ -359,6 +359,8 @@ union UVIDTVStatus

unsigned int GetTicksPerLine();
unsigned int GetTicksPerFrame();

int GetNumFields();
};

#endif // _VIDEOINTERFACE_H
4 changes: 2 additions & 2 deletions Source/Core/DolphinWX/Src/ISOProperties.cpp
Expand Up @@ -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);
Expand Down

0 comments on commit f498686

Please sign in to comment.