1. TAS Groundwork: Saving the state (compression and memory dump to file) is now done on a separate thread (thread-safe). Now state saving is silent and quick.
2. When stopping, GUI doesn't let the user choose another game and effectively crash Dolphin 3. Omitted an unneeded loop in AudioCommon git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3552 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
8a6fcdc2bc
commit
46b0fd3c96
|
@ -70,13 +70,6 @@ namespace AudioCommon
|
|||
delete soundStream;
|
||||
soundStream = NULL;
|
||||
}
|
||||
|
||||
// Check that soundstream already is stopped.
|
||||
while (soundStream)
|
||||
{
|
||||
ERROR_LOG(DSPHLE, "Waiting for sound stream");
|
||||
Common::SleepCurrentThread(2000);
|
||||
}
|
||||
|
||||
INFO_LOG(DSPHLE, "Done shutting down sound stream");
|
||||
}
|
||||
|
|
|
@ -184,7 +184,10 @@ void ReconnectWiimote()
|
|||
#endif
|
||||
|
||||
|
||||
|
||||
bool isRunning()
|
||||
{
|
||||
return (GetState() != CORE_UNINITIALIZED) || g_bHwInit;
|
||||
}
|
||||
|
||||
|
||||
// This is called from the GUI thread. See the booting call schedule in BootManager.cpp
|
||||
|
@ -563,25 +566,23 @@ void EmuThreadEnd()
|
|||
}
|
||||
#endif
|
||||
|
||||
// The hardware is uninitialized
|
||||
g_bHwInit = false;
|
||||
|
||||
HW::Shutdown();
|
||||
Plugins.ShutdownPlugins();
|
||||
|
||||
// The hardware is uninitialized
|
||||
g_bHwInit = false;
|
||||
|
||||
INFO_LOG(MASTER_LOG, "EmuThread exited");
|
||||
// The CPU should return when a game is stopped and cleanup should be done here,
|
||||
// so we can restart the plugins (or load new ones) for the next game.
|
||||
if (_CoreParameter.hMainWindow == g_pWindowHandle)
|
||||
Host_UpdateMainFrame();
|
||||
|
||||
Host_UpdateMainFrame();
|
||||
|
||||
#ifdef SETUP_TIMER_WAITING
|
||||
EmuThreadReachedEnd = true;
|
||||
Host_UpdateGUI();
|
||||
INFO_LOG(CONSOLE, "Stop [Video Thread]: Done\n");
|
||||
delete g_EmuThread; // Wait for emuthread to close.
|
||||
g_EmuThread = 0;
|
||||
#endif
|
||||
#ifndef SETUP_TIMER_WAITING
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -43,6 +43,8 @@ namespace Core
|
|||
// Init core
|
||||
bool Init();
|
||||
void Stop();
|
||||
|
||||
bool isRunning();
|
||||
|
||||
void SetState(EState _State);
|
||||
EState GetState();
|
||||
|
|
|
@ -78,26 +78,21 @@ void DoState(PointerWrap &p)
|
|||
CoreTiming::DoState(p);
|
||||
}
|
||||
|
||||
void SaveStateCallback(u64 userdata, int cyclesLate)
|
||||
THREAD_RETURN CompressAndDumpState(void *pArgs)
|
||||
{
|
||||
saveStruct *saveArg = (saveStruct *)pArgs;
|
||||
u8 *buffer = saveArg->buffer;
|
||||
size_t sz = saveArg->size;
|
||||
lzo_uint out_len = 0;
|
||||
|
||||
delete saveArg;
|
||||
|
||||
FILE *f = fopen(cur_filename.c_str(), "wb");
|
||||
if(f == NULL) {
|
||||
Core::DisplayMessage("Could not save state", 2000);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
jit.ClearCache();
|
||||
u8 *ptr = 0;
|
||||
PointerWrap p(&ptr, PointerWrap::MODE_MEASURE);
|
||||
DoState(p);
|
||||
size_t sz = (size_t)ptr;
|
||||
u8 *buffer = new u8[sz];
|
||||
ptr = buffer;
|
||||
p.SetMode(PointerWrap::MODE_WRITE);
|
||||
DoState(p);
|
||||
|
||||
if (bCompressed) {
|
||||
fwrite(&sz, sizeof(int), 1, f);
|
||||
} else {
|
||||
|
@ -139,7 +134,39 @@ void SaveStateCallback(u64 userdata, int cyclesLate)
|
|||
delete [] buffer;
|
||||
|
||||
Core::DisplayMessage(StringFromFormat("Saved State to %s",
|
||||
cur_filename.c_str()).c_str(), 2000);
|
||||
cur_filename.c_str()).c_str(), 2000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Common::Thread *saveThread = NULL;
|
||||
|
||||
void SaveStateCallback(u64 userdata, int cyclesLate)
|
||||
{
|
||||
// If already saving state, wait for it to finish
|
||||
if(saveThread)
|
||||
{
|
||||
delete saveThread;
|
||||
saveThread = NULL;
|
||||
}
|
||||
|
||||
jit.ClearCache();
|
||||
u8 *ptr = 0;
|
||||
PointerWrap p(&ptr, PointerWrap::MODE_MEASURE);
|
||||
DoState(p);
|
||||
size_t sz = (size_t)ptr;
|
||||
u8 *buffer = new u8[sz];
|
||||
ptr = buffer;
|
||||
p.SetMode(PointerWrap::MODE_WRITE);
|
||||
DoState(p);
|
||||
|
||||
saveStruct *saveData = new saveStruct;
|
||||
saveData->buffer = buffer;
|
||||
saveData->size = sz;
|
||||
|
||||
Core::DisplayMessage("Saving State...", 1000);
|
||||
|
||||
saveThread = new Common::Thread(CompressAndDumpState, saveData);
|
||||
}
|
||||
|
||||
void LoadStateCallback(u64 userdata, int cyclesLate)
|
||||
|
@ -214,7 +241,11 @@ void State_Init()
|
|||
|
||||
void State_Shutdown()
|
||||
{
|
||||
// nothing to do, here for consistency.
|
||||
if(saveThread)
|
||||
{
|
||||
delete saveThread;
|
||||
saveThread = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
std::string MakeStateFilename(int state_number)
|
||||
|
|
|
@ -28,4 +28,10 @@ void State_Shutdown();
|
|||
void State_Save(int slot);
|
||||
void State_Load(int slot);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 *buffer;
|
||||
size_t size;
|
||||
} saveStruct;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -584,19 +584,13 @@ void CFrame::DoStop()
|
|||
|
||||
Core::Stop();
|
||||
|
||||
/*
|
||||
This is needed together with the option to not "delete g_EmuThread" in Core.cpp, because then
|
||||
we have to wait a moment before GetState() == CORE_UNINITIALIZED so that UpdateGUI() works.
|
||||
It's also needed when a WaitForSingleObject() has timed out so that the ShutDown() process
|
||||
has continued without all threads having come to a rest. It's not compatible with the
|
||||
SETUP_TIMER_WAITING option (because the Stop returns before it's finished).
|
||||
|
||||
Without this we just see the gray CPanel background because the ISO list will not be displayed.
|
||||
*/
|
||||
#ifndef SETUP_TIMER_WAITING
|
||||
if (bRenderToMain)
|
||||
while(Core::GetState() != Core::CORE_UNINITIALIZED) SLEEP(10);
|
||||
#endif
|
||||
#ifdef SETUP_TIMER_WAITING
|
||||
// Idle-wait for core to completely shut down (without this wait the
|
||||
// GameCtrlPanel is restored to a state where we can open another game
|
||||
// and effectively crash Dolphin)
|
||||
while(Core::isRunning())
|
||||
SLEEP(10);
|
||||
#endif
|
||||
|
||||
UpdateGUI();
|
||||
}
|
||||
|
@ -828,7 +822,7 @@ void CFrame::UpdateGUI()
|
|||
#endif
|
||||
|
||||
// Save status
|
||||
bool initialized = Core::GetState() != Core::CORE_UNINITIALIZED;
|
||||
bool initialized = Core::isRunning();
|
||||
bool running = Core::GetState() == Core::CORE_RUN;
|
||||
bool paused = Core::GetState() == Core::CORE_PAUSE;
|
||||
|
||||
|
|
Loading…
Reference in New Issue