From 06b65ea4258d1ee31d43f8c9e4bd4647c483954c Mon Sep 17 00:00:00 2001 From: "XTra.KrazzY" Date: Fri, 3 Jul 2009 12:22:32 +0000 Subject: [PATCH] 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 --- Source/Core/Core/Src/Core.cpp | 11 +++---- .../Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp | 11 ++++++- .../Core/Core/Src/HW/EXI_DeviceMemoryCard.h | 1 + Source/Core/Core/Src/HW/HW.cpp | 2 +- Source/Core/Core/Src/State.cpp | 11 +++++-- Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp | 32 +++++++++++++++++-- Source/Plugins/Plugin_Wiimote/Src/EmuMain.h | 3 +- Source/Plugins/Plugin_Wiimote/Src/main.cpp | 22 +++++++++++-- .../Plugin_Wiimote/Src/wiimote_real.cpp | 5 ++- .../Plugins/Plugin_Wiimote/Src/wiimote_real.h | 3 +- 10 files changed, 83 insertions(+), 18 deletions(-) diff --git a/Source/Core/Core/Src/Core.cpp b/Source/Core/Core/Src/Core.cpp index ba251211bb..f452eb6da7 100644 --- a/Source/Core/Core/Src/Core.cpp +++ b/Source/Core/Core/Src/Core.cpp @@ -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; diff --git a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp index 6bfe923f30..cc31986c9f 100644 --- a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp +++ b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.cpp @@ -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) diff --git a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.h b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.h index 42f8f5e9b0..1e450b5fea 100644 --- a/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.h +++ b/Source/Core/Core/Src/HW/EXI_DeviceMemoryCard.h @@ -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; diff --git a/Source/Core/Core/Src/HW/HW.cpp b/Source/Core/Core/Src/HW/HW.cpp index 1741ceb4fa..027b1459b9 100644 --- a/Source/Core/Core/Src/HW/HW.cpp +++ b/Source/Core/Core/Src/HW/HW.cpp @@ -75,7 +75,7 @@ namespace HW { SystemTimers::Shutdown(); CCPU::Shutdown(); - ExpansionInterface::Shutdown(); + ExpansionInterface::Shutdown(); DVDInterface::Shutdown(); DSP::Shutdown(); Memory::Shutdown(); diff --git a/Source/Core/Core/Src/State.cpp b/Source/Core/Core/Src/State.cpp index 920fa20fd8..b8cdde2755 100644 --- a/Source/Core/Core/Src/State.cpp +++ b/Source/Core/Core/Src/State.cpp @@ -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; diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp index 229e26a618..2209d853b9 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.cpp @@ -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 diff --git a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.h b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.h index ca5fea28c0..b2a96ae109 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/EmuMain.h +++ b/Source/Plugins/Plugin_Wiimote/Src/EmuMain.h @@ -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) ; diff --git a/Source/Plugins/Plugin_Wiimote/Src/main.cpp b/Source/Plugins/Plugin_Wiimote/Src/main.cpp index b8282bc500..b0cc4703ab 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/main.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/main.cpp @@ -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); } diff --git a/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.cpp b/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.cpp index dc59ae7ac2..808c7c07bc 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.cpp @@ -400,7 +400,10 @@ int Initialize() return g_NumberOfWiiMotes; } -void DoState(void* ptr, int mode) {} +void DoState(PointerWrap &p) +{ + //TODO: Implement +} void Shutdown(void) { diff --git a/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.h b/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.h index 109711b895..6cb76bd29c 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.h +++ b/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.h @@ -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);