mirror of https://github.com/PCSX2/pcsx2.git
Some bugfixes to suspend/resume and changing plugin options on the fly.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2915 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
df60f016c8
commit
bd76de1a8b
|
@ -400,8 +400,9 @@ SaveSinglePluginHelper::SaveSinglePluginHelper( PluginsEnum_t pid )
|
||||||
|
|
||||||
SaveSinglePluginHelper::~SaveSinglePluginHelper() throw()
|
SaveSinglePluginHelper::~SaveSinglePluginHelper() throw()
|
||||||
{
|
{
|
||||||
try
|
bool allowResume = true;
|
||||||
{
|
|
||||||
|
try {
|
||||||
if( m_validstate )
|
if( m_validstate )
|
||||||
{
|
{
|
||||||
Console.WriteLn( Color_Green, L"Recovering single plugin: " + tbl_PluginInfo[m_pid].GetShortname() );
|
Console.WriteLn( Color_Green, L"Recovering single plugin: " + tbl_PluginInfo[m_pid].GetShortname() );
|
||||||
|
@ -413,7 +414,19 @@ SaveSinglePluginHelper::~SaveSinglePluginHelper() throw()
|
||||||
|
|
||||||
s_DisableGsWindow = false;
|
s_DisableGsWindow = false;
|
||||||
}
|
}
|
||||||
DESTRUCTOR_CATCHALL;
|
catch( BaseException& ex )
|
||||||
|
{
|
||||||
|
allowResume = false;
|
||||||
|
Console.Error( "Unhandled BaseException in %s (ignored!):", __pxFUNCTION__ );
|
||||||
|
Console.Error( ex.FormatDiagnosticMessage() );
|
||||||
|
}
|
||||||
|
catch( std::exception& ex )
|
||||||
|
{
|
||||||
|
allowResume = false;
|
||||||
|
Console.Error( "Unhandled std::exception in %s (ignored!):", __pxFUNCTION__ );
|
||||||
|
Console.Error( ex.what() );
|
||||||
|
}
|
||||||
|
|
||||||
s_DisableGsWindow = false;
|
s_DisableGsWindow = false;
|
||||||
|
if( allowResume ) m_scoped_pause.AllowResume();
|
||||||
}
|
}
|
||||||
|
|
|
@ -275,14 +275,62 @@ enum
|
||||||
};
|
};
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// SysExecEvent_FullStop
|
// BaseSysExecEvent_ScopedCore
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
class SysExecEvent_FullStop : public SysExecEvent
|
class BaseSysExecEvent_ScopedCore : public SysExecEvent
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
SynchronousActionState* m_resume;
|
SynchronousActionState* m_resume;
|
||||||
Threading::Mutex* m_mtx_resume;
|
Threading::Mutex* m_mtx_resume;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~BaseSysExecEvent_ScopedCore() throw() {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BaseSysExecEvent_ScopedCore( SynchronousActionState* sync=NULL, SynchronousActionState* resume_sync=NULL, Threading::Mutex* mtx_resume=NULL )
|
||||||
|
: SysExecEvent( sync )
|
||||||
|
{
|
||||||
|
m_resume = resume_sync;
|
||||||
|
m_mtx_resume = mtx_resume;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _post_and_wait( IScopedCoreThread& core )
|
||||||
|
{
|
||||||
|
PostResult();
|
||||||
|
|
||||||
|
if( m_resume )
|
||||||
|
{
|
||||||
|
ScopedLock lock( m_mtx_resume );
|
||||||
|
|
||||||
|
// If the sender of the message requests a non-blocking resume, then we need
|
||||||
|
// to deallocate the m_sync object, since the sender will likely leave scope and
|
||||||
|
// invalidate it.
|
||||||
|
switch( m_resume->WaitForResult() )
|
||||||
|
{
|
||||||
|
case FullStop_BlockingResume:
|
||||||
|
if( m_sync ) m_sync->ClearResult();
|
||||||
|
core.AllowResume();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FullStop_NonblockingResume:
|
||||||
|
m_sync = NULL;
|
||||||
|
core.AllowResume();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FullStop_SkipResume:
|
||||||
|
m_sync = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
// SysExecEvent_FullStop
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
class SysExecEvent_FullStop : public BaseSysExecEvent_ScopedCore
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~SysExecEvent_FullStop() throw() {}
|
virtual ~SysExecEvent_FullStop() throw() {}
|
||||||
SysExecEvent_FullStop* Clone() const
|
SysExecEvent_FullStop* Clone() const
|
||||||
|
@ -291,46 +339,16 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
SysExecEvent_FullStop( SynchronousActionState* sync=NULL, SynchronousActionState* resume_sync=NULL, Threading::Mutex* mtx_resume=NULL )
|
SysExecEvent_FullStop( SynchronousActionState* sync=NULL, SynchronousActionState* resume_sync=NULL, Threading::Mutex* mtx_resume=NULL )
|
||||||
: SysExecEvent( sync )
|
: BaseSysExecEvent_ScopedCore( sync, resume_sync, mtx_resume ) { }
|
||||||
{
|
|
||||||
m_resume = resume_sync;
|
|
||||||
m_mtx_resume = mtx_resume;
|
|
||||||
}
|
|
||||||
|
|
||||||
SysExecEvent_FullStop( SynchronousActionState& sync, SynchronousActionState& resume_sync, Threading::Mutex& mtx_resume )
|
SysExecEvent_FullStop( SynchronousActionState& sync, SynchronousActionState& resume_sync, Threading::Mutex& mtx_resume )
|
||||||
: SysExecEvent( sync )
|
: BaseSysExecEvent_ScopedCore( &sync, &resume_sync, &mtx_resume ) { }
|
||||||
{
|
|
||||||
m_resume = &resume_sync;
|
|
||||||
m_mtx_resume = &mtx_resume;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void _DoInvoke()
|
void _DoInvoke()
|
||||||
{
|
{
|
||||||
ScopedCoreThreadClose closed_core;
|
ScopedCoreThreadClose closed_core;
|
||||||
PostResult();
|
_post_and_wait(closed_core);
|
||||||
|
|
||||||
if( m_resume )
|
|
||||||
{
|
|
||||||
ScopedLock lock( m_mtx_resume );
|
|
||||||
|
|
||||||
// If the sender of the message requests a non-blocking resume, then we need
|
|
||||||
// to deallocate the m_sync object, since the sender will likely leave scope and
|
|
||||||
// invalidate it.
|
|
||||||
switch( m_resume->WaitForResult() )
|
|
||||||
{
|
|
||||||
case FullStop_SkipResume: return;
|
|
||||||
|
|
||||||
case FullStop_BlockingResume:
|
|
||||||
if( m_sync ) m_sync->ClearResult();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FullStop_NonblockingResume:
|
|
||||||
m_sync = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
closed_core.AllowResume();
|
closed_core.AllowResume();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -338,12 +356,8 @@ protected:
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// SysExecEvent_FullStop
|
// SysExecEvent_FullStop
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
class SysExecEvent_Pause : public SysExecEvent
|
class SysExecEvent_Pause : public BaseSysExecEvent_ScopedCore
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
SynchronousActionState* m_resume;
|
|
||||||
Threading::Mutex* m_mtx_resume;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~SysExecEvent_Pause() throw() {}
|
virtual ~SysExecEvent_Pause() throw() {}
|
||||||
SysExecEvent_Pause* Clone() const
|
SysExecEvent_Pause* Clone() const
|
||||||
|
@ -352,46 +366,16 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
SysExecEvent_Pause( SynchronousActionState* sync=NULL, SynchronousActionState* resume_sync=NULL, Threading::Mutex* mtx_resume=NULL )
|
SysExecEvent_Pause( SynchronousActionState* sync=NULL, SynchronousActionState* resume_sync=NULL, Threading::Mutex* mtx_resume=NULL )
|
||||||
: SysExecEvent( sync )
|
: BaseSysExecEvent_ScopedCore( sync, resume_sync, mtx_resume ) { }
|
||||||
{
|
|
||||||
m_resume = resume_sync;
|
|
||||||
m_mtx_resume = mtx_resume;
|
|
||||||
}
|
|
||||||
|
|
||||||
SysExecEvent_Pause( SynchronousActionState& sync, SynchronousActionState& resume_sync, Threading::Mutex& mtx_resume )
|
SysExecEvent_Pause( SynchronousActionState& sync, SynchronousActionState& resume_sync, Threading::Mutex& mtx_resume )
|
||||||
: SysExecEvent( sync )
|
: BaseSysExecEvent_ScopedCore( &sync, &resume_sync, &mtx_resume ) { }
|
||||||
{
|
|
||||||
m_resume = &resume_sync;
|
|
||||||
m_mtx_resume = &mtx_resume;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void _DoInvoke()
|
void _DoInvoke()
|
||||||
{
|
{
|
||||||
ScopedCoreThreadPause paused_core;
|
ScopedCoreThreadPause paused_core;
|
||||||
PostResult();
|
_post_and_wait(paused_core);
|
||||||
|
|
||||||
if( m_resume )
|
|
||||||
{
|
|
||||||
ScopedLock lock( m_mtx_resume );
|
|
||||||
|
|
||||||
// If the sender of the message requests a non-blocking resume, then we need
|
|
||||||
// to deallocate the m_sync object, since the sender will likely leave scope and
|
|
||||||
// invalidate it.
|
|
||||||
switch( m_resume->WaitForResult() )
|
|
||||||
{
|
|
||||||
case FullStop_SkipResume: return;
|
|
||||||
|
|
||||||
case FullStop_BlockingResume:
|
|
||||||
if( m_sync ) m_sync->ClearResult();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FullStop_NonblockingResume:
|
|
||||||
m_sync = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
paused_core.AllowResume();
|
paused_core.AllowResume();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -143,6 +143,7 @@ public:
|
||||||
bool IsPaused() const { return GetMenuBar()->IsChecked( MenuId_Sys_SuspendResume ); }
|
bool IsPaused() const { return GetMenuBar()->IsChecked( MenuId_Sys_SuspendResume ); }
|
||||||
void UpdateIsoSrcSelection();
|
void UpdateIsoSrcSelection();
|
||||||
void RemoveCdvdMenu();
|
void RemoveCdvdMenu();
|
||||||
|
void EnableMenuItem( int id, bool enable );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void ApplySettings();
|
void ApplySettings();
|
||||||
|
|
|
@ -448,7 +448,7 @@ void MainEmuFrame::Menu_SuspendResume_Click(wxCommandEvent &event)
|
||||||
// has responded (it updates status after the plugins are loaded and emulation has
|
// has responded (it updates status after the plugins are loaded and emulation has
|
||||||
// engaged successfully).
|
// engaged successfully).
|
||||||
|
|
||||||
GetMenuBar()->Enable( MenuId_Sys_SuspendResume, false );
|
EnableMenuItem( MenuId_Sys_SuspendResume, false );
|
||||||
GetSysExecutorThread().PostEvent( new SysExecEvent_ToggleSuspend() );
|
GetSysExecutorThread().PostEvent( new SysExecEvent_ToggleSuspend() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,11 +17,19 @@
|
||||||
#include "Mainframe.h"
|
#include "Mainframe.h"
|
||||||
#include "GSFrame.h"
|
#include "GSFrame.h"
|
||||||
|
|
||||||
|
// This is necessary because this stupid wxWdigets thing has implicit debug errors
|
||||||
|
// in the FindItem call that asserts if the menu options are missing. This is bad
|
||||||
|
// mojo for configurable/dynamic menus. >_<
|
||||||
|
void MainEmuFrame::EnableMenuItem( int id, bool enable )
|
||||||
|
{
|
||||||
|
if( wxMenuItem* item = m_menubar.FindItem(id) )
|
||||||
|
item->Enable( enable );
|
||||||
|
}
|
||||||
|
|
||||||
static void _SaveLoadStuff( bool enabled )
|
static void _SaveLoadStuff( bool enabled )
|
||||||
{
|
{
|
||||||
sMainFrame.GetMenuBar()->Enable( MenuId_Sys_LoadStates, enabled );
|
sMainFrame.EnableMenuItem( MenuId_Sys_LoadStates, enabled );
|
||||||
sMainFrame.GetMenuBar()->Enable( MenuId_Sys_SaveStates, enabled );
|
sMainFrame.EnableMenuItem( MenuId_Sys_SaveStates, enabled );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updates the enable/disable status of all System related controls: menus, toolbars,
|
// Updates the enable/disable status of all System related controls: menus, toolbars,
|
||||||
|
@ -35,11 +43,10 @@ void UI_UpdateSysControls()
|
||||||
_SaveLoadStuff( true );
|
_SaveLoadStuff( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void UI_DisableSysReset()
|
void UI_DisableSysReset()
|
||||||
{
|
{
|
||||||
if( wxGetApp().PostMethodMyself( UI_DisableSysReset ) ) return;
|
if( wxGetApp().PostMethodMyself( UI_DisableSysReset ) ) return;
|
||||||
sMainFrame.GetMenuBar()->Enable( MenuId_Sys_Restart, false );
|
sMainFrame.EnableMenuItem( MenuId_Sys_Restart, false );
|
||||||
|
|
||||||
_SaveLoadStuff( false );
|
_SaveLoadStuff( false );
|
||||||
}
|
}
|
||||||
|
@ -48,16 +55,16 @@ void UI_DisableSysShutdown()
|
||||||
{
|
{
|
||||||
if( wxGetApp().PostMethodMyself( &UI_DisableSysShutdown ) ) return;
|
if( wxGetApp().PostMethodMyself( &UI_DisableSysShutdown ) ) return;
|
||||||
|
|
||||||
sMainFrame.GetMenuBar()->Enable( MenuId_Sys_Restart, false );
|
sMainFrame.EnableMenuItem( MenuId_Sys_Restart, false );
|
||||||
sMainFrame.GetMenuBar()->Enable( MenuId_Sys_Shutdown, false );
|
sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
void UI_EnableSysShutdown()
|
void UI_EnableSysShutdown()
|
||||||
{
|
{
|
||||||
if( wxGetApp().PostMethodMyself( &UI_EnableSysShutdown ) ) return;
|
if( wxGetApp().PostMethodMyself( &UI_EnableSysShutdown ) ) return;
|
||||||
|
|
||||||
sMainFrame.GetMenuBar()->Enable( MenuId_Sys_Restart, true );
|
sMainFrame.EnableMenuItem( MenuId_Sys_Restart, true );
|
||||||
sMainFrame.GetMenuBar()->Enable( MenuId_Sys_Shutdown, true );
|
sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,16 +72,16 @@ void UI_DisableSysActions()
|
||||||
{
|
{
|
||||||
if( wxGetApp().PostMethodMyself( &UI_DisableSysShutdown ) ) return;
|
if( wxGetApp().PostMethodMyself( &UI_DisableSysShutdown ) ) return;
|
||||||
|
|
||||||
sMainFrame.GetMenuBar()->Enable( MenuId_Sys_Restart, false );
|
sMainFrame.EnableMenuItem( MenuId_Sys_Restart, false );
|
||||||
sMainFrame.GetMenuBar()->Enable( MenuId_Sys_Shutdown, false );
|
sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
void UI_EnableSysActions()
|
void UI_EnableSysActions()
|
||||||
{
|
{
|
||||||
if( wxGetApp().PostMethodMyself( &UI_EnableSysShutdown ) ) return;
|
if( wxGetApp().PostMethodMyself( &UI_EnableSysShutdown ) ) return;
|
||||||
|
|
||||||
sMainFrame.GetMenuBar()->Enable( MenuId_Sys_Restart, true );
|
sMainFrame.EnableMenuItem( MenuId_Sys_Restart, true );
|
||||||
sMainFrame.GetMenuBar()->Enable( MenuId_Sys_Shutdown, true );
|
sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue