diff --git a/pcsx2/gui/AppCorePlugins.h b/pcsx2/gui/AppCorePlugins.h
index c9ef5711df..56f9c80d9f 100644
--- a/pcsx2/gui/AppCorePlugins.h
+++ b/pcsx2/gui/AppCorePlugins.h
@@ -1,52 +1,52 @@
-/* PCSX2 - PS2 Emulator for PCs
- * Copyright (C) 2002-2010 PCSX2 Dev Team
- *
- * PCSX2 is free software: you can redistribute it and/or modify it under the terms
- * of the GNU Lesser General Public License as published by the Free Software Found-
- * ation, either version 3 of the License, or (at your option) any later version.
- *
- * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with PCSX2.
- * If not, see .
- */
-
-#pragma once
-
-#include "AppCommon.h"
-
-// --------------------------------------------------------------------------------------
-// AppPluginManager
-// --------------------------------------------------------------------------------------
-// This extension of PluginManager provides event listener sources for plugins -- loading,
-// unloading, open, close, shutdown, etc.
-//
-// FIXME : Should this be made part of the PCSX2 core emulation? (integrated into PluginManager)
-// I'm undecided on if it makes sense more in that context or in this one (interface).
-//
-class AppPluginManager : public PluginManager
-{
- typedef PluginManager _parent;
-
-public:
- AppPluginManager();
- virtual ~AppPluginManager() throw();
-
- void Load( const wxString (&folders)[PluginId_Count] );
- void Load( PluginsEnum_t pid, const wxString& srcfile );
- void Unload( PluginsEnum_t pid );
- void Unload();
-
- void Init();
- void Init( PluginsEnum_t pid );
- void Shutdown( PluginsEnum_t pid );
- void Shutdown();
- void Close();
- void Open();
-
-protected:
- bool OpenPlugin_GS();
- void ClosePlugin_GS();
-};
+/* PCSX2 - PS2 Emulator for PCs
+ * Copyright (C) 2002-2010 PCSX2 Dev Team
+ *
+ * PCSX2 is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU Lesser General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with PCSX2.
+ * If not, see .
+ */
+
+#pragma once
+
+#include "AppCommon.h"
+
+// --------------------------------------------------------------------------------------
+// AppPluginManager
+// --------------------------------------------------------------------------------------
+// This extension of PluginManager provides event listener sources for plugins -- loading,
+// unloading, open, close, shutdown, etc.
+//
+// FIXME : Should this be made part of the PCSX2 core emulation? (integrated into PluginManager)
+// I'm undecided on if it makes sense more in that context or in this one (interface).
+//
+class AppPluginManager : public PluginManager
+{
+ typedef PluginManager _parent;
+
+public:
+ AppPluginManager();
+ virtual ~AppPluginManager() throw();
+
+ void Load( const wxString (&folders)[PluginId_Count] );
+ void Load( PluginsEnum_t pid, const wxString& srcfile );
+ void Unload( PluginsEnum_t pid );
+ void Unload();
+
+ void Init();
+ void Init( PluginsEnum_t pid );
+ void Shutdown( PluginsEnum_t pid );
+ void Shutdown();
+ void Close();
+ void Open();
+
+protected:
+ bool OpenPlugin_GS();
+ void ClosePlugin_GS();
+};
diff --git a/pcsx2/gui/AppCoreThread.h b/pcsx2/gui/AppCoreThread.h
index 22fe1cdc0c..b9bfe7a231 100644
--- a/pcsx2/gui/AppCoreThread.h
+++ b/pcsx2/gui/AppCoreThread.h
@@ -1,236 +1,236 @@
-/* PCSX2 - PS2 Emulator for PCs
- * Copyright (C) 2002-2010 PCSX2 Dev Team
- *
- * PCSX2 is free software: you can redistribute it and/or modify it under the terms
- * of the GNU Lesser General Public License as published by the Free Software Found-
- * ation, either version 3 of the License, or (at your option) any later version.
- *
- * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with PCSX2.
- * If not, see .
- */
-
-#pragma once
-
-#include "System/SysThreads.h"
-#include "AppCommon.h"
-#include "AppCorePlugins.h"
-#include "SaveState.h"
-
-#define AffinityAssert_AllowFrom_CoreThread() \
- pxAssertMsg( GetCoreThread().IsSelf(), "Thread affinity violation: Call allowed from SysCoreThread only." )
-
-#define AffinityAssert_DisallowFrom_CoreThread() \
- pxAssertMsg( !GetCoreThread().IsSelf(), "Thread affinity violation: Call is *not* allowed from SysCoreThread." )
-
-class IScopedCoreThread;
-class BaseScopedCoreThread;
-
-enum ScopedCoreResumeType
-{
- ScopedCore_BlockingResume
-, ScopedCore_NonblockingResume
-, ScopedCore_SkipResume
-};
-
-
-// --------------------------------------------------------------------------------------
-// BaseSysExecEvent_ScopedCore
-// --------------------------------------------------------------------------------------
-class BaseSysExecEvent_ScopedCore : public SysExecEvent
-{
-protected:
- SynchronousActionState* m_resume;
- Threading::Mutex* m_mtx_resume;
-
-public:
- virtual ~BaseSysExecEvent_ScopedCore() throw() {}
-
- BaseSysExecEvent_ScopedCore& SetResumeStates( SynchronousActionState* sync, Threading::Mutex* mutex )
- {
- m_resume = sync;
- m_mtx_resume = mutex;
- return *this;
- }
-
- BaseSysExecEvent_ScopedCore& SetResumeStates( SynchronousActionState& sync, Threading::Mutex& mutex )
- {
- m_resume = &sync;
- m_mtx_resume = &mutex;
- return *this;
- }
-
-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 );
-
- virtual void DoScopedTask() {}
-};
-
-
-// --------------------------------------------------------------------------------------
-// SysExecEvent_CoreThreadClose
-// --------------------------------------------------------------------------------------
-class SysExecEvent_CoreThreadClose : public BaseSysExecEvent_ScopedCore
-{
-public:
- wxString GetEventName() const { return L"CloseCoreThread"; }
-
- virtual ~SysExecEvent_CoreThreadClose() throw() {}
- SysExecEvent_CoreThreadClose* Clone() const { return new SysExecEvent_CoreThreadClose( *this ); }
-
- SysExecEvent_CoreThreadClose( SynchronousActionState* sync=NULL, SynchronousActionState* resume_sync=NULL, Threading::Mutex* mtx_resume=NULL )
- : BaseSysExecEvent_ScopedCore( sync, resume_sync, mtx_resume ) { }
-
-protected:
- void InvokeEvent();
-};
-
-// --------------------------------------------------------------------------------------
-// SysExecEvent_CoreThreadPause
-// --------------------------------------------------------------------------------------
-class SysExecEvent_CoreThreadPause : public BaseSysExecEvent_ScopedCore
-{
-public:
- wxString GetEventName() const { return L"PauseCoreThread"; }
-
- virtual ~SysExecEvent_CoreThreadPause() throw() {}
- SysExecEvent_CoreThreadPause* Clone() const { return new SysExecEvent_CoreThreadPause( *this ); }
-
- SysExecEvent_CoreThreadPause( SynchronousActionState* sync=NULL, SynchronousActionState* resume_sync=NULL, Threading::Mutex* mtx_resume=NULL )
- : BaseSysExecEvent_ScopedCore( sync, resume_sync, mtx_resume ) { }
-
-protected:
- void InvokeEvent();
-};
-
-// --------------------------------------------------------------------------------------
-// AppCoreThread class
-// --------------------------------------------------------------------------------------
-class AppCoreThread : public SysCoreThread
-{
- typedef SysCoreThread _parent;
-
-public:
- AppCoreThread();
- virtual ~AppCoreThread() throw();
-
- virtual void Suspend( bool isBlocking=false );
- virtual void Resume();
- virtual void Shutdown();
- virtual void Cancel( bool isBlocking=true );
- virtual void StateCheckInThread();
- virtual void ChangeCdvdSource();
-
- virtual void ApplySettings( const Pcsx2Config& src );
- virtual void UploadStateCopy( const VmStateBuffer& copy );
-
-protected:
- virtual void OnResumeReady();
- virtual void OnResumeInThread( bool IsSuspended );
- virtual void OnSuspendInThread();
- virtual void OnCleanupInThread();
- virtual void PostVsyncToUI();
- virtual void ExecuteTaskInThread();
- virtual void DoCpuReset();
-};
-
-// --------------------------------------------------------------------------------------
-// IScopedCoreThread / BaseScopedCoreThread
-// --------------------------------------------------------------------------------------
-class IScopedCoreThread
-{
-protected:
- IScopedCoreThread() {}
-
-public:
- virtual ~IScopedCoreThread() throw() {};
- virtual void AllowResume()=0;
- virtual void DisallowResume()=0;
-};
-
-class BaseScopedCoreThread : public IScopedCoreThread
-{
- DeclareNoncopyableObject( BaseScopedCoreThread );
-
-protected:
- bool m_allowResume;
- bool m_alreadyStopped;
- bool m_alreadyScoped;
- SynchronousActionState m_sync;
- SynchronousActionState m_sync_resume;
- Threading::Mutex m_mtx_resume;
-
- BaseScopedCoreThread();
-
-public:
- virtual ~BaseScopedCoreThread() throw()=0;
- virtual void AllowResume();
- virtual void DisallowResume();
-
- virtual bool PostToSysExec( BaseSysExecEvent_ScopedCore* msg );
-
-protected:
- // Called from destructors -- do not make virtual!!
- void DoResume();
-};
-
-// --------------------------------------------------------------------------------------
-// ScopedCoreThreadClose / ScopedCoreThreadPause / ScopedCoreThreadPopup
-// --------------------------------------------------------------------------------------
-// This class behaves a bit differently from other scoped classes due to the "standard"
-// assumption that we actually do *not* want to resume CoreThread operations when an
-// exception occurs. Because of this, the destructor of this class does *not* unroll the
-// suspend operation. Instead you must manually instruct the class to resume using a call
-// to the provisioned AllowResume() method.
-//
-// If the class leaves scope without having been resumed, a log is written to the console.
-// This can be useful for troubleshooting, and also allows the log a second line of info
-// indicating the status of CoreThread execution at the time of the exception.
-//
-// ScopedCoreThreadPopup is intended for use where message boxes are popped up to the user.
-// The old style GUI (without GSopen2) must use a full close of the CoreThread, in order to
-// ensure that the GS window isn't blocking the popup, and to avoid crashes if the GS window
-// is maximized or fullscreen.
-//
-class ScopedCoreThreadClose : public BaseScopedCoreThread
-{
- typedef BaseScopedCoreThread _parent;
-
-public:
- ScopedCoreThreadClose();
- virtual ~ScopedCoreThreadClose() throw();
-
- void LoadPlugins();
-};
-
-struct ScopedCoreThreadPause : public BaseScopedCoreThread
-{
- typedef BaseScopedCoreThread _parent;
-
-public:
- ScopedCoreThreadPause( BaseSysExecEvent_ScopedCore* abuse_me=NULL );
- virtual ~ScopedCoreThreadPause() throw();
-};
-
-struct ScopedCoreThreadPopup : public IScopedCoreThread
-{
-protected:
- ScopedPtr m_scoped_core;
-
-public:
- ScopedCoreThreadPopup();
- virtual ~ScopedCoreThreadPopup() throw() {}
-
- virtual void AllowResume();
- virtual void DisallowResume();
-};
+/* PCSX2 - PS2 Emulator for PCs
+ * Copyright (C) 2002-2010 PCSX2 Dev Team
+ *
+ * PCSX2 is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU Lesser General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with PCSX2.
+ * If not, see .
+ */
+
+#pragma once
+
+#include "System/SysThreads.h"
+#include "AppCommon.h"
+#include "AppCorePlugins.h"
+#include "SaveState.h"
+
+#define AffinityAssert_AllowFrom_CoreThread() \
+ pxAssertMsg( GetCoreThread().IsSelf(), "Thread affinity violation: Call allowed from SysCoreThread only." )
+
+#define AffinityAssert_DisallowFrom_CoreThread() \
+ pxAssertMsg( !GetCoreThread().IsSelf(), "Thread affinity violation: Call is *not* allowed from SysCoreThread." )
+
+class IScopedCoreThread;
+class BaseScopedCoreThread;
+
+enum ScopedCoreResumeType
+{
+ ScopedCore_BlockingResume
+, ScopedCore_NonblockingResume
+, ScopedCore_SkipResume
+};
+
+
+// --------------------------------------------------------------------------------------
+// BaseSysExecEvent_ScopedCore
+// --------------------------------------------------------------------------------------
+class BaseSysExecEvent_ScopedCore : public SysExecEvent
+{
+protected:
+ SynchronousActionState* m_resume;
+ Threading::Mutex* m_mtx_resume;
+
+public:
+ virtual ~BaseSysExecEvent_ScopedCore() throw() {}
+
+ BaseSysExecEvent_ScopedCore& SetResumeStates( SynchronousActionState* sync, Threading::Mutex* mutex )
+ {
+ m_resume = sync;
+ m_mtx_resume = mutex;
+ return *this;
+ }
+
+ BaseSysExecEvent_ScopedCore& SetResumeStates( SynchronousActionState& sync, Threading::Mutex& mutex )
+ {
+ m_resume = &sync;
+ m_mtx_resume = &mutex;
+ return *this;
+ }
+
+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 );
+
+ virtual void DoScopedTask() {}
+};
+
+
+// --------------------------------------------------------------------------------------
+// SysExecEvent_CoreThreadClose
+// --------------------------------------------------------------------------------------
+class SysExecEvent_CoreThreadClose : public BaseSysExecEvent_ScopedCore
+{
+public:
+ wxString GetEventName() const { return L"CloseCoreThread"; }
+
+ virtual ~SysExecEvent_CoreThreadClose() throw() {}
+ SysExecEvent_CoreThreadClose* Clone() const { return new SysExecEvent_CoreThreadClose( *this ); }
+
+ SysExecEvent_CoreThreadClose( SynchronousActionState* sync=NULL, SynchronousActionState* resume_sync=NULL, Threading::Mutex* mtx_resume=NULL )
+ : BaseSysExecEvent_ScopedCore( sync, resume_sync, mtx_resume ) { }
+
+protected:
+ void InvokeEvent();
+};
+
+// --------------------------------------------------------------------------------------
+// SysExecEvent_CoreThreadPause
+// --------------------------------------------------------------------------------------
+class SysExecEvent_CoreThreadPause : public BaseSysExecEvent_ScopedCore
+{
+public:
+ wxString GetEventName() const { return L"PauseCoreThread"; }
+
+ virtual ~SysExecEvent_CoreThreadPause() throw() {}
+ SysExecEvent_CoreThreadPause* Clone() const { return new SysExecEvent_CoreThreadPause( *this ); }
+
+ SysExecEvent_CoreThreadPause( SynchronousActionState* sync=NULL, SynchronousActionState* resume_sync=NULL, Threading::Mutex* mtx_resume=NULL )
+ : BaseSysExecEvent_ScopedCore( sync, resume_sync, mtx_resume ) { }
+
+protected:
+ void InvokeEvent();
+};
+
+// --------------------------------------------------------------------------------------
+// AppCoreThread class
+// --------------------------------------------------------------------------------------
+class AppCoreThread : public SysCoreThread
+{
+ typedef SysCoreThread _parent;
+
+public:
+ AppCoreThread();
+ virtual ~AppCoreThread() throw();
+
+ virtual void Suspend( bool isBlocking=false );
+ virtual void Resume();
+ virtual void Shutdown();
+ virtual void Cancel( bool isBlocking=true );
+ virtual void StateCheckInThread();
+ virtual void ChangeCdvdSource();
+
+ virtual void ApplySettings( const Pcsx2Config& src );
+ virtual void UploadStateCopy( const VmStateBuffer& copy );
+
+protected:
+ virtual void OnResumeReady();
+ virtual void OnResumeInThread( bool IsSuspended );
+ virtual void OnSuspendInThread();
+ virtual void OnCleanupInThread();
+ virtual void PostVsyncToUI();
+ virtual void ExecuteTaskInThread();
+ virtual void DoCpuReset();
+};
+
+// --------------------------------------------------------------------------------------
+// IScopedCoreThread / BaseScopedCoreThread
+// --------------------------------------------------------------------------------------
+class IScopedCoreThread
+{
+protected:
+ IScopedCoreThread() {}
+
+public:
+ virtual ~IScopedCoreThread() throw() {};
+ virtual void AllowResume()=0;
+ virtual void DisallowResume()=0;
+};
+
+class BaseScopedCoreThread : public IScopedCoreThread
+{
+ DeclareNoncopyableObject( BaseScopedCoreThread );
+
+protected:
+ bool m_allowResume;
+ bool m_alreadyStopped;
+ bool m_alreadyScoped;
+ SynchronousActionState m_sync;
+ SynchronousActionState m_sync_resume;
+ Threading::Mutex m_mtx_resume;
+
+ BaseScopedCoreThread();
+
+public:
+ virtual ~BaseScopedCoreThread() throw()=0;
+ virtual void AllowResume();
+ virtual void DisallowResume();
+
+ virtual bool PostToSysExec( BaseSysExecEvent_ScopedCore* msg );
+
+protected:
+ // Called from destructors -- do not make virtual!!
+ void DoResume();
+};
+
+// --------------------------------------------------------------------------------------
+// ScopedCoreThreadClose / ScopedCoreThreadPause / ScopedCoreThreadPopup
+// --------------------------------------------------------------------------------------
+// This class behaves a bit differently from other scoped classes due to the "standard"
+// assumption that we actually do *not* want to resume CoreThread operations when an
+// exception occurs. Because of this, the destructor of this class does *not* unroll the
+// suspend operation. Instead you must manually instruct the class to resume using a call
+// to the provisioned AllowResume() method.
+//
+// If the class leaves scope without having been resumed, a log is written to the console.
+// This can be useful for troubleshooting, and also allows the log a second line of info
+// indicating the status of CoreThread execution at the time of the exception.
+//
+// ScopedCoreThreadPopup is intended for use where message boxes are popped up to the user.
+// The old style GUI (without GSopen2) must use a full close of the CoreThread, in order to
+// ensure that the GS window isn't blocking the popup, and to avoid crashes if the GS window
+// is maximized or fullscreen.
+//
+class ScopedCoreThreadClose : public BaseScopedCoreThread
+{
+ typedef BaseScopedCoreThread _parent;
+
+public:
+ ScopedCoreThreadClose();
+ virtual ~ScopedCoreThreadClose() throw();
+
+ void LoadPlugins();
+};
+
+struct ScopedCoreThreadPause : public BaseScopedCoreThread
+{
+ typedef BaseScopedCoreThread _parent;
+
+public:
+ ScopedCoreThreadPause( BaseSysExecEvent_ScopedCore* abuse_me=NULL );
+ virtual ~ScopedCoreThreadPause() throw();
+};
+
+struct ScopedCoreThreadPopup : public IScopedCoreThread
+{
+protected:
+ ScopedPtr m_scoped_core;
+
+public:
+ ScopedCoreThreadPopup();
+ virtual ~ScopedCoreThreadPopup() throw() {}
+
+ virtual void AllowResume();
+ virtual void DisallowResume();
+};
diff --git a/pcsx2/gui/Dialogs/BaseConfigurationDialog.inl b/pcsx2/gui/Dialogs/BaseConfigurationDialog.inl
index 7c695221a2..03a7bb0795 100644
--- a/pcsx2/gui/Dialogs/BaseConfigurationDialog.inl
+++ b/pcsx2/gui/Dialogs/BaseConfigurationDialog.inl
@@ -1,28 +1,28 @@
-/* PCSX2 - PS2 Emulator for PCs
- * Copyright (C) 2002-2010 PCSX2 Dev Team
- *
- * PCSX2 is free software: you can redistribute it and/or modify it under the terms
- * of the GNU Lesser General Public License as published by the Free Software Found-
- * ation, either version 3 of the License, or (at your option) any later version.
- *
- * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with PCSX2.
- * If not, see .
- */
-
-#pragma once
-
-#include
-
-template< typename T >
-void Dialogs::BaseConfigurationDialog::AddPage( const char* label, int iconid )
-{
- const wxString labelstr( fromUTF8( label ) );
- const int curidx = m_labels.Add( labelstr );
- m_ApplyState.SetCurrentPage( curidx );
- m_listbook.AddPage( new T( &m_listbook ), wxGetTranslation( labelstr ),
- ( labelstr == GetConfSettingsTabName() ), iconid );
-}
+/* PCSX2 - PS2 Emulator for PCs
+ * Copyright (C) 2002-2010 PCSX2 Dev Team
+ *
+ * PCSX2 is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU Lesser General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with PCSX2.
+ * If not, see .
+ */
+
+#pragma once
+
+#include
+
+template< typename T >
+void Dialogs::BaseConfigurationDialog::AddPage( const char* label, int iconid )
+{
+ const wxString labelstr( fromUTF8( label ) );
+ const int curidx = m_labels.Add( labelstr );
+ m_ApplyState.SetCurrentPage( curidx );
+ m_listbook.AddPage( new T( &m_listbook ), wxGetTranslation( labelstr ),
+ ( labelstr == GetConfSettingsTabName() ), iconid );
+}
diff --git a/pcsx2/gui/ExecutorThread.cpp b/pcsx2/gui/ExecutorThread.cpp
index 7408b2d554..41f578ca62 100644
--- a/pcsx2/gui/ExecutorThread.cpp
+++ b/pcsx2/gui/ExecutorThread.cpp
@@ -1,514 +1,514 @@
-/* PCSX2 - PS2 Emulator for PCs
- * Copyright (C) 2002-2010 PCSX2 Dev Team
- *
- * PCSX2 is free software: you can redistribute it and/or modify it under the terms
- * of the GNU Lesser General Public License as published by the Free Software Found-
- * ation, either version 3 of the License, or (at your option) any later version.
- *
- * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with PCSX2.
- * If not, see .
- */
-
-#include "PrecompiledHeader.h"
-#include "App.h"
-
-
-wxString SysExecEvent::GetEventName() const
-{
- pxFail( "Warning: Unnamed SysExecutor Event! Please overload GetEventName() in all SysExecEvent derived classes." );
- return wxEmptyString;
-}
-
-wxString SysExecEvent::GetEventMessage() const
-{
- return GetEventName();
-}
-
-// This is called from _DoInvokeEvent after various affinity and state checks have verified the
-// message as executable. Override this when possible. Only override _DoInvokeEvent if you
-// need some kind of additional low-level ability.
-void SysExecEvent::InvokeEvent()
-{
-}
-
-// This is called by _DoInvokeEvent *always* -- even when exceptions occur during InvokeEvent(),
-// making this function a bit like a C# 'finally' block (try/catch/finally -- a nice feature lacking
-// from C++ prior to the new C++0x standard).
-//
-// This function calls PostResult by default, and should be invoked by derived classes overriding
-// CleanupEvent(), unless you want to change the PostResult behavior.
-void SysExecEvent::CleanupEvent()
-{
- PostResult();
-}
-
-// Transports the specified exception to the thread/context that invoked this event.
-// Events are run from a try/catch block in the event handler that automatically transports
-// exceptions as neeeded, so there shouldn't be much need to use this method directly.
-void SysExecEvent::SetException( BaseException* ex )
-{
- if( !ex ) return;
-
- ex->DiagMsg() += wxsFormat(L"(%s) ", GetEventName().c_str());
- //ex->UserMsg() = prefix + ex->UserMsg();
-
- if( m_sync )
- {
- // Throws the exception inline with the message handler (this makes the exception
- // look like it was thrown quite naturally).
- m_sync->SetException( ex );
- }
- else
- {
- // transport the exception to the main thread, since the message is fully
- // asynchronous, or has already entered an asynchronous state. Message is sent
- // as a non-blocking action since proper handling of user errors on async messages
- // is *usually* to log/ignore it (hah), or to suspend emulation and issue a dialog
- // box to the user.
-
- wxGetApp().PostEvent( pxExceptionEvent( ex ) );
- }
-}
-
-void SysExecEvent::SetException( const BaseException& ex )
-{
- SetException( ex.Clone() );
-}
-
-
-// This method calls _DoInvoke after performing some setup, exception handling, and
-// affinity checks. For implementing behavior of your event, override _DoInvoke
-// instead, which is the intended method of implementing derived class invocation.
-void SysExecEvent::_DoInvokeEvent()
-{
- AffinityAssert_AllowFrom_SysExecutor();
-
- try {
- InvokeEvent();
- }
- catch( BaseException& ex )
- {
- SetException( ex );
- }
- catch( std::runtime_error& ex )
- {
- SetException( new Exception::RuntimeError(ex) );
- }
-
- // Cleanup Execution -- performed regardless of exception or not above.
- try {
- CleanupEvent();
- }
- catch( BaseException& ex )
- {
- SetException( ex );
- }
- catch( std::runtime_error& ex )
- {
- SetException( new Exception::RuntimeError(ex) );
- }
-}
-
-// Posts an empty result to the invoking context/thread of this message, if one exists.
-// If the invoking thread posted the event in non-blocking fashion then no action is
-// taken.
-void SysExecEvent::PostResult() const
-{
- if( m_sync ) m_sync->PostResult();
-}
-
-// --------------------------------------------------------------------------------------
-// pxEvtHandler Implementations
-// --------------------------------------------------------------------------------------
-pxEvtHandler::pxEvtHandler()
-{
- AtomicExchange( m_Quitting, false );
- m_qpc_Start = 0;
-}
-
-// Puts the event queue into Shutdown mode, which does *not* immediately stop nor cancel
-// the queue's processing. Instead it marks the queue inaccessible to all new events
-// and continues procesing queued events for critical events that should not be ignored.
-// (typically these are shutdown events critical to closing the app cleanly). Once
-// all such events have been processed, the thread is stopped.
-//
-void pxEvtHandler::ShutdownQueue()
-{
- if( m_Quitting ) return;
- AtomicExchange( m_Quitting, true );
- m_wakeup.Post();
-}
-
-struct ScopedThreadCancelDisable
-{
- ScopedThreadCancelDisable()
- {
- int oldstate;
- pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldstate );
- }
-
- ~ScopedThreadCancelDisable() throw()
- {
- int oldstate;
- pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, &oldstate );
- }
-};
-
-void pxEvtHandler::ProcessEvents( pxEvtList& list )
-{
- ScopedLock synclock( m_mtx_pending );
-
- pxEvtList::iterator node;
- while( node = list.begin(), node != list.end() )
- {
- ScopedPtr deleteMe(*node);
-
- list.erase( node );
- if( !m_Quitting || deleteMe->IsCriticalEvent() )
- {
- // Some messages can be blocking, so we should release the mutex lock while
- // processing, to avoid having cases where the main thread deadlocks simply
- // trying to add a message to the queue due to the basic mutex acquire needed.
-
- m_qpc_Start = GetCPUTicks();
-
- synclock.Release();
-
- DevCon.WriteLn( L"(pxEvtHandler) Executing Event: %s [%s]", deleteMe->GetEventName().c_str(), deleteMe->AllowCancelOnExit() ? L"Cancelable" : L"Noncancelable" );
-
- if( deleteMe->AllowCancelOnExit() )
- deleteMe->_DoInvokeEvent();
- else
- {
- ScopedThreadCancelDisable thr_cancel_scope;
- deleteMe->_DoInvokeEvent();
- }
-
- u64 qpc_end = GetCPUTicks();
- DevCon.WriteLn( L"(pxEvtHandler) Event '%s' completed in %dms", deleteMe->GetEventName().c_str(), ((qpc_end-m_qpc_Start)*1000) / GetTickFrequency() );
-
- synclock.Acquire();
- m_qpc_Start = 0; // lets the main thread know the message completed.
- }
- else
- {
- Console.WriteLn( L"(pxEvtHandler) Skipping Event: %s", deleteMe->GetEventName().c_str() );
- deleteMe->PostResult();
- }
- }
-}
-
-void pxEvtHandler::ProcessIdleEvents()
-{
- ProcessEvents( m_idleEvents );
-}
-
-void pxEvtHandler::ProcessPendingEvents()
-{
- ProcessEvents( m_pendingEvents );
-}
-
-// This method is provided for wxWidgets API conformance. I like to use PostEvent instead
-// since it's remenicient of PostMessage in Windows (and behaves rather similarly).
-void pxEvtHandler::AddPendingEvent( SysExecEvent& evt )
-{
- PostEvent( evt );
-}
-
-// Adds an event to the event queue in non-blocking fashion. The thread executing this
-// event queue will be woken up if it's idle/sleeping.
-// IMPORTANT: The pointer version of this function will *DELETE* the event object passed
-// to it automatically when the event has been executed. If you are using a scoped event
-// you should use the Reference/Handle overload instead!
-//
-void pxEvtHandler::PostEvent( SysExecEvent* evt )
-{
- if( !evt ) return;
-
- if( m_Quitting )
- {
- evt->PostResult();
- return;
- }
-
- ScopedLock synclock( m_mtx_pending );
-
- //DbgCon.WriteLn( L"(%s) Posting event: %s (queue count=%d)", GetEventHandlerName().c_str(), evt->GetEventName().c_str(), m_pendingEvents.size() );
-
- m_pendingEvents.push_back( evt );
- if( m_pendingEvents.size() == 1)
- m_wakeup.Post();
-}
-
-void pxEvtHandler::PostEvent( const SysExecEvent& evt )
-{
- PostEvent( evt.Clone() );
-}
-
-void pxEvtHandler::PostIdleEvent( SysExecEvent* evt )
-{
- if( !evt ) return;
-
- if( m_Quitting )
- {
- evt->PostResult();
- return;
- }
-
- ScopedLock synclock( m_mtx_pending );
-
- if( m_idleEvents.size() == 0)
- {
- m_pendingEvents.push_back( evt );
- m_wakeup.Post();
- }
- else
- m_idleEvents.push_back( evt );
-}
-
-void pxEvtHandler::PostIdleEvent( const SysExecEvent& evt )
-{
- PostIdleEvent( evt.Clone() );
-}
-
-void pxEvtHandler::ProcessEvent( SysExecEvent& evt )
-{
- if( wxThread::GetCurrentId() != m_OwnerThreadId )
- {
- SynchronousActionState sync;
- evt.SetSyncState( sync );
- PostEvent( evt );
- sync.WaitForResult();
- }
- else
- evt._DoInvokeEvent();
-}
-
-void pxEvtHandler::ProcessEvent( SysExecEvent* evt )
-{
- if( !evt ) return;
-
- if( wxThread::GetCurrentId() != m_OwnerThreadId )
- {
- SynchronousActionState sync;
- evt->SetSyncState( sync );
- PostEvent( evt );
- sync.WaitForResult();
- }
- else
- {
- ScopedPtr deleteMe( evt );
- deleteMe->_DoInvokeEvent();
- }
-}
-
-bool pxEvtHandler::ProcessMethodSelf( FnType_Void* method )
-{
- if( wxThread::GetCurrentId() != m_OwnerThreadId )
- {
- SynchronousActionState sync;
- SysExecEvent_MethodVoid evt(method);
- evt.SetSyncState( sync );
- PostEvent( evt );
- sync.WaitForResult();
-
- return true;
- }
-
- return false;
-}
-
-// This method invokes the derived class Idle implementations (if any) and then enters
-// the sleep state until such time that new messages are received.
-//
-// FUTURE: Processes idle messages from the idle message queue (not implemented yet).
-//
-// Extending: Derived classes should override _DoIdle instead, unless it is necessary
-// to implement post-wakeup behavior.
-//
-void pxEvtHandler::Idle()
-{
- ProcessIdleEvents();
- _DoIdle();
- m_wakeup.WaitWithoutYield();
-}
-
-void pxEvtHandler::SetActiveThread()
-{
- m_OwnerThreadId = wxThread::GetCurrentId();
-}
-
-// --------------------------------------------------------------------------------------
-// WaitingForThreadedTaskDialog
-// --------------------------------------------------------------------------------------
-// Note: currently unused (legacy code). May be utilized at a later date, so I'm leaving
-// it in (for now!)
-//
-class WaitingForThreadedTaskDialog
- : public wxDialogWithHelpers
-{
-private:
- typedef wxDialogWithHelpers _parent;
-
-protected:
- PersistentThread* m_thread;
-
-public:
- WaitingForThreadedTaskDialog( PersistentThread* thr, wxWindow* parent, const wxString& title, const wxString& content );
- virtual ~WaitingForThreadedTaskDialog() throw() {}
-
-protected:
- void OnCancel_Clicked( wxCommandEvent& evt );
- void OnTerminateApp_Clicked( wxCommandEvent& evt );
-};
-
-// --------------------------------------------------------------------------------------
-// WaitingForThreadedTaskDialog Implementations
-// --------------------------------------------------------------------------------------
-WaitingForThreadedTaskDialog::WaitingForThreadedTaskDialog( PersistentThread* thr, wxWindow* parent, const wxString& title, const wxString& content )
- : wxDialogWithHelpers( parent, title, wxVERTICAL )
-{
- m_thread = thr;
- m_idealWidth = 500;
-
- *this += Heading( content );
- *this += 15;
- *this += Heading( _("Press Cancel to attempt to cancel the action.") );
- *this += Heading( _("Press Terminate to kill PCSX2 immediately.") );
-
- *this += new wxButton( this, wxID_CANCEL );
- *this += new wxButton( this, wxID_ANY, _("Terminate App") );
-}
-
-void WaitingForThreadedTaskDialog::OnCancel_Clicked( wxCommandEvent& evt )
-{
- evt.Skip();
- if( !m_thread ) return;
- m_thread->Cancel( false );
-
- if( wxWindow* cancel = FindWindowById( wxID_CANCEL ) ) cancel->Disable();
-}
-
-void WaitingForThreadedTaskDialog::OnTerminateApp_Clicked( wxCommandEvent& evt )
-{
- // (note: SIGTERM is a "handled" kill that performs shutdown stuff, which typically just crashes anyway)
- wxKill( wxGetProcessId(), wxSIGKILL );
-}
-
-// --------------------------------------------------------------------------------------
-// ExecutorThread Implementations
-// --------------------------------------------------------------------------------------
-ExecutorThread::ExecutorThread( pxEvtHandler* evthandler )
-{
- m_EvtHandler = evthandler;
-}
-
-// Exposes the internal pxEvtHandler::ShutdownQueue API. See pxEvtHandler for details.
-void ExecutorThread::ShutdownQueue()
-{
- if( !m_EvtHandler ) return;
-
- if( !m_EvtHandler->IsShuttingDown() )
- m_EvtHandler->ShutdownQueue();
-
- Block();
-}
-
-// Exposes the internal pxEvtHandler::PostEvent API. See pxEvtHandler for details.
-void ExecutorThread::PostEvent( SysExecEvent* evt )
-{
- if( !pxAssert( m_EvtHandler ) ) return;
- m_EvtHandler->PostEvent( evt );
-}
-
-void ExecutorThread::PostEvent( const SysExecEvent& evt )
-{
- if( !pxAssert( m_EvtHandler ) ) return;
- m_EvtHandler->PostEvent( evt );
-}
-
-// Exposes the internal pxEvtHandler::PostIdleEvent API. See pxEvtHandler for details.
-void ExecutorThread::PostIdleEvent( SysExecEvent* evt )
-{
- if( !pxAssert( m_EvtHandler ) ) return;
- m_EvtHandler->PostIdleEvent( evt );
-}
-
-void ExecutorThread::PostIdleEvent( const SysExecEvent& evt )
-{
- if( !pxAssert( m_EvtHandler ) ) return;
- m_EvtHandler->PostIdleEvent( evt );
-}
-
-// Exposes the internal pxEvtHandler::ProcessEvent API. See pxEvtHandler for details.
-void ExecutorThread::ProcessEvent( SysExecEvent* evt )
-{
- if( m_EvtHandler )
- m_EvtHandler->ProcessEvent( evt );
- else
- {
- ScopedPtr deleteMe( evt );
- deleteMe->_DoInvokeEvent();
- }
-}
-
-void ExecutorThread::ProcessEvent( SysExecEvent& evt )
-{
- if( m_EvtHandler )
- m_EvtHandler->ProcessEvent( evt );
- else
- evt._DoInvokeEvent();
-}
-
-void ExecutorThread::OnStart()
-{
- //if( !m_ExecutorTimer )
- // m_ExecutorTimer = new wxTimer( wxTheApp, pxEvt_ThreadTaskTimeout_SysExec );
-
- m_name = L"SysExecutor";
- _parent::OnStart();
-}
-
-void ExecutorThread::ExecuteTaskInThread()
-{
- if( !pxAssertDev( m_EvtHandler, "Gimme a damn Event Handler first, object whore." ) ) return;
-
- m_EvtHandler->SetActiveThread();
-
- while( true )
- {
- if( !pxAssertDev( m_EvtHandler, "Event handler has been deallocated during SysExecutor thread execution." ) ) return;
-
- m_EvtHandler->Idle();
- m_EvtHandler->ProcessPendingEvents();
- if( m_EvtHandler->IsShuttingDown() ) break;
- }
-}
-
-void ExecutorThread::OnCleanupInThread()
-{
- //wxGetApp().PostCommand( m_task, pxEvt_ThreadTaskComplete );
- _parent::OnCleanupInThread();
-}
-
-// --------------------------------------------------------------------------------------
-// Threaded Event Handlers (Pcsx2App)
-// --------------------------------------------------------------------------------------
-
-// This event is called when the SysExecutorThread's timer triggers, which means the
-// VM/system task has taken an oddly long period of time to complete. The task is able
-// to invoke a modal dialog from here that will grant the user some options for handling
-// the unresponsive task.
-void Pcsx2App::OnSysExecutorTaskTimeout( wxTimerEvent& evt )
-{
- if( !SysExecutorThread.IsRunning() ) return;
-
- //BaseThreadedInvocation* task = SysExecutorThread.GetTask();
- //if( !task ) return;
-
- //task->ShowModalStatus();
-}
+/* PCSX2 - PS2 Emulator for PCs
+ * Copyright (C) 2002-2010 PCSX2 Dev Team
+ *
+ * PCSX2 is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU Lesser General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with PCSX2.
+ * If not, see .
+ */
+
+#include "PrecompiledHeader.h"
+#include "App.h"
+
+
+wxString SysExecEvent::GetEventName() const
+{
+ pxFail( "Warning: Unnamed SysExecutor Event! Please overload GetEventName() in all SysExecEvent derived classes." );
+ return wxEmptyString;
+}
+
+wxString SysExecEvent::GetEventMessage() const
+{
+ return GetEventName();
+}
+
+// This is called from _DoInvokeEvent after various affinity and state checks have verified the
+// message as executable. Override this when possible. Only override _DoInvokeEvent if you
+// need some kind of additional low-level ability.
+void SysExecEvent::InvokeEvent()
+{
+}
+
+// This is called by _DoInvokeEvent *always* -- even when exceptions occur during InvokeEvent(),
+// making this function a bit like a C# 'finally' block (try/catch/finally -- a nice feature lacking
+// from C++ prior to the new C++0x standard).
+//
+// This function calls PostResult by default, and should be invoked by derived classes overriding
+// CleanupEvent(), unless you want to change the PostResult behavior.
+void SysExecEvent::CleanupEvent()
+{
+ PostResult();
+}
+
+// Transports the specified exception to the thread/context that invoked this event.
+// Events are run from a try/catch block in the event handler that automatically transports
+// exceptions as neeeded, so there shouldn't be much need to use this method directly.
+void SysExecEvent::SetException( BaseException* ex )
+{
+ if( !ex ) return;
+
+ ex->DiagMsg() += wxsFormat(L"(%s) ", GetEventName().c_str());
+ //ex->UserMsg() = prefix + ex->UserMsg();
+
+ if( m_sync )
+ {
+ // Throws the exception inline with the message handler (this makes the exception
+ // look like it was thrown quite naturally).
+ m_sync->SetException( ex );
+ }
+ else
+ {
+ // transport the exception to the main thread, since the message is fully
+ // asynchronous, or has already entered an asynchronous state. Message is sent
+ // as a non-blocking action since proper handling of user errors on async messages
+ // is *usually* to log/ignore it (hah), or to suspend emulation and issue a dialog
+ // box to the user.
+
+ wxGetApp().PostEvent( pxExceptionEvent( ex ) );
+ }
+}
+
+void SysExecEvent::SetException( const BaseException& ex )
+{
+ SetException( ex.Clone() );
+}
+
+
+// This method calls _DoInvoke after performing some setup, exception handling, and
+// affinity checks. For implementing behavior of your event, override _DoInvoke
+// instead, which is the intended method of implementing derived class invocation.
+void SysExecEvent::_DoInvokeEvent()
+{
+ AffinityAssert_AllowFrom_SysExecutor();
+
+ try {
+ InvokeEvent();
+ }
+ catch( BaseException& ex )
+ {
+ SetException( ex );
+ }
+ catch( std::runtime_error& ex )
+ {
+ SetException( new Exception::RuntimeError(ex) );
+ }
+
+ // Cleanup Execution -- performed regardless of exception or not above.
+ try {
+ CleanupEvent();
+ }
+ catch( BaseException& ex )
+ {
+ SetException( ex );
+ }
+ catch( std::runtime_error& ex )
+ {
+ SetException( new Exception::RuntimeError(ex) );
+ }
+}
+
+// Posts an empty result to the invoking context/thread of this message, if one exists.
+// If the invoking thread posted the event in non-blocking fashion then no action is
+// taken.
+void SysExecEvent::PostResult() const
+{
+ if( m_sync ) m_sync->PostResult();
+}
+
+// --------------------------------------------------------------------------------------
+// pxEvtHandler Implementations
+// --------------------------------------------------------------------------------------
+pxEvtHandler::pxEvtHandler()
+{
+ AtomicExchange( m_Quitting, false );
+ m_qpc_Start = 0;
+}
+
+// Puts the event queue into Shutdown mode, which does *not* immediately stop nor cancel
+// the queue's processing. Instead it marks the queue inaccessible to all new events
+// and continues procesing queued events for critical events that should not be ignored.
+// (typically these are shutdown events critical to closing the app cleanly). Once
+// all such events have been processed, the thread is stopped.
+//
+void pxEvtHandler::ShutdownQueue()
+{
+ if( m_Quitting ) return;
+ AtomicExchange( m_Quitting, true );
+ m_wakeup.Post();
+}
+
+struct ScopedThreadCancelDisable
+{
+ ScopedThreadCancelDisable()
+ {
+ int oldstate;
+ pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldstate );
+ }
+
+ ~ScopedThreadCancelDisable() throw()
+ {
+ int oldstate;
+ pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, &oldstate );
+ }
+};
+
+void pxEvtHandler::ProcessEvents( pxEvtList& list )
+{
+ ScopedLock synclock( m_mtx_pending );
+
+ pxEvtList::iterator node;
+ while( node = list.begin(), node != list.end() )
+ {
+ ScopedPtr deleteMe(*node);
+
+ list.erase( node );
+ if( !m_Quitting || deleteMe->IsCriticalEvent() )
+ {
+ // Some messages can be blocking, so we should release the mutex lock while
+ // processing, to avoid having cases where the main thread deadlocks simply
+ // trying to add a message to the queue due to the basic mutex acquire needed.
+
+ m_qpc_Start = GetCPUTicks();
+
+ synclock.Release();
+
+ DevCon.WriteLn( L"(pxEvtHandler) Executing Event: %s [%s]", deleteMe->GetEventName().c_str(), deleteMe->AllowCancelOnExit() ? L"Cancelable" : L"Noncancelable" );
+
+ if( deleteMe->AllowCancelOnExit() )
+ deleteMe->_DoInvokeEvent();
+ else
+ {
+ ScopedThreadCancelDisable thr_cancel_scope;
+ deleteMe->_DoInvokeEvent();
+ }
+
+ u64 qpc_end = GetCPUTicks();
+ DevCon.WriteLn( L"(pxEvtHandler) Event '%s' completed in %dms", deleteMe->GetEventName().c_str(), ((qpc_end-m_qpc_Start)*1000) / GetTickFrequency() );
+
+ synclock.Acquire();
+ m_qpc_Start = 0; // lets the main thread know the message completed.
+ }
+ else
+ {
+ Console.WriteLn( L"(pxEvtHandler) Skipping Event: %s", deleteMe->GetEventName().c_str() );
+ deleteMe->PostResult();
+ }
+ }
+}
+
+void pxEvtHandler::ProcessIdleEvents()
+{
+ ProcessEvents( m_idleEvents );
+}
+
+void pxEvtHandler::ProcessPendingEvents()
+{
+ ProcessEvents( m_pendingEvents );
+}
+
+// This method is provided for wxWidgets API conformance. I like to use PostEvent instead
+// since it's remenicient of PostMessage in Windows (and behaves rather similarly).
+void pxEvtHandler::AddPendingEvent( SysExecEvent& evt )
+{
+ PostEvent( evt );
+}
+
+// Adds an event to the event queue in non-blocking fashion. The thread executing this
+// event queue will be woken up if it's idle/sleeping.
+// IMPORTANT: The pointer version of this function will *DELETE* the event object passed
+// to it automatically when the event has been executed. If you are using a scoped event
+// you should use the Reference/Handle overload instead!
+//
+void pxEvtHandler::PostEvent( SysExecEvent* evt )
+{
+ if( !evt ) return;
+
+ if( m_Quitting )
+ {
+ evt->PostResult();
+ return;
+ }
+
+ ScopedLock synclock( m_mtx_pending );
+
+ //DbgCon.WriteLn( L"(%s) Posting event: %s (queue count=%d)", GetEventHandlerName().c_str(), evt->GetEventName().c_str(), m_pendingEvents.size() );
+
+ m_pendingEvents.push_back( evt );
+ if( m_pendingEvents.size() == 1)
+ m_wakeup.Post();
+}
+
+void pxEvtHandler::PostEvent( const SysExecEvent& evt )
+{
+ PostEvent( evt.Clone() );
+}
+
+void pxEvtHandler::PostIdleEvent( SysExecEvent* evt )
+{
+ if( !evt ) return;
+
+ if( m_Quitting )
+ {
+ evt->PostResult();
+ return;
+ }
+
+ ScopedLock synclock( m_mtx_pending );
+
+ if( m_idleEvents.size() == 0)
+ {
+ m_pendingEvents.push_back( evt );
+ m_wakeup.Post();
+ }
+ else
+ m_idleEvents.push_back( evt );
+}
+
+void pxEvtHandler::PostIdleEvent( const SysExecEvent& evt )
+{
+ PostIdleEvent( evt.Clone() );
+}
+
+void pxEvtHandler::ProcessEvent( SysExecEvent& evt )
+{
+ if( wxThread::GetCurrentId() != m_OwnerThreadId )
+ {
+ SynchronousActionState sync;
+ evt.SetSyncState( sync );
+ PostEvent( evt );
+ sync.WaitForResult();
+ }
+ else
+ evt._DoInvokeEvent();
+}
+
+void pxEvtHandler::ProcessEvent( SysExecEvent* evt )
+{
+ if( !evt ) return;
+
+ if( wxThread::GetCurrentId() != m_OwnerThreadId )
+ {
+ SynchronousActionState sync;
+ evt->SetSyncState( sync );
+ PostEvent( evt );
+ sync.WaitForResult();
+ }
+ else
+ {
+ ScopedPtr deleteMe( evt );
+ deleteMe->_DoInvokeEvent();
+ }
+}
+
+bool pxEvtHandler::ProcessMethodSelf( FnType_Void* method )
+{
+ if( wxThread::GetCurrentId() != m_OwnerThreadId )
+ {
+ SynchronousActionState sync;
+ SysExecEvent_MethodVoid evt(method);
+ evt.SetSyncState( sync );
+ PostEvent( evt );
+ sync.WaitForResult();
+
+ return true;
+ }
+
+ return false;
+}
+
+// This method invokes the derived class Idle implementations (if any) and then enters
+// the sleep state until such time that new messages are received.
+//
+// FUTURE: Processes idle messages from the idle message queue (not implemented yet).
+//
+// Extending: Derived classes should override _DoIdle instead, unless it is necessary
+// to implement post-wakeup behavior.
+//
+void pxEvtHandler::Idle()
+{
+ ProcessIdleEvents();
+ _DoIdle();
+ m_wakeup.WaitWithoutYield();
+}
+
+void pxEvtHandler::SetActiveThread()
+{
+ m_OwnerThreadId = wxThread::GetCurrentId();
+}
+
+// --------------------------------------------------------------------------------------
+// WaitingForThreadedTaskDialog
+// --------------------------------------------------------------------------------------
+// Note: currently unused (legacy code). May be utilized at a later date, so I'm leaving
+// it in (for now!)
+//
+class WaitingForThreadedTaskDialog
+ : public wxDialogWithHelpers
+{
+private:
+ typedef wxDialogWithHelpers _parent;
+
+protected:
+ PersistentThread* m_thread;
+
+public:
+ WaitingForThreadedTaskDialog( PersistentThread* thr, wxWindow* parent, const wxString& title, const wxString& content );
+ virtual ~WaitingForThreadedTaskDialog() throw() {}
+
+protected:
+ void OnCancel_Clicked( wxCommandEvent& evt );
+ void OnTerminateApp_Clicked( wxCommandEvent& evt );
+};
+
+// --------------------------------------------------------------------------------------
+// WaitingForThreadedTaskDialog Implementations
+// --------------------------------------------------------------------------------------
+WaitingForThreadedTaskDialog::WaitingForThreadedTaskDialog( PersistentThread* thr, wxWindow* parent, const wxString& title, const wxString& content )
+ : wxDialogWithHelpers( parent, title, wxVERTICAL )
+{
+ m_thread = thr;
+ m_idealWidth = 500;
+
+ *this += Heading( content );
+ *this += 15;
+ *this += Heading( _("Press Cancel to attempt to cancel the action.") );
+ *this += Heading( _("Press Terminate to kill PCSX2 immediately.") );
+
+ *this += new wxButton( this, wxID_CANCEL );
+ *this += new wxButton( this, wxID_ANY, _("Terminate App") );
+}
+
+void WaitingForThreadedTaskDialog::OnCancel_Clicked( wxCommandEvent& evt )
+{
+ evt.Skip();
+ if( !m_thread ) return;
+ m_thread->Cancel( false );
+
+ if( wxWindow* cancel = FindWindowById( wxID_CANCEL ) ) cancel->Disable();
+}
+
+void WaitingForThreadedTaskDialog::OnTerminateApp_Clicked( wxCommandEvent& evt )
+{
+ // (note: SIGTERM is a "handled" kill that performs shutdown stuff, which typically just crashes anyway)
+ wxKill( wxGetProcessId(), wxSIGKILL );
+}
+
+// --------------------------------------------------------------------------------------
+// ExecutorThread Implementations
+// --------------------------------------------------------------------------------------
+ExecutorThread::ExecutorThread( pxEvtHandler* evthandler )
+{
+ m_EvtHandler = evthandler;
+}
+
+// Exposes the internal pxEvtHandler::ShutdownQueue API. See pxEvtHandler for details.
+void ExecutorThread::ShutdownQueue()
+{
+ if( !m_EvtHandler ) return;
+
+ if( !m_EvtHandler->IsShuttingDown() )
+ m_EvtHandler->ShutdownQueue();
+
+ Block();
+}
+
+// Exposes the internal pxEvtHandler::PostEvent API. See pxEvtHandler for details.
+void ExecutorThread::PostEvent( SysExecEvent* evt )
+{
+ if( !pxAssert( m_EvtHandler ) ) return;
+ m_EvtHandler->PostEvent( evt );
+}
+
+void ExecutorThread::PostEvent( const SysExecEvent& evt )
+{
+ if( !pxAssert( m_EvtHandler ) ) return;
+ m_EvtHandler->PostEvent( evt );
+}
+
+// Exposes the internal pxEvtHandler::PostIdleEvent API. See pxEvtHandler for details.
+void ExecutorThread::PostIdleEvent( SysExecEvent* evt )
+{
+ if( !pxAssert( m_EvtHandler ) ) return;
+ m_EvtHandler->PostIdleEvent( evt );
+}
+
+void ExecutorThread::PostIdleEvent( const SysExecEvent& evt )
+{
+ if( !pxAssert( m_EvtHandler ) ) return;
+ m_EvtHandler->PostIdleEvent( evt );
+}
+
+// Exposes the internal pxEvtHandler::ProcessEvent API. See pxEvtHandler for details.
+void ExecutorThread::ProcessEvent( SysExecEvent* evt )
+{
+ if( m_EvtHandler )
+ m_EvtHandler->ProcessEvent( evt );
+ else
+ {
+ ScopedPtr deleteMe( evt );
+ deleteMe->_DoInvokeEvent();
+ }
+}
+
+void ExecutorThread::ProcessEvent( SysExecEvent& evt )
+{
+ if( m_EvtHandler )
+ m_EvtHandler->ProcessEvent( evt );
+ else
+ evt._DoInvokeEvent();
+}
+
+void ExecutorThread::OnStart()
+{
+ //if( !m_ExecutorTimer )
+ // m_ExecutorTimer = new wxTimer( wxTheApp, pxEvt_ThreadTaskTimeout_SysExec );
+
+ m_name = L"SysExecutor";
+ _parent::OnStart();
+}
+
+void ExecutorThread::ExecuteTaskInThread()
+{
+ if( !pxAssertDev( m_EvtHandler, "Gimme a damn Event Handler first, object whore." ) ) return;
+
+ m_EvtHandler->SetActiveThread();
+
+ while( true )
+ {
+ if( !pxAssertDev( m_EvtHandler, "Event handler has been deallocated during SysExecutor thread execution." ) ) return;
+
+ m_EvtHandler->Idle();
+ m_EvtHandler->ProcessPendingEvents();
+ if( m_EvtHandler->IsShuttingDown() ) break;
+ }
+}
+
+void ExecutorThread::OnCleanupInThread()
+{
+ //wxGetApp().PostCommand( m_task, pxEvt_ThreadTaskComplete );
+ _parent::OnCleanupInThread();
+}
+
+// --------------------------------------------------------------------------------------
+// Threaded Event Handlers (Pcsx2App)
+// --------------------------------------------------------------------------------------
+
+// This event is called when the SysExecutorThread's timer triggers, which means the
+// VM/system task has taken an oddly long period of time to complete. The task is able
+// to invoke a modal dialog from here that will grant the user some options for handling
+// the unresponsive task.
+void Pcsx2App::OnSysExecutorTaskTimeout( wxTimerEvent& evt )
+{
+ if( !SysExecutorThread.IsRunning() ) return;
+
+ //BaseThreadedInvocation* task = SysExecutorThread.GetTask();
+ //if( !task ) return;
+
+ //task->ShowModalStatus();
+}
diff --git a/pcsx2/gui/GSFrame.h b/pcsx2/gui/GSFrame.h
index 2212493c03..3b1456046b 100644
--- a/pcsx2/gui/GSFrame.h
+++ b/pcsx2/gui/GSFrame.h
@@ -1,120 +1,120 @@
-
-/* PCSX2 - PS2 Emulator for PCs
- * Copyright (C) 2002-2010 PCSX2 Dev Team
- *
- * PCSX2 is free software: you can redistribute it and/or modify it under the terms
- * of the GNU Lesser General Public License as published by the Free Software Found-
- * ation, either version 3 of the License, or (at your option) any later version.
- *
- * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with PCSX2.
- * If not, see .
- */
-
-#pragma once
-
-#include "App.h"
-#include "CpuUsageProvider.h"
-
-
-enum LimiterModeType
-{
- Limit_Nominal,
- Limit_Turbo,
- Limit_Slomo,
-};
-
-extern LimiterModeType g_LimiterMode;
-
-// --------------------------------------------------------------------------------------
-// GSPanel
-// --------------------------------------------------------------------------------------
-class GSPanel : public wxWindow, public EventListener_AppStatus
-{
- typedef wxWindow _parent;
-
-protected:
- AcceleratorDictionary m_Accels;
- wxTimer m_HideMouseTimer;
- bool m_CursorShown;
- bool m_HasFocus;
-
-public:
- GSPanel( wxWindow* parent );
- virtual ~GSPanel() throw();
-
- void DoResize();
- void DoShowMouse();
-
-protected:
- void AppStatusEvent_OnSettingsApplied();
-
-#ifdef __WXMSW__
- virtual WXLRESULT MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam);
-#endif
-
- void InitDefaultAccelerators();
-
- void OnCloseWindow( wxCloseEvent& evt );
- void OnResize(wxSizeEvent& event);
- void OnShowMouse( wxMouseEvent& evt );
- void OnHideMouseTimeout( wxTimerEvent& evt );
- void OnKeyDown( wxKeyEvent& evt );
- void OnFocus( wxFocusEvent& evt );
- void OnFocusLost( wxFocusEvent& evt );
-};
-
-
-// --------------------------------------------------------------------------------------
-// GSFrame
-// --------------------------------------------------------------------------------------
-class GSFrame : public wxFrame,
- public EventListener_AppStatus,
- public EventListener_CoreThread
-{
- typedef wxFrame _parent;
-
-protected:
- wxTimer m_timer_UpdateTitle;
- wxWindowID m_id_gspanel;
- wxWindowID m_id_OutputDisabled;
- wxStaticText* m_label_Disabled;
- wxStatusBar* m_statusbar;
-
- CpuUsageProvider m_CpuUsage;
-
-public:
- GSFrame(wxWindow* parent, const wxString& title);
- virtual ~GSFrame() throw();
-
- GSPanel* GetViewport();
- void SetFocus();
- bool Show( bool shown=true );
- wxStaticText* GetLabel_OutputDisabled() const;
-
-protected:
- void OnCloseWindow( wxCloseEvent& evt );
- void OnMove( wxMoveEvent& evt );
- void OnResize( wxSizeEvent& evt );
- void OnActivate( wxActivateEvent& evt );
- void OnUpdateTitle( wxTimerEvent& evt );
-
- void AppStatusEvent_OnSettingsApplied();
- void CoreThread_OnResumed();
- void CoreThread_OnSuspended();
-};
-
-// --------------------------------------------------------------------------------------
-// s* macros! ['s' stands for 'shortcut']
-// --------------------------------------------------------------------------------------
-// Use these for "silent fail" invocation of PCSX2 Application-related constructs. If the
-// construct (albeit wxApp, MainFrame, CoreThread, etc) is null, the requested method will
-// not be invoked, and an optional "else" clause can be affixed for handling the end case.
-//
-// See App.h (sApp) for more details.
-//
-#define sGSFrame \
- if( GSFrame* __gsframe_ = wxGetApp().GetGsFramePtr() ) (*__gsframe_)
+
+/* PCSX2 - PS2 Emulator for PCs
+ * Copyright (C) 2002-2010 PCSX2 Dev Team
+ *
+ * PCSX2 is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU Lesser General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with PCSX2.
+ * If not, see .
+ */
+
+#pragma once
+
+#include "App.h"
+#include "CpuUsageProvider.h"
+
+
+enum LimiterModeType
+{
+ Limit_Nominal,
+ Limit_Turbo,
+ Limit_Slomo,
+};
+
+extern LimiterModeType g_LimiterMode;
+
+// --------------------------------------------------------------------------------------
+// GSPanel
+// --------------------------------------------------------------------------------------
+class GSPanel : public wxWindow, public EventListener_AppStatus
+{
+ typedef wxWindow _parent;
+
+protected:
+ AcceleratorDictionary m_Accels;
+ wxTimer m_HideMouseTimer;
+ bool m_CursorShown;
+ bool m_HasFocus;
+
+public:
+ GSPanel( wxWindow* parent );
+ virtual ~GSPanel() throw();
+
+ void DoResize();
+ void DoShowMouse();
+
+protected:
+ void AppStatusEvent_OnSettingsApplied();
+
+#ifdef __WXMSW__
+ virtual WXLRESULT MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam);
+#endif
+
+ void InitDefaultAccelerators();
+
+ void OnCloseWindow( wxCloseEvent& evt );
+ void OnResize(wxSizeEvent& event);
+ void OnShowMouse( wxMouseEvent& evt );
+ void OnHideMouseTimeout( wxTimerEvent& evt );
+ void OnKeyDown( wxKeyEvent& evt );
+ void OnFocus( wxFocusEvent& evt );
+ void OnFocusLost( wxFocusEvent& evt );
+};
+
+
+// --------------------------------------------------------------------------------------
+// GSFrame
+// --------------------------------------------------------------------------------------
+class GSFrame : public wxFrame,
+ public EventListener_AppStatus,
+ public EventListener_CoreThread
+{
+ typedef wxFrame _parent;
+
+protected:
+ wxTimer m_timer_UpdateTitle;
+ wxWindowID m_id_gspanel;
+ wxWindowID m_id_OutputDisabled;
+ wxStaticText* m_label_Disabled;
+ wxStatusBar* m_statusbar;
+
+ CpuUsageProvider m_CpuUsage;
+
+public:
+ GSFrame(wxWindow* parent, const wxString& title);
+ virtual ~GSFrame() throw();
+
+ GSPanel* GetViewport();
+ void SetFocus();
+ bool Show( bool shown=true );
+ wxStaticText* GetLabel_OutputDisabled() const;
+
+protected:
+ void OnCloseWindow( wxCloseEvent& evt );
+ void OnMove( wxMoveEvent& evt );
+ void OnResize( wxSizeEvent& evt );
+ void OnActivate( wxActivateEvent& evt );
+ void OnUpdateTitle( wxTimerEvent& evt );
+
+ void AppStatusEvent_OnSettingsApplied();
+ void CoreThread_OnResumed();
+ void CoreThread_OnSuspended();
+};
+
+// --------------------------------------------------------------------------------------
+// s* macros! ['s' stands for 'shortcut']
+// --------------------------------------------------------------------------------------
+// Use these for "silent fail" invocation of PCSX2 Application-related constructs. If the
+// construct (albeit wxApp, MainFrame, CoreThread, etc) is null, the requested method will
+// not be invoked, and an optional "else" clause can be affixed for handling the end case.
+//
+// See App.h (sApp) for more details.
+//
+#define sGSFrame \
+ if( GSFrame* __gsframe_ = wxGetApp().GetGsFramePtr() ) (*__gsframe_)
diff --git a/pcsx2/gui/SysState.cpp b/pcsx2/gui/SysState.cpp
index 24f1c88676..0aac4d4218 100644
--- a/pcsx2/gui/SysState.cpp
+++ b/pcsx2/gui/SysState.cpp
@@ -1,353 +1,353 @@
-/* PCSX2 - PS2 Emulator for PCs
- * Copyright (C) 2002-2010 PCSX2 Dev Team
- *
- * PCSX2 is free software: you can redistribute it and/or modify it under the terms
- * of the GNU Lesser General Public License as published by the Free Software Found-
- * ation, either version 3 of te License, or (at your option) any later version.
- *
- * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with PCSX2.
- * If not, see .
- */
-
-#include "PrecompiledHeader.h"
-#include "App.h"
-
-#include "System/SysThreads.h"
-#include "SaveState.h"
-
-#include "ZipTools/ThreadedZipTools.h"
-
-// Used to hold the current state backup (fullcopy of PS2 memory and plugin states).
-//static VmStateBuffer state_buffer( L"Public Savestate Buffer" );
-
-static const char SavestateIdentString[] = "PCSX2 Savestate";
-static const uint SavestateIdentLen = sizeof(SavestateIdentString);
-
-static void SaveStateFile_WriteHeader( IStreamWriter& thr )
-{
- thr.Write( SavestateIdentString );
- thr.Write( g_SaveVersion );
-}
-
-static void SaveStateFile_ReadHeader( IStreamReader& thr )
-{
- char ident[SavestateIdentLen] = {0};
-
- thr.Read( ident );
-
- if( strcmp(SavestateIdentString, ident) )
- throw Exception::SaveStateLoadError( thr.GetStreamName(),
- wxsFormat( L"Unrecognized file signature while loading savestate: %s", ident ),
- _("File is not a valid PCSX2 savestate, or is from an older unsupported version of PCSX2.")
- );
-
- u32 savever;
- thr.Read( savever );
-
- if( (savever >> 16) != (g_SaveVersion >> 16) )
- throw Exception::SaveStateLoadError( thr.GetStreamName(),
- wxsFormat( L"Unrecognized file signature while loading savestate: %s", ident ),
- _("File is not a valid PCSX2 savestate, or is from an older unsupported version of PCSX2.")
- );
-
- if( savever > g_SaveVersion )
- throw Exception::SaveStateLoadError( thr.GetStreamName(),
- wxsFormat( L"Unrecognized file signature while loading savestate: %s", ident ),
- _("File is not a valid PCSX2 savestate, or is from an older unsupported version of PCSX2.")
- );
-};
-
-// --------------------------------------------------------------------------------------
-// gzipReader
-// --------------------------------------------------------------------------------------
-// Interface for reading data from a gzip stream.
-//
-class gzipReader : public IStreamReader
-{
- DeclareNoncopyableObject(gzipReader);
-
-protected:
- wxString m_filename;
- gzFile m_gzfp;
-
-public:
- gzipReader( const wxString& filename )
- : m_filename( filename )
- {
- if( NULL == (m_gzfp = gzopen( m_filename.ToUTF8(), "rb" )) )
- throw Exception::CannotCreateStream( m_filename, "Cannot open file for reading." );
-
- gzbuffer(m_gzfp, 0x100000); // 1mb buffer for zlib internal operations
- }
-
- virtual ~gzipReader() throw ()
- {
- if( m_gzfp ) gzclose( m_gzfp );
- }
-
- wxString GetStreamName() const { return m_filename; }
-
- void Read( void* dest, size_t size )
- {
- int result = gzread( m_gzfp, dest, size );
- if( result == -1)
- throw Exception::BadStream( m_filename, "Data read failed: Invalid or corrupted gzip archive." );
-
- if( (size_t)result < size )
- throw Exception::EndOfStream( m_filename );
- }
-};
-
-static bool IsSavingOrLoading = false;
-
-
-// --------------------------------------------------------------------------------------
-// SysExecEvent_DownloadState
-// --------------------------------------------------------------------------------------
-// Pauses core emulation and downloads the savestate into the state_buffer.
-//
-class SysExecEvent_DownloadState : public SysExecEvent
-{
-protected:
- VmStateBuffer* m_dest_buffer;
-
-public:
- wxString GetEventName() const { return L"VM_Download"; }
-
- virtual ~SysExecEvent_DownloadState() throw() {}
- SysExecEvent_DownloadState* Clone() const { return new SysExecEvent_DownloadState( *this ); }
- SysExecEvent_DownloadState( VmStateBuffer* dest=NULL )
- {
- m_dest_buffer = dest;
- }
-
- bool IsCriticalEvent() const { return true; }
- bool AllowCancelOnExit() const { return false; }
-
-protected:
- void InvokeEvent()
- {
- ScopedCoreThreadPause paused_core;
-
- if( !SysHasValidState() )
- throw Exception::RuntimeError( L"Cannot complete state freeze request; the virtual machine state is reset.", _("You'll need to start a new virtual machine before you can save its state.") );
-
- memSavingState(m_dest_buffer).FreezeAll();
-
- UI_EnableStateActions();
- paused_core.AllowResume();
- }
-};
-
-// It's bad mojo to have savestates trying to read and write from the same file at the
-// same time. To prevent that we use this mutex lock, which is used by both the
-// CompressThread and the UnzipFromDisk events. (note that CompressThread locks the
-// mutex during OnStartInThread, which ensures that the ZipToDisk event blocks; preventing
-// the SysExecutor's Idle Event from re-enabing savestates and slots.)
-//
-static Mutex mtx_CompressToDisk;
-
-// --------------------------------------------------------------------------------------
-// CompressThread_VmState
-// --------------------------------------------------------------------------------------
-class VmStateZipThread : public CompressThread_gzip
-{
- typedef CompressThread_gzip _parent;
-
-protected:
- ScopedLock m_lock_Compress;
-
-public:
- VmStateZipThread( const wxString& file, VmStateBuffer* srcdata )
- : _parent( file, srcdata, SaveStateFile_WriteHeader )
- {
- m_lock_Compress.Assign(mtx_CompressToDisk);
- }
-
- VmStateZipThread( const wxString& file, ScopedPtr& srcdata )
- : _parent( file, srcdata, SaveStateFile_WriteHeader )
- {
- m_lock_Compress.Assign(mtx_CompressToDisk);
- }
-
- virtual ~VmStateZipThread() throw()
- {
-
- }
-
-protected:
- void OnStartInThread()
- {
- _parent::OnStartInThread();
- m_lock_Compress.Acquire();
- }
-
- void OnCleanupInThread()
- {
- m_lock_Compress.Release();
- _parent::OnCleanupInThread();
- }
-};
-
-// --------------------------------------------------------------------------------------
-// SysExecEvent_ZipToDisk
-// --------------------------------------------------------------------------------------
-class SysExecEvent_ZipToDisk : public SysExecEvent
-{
-protected:
- VmStateBuffer* m_src_buffer;
- wxString m_filename;
-
-public:
- wxString GetEventName() const { return L"VM_ZipToDisk"; }
-
- virtual ~SysExecEvent_ZipToDisk() throw()
- {
- delete m_src_buffer;
- }
-
- SysExecEvent_ZipToDisk* Clone() const { return new SysExecEvent_ZipToDisk( *this ); }
-
- SysExecEvent_ZipToDisk( ScopedPtr& src, const wxString& filename )
- : m_filename( filename )
- {
- m_src_buffer = src.DetachPtr();
- }
-
- SysExecEvent_ZipToDisk( VmStateBuffer* src, const wxString& filename )
- : m_filename( filename )
- {
- m_src_buffer = src;
- }
-
- bool IsCriticalEvent() const { return true; }
- bool AllowCancelOnExit() const { return false; }
-
-protected:
- void InvokeEvent()
- {
- (new VmStateZipThread( m_filename, m_src_buffer ))->Start();
- m_src_buffer = NULL;
- }
-};
-
-// --------------------------------------------------------------------------------------
-// SysExecEvent_UnzipFromDisk
-// --------------------------------------------------------------------------------------
-// Note: Unzipping always goes directly into the SysCoreThread's static VM state, and is
-// always a blocking action on the SysExecutor thread (the system cannot execute other
-// commands while states are unzipping or uploading into the system).
-//
-class SysExecEvent_UnzipFromDisk : public SysExecEvent
-{
-protected:
- wxString m_filename;
-
-public:
- wxString GetEventName() const { return L"VM_UnzipFromDisk"; }
-
- virtual ~SysExecEvent_UnzipFromDisk() throw() {}
- SysExecEvent_UnzipFromDisk* Clone() const { return new SysExecEvent_UnzipFromDisk( *this ); }
- SysExecEvent_UnzipFromDisk( const wxString& filename )
- : m_filename( filename )
- {
- }
-
- wxString GetStreamName() const { return m_filename; }
-
-protected:
- void InvokeEvent()
- {
- ScopedLock lock( mtx_CompressToDisk );
- gzipReader m_gzreader(m_filename );
- SaveStateFile_ReadHeader( m_gzreader );
-
- // We use direct Suspend/Resume control here, since it's desirable that emulation
- // *ALWAYS* start execution after the new savestate is loaded.
-
- GetCoreThread().Pause();
-
- // fixme: should start initially with the file size, and then grow from there.
-
- static const int BlockSize = 0x100000;
-
- VmStateBuffer buffer( 0x800000, L"StateBuffer_UnzipFromDisk" ); // start with an 8 meg buffer to avoid frequent reallocation.
- int curidx = 0;
-
- try {
- while(true) {
- buffer.MakeRoomFor( curidx+BlockSize );
- m_gzreader.Read( buffer.GetPtr(curidx), BlockSize );
- curidx += BlockSize;
- Threading::pxTestCancel();
- }
- }
- catch( Exception::EndOfStream& )
- {
- // This exception actually means success! Any others we let get sent
- // to the main event handler/thread for handling.
- }
-
- // Optional shutdown of plugins when loading states? I'm not implementing it yet because some
- // things, like the SPU2-recovery trick, rely on not resetting the plugins prior to loading
- // the new savestate data.
- //if( ShutdownOnStateLoad ) GetCoreThread().Cancel();
-
-
- GetCoreThread().UploadStateCopy( buffer );
- GetCoreThread().Resume(); // force resume regardless of emulation state earlier.
- }
-};
-
-// =====================================================================================================
-// StateCopy Public Interface
-// =====================================================================================================
-
-void StateCopy_SaveToFile( const wxString& file )
-{
- UI_DisableStateActions();
-
- ScopedPtr zipbuf(new VmStateBuffer( L"Zippable Savestate" ));
- GetSysExecutorThread().PostEvent(new SysExecEvent_DownloadState( zipbuf ));
- GetSysExecutorThread().PostEvent(new SysExecEvent_ZipToDisk( zipbuf, file ));
-}
-
-void StateCopy_LoadFromFile( const wxString& file )
-{
- UI_DisableSysActions();
- GetSysExecutorThread().PostEvent(new SysExecEvent_UnzipFromDisk( file ));
-}
-
-// Saves recovery state info to the given saveslot, or saves the active emulation state
-// (if one exists) and no recovery data was found. This is needed because when a recovery
-// state is made, the emulation state is usually reset so the only persisting state is
-// the one in the memory save. :)
-void StateCopy_SaveToSlot( uint num )
-{
- const wxString file( SaveStateBase::GetFilename( num ) );
-
- Console.WriteLn( Color_StrongGreen, "Saving savestate to slot %d...", num );
- Console.Indent().WriteLn( Color_StrongGreen, L"filename: %s", file.c_str() );
-
- StateCopy_SaveToFile( file );
-}
-
-void StateCopy_LoadFromSlot( uint slot )
-{
- wxString file( SaveStateBase::GetFilename( slot ) );
-
- if( !wxFileExists( file ) )
- {
- Console.Warning( "Savestate slot %d is empty.", slot );
- return;
- }
-
- Console.WriteLn( Color_StrongGreen, "Loading savestate from slot %d...", slot );
- Console.Indent().WriteLn( Color_StrongGreen, L"filename: %s", file.c_str() );
-
- StateCopy_LoadFromFile( file );
-}
+/* PCSX2 - PS2 Emulator for PCs
+ * Copyright (C) 2002-2010 PCSX2 Dev Team
+ *
+ * PCSX2 is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU Lesser General Public License as published by the Free Software Found-
+ * ation, either version 3 of te License, or (at your option) any later version.
+ *
+ * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with PCSX2.
+ * If not, see .
+ */
+
+#include "PrecompiledHeader.h"
+#include "App.h"
+
+#include "System/SysThreads.h"
+#include "SaveState.h"
+
+#include "ZipTools/ThreadedZipTools.h"
+
+// Used to hold the current state backup (fullcopy of PS2 memory and plugin states).
+//static VmStateBuffer state_buffer( L"Public Savestate Buffer" );
+
+static const char SavestateIdentString[] = "PCSX2 Savestate";
+static const uint SavestateIdentLen = sizeof(SavestateIdentString);
+
+static void SaveStateFile_WriteHeader( IStreamWriter& thr )
+{
+ thr.Write( SavestateIdentString );
+ thr.Write( g_SaveVersion );
+}
+
+static void SaveStateFile_ReadHeader( IStreamReader& thr )
+{
+ char ident[SavestateIdentLen] = {0};
+
+ thr.Read( ident );
+
+ if( strcmp(SavestateIdentString, ident) )
+ throw Exception::SaveStateLoadError( thr.GetStreamName(),
+ wxsFormat( L"Unrecognized file signature while loading savestate: %s", ident ),
+ _("File is not a valid PCSX2 savestate, or is from an older unsupported version of PCSX2.")
+ );
+
+ u32 savever;
+ thr.Read( savever );
+
+ if( (savever >> 16) != (g_SaveVersion >> 16) )
+ throw Exception::SaveStateLoadError( thr.GetStreamName(),
+ wxsFormat( L"Unrecognized file signature while loading savestate: %s", ident ),
+ _("File is not a valid PCSX2 savestate, or is from an older unsupported version of PCSX2.")
+ );
+
+ if( savever > g_SaveVersion )
+ throw Exception::SaveStateLoadError( thr.GetStreamName(),
+ wxsFormat( L"Unrecognized file signature while loading savestate: %s", ident ),
+ _("File is not a valid PCSX2 savestate, or is from an older unsupported version of PCSX2.")
+ );
+};
+
+// --------------------------------------------------------------------------------------
+// gzipReader
+// --------------------------------------------------------------------------------------
+// Interface for reading data from a gzip stream.
+//
+class gzipReader : public IStreamReader
+{
+ DeclareNoncopyableObject(gzipReader);
+
+protected:
+ wxString m_filename;
+ gzFile m_gzfp;
+
+public:
+ gzipReader( const wxString& filename )
+ : m_filename( filename )
+ {
+ if( NULL == (m_gzfp = gzopen( m_filename.ToUTF8(), "rb" )) )
+ throw Exception::CannotCreateStream( m_filename, "Cannot open file for reading." );
+
+ gzbuffer(m_gzfp, 0x100000); // 1mb buffer for zlib internal operations
+ }
+
+ virtual ~gzipReader() throw ()
+ {
+ if( m_gzfp ) gzclose( m_gzfp );
+ }
+
+ wxString GetStreamName() const { return m_filename; }
+
+ void Read( void* dest, size_t size )
+ {
+ int result = gzread( m_gzfp, dest, size );
+ if( result == -1)
+ throw Exception::BadStream( m_filename, "Data read failed: Invalid or corrupted gzip archive." );
+
+ if( (size_t)result < size )
+ throw Exception::EndOfStream( m_filename );
+ }
+};
+
+static bool IsSavingOrLoading = false;
+
+
+// --------------------------------------------------------------------------------------
+// SysExecEvent_DownloadState
+// --------------------------------------------------------------------------------------
+// Pauses core emulation and downloads the savestate into the state_buffer.
+//
+class SysExecEvent_DownloadState : public SysExecEvent
+{
+protected:
+ VmStateBuffer* m_dest_buffer;
+
+public:
+ wxString GetEventName() const { return L"VM_Download"; }
+
+ virtual ~SysExecEvent_DownloadState() throw() {}
+ SysExecEvent_DownloadState* Clone() const { return new SysExecEvent_DownloadState( *this ); }
+ SysExecEvent_DownloadState( VmStateBuffer* dest=NULL )
+ {
+ m_dest_buffer = dest;
+ }
+
+ bool IsCriticalEvent() const { return true; }
+ bool AllowCancelOnExit() const { return false; }
+
+protected:
+ void InvokeEvent()
+ {
+ ScopedCoreThreadPause paused_core;
+
+ if( !SysHasValidState() )
+ throw Exception::RuntimeError( L"Cannot complete state freeze request; the virtual machine state is reset.", _("You'll need to start a new virtual machine before you can save its state.") );
+
+ memSavingState(m_dest_buffer).FreezeAll();
+
+ UI_EnableStateActions();
+ paused_core.AllowResume();
+ }
+};
+
+// It's bad mojo to have savestates trying to read and write from the same file at the
+// same time. To prevent that we use this mutex lock, which is used by both the
+// CompressThread and the UnzipFromDisk events. (note that CompressThread locks the
+// mutex during OnStartInThread, which ensures that the ZipToDisk event blocks; preventing
+// the SysExecutor's Idle Event from re-enabing savestates and slots.)
+//
+static Mutex mtx_CompressToDisk;
+
+// --------------------------------------------------------------------------------------
+// CompressThread_VmState
+// --------------------------------------------------------------------------------------
+class VmStateZipThread : public CompressThread_gzip
+{
+ typedef CompressThread_gzip _parent;
+
+protected:
+ ScopedLock m_lock_Compress;
+
+public:
+ VmStateZipThread( const wxString& file, VmStateBuffer* srcdata )
+ : _parent( file, srcdata, SaveStateFile_WriteHeader )
+ {
+ m_lock_Compress.Assign(mtx_CompressToDisk);
+ }
+
+ VmStateZipThread( const wxString& file, ScopedPtr& srcdata )
+ : _parent( file, srcdata, SaveStateFile_WriteHeader )
+ {
+ m_lock_Compress.Assign(mtx_CompressToDisk);
+ }
+
+ virtual ~VmStateZipThread() throw()
+ {
+
+ }
+
+protected:
+ void OnStartInThread()
+ {
+ _parent::OnStartInThread();
+ m_lock_Compress.Acquire();
+ }
+
+ void OnCleanupInThread()
+ {
+ m_lock_Compress.Release();
+ _parent::OnCleanupInThread();
+ }
+};
+
+// --------------------------------------------------------------------------------------
+// SysExecEvent_ZipToDisk
+// --------------------------------------------------------------------------------------
+class SysExecEvent_ZipToDisk : public SysExecEvent
+{
+protected:
+ VmStateBuffer* m_src_buffer;
+ wxString m_filename;
+
+public:
+ wxString GetEventName() const { return L"VM_ZipToDisk"; }
+
+ virtual ~SysExecEvent_ZipToDisk() throw()
+ {
+ delete m_src_buffer;
+ }
+
+ SysExecEvent_ZipToDisk* Clone() const { return new SysExecEvent_ZipToDisk( *this ); }
+
+ SysExecEvent_ZipToDisk( ScopedPtr& src, const wxString& filename )
+ : m_filename( filename )
+ {
+ m_src_buffer = src.DetachPtr();
+ }
+
+ SysExecEvent_ZipToDisk( VmStateBuffer* src, const wxString& filename )
+ : m_filename( filename )
+ {
+ m_src_buffer = src;
+ }
+
+ bool IsCriticalEvent() const { return true; }
+ bool AllowCancelOnExit() const { return false; }
+
+protected:
+ void InvokeEvent()
+ {
+ (new VmStateZipThread( m_filename, m_src_buffer ))->Start();
+ m_src_buffer = NULL;
+ }
+};
+
+// --------------------------------------------------------------------------------------
+// SysExecEvent_UnzipFromDisk
+// --------------------------------------------------------------------------------------
+// Note: Unzipping always goes directly into the SysCoreThread's static VM state, and is
+// always a blocking action on the SysExecutor thread (the system cannot execute other
+// commands while states are unzipping or uploading into the system).
+//
+class SysExecEvent_UnzipFromDisk : public SysExecEvent
+{
+protected:
+ wxString m_filename;
+
+public:
+ wxString GetEventName() const { return L"VM_UnzipFromDisk"; }
+
+ virtual ~SysExecEvent_UnzipFromDisk() throw() {}
+ SysExecEvent_UnzipFromDisk* Clone() const { return new SysExecEvent_UnzipFromDisk( *this ); }
+ SysExecEvent_UnzipFromDisk( const wxString& filename )
+ : m_filename( filename )
+ {
+ }
+
+ wxString GetStreamName() const { return m_filename; }
+
+protected:
+ void InvokeEvent()
+ {
+ ScopedLock lock( mtx_CompressToDisk );
+ gzipReader m_gzreader(m_filename );
+ SaveStateFile_ReadHeader( m_gzreader );
+
+ // We use direct Suspend/Resume control here, since it's desirable that emulation
+ // *ALWAYS* start execution after the new savestate is loaded.
+
+ GetCoreThread().Pause();
+
+ // fixme: should start initially with the file size, and then grow from there.
+
+ static const int BlockSize = 0x100000;
+
+ VmStateBuffer buffer( 0x800000, L"StateBuffer_UnzipFromDisk" ); // start with an 8 meg buffer to avoid frequent reallocation.
+ int curidx = 0;
+
+ try {
+ while(true) {
+ buffer.MakeRoomFor( curidx+BlockSize );
+ m_gzreader.Read( buffer.GetPtr(curidx), BlockSize );
+ curidx += BlockSize;
+ Threading::pxTestCancel();
+ }
+ }
+ catch( Exception::EndOfStream& )
+ {
+ // This exception actually means success! Any others we let get sent
+ // to the main event handler/thread for handling.
+ }
+
+ // Optional shutdown of plugins when loading states? I'm not implementing it yet because some
+ // things, like the SPU2-recovery trick, rely on not resetting the plugins prior to loading
+ // the new savestate data.
+ //if( ShutdownOnStateLoad ) GetCoreThread().Cancel();
+
+
+ GetCoreThread().UploadStateCopy( buffer );
+ GetCoreThread().Resume(); // force resume regardless of emulation state earlier.
+ }
+};
+
+// =====================================================================================================
+// StateCopy Public Interface
+// =====================================================================================================
+
+void StateCopy_SaveToFile( const wxString& file )
+{
+ UI_DisableStateActions();
+
+ ScopedPtr zipbuf(new VmStateBuffer( L"Zippable Savestate" ));
+ GetSysExecutorThread().PostEvent(new SysExecEvent_DownloadState( zipbuf ));
+ GetSysExecutorThread().PostEvent(new SysExecEvent_ZipToDisk( zipbuf, file ));
+}
+
+void StateCopy_LoadFromFile( const wxString& file )
+{
+ UI_DisableSysActions();
+ GetSysExecutorThread().PostEvent(new SysExecEvent_UnzipFromDisk( file ));
+}
+
+// Saves recovery state info to the given saveslot, or saves the active emulation state
+// (if one exists) and no recovery data was found. This is needed because when a recovery
+// state is made, the emulation state is usually reset so the only persisting state is
+// the one in the memory save. :)
+void StateCopy_SaveToSlot( uint num )
+{
+ const wxString file( SaveStateBase::GetFilename( num ) );
+
+ Console.WriteLn( Color_StrongGreen, "Saving savestate to slot %d...", num );
+ Console.Indent().WriteLn( Color_StrongGreen, L"filename: %s", file.c_str() );
+
+ StateCopy_SaveToFile( file );
+}
+
+void StateCopy_LoadFromSlot( uint slot )
+{
+ wxString file( SaveStateBase::GetFilename( slot ) );
+
+ if( !wxFileExists( file ) )
+ {
+ Console.Warning( "Savestate slot %d is empty.", slot );
+ return;
+ }
+
+ Console.WriteLn( Color_StrongGreen, "Loading savestate from slot %d...", slot );
+ Console.Indent().WriteLn( Color_StrongGreen, L"filename: %s", file.c_str() );
+
+ StateCopy_LoadFromFile( file );
+}
diff --git a/pcsx2/gui/UpdateUI.cpp b/pcsx2/gui/UpdateUI.cpp
index e6788042ef..1a15f7373a 100644
--- a/pcsx2/gui/UpdateUI.cpp
+++ b/pcsx2/gui/UpdateUI.cpp
@@ -1,109 +1,109 @@
-/* PCSX2 - PS2 Emulator for PCs
- * Copyright (C) 2002-2010 PCSX2 Dev Team
- *
- * PCSX2 is free software: you can redistribute it and/or modify it under the terms
- * of the GNU Lesser General Public License as published by the Free Software Found-
- * ation, either version 3 of the License, or (at your option) any later version.
- *
- * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with PCSX2.
- * If not, see .
- */
-
-#include "PrecompiledHeader.h"
-#include "MainFrame.h"
-#include "GSFrame.h"
-
-// General Notes:
-// * It's very important that we re-discover menu items by ID every time we change them,
-// because the modern era of configurable GUIs means that we can't be assured the IDs
-// exist anymore.
-
-
-// This is necessary because this stupid wxWidgets 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 )
-{
- sMainFrame.EnableMenuItem( MenuId_Sys_LoadStates, enabled );
- sMainFrame.EnableMenuItem( MenuId_Sys_SaveStates, enabled );
-}
-
-// Updates the enable/disable status of all System related controls: menus, toolbars,
-// etc. Typically called by SysEvtHandler whenever the message pump becomes idle.
-void UI_UpdateSysControls()
-{
- if( wxGetApp().PostMethodMyself( &UI_UpdateSysControls ) ) return;
-
- sApp.PostAction( CoreThreadStatusEvent( CoreThread_Indeterminate ) );
-
- _SaveLoadStuff( true );
-}
-
-void UI_DisableSysReset()
-{
- if( wxGetApp().PostMethodMyself( UI_DisableSysReset ) ) return;
- sMainFrame.EnableMenuItem( MenuId_Sys_Restart, false );
-
- _SaveLoadStuff( false );
-}
-
-void UI_DisableSysShutdown()
-{
- if( wxGetApp().PostMethodMyself( &UI_DisableSysShutdown ) ) return;
-
- sMainFrame.EnableMenuItem( MenuId_Sys_Restart, false );
- sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, false );
-}
-
-void UI_EnableSysShutdown()
-{
- if( wxGetApp().PostMethodMyself( &UI_EnableSysShutdown ) ) return;
-
- sMainFrame.EnableMenuItem( MenuId_Sys_Restart, true );
- sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, true );
-}
-
-
-void UI_DisableSysActions()
-{
- if( wxGetApp().PostMethodMyself( &UI_DisableSysActions ) ) return;
-
- sMainFrame.EnableMenuItem( MenuId_Sys_Restart, false );
- sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, false );
-
- _SaveLoadStuff( false );
-}
-
-void UI_EnableSysActions()
-{
- if( wxGetApp().PostMethodMyself( &UI_EnableSysActions ) ) return;
-
- sMainFrame.EnableMenuItem( MenuId_Sys_Restart, true );
- sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, true );
-
- _SaveLoadStuff( true );
-}
-
-void UI_DisableStateActions()
-{
- if( wxGetApp().PostMethodMyself( &UI_DisableStateActions ) ) return;
- _SaveLoadStuff( false );
-}
-
-void UI_EnableStateActions()
-{
- if( wxGetApp().PostMethodMyself( &UI_EnableStateActions ) ) return;
- _SaveLoadStuff( true );
-}
-
-
+/* PCSX2 - PS2 Emulator for PCs
+ * Copyright (C) 2002-2010 PCSX2 Dev Team
+ *
+ * PCSX2 is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU Lesser General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with PCSX2.
+ * If not, see .
+ */
+
+#include "PrecompiledHeader.h"
+#include "MainFrame.h"
+#include "GSFrame.h"
+
+// General Notes:
+// * It's very important that we re-discover menu items by ID every time we change them,
+// because the modern era of configurable GUIs means that we can't be assured the IDs
+// exist anymore.
+
+
+// This is necessary because this stupid wxWidgets 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 )
+{
+ sMainFrame.EnableMenuItem( MenuId_Sys_LoadStates, enabled );
+ sMainFrame.EnableMenuItem( MenuId_Sys_SaveStates, enabled );
+}
+
+// Updates the enable/disable status of all System related controls: menus, toolbars,
+// etc. Typically called by SysEvtHandler whenever the message pump becomes idle.
+void UI_UpdateSysControls()
+{
+ if( wxGetApp().PostMethodMyself( &UI_UpdateSysControls ) ) return;
+
+ sApp.PostAction( CoreThreadStatusEvent( CoreThread_Indeterminate ) );
+
+ _SaveLoadStuff( true );
+}
+
+void UI_DisableSysReset()
+{
+ if( wxGetApp().PostMethodMyself( UI_DisableSysReset ) ) return;
+ sMainFrame.EnableMenuItem( MenuId_Sys_Restart, false );
+
+ _SaveLoadStuff( false );
+}
+
+void UI_DisableSysShutdown()
+{
+ if( wxGetApp().PostMethodMyself( &UI_DisableSysShutdown ) ) return;
+
+ sMainFrame.EnableMenuItem( MenuId_Sys_Restart, false );
+ sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, false );
+}
+
+void UI_EnableSysShutdown()
+{
+ if( wxGetApp().PostMethodMyself( &UI_EnableSysShutdown ) ) return;
+
+ sMainFrame.EnableMenuItem( MenuId_Sys_Restart, true );
+ sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, true );
+}
+
+
+void UI_DisableSysActions()
+{
+ if( wxGetApp().PostMethodMyself( &UI_DisableSysActions ) ) return;
+
+ sMainFrame.EnableMenuItem( MenuId_Sys_Restart, false );
+ sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, false );
+
+ _SaveLoadStuff( false );
+}
+
+void UI_EnableSysActions()
+{
+ if( wxGetApp().PostMethodMyself( &UI_EnableSysActions ) ) return;
+
+ sMainFrame.EnableMenuItem( MenuId_Sys_Restart, true );
+ sMainFrame.EnableMenuItem( MenuId_Sys_Shutdown, true );
+
+ _SaveLoadStuff( true );
+}
+
+void UI_DisableStateActions()
+{
+ if( wxGetApp().PostMethodMyself( &UI_DisableStateActions ) ) return;
+ _SaveLoadStuff( false );
+}
+
+void UI_EnableStateActions()
+{
+ if( wxGetApp().PostMethodMyself( &UI_EnableStateActions ) ) return;
+ _SaveLoadStuff( true );
+}
+
+
diff --git a/pcsx2/gui/pxEventThread.h b/pcsx2/gui/pxEventThread.h
index fb3d394a00..40ad185d40 100644
--- a/pcsx2/gui/pxEventThread.h
+++ b/pcsx2/gui/pxEventThread.h
@@ -1,237 +1,237 @@
-/* PCSX2 - PS2 Emulator for PCs
- * Copyright (C) 2002-2010 PCSX2 Dev Team
- *
- * PCSX2 is free software: you can redistribute it and/or modify it under the terms
- * of the GNU Lesser General Public License as published by the Free Software Found-
- * ation, either version 3 of the License, or (at your option) any later version.
- *
- * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with PCSX2.
- * If not, see .
- */
-
-#pragma once
-
-#include "Utilities/PersistentThread.h"
-#include "Utilities/pxEvents.h"
-
-// TODO!! Make this system a bit more generic, and then move it to the Utilities library.
-
-// --------------------------------------------------------------------------------------
-// SysExecEvent
-// --------------------------------------------------------------------------------------
-// Base class for all pxEvtHandler processable events.
-//
-// Rules for deriving:
-// * Override InvokeEvent(), *NOT* _DoInvokeEvent(). _DoInvokeEvent() performs setup and
-// wraps exceptions for transport to the invoking context/thread, and then itself calls
-// InvokeEvent() to perform the derived class implementation.
-//
-// * Derived classes must implement their own versions of an empty constructor and
-// Clone(), or else the class will fail to be copied to the event handler's thread
-// context correctly.
-//
-// * This class is not abstract, and gives no error if the invocation method is not
-// overridden: It can be used as a simple ping device against the event queue, Re-
-// awaking the invoking thread as soon as the queue has caught up to and processed
-// the event.
-//
-// * Avoid using virtual class inheritence. It's unreliable at best.
-//
-class SysExecEvent : public ICloneable
-{
-protected:
- SynchronousActionState* m_sync;
-
-public:
- virtual ~SysExecEvent() throw() {}
- SysExecEvent* Clone() const { return new SysExecEvent( *this ); }
-
- SysExecEvent( SynchronousActionState* sync=NULL )
- {
- m_sync = sync;
- }
-
- SysExecEvent( SynchronousActionState& sync )
- {
- m_sync = &sync;
- }
-
- const SynchronousActionState* GetSyncState() const { return m_sync; }
- SynchronousActionState* GetSyncState() { return m_sync; }
-
- SysExecEvent& SetSyncState( SynchronousActionState* obj ) { m_sync = obj; return *this; }
- SysExecEvent& SetSyncState( SynchronousActionState& obj ) { m_sync = &obj; return *this; }
-
- // Tells the Event Handler whether or not this event can be skipped when the system
- // is being quit or reset. Typically set this to true for events which shut down the
- // system, since program crashes can occur if the program tries to exit while threads
- // are running.
- virtual bool IsCriticalEvent() const { return false; }
-
- // Tells the Event Handler whether or not this event can be canceled. Typically events
- // should not prohibit cancellation, since it expedites program termination and helps
- // avoid permanent deadlock. Some actions like saving states and shutdown procedures
- // should not allow cancellation since they could result in program crashes or corrupted
- // data.
- virtual bool AllowCancelOnExit() const { return true; }
-
- virtual void _DoInvokeEvent();
- virtual void PostResult() const;
-
- virtual wxString GetEventName() const;
- virtual wxString GetEventMessage() const;
-
- virtual int GetResult()
- {
- if( !pxAssertDev( m_sync != NULL, "SysEvent: Expecting return value, but no sync object provided." ) ) return 0;
- return m_sync->return_value;
- }
-
- virtual void SetException( BaseException* ex );
-
- void SetException( const BaseException& ex );
-
-protected:
- virtual void InvokeEvent();
- virtual void CleanupEvent();
-};
-
-// --------------------------------------------------------------------------------------
-// SysExecEvent_MethodVoid
-// --------------------------------------------------------------------------------------
-class SysExecEvent_MethodVoid : public SysExecEvent
-{
-protected:
- FnType_Void* m_method;
-
-public:
- wxString GetEventName() const { return L"MethodVoid"; }
-
- virtual ~SysExecEvent_MethodVoid() throw() {}
- SysExecEvent_MethodVoid* Clone() const { return new SysExecEvent_MethodVoid( *this ); }
-
- explicit SysExecEvent_MethodVoid( FnType_Void* method = NULL )
- {
- m_method = method;
- }
-
-protected:
- void InvokeEvent()
- {
- if( m_method ) m_method();
- }
-};
-
-
-typedef std::list pxEvtList;
-
-// --------------------------------------------------------------------------------------
-// pxEvtHandler
-// --------------------------------------------------------------------------------------
-// Purpose: To provide a safe environment for queuing tasks that must be executed in
-// sequential order (in blocking fashion). Unlike the wxWidgets event handlers, instances
-// of this handler can be stalled for extended periods of time without affecting the
-// responsiveness of the GUI or frame updates of the DirectX output windows. This class
-// is mostly intended to be used from the context of an ExecutorThread.
-//
-// Rationales:
-// * Using the main event handler of wxWidgets is dangerous because it must call itself
-// recursively when waiting on threaded events such as semaphore and mutexes. Thus,
-// tasks such as suspending the VM would invoke the event queue while waiting,
-// running events that expect the suspend to be complete while the suspend was still
-// pending.
-//
-// * wxWidgets Event Queue (wxEvtHandler) isn't thread-safe and isn't even
-// intended for use for anything other than wxWindow events (it uses static vars
-// and checks/modifies wxApp globals while processing), so it's useless to us.
-// Have to roll our own. -_-
-//
-class pxEvtHandler
-{
-protected:
- pxEvtList m_pendingEvents;
- pxEvtList m_idleEvents;
-
- Threading::MutexRecursive m_mtx_pending;
- Threading::Semaphore m_wakeup;
- wxThreadIdType m_OwnerThreadId;
- volatile u32 m_Quitting;
-
- // Used for performance measuring the execution of individual events,
- // and also for detecting deadlocks during message processing.
- volatile u64 m_qpc_Start;
-
-public:
- pxEvtHandler();
- virtual ~pxEvtHandler() throw() {}
-
- virtual wxString GetEventHandlerName() const { return L"pxEvtHandler"; }
-
- virtual void ShutdownQueue();
- bool IsShuttingDown() const { return !!m_Quitting; }
-
- void ProcessEvents( pxEvtList& list );
- void ProcessPendingEvents();
- void ProcessIdleEvents();
- void Idle();
-
- void AddPendingEvent( SysExecEvent& evt );
- void PostEvent( SysExecEvent* evt );
- void PostEvent( const SysExecEvent& evt );
- void PostIdleEvent( SysExecEvent* evt );
- void PostIdleEvent( const SysExecEvent& evt );
-
- void ProcessEvent( SysExecEvent* evt );
- void ProcessEvent( SysExecEvent& evt );
-
- bool ProcessMethodSelf( FnType_Void* method );
- void SetActiveThread();
-
-protected:
- virtual void _DoIdle() {}
-};
-
-// --------------------------------------------------------------------------------------
-// ExecutorThread
-// --------------------------------------------------------------------------------------
-// Threaded wrapper class for implementing pxEvtHandler. Simply create the desired
-// EvtHandler, start the thread, and enjoy queued event execution in fully blocking fashion.
-//
-class ExecutorThread : public Threading::PersistentThread
-{
- typedef Threading::PersistentThread _parent;
-
-protected:
- ScopedPtr m_ExecutorTimer;
- ScopedPtr m_EvtHandler;
-
-public:
- ExecutorThread( pxEvtHandler* evtandler = NULL );
- virtual ~ExecutorThread() throw() { }
-
- virtual void ShutdownQueue();
-
- void PostEvent( SysExecEvent* evt );
- void PostEvent( const SysExecEvent& evt );
-
- void PostIdleEvent( SysExecEvent* evt );
- void PostIdleEvent( const SysExecEvent& evt );
-
- void ProcessEvent( SysExecEvent* evt );
- void ProcessEvent( SysExecEvent& evt );
-
- bool ProcessMethodSelf( void (*evt)() )
- {
- return m_EvtHandler ? m_EvtHandler->ProcessMethodSelf( evt ) : false;
- }
-
-protected:
- void OnStart();
- void ExecuteTaskInThread();
- void OnCleanupInThread();
-};
-
+/* PCSX2 - PS2 Emulator for PCs
+ * Copyright (C) 2002-2010 PCSX2 Dev Team
+ *
+ * PCSX2 is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU Lesser General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with PCSX2.
+ * If not, see .
+ */
+
+#pragma once
+
+#include "Utilities/PersistentThread.h"
+#include "Utilities/pxEvents.h"
+
+// TODO!! Make this system a bit more generic, and then move it to the Utilities library.
+
+// --------------------------------------------------------------------------------------
+// SysExecEvent
+// --------------------------------------------------------------------------------------
+// Base class for all pxEvtHandler processable events.
+//
+// Rules for deriving:
+// * Override InvokeEvent(), *NOT* _DoInvokeEvent(). _DoInvokeEvent() performs setup and
+// wraps exceptions for transport to the invoking context/thread, and then itself calls
+// InvokeEvent() to perform the derived class implementation.
+//
+// * Derived classes must implement their own versions of an empty constructor and
+// Clone(), or else the class will fail to be copied to the event handler's thread
+// context correctly.
+//
+// * This class is not abstract, and gives no error if the invocation method is not
+// overridden: It can be used as a simple ping device against the event queue, Re-
+// awaking the invoking thread as soon as the queue has caught up to and processed
+// the event.
+//
+// * Avoid using virtual class inheritence. It's unreliable at best.
+//
+class SysExecEvent : public ICloneable
+{
+protected:
+ SynchronousActionState* m_sync;
+
+public:
+ virtual ~SysExecEvent() throw() {}
+ SysExecEvent* Clone() const { return new SysExecEvent( *this ); }
+
+ SysExecEvent( SynchronousActionState* sync=NULL )
+ {
+ m_sync = sync;
+ }
+
+ SysExecEvent( SynchronousActionState& sync )
+ {
+ m_sync = &sync;
+ }
+
+ const SynchronousActionState* GetSyncState() const { return m_sync; }
+ SynchronousActionState* GetSyncState() { return m_sync; }
+
+ SysExecEvent& SetSyncState( SynchronousActionState* obj ) { m_sync = obj; return *this; }
+ SysExecEvent& SetSyncState( SynchronousActionState& obj ) { m_sync = &obj; return *this; }
+
+ // Tells the Event Handler whether or not this event can be skipped when the system
+ // is being quit or reset. Typically set this to true for events which shut down the
+ // system, since program crashes can occur if the program tries to exit while threads
+ // are running.
+ virtual bool IsCriticalEvent() const { return false; }
+
+ // Tells the Event Handler whether or not this event can be canceled. Typically events
+ // should not prohibit cancellation, since it expedites program termination and helps
+ // avoid permanent deadlock. Some actions like saving states and shutdown procedures
+ // should not allow cancellation since they could result in program crashes or corrupted
+ // data.
+ virtual bool AllowCancelOnExit() const { return true; }
+
+ virtual void _DoInvokeEvent();
+ virtual void PostResult() const;
+
+ virtual wxString GetEventName() const;
+ virtual wxString GetEventMessage() const;
+
+ virtual int GetResult()
+ {
+ if( !pxAssertDev( m_sync != NULL, "SysEvent: Expecting return value, but no sync object provided." ) ) return 0;
+ return m_sync->return_value;
+ }
+
+ virtual void SetException( BaseException* ex );
+
+ void SetException( const BaseException& ex );
+
+protected:
+ virtual void InvokeEvent();
+ virtual void CleanupEvent();
+};
+
+// --------------------------------------------------------------------------------------
+// SysExecEvent_MethodVoid
+// --------------------------------------------------------------------------------------
+class SysExecEvent_MethodVoid : public SysExecEvent
+{
+protected:
+ FnType_Void* m_method;
+
+public:
+ wxString GetEventName() const { return L"MethodVoid"; }
+
+ virtual ~SysExecEvent_MethodVoid() throw() {}
+ SysExecEvent_MethodVoid* Clone() const { return new SysExecEvent_MethodVoid( *this ); }
+
+ explicit SysExecEvent_MethodVoid( FnType_Void* method = NULL )
+ {
+ m_method = method;
+ }
+
+protected:
+ void InvokeEvent()
+ {
+ if( m_method ) m_method();
+ }
+};
+
+
+typedef std::list pxEvtList;
+
+// --------------------------------------------------------------------------------------
+// pxEvtHandler
+// --------------------------------------------------------------------------------------
+// Purpose: To provide a safe environment for queuing tasks that must be executed in
+// sequential order (in blocking fashion). Unlike the wxWidgets event handlers, instances
+// of this handler can be stalled for extended periods of time without affecting the
+// responsiveness of the GUI or frame updates of the DirectX output windows. This class
+// is mostly intended to be used from the context of an ExecutorThread.
+//
+// Rationales:
+// * Using the main event handler of wxWidgets is dangerous because it must call itself
+// recursively when waiting on threaded events such as semaphore and mutexes. Thus,
+// tasks such as suspending the VM would invoke the event queue while waiting,
+// running events that expect the suspend to be complete while the suspend was still
+// pending.
+//
+// * wxWidgets Event Queue (wxEvtHandler) isn't thread-safe and isn't even
+// intended for use for anything other than wxWindow events (it uses static vars
+// and checks/modifies wxApp globals while processing), so it's useless to us.
+// Have to roll our own. -_-
+//
+class pxEvtHandler
+{
+protected:
+ pxEvtList m_pendingEvents;
+ pxEvtList m_idleEvents;
+
+ Threading::MutexRecursive m_mtx_pending;
+ Threading::Semaphore m_wakeup;
+ wxThreadIdType m_OwnerThreadId;
+ volatile u32 m_Quitting;
+
+ // Used for performance measuring the execution of individual events,
+ // and also for detecting deadlocks during message processing.
+ volatile u64 m_qpc_Start;
+
+public:
+ pxEvtHandler();
+ virtual ~pxEvtHandler() throw() {}
+
+ virtual wxString GetEventHandlerName() const { return L"pxEvtHandler"; }
+
+ virtual void ShutdownQueue();
+ bool IsShuttingDown() const { return !!m_Quitting; }
+
+ void ProcessEvents( pxEvtList& list );
+ void ProcessPendingEvents();
+ void ProcessIdleEvents();
+ void Idle();
+
+ void AddPendingEvent( SysExecEvent& evt );
+ void PostEvent( SysExecEvent* evt );
+ void PostEvent( const SysExecEvent& evt );
+ void PostIdleEvent( SysExecEvent* evt );
+ void PostIdleEvent( const SysExecEvent& evt );
+
+ void ProcessEvent( SysExecEvent* evt );
+ void ProcessEvent( SysExecEvent& evt );
+
+ bool ProcessMethodSelf( FnType_Void* method );
+ void SetActiveThread();
+
+protected:
+ virtual void _DoIdle() {}
+};
+
+// --------------------------------------------------------------------------------------
+// ExecutorThread
+// --------------------------------------------------------------------------------------
+// Threaded wrapper class for implementing pxEvtHandler. Simply create the desired
+// EvtHandler, start the thread, and enjoy queued event execution in fully blocking fashion.
+//
+class ExecutorThread : public Threading::PersistentThread
+{
+ typedef Threading::PersistentThread _parent;
+
+protected:
+ ScopedPtr m_ExecutorTimer;
+ ScopedPtr m_EvtHandler;
+
+public:
+ ExecutorThread( pxEvtHandler* evtandler = NULL );
+ virtual ~ExecutorThread() throw() { }
+
+ virtual void ShutdownQueue();
+
+ void PostEvent( SysExecEvent* evt );
+ void PostEvent( const SysExecEvent& evt );
+
+ void PostIdleEvent( SysExecEvent* evt );
+ void PostIdleEvent( const SysExecEvent& evt );
+
+ void ProcessEvent( SysExecEvent* evt );
+ void ProcessEvent( SysExecEvent& evt );
+
+ bool ProcessMethodSelf( void (*evt)() )
+ {
+ return m_EvtHandler ? m_EvtHandler->ProcessMethodSelf( evt ) : false;
+ }
+
+protected:
+ void OnStart();
+ void ExecuteTaskInThread();
+ void OnCleanupInThread();
+};
+