statesave prep: Change coretiming to index/registration model, instead of storing pointers. This will make it possible to save/load the event queue.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@258 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2008-08-21 20:01:18 +00:00
parent 9e3747e2f3
commit 6a4d697f5f
15 changed files with 174 additions and 138 deletions

View File

@ -39,7 +39,6 @@ struct SCoreStartupParameter
bool bUseDualCore;
bool bNTSC;
bool bHLEBios;
bool bThrottle;
bool bUseFastMem;
bool bLockThreads;
bool bOptimizeQuantizers;

View File

@ -15,6 +15,8 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include <vector>
#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<EventType> 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;

View File

@ -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);

View File

@ -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;
};

View File

@ -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

View File

@ -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()

View File

@ -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:

View File

@ -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<CEXIMemoryCard*>(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<u64>(this));
CoreTiming::RemoveEvent(et_this_card);
CoreTiming::ScheduleEvent(500000000, et_this_card, card_index);
break;
}
}

View File

@ -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

View File

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

View File

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

View File

@ -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; i<HISTORYLENGTH-1; i++)
timeHistory[i] = timeHistory[i+1];
int t = (int)timer.GetTimeDifference();
//timer.Update();
if (timeHistory[0] != 0)
{
const int delta = (int)(1000*(HISTORYLENGTH-1)/ThrottleFrequency);
while (t - timeHistory[0] < delta)
{
// ugh, busy wait
Common::SleepCurrentThread(0);
t = (int)timer.GetTimeDifference();
}
}
timeHistory[HISTORYLENGTH-1] = t;
CoreTiming::ScheduleEvent((int)(GetTicksPerSecond()/ThrottleFrequency)-cyclesLate, &Throttle, "Throttle");
CoreTiming::ScheduleEvent(GPU_PERIOD-cyclesLate, et_GPU);
}
void Init()
@ -202,7 +176,7 @@ void Init()
AI_PERIOD = GetTicksPerSecond() / 80;
DSP_PERIOD = (int)(GetTicksPerSecond() * 0.003f);
HLE_IPC_PERIOD = (int)(GetTicksPerSecond() * 0.003f);
IPC_HLE_PERIOD = (int)(GetTicksPerSecond() * 0.003f);
}
else
{
@ -215,25 +189,28 @@ void Init()
DSP_PERIOD = (int)(GetTicksPerSecond() * 0.005f);
}
Common::Timer::IncreaseResolution();
memset(timeHistory, 0, sizeof(timeHistory));
CoreTiming::Clear();
CoreTiming::ScheduleEvent((int)(GetTicksPerSecond() / ThrottleFrequency), &Throttle, "Throttle");
et_Dec = CoreTiming::RegisterEvent("DecCallback", DecrementerCallback);
et_AI = CoreTiming::RegisterEvent("AICallback", AICallback);
et_VI = CoreTiming::RegisterEvent("VICallback", VICallback);
et_SI = CoreTiming::RegisterEvent("SICallback", SICallback);
et_DSP = CoreTiming::RegisterEvent("DSPCallback", DSPCallback);
et_GPU = CoreTiming::RegisterEvent("GPUCallback", GPUCallback);
et_AudioFifo = CoreTiming::RegisterEvent("AudioFifoCallback", AudioFifoCallback);
et_IPC_HLE = CoreTiming::RegisterEvent("IPC_HLE_UpdateCallback", IPC_HLE_UpdateCallback);
CoreTiming::ScheduleEvent(AI_PERIOD, &AICallback, "AICallback");
CoreTiming::ScheduleEvent(VI_PERIOD, &VICallback, "VICallback");
CoreTiming::ScheduleEvent(DSP_PERIOD, &DSPCallback, "DSPCallback");
CoreTiming::ScheduleEvent(SI_PERIOD, &SICallback, "SICallback");
CoreTiming::ScheduleEvent(CPU_CORE_CLOCK / (32000 * 4 / 32), &AudioFifoCallback, "AudioFifoCallback");
CoreTiming::ScheduleEvent(AI_PERIOD, et_AI);
CoreTiming::ScheduleEvent(VI_PERIOD, et_VI);
CoreTiming::ScheduleEvent(DSP_PERIOD, et_DSP);
CoreTiming::ScheduleEvent(SI_PERIOD, et_SI);
CoreTiming::ScheduleEvent(CPU_CORE_CLOCK / (32000 * 4 / 32), et_AudioFifo);
if (!Core::GetStartupParameter().bUseDualCore)
CoreTiming::ScheduleEvent(GPU_PERIOD, &RunGPUCallback, "RunGPUCallback");
CoreTiming::ScheduleEvent(GPU_PERIOD, et_GPU);
if (Core::GetStartupParameter().bWii)
{
CoreTiming::ScheduleEvent(HLE_IPC_PERIOD, &IPC_HLE_UpdateCallback, "IPC_HLE_UpdateCallback");
}
CoreTiming::ScheduleEvent(IPC_HLE_PERIOD, et_IPC_HLE);
CoreTiming::RegisterAdvanceCallback(&AdvanceCallback);
}
@ -243,4 +220,4 @@ void Shutdown()
CoreTiming::Clear();
}
}
} // namespace

View File

@ -66,7 +66,6 @@ void SConfig::SaveSettings()
ini.Set("Core", "HLEBios", m_LocalCoreStartupParameter.bHLEBios);
ini.Set("Core", "UseDynarec", m_LocalCoreStartupParameter.bUseDynarec);
ini.Set("Core", "UseDualCore", m_LocalCoreStartupParameter.bUseDualCore);
ini.Set("Core", "Throttle", m_LocalCoreStartupParameter.bThrottle);
ini.Set("Core", "LockThreads", m_LocalCoreStartupParameter.bLockThreads);
ini.Set("Core", "DefaultGCM", m_LocalCoreStartupParameter.m_strDefaultGCM);
ini.Set("Core", "OptimizeQuantizers", m_LocalCoreStartupParameter.bOptimizeQuantizers);
@ -117,7 +116,6 @@ void SConfig::LoadSettings()
ini.Get("Core", "HLEBios", &m_LocalCoreStartupParameter.bHLEBios, true);
ini.Get("Core", "UseDynarec", &m_LocalCoreStartupParameter.bUseDynarec, true);
ini.Get("Core", "UseDualCore", &m_LocalCoreStartupParameter.bUseDualCore, false);
ini.Get("Core", "Throttle", &m_LocalCoreStartupParameter.bThrottle, true);
ini.Get("Core", "LockThreads", &m_LocalCoreStartupParameter.bLockThreads, true);
ini.Get("Core", "OptimizeQuantizers", &m_LocalCoreStartupParameter.bOptimizeQuantizers, true);
}

View File

@ -94,7 +94,6 @@ EVT_MENU(IDM_BROWSE, CFrame::OnBrowse)
EVT_MENU(IDM_MEMCARD, CFrame::OnMemcard)
EVT_MENU(IDM_TOGGLE_FULLSCREEN, CFrame::OnToggleFullscreen)
EVT_MENU(IDM_TOGGLE_DUALCORE, CFrame::OnToggleDualCore)
EVT_MENU(IDM_TOGGLE_THROTTLE, CFrame::OnToggleThrottle)
EVT_MENU(IDM_TOGGLE_TOOLBAR, CFrame::OnToggleToolbar)
EVT_HOST_COMMAND(wxID_ANY, CFrame::OnHostMessage)
END_EVENT_TABLE()
@ -197,8 +196,6 @@ void CFrame::CreateMenu()
pOptionsMenu->Append(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();

View File

@ -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,