Uber-fast stop (thanks to smart memory card flushing) and various savestate changes.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3659 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
3ddbb094ab
commit
06b65ea425
|
@ -232,9 +232,7 @@ bool Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called from GUI thread or VI thread (why VI??? That must be bad. Window close? TODO: Investigate.)
|
// Called from GUI thread or VI thread (why VI??? That must be bad. Window close? TODO: Investigate.)
|
||||||
// JP: No, when you press Stop this is run from the Main Thread it seems
|
void Stop() // - Hammertime!
|
||||||
// - Hammertime!
|
|
||||||
void Stop()
|
|
||||||
{
|
{
|
||||||
const SCoreStartupParameter& _CoreParameter = SConfig::GetInstance().m_LocalCoreStartupParameter;
|
const SCoreStartupParameter& _CoreParameter = SConfig::GetInstance().m_LocalCoreStartupParameter;
|
||||||
|
|
||||||
|
@ -253,12 +251,12 @@ void Stop()
|
||||||
// Stop the CPU
|
// Stop the CPU
|
||||||
PowerPC::Stop();
|
PowerPC::Stop();
|
||||||
CCPU::StepOpcode(); // Kick it if it's waiting (code stepping wait loop)
|
CCPU::StepOpcode(); // Kick it if it's waiting (code stepping wait loop)
|
||||||
|
|
||||||
// Wait until the CPU finishes exiting the main run loop
|
// Wait until the CPU finishes exiting the main run loop
|
||||||
cpuRunloopQuit.Wait();
|
cpuRunloopQuit.Wait();
|
||||||
cpuRunloopQuit.Shutdown();
|
cpuRunloopQuit.Shutdown();
|
||||||
// At this point, we must be out of the CPU:s runloop.
|
// At this point, we must be out of the CPU:s runloop.
|
||||||
|
|
||||||
// Stop audio thread.
|
// Stop audio thread.
|
||||||
CPluginManager::GetInstance().GetDSP()->DSP_StopSoundStream();
|
CPluginManager::GetInstance().GetDSP()->DSP_StopSoundStream();
|
||||||
|
|
||||||
|
@ -300,8 +298,7 @@ void Stop()
|
||||||
#endif
|
#endif
|
||||||
delete g_EmuThread; // Wait for emuthread to close.
|
delete g_EmuThread; // Wait for emuthread to close.
|
||||||
g_EmuThread = 0;
|
g_EmuThread = 0;
|
||||||
#endif
|
#else
|
||||||
#ifdef SETUP_TIMER_WAITING
|
|
||||||
Host_UpdateGUI();
|
Host_UpdateGUI();
|
||||||
StopUpToVideoDone = false;
|
StopUpToVideoDone = false;
|
||||||
StopReachedEnd = true;
|
StopReachedEnd = true;
|
||||||
|
|
|
@ -43,7 +43,8 @@ void CEXIMemoryCard::FlushCallback(u64 userdata, int cyclesLate)
|
||||||
CEXIMemoryCard::CEXIMemoryCard(const std::string& _rName, const std::string& _rFilename, int _card_index) :
|
CEXIMemoryCard::CEXIMemoryCard(const std::string& _rName, const std::string& _rFilename, int _card_index) :
|
||||||
m_strFilename(_rFilename),
|
m_strFilename(_rFilename),
|
||||||
card_index(_card_index),
|
card_index(_card_index),
|
||||||
flushThread(NULL)
|
flushThread(NULL),
|
||||||
|
m_bDirty(false)
|
||||||
{
|
{
|
||||||
cards[_card_index] = this;
|
cards[_card_index] = this;
|
||||||
et_this_card = CoreTiming::RegisterEvent(_rName.c_str(), FlushCallback);
|
et_this_card = CoreTiming::RegisterEvent(_rName.c_str(), FlushCallback);
|
||||||
|
@ -138,6 +139,9 @@ THREAD_RETURN innerFlush(void *pArgs)
|
||||||
// Flush memory card contents to disc
|
// Flush memory card contents to disc
|
||||||
void CEXIMemoryCard::Flush(bool exiting)
|
void CEXIMemoryCard::Flush(bool exiting)
|
||||||
{
|
{
|
||||||
|
if(!m_bDirty)
|
||||||
|
return;
|
||||||
|
|
||||||
if(flushThread)
|
if(flushThread)
|
||||||
{
|
{
|
||||||
delete flushThread;
|
delete flushThread;
|
||||||
|
@ -157,6 +161,8 @@ void CEXIMemoryCard::Flush(bool exiting)
|
||||||
flushThread = new Common::Thread(innerFlush, fs);
|
flushThread = new Common::Thread(innerFlush, fs);
|
||||||
if(exiting)
|
if(exiting)
|
||||||
flushThread->WaitForDeath();
|
flushThread->WaitForDeath();
|
||||||
|
|
||||||
|
m_bDirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CEXIMemoryCard::~CEXIMemoryCard()
|
CEXIMemoryCard::~CEXIMemoryCard()
|
||||||
|
@ -205,6 +211,7 @@ void CEXIMemoryCard::SetCS(int cs)
|
||||||
status &= ~MC_STATUS_BUSY;
|
status &= ~MC_STATUS_BUSY;
|
||||||
|
|
||||||
m_bInterruptSet = 1;
|
m_bInterruptSet = 1;
|
||||||
|
m_bDirty = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -213,6 +220,7 @@ void CEXIMemoryCard::SetCS(int cs)
|
||||||
{
|
{
|
||||||
memset(memory_card_content, 0xFF, memory_card_size);
|
memset(memory_card_content, 0xFF, memory_card_size);
|
||||||
status &= ~MC_STATUS_BUSY;
|
status &= ~MC_STATUS_BUSY;
|
||||||
|
m_bDirty = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -234,6 +242,7 @@ void CEXIMemoryCard::SetCS(int cs)
|
||||||
status &= ~MC_STATUS_BUSY;
|
status &= ~MC_STATUS_BUSY;
|
||||||
|
|
||||||
m_bInterruptSet = 1;
|
m_bInterruptSet = 1;
|
||||||
|
m_bDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Page written to memory card, not just to buffer - let's schedule a flush 0.5b cycles into the future (1 sec)
|
// Page written to memory card, not just to buffer - let's schedule a flush 0.5b cycles into the future (1 sec)
|
||||||
|
|
|
@ -79,6 +79,7 @@ private:
|
||||||
u32 m_uPosition;
|
u32 m_uPosition;
|
||||||
u8 programming_buffer[128];
|
u8 programming_buffer[128];
|
||||||
u32 formatDelay;
|
u32 formatDelay;
|
||||||
|
bool m_bDirty;
|
||||||
|
|
||||||
//! memory card parameters
|
//! memory card parameters
|
||||||
unsigned int nintendo_card_id, card_id;
|
unsigned int nintendo_card_id, card_id;
|
||||||
|
|
|
@ -75,7 +75,7 @@ namespace HW
|
||||||
{
|
{
|
||||||
SystemTimers::Shutdown();
|
SystemTimers::Shutdown();
|
||||||
CCPU::Shutdown();
|
CCPU::Shutdown();
|
||||||
ExpansionInterface::Shutdown();
|
ExpansionInterface::Shutdown();
|
||||||
DVDInterface::Shutdown();
|
DVDInterface::Shutdown();
|
||||||
DSP::Shutdown();
|
DSP::Shutdown();
|
||||||
Memory::Shutdown();
|
Memory::Shutdown();
|
||||||
|
|
|
@ -31,6 +31,9 @@
|
||||||
|
|
||||||
#include "minilzo.h"
|
#include "minilzo.h"
|
||||||
|
|
||||||
|
///////////
|
||||||
|
// TODO: Investigate a memory leak on save/load state
|
||||||
|
///////////
|
||||||
|
|
||||||
#if defined(__LZO_STRICT_16BIT)
|
#if defined(__LZO_STRICT_16BIT)
|
||||||
#define IN_LEN (8*1024u)
|
#define IN_LEN (8*1024u)
|
||||||
|
@ -286,8 +289,12 @@ void LoadStateCallback(u64 userdata, int cyclesLate)
|
||||||
fread(out, 1, cur_len, f);
|
fread(out, 1, cur_len, f);
|
||||||
|
|
||||||
int res = lzo1x_decompress(out, cur_len, (buffer + i), &new_len, NULL);
|
int res = lzo1x_decompress(out, cur_len, (buffer + i), &new_len, NULL);
|
||||||
if(res != LZO_E_OK)
|
if(res != LZO_E_OK) {
|
||||||
PanicAlert("Internal LZO Error - decompression failed (%d)", res);
|
PanicAlert("Internal LZO Error - decompression failed (%d)\n"
|
||||||
|
"Try loading the state again", res);
|
||||||
|
fclose(f);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// The size of the data to read to our buffer is 'new_len'
|
// The size of the data to read to our buffer is 'new_len'
|
||||||
i += new_len;
|
i += new_len;
|
||||||
|
|
|
@ -509,9 +509,37 @@ void Initialize()
|
||||||
// ================
|
// ================
|
||||||
|
|
||||||
|
|
||||||
void DoState(void* ptr, int mode)
|
void DoState(PointerWrap &p)
|
||||||
{
|
{
|
||||||
//TODO: implement
|
return;
|
||||||
|
// TODO: Shorten the list
|
||||||
|
p.Do(g_Leds);
|
||||||
|
//p.Do(g_Speaker);
|
||||||
|
//p.Do(g_SpeakerVoice);
|
||||||
|
p.Do(g_IR);
|
||||||
|
p.DoArray(g_Eeprom, WIIMOTE_EEPROM_SIZE);
|
||||||
|
p.DoArray(g_RegSpeaker, WIIMOTE_REG_SPEAKER_SIZE);
|
||||||
|
p.DoArray(g_RegExt, WIIMOTE_REG_EXT_SIZE);
|
||||||
|
p.DoArray(g_RegExtTmp, WIIMOTE_REG_EXT_SIZE);
|
||||||
|
p.DoArray(g_RegIr, WIIMOTE_REG_IR_SIZE);
|
||||||
|
|
||||||
|
p.Do(g_ReportingMode);
|
||||||
|
p.Do(g_ReportingChannel);
|
||||||
|
|
||||||
|
p.Do(AckDelay);
|
||||||
|
|
||||||
|
p.Do(g_ExtKey);
|
||||||
|
p.Do(g_Encryption);
|
||||||
|
|
||||||
|
p.Do(NumPads);
|
||||||
|
p.Do(NumGoodPads);
|
||||||
|
p.Do(joyinfo);
|
||||||
|
p.DoArray(PadState, 4);
|
||||||
|
p.DoArray(PadMapping, 4);
|
||||||
|
|
||||||
|
p.Do(g_Wm);
|
||||||
|
p.Do(g_Nc);
|
||||||
|
p.Do(g_Cc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is not needed if we call FreeLibrary() when we stop a game, but if it's not called we need to reset
|
/* This is not needed if we call FreeLibrary() when we stop a game, but if it's not called we need to reset
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#include "wiimote_hid.h"
|
#include "wiimote_hid.h"
|
||||||
#include "EmuDefinitions.h"
|
#include "EmuDefinitions.h"
|
||||||
|
#include "ChunkFile.h"
|
||||||
|
|
||||||
namespace WiiMoteEmu
|
namespace WiiMoteEmu
|
||||||
{
|
{
|
||||||
|
@ -35,7 +36,7 @@ void GetMousePos(float& x, float& y);
|
||||||
|
|
||||||
// General functions
|
// General functions
|
||||||
void Initialize();
|
void Initialize();
|
||||||
void DoState(void* ptr, int mode);
|
void DoState(PointerWrap &p);
|
||||||
void Shutdown(void);
|
void Shutdown(void);
|
||||||
void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size);
|
void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size);
|
||||||
void ControlChannel(u16 _channelID, const void* _pData, u32 _Size) ;
|
void ControlChannel(u16 _channelID, const void* _pData, u32 _Size) ;
|
||||||
|
|
|
@ -266,10 +266,28 @@ void Shutdown(void)
|
||||||
|
|
||||||
void DoState(unsigned char **ptr, int mode)
|
void DoState(unsigned char **ptr, int mode)
|
||||||
{
|
{
|
||||||
|
PointerWrap p(ptr, mode);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
// TODO: Shorten the list
|
||||||
|
//p.Do(g_EmulatorRunning);
|
||||||
|
//p.Do(g_ISOId);
|
||||||
|
p.Do(g_FrameOpen);
|
||||||
|
p.Do(g_RealWiiMotePresent);
|
||||||
|
p.Do(g_RealWiiMoteInitialized);
|
||||||
|
p.Do(g_EmulatedWiiMoteInitialized);
|
||||||
|
p.Do(g_WiimoteUnexpectedDisconnect);
|
||||||
|
p.Do(g_UpdateCounter);
|
||||||
|
p.Do(g_UpdateTime);
|
||||||
|
p.Do(g_UpdateRate);
|
||||||
|
p.Do(g_UpdateWriteScreen);
|
||||||
|
p.Do(g_UpdateTimeList);
|
||||||
|
|
||||||
#if HAVE_WIIUSE
|
#if HAVE_WIIUSE
|
||||||
WiiMoteReal::DoState(ptr, mode);
|
WiiMoteReal::DoState(p);
|
||||||
#endif
|
#endif
|
||||||
WiiMoteEmu::DoState(ptr, mode);
|
WiiMoteEmu::DoState(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -400,7 +400,10 @@ int Initialize()
|
||||||
return g_NumberOfWiiMotes;
|
return g_NumberOfWiiMotes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoState(void* ptr, int mode) {}
|
void DoState(PointerWrap &p)
|
||||||
|
{
|
||||||
|
//TODO: Implement
|
||||||
|
}
|
||||||
|
|
||||||
void Shutdown(void)
|
void Shutdown(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
// Includes
|
// Includes
|
||||||
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
|
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||||
#include "wiiuse.h"
|
#include "wiiuse.h"
|
||||||
|
#include "ChunkFile.h"
|
||||||
///////////////////////////////////
|
///////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,7 +34,7 @@ namespace WiiMoteReal
|
||||||
#define MAX_WIIMOTES 1
|
#define MAX_WIIMOTES 1
|
||||||
|
|
||||||
int Initialize();
|
int Initialize();
|
||||||
void DoState(void* ptr, int mode);
|
void DoState(PointerWrap &p);
|
||||||
void Shutdown(void);
|
void Shutdown(void);
|
||||||
void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size);
|
void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size);
|
||||||
void ControlChannel(u16 _channelID, const void* _pData, u32 _Size);
|
void ControlChannel(u16 _channelID, const void* _pData, u32 _Size);
|
||||||
|
|
Loading…
Reference in New Issue