diff --git a/Source/Core/Core/Src/CoreParameter.h b/Source/Core/Core/Src/CoreParameter.h index ac8b704bfe..e71a2130e7 100644 --- a/Source/Core/Core/Src/CoreParameter.h +++ b/Source/Core/Core/Src/CoreParameter.h @@ -39,7 +39,6 @@ struct SCoreStartupParameter bool bUseDualCore; bool bNTSC; bool bHLEBios; - bool bThrottle; bool bUseFastMem; bool bLockThreads; bool bOptimizeQuantizers; diff --git a/Source/Core/Core/Src/CoreTiming.cpp b/Source/Core/Core/Src/CoreTiming.cpp index 3799db6501..0b5648883d 100644 --- a/Source/Core/Core/Src/CoreTiming.cpp +++ b/Source/Core/Core/Src/CoreTiming.cpp @@ -15,6 +15,8 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ +#include + #include "Thread.h" #include "PowerPC/PowerPC.h" #include "CoreTiming.h" @@ -24,12 +26,52 @@ namespace CoreTiming { + +struct EventType +{ + TimedCallback callback; + const char *name; +}; + +std::vector event_types; + +struct Event +{ + s64 time; + u64 userdata; + Event *next; + int type; +}; + +// STATE_TO_SAVE (how?) +Event *first; +Event *tsFirst; + int downcount, slicelength; int maxSliceLength = 20000; s64 globalTimer; s64 idledCycles; +Common::CriticalSection externalEventSection; + +int RegisterEvent(const char *name, TimedCallback callback) +{ + EventType type; + type.name = name; + type.callback = callback; + event_types.push_back(type); + return event_types.size() - 1; +} + +void UnregisterAllEvents() +{ + if (first) + PanicAlert("Cannot unregister events with events pending"); + event_types.clear(); +} + + u64 GetTicks() { return (u64)globalTimer; @@ -40,29 +82,14 @@ u64 GetIdleTicks() return (u64)idledCycles; } -struct Event -{ - TimedCallback callback; - Event *next; - s64 time; - u64 userdata; - const char *name; -}; - -Event *first; -Event *tsFirst; - -Common::CriticalSection externalEventSection; - // This is to be called when outside threads, such as the graphics thread, wants to // schedule things to be executed on the main thread. -void ScheduleEvent_Threadsafe(int cyclesIntoFuture, TimedCallback callback, const char *name, u64 userdata) +void ScheduleEvent_Threadsafe(int cyclesIntoFuture, int event_type, u64 userdata) { externalEventSection.Enter(); Event *ne = new Event; ne->time = globalTimer + cyclesIntoFuture; - ne->name = name; - ne->callback = callback; + ne->type = event_type; ne->next = tsFirst; ne->userdata = userdata; tsFirst = ne; @@ -125,12 +152,11 @@ void AddEventToQueue(Event *ne) // This must be run ONLY from within the cpu thread // cyclesIntoFuture may be VERY inaccurate if called from anything else // than Advance -void ScheduleEvent(int cyclesIntoFuture, TimedCallback callback, const char *name, u64 userdata) +void ScheduleEvent(int cyclesIntoFuture, int event_type, u64 userdata) { Event *ne = new Event; - ne->callback = callback; ne->userdata = userdata; - ne->name = name; + ne->type = event_type; ne->time = globalTimer + cyclesIntoFuture; AddEventToQueue(ne); @@ -144,24 +170,24 @@ void RegisterAdvanceCallback(void (*callback)(int cyclesExecuted)) advanceCallback = callback; } -bool IsScheduled(TimedCallback callback) +bool IsScheduled(int event_type) { if (!first) return false; Event *e = first; while (e) { - if (e->callback == callback) + if (e->type == event_type) return true; e = e->next; } return false; } -void RemoveEvent(TimedCallback callback) +void RemoveEvent(int event_type) { if (!first) return; - if (first->callback == callback) + if (first->type == event_type) { Event *next = first->next; delete first; @@ -173,7 +199,7 @@ void RemoveEvent(TimedCallback callback) Event *ptr = prev->next; while (ptr) { - if (ptr->callback == callback) + if (ptr->type == event_type) { prev->next = ptr->next; delete ptr; @@ -219,8 +245,7 @@ void Advance() // LOG(GEKKO, "[Scheduler] %s (%lld, %lld) ", // first->name ? first->name : "?", (u64)globalTimer, (u64)first->time); - first->callback(first->userdata, (int)(globalTimer - first->time)); - + event_types[first->type].callback(first->userdata, (int)(globalTimer - first->time)); Event *next = first->next; delete first; first = next; diff --git a/Source/Core/Core/Src/CoreTiming.h b/Source/Core/Core/Src/CoreTiming.h index f9e99afa0f..5139df3586 100644 --- a/Source/Core/Core/Src/CoreTiming.h +++ b/Source/Core/Core/Src/CoreTiming.h @@ -14,32 +14,49 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ + #ifndef _CORETIMING_H #define _CORETIMING_H +// This is a system to schedule events into the emulated machine's future. Time is measured +// in main CPU clock cycles. + +// To schedule an event, you first have to register its type. This is where you pass in the +// callback. You then schedule events using the type id you get back. + #include "Common.h" namespace CoreTiming { -enum { - SOON = 100 -}; - typedef void (*TimedCallback)(u64 userdata, int cyclesLate); u64 GetTicks(); u64 GetIdleTicks(); + // The int that the callbacks get is how many cycles late it was. // So to schedule a new event on a regular basis: // inside callback: // ScheduleEvent(periodInCycles - cyclesLate, callback, "whatever") -void ScheduleEvent(int cyclesIntoFuture, TimedCallback callback, const char *name, u64 userdata=0); -void ScheduleEvent_Threadsafe(int cyclesIntoFuture, TimedCallback callback, const char *name, u64 userdata=0); -void RemoveEvent(TimedCallback callback); -bool IsScheduled(TimedCallback callback); + +// Returns the event_type identifier. +int RegisterEvent(const char *name, TimedCallback callback); +void UnregisterAllEvents(); + +// userdata MAY NOT CONTAIN POINTERS. userdata might get written and reloaded from disk, +// when we implement state saves. +void ScheduleEvent(int cyclesIntoFuture, int event_type, u64 userdata=0); +void ScheduleEvent_Threadsafe(int cyclesIntoFuture, int event_type, u64 userdata=0); + +// We only permit one event of each type in the queue at a time. +void RemoveEvent(int event_type); +bool IsScheduled(int event_type); void Advance(); + +// Pretend that the main CPU has executed enough cycles to reach the next event. void Idle(); + +// Clear all pending events. This should ONLY be done on exit. void Clear(); void LogPendingEvents(); void SetMaximumSlice(int maximumSliceLength); diff --git a/Source/Core/Core/Src/Debugger/DebugInterface.h b/Source/Core/Core/Src/Debugger/DebugInterface.h index 3008f5af7d..395d192b31 100644 --- a/Source/Core/Core/Src/Debugger/DebugInterface.h +++ b/Source/Core/Core/Src/Debugger/DebugInterface.h @@ -22,7 +22,7 @@ public: virtual void setPC(unsigned int /*address*/) {} virtual void step() {} virtual void runToBreakpoint() {} - virtual void insertBLR(unsigned int address) {} + virtual void insertBLR(unsigned int /*address*/) {} virtual int getColor(unsigned int /*address*/){return 0xFFFFFFFF;} virtual std::string getDescription(unsigned int /*address*/) = 0; }; diff --git a/Source/Core/Core/Src/HW/CommandProcessor.cpp b/Source/Core/Core/Src/HW/CommandProcessor.cpp index bf7b613880..99fa6967a9 100644 --- a/Source/Core/Core/Src/HW/CommandProcessor.cpp +++ b/Source/Core/Core/Src/HW/CommandProcessor.cpp @@ -91,6 +91,7 @@ union UCPClearReg UCPClearReg(u16 _hex) {Hex = _hex; } }; +// STATE_TO_SAVE // variables UCPStatusReg m_CPStatusReg; UCPCtrlReg m_CPCtrlReg; @@ -114,6 +115,13 @@ inline void WriteHigh(u32& _reg, u16 highbits) {_reg = (_reg & 0x0000FFFF) | ((u inline u16 ReadLow (u32 _reg) {return (u16)(_reg & 0xFFFF);} inline u16 ReadHigh (u32 _reg) {return (u16)(_reg >> 16);} +int et_UpdateInterrupts; + +void UpdateInterrupts_Wrapper(u64 userdata, int cyclesLate) +{ + UpdateInterrupts(); +} + void Init() { m_CPStatusReg.Hex = 0; @@ -132,6 +140,9 @@ void Init() fifo.bFF_GPReadEnable = false; fifo.bFF_GPLinkEnable = false; fifo.bFF_BPEnable = false; + + et_UpdateInterrupts = CoreTiming::RegisterEvent("UpdateInterrupts", UpdateInterrupts_Wrapper); + #ifdef _WIN32 InitializeCriticalSection(&fifo.sync); #endif @@ -464,14 +475,9 @@ void UpdateInterrupts() } } -void UpdateInterrupts_Wrapper(u64 userdata, int cyclesLate) -{ - UpdateInterrupts(); -} - void UpdateInterruptsFromVideoPlugin() { - CoreTiming::ScheduleEvent_Threadsafe(0, &UpdateInterrupts_Wrapper, "CP:UI"); + CoreTiming::ScheduleEvent_Threadsafe(0, et_UpdateInterrupts); } } // end of namespace CommandProcessor diff --git a/Source/Core/Core/Src/HW/DSP.cpp b/Source/Core/Core/Src/HW/DSP.cpp index db49f62839..2b40ea7d8a 100644 --- a/Source/Core/Core/Src/HW/DSP.cpp +++ b/Source/Core/Core/Src/HW/DSP.cpp @@ -164,6 +164,8 @@ struct ARDMA } }; + +// STATE_TO_SAVE u8 *g_ARAM = NULL; DSPState g_dspState; AudioDMA g_audioDMA; @@ -179,11 +181,19 @@ void WriteARAM(u8 _iValue, u32 _iAddress); bool Update_DSP_ReadRegister(); void Update_DSP_WriteRegister(); +int et_GenerateDSPInterrupt; + +void GenerateDSPInterrupt_Wrapper(u64 userdata, int cyclesLate) +{ + GenerateDSPInterrupt((DSPInterruptType)(userdata&0xFFFF), (bool)((userdata>>16) & 1)); +} + void Init() { g_ARAM = (u8 *)AllocateMemoryPages(ARAM_SIZE); g_dspState.DSPControl.Hex = 0; g_dspState.DSPControl.DSPHalt = 1; + et_GenerateDSPInterrupt = CoreTiming::RegisterEvent("DSPint", GenerateDSPInterrupt_Wrapper); } void Shutdown() @@ -525,16 +535,11 @@ void GenerateDSPInterrupt(DSPInterruptType type, bool _bSet) UpdateInterrupts(); } -void GenerateDSPInterrupt_Wrapper(u64 userdata, int cyclesLate) -{ - GenerateDSPInterrupt((DSPInterruptType)(userdata&0xFFFF), (bool)((userdata>>16) & 1)); -} - // CALLED FROM DSP PLUGIN, POSSIBLY THREADED void GenerateDSPInterruptFromPlugin(DSPInterruptType type, bool _bSet) { CoreTiming::ScheduleEvent_Threadsafe( - 0, GenerateDSPInterrupt_Wrapper, "DSPInt", type | (_bSet<<16)); + 0, et_GenerateDSPInterrupt, type | (_bSet<<16)); } void Update_ARAM_DMA() diff --git a/Source/Core/Core/Src/HW/EXI_Device.cpp b/Source/Core/Core/Src/HW/EXI_Device.cpp index 38a1f2ad71..9e84a69725 100644 --- a/Source/Core/Core/Src/HW/EXI_Device.cpp +++ b/Source/Core/Core/Src/HW/EXI_Device.cpp @@ -129,11 +129,11 @@ IEXIDevice* EXIDevice_Create(TEXIDevices _EXIDevice) break; case EXIDEVICE_MEMORYCARD_A: - return new CEXIMemoryCard("MemoryCardA", Core::GetStartupParameter().m_strMemoryCardA); + return new CEXIMemoryCard("MemoryCardA", Core::GetStartupParameter().m_strMemoryCardA, 0); break; case EXIDEVICE_MEMORYCARD_B: - return new CEXIMemoryCard("MemoryCardB", Core::GetStartupParameter().m_strMemoryCardB); + return new CEXIMemoryCard("MemoryCardB", Core::GetStartupParameter().m_strMemoryCardB, 1); break; case EXIDEVICE_IPL: diff --git a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp index cbbb92602e..969f664e34 100644 --- a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp +++ b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp @@ -31,9 +31,21 @@ #define MC_STATUS_PROGRAMEERROR 0x08 #define MC_STATUS_READY 0x01 -CEXIMemoryCard::CEXIMemoryCard(const std::string& _rName, const std::string& _rFilename) : +static CEXIMemoryCard *cards[2]; + +void CEXIMemoryCard::FlushCallback(u64 userdata, int cyclesLate) +{ + CEXIMemoryCard *ptr = cards[userdata]; + ptr->Flush(); +} + +CEXIMemoryCard::CEXIMemoryCard(const std::string& _rName, const std::string& _rFilename, int card_index) : m_strFilename(_rFilename) { + this->card_index = card_index; + cards[card_index] = this; + et_this_card = CoreTiming::RegisterEvent(_rName.c_str(), FlushCallback); + nintendo_card_id = 0x00000010; // 16MBit nintendo card card_id = 0xc221; /* nintendo_card_id = 0x00000510; // 16MBit "bigben" card @@ -85,13 +97,7 @@ void CEXIMemoryCard::Flush() } fwrite(memory_card_content, memory_card_size, 1, pFile); fclose(pFile); -} - -void CEXIMemoryCard::FlushCallback(u64 userdata, int cyclesLate) -{ - CEXIMemoryCard *ptr = reinterpret_cast(userdata); - ptr->Flush(); - Core::DisplayMessage(StringFromFormat("Wrote memory card contents to %s", ptr->GetFileName().c_str()), 4000); + Core::DisplayMessage(StringFromFormat("Wrote memory card contents to %s", GetFileName().c_str()), 4000); } @@ -161,8 +167,8 @@ void CEXIMemoryCard::SetCS(int cs) // Page written to memory card, not just to buffer - let's schedule a flush 0.5b cycles into the future (1 sec) // But first we unschedule already scheduled flushes - no point in flushing once per page for a large write. - CoreTiming::RemoveEvent(&CEXIMemoryCard::FlushCallback); - CoreTiming::ScheduleEvent(500000000, &CEXIMemoryCard::FlushCallback, "Memory Card Flush", reinterpret_cast(this)); + CoreTiming::RemoveEvent(et_this_card); + CoreTiming::ScheduleEvent(500000000, et_this_card, card_index); break; } } diff --git a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.h b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.h index a8e75b3a2e..b4e0fb1512 100644 --- a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.h +++ b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.h @@ -21,7 +21,7 @@ class CEXIMemoryCard : public IEXIDevice { public: - CEXIMemoryCard(const std::string& _rName, const std::string& _rFilename); + CEXIMemoryCard(const std::string& _rName, const std::string& _rFilename, int card_index); virtual ~CEXIMemoryCard(); void SetCS(int cs); void Update(); @@ -58,7 +58,8 @@ private: }; std::string m_strFilename; - + int card_index; + int et_this_card; //! memory card state // STATE_TO_SAVE diff --git a/Source/Core/Core/Src/HW/HW.cpp b/Source/Core/Core/Src/HW/HW.cpp index 401fd792eb..828f438fcf 100644 --- a/Source/Core/Core/Src/HW/HW.cpp +++ b/Source/Core/Core/Src/HW/HW.cpp @@ -34,6 +34,7 @@ #include "VideoInterface.h" #include "WII_IPC.h" #include "../Plugins/Plugin_Video.h" +#include "../CoreTiming.h" #include "SystemTimers.h" #include "../IPC_HLE/WII_IPC_HLE.h" @@ -75,5 +76,7 @@ namespace HW WII_IPC_HLE_Interface::Shutdown(); WII_IPCInterface::Shutdown(); Thunk_Shutdown(); + + CoreTiming::UnregisterAllEvents(); } } diff --git a/Source/Core/Core/Src/HW/PixelEngine.cpp b/Source/Core/Core/Src/HW/PixelEngine.cpp index 38daae778c..78c990e303 100644 --- a/Source/Core/Core/Src/HW/PixelEngine.cpp +++ b/Source/Core/Core/Src/HW/PixelEngine.cpp @@ -57,12 +57,21 @@ static u16 g_token = 0; static bool g_bSignalTokenInterrupt; static bool g_bSignalFinishInterrupt; +int et_SetTokenOnMainThread; +int et_SetFinishOnMainThread; + void UpdateInterrupts(); +void SetToken_OnMainThread(u64 userdata, int cyclesLate); +void SetFinish_OnMainThread(u64 userdata, int cyclesLate); + void Init() { g_token = 0; g_ctrlReg.Hex = 0; + + et_SetTokenOnMainThread = CoreTiming::RegisterEvent("SetToken", SetToken_OnMainThread); + et_SetFinishOnMainThread = CoreTiming::RegisterEvent("SetFinish", SetFinish_OnMainThread); } void Read16(u16& _uReturnValue, const u32 _iAddress) @@ -164,7 +173,7 @@ void SetFinish_OnMainThread(u64 userdata, int cyclesLate) void SetToken(const unsigned __int16 _token, const int _bSetTokenAcknowledge) { CoreTiming::ScheduleEvent_Threadsafe( - 0, SetToken_OnMainThread, "SetToken", _token | (_bSetTokenAcknowledge << 16)); + 0, et_SetTokenOnMainThread, _token | (_bSetTokenAcknowledge << 16)); } // SetFinish @@ -172,7 +181,7 @@ void SetToken(const unsigned __int16 _token, const int _bSetTokenAcknowledge) void SetFinish() { CoreTiming::ScheduleEvent_Threadsafe( - 0, SetFinish_OnMainThread, "SetFinish"); + 0, et_SetFinishOnMainThread); LOG(PIXELENGINE, "VIDEO Set Finish"); } diff --git a/Source/Core/Core/Src/HW/SystemTimers.cpp b/Source/Core/Core/Src/HW/SystemTimers.cpp index 2c02fa2f60..10615acca7 100644 --- a/Source/Core/Core/Src/HW/SystemTimers.cpp +++ b/Source/Core/Core/Src/HW/SystemTimers.cpp @@ -37,7 +37,6 @@ namespace SystemTimers u32 CPU_CORE_CLOCK = 486000000u; // 486 mhz (its not 485, stop bugging me!) -const int ThrottleFrequency = 60; s64 fakeDec; //ratio of TB and Decrementer to clock cycles @@ -46,6 +45,15 @@ enum { TIMER_RATIO = 8 }; +int et_Dec; +int et_VI; +int et_SI; +int et_AI; +int et_AudioFifo; +int et_DSP; +int et_IPC_HLE; +int et_GPU; + // These are badly educated guesses // Feel free to experiment int @@ -58,7 +66,6 @@ int // We should obey that instead of arbitrarly checking at 60fps. SI_PERIOD = GetTicksPerSecond() / 60, //once a frame is good for controllers - // These are the big question marks IMHO :) // This one should simply be determined by the increasing counter in AI. AI_PERIOD = GetTicksPerSecond() / 80, @@ -67,7 +74,7 @@ int // This is completely arbitrary. If we find that we need lower latency, we can just // increase this number. - HLE_IPC_PERIOD = GetTicksPerSecond() / 250, + IPC_HLE_PERIOD = GetTicksPerSecond() / 250, // This one is also fairly arbitrary. Every N cycles, run the GPU until it starves (in single core mode only). GPU_PERIOD = 10000; @@ -87,14 +94,14 @@ void AICallback(u64 userdata, int cyclesLate) // Update disk streaming. All that code really needs a revamp, including replacing the codec with the one // from in_cube. AudioInterface::Update(); - CoreTiming::ScheduleEvent(AI_PERIOD-cyclesLate, &AICallback, "AICallback"); + CoreTiming::ScheduleEvent(AI_PERIOD-cyclesLate, et_AI); } void DSPCallback(u64 userdata, int cyclesLate) { // ~1/6th as many cycles as the period PPC-side. PluginDSP::DSP_Update(DSP_PERIOD / 6); - CoreTiming::ScheduleEvent(DSP_PERIOD-cyclesLate, &DSPCallback, "DSPCallback"); + CoreTiming::ScheduleEvent(DSP_PERIOD-cyclesLate, et_DSP); } void AudioFifoCallback(u64 userdata, int cyclesLate) @@ -102,19 +109,19 @@ void AudioFifoCallback(u64 userdata, int cyclesLate) int period = CPU_CORE_CLOCK / (AudioInterface::GetDSPSampleRate() * 4 / 32); DSP::UpdateAudioDMA(); // Push audio to speakers. - CoreTiming::ScheduleEvent(period - cyclesLate, &AudioFifoCallback, "AudioFifoCallback"); + CoreTiming::ScheduleEvent(period - cyclesLate, et_AudioFifo); } void IPC_HLE_UpdateCallback(u64 userdata, int cyclesLate) { WII_IPC_HLE_Interface::Update(); - CoreTiming::ScheduleEvent(HLE_IPC_PERIOD-cyclesLate, &IPC_HLE_UpdateCallback, "IPC_HLE_UpdateCallback"); + CoreTiming::ScheduleEvent(IPC_HLE_PERIOD-cyclesLate, et_IPC_HLE); } void VICallback(u64 userdata, int cyclesLate) { VideoInterface::Update(); - CoreTiming::ScheduleEvent(VI_PERIOD-cyclesLate, &VICallback, "VICallback"); + CoreTiming::ScheduleEvent(VI_PERIOD-cyclesLate, et_VI); } void SICallback(u64 userdata, int cyclesLate) @@ -123,7 +130,7 @@ void SICallback(u64 userdata, int cyclesLate) PatchEngine_ApplyFramePatches(); // OK, do what we are here to do. SerialInterface::UpdateDevices(); - CoreTiming::ScheduleEvent(SI_PERIOD-cyclesLate, &SICallback, "SICallback"); + CoreTiming::ScheduleEvent(SI_PERIOD-cyclesLate, et_SI); } void DecrementerCallback(u64 userdata, int cyclesLate) @@ -138,8 +145,8 @@ void DecrementerSet() { u32 decValue = PowerPC::ppcState.spr[SPR_DEC]; fakeDec = decValue*TIMER_RATIO; - CoreTiming::RemoveEvent(DecrementerCallback); - CoreTiming::ScheduleEvent(decValue * TIMER_RATIO, DecrementerCallback, "DecCallback"); + CoreTiming::RemoveEvent(et_Dec); + CoreTiming::ScheduleEvent(decValue * TIMER_RATIO, et_Dec); } void AdvanceCallback(int cyclesExecuted) @@ -151,43 +158,10 @@ void AdvanceCallback(int cyclesExecuted) PowerPC::ppcState.spr[SPR_DEC] = (u32)fakeDec / TIMER_RATIO; } -void RunGPUCallback(u64 userdata, int cyclesLate) +void GPUCallback(u64 userdata, int cyclesLate) { CommandProcessor::CatchUpGPU(); - CoreTiming::ScheduleEvent(GPU_PERIOD-cyclesLate, &RunGPUCallback, "RunGPUCallback"); -} - -// TODO(ector): improve, by using a more accurate timer -// calculate the timing over the past 7 frames -// calculating over all time doesn't work : if it's slow for a while, will run like crazy after that -// calculating over just 1 frame is too shaky -#define HISTORYLENGTH 7 -int timeHistory[HISTORYLENGTH] = {0,0,0,0,0}; - -void Throttle(u64 userdata, int cyclesLate) -{ - if (!Core::GetStartupParameter().bThrottle) - return; - static Common::Timer timer; - - for (int i=0; iAppend(IDM_TOGGLE_FULLSCREEN, _T("&Fullscreen")); pOptionsMenu->AppendCheckItem(IDM_TOGGLE_DUALCORE, _T("&Dual-core (unstable!)")); pOptionsMenu->Check(IDM_TOGGLE_DUALCORE, SConfig::GetInstance().m_LocalCoreStartupParameter.bUseDualCore); - pOptionsMenu->AppendCheckItem(IDM_TOGGLE_THROTTLE, _T("&Enable throttle")); - pOptionsMenu->Check(IDM_TOGGLE_THROTTLE, SConfig::GetInstance().m_LocalCoreStartupParameter.bThrottle); m_pMenuBar->Append(pOptionsMenu, _T("&Options")); // misc menu @@ -499,12 +496,6 @@ void CFrame::OnToggleDualCore(wxCommandEvent& WXUNUSED (event)) SConfig::GetInstance().SaveSettings(); } -void CFrame::OnToggleThrottle(wxCommandEvent& WXUNUSED (event)) -{ - SConfig::GetInstance().m_LocalCoreStartupParameter.bThrottle = !SConfig::GetInstance().m_LocalCoreStartupParameter.bThrottle; - SConfig::GetInstance().SaveSettings(); -} - void CFrame::OnToggleToolbar(wxCommandEvent& event) { wxToolBarBase* toolBar = GetToolBar(); diff --git a/Source/Core/DolphinWX/src/Globals.h b/Source/Core/DolphinWX/src/Globals.h index 3440b8a8b6..0f71cca6c1 100644 --- a/Source/Core/DolphinWX/src/Globals.h +++ b/Source/Core/DolphinWX/src/Globals.h @@ -34,7 +34,6 @@ enum IDM_CONFIG_PAD_PLUGIN, IDM_TOGGLE_FULLSCREEN, IDM_TOGGLE_DUALCORE, - IDM_TOGGLE_THROTTLE, IDM_TOGGLE_TOOLBAR, IDM_NOTIFYMAPLOADED, IDM_UPDATELOGDISPLAY,