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:
XTra.KrazzY 2009-07-03 12:22:32 +00:00
parent 3ddbb094ab
commit 06b65ea425
10 changed files with 83 additions and 18 deletions

View File

@ -232,9 +232,7 @@ bool Init()
}
// 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
// - Hammertime!
void Stop()
void Stop() // - Hammertime!
{
const SCoreStartupParameter& _CoreParameter = SConfig::GetInstance().m_LocalCoreStartupParameter;
@ -253,12 +251,12 @@ void Stop()
// Stop the CPU
PowerPC::Stop();
CCPU::StepOpcode(); // Kick it if it's waiting (code stepping wait loop)
// Wait until the CPU finishes exiting the main run loop
cpuRunloopQuit.Wait();
cpuRunloopQuit.Shutdown();
// At this point, we must be out of the CPU:s runloop.
// Stop audio thread.
CPluginManager::GetInstance().GetDSP()->DSP_StopSoundStream();
@ -300,8 +298,7 @@ void Stop()
#endif
delete g_EmuThread; // Wait for emuthread to close.
g_EmuThread = 0;
#endif
#ifdef SETUP_TIMER_WAITING
#else
Host_UpdateGUI();
StopUpToVideoDone = false;
StopReachedEnd = true;

View File

@ -43,7 +43,8 @@ void CEXIMemoryCard::FlushCallback(u64 userdata, int cyclesLate)
CEXIMemoryCard::CEXIMemoryCard(const std::string& _rName, const std::string& _rFilename, int _card_index) :
m_strFilename(_rFilename),
card_index(_card_index),
flushThread(NULL)
flushThread(NULL),
m_bDirty(false)
{
cards[_card_index] = this;
et_this_card = CoreTiming::RegisterEvent(_rName.c_str(), FlushCallback);
@ -138,6 +139,9 @@ THREAD_RETURN innerFlush(void *pArgs)
// Flush memory card contents to disc
void CEXIMemoryCard::Flush(bool exiting)
{
if(!m_bDirty)
return;
if(flushThread)
{
delete flushThread;
@ -157,6 +161,8 @@ void CEXIMemoryCard::Flush(bool exiting)
flushThread = new Common::Thread(innerFlush, fs);
if(exiting)
flushThread->WaitForDeath();
m_bDirty = false;
}
CEXIMemoryCard::~CEXIMemoryCard()
@ -205,6 +211,7 @@ void CEXIMemoryCard::SetCS(int cs)
status &= ~MC_STATUS_BUSY;
m_bInterruptSet = 1;
m_bDirty = true;
}
break;
@ -213,6 +220,7 @@ void CEXIMemoryCard::SetCS(int cs)
{
memset(memory_card_content, 0xFF, memory_card_size);
status &= ~MC_STATUS_BUSY;
m_bDirty = true;
}
break;
@ -234,6 +242,7 @@ void CEXIMemoryCard::SetCS(int cs)
status &= ~MC_STATUS_BUSY;
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)

View File

@ -79,6 +79,7 @@ private:
u32 m_uPosition;
u8 programming_buffer[128];
u32 formatDelay;
bool m_bDirty;
//! memory card parameters
unsigned int nintendo_card_id, card_id;

View File

@ -75,7 +75,7 @@ namespace HW
{
SystemTimers::Shutdown();
CCPU::Shutdown();
ExpansionInterface::Shutdown();
ExpansionInterface::Shutdown();
DVDInterface::Shutdown();
DSP::Shutdown();
Memory::Shutdown();

View File

@ -31,6 +31,9 @@
#include "minilzo.h"
///////////
// TODO: Investigate a memory leak on save/load state
///////////
#if defined(__LZO_STRICT_16BIT)
#define IN_LEN (8*1024u)
@ -286,8 +289,12 @@ void LoadStateCallback(u64 userdata, int cyclesLate)
fread(out, 1, cur_len, f);
int res = lzo1x_decompress(out, cur_len, (buffer + i), &new_len, NULL);
if(res != LZO_E_OK)
PanicAlert("Internal LZO Error - decompression failed (%d)", res);
if(res != LZO_E_OK) {
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'
i += new_len;

View File

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

View File

@ -25,6 +25,7 @@
#include "wiimote_hid.h"
#include "EmuDefinitions.h"
#include "ChunkFile.h"
namespace WiiMoteEmu
{
@ -35,7 +36,7 @@ void GetMousePos(float& x, float& y);
// General functions
void Initialize();
void DoState(void* ptr, int mode);
void DoState(PointerWrap &p);
void Shutdown(void);
void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size);
void ControlChannel(u16 _channelID, const void* _pData, u32 _Size) ;

View File

@ -266,10 +266,28 @@ void Shutdown(void)
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
WiiMoteReal::DoState(ptr, mode);
WiiMoteReal::DoState(p);
#endif
WiiMoteEmu::DoState(ptr, mode);
WiiMoteEmu::DoState(p);
}

View File

@ -400,7 +400,10 @@ int Initialize()
return g_NumberOfWiiMotes;
}
void DoState(void* ptr, int mode) {}
void DoState(PointerWrap &p)
{
//TODO: Implement
}
void Shutdown(void)
{

View File

@ -24,6 +24,7 @@
// Includes
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
#include "wiiuse.h"
#include "ChunkFile.h"
///////////////////////////////////
@ -33,7 +34,7 @@ namespace WiiMoteReal
#define MAX_WIIMOTES 1
int Initialize();
void DoState(void* ptr, int mode);
void DoState(PointerWrap &p);
void Shutdown(void);
void InterruptChannel(u16 _channelID, const void* _pData, u32 _Size);
void ControlChannel(u16 _channelID, const void* _pData, u32 _Size);