mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-08-08 09:09:04 +00:00
Merge pull request #1798 from FioraAeterna/overclock
Support overclocking and underclocking the Gamecube CPU
This commit is contained in:
commit
394257f33b
12 changed files with 111 additions and 10 deletions
|
@ -250,6 +250,8 @@ bool BootCore(const std::string& _rFilename)
|
|||
StartUp.bEnableMemcardSaving = g_NetPlaySettings.m_WriteToMemcard;
|
||||
StartUp.iCPUCore = g_NetPlaySettings.m_CPUcore;
|
||||
SConfig::GetInstance().m_DSPEnableJIT = g_NetPlaySettings.m_DSPEnableJIT;
|
||||
SConfig::GetInstance().m_OCEnable = g_NetPlaySettings.m_OCEnable;
|
||||
SConfig::GetInstance().m_OCFactor = g_NetPlaySettings.m_OCFactor;
|
||||
SConfig::GetInstance().m_EXIDevice[0] = g_NetPlaySettings.m_EXIDevice[0];
|
||||
SConfig::GetInstance().m_EXIDevice[1] = g_NetPlaySettings.m_EXIDevice[1];
|
||||
config_cache.bSetEXIDevice[0] = true;
|
||||
|
|
|
@ -345,6 +345,8 @@ void SConfig::SaveCoreSettings(IniFile& ini)
|
|||
core->Set("RunCompareClient", m_LocalCoreStartupParameter.bRunCompareClient);
|
||||
core->Set("FrameLimit", m_Framelimit);
|
||||
core->Set("FrameSkip", m_FrameSkip);
|
||||
core->Set("Overclock", m_OCFactor);
|
||||
core->Set("OverclockEnable", m_OCEnable);
|
||||
core->Set("GFXBackend", m_LocalCoreStartupParameter.m_strVideoBackend);
|
||||
core->Set("GPUDeterminismMode", m_LocalCoreStartupParameter.m_strGPUDeterminismMode);
|
||||
core->Set("GameCubeAdapter", m_GameCubeAdapter);
|
||||
|
@ -580,6 +582,8 @@ void SConfig::LoadCoreSettings(IniFile& ini)
|
|||
core->Get("FastDiscSpeed", &m_LocalCoreStartupParameter.bFastDiscSpeed, false);
|
||||
core->Get("DCBZ", &m_LocalCoreStartupParameter.bDCBZOFF, false);
|
||||
core->Get("FrameLimit", &m_Framelimit, 1); // auto frame limit by default
|
||||
core->Get("Overclock", &m_OCFactor, 1.0f);
|
||||
core->Get("OverclockEnable", &m_OCEnable, false);
|
||||
core->Get("FrameSkip", &m_FrameSkip, 0);
|
||||
core->Get("GFXBackend", &m_LocalCoreStartupParameter.m_strVideoBackend, "");
|
||||
core->Get("GPUDeterminismMode", &m_LocalCoreStartupParameter.m_strGPUDeterminismMode, "auto");
|
||||
|
|
|
@ -49,6 +49,8 @@ struct SConfig : NonCopyable
|
|||
int m_InterfaceLanguage;
|
||||
// framelimit choose
|
||||
unsigned int m_Framelimit;
|
||||
bool m_OCEnable;
|
||||
float m_OCFactor;
|
||||
// other interface settings
|
||||
bool m_InterfaceToolbar;
|
||||
bool m_InterfaceStatusbar;
|
||||
|
|
|
@ -327,6 +327,8 @@ void EmuThread()
|
|||
|
||||
Common::SetCurrentThreadName("Emuthread - Starting");
|
||||
|
||||
if (SConfig::GetInstance().m_OCEnable)
|
||||
DisplayMessage("WARNING: running at non-native CPU clock! Game may not be stable.", 8000);
|
||||
DisplayMessage(cpu_info.brand_string, 8000);
|
||||
DisplayMessage(cpu_info.Summarize(), 8000);
|
||||
DisplayMessage(core_parameter.m_strFilename, 3000);
|
||||
|
|
|
@ -48,6 +48,7 @@ static Common::FifoQueue<BaseEvent, false> tsQueue;
|
|||
// event pools
|
||||
static Event *eventPool = nullptr;
|
||||
|
||||
float lastOCFactor;
|
||||
int slicelength;
|
||||
static int maxSliceLength = MAX_SLICE_LENGTH;
|
||||
|
||||
|
@ -82,6 +83,23 @@ static void FreeEvent(Event* ev)
|
|||
|
||||
static void EmptyTimedCallback(u64 userdata, int cyclesLate) {}
|
||||
|
||||
// Changing the CPU speed in Dolphin isn't actually done by changing the physical clock rate,
|
||||
// but by changing the amount of work done in a particular amount of time. This tends to be more
|
||||
// compatible because it stops the games from actually knowing directly that the clock rate has
|
||||
// changed, and ensures that anything based on waiting a specific number of cycles still works.
|
||||
//
|
||||
// Technically it might be more accurate to call this changing the IPC instead of the CPU speed,
|
||||
// but the effect is largely the same.
|
||||
static int DowncountToCycles(int downcount)
|
||||
{
|
||||
return (int)(downcount / lastOCFactor);
|
||||
}
|
||||
|
||||
static int CyclesToDowncount(int cycles)
|
||||
{
|
||||
return (int)(cycles * lastOCFactor);
|
||||
}
|
||||
|
||||
int RegisterEvent(const std::string& name, TimedCallback callback)
|
||||
{
|
||||
EventType type;
|
||||
|
@ -115,7 +133,8 @@ void UnregisterAllEvents()
|
|||
|
||||
void Init()
|
||||
{
|
||||
PowerPC::ppcState.downcount = maxSliceLength;
|
||||
lastOCFactor = SConfig::GetInstance().m_OCEnable ? SConfig::GetInstance().m_OCFactor : 1.0f;
|
||||
PowerPC::ppcState.downcount = CyclesToDowncount(maxSliceLength);
|
||||
slicelength = maxSliceLength;
|
||||
globalTimer = 0;
|
||||
idledCycles = 0;
|
||||
|
@ -182,6 +201,7 @@ void DoState(PointerWrap &p)
|
|||
p.Do(fakeDecStartTicks);
|
||||
p.Do(fakeTBStartValue);
|
||||
p.Do(fakeTBStartTicks);
|
||||
p.Do(lastOCFactor);
|
||||
p.DoMarker("CoreTimingData");
|
||||
|
||||
MoveEvents();
|
||||
|
@ -338,10 +358,10 @@ void SetMaximumSlice(int maximumSliceLength)
|
|||
|
||||
void ForceExceptionCheck(int cycles)
|
||||
{
|
||||
if (PowerPC::ppcState.downcount > cycles)
|
||||
if (DowncountToCycles(PowerPC::ppcState.downcount) > cycles)
|
||||
{
|
||||
slicelength -= (PowerPC::ppcState.downcount - cycles); // Account for cycles already executed by adjusting the slicelength
|
||||
PowerPC::ppcState.downcount = cycles;
|
||||
slicelength -= (DowncountToCycles(PowerPC::ppcState.downcount) - cycles); // Account for cycles already executed by adjusting the slicelength
|
||||
PowerPC::ppcState.downcount = CyclesToDowncount(cycles);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -392,9 +412,10 @@ void Advance()
|
|||
{
|
||||
MoveEvents();
|
||||
|
||||
int cyclesExecuted = slicelength - PowerPC::ppcState.downcount;
|
||||
int cyclesExecuted = slicelength - DowncountToCycles(PowerPC::ppcState.downcount);
|
||||
globalTimer += cyclesExecuted;
|
||||
PowerPC::ppcState.downcount = slicelength;
|
||||
lastOCFactor = SConfig::GetInstance().m_OCEnable ? SConfig::GetInstance().m_OCFactor : 1.0f;
|
||||
PowerPC::ppcState.downcount = CyclesToDowncount(slicelength);
|
||||
|
||||
while (first)
|
||||
{
|
||||
|
@ -416,14 +437,14 @@ void Advance()
|
|||
if (!first)
|
||||
{
|
||||
WARN_LOG(POWERPC, "WARNING - no events in queue. Setting downcount to 10000");
|
||||
PowerPC::ppcState.downcount += 10000;
|
||||
PowerPC::ppcState.downcount += CyclesToDowncount(10000);
|
||||
}
|
||||
else
|
||||
{
|
||||
slicelength = (int)(first->time - globalTimer);
|
||||
if (slicelength > maxSliceLength)
|
||||
slicelength = maxSliceLength;
|
||||
PowerPC::ppcState.downcount = slicelength;
|
||||
PowerPC::ppcState.downcount = CyclesToDowncount(slicelength);
|
||||
}
|
||||
|
||||
if (advanceCallback)
|
||||
|
@ -456,7 +477,7 @@ void Idle()
|
|||
}
|
||||
}
|
||||
|
||||
idledCycles += PowerPC::ppcState.downcount;
|
||||
idledCycles += DowncountToCycles(PowerPC::ppcState.downcount);
|
||||
PowerPC::ppcState.downcount = 0;
|
||||
|
||||
Advance();
|
||||
|
|
|
@ -250,6 +250,8 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
|
|||
packet >> g_NetPlaySettings.m_DSPEnableJIT;
|
||||
packet >> g_NetPlaySettings.m_DSPHLE;
|
||||
packet >> g_NetPlaySettings.m_WriteToMemcard;
|
||||
packet >> g_NetPlaySettings.m_OCEnable;
|
||||
packet >> g_NetPlaySettings.m_OCFactor;
|
||||
int tmp;
|
||||
packet >> tmp;
|
||||
g_NetPlaySettings.m_EXIDevice[0] = (TEXIDevices) tmp;
|
||||
|
|
|
@ -16,6 +16,8 @@ struct NetSettings
|
|||
bool m_DSPHLE;
|
||||
bool m_DSPEnableJIT;
|
||||
bool m_WriteToMemcard;
|
||||
bool m_OCEnable;
|
||||
float m_OCFactor;
|
||||
TEXIDevices m_EXIDevice[2];
|
||||
};
|
||||
|
||||
|
|
|
@ -554,6 +554,8 @@ bool NetPlayServer::StartGame()
|
|||
spac << m_settings.m_DSPEnableJIT;
|
||||
spac << m_settings.m_DSPHLE;
|
||||
spac << m_settings.m_WriteToMemcard;
|
||||
spac << m_settings.m_OCEnable;
|
||||
spac << m_settings.m_OCFactor;
|
||||
spac << m_settings.m_EXIDevice[0];
|
||||
spac << m_settings.m_EXIDevice[1];
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue