mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-06-24 11:11:38 +00:00
Support overclocking and underclocking the Gamecube CPU
Won't work with all games, but provides a nice way to spend extra CPU to make a variable framerate game faster (e.g. Spyro or The Last Story), or to make a game use less CPU at the cost of a lower framerate (e.g. Rogue Leader).
This commit is contained in:
parent
e32d63c43d
commit
c2c950108d
12 changed files with 111 additions and 10 deletions
|
@ -64,6 +64,8 @@ template <typename N>
|
||||||
static bool TryParse(const std::string &str, N *const output)
|
static bool TryParse(const std::string &str, N *const output)
|
||||||
{
|
{
|
||||||
std::istringstream iss(str);
|
std::istringstream iss(str);
|
||||||
|
// is this right? not doing this breaks reading floats on locales that use different decimal separators
|
||||||
|
iss.imbue(std::locale(".1252"));
|
||||||
|
|
||||||
N tmp = 0;
|
N tmp = 0;
|
||||||
if (iss >> tmp)
|
if (iss >> tmp)
|
||||||
|
|
|
@ -250,6 +250,8 @@ bool BootCore(const std::string& _rFilename)
|
||||||
StartUp.bEnableMemcardSaving = g_NetPlaySettings.m_WriteToMemcard;
|
StartUp.bEnableMemcardSaving = g_NetPlaySettings.m_WriteToMemcard;
|
||||||
StartUp.iCPUCore = g_NetPlaySettings.m_CPUcore;
|
StartUp.iCPUCore = g_NetPlaySettings.m_CPUcore;
|
||||||
SConfig::GetInstance().m_DSPEnableJIT = g_NetPlaySettings.m_DSPEnableJIT;
|
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[0] = g_NetPlaySettings.m_EXIDevice[0];
|
||||||
SConfig::GetInstance().m_EXIDevice[1] = g_NetPlaySettings.m_EXIDevice[1];
|
SConfig::GetInstance().m_EXIDevice[1] = g_NetPlaySettings.m_EXIDevice[1];
|
||||||
config_cache.bSetEXIDevice[0] = true;
|
config_cache.bSetEXIDevice[0] = true;
|
||||||
|
|
|
@ -345,6 +345,8 @@ void SConfig::SaveCoreSettings(IniFile& ini)
|
||||||
core->Set("RunCompareClient", m_LocalCoreStartupParameter.bRunCompareClient);
|
core->Set("RunCompareClient", m_LocalCoreStartupParameter.bRunCompareClient);
|
||||||
core->Set("FrameLimit", m_Framelimit);
|
core->Set("FrameLimit", m_Framelimit);
|
||||||
core->Set("FrameSkip", m_FrameSkip);
|
core->Set("FrameSkip", m_FrameSkip);
|
||||||
|
core->Set("Overclock", m_OCFactor);
|
||||||
|
core->Set("OverclockEnable", m_OCEnable);
|
||||||
core->Set("GFXBackend", m_LocalCoreStartupParameter.m_strVideoBackend);
|
core->Set("GFXBackend", m_LocalCoreStartupParameter.m_strVideoBackend);
|
||||||
core->Set("GPUDeterminismMode", m_LocalCoreStartupParameter.m_strGPUDeterminismMode);
|
core->Set("GPUDeterminismMode", m_LocalCoreStartupParameter.m_strGPUDeterminismMode);
|
||||||
core->Set("GameCubeAdapter", m_GameCubeAdapter);
|
core->Set("GameCubeAdapter", m_GameCubeAdapter);
|
||||||
|
@ -580,6 +582,8 @@ void SConfig::LoadCoreSettings(IniFile& ini)
|
||||||
core->Get("FastDiscSpeed", &m_LocalCoreStartupParameter.bFastDiscSpeed, false);
|
core->Get("FastDiscSpeed", &m_LocalCoreStartupParameter.bFastDiscSpeed, false);
|
||||||
core->Get("DCBZ", &m_LocalCoreStartupParameter.bDCBZOFF, false);
|
core->Get("DCBZ", &m_LocalCoreStartupParameter.bDCBZOFF, false);
|
||||||
core->Get("FrameLimit", &m_Framelimit, 1); // auto frame limit by default
|
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("FrameSkip", &m_FrameSkip, 0);
|
||||||
core->Get("GFXBackend", &m_LocalCoreStartupParameter.m_strVideoBackend, "");
|
core->Get("GFXBackend", &m_LocalCoreStartupParameter.m_strVideoBackend, "");
|
||||||
core->Get("GPUDeterminismMode", &m_LocalCoreStartupParameter.m_strGPUDeterminismMode, "auto");
|
core->Get("GPUDeterminismMode", &m_LocalCoreStartupParameter.m_strGPUDeterminismMode, "auto");
|
||||||
|
|
|
@ -49,6 +49,8 @@ struct SConfig : NonCopyable
|
||||||
int m_InterfaceLanguage;
|
int m_InterfaceLanguage;
|
||||||
// framelimit choose
|
// framelimit choose
|
||||||
unsigned int m_Framelimit;
|
unsigned int m_Framelimit;
|
||||||
|
bool m_OCEnable;
|
||||||
|
float m_OCFactor;
|
||||||
// other interface settings
|
// other interface settings
|
||||||
bool m_InterfaceToolbar;
|
bool m_InterfaceToolbar;
|
||||||
bool m_InterfaceStatusbar;
|
bool m_InterfaceStatusbar;
|
||||||
|
|
|
@ -327,6 +327,8 @@ void EmuThread()
|
||||||
|
|
||||||
Common::SetCurrentThreadName("Emuthread - Starting");
|
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.brand_string, 8000);
|
||||||
DisplayMessage(cpu_info.Summarize(), 8000);
|
DisplayMessage(cpu_info.Summarize(), 8000);
|
||||||
DisplayMessage(core_parameter.m_strFilename, 3000);
|
DisplayMessage(core_parameter.m_strFilename, 3000);
|
||||||
|
|
|
@ -48,6 +48,7 @@ static Common::FifoQueue<BaseEvent, false> tsQueue;
|
||||||
// event pools
|
// event pools
|
||||||
static Event *eventPool = nullptr;
|
static Event *eventPool = nullptr;
|
||||||
|
|
||||||
|
float lastOCFactor;
|
||||||
int slicelength;
|
int slicelength;
|
||||||
static int maxSliceLength = MAX_SLICE_LENGTH;
|
static int maxSliceLength = MAX_SLICE_LENGTH;
|
||||||
|
|
||||||
|
@ -82,6 +83,23 @@ static void FreeEvent(Event* ev)
|
||||||
|
|
||||||
static void EmptyTimedCallback(u64 userdata, int cyclesLate) {}
|
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)
|
int RegisterEvent(const std::string& name, TimedCallback callback)
|
||||||
{
|
{
|
||||||
EventType type;
|
EventType type;
|
||||||
|
@ -115,7 +133,8 @@ void UnregisterAllEvents()
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
PowerPC::ppcState.downcount = maxSliceLength;
|
lastOCFactor = SConfig::GetInstance().m_OCEnable ? SConfig::GetInstance().m_OCFactor : 1.0f;
|
||||||
|
PowerPC::ppcState.downcount = CyclesToDowncount(maxSliceLength);
|
||||||
slicelength = maxSliceLength;
|
slicelength = maxSliceLength;
|
||||||
globalTimer = 0;
|
globalTimer = 0;
|
||||||
idledCycles = 0;
|
idledCycles = 0;
|
||||||
|
@ -182,6 +201,7 @@ void DoState(PointerWrap &p)
|
||||||
p.Do(fakeDecStartTicks);
|
p.Do(fakeDecStartTicks);
|
||||||
p.Do(fakeTBStartValue);
|
p.Do(fakeTBStartValue);
|
||||||
p.Do(fakeTBStartTicks);
|
p.Do(fakeTBStartTicks);
|
||||||
|
p.Do(lastOCFactor);
|
||||||
p.DoMarker("CoreTimingData");
|
p.DoMarker("CoreTimingData");
|
||||||
|
|
||||||
MoveEvents();
|
MoveEvents();
|
||||||
|
@ -338,10 +358,10 @@ void SetMaximumSlice(int maximumSliceLength)
|
||||||
|
|
||||||
void ForceExceptionCheck(int cycles)
|
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
|
slicelength -= (DowncountToCycles(PowerPC::ppcState.downcount) - cycles); // Account for cycles already executed by adjusting the slicelength
|
||||||
PowerPC::ppcState.downcount = cycles;
|
PowerPC::ppcState.downcount = CyclesToDowncount(cycles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,9 +412,10 @@ void Advance()
|
||||||
{
|
{
|
||||||
MoveEvents();
|
MoveEvents();
|
||||||
|
|
||||||
int cyclesExecuted = slicelength - PowerPC::ppcState.downcount;
|
int cyclesExecuted = slicelength - DowncountToCycles(PowerPC::ppcState.downcount);
|
||||||
globalTimer += cyclesExecuted;
|
globalTimer += cyclesExecuted;
|
||||||
PowerPC::ppcState.downcount = slicelength;
|
lastOCFactor = SConfig::GetInstance().m_OCEnable ? SConfig::GetInstance().m_OCFactor : 1.0f;
|
||||||
|
PowerPC::ppcState.downcount = CyclesToDowncount(slicelength);
|
||||||
|
|
||||||
while (first)
|
while (first)
|
||||||
{
|
{
|
||||||
|
@ -416,14 +437,14 @@ void Advance()
|
||||||
if (!first)
|
if (!first)
|
||||||
{
|
{
|
||||||
WARN_LOG(POWERPC, "WARNING - no events in queue. Setting downcount to 10000");
|
WARN_LOG(POWERPC, "WARNING - no events in queue. Setting downcount to 10000");
|
||||||
PowerPC::ppcState.downcount += 10000;
|
PowerPC::ppcState.downcount += CyclesToDowncount(10000);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
slicelength = (int)(first->time - globalTimer);
|
slicelength = (int)(first->time - globalTimer);
|
||||||
if (slicelength > maxSliceLength)
|
if (slicelength > maxSliceLength)
|
||||||
slicelength = maxSliceLength;
|
slicelength = maxSliceLength;
|
||||||
PowerPC::ppcState.downcount = slicelength;
|
PowerPC::ppcState.downcount = CyclesToDowncount(slicelength);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (advanceCallback)
|
if (advanceCallback)
|
||||||
|
@ -456,7 +477,7 @@ void Idle()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
idledCycles += PowerPC::ppcState.downcount;
|
idledCycles += DowncountToCycles(PowerPC::ppcState.downcount);
|
||||||
PowerPC::ppcState.downcount = 0;
|
PowerPC::ppcState.downcount = 0;
|
||||||
|
|
||||||
Advance();
|
Advance();
|
||||||
|
|
|
@ -250,6 +250,8 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
|
||||||
packet >> g_NetPlaySettings.m_DSPEnableJIT;
|
packet >> g_NetPlaySettings.m_DSPEnableJIT;
|
||||||
packet >> g_NetPlaySettings.m_DSPHLE;
|
packet >> g_NetPlaySettings.m_DSPHLE;
|
||||||
packet >> g_NetPlaySettings.m_WriteToMemcard;
|
packet >> g_NetPlaySettings.m_WriteToMemcard;
|
||||||
|
packet >> g_NetPlaySettings.m_OCEnable;
|
||||||
|
packet >> g_NetPlaySettings.m_OCFactor;
|
||||||
int tmp;
|
int tmp;
|
||||||
packet >> tmp;
|
packet >> tmp;
|
||||||
g_NetPlaySettings.m_EXIDevice[0] = (TEXIDevices) tmp;
|
g_NetPlaySettings.m_EXIDevice[0] = (TEXIDevices) tmp;
|
||||||
|
|
|
@ -16,6 +16,8 @@ struct NetSettings
|
||||||
bool m_DSPHLE;
|
bool m_DSPHLE;
|
||||||
bool m_DSPEnableJIT;
|
bool m_DSPEnableJIT;
|
||||||
bool m_WriteToMemcard;
|
bool m_WriteToMemcard;
|
||||||
|
bool m_OCEnable;
|
||||||
|
float m_OCFactor;
|
||||||
TEXIDevices m_EXIDevice[2];
|
TEXIDevices m_EXIDevice[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -554,6 +554,8 @@ bool NetPlayServer::StartGame()
|
||||||
spac << m_settings.m_DSPEnableJIT;
|
spac << m_settings.m_DSPEnableJIT;
|
||||||
spac << m_settings.m_DSPHLE;
|
spac << m_settings.m_DSPHLE;
|
||||||
spac << m_settings.m_WriteToMemcard;
|
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[0];
|
||||||
spac << m_settings.m_EXIDevice[1];
|
spac << m_settings.m_EXIDevice[1];
|
||||||
|
|
||||||
|
|
|
@ -134,7 +134,8 @@ EVT_CHOICE(ID_FRAMELIMIT, CConfigMain::CoreSettingsChanged)
|
||||||
|
|
||||||
EVT_RADIOBOX(ID_CPUENGINE, CConfigMain::CoreSettingsChanged)
|
EVT_RADIOBOX(ID_CPUENGINE, CConfigMain::CoreSettingsChanged)
|
||||||
EVT_CHECKBOX(ID_NTSCJ, CConfigMain::CoreSettingsChanged)
|
EVT_CHECKBOX(ID_NTSCJ, CConfigMain::CoreSettingsChanged)
|
||||||
|
EVT_SLIDER(ID_OVERCLOCK, CConfigMain::CoreSettingsChanged)
|
||||||
|
EVT_CHECKBOX(ID_ENABLEOVERCLOCK, CConfigMain::CoreSettingsChanged)
|
||||||
|
|
||||||
EVT_RADIOBOX(ID_DSPENGINE, CConfigMain::AudioSettingsChanged)
|
EVT_RADIOBOX(ID_DSPENGINE, CConfigMain::AudioSettingsChanged)
|
||||||
EVT_CHECKBOX(ID_ENABLE_THROTTLE, CConfigMain::AudioSettingsChanged)
|
EVT_CHECKBOX(ID_ENABLE_THROTTLE, CConfigMain::AudioSettingsChanged)
|
||||||
|
@ -327,6 +328,10 @@ void CConfigMain::InitializeGUIValues()
|
||||||
SkipIdle->SetValue(startup_params.bSkipIdle);
|
SkipIdle->SetValue(startup_params.bSkipIdle);
|
||||||
EnableCheats->SetValue(startup_params.bEnableCheats);
|
EnableCheats->SetValue(startup_params.bEnableCheats);
|
||||||
Framelimit->SetSelection(SConfig::GetInstance().m_Framelimit);
|
Framelimit->SetSelection(SConfig::GetInstance().m_Framelimit);
|
||||||
|
int ocFactor = (int)(log2f(SConfig::GetInstance().m_OCFactor) * 25.f + 100.f + 0.5f);
|
||||||
|
EnableOC->SetValue(SConfig::GetInstance().m_OCEnable);
|
||||||
|
OCSlider->SetValue(ocFactor);
|
||||||
|
UpdateCPUClock();
|
||||||
|
|
||||||
// General - Advanced
|
// General - Advanced
|
||||||
for (unsigned int a = 0; a < (sizeof(CPUCores) / sizeof(CPUCore)); ++a)
|
for (unsigned int a = 0; a < (sizeof(CPUCores) / sizeof(CPUCore)); ++a)
|
||||||
|
@ -497,6 +502,7 @@ void CConfigMain::CreateGUIControls()
|
||||||
wxPanel* const AudioPage = new wxPanel(Notebook, ID_AUDIOPAGE);
|
wxPanel* const AudioPage = new wxPanel(Notebook, ID_AUDIOPAGE);
|
||||||
wxPanel* const GamecubePage = new wxPanel(Notebook, ID_GAMECUBEPAGE);
|
wxPanel* const GamecubePage = new wxPanel(Notebook, ID_GAMECUBEPAGE);
|
||||||
wxPanel* const WiiPage = new wxPanel(Notebook, ID_WIIPAGE);
|
wxPanel* const WiiPage = new wxPanel(Notebook, ID_WIIPAGE);
|
||||||
|
wxPanel* const AdvancedPage = new wxPanel(Notebook, ID_ADVANCEDPAGE);
|
||||||
PathsPage = new wxPanel(Notebook, ID_PATHSPAGE);
|
PathsPage = new wxPanel(Notebook, ID_PATHSPAGE);
|
||||||
|
|
||||||
Notebook->AddPage(GeneralPage, _("General"));
|
Notebook->AddPage(GeneralPage, _("General"));
|
||||||
|
@ -505,6 +511,7 @@ void CConfigMain::CreateGUIControls()
|
||||||
Notebook->AddPage(GamecubePage, _("GameCube"));
|
Notebook->AddPage(GamecubePage, _("GameCube"));
|
||||||
Notebook->AddPage(WiiPage, _("Wii"));
|
Notebook->AddPage(WiiPage, _("Wii"));
|
||||||
Notebook->AddPage(PathsPage, _("Paths"));
|
Notebook->AddPage(PathsPage, _("Paths"));
|
||||||
|
Notebook->AddPage(AdvancedPage, _("Advanced"));
|
||||||
|
|
||||||
// General page
|
// General page
|
||||||
// Core Settings - Basic
|
// Core Settings - Basic
|
||||||
|
@ -521,6 +528,7 @@ void CConfigMain::CreateGUIControls()
|
||||||
wxBoxSizer* sFramelimit = new wxBoxSizer(wxHORIZONTAL);
|
wxBoxSizer* sFramelimit = new wxBoxSizer(wxHORIZONTAL);
|
||||||
sFramelimit->Add(TEXT_BOX(GeneralPage, _("Framelimit:")), 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
sFramelimit->Add(TEXT_BOX(GeneralPage, _("Framelimit:")), 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
||||||
sFramelimit->Add(Framelimit, 0, wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, 5);
|
sFramelimit->Add(Framelimit, 0, wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, 5);
|
||||||
|
|
||||||
wxStaticBoxSizer* const sbBasic = new wxStaticBoxSizer(wxVERTICAL, GeneralPage, _("Basic Settings"));
|
wxStaticBoxSizer* const sbBasic = new wxStaticBoxSizer(wxVERTICAL, GeneralPage, _("Basic Settings"));
|
||||||
sbBasic->Add(CPUThread, 0, wxALL, 5);
|
sbBasic->Add(CPUThread, 0, wxALL, 5);
|
||||||
sbBasic->Add(SkipIdle, 0, wxALL, 5);
|
sbBasic->Add(SkipIdle, 0, wxALL, 5);
|
||||||
|
@ -782,6 +790,33 @@ void CConfigMain::CreateGUIControls()
|
||||||
sMain->Add(Notebook, 1, wxEXPAND|wxALL, 5);
|
sMain->Add(Notebook, 1, wxEXPAND|wxALL, 5);
|
||||||
sMain->Add(CreateButtonSizer(wxOK), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
sMain->Add(CreateButtonSizer(wxOK), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
||||||
|
|
||||||
|
wxStaticBoxSizer* sbCPUOptions = new wxStaticBoxSizer(wxVERTICAL, AdvancedPage, _("CPU Options"));
|
||||||
|
wxBoxSizer* bOverclockEnable = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
wxBoxSizer* bOverclock = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
wxBoxSizer* bOverclockDesc = new wxBoxSizer(wxHORIZONTAL);
|
||||||
|
EnableOC = new wxCheckBox(AdvancedPage, ID_ENABLEOVERCLOCK, _("Enable CPU Clock Override"));
|
||||||
|
OCSlider = new wxSlider(AdvancedPage, ID_OVERCLOCK, 100, 0, 150, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL);
|
||||||
|
wxStaticText* OCDescription = new wxStaticText(AdvancedPage, wxID_ANY,
|
||||||
|
_("Higher values can make variable-framerate games\n"
|
||||||
|
"run at a higher framerate, at the expense of CPU.\n"
|
||||||
|
"Lower values can make variable-framerate games\n"
|
||||||
|
"run at a lower framerate, saving CPU.\n\n"
|
||||||
|
"WARNING: Changing this from the default (100%)\n"
|
||||||
|
"can and will break games and cause glitches.\n"
|
||||||
|
"Do so at your own risk. Please do not report\n"
|
||||||
|
"bugs that occur with a non-default clock.\n"));
|
||||||
|
OCText = new wxStaticText(AdvancedPage, wxID_ANY, "");
|
||||||
|
bOverclockEnable->Add(EnableOC);
|
||||||
|
bOverclock->Add(OCSlider, 1, wxALL, 5);
|
||||||
|
bOverclock->Add(OCText, 1, wxALL, 5);
|
||||||
|
bOverclockDesc->Add(OCDescription, 1, wxALL, 5);
|
||||||
|
sbCPUOptions->Add(bOverclockEnable);
|
||||||
|
sbCPUOptions->Add(bOverclock);
|
||||||
|
sbCPUOptions->Add(bOverclockDesc);
|
||||||
|
wxBoxSizer* const sAdvancedPage = new wxBoxSizer(wxVERTICAL);
|
||||||
|
sAdvancedPage->Add(sbCPUOptions, 0, wxEXPAND | wxALL, 5);
|
||||||
|
AdvancedPage->SetSizer(sAdvancedPage);
|
||||||
|
|
||||||
InitializeGUIValues();
|
InitializeGUIValues();
|
||||||
InitializeGUITooltips();
|
InitializeGUITooltips();
|
||||||
|
|
||||||
|
@ -805,6 +840,14 @@ void CConfigMain::OnOk(wxCommandEvent& WXUNUSED (event))
|
||||||
SConfig::GetInstance().SaveSettings();
|
SConfig::GetInstance().SaveSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CConfigMain::UpdateCPUClock()
|
||||||
|
{
|
||||||
|
bool wii = SConfig::GetInstance().m_LocalCoreStartupParameter.bWii;
|
||||||
|
int percent = (int)(roundf(SConfig::GetInstance().m_OCFactor * 100.f));
|
||||||
|
int clock = (int)(roundf(SConfig::GetInstance().m_OCFactor * (wii ? 729.f : 486.f)));
|
||||||
|
OCText->SetLabel(SConfig::GetInstance().m_OCEnable ? wxString::Format("%d %% (%d mhz)", percent, clock) : "");
|
||||||
|
}
|
||||||
|
|
||||||
// Core settings
|
// Core settings
|
||||||
void CConfigMain::CoreSettingsChanged(wxCommandEvent& event)
|
void CConfigMain::CoreSettingsChanged(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
|
@ -839,6 +882,16 @@ void CConfigMain::CoreSettingsChanged(wxCommandEvent& event)
|
||||||
case ID_NTSCJ:
|
case ID_NTSCJ:
|
||||||
startup_params.bForceNTSCJ = _NTSCJ->IsChecked();
|
startup_params.bForceNTSCJ = _NTSCJ->IsChecked();
|
||||||
break;
|
break;
|
||||||
|
case ID_ENABLEOVERCLOCK:
|
||||||
|
SConfig::GetInstance().m_OCEnable = EnableOC->IsChecked();
|
||||||
|
OCSlider->Enable(SConfig::GetInstance().m_OCEnable);
|
||||||
|
UpdateCPUClock();
|
||||||
|
break;
|
||||||
|
case ID_OVERCLOCK:
|
||||||
|
// Vaguely exponential scaling?
|
||||||
|
SConfig::GetInstance().m_OCFactor = exp2f((OCSlider->GetValue() - 100.f) / 25.f);
|
||||||
|
UpdateCPUClock();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,7 @@ public:
|
||||||
ID_GAMECUBEPAGE,
|
ID_GAMECUBEPAGE,
|
||||||
ID_WIIPAGE,
|
ID_WIIPAGE,
|
||||||
ID_PATHSPAGE,
|
ID_PATHSPAGE,
|
||||||
|
ID_ADVANCEDPAGE,
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -77,7 +78,9 @@ private:
|
||||||
ID_CPUTHREAD = 1010,
|
ID_CPUTHREAD = 1010,
|
||||||
ID_IDLESKIP,
|
ID_IDLESKIP,
|
||||||
ID_ENABLECHEATS,
|
ID_ENABLECHEATS,
|
||||||
|
ID_ENABLEOVERCLOCK,
|
||||||
ID_FRAMELIMIT,
|
ID_FRAMELIMIT,
|
||||||
|
ID_OVERCLOCK,
|
||||||
|
|
||||||
ID_CPUENGINE,
|
ID_CPUENGINE,
|
||||||
|
|
||||||
|
@ -144,6 +147,9 @@ private:
|
||||||
// Advanced
|
// Advanced
|
||||||
wxRadioBox* CPUEngine;
|
wxRadioBox* CPUEngine;
|
||||||
wxCheckBox* _NTSCJ;
|
wxCheckBox* _NTSCJ;
|
||||||
|
wxSlider* OCSlider;
|
||||||
|
wxStaticText* OCText;
|
||||||
|
wxCheckBox* EnableOC;
|
||||||
|
|
||||||
|
|
||||||
wxBoxSizer* sDisplayPage; // Display settings
|
wxBoxSizer* sDisplayPage; // Display settings
|
||||||
|
@ -238,6 +244,7 @@ private:
|
||||||
void UpdateGUI();
|
void UpdateGUI();
|
||||||
void OnClose(wxCloseEvent& event);
|
void OnClose(wxCloseEvent& event);
|
||||||
|
|
||||||
|
void UpdateCPUClock();
|
||||||
void CoreSettingsChanged(wxCommandEvent& event);
|
void CoreSettingsChanged(wxCommandEvent& event);
|
||||||
|
|
||||||
void DisplaySettingsChanged(wxCommandEvent& event);
|
void DisplaySettingsChanged(wxCommandEvent& event);
|
||||||
|
|
|
@ -438,6 +438,8 @@ void NetPlayDiag::GetNetSettings(NetSettings &settings)
|
||||||
settings.m_DSPHLE = instance.m_LocalCoreStartupParameter.bDSPHLE;
|
settings.m_DSPHLE = instance.m_LocalCoreStartupParameter.bDSPHLE;
|
||||||
settings.m_DSPEnableJIT = instance.m_DSPEnableJIT;
|
settings.m_DSPEnableJIT = instance.m_DSPEnableJIT;
|
||||||
settings.m_WriteToMemcard = m_memcard_write->GetValue();
|
settings.m_WriteToMemcard = m_memcard_write->GetValue();
|
||||||
|
settings.m_OCEnable = instance.m_OCEnable;
|
||||||
|
settings.m_OCFactor = instance.m_OCFactor;
|
||||||
settings.m_EXIDevice[0] = instance.m_EXIDevice[0];
|
settings.m_EXIDevice[0] = instance.m_EXIDevice[0];
|
||||||
settings.m_EXIDevice[1] = instance.m_EXIDevice[1];
|
settings.m_EXIDevice[1] = instance.m_EXIDevice[1];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue