mirror of https://github.com/PCSX2/pcsx2.git
wxgui:
* Fixed thread classing so that detached pthreeads are handled safely, and so that virtual functions in C++ destructors are explicitly specified. * Added some helper functions to Pcsx2App for safely executing menu commands form any thread in the emu. * Fixed several minor bugs in settings / config handling. git-svn-id: http://pcsx2.googlecode.com/svn/branches/wxgui@1730 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
ee97290cd2
commit
64e43a9086
|
@ -109,8 +109,8 @@ namespace Threading
|
||||||
// derived class if your thread utilizes the post).
|
// derived class if your thread utilizes the post).
|
||||||
//
|
//
|
||||||
// Notes:
|
// Notes:
|
||||||
// * Constructing threads as static vars isn't recommended since it can potentially con-
|
// * Constructing threads as static global vars isn't recommended since it can potentially
|
||||||
// fuse w32pthreads, if the static initializers are executed out-of-order (C++ offers
|
// confuse w32pthreads, if the static initializers are executed out-of-order (C++ offers
|
||||||
// no dependency options for ensuring correct static var initializations). Use heap
|
// no dependency options for ensuring correct static var initializations). Use heap
|
||||||
// allocation to create thread objects instead.
|
// allocation to create thread objects instead.
|
||||||
//
|
//
|
||||||
|
@ -121,10 +121,11 @@ namespace Threading
|
||||||
protected:
|
protected:
|
||||||
typedef int (*PlainJoeFP)();
|
typedef int (*PlainJoeFP)();
|
||||||
pthread_t m_thread;
|
pthread_t m_thread;
|
||||||
|
Semaphore m_sem_event; // general wait event that's needed by most threads.
|
||||||
sptr m_returncode; // value returned from the thread on close.
|
sptr m_returncode; // value returned from the thread on close.
|
||||||
|
|
||||||
bool m_running;
|
volatile long m_detached; // a boolean value which indicates if the m_thread handle is valid
|
||||||
Semaphore m_sem_event; // general wait event that's needed by most threads.
|
volatile long m_running; // set true by Start(), and set false by Cancel(), Block(), etc.
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~PersistentThread();
|
virtual ~PersistentThread();
|
||||||
|
@ -132,6 +133,7 @@ namespace Threading
|
||||||
|
|
||||||
virtual void Start();
|
virtual void Start();
|
||||||
virtual void Cancel( bool isBlocking = true );
|
virtual void Cancel( bool isBlocking = true );
|
||||||
|
virtual void Detach();
|
||||||
|
|
||||||
// Gets the return code of the thread.
|
// Gets the return code of the thread.
|
||||||
// Throws std::logic_error if the thread has not terminated.
|
// Throws std::logic_error if the thread has not terminated.
|
||||||
|
@ -142,6 +144,8 @@ namespace Threading
|
||||||
|
|
||||||
bool IsSelf() const;
|
bool IsSelf() const;
|
||||||
|
|
||||||
|
virtual void DoThreadCleanup();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Used to dispatch the thread callback function.
|
// Used to dispatch the thread callback function.
|
||||||
// (handles some thread cleanup on Win32, and is basically a typecast
|
// (handles some thread cleanup on Win32, and is basically a typecast
|
||||||
|
@ -150,14 +154,6 @@ namespace Threading
|
||||||
|
|
||||||
// Implemented by derived class to handle threading actions!
|
// Implemented by derived class to handle threading actions!
|
||||||
virtual sptr ExecuteTask()=0;
|
virtual sptr ExecuteTask()=0;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Static Methods (PersistentThread)
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
public:
|
|
||||||
// performs a test on the given thread handle, returning true if the thread exists
|
|
||||||
// or false if the thread is dead/done/never existed.
|
|
||||||
static bool Exists( pthread_t pid );
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -29,22 +29,40 @@ using namespace Threading;
|
||||||
|
|
||||||
namespace Threading
|
namespace Threading
|
||||||
{
|
{
|
||||||
|
static void _pt_callback_cleanup( void* handle )
|
||||||
|
{
|
||||||
|
((PersistentThread*)handle)->DoThreadCleanup();
|
||||||
|
}
|
||||||
|
|
||||||
PersistentThread::PersistentThread() :
|
PersistentThread::PersistentThread() :
|
||||||
m_thread()
|
m_thread()
|
||||||
, m_returncode( 0 )
|
|
||||||
, m_running( false )
|
|
||||||
, m_sem_event()
|
, m_sem_event()
|
||||||
|
, m_returncode( 0 )
|
||||||
|
, m_detached( false )
|
||||||
|
, m_running( false )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform a blocking termination of the thread, to ensure full object cleanup.
|
// This destructor performs basic "last chance" cleanup, which is a blocking
|
||||||
|
// join against non-detached threads. Detached threads are unhandled.
|
||||||
|
// Extending classes should always implement their own thread closure process.
|
||||||
|
// This class must not be deleted from its own thread. That would be like marrying
|
||||||
|
// your sister, and then cheating on her with your daughter.
|
||||||
PersistentThread::~PersistentThread()
|
PersistentThread::~PersistentThread()
|
||||||
{
|
{
|
||||||
Cancel( false );
|
wxASSERT( !IsSelf() ); // not allowed from our own thread.
|
||||||
|
|
||||||
|
if( !_InterlockedExchange( &m_detached, true ) )
|
||||||
|
{
|
||||||
|
pthread_join( m_thread, (void**)&m_returncode );
|
||||||
|
m_running = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function should not be called from the owner thread.
|
||||||
void PersistentThread::Start()
|
void PersistentThread::Start()
|
||||||
{
|
{
|
||||||
|
wxASSERT( !IsSelf() ); // not allowed from our own thread.
|
||||||
if( m_running ) return;
|
if( m_running ) return;
|
||||||
|
|
||||||
if( pthread_create( &m_thread, NULL, _internal_callback, this ) != 0 )
|
if( pthread_create( &m_thread, NULL, _internal_callback, this ) != 0 )
|
||||||
|
@ -53,26 +71,43 @@ namespace Threading
|
||||||
m_running = true;
|
m_running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function should not be called from the owner thread.
|
||||||
|
void PersistentThread::Detach()
|
||||||
|
{
|
||||||
|
wxASSERT( !IsSelf() ); // not allowed from our own thread.
|
||||||
|
if( _InterlockedExchange( &m_detached, true ) ) return;
|
||||||
|
pthread_detach( m_thread );
|
||||||
|
}
|
||||||
|
|
||||||
// Remarks:
|
// Remarks:
|
||||||
// Provision of non-blocking Cancel() is probably academic, since destroying a PersistentThread
|
// Provision of non-blocking Cancel() is probably academic, since destroying a PersistentThread
|
||||||
// object performs a blocking Cancel regardless of if you explicitly do a non-blocking Cancel()
|
// object performs a blocking Cancel regardless of if you explicitly do a non-blocking Cancel()
|
||||||
// prior, since the ExecuteTask() method requires a valid object state. If you really need
|
// prior, since the ExecuteTask() method requires a valid object state. If you really need
|
||||||
// fire-and-forget behavior on threads, use pthreads directly for now.
|
// fire-and-forget behavior on threads, use pthreads directly for now.
|
||||||
// (TODO : make a DetachedThread class?)
|
//
|
||||||
|
// This function should not be called from the owner thread.
|
||||||
//
|
//
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// isBlocking - indicates if the Cancel action should block for thread completion or not.
|
// isBlocking - indicates if the Cancel action should block for thread completion or not.
|
||||||
//
|
//
|
||||||
void PersistentThread::Cancel( bool isBlocking )
|
void PersistentThread::Cancel( bool isBlocking )
|
||||||
{
|
{
|
||||||
if( !m_running ) return;
|
wxASSERT( !IsSelf() );
|
||||||
m_running = false;
|
if( _InterlockedExchange( &m_detached, true ) )
|
||||||
|
{
|
||||||
|
if( m_running )
|
||||||
|
Console::Notice( "Threading Warning: Attempted to cancel detached thread; Ignoring..." );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
pthread_cancel( m_thread );
|
pthread_cancel( m_thread );
|
||||||
|
|
||||||
if( isBlocking )
|
if( isBlocking )
|
||||||
pthread_join( m_thread, (void**)&m_returncode );
|
pthread_join( m_thread, (void**)&m_returncode );
|
||||||
else
|
else
|
||||||
pthread_detach( m_thread );
|
pthread_detach( m_thread );
|
||||||
|
|
||||||
|
m_running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blocks execution of the calling thread until this thread completes its task. The
|
// Blocks execution of the calling thread until this thread completes its task. The
|
||||||
|
@ -85,11 +120,21 @@ namespace Threading
|
||||||
//
|
//
|
||||||
sptr PersistentThread::Block()
|
sptr PersistentThread::Block()
|
||||||
{
|
{
|
||||||
bool isOwner = (pthread_self() == m_thread);
|
DevAssert( !IsSelf(), "Thread deadlock detected; Block() should never be called by the owner thread." );
|
||||||
DevAssert( !isOwner, "Thread deadlock detected; Block() should never be called by the owner thread." );
|
|
||||||
|
|
||||||
pthread_join( m_thread, (void**)&m_returncode );
|
if( _InterlockedExchange( &m_detached, true ) )
|
||||||
return m_returncode;
|
{
|
||||||
|
// already detached: if we're still running then its an invalid operation
|
||||||
|
if( m_running )
|
||||||
|
throw Exception::InvalidOperation( "Blocking on detached threads requires manual semaphore implementation." );
|
||||||
|
|
||||||
|
return m_returncode;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pthread_join( m_thread, (void**)&m_returncode );
|
||||||
|
return m_returncode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PersistentThread::IsSelf() const
|
bool PersistentThread::IsSelf() const
|
||||||
|
@ -97,15 +142,12 @@ namespace Threading
|
||||||
return pthread_self() == m_thread;
|
return pthread_self() == m_thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PersistentThread::Exists( pthread_t pid )
|
|
||||||
{
|
|
||||||
// passing 0 to pthread_kill is a NOP, and returns the status of the thread only.
|
|
||||||
return ( ESRCH != pthread_kill( pid, 0 ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PersistentThread::IsRunning() const
|
bool PersistentThread::IsRunning() const
|
||||||
{
|
{
|
||||||
return ( m_running && (ESRCH != pthread_kill( m_thread, 0 )) );
|
if( !!m_detached )
|
||||||
|
return !!m_running;
|
||||||
|
else
|
||||||
|
return ( ESRCH != pthread_kill( m_thread, 0 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exceptions:
|
// Exceptions:
|
||||||
|
@ -113,21 +155,28 @@ namespace Threading
|
||||||
//
|
//
|
||||||
sptr PersistentThread::GetReturnCode() const
|
sptr PersistentThread::GetReturnCode() const
|
||||||
{
|
{
|
||||||
if( !m_running )
|
|
||||||
throw Exception::InvalidOperation( "Thread.GetReturnCode : thread has not been started." );
|
|
||||||
|
|
||||||
if( IsRunning() )
|
if( IsRunning() )
|
||||||
throw Exception::InvalidOperation( "Thread.GetReturnCode : thread is still running." );
|
throw Exception::InvalidOperation( "Thread.GetReturnCode : thread is still running." );
|
||||||
|
|
||||||
return m_returncode;
|
return m_returncode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// invoked when canceling or exiting the thread.
|
||||||
|
void PersistentThread::DoThreadCleanup()
|
||||||
|
{
|
||||||
|
wxASSERT( IsSelf() ); // only allowed from our own thread, thanks.
|
||||||
|
_InterlockedExchange( &m_running, false );
|
||||||
|
}
|
||||||
|
|
||||||
void* PersistentThread::_internal_callback( void* itsme )
|
void* PersistentThread::_internal_callback( void* itsme )
|
||||||
{
|
{
|
||||||
jASSUME( itsme != NULL );
|
jASSUME( itsme != NULL );
|
||||||
|
|
||||||
PersistentThread& owner = *((PersistentThread*)itsme);
|
PersistentThread& owner = *((PersistentThread*)itsme);
|
||||||
|
|
||||||
|
pthread_cleanup_push( _pt_callback_cleanup, itsme );
|
||||||
owner.m_returncode = owner.ExecuteTask();
|
owner.m_returncode = owner.ExecuteTask();
|
||||||
|
pthread_cleanup_pop( true );
|
||||||
|
|
||||||
return (void*)owner.m_returncode;
|
return (void*)owner.m_returncode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -219,7 +219,7 @@ void mtgsThreadObject::Start()
|
||||||
|
|
||||||
mtgsThreadObject::~mtgsThreadObject()
|
mtgsThreadObject::~mtgsThreadObject()
|
||||||
{
|
{
|
||||||
Cancel();
|
mtgsThreadObject::Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void mtgsThreadObject::Cancel()
|
void mtgsThreadObject::Cancel()
|
||||||
|
|
|
@ -704,8 +704,9 @@ static bool OpenPlugin_GS()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( mtgsThread->IsSelf() )
|
if( !mtgsThread->IsSelf() ) return true; // already opened?
|
||||||
return !GSopen( (void*)&pDsp, "PCSX2", renderswitch ? 2 : 1 );
|
|
||||||
|
return !GSopen( (void*)&pDsp, "PCSX2", renderswitch ? 2 : 1 );
|
||||||
|
|
||||||
// Note: rederswitch is us abusing the isMultiThread parameter for that so
|
// Note: rederswitch is us abusing the isMultiThread parameter for that so
|
||||||
// we don't need a new callback
|
// we don't need a new callback
|
||||||
|
|
|
@ -110,6 +110,6 @@ namespace Msgbox
|
||||||
}
|
}
|
||||||
|
|
||||||
BEGIN_DECLARE_EVENT_TYPES()
|
BEGIN_DECLARE_EVENT_TYPES()
|
||||||
DECLARE_EVENT_TYPE( pxEVT_MSGBOX, -1 );
|
DECLARE_EVENT_TYPE( pxEVT_MSGBOX, -1 )
|
||||||
DECLARE_EVENT_TYPE( pxEVT_CallStackBox, -1 );
|
DECLARE_EVENT_TYPE( pxEVT_CallStackBox, -1 )
|
||||||
END_DECLARE_EVENT_TYPES()
|
END_DECLARE_EVENT_TYPES()
|
||||||
|
|
102
pcsx2/gui/App.h
102
pcsx2/gui/App.h
|
@ -32,6 +32,89 @@
|
||||||
|
|
||||||
class IniInterface;
|
class IniInterface;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// All Menu Options for the Main Window! :D
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
enum MenuIdentifiers
|
||||||
|
{
|
||||||
|
// Main Menu Section
|
||||||
|
Menu_Run = 1,
|
||||||
|
Menu_Config, // General config, plus non audio/video plugins.
|
||||||
|
Menu_Video, // Video options filled in by GS plugin
|
||||||
|
Menu_Audio, // audio options filled in by SPU2 plugin
|
||||||
|
Menu_Misc, // Misc options and help!
|
||||||
|
|
||||||
|
// Run SubSection
|
||||||
|
Menu_RunIso = 20, // Opens submenu with Iso browser, and recent isos.
|
||||||
|
Menu_IsoBrowse, // Open dialog, runs selected iso.
|
||||||
|
Menu_BootCDVD, // opens a submenu filled by CDVD plugin (usually list of drives)
|
||||||
|
Menu_RunWithoutDisc, // used to enter the bios (subs in cdvdnull)
|
||||||
|
Menu_RunELF,
|
||||||
|
Menu_SkipBiosToggle, // enables the Bios Skip speedhack
|
||||||
|
Menu_EnableSkipBios, // check marked menu that toggles Skip Bios boot feature.
|
||||||
|
Menu_PauseExec, // suspends/resumes active emulation
|
||||||
|
Menu_Reset, // Issues a complete reset.
|
||||||
|
Menu_States, // Opens states submenu
|
||||||
|
Menu_Run_Exit = wxID_EXIT,
|
||||||
|
|
||||||
|
Menu_State_Load = 40,
|
||||||
|
Menu_State_LoadOther,
|
||||||
|
Menu_State_Load01, // first of many load slots
|
||||||
|
Menu_State_Save = 60,
|
||||||
|
Menu_State_SaveOther,
|
||||||
|
Menu_State_Save01, // first of many save slots
|
||||||
|
|
||||||
|
// Config Subsection
|
||||||
|
Menu_Config_Settings = 100,
|
||||||
|
Menu_Config_BIOS,
|
||||||
|
Menu_Config_CDVD,
|
||||||
|
Menu_Config_DEV9,
|
||||||
|
Menu_Config_USB,
|
||||||
|
Menu_Config_FireWire,
|
||||||
|
Menu_Config_Patches,
|
||||||
|
|
||||||
|
// Video Subsection
|
||||||
|
// Top items are Pcsx2-controlled. GS plugin items are inserted beneath.
|
||||||
|
Menu_Video_Basics = 200, // includes frame timings and skippings settings
|
||||||
|
Menu_Video_Advanced, // inserted at the bottom of the menu
|
||||||
|
Menu_GS_Custom1 = 210, // start index for GS custom entries (valid up to 299)
|
||||||
|
Menu_GS_CustomMax = 299,
|
||||||
|
|
||||||
|
// Audio subsection
|
||||||
|
// Top items are Pcsx2-controlled. SPU2 plugin items are inserted beneath.
|
||||||
|
// [no items at this time]
|
||||||
|
Menu_Audio_Advanced = 300, // inserted at the bottom of the menu
|
||||||
|
Menu_Audio_Custom1 = 310,
|
||||||
|
Menu_Audio_CustomMax = 399,
|
||||||
|
|
||||||
|
// Controller subsection
|
||||||
|
// Top items are Pcsx2-controlled. Pad plugin items are inserted beneath.
|
||||||
|
// [no items at this time]
|
||||||
|
Menu_Pad_Advanced = 400,
|
||||||
|
Menu_Pad_Custom1 = 410,
|
||||||
|
Menu_Pad_CustomMax = 499,
|
||||||
|
|
||||||
|
// Miscellaneous Menu! (Misc)
|
||||||
|
Menu_About = wxID_ABOUT,
|
||||||
|
Menu_Website = 500, // Visit our awesome website!
|
||||||
|
Menu_Profiler, // Enable profiler
|
||||||
|
Menu_Console, // Enable console
|
||||||
|
Menu_Patches,
|
||||||
|
|
||||||
|
// Debug Subsection
|
||||||
|
Menu_Debug_Open = 600, // opens the debugger window / starts a debug session
|
||||||
|
Menu_Debug_MemoryDump,
|
||||||
|
Menu_Debug_Logging, // dialog for selection additional log options
|
||||||
|
Menu_Debug_Usermode,
|
||||||
|
Menu_Languages,
|
||||||
|
|
||||||
|
// Language Menu
|
||||||
|
// (Updated entirely dynamically, all values from range 1000 onward are reserved for languages)
|
||||||
|
Menu_Language_Start = 1000
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
struct AppImageIds
|
struct AppImageIds
|
||||||
|
@ -97,7 +180,6 @@ class Pcsx2App : public wxApp
|
||||||
protected:
|
protected:
|
||||||
MainEmuFrame* m_MainFrame;
|
MainEmuFrame* m_MainFrame;
|
||||||
ConsoleLogFrame* m_ProgramLogBox;
|
ConsoleLogFrame* m_ProgramLogBox;
|
||||||
ConsoleLogFrame* m_Ps2ConLogBox;
|
|
||||||
wxBitmap* m_Bitmap_Logo;
|
wxBitmap* m_Bitmap_Logo;
|
||||||
|
|
||||||
wxImageList m_ConfigImages;
|
wxImageList m_ConfigImages;
|
||||||
|
@ -135,16 +217,17 @@ public:
|
||||||
return *m_MainFrame;
|
return *m_MainFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PostMenuAction( MenuIdentifiers menu_id ) const;
|
||||||
|
void Ping() const;
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Console / Program Logging Helpers
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
ConsoleLogFrame* GetProgramLog()
|
ConsoleLogFrame* GetProgramLog()
|
||||||
{
|
{
|
||||||
return m_ProgramLogBox;
|
return m_ProgramLogBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsoleLogFrame* GetConsoleLog()
|
|
||||||
{
|
|
||||||
return m_Ps2ConLogBox;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CloseProgramLog()
|
void CloseProgramLog()
|
||||||
{
|
{
|
||||||
m_ProgramLogBox->Close();
|
m_ProgramLogBox->Close();
|
||||||
|
@ -165,18 +248,13 @@ public:
|
||||||
m_ProgramLogBox->GetEventHandler()->AddPendingEvent( evt );
|
m_ProgramLogBox->GetEventHandler()->AddPendingEvent( evt );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsoleLog_PostEvent( wxEvent& evt )
|
|
||||||
{
|
|
||||||
if( m_Ps2ConLogBox == NULL ) return;
|
|
||||||
m_Ps2ConLogBox->GetEventHandler()->AddPendingEvent( evt );
|
|
||||||
}
|
|
||||||
|
|
||||||
//ConsoleLogFrame* GetConsoleFrame() const { return m_ProgramLogBox; }
|
//ConsoleLogFrame* GetConsoleFrame() const { return m_ProgramLogBox; }
|
||||||
//void SetConsoleFrame( ConsoleLogFrame& frame ) { m_ProgramLogBox = &frame; }
|
//void SetConsoleFrame( ConsoleLogFrame& frame ) { m_ProgramLogBox = &frame; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void ReadUserModeSettings();
|
void ReadUserModeSettings();
|
||||||
bool TryOpenConfigCwd();
|
bool TryOpenConfigCwd();
|
||||||
|
void OnSemaphorePing( wxCommandEvent& evt );
|
||||||
void OnMessageBox( pxMessageBoxEvent& evt );
|
void OnMessageBox( pxMessageBoxEvent& evt );
|
||||||
void CleanupMess();
|
void CleanupMess();
|
||||||
void OpenWizardConsole();
|
void OpenWizardConsole();
|
||||||
|
|
|
@ -359,6 +359,7 @@ wxString AppConfig::FullpathToMcd( uint mcdidx ) const { return Path::Combine( F
|
||||||
|
|
||||||
AppConfig::AppConfig() :
|
AppConfig::AppConfig() :
|
||||||
MainGuiPosition( wxDefaultPosition )
|
MainGuiPosition( wxDefaultPosition )
|
||||||
|
, SettingsTabName( L"Cpu" )
|
||||||
, LanguageId( wxLANGUAGE_DEFAULT )
|
, LanguageId( wxLANGUAGE_DEFAULT )
|
||||||
, RecentFileCount( 6 )
|
, RecentFileCount( 6 )
|
||||||
, DeskTheme( L"default" )
|
, DeskTheme( L"default" )
|
||||||
|
@ -418,6 +419,7 @@ void AppConfig::LoadSave( IniInterface& ini )
|
||||||
AppConfig defaults;
|
AppConfig defaults;
|
||||||
|
|
||||||
IniEntry( MainGuiPosition );
|
IniEntry( MainGuiPosition );
|
||||||
|
IniEntry( SettingsTabName );
|
||||||
ini.EnumEntry( L"LanguageId", LanguageId, NULL, defaults.LanguageId );
|
ini.EnumEntry( L"LanguageId", LanguageId, NULL, defaults.LanguageId );
|
||||||
IniEntry( RecentFileCount );
|
IniEntry( RecentFileCount );
|
||||||
IniEntry( DeskTheme );
|
IniEntry( DeskTheme );
|
||||||
|
|
|
@ -104,6 +104,10 @@ public:
|
||||||
public:
|
public:
|
||||||
wxPoint MainGuiPosition;
|
wxPoint MainGuiPosition;
|
||||||
|
|
||||||
|
// Because remembering the last used tab on the settings panel is cool (tab is remembered
|
||||||
|
// by it's UTF/ASCII name).
|
||||||
|
wxString SettingsTabName;
|
||||||
|
|
||||||
// Current language in use (correlates to a wxWidgets wxLANGUAGE specifier)
|
// Current language in use (correlates to a wxWidgets wxLANGUAGE specifier)
|
||||||
wxLanguage LanguageId;
|
wxLanguage LanguageId;
|
||||||
|
|
||||||
|
|
|
@ -647,6 +647,9 @@ namespace Console
|
||||||
const wxString fmtline( wxString::FromAscii( fmt ) + L"\n" );
|
const wxString fmtline( wxString::FromAscii( fmt ) + L"\n" );
|
||||||
_immediate_logger( fmtline );
|
_immediate_logger( fmtline );
|
||||||
|
|
||||||
|
if( emuLog != NULL )
|
||||||
|
fflush( emuLog );
|
||||||
|
|
||||||
// Implementation note: I've duplicated Write+Newline behavior here to avoid polluting
|
// Implementation note: I've duplicated Write+Newline behavior here to avoid polluting
|
||||||
// the message pump with lots of erroneous messages (Newlines can be bound into Write message).
|
// the message pump with lots of erroneous messages (Newlines can be bound into Write message).
|
||||||
|
|
||||||
|
@ -664,6 +667,9 @@ namespace Console
|
||||||
const wxString fmtline( fmt + L"\n" );
|
const wxString fmtline( fmt + L"\n" );
|
||||||
_immediate_logger( fmtline );
|
_immediate_logger( fmtline );
|
||||||
|
|
||||||
|
if( emuLog != NULL )
|
||||||
|
fflush( emuLog );
|
||||||
|
|
||||||
// Implementation note: I've duplicated Write+Newline behavior here to avoid polluting
|
// Implementation note: I've duplicated Write+Newline behavior here to avoid polluting
|
||||||
// the message pump with lots of erroneous messages (Newlines can be bound into Write message).
|
// the message pump with lots of erroneous messages (Newlines can be bound into Write message).
|
||||||
|
|
||||||
|
|
|
@ -43,13 +43,22 @@ using namespace Panels;
|
||||||
static const int s_orient = wxBK_LEFT;
|
static const int s_orient = wxBK_LEFT;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static const int IdealWidth = 500;
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
void Dialogs::ConfigurationDialog::AddPage( const char* label, int iconid )
|
||||||
|
{
|
||||||
|
const wxString labelstr( wxString::FromUTF8( label ) );
|
||||||
|
const int curidx = m_labels.Add( labelstr );
|
||||||
|
g_ApplyState.SetCurrentPage( curidx );
|
||||||
|
m_listbook.AddPage( new T( m_listbook, IdealWidth ), wxGetTranslation( labelstr ),
|
||||||
|
( labelstr == g_Conf->SettingsTabName ), iconid );
|
||||||
|
}
|
||||||
|
|
||||||
Dialogs::ConfigurationDialog::ConfigurationDialog( wxWindow* parent, int id ) :
|
Dialogs::ConfigurationDialog::ConfigurationDialog( wxWindow* parent, int id ) :
|
||||||
wxDialogWithHelpers( parent, id, _("PCSX2 Configuration"), true )
|
wxDialogWithHelpers( parent, id, _("PCSX2 Configuration"), true )
|
||||||
, m_listbook( *new wxListbook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, s_orient ) )
|
, m_listbook( *new wxListbook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, s_orient ) )
|
||||||
{
|
{
|
||||||
static const int IdealWidth = 500;
|
|
||||||
|
|
||||||
wxBoxSizer& mainSizer = *new wxBoxSizer( wxVERTICAL );
|
wxBoxSizer& mainSizer = *new wxBoxSizer( wxVERTICAL );
|
||||||
|
|
||||||
m_listbook.SetImageList( &wxGetApp().GetImgList_Config() );
|
m_listbook.SetImageList( &wxGetApp().GetImgList_Config() );
|
||||||
|
@ -57,23 +66,12 @@ Dialogs::ConfigurationDialog::ConfigurationDialog( wxWindow* parent, int id ) :
|
||||||
|
|
||||||
g_ApplyState.StartBook( &m_listbook );
|
g_ApplyState.StartBook( &m_listbook );
|
||||||
|
|
||||||
g_ApplyState.SetCurrentPage( m_listbook.GetPageCount() );
|
AddPage<CpuPanel> ( wxLt("CPU"), cfgid.Cpu );
|
||||||
m_listbook.AddPage( new CpuPanel( m_listbook, IdealWidth ), _("CPU"), false, cfgid.Cpu );
|
AddPage<VideoPanel> ( wxLt("GS/Video"), cfgid.Video );
|
||||||
|
AddPage<SpeedHacksPanel> ( wxLt("Speedhacks"), cfgid.Speedhacks );
|
||||||
g_ApplyState.SetCurrentPage( m_listbook.GetPageCount() );
|
AddPage<GameFixesPanel> ( wxLt("Game Fixes"), cfgid.Gamefixes );
|
||||||
m_listbook.AddPage( new VideoPanel( m_listbook, IdealWidth ), _("GS/Video"), false, cfgid.Video );
|
AddPage<PluginSelectorPanel>( wxLt("Plugins"), cfgid.Plugins );
|
||||||
|
AddPage<StandardPathsPanel> ( wxLt("Folders"), cfgid.Paths );
|
||||||
g_ApplyState.SetCurrentPage( m_listbook.GetPageCount() );
|
|
||||||
m_listbook.AddPage( new SpeedHacksPanel( m_listbook, IdealWidth ), _("Speedhacks"), false, cfgid.Speedhacks );
|
|
||||||
|
|
||||||
g_ApplyState.SetCurrentPage( m_listbook.GetPageCount() );
|
|
||||||
m_listbook.AddPage( new GameFixesPanel( m_listbook, IdealWidth ), _("Game Fixes"), false, cfgid.Gamefixes );
|
|
||||||
|
|
||||||
g_ApplyState.SetCurrentPage( m_listbook.GetPageCount() );
|
|
||||||
m_listbook.AddPage( new PluginSelectorPanel( m_listbook, IdealWidth ), _("Plugins"), false, cfgid.Plugins );
|
|
||||||
|
|
||||||
g_ApplyState.SetCurrentPage( m_listbook.GetPageCount() );
|
|
||||||
m_listbook.AddPage( new StandardPathsPanel( m_listbook ), _("Folders"), false, cfgid.Paths );
|
|
||||||
|
|
||||||
mainSizer.Add( &m_listbook );
|
mainSizer.Add( &m_listbook );
|
||||||
AddOkCancel( mainSizer, true );
|
AddOkCancel( mainSizer, true );
|
||||||
|
@ -94,6 +92,7 @@ Dialogs::ConfigurationDialog::ConfigurationDialog( wxWindow* parent, int id ) :
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Connect( wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ConfigurationDialog::OnOk_Click ) );
|
Connect( wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ConfigurationDialog::OnOk_Click ) );
|
||||||
|
Connect( wxID_CANCEL, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ConfigurationDialog::OnCancel_Click ) );
|
||||||
Connect( wxID_APPLY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ConfigurationDialog::OnApply_Click ) );
|
Connect( wxID_APPLY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ConfigurationDialog::OnApply_Click ) );
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -121,17 +120,30 @@ Dialogs::ConfigurationDialog::~ConfigurationDialog()
|
||||||
|
|
||||||
void Dialogs::ConfigurationDialog::OnOk_Click( wxCommandEvent& evt )
|
void Dialogs::ConfigurationDialog::OnOk_Click( wxCommandEvent& evt )
|
||||||
{
|
{
|
||||||
if( g_ApplyState.ApplyAll() )
|
if( g_ApplyState.ApplyAll( false ) )
|
||||||
{
|
{
|
||||||
|
FindWindow( wxID_APPLY )->Disable();
|
||||||
|
g_Conf->SettingsTabName = m_labels[m_listbook.GetSelection()];
|
||||||
|
g_Conf->Save();
|
||||||
|
|
||||||
Close();
|
Close();
|
||||||
evt.Skip();
|
evt.Skip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Dialogs::ConfigurationDialog::OnCancel_Click( wxCommandEvent& evt )
|
||||||
|
{
|
||||||
|
evt.Skip();
|
||||||
|
g_Conf->SettingsTabName = m_labels[m_listbook.GetSelection()];
|
||||||
|
}
|
||||||
|
|
||||||
void Dialogs::ConfigurationDialog::OnApply_Click( wxCommandEvent& evt )
|
void Dialogs::ConfigurationDialog::OnApply_Click( wxCommandEvent& evt )
|
||||||
{
|
{
|
||||||
FindWindow( wxID_APPLY )->Disable();
|
if( g_ApplyState.ApplyAll( false ) )
|
||||||
g_ApplyState.ApplyAll();
|
FindWindow( wxID_APPLY )->Disable();
|
||||||
|
|
||||||
|
g_Conf->SettingsTabName = m_labels[m_listbook.GetSelection()];
|
||||||
|
g_Conf->Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,13 +32,18 @@ namespace Dialogs
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
wxListbook& m_listbook;
|
wxListbook& m_listbook;
|
||||||
|
wxArrayString m_labels;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~ConfigurationDialog();
|
virtual ~ConfigurationDialog();
|
||||||
ConfigurationDialog(wxWindow* parent, int id=wxID_ANY);
|
ConfigurationDialog(wxWindow* parent, int id=wxID_ANY);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
template< typename T >
|
||||||
|
void AddPage( const char* label, int iconid );
|
||||||
|
|
||||||
void OnOk_Click( wxCommandEvent& evt );
|
void OnOk_Click( wxCommandEvent& evt );
|
||||||
|
void OnCancel_Click( wxCommandEvent& evt );
|
||||||
void OnApply_Click( wxCommandEvent& evt );
|
void OnApply_Click( wxCommandEvent& evt );
|
||||||
|
|
||||||
virtual void OnSomethingChanged( wxCommandEvent& evt )
|
virtual void OnSomethingChanged( wxCommandEvent& evt )
|
||||||
|
|
|
@ -24,95 +24,12 @@
|
||||||
|
|
||||||
#include "App.h"
|
#include "App.h"
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
class MainEmuFrame: public wxFrame
|
class MainEmuFrame: public wxFrame
|
||||||
{
|
{
|
||||||
protected:
|
public:
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
// All Menu Options for the Main Window! :D
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
|
|
||||||
enum Identifiers
|
|
||||||
{
|
|
||||||
// Main Menu Section
|
|
||||||
Menu_Run = 1,
|
|
||||||
Menu_Config, // General config, plus non audio/video plugins.
|
|
||||||
Menu_Video, // Video options filled in by GS plugin
|
|
||||||
Menu_Audio, // audio options filled in by SPU2 plugin
|
|
||||||
Menu_Misc, // Misc options and help!
|
|
||||||
|
|
||||||
// Run SubSection
|
|
||||||
Menu_RunIso = 20, // Opens submenu with Iso browser, and recent isos.
|
|
||||||
Menu_IsoBrowse, // Open dialog, runs selected iso.
|
|
||||||
Menu_BootCDVD, // opens a submenu filled by CDVD plugin (usually list of drives)
|
|
||||||
Menu_RunWithoutDisc, // used to enter the bios (subs in cdvdnull)
|
|
||||||
Menu_RunELF,
|
|
||||||
Menu_SkipBiosToggle, // enables the Bios Skip speedhack
|
|
||||||
Menu_EnableSkipBios, // check marked menu that toggles Skip Bios boot feature.
|
|
||||||
Menu_PauseExec, // suspends/resumes active emulation
|
|
||||||
Menu_Reset, // Issues a complete reset.
|
|
||||||
Menu_States, // Opens states submenu
|
|
||||||
Menu_Run_Exit = wxID_EXIT,
|
|
||||||
|
|
||||||
Menu_State_Load = 40,
|
|
||||||
Menu_State_LoadOther,
|
|
||||||
Menu_State_Load01, // first of many load slots
|
|
||||||
Menu_State_Save = 60,
|
|
||||||
Menu_State_SaveOther,
|
|
||||||
Menu_State_Save01, // first of many save slots
|
|
||||||
|
|
||||||
// Config Subsection
|
|
||||||
Menu_Config_Settings = 100,
|
|
||||||
Menu_Config_BIOS,
|
|
||||||
Menu_Config_CDVD,
|
|
||||||
Menu_Config_DEV9,
|
|
||||||
Menu_Config_USB,
|
|
||||||
Menu_Config_FireWire,
|
|
||||||
Menu_Config_Patches,
|
|
||||||
|
|
||||||
// Video Subsection
|
|
||||||
// Top items are Pcsx2-controlled. GS plugin items are inserted beneath.
|
|
||||||
Menu_Video_Basics = 200, // includes frame timings and skippings settings
|
|
||||||
Menu_Video_Advanced, // inserted at the bottom of the menu
|
|
||||||
Menu_GS_Custom1 = 210, // start index for GS custom entries (valid up to 299)
|
|
||||||
Menu_GS_CustomMax = 299,
|
|
||||||
|
|
||||||
// Audio subsection
|
|
||||||
// Top items are Pcsx2-controlled. SPU2 plugin items are inserted beneath.
|
|
||||||
// [no items at this time]
|
|
||||||
Menu_Audio_Advanced = 300, // inserted at the bottom of the menu
|
|
||||||
Menu_Audio_Custom1 = 310,
|
|
||||||
Menu_Audio_CustomMax = 399,
|
|
||||||
|
|
||||||
// Controller subsection
|
|
||||||
// Top items are Pcsx2-controlled. Pad plugin items are inserted beneath.
|
|
||||||
// [no items at this time]
|
|
||||||
Menu_Pad_Advanced = 400,
|
|
||||||
Menu_Pad_Custom1 = 410,
|
|
||||||
Menu_Pad_CustomMax = 499,
|
|
||||||
|
|
||||||
// Miscellaneous Menu! (Misc)
|
|
||||||
Menu_About = wxID_ABOUT,
|
|
||||||
Menu_Website = 500, // Visit our awesome website!
|
|
||||||
Menu_Profiler, // Enable profiler
|
|
||||||
Menu_Console, // Enable console
|
|
||||||
Menu_Patches,
|
|
||||||
|
|
||||||
// Debug Subsection
|
|
||||||
Menu_Debug_Open = 600, // opens the debugger window / starts a debug session
|
|
||||||
Menu_Debug_MemoryDump,
|
|
||||||
Menu_Debug_Logging, // dialog for selection additional log options
|
|
||||||
Menu_Debug_Usermode,
|
|
||||||
Menu_Languages,
|
|
||||||
|
|
||||||
// Language Menu
|
|
||||||
// (Updated entirely dynamically, all values from range 1000 onward are reserved for languages)
|
|
||||||
Menu_Language_Start = 1000
|
|
||||||
};
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// MainEmuFrame Protected Variables
|
// MainEmuFrame Protected Variables
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -138,7 +55,7 @@ protected:
|
||||||
bool m_IsPaused;
|
bool m_IsPaused;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// MainEmuFrame Constructors and Member Methods
|
// MainEmuFrame Constructors and Member Methods
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -177,7 +94,7 @@ protected:
|
||||||
void Menu_ShowAboutBox(wxCommandEvent &event);
|
void Menu_ShowAboutBox(wxCommandEvent &event);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// MainEmuFram Internal API for Populating Main Menu Contents
|
// MainEmuFram Internal API for Populating Main Menu Contents
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
wxMenu* MakeStatesSubMenu( int baseid ) const;
|
wxMenu* MakeStatesSubMenu( int baseid ) const;
|
||||||
|
|
|
@ -118,7 +118,7 @@ namespace Panels
|
||||||
|
|
||||||
void StartBook( wxBookCtrlBase* book );
|
void StartBook( wxBookCtrlBase* book );
|
||||||
void StartWizard();
|
void StartWizard();
|
||||||
bool ApplyAll();
|
bool ApplyAll( bool saveOnSuccess=true );
|
||||||
bool ApplyPage( int pageid, bool saveOnSuccess=true );
|
bool ApplyPage( int pageid, bool saveOnSuccess=true );
|
||||||
void DoCleanup();
|
void DoCleanup();
|
||||||
};
|
};
|
||||||
|
@ -323,7 +323,7 @@ namespace Panels
|
||||||
class StandardPathsPanel : public BasePathsPanel
|
class StandardPathsPanel : public BasePathsPanel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StandardPathsPanel( wxWindow& parent );
|
StandardPathsPanel( wxWindow& parent, int idealWidth );
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -452,8 +452,8 @@ namespace Panels
|
||||||
public:
|
public:
|
||||||
virtual ~PluginSelectorPanel();
|
virtual ~PluginSelectorPanel();
|
||||||
PluginSelectorPanel( wxWindow& parent, int idealWidth );
|
PluginSelectorPanel( wxWindow& parent, int idealWidth );
|
||||||
virtual void CancelRefresh();
|
|
||||||
|
|
||||||
|
void CancelRefresh(); // used from destructor, stays non-virtual
|
||||||
void Apply( AppConfig& conf );
|
void Apply( AppConfig& conf );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -33,7 +33,7 @@ static wxString GetNormalizedConfigFolder( FoldersEnum_t folderId )
|
||||||
return normalized.ToString();
|
return normalized.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass me TRUE if the default path is to be used, and the DirPcikerCtrl disabled from use.
|
// Pass me TRUE if the default path is to be used, and the DirPickerCtrl disabled from use.
|
||||||
void Panels::DirPickerPanel::UpdateCheckStatus( bool someNoteworthyBoolean )
|
void Panels::DirPickerPanel::UpdateCheckStatus( bool someNoteworthyBoolean )
|
||||||
{
|
{
|
||||||
m_pickerCtrl->Enable( !someNoteworthyBoolean );
|
m_pickerCtrl->Enable( !someNoteworthyBoolean );
|
||||||
|
|
|
@ -100,9 +100,9 @@ bool Panels::StaticApplyState::ApplyPage( int pageid, bool saveOnSuccess )
|
||||||
|
|
||||||
// Returns false if one of the panels fails input validation (in which case dialogs
|
// Returns false if one of the panels fails input validation (in which case dialogs
|
||||||
// should not be closed, etc).
|
// should not be closed, etc).
|
||||||
bool Panels::StaticApplyState::ApplyAll()
|
bool Panels::StaticApplyState::ApplyAll( bool saveOnSuccess )
|
||||||
{
|
{
|
||||||
return ApplyPage( -1 );
|
return ApplyPage( -1, saveOnSuccess );
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
|
@ -40,7 +40,7 @@ Panels::DirPickerPanel& Panels::BasePathsPanel::AddDirPicker( wxBoxSizer& sizer,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
Panels::StandardPathsPanel::StandardPathsPanel( wxWindow& parent ) :
|
Panels::StandardPathsPanel::StandardPathsPanel( wxWindow& parent, __unused int idealWidth ) :
|
||||||
BasePathsPanel( parent )
|
BasePathsPanel( parent )
|
||||||
{
|
{
|
||||||
s_main.AddSpacer( BetweenFolderSpace );
|
s_main.AddSpacer( BetweenFolderSpace );
|
||||||
|
|
|
@ -420,7 +420,7 @@ Panels::PluginSelectorPanel::EnumThread::EnumThread( PluginSelectorPanel& master
|
||||||
|
|
||||||
Panels::PluginSelectorPanel::EnumThread::~EnumThread()
|
Panels::PluginSelectorPanel::EnumThread::~EnumThread()
|
||||||
{
|
{
|
||||||
Cancel();
|
EnumThread::Cancel();
|
||||||
safe_delete_array( Results );
|
safe_delete_array( Results );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,7 +435,7 @@ sptr Panels::PluginSelectorPanel::EnumThread::ExecuteTask()
|
||||||
{
|
{
|
||||||
DevCon::Status( "Plugin Enumeration Thread started..." );
|
DevCon::Status( "Plugin Enumeration Thread started..." );
|
||||||
|
|
||||||
Sleep( 10 ); // gives the gui thread some time to refresh
|
wxGetApp().Ping(); // gives the gui thread some time to refresh
|
||||||
|
|
||||||
for( int curidx=0; curidx < m_master.FileCount(); ++curidx )
|
for( int curidx=0; curidx < m_master.FileCount(); ++curidx )
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,6 +31,12 @@
|
||||||
|
|
||||||
IMPLEMENT_APP(Pcsx2App)
|
IMPLEMENT_APP(Pcsx2App)
|
||||||
|
|
||||||
|
DEFINE_EVENT_TYPE( pxEVT_SemaphorePing )
|
||||||
|
|
||||||
|
BEGIN_DECLARE_EVENT_TYPES()
|
||||||
|
DECLARE_EVENT_TYPE( pxEVT_SemaphorePing, -1 )
|
||||||
|
END_DECLARE_EVENT_TYPES()
|
||||||
|
|
||||||
bool UseAdminMode = false;
|
bool UseAdminMode = false;
|
||||||
AppConfig* g_Conf = NULL;
|
AppConfig* g_Conf = NULL;
|
||||||
wxFileHistory* g_RecentIsoList = NULL;
|
wxFileHistory* g_RecentIsoList = NULL;
|
||||||
|
@ -77,8 +83,15 @@ sptr AppEmuThread::ExecuteTask()
|
||||||
{
|
{
|
||||||
if( ex.StreamName == g_Conf->FullpathToBios() )
|
if( ex.StreamName == g_Conf->FullpathToBios() )
|
||||||
{
|
{
|
||||||
Msgbox::OkCancel( ex.FormatDisplayMessage() +
|
GetPluginManager().Close();
|
||||||
|
bool result = Msgbox::OkCancel( ex.FormatDisplayMessage() +
|
||||||
_("\n\nPress Ok to go to the BIOS Configuration Panel.") );
|
_("\n\nPress Ok to go to the BIOS Configuration Panel.") );
|
||||||
|
|
||||||
|
if( result )
|
||||||
|
{
|
||||||
|
wxGetApp().PostMenuAction( Menu_Config_BIOS );
|
||||||
|
wxGetApp().Ping();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -91,16 +104,17 @@ sptr AppEmuThread::ExecuteTask()
|
||||||
if( g_Conf->FullpathTo( pid ) == ex.StreamName ) break;
|
if( g_Conf->FullpathTo( pid ) == ex.StreamName ) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pi->shortname == NULL )
|
if( pi->shortname != NULL )
|
||||||
{
|
{
|
||||||
// Some other crap file failure >_<
|
bool result = Msgbox::OkCancel( ex.FormatDisplayMessage() +
|
||||||
}
|
_("\n\nPress Ok to go to the Plugin Configuration Panel.") );
|
||||||
|
|
||||||
int result = Msgbox::OkCancel( ex.FormatDisplayMessage() +
|
if( result )
|
||||||
_("\n\nPress Ok to go to the Plugin Configuration Panel.") );
|
{
|
||||||
|
g_Conf->SettingsTabName = L"Plugins";
|
||||||
if( result == wxID_OK )
|
wxGetApp().PostMenuAction( Menu_Config_Settings );
|
||||||
{
|
wxGetApp().Ping();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,6 +177,7 @@ void Pcsx2App::ReadUserModeSettings()
|
||||||
// Save user's new settings
|
// Save user's new settings
|
||||||
IniSaver saver( *conf_usermode );
|
IniSaver saver( *conf_usermode );
|
||||||
g_Conf->LoadSaveUserMode( saver, groupname );
|
g_Conf->LoadSaveUserMode( saver, groupname );
|
||||||
|
AppConfig_ReloadGlobalSettings( true );
|
||||||
g_Conf->Save();
|
g_Conf->Save();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -187,6 +202,7 @@ void Pcsx2App::ReadUserModeSettings()
|
||||||
// Save user's new settings
|
// Save user's new settings
|
||||||
IniSaver saver( *conf_usermode );
|
IniSaver saver( *conf_usermode );
|
||||||
g_Conf->LoadSaveUserMode( saver, groupname );
|
g_Conf->LoadSaveUserMode( saver, groupname );
|
||||||
|
AppConfig_ReloadGlobalSettings( true );
|
||||||
g_Conf->Save();
|
g_Conf->Save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -242,6 +258,13 @@ bool Pcsx2App::OnInit()
|
||||||
|
|
||||||
wxLocale::AddCatalogLookupPathPrefix( wxGetCwd() );
|
wxLocale::AddCatalogLookupPathPrefix( wxGetCwd() );
|
||||||
|
|
||||||
|
#define pxMessageBoxEventThing(func) \
|
||||||
|
(wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(pxMessageBoxEventFunction, &func )
|
||||||
|
|
||||||
|
Connect( pxEVT_MSGBOX, pxMessageBoxEventThing( Pcsx2App::OnMessageBox ) );
|
||||||
|
Connect( pxEVT_CallStackBox, pxMessageBoxEventThing( Pcsx2App::OnMessageBox ) );
|
||||||
|
Connect( pxEVT_SemaphorePing, wxCommandEventHandler( Pcsx2App::OnSemaphorePing ) );
|
||||||
|
|
||||||
// User/Admin Mode Dual Setup:
|
// User/Admin Mode Dual Setup:
|
||||||
// Pcsx2 now supports two fundamental modes of operation. The default is Classic mode,
|
// Pcsx2 now supports two fundamental modes of operation. The default is Classic mode,
|
||||||
// which uses the Current Working Directory (CWD) for all user data files, and requires
|
// which uses the Current Working Directory (CWD) for all user data files, and requires
|
||||||
|
@ -270,9 +293,6 @@ bool Pcsx2App::OnInit()
|
||||||
|
|
||||||
m_ProgramLogBox = new ConsoleLogFrame( m_MainFrame, L"PCSX2 Program Log", g_Conf->ProgLogBox );
|
m_ProgramLogBox = new ConsoleLogFrame( m_MainFrame, L"PCSX2 Program Log", g_Conf->ProgLogBox );
|
||||||
|
|
||||||
m_Ps2ConLogBox = m_ProgramLogBox; // just use a single logger for now.
|
|
||||||
//m_Ps2ConLogBox = new ConsoleLogFrame( NULL, L"PS2 Console Log" );
|
|
||||||
|
|
||||||
SetTopWindow( m_MainFrame ); // not really needed...
|
SetTopWindow( m_MainFrame ); // not really needed...
|
||||||
SetExitOnFrameDelete( true ); // but being explicit doesn't hurt...
|
SetExitOnFrameDelete( true ); // but being explicit doesn't hurt...
|
||||||
m_MainFrame->Show();
|
m_MainFrame->Show();
|
||||||
|
@ -286,15 +306,42 @@ bool Pcsx2App::OnInit()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define pxMessageBoxEventThing(func) \
|
|
||||||
(wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(pxMessageBoxEventFunction, &func )
|
|
||||||
|
|
||||||
Connect( pxEVT_MSGBOX, pxMessageBoxEventThing( Pcsx2App::OnMessageBox ) );
|
|
||||||
Connect( pxEVT_CallStackBox,pxMessageBoxEventThing( Pcsx2App::OnMessageBox ) );
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allows for activating menu actions from anywhere in PCSX2.
|
||||||
|
// And it's Thread Safe!
|
||||||
|
void Pcsx2App::PostMenuAction( MenuIdentifiers menu_id ) const
|
||||||
|
{
|
||||||
|
wxASSERT( m_MainFrame != NULL );
|
||||||
|
if( m_MainFrame == NULL ) return;
|
||||||
|
|
||||||
|
wxCommandEvent joe( wxEVT_COMMAND_MENU_SELECTED, menu_id );
|
||||||
|
m_MainFrame->GetEventHandler()->AddPendingEvent( joe );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Waits for the main GUI thread to respond. If run from the main GUI thread, returns
|
||||||
|
// immediately without error.
|
||||||
|
void Pcsx2App::Ping() const
|
||||||
|
{
|
||||||
|
if( wxThread::IsMain() ) return;
|
||||||
|
|
||||||
|
Semaphore sema;
|
||||||
|
wxCommandEvent bean( pxEVT_SemaphorePing );
|
||||||
|
bean.SetClientData( &sema );
|
||||||
|
wxGetApp().AddPendingEvent( bean );
|
||||||
|
sema.WaitNoCancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Pcsx2App Event Handlers
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void Pcsx2App::OnSemaphorePing( wxCommandEvent& evt )
|
||||||
|
{
|
||||||
|
((Semaphore*)evt.GetClientData())->Post();
|
||||||
|
}
|
||||||
|
|
||||||
void Pcsx2App::OnMessageBox( pxMessageBoxEvent& evt )
|
void Pcsx2App::OnMessageBox( pxMessageBoxEvent& evt )
|
||||||
{
|
{
|
||||||
Msgbox::OnEvent( evt );
|
Msgbox::OnEvent( evt );
|
||||||
|
@ -351,7 +398,6 @@ int Pcsx2App::OnExit()
|
||||||
|
|
||||||
Pcsx2App::Pcsx2App() :
|
Pcsx2App::Pcsx2App() :
|
||||||
m_ProgramLogBox( NULL )
|
m_ProgramLogBox( NULL )
|
||||||
, m_Ps2ConLogBox( NULL )
|
|
||||||
, m_ConfigImages( 32, 32 )
|
, m_ConfigImages( 32, 32 )
|
||||||
, m_ConfigImagesAreLoaded( false )
|
, m_ConfigImagesAreLoaded( false )
|
||||||
, m_ToolbarImages( NULL )
|
, m_ToolbarImages( NULL )
|
||||||
|
|
|
@ -103,11 +103,9 @@ sptr CoreEmuThread::ExecuteTask()
|
||||||
m_ResumeEvent.Wait();
|
m_ResumeEvent.Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_cleanup_push( _cet_callback_cleanup, this );
|
|
||||||
CpuInitializeMess();
|
CpuInitializeMess();
|
||||||
StateCheck();
|
StateCheck();
|
||||||
CpuExecute();
|
CpuExecute();
|
||||||
pthread_cleanup_pop( true );
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -154,20 +152,17 @@ CoreEmuThread::CoreEmuThread( const wxString& elf_file ) :
|
||||||
, m_lock_ExecMode()
|
, m_lock_ExecMode()
|
||||||
{
|
{
|
||||||
PersistentThread::Start();
|
PersistentThread::Start();
|
||||||
pthread_detach( m_thread );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoked by the pthread_exit or pthread_cancel
|
// Invoked by the pthread_exit or pthread_cancel
|
||||||
void CoreEmuThread::DoThreadCleanup()
|
void CoreEmuThread::DoThreadCleanup()
|
||||||
{
|
{
|
||||||
wxASSERT( IsSelf() ); // only allowed from our own thread, thanks.
|
PersistentThread::DoThreadCleanup();
|
||||||
m_running = false;
|
|
||||||
GetPluginManager().Close();
|
GetPluginManager().Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
CoreEmuThread::~CoreEmuThread()
|
CoreEmuThread::~CoreEmuThread()
|
||||||
{
|
{
|
||||||
Cancel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resumes the core execution state, or does nothing is the core is already running. If
|
// Resumes the core execution state, or does nothing is the core is already running. If
|
||||||
|
|
Loading…
Reference in New Issue