User Interface:

* Fixed and added better Emulation/System menu updating.  Suspend/Resume is more consistent, and Reset grays itself out after being used.
 * Entering plugin configurations auto-suspends the emulator.
 * Changing plugins in the Configuration PAnel takes effect now without a restart.
 * Added preliminary support for an ExtensibleConfirmation Dialog box (contains a sizer you can add content to, and also has an optional "[x] Do not show this again" checkbox).

Bugfixes:
 * Added some mutex protection to cdvdNewDiskCB; "just in case."
 * Resolved several recursion and deadlock scenarios when (very!) rapidly suspending, resuming, and resetting the emu.

Developments / Code Cleanups:
 * Renamed SysCoreThread ExecutionModes:  Suspend/Resume are now Opened/Closed (which more accurately reflects the fact they opena nd close the plugins, and helps avoid ambiguity with the "Paused" state).
 * Added Exception::ThreadTimedOut, which is now thrown from Semaphore::Wait when recursive wxApp::Yield() calls are detected, and a deadlock occurs (basically cancels the current action which, most of the time, allows for full recovery).
 * Major Threading namespace cleanups, documentations, etc.
 * Removed wxScopedArray (scopedarray.h) and replaced it with a better implemeneted ScopedArray class.
 * Removed toUTF8 class, which I only added a couple weeks ago because I didn't realize wxCharBuffer had an implicit typecast to (char*).
 * Implemented more Source/Listener events for Pcsx2App.  CoreThread events are sourced properly now, and added SettingsApplied and SettingsLoadSave Sources.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2010 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-10-16 03:58:29 +00:00
parent adf4b7ae50
commit 1f2daa6459
43 changed files with 2101 additions and 1437 deletions

View File

@ -294,6 +294,12 @@ namespace Exception
DEFINE_RUNTIME_EXCEPTION( ThreadCreationError, wxLt("Thread could not be created.") );
};
class ThreadTimedOut : public virtual RuntimeError
{
public:
DEFINE_RUNTIME_EXCEPTION( ThreadTimedOut, "Blocking action timed out due to potential deadlock." );
};
// ---------------------------------------------------------------------------------------
// Streaming (file) Exceptions:
// Stream / BadStream / CreateStream / FileNotFound / AccessDenied / EndOfStream

View File

@ -308,11 +308,11 @@ public:
if( m_ptr == NULL )
{
throw Exception::OutOfMemory(
// English Diagonstic message:
// English Diagnostic message:
wxsFormat(
L"Out-of-memory on SafeList block re-allocation.\n"
L"Old size: %d bytes, New size: %d bytes",
m_allocsize, newalloc
L"Name: %s, Old size: %d bytes, New size: %d bytes",
Name, m_allocsize, newalloc
),
wxsFormat( _("Out of memory, trying to allocate %d bytes."), newalloc )

View File

@ -1,7 +1,5 @@
#pragma once
#include <wx/scopedarray.h>
// --------------------------------------------------------------------------------------
// ScopedPtr
// --------------------------------------------------------------------------------------
@ -10,7 +8,7 @@ template< typename T >
class ScopedPtr
{
DeclareNoncopyableObject(ScopedPtr);
protected:
T* m_ptr;
@ -19,7 +17,7 @@ public:
wxEXPLICIT ScopedPtr(T * ptr = NULL) : m_ptr(ptr) { }
~ScopedPtr()
~ScopedPtr() throw()
{ Delete(); }
ScopedPtr& Reassign(T * ptr = NULL)
@ -32,7 +30,7 @@ public:
return *this;
}
ScopedPtr& Delete()
ScopedPtr& Delete() throw()
{
// Thread-safe deletion: Set the pointer to NULL first, and then issue
// the deletion. This allows pending Application messages that might be
@ -118,6 +116,125 @@ public:
}
};
// --------------------------------------------------------------------------------------
// ScopedArray - same as ScopedPtr but uses delete[], and has operator[]
// --------------------------------------------------------------------------------------
template< typename T >
class ScopedArray
{
DeclareNoncopyableObject(ScopedArray);
protected:
T* m_array;
uint m_valid_range;
public:
typedef T element_type;
wxEXPLICIT ScopedArray(T * ptr = NULL) :
m_array(ptr)
, m_valid_range( 0xffffffff )
{
}
wxEXPLICIT ScopedArray( int size ) :
m_array( pxAssertDev( size >= 0, "Invalid negative size specified." ) ? new T[size] : NULL )
, m_valid_range( (uint)size )
{
}
// For breaking the 2gb barrier, lets provision this:
wxEXPLICIT ScopedArray( s64 size ) :
m_array( pxAssertDev( size >= 0 && (size < UINT_MAX), "Invalid negative size specified to ScopedArray." ) ? new T[size] : NULL )
, m_valid_range( (uint)size )
{
}
~ScopedArray() throw()
{ Delete(); }
ScopedArray& Reassign(T * ptr = NULL)
{
if( ptr != m_array )
{
Delete();
m_array = ptr;
}
return *this;
}
ScopedArray& Delete() throw()
{
// Thread-safe deletion: Set the pointer to NULL first, and then issue
// the deletion. This allows pending Application messages that might be
// dependent on the current object to nullify their actions.
T* deleteme = m_array;
m_array = NULL;
delete[] deleteme;
return *this;
}
// Removes the pointer from scoped management, but does not delete!
T *DetachPtr()
{
T *ptr = m_array;
m_array = NULL;
return ptr;
}
// Returns the managed pointer. Can return NULL as a valid result if the ScopedPtr
// has no object in management.
T* GetPtr() const
{
return m_array;
}
void SwapPtr(ScopedArray& other)
{
T * const tmp = other.m_array;
other.m_array = m_array;
m_array = tmp;
}
// ----------------------------------------------------------------------------
// ScopedPtr Operators
// ----------------------------------------------------------------------------
// I've decided to use the ATL's approach to pointer validity tests, opposed to
// the wx/boost approach (which uses some bizarre member method pointer crap, and can't
// allow the T* implicit casting.
bool operator!() const throw()
{
return m_array == NULL;
}
// Equality
bool operator==(T* pT) const throw()
{
return m_array == pT;
}
// Inequality
bool operator!=(T* pT) const throw()
{
return !operator==(pT);
}
// Convenient assignment operator. ScopedPtr = NULL will issue an automatic deletion
// of the managed pointer.
ScopedArray& operator=( T* src )
{
return Reassign( src );
}
T& operator[]( uint idx ) const
{
pxAssertDev( idx < m_valid_range, "Array index out of bounds on ScopedArray." );
return m_array[idx];
}
};
// --------------------------------------------------------------------------------------
// pxObjPtr -- fancified version of wxScopedPtr

View File

@ -23,38 +23,6 @@
extern void px_fputs( FILE* fp, const char* src );
// --------------------------------------------------------------------------------------
// toUTF8 - shortcut for str.ToUTF8().data()
// --------------------------------------------------------------------------------------
class toUTF8
{
DeclareNoncopyableObject( toUTF8 );
protected:
wxCharBuffer m_charbuffer;
public:
toUTF8( const wxString& str ) : m_charbuffer( str.ToUTF8().data() ) { }
virtual ~toUTF8() throw() {}
operator const char*() { return m_charbuffer.data(); }
};
// This class provided for completeness sake. You probably should use toUTF8 instead.
class toAscii
{
DeclareNoncopyableObject( toAscii );
protected:
wxCharBuffer m_charbuffer;
public:
toAscii( const wxString& str ) : m_charbuffer( str.ToAscii().data() ) { }
virtual ~toAscii() throw() {}
operator const char*() { return m_charbuffer.data(); }
};
extern wxString fromUTF8( const char* src );
extern wxString fromAscii( const char* src );

View File

@ -25,10 +25,30 @@
#undef Yield // release th burden of windows.h global namespace spam.
class wxTimeSpan;
#define AllowFromMainThreadOnly() \
pxAssertMsg( wxThread::IsMain(), "Thread affinity violation: Call allowed from main thread only." )
namespace Threading
{
//////////////////////////////////////////////////////////////////////////////////////////
// Define some useful object handles - wait events, mutexes.
// --------------------------------------------------------------------------------------
// Platform Specific External APIs
// --------------------------------------------------------------------------------------
// The following set of documented functions have Linux/Win32 specific implementations,
// which are found in WinThreads.cpp and LnxThreads.cpp
// Returns the number of available logical CPUs (cores plus hyperthreaded cpus)
extern void CountLogicalCores( int LogicalCoresPerPhysicalCPU, int PhysicalCoresPerPhysicalCPU );
// Releases a timeslice to other threads.
extern void Timeslice();
// For use in spin/wait loops.
extern void SpinWait();
// sleeps the current thread for the given number of milliseconds.
extern void Sleep( int ms );
// pthread Cond is an evil api that is not suited for Pcsx2 needs.
// Let's not use it. Use mutexes and semaphores instead to create waits. (Air)
@ -39,7 +59,7 @@ namespace Threading
pthread_mutex_t mutex;
WaitEvent();
~WaitEvent();
~WaitEvent() throw();
void Set();
void Wait();
@ -64,7 +84,7 @@ namespace Threading
public:
NonblockingMutex() : val( false ) {}
virtual ~NonblockingMutex() throw() {};
virtual ~NonblockingMutex() throw() {}
bool TryLock() throw()
{
@ -78,25 +98,31 @@ namespace Threading
{ val = false; }
};
struct Semaphore
class Semaphore
{
sem_t sema;
protected:
sem_t m_sema;
public:
Semaphore();
~Semaphore();
virtual ~Semaphore() throw();
void Reset();
void Post();
void Post( int multiple );
#if wxUSE_GUI
void WaitGui();
bool WaitGui( const wxTimeSpan& timeout );
#endif
void Wait();
bool Wait( const wxTimeSpan& timeout );
void WaitRaw();
bool WaitRaw( const wxTimeSpan& timeout );
void WaitNoCancel();
int Count();
#if wxUSE_GUI
void Wait();
bool Wait( const wxTimeSpan& timeout );
protected:
bool _WaitGui_RecursionGuard();
#endif
};
class MutexLock
@ -124,19 +150,6 @@ namespace Threading
virtual ~MutexLockRecursive() throw();
};
// Returns the number of available logical CPUs (cores plus hyperthreaded cpus)
extern void CountLogicalCores( int LogicalCoresPerPhysicalCPU, int PhysicalCoresPerPhysicalCPU );
// Releases a timeslice to other threads.
extern void Timeslice();
// For use in spin/wait loops.
extern void SpinWait();
// sleeps the current thread for the given number of milliseconds.
extern void Sleep( int ms );
// --------------------------------------------------------------------------------------
// IThread - Interface for the public access to PersistentThread.
// --------------------------------------------------------------------------------------
@ -279,8 +292,8 @@ namespace Threading
DeclareNoncopyableObject(ScopedLock);
protected:
MutexLock& m_lock;
bool m_IsLocked;
MutexLock& m_lock;
bool m_IsLocked;
public:
virtual ~ScopedLock() throw()
@ -311,6 +324,25 @@ namespace Threading
m_lock.Lock();
m_IsLocked = true;
}
bool IsLocked() const { return m_IsLocked; }
protected:
// Special constructor used by ScopedTryLock
ScopedLock( MutexLock& locker, bool isTryLock ) :
m_lock( locker )
, m_IsLocked( isTryLock ? m_lock.TryLock() : false )
{
}
};
class ScopedTryLock : public ScopedLock
{
public:
ScopedTryLock( MutexLock& locker ) : ScopedLock( locker, true ) { }
virtual ~ScopedTryLock() throw() {}
bool Failed() const { return !m_IsLocked; }
};
//////////////////////////////////////////////////////////////////////////////////////////

View File

@ -7,11 +7,9 @@ This folder contains various classes borrowed from wxWidgets 2.9.x / 3.0.
/Common/include is a PCSX2 project default include search path, and with the /wx
folder prefix, these files can be included the same way as other wxWidgets includes:
#include <wx/scopedptr.h>
#include <wx/something.h>
If/when PCSX2 upgrades to wx2.9/3.0 these files will be removed and the wxWidgets
distribution files will automatically be used instead.
NOTE: Removed wxScopedPtr in favor of our own implementation, which uses a more
sensible API naming convention and also features better operator assignment.
NOTE: Folder is currently empty, by design. Nothing from 2.9/3.0 is useful anymore (for now).

View File

@ -1,63 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
// Name: wx/scopedarray.h
// Purpose: scoped smart pointer class
// Author: Vadim Zeitlin
// Created: 2009-02-03
// RCS-ID: $Id: scopedarray.h 58634 2009-02-03 12:01:46Z VZ $
// Copyright: (c) Jesse Lovelace and original Boost authors (see below)
// (c) 2009 Vadim Zeitlin
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#pragma once
#include "wx/defs.h"
// ----------------------------------------------------------------------------
// wxScopedArray: A scoped array, same as a wxScopedPtr but uses delete[]
// instead of delete.
// ----------------------------------------------------------------------------
template <class T>
class wxScopedArray
{
public:
typedef T element_type;
wxEXPLICIT wxScopedArray(T * array = NULL) : m_array(array) { }
~wxScopedArray() { delete [] m_array; }
// test for pointer validity: defining conversion to unspecified_bool_type
// and not more obvious bool to avoid implicit conversions to integer types
typedef T *(wxScopedArray<T>::*unspecified_bool_type)() const;
operator unspecified_bool_type() const
{
return m_array ? &wxScopedArray<T>::get : NULL;
}
void reset(T *array = NULL)
{
if ( array != m_array )
{
delete [] m_array;
m_array = array;
}
}
T& operator[](size_t n) const { return m_array[n]; }
T *get() const { return m_array; }
void swap(wxScopedArray &other)
{
T * const tmp = other.m_array;
other.m_array = m_array;
m_array = tmp;
}
private:
T *m_array;
wxScopedArray(const wxScopedArray<T>&);
wxScopedArray& operator=(const wxScopedArray<T>&);
};

View File

@ -146,7 +146,7 @@ void ConsoleBuffer_Clear()
void ConsoleBuffer_FlushToFile( FILE *fp )
{
if( fp == NULL || m_buffer.IsEmpty() ) return;
px_fputs( fp, toUTF8(m_buffer) );
px_fputs( fp, m_buffer.ToUTF8() );
m_buffer.Clear();
}

View File

@ -45,11 +45,6 @@ namespace Threading
}
}
__forceinline void Timeslice()
{
usleep(500);
}
__forceinline void Sleep( int ms )
{
usleep( 1000*ms );

File diff suppressed because it is too large Load Diff

View File

@ -51,11 +51,6 @@ namespace Threading
//ptw32_smp_system = ( x86caps.LogicalCores > 1 ) ? TRUE : FALSE;
}
__forceinline void Timeslice()
{
::Sleep(0);
}
__forceinline void Sleep( int ms )
{
::Sleep( ms );

View File

@ -81,11 +81,11 @@ FILE *_cdvdOpenMechaVer()
const wxCharBuffer file( mecfile.GetFullPath().ToUTF8() );
// if file doesnt exist, create empty one
fd = fopen(file.data(), "r+b");
fd = fopen(file, "r+b");
if (fd == NULL)
{
Console.Notice("MEC File Not Found , Creating Blank File");
fd = fopen(file.data(), "wb");
fd = fopen(file, "wb");
if (fd == NULL)
{
Console.Error( "\tMEC File Creation failed!" );
@ -121,11 +121,11 @@ FILE *_cdvdOpenNVM()
const wxCharBuffer file( nvmfile.GetFullPath().ToUTF8() );
// if file doesn't exist, create empty one
fd = fopen(file.data(), "r+b");
fd = fopen(file, "r+b");
if (fd == NULL)
{
Console.Notice("NVM File Not Found , Creating Blank File");
fd = fopen(file.data(), "wb");
fd = fopen(file, "wb");
if (fd == NULL)
{
Console.Error( "\tNVM File Creation failed!" );
@ -301,11 +301,15 @@ s32 cdvdWriteConfig(const u8* config)
}
}
void reloadElfInfo(const char* str)
static MutexLockRecursive Mutex_NewDiskCB;
static void reloadElfInfo(const char* str)
{
// Now's a good time to reload the ELF info...
// Now's a good time to reload the ELF info...
if (ElfCRC == 0)
{
ScopedLock locker( Mutex_NewDiskCB );
ElfCRC = loadElfCRC( str );
ElfApplyPatches();
mtgsThread.SendGameCRC( ElfCRC );
@ -504,7 +508,7 @@ void SaveStateBase::cdvdFreeze()
}
}
void cdvdDetectDisk()
static void cdvdDetectDisk()
{
cdvd.Type = DoCDVDdetectDiskType();
@ -516,12 +520,14 @@ void cdvdDetectDisk()
void cdvdNewDiskCB()
{
if( !Mutex_NewDiskCB.TryLock() ) return;
DoCDVDresetDiskTypeCache();
cdvdDetectDisk();
try { cdvdDetectDisk(); }
catch(...) { Mutex_NewDiskCB.Unlock(); } // ensure mutex gets unlocked.
}
void mechaDecryptBytes( u32 madr, int size )
static void mechaDecryptBytes( u32 madr, int size )
{
int shiftAmount = (cdvd.decSet>>4) & 7;
int doXor = (cdvd.decSet) & 1;

View File

@ -137,7 +137,6 @@ extern void cdvdActionInterrupt();
extern void cdvdReadInterrupt();
// We really should not have a function with the exact same name as a callback except for case!
extern void cdvdDetectDisk();
extern void cdvdNewDiskCB();
extern u8 cdvdRead(u8 key);
extern void cdvdWrite(u8 key, u8 rt);

View File

@ -292,15 +292,17 @@ void CDVDsys_ChangeSource( CDVD_SourceType type )
jNO_DEFAULT;
}
CDVD->newDiskCB( cdvdNewDiskCB );
}
bool DoCDVDopen()
{
CheckNullCDVD();
int ret = CDVD->open( m_SourceFilename[m_CurrentSourceType].IsEmpty() ? NULL : m_SourceFilename[m_CurrentSourceType].ToUTF8().data() );
// the new disk callback is set on Init also, but just in case the plugin clears it for
// some reason on close, we re-send here:
CDVD->newDiskCB( cdvdNewDiskCB );
int ret = CDVD->open( !m_SourceFilename[m_CurrentSourceType].IsEmpty() ? m_SourceFilename[m_CurrentSourceType].ToUTF8() : (char*)NULL );
if( ret == -1 ) return false;
int cdtype = DoCDVDdetectDiskType();

View File

@ -439,7 +439,7 @@ __forceinline void rcntUpdate_vSync()
{
eeRecIsReset = false;
mtgsThread.RethrowException();
SysCoreThread::Get().StateCheck();
SysCoreThread::Get().StateCheckInThread();
if( eeRecIsReset )
{
eeRecIsReset = false;

View File

@ -527,7 +527,7 @@ void gsDynamicSkipEnable()
{
if( !m_StrictSkipping ) return;
mtgsWaitGS();
mtgsThread.WaitGS();
m_iSlowStart = GetCPUTicks();
frameLimitReset();
}

View File

@ -82,9 +82,9 @@ struct MTGS_FreezeData
s32 retval; // value returned from the call, valid only after an mtgsWaitGS()
};
class mtgsThreadObject : public SysSuspendableThread
class mtgsThreadObject : public SysThreadBase
{
typedef SysSuspendableThread _parent;
typedef SysThreadBase _parent;
protected:
// note: when g_pGSRingPos == g_pGSWritePos, the fifo is empty
@ -170,8 +170,6 @@ protected:
extern __aligned16 mtgsThreadObject mtgsThread;
void mtgsWaitGS();
/////////////////////////////////////////////////////////////////////////////
// Generalized GS Functions and Stuff

View File

@ -1,466 +1,466 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="pcsx2" />
<Option platforms="Windows;Unix;" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option platforms="Windows;Unix;" />
<Option output="$(SvnRootDir)/bin/pcsx2-dbg" prefix_auto="1" extension_auto="1" />
<Option working_dir="$(SvnRootDir)/bin/" />
<Option object_output="./.objs/debug" />
<Option external_deps="../../tools/bin/bin2cpp;" />
<Option type="0" />
<Option compiler="gcc" />
<Compiler>
<Add option="-g" />
<Add option="`wx-config --version=2.8 --static=no --unicode=yes --debug=yes --cflags`" />
<Add option="-DPCSX2_DEVBUILD" />
<Add option="-DPCSX2_DEBUG" />
</Compiler>
<ResourceCompiler>
<Add directory="$(ProjectRootDir)/gui" />
</ResourceCompiler>
<Linker>
<Add option="`wx-config --version=2.8 --static=no --unicode=yes --debug=yes --libs`" />
<Add library="$(SvnRootDir)/deps/debug/zlib.a" />
<Add library="$(SvnRootDir)/deps/debug/libx86emitter.a" />
<Add library="$(SvnRootDir)/deps/debug/libUtilities.a" />
</Linker>
</Target>
<Target title="Devel">
<Option platforms="Windows;Unix;" />
<Option output="$(SvnRootDir)/bin/pcsx2-dev" prefix_auto="1" extension_auto="1" />
<Option working_dir="$(SvnRootDir)/bin/" />
<Option object_output="./.objs/devel" />
<Option external_deps="../../tools/bin/bin2cpp;" />
<Option type="0" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
<Add option="-W" />
<Add option="`wx-config --version=2.8 --static=no --unicode=yes --debug=yes --cflags`" />
<Add option="-DNDEBUG" />
<Add option="-DPCSX2_DEVBUILD" />
<Add option="-DPCSX2_DEVEL" />
</Compiler>
<ResourceCompiler>
<Add directory="$(ProjectRootDir)/gui" />
</ResourceCompiler>
<Linker>
<Add option="`wx-config --version=2.8 --static=no --unicode=yes --debug=yes --libs`" />
<Add library="$(SvnRootDir)/deps/devel/zlib.a" />
<Add library="$(SvnRootDir)/deps/devel/libx86emitter.a" />
<Add library="$(SvnRootDir)/deps/devel/libUtilities.a" />
</Linker>
</Target>
<Target title="Release">
<Option platforms="Windows;Unix;" />
<Option output="$(SvnRootDir)/bin/pcsx2" prefix_auto="1" extension_auto="1" />
<Option working_dir="$(SvnRootDir)/bin/" />
<Option object_output="./.objs/release" />
<Option external_deps="../../tools/bin/bin2cpp;" />
<Option type="0" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
<Add option="`wx-config --version=2.8 --static=no --unicode=yes --debug=no --cflags`" />
<Add option="-DNDEBUG" />
</Compiler>
<ResourceCompiler>
<Add directory="$(ProjectRootDir)/gui" />
</ResourceCompiler>
<Linker>
<Add option="-s" />
<Add option="`wx-config --version=2.8 --static=no --unicode=yes --debug=no --libs`" />
<Add library="$(SvnRootDir)/deps/release/zlib.a" />
<Add library="$(SvnRootDir)/deps/release/libx86emitter.a" />
<Add library="$(SvnRootDir)/deps/release/libUtilities.a" />
</Linker>
</Target>
<Environment>
<Variable name="SvnRootDir" value="../../" />
<Variable name="ProjectRootDir" value='&quot;$(SvnRootDir)/pcsx2/&quot;' />
<Variable name="CommonDir" value='&quot;$(SvnRootDir)/common/&quot;' />
</Environment>
</Build>
<Compiler>
<Add option="-Wno-format" />
<Add option="-Wno-unused-parameter" />
<Add option="-Wno-unused-value" />
<Add option="-Wunused-variable" />
<Add option="-fno-guess-branch-probability" />
<Add option="-fno-dse" />
<Add option="-fno-tree-dse" />
<Add option="-pipe -msse -msse2" />
<Add option="-mpreferred-stack-boundary=2" />
<Add option="-DWX_PRECOMP" />
<Add directory="$(SvnRootDir)/common/include/" />
<Add directory="$(SvnRootDir)/3rdparty/" />
<Add directory="$(ProjectRootDir)" />
<Add directory="$(ProjectRootDir)/gui" />
<Add directory="$(ProjectRootDir)/x86" />
</Compiler>
<Unit filename="../../common/include/PS2Edefs.h" />
<Unit filename="../../common/include/PS2Etypes.h" />
<Unit filename="../../common/include/Pcsx2Api.h" />
<Unit filename="../../common/include/Pcsx2Defs.h" />
<Unit filename="../../common/include/Pcsx2Types.h" />
<Unit filename="../../common/include/PluginCallbacks.h" />
<Unit filename="../../common/include/wx/folderdesc.txt" />
<Unit filename="../../common/include/wx/scopedarray.h" />
<Unit filename="../CDVD/CDVD.cpp" />
<Unit filename="../CDVD/CDVD.h" />
<Unit filename="../CDVD/CDVD_internal.h" />
<Unit filename="../CDVD/CDVDaccess.cpp" />
<Unit filename="../CDVD/CDVDaccess.h" />
<Unit filename="../CDVD/CDVDisoReader.cpp" />
<Unit filename="../CDVD/CDVDisoReader.h" />
<Unit filename="../CDVD/CdRom.cpp" />
<Unit filename="../CDVD/CdRom.h" />
<Unit filename="../CDVD/IsoFScdvd.h" />
<Unit filename="../CDVD/IsoFSdrv.cpp" />
<Unit filename="../CDVD/IsoFSdrv.h" />
<Unit filename="../CDVD/IsoFStools.cpp" />
<Unit filename="../CDVD/IsoFStools.h" />
<Unit filename="../CDVD/IsoFileFormats.cpp" />
<Unit filename="../CDVD/IsoFileFormats.h" />
<Unit filename="../CDVD/IsoFileTools.cpp" />
<Unit filename="../CDVD/IsoFileTools.h" />
<Unit filename="../COP0.cpp" />
<Unit filename="../COP2.cpp" />
<Unit filename="../Cache.cpp" />
<Unit filename="../Cache.h" />
<Unit filename="../Common.h" />
<Unit filename="../Config.h" />
<Unit filename="../Counters.cpp" />
<Unit filename="../Counters.h" />
<Unit filename="../DebugTools/Debug.h" />
<Unit filename="../DebugTools/DisASM.h" />
<Unit filename="../DebugTools/DisR3000A.cpp" />
<Unit filename="../DebugTools/DisR5900.cpp" />
<Unit filename="../DebugTools/DisR5900asm.cpp" />
<Unit filename="../DebugTools/DisVU0Micro.cpp" />
<Unit filename="../DebugTools/DisVU1Micro.cpp" />
<Unit filename="../DebugTools/DisVUmicro.h" />
<Unit filename="../DebugTools/DisVUops.h" />
<Unit filename="../Docs/ChangeLog.txt" />
<Unit filename="../Docs/License.txt" />
<Unit filename="../Docs/devblog.txt" />
<Unit filename="../Dump.cpp" />
<Unit filename="../Dump.h" />
<Unit filename="../Elfheader.cpp" />
<Unit filename="../Elfheader.h" />
<Unit filename="../FPU.cpp" />
<Unit filename="../FiFo.cpp" />
<Unit filename="../GS.cpp" />
<Unit filename="../GS.h" />
<Unit filename="../GSState.cpp" />
<Unit filename="../Gif.cpp" />
<Unit filename="../Gif.h" />
<Unit filename="../HostGui.h" />
<Unit filename="../Hw.cpp" />
<Unit filename="../Hw.h" />
<Unit filename="../HwRead.cpp" />
<Unit filename="../HwWrite.cpp" />
<Unit filename="../IPU/IPU.cpp" />
<Unit filename="../IPU/IPU.h" />
<Unit filename="../IPU/acoroutine.S" />
<Unit filename="../IPU/coroutine.cpp" />
<Unit filename="../IPU/coroutine.h" />
<Unit filename="../IPU/mpeg2lib/Idct.cpp" />
<Unit filename="../IPU/mpeg2lib/Mpeg.cpp" />
<Unit filename="../IPU/mpeg2lib/Mpeg.h" />
<Unit filename="../IPU/mpeg2lib/Vlc.h" />
<Unit filename="../IPU/yuv2rgb.cpp" />
<Unit filename="../IPU/yuv2rgb.h" />
<Unit filename="../Interpreter.cpp" />
<Unit filename="../IopBios.cpp" />
<Unit filename="../IopBios.h" />
<Unit filename="../IopBios2.h" />
<Unit filename="../IopCommon.h" />
<Unit filename="../IopCounters.cpp" />
<Unit filename="../IopCounters.h" />
<Unit filename="../IopDma.cpp" />
<Unit filename="../IopDma.h" />
<Unit filename="../IopHw.cpp" />
<Unit filename="../IopHw.h" />
<Unit filename="../IopMem.cpp" />
<Unit filename="../IopMem.h" />
<Unit filename="../IopSio2.cpp" />
<Unit filename="../IopSio2.h" />
<Unit filename="LnxHostSys.cpp" />
<Unit filename="LnxKeyCodes.cpp">
<Option compiler="gcc" use="1" buildCommand="$compiler $options $includes `pkg-config gtk+-2.0 --cflags` -c $file -o $object" />
</Unit>
<Unit filename="../MMI.cpp" />
<Unit filename="../MTGS.cpp" />
<Unit filename="../Memory.cpp" />
<Unit filename="../Memory.h" />
<Unit filename="../NakedAsm.h" />
<Unit filename="../Patch.cpp" />
<Unit filename="../Patch.h" />
<Unit filename="../PathDefs.h" />
<Unit filename="../Pcsx2Config.cpp" />
<Unit filename="../PluginManager.cpp" />
<Unit filename="../Plugins.h" />
<Unit filename="../PrecompiledHeader.h" />
<Unit filename="../R3000A.cpp" />
<Unit filename="../R3000A.h" />
<Unit filename="../R3000AInterpreter.cpp" />
<Unit filename="../R3000AOpcodeTables.cpp" />
<Unit filename="../R5900.cpp" />
<Unit filename="../R5900.h" />
<Unit filename="../R5900Exceptions.h" />
<Unit filename="../R5900OpcodeImpl.cpp" />
<Unit filename="../R5900OpcodeTables.cpp" />
<Unit filename="../R5900OpcodeTables.h" />
<Unit filename="../RecoverySystem.cpp" />
<Unit filename="../SPR.cpp" />
<Unit filename="../SPR.h" />
<Unit filename="../SamplProf.h" />
<Unit filename="../SaveState.cpp" />
<Unit filename="../SaveState.h" />
<Unit filename="../Sif.cpp" />
<Unit filename="../Sif.h" />
<Unit filename="../Sifcmd.h" />
<Unit filename="../Sio.cpp" />
<Unit filename="../Sio.h" />
<Unit filename="../SourceLog.cpp" />
<Unit filename="../Stats.cpp" />
<Unit filename="../Stats.h" />
<Unit filename="../StringUtils.h" />
<Unit filename="../System.cpp" />
<Unit filename="../System.h" />
<Unit filename="../System/SysThreads.cpp" />
<Unit filename="../System/SysThreads.h" />
<Unit filename="../Tags.h" />
<Unit filename="../Utilities/AsciiFile.h" />
<Unit filename="../Utilities/FileUtils.cpp" />
<Unit filename="../Utilities/folderdesc.txt" />
<Unit filename="../VU.h" />
<Unit filename="../VU0.cpp" />
<Unit filename="../VU0micro.cpp" />
<Unit filename="../VU0microInterp.cpp" />
<Unit filename="../VU1micro.cpp" />
<Unit filename="../VU1microInterp.cpp" />
<Unit filename="../VUflags.cpp" />
<Unit filename="../VUflags.h" />
<Unit filename="../VUmicro.h" />
<Unit filename="../VUmicroMem.cpp" />
<Unit filename="../VUops.cpp" />
<Unit filename="../VUops.h" />
<Unit filename="../Vif.cpp" />
<Unit filename="../Vif.h" />
<Unit filename="../Vif0Dma.cpp" />
<Unit filename="../Vif1Dma.cpp" />
<Unit filename="../VifDma.cpp" />
<Unit filename="../VifDma.h" />
<Unit filename="../VifDma_internal.h" />
<Unit filename="../gui/AdvancedDialog.cpp" />
<Unit filename="../gui/AdvancedDialog.h" />
<Unit filename="../gui/App.h" />
<Unit filename="../gui/AppAssert.cpp" />
<Unit filename="../gui/AppConfig.cpp" />
<Unit filename="../gui/AppConfig.h" />
<Unit filename="../gui/AppCoreThread.cpp" />
<Unit filename="../gui/AppInit.cpp" />
<Unit filename="../gui/AppMain.cpp" />
<Unit filename="../gui/AppRes.cpp" />
<Unit filename="../gui/CheckedStaticBox.cpp" />
<Unit filename="../gui/CheckedStaticBox.h" />
<Unit filename="../gui/ConsoleLogger.cpp" />
<Unit filename="../gui/ConsoleLogger.h" />
<Unit filename="../gui/Dialogs/AboutBoxDialog.cpp" />
<Unit filename="../gui/Dialogs/ConfigurationDialog.cpp" />
<Unit filename="../gui/Dialogs/ConfigurationDialog.h" />
<Unit filename="../gui/Dialogs/FirstTimeWizard.cpp" />
<Unit filename="../gui/Dialogs/ImportSettingsDialog.cpp" />
<Unit filename="../gui/Dialogs/LogOptionsDialog.cpp" />
<Unit filename="../gui/Dialogs/LogOptionsDialog.h" />
<Unit filename="../gui/Dialogs/ModalPopups.h" />
<Unit filename="../gui/Dialogs/PickUserModeDialog.cpp" />
<Unit filename="../gui/FrameForGS.cpp" />
<Unit filename="../gui/GlobalCommands.cpp" />
<Unit filename="../gui/IniInterface.cpp" />
<Unit filename="../gui/IniInterface.h" />
<Unit filename="../gui/MainFrame.cpp" />
<Unit filename="../gui/MainFrame.h" />
<Unit filename="../gui/MainMenuClicks.cpp" />
<Unit filename="../gui/MemoryCardFile.cpp" />
<Unit filename="../gui/Panels/AudioPanel.cpp" />
<Unit filename="../gui/Panels/BiosSelectorPanel.cpp" />
<Unit filename="../gui/Panels/ConfigurationPanels.h" />
<Unit filename="../gui/Panels/CpuPanel.cpp" />
<Unit filename="../gui/Panels/DirPickerPanel.cpp" />
<Unit filename="../gui/Panels/GameFixesPanel.cpp" />
<Unit filename="../gui/Panels/MiscPanelStuff.cpp" />
<Unit filename="../gui/Panels/PathsPanel.cpp" />
<Unit filename="../gui/Panels/PluginSelectorPanel.cpp" />
<Unit filename="../gui/Panels/SpeedhacksPanel.cpp" />
<Unit filename="../gui/Panels/VideoPanel.cpp" />
<Unit filename="../gui/Plugins.cpp" />
<Unit filename="../gui/Resources/AppIcon16.h" />
<Unit filename="../gui/Resources/AppIcon16.png">
<Option compile="1" />
<Option weight="0" />
<Option compiler="gcc" use="1" buildCommand="$(SvnRootDir)/tools/bin2app.sh $(SvnRootDir) $file" />
</Unit>
<Unit filename="../gui/Resources/AppIcon32.h" />
<Unit filename="../gui/Resources/AppIcon32.png">
<Option compile="1" />
<Option weight="0" />
<Option compiler="gcc" use="1" buildCommand="$(SvnRootDir)/tools/bin2app.sh $(SvnRootDir) $file" />
</Unit>
<Unit filename="../gui/Resources/AppIcon64.h" />
<Unit filename="../gui/Resources/AppIcon64.png">
<Option compile="1" />
<Option weight="0" />
<Option compiler="gcc" use="1" buildCommand="$(SvnRootDir)/tools/bin2app.sh $(SvnRootDir) $file" />
</Unit>
<Unit filename="../gui/Resources/BackgroundLogo.h" />
<Unit filename="../gui/Resources/BackgroundLogo.png">
<Option compile="1" />
<Option weight="0" />
<Option compiler="gcc" use="1" buildCommand="$(SvnRootDir)/tools/bin2app.sh $(SvnRootDir) $file" />
</Unit>
<Unit filename="../gui/Resources/ConfigIcon_Cpu.h" />
<Unit filename="../gui/Resources/ConfigIcon_Cpu.png">
<Option compile="1" />
<Option weight="0" />
<Option compiler="gcc" use="1" buildCommand="$(SvnRootDir)/tools/bin2app.sh $(SvnRootDir) $file" />
</Unit>
<Unit filename="../gui/Resources/ConfigIcon_Gamefixes.h" />
<Unit filename="../gui/Resources/ConfigIcon_Gamefixes.png">
<Option compile="1" />
<Option weight="0" />
<Option compiler="gcc" use="1" buildCommand="$(SvnRootDir)/tools/bin2app.sh $(SvnRootDir) $file" />
</Unit>
<Unit filename="../gui/Resources/ConfigIcon_Paths.h" />
<Unit filename="../gui/Resources/ConfigIcon_Paths.png">
<Option compile="1" />
<Option weight="0" />
<Option compiler="gcc" use="1" buildCommand="$(SvnRootDir)/tools/bin2app.sh $(SvnRootDir) $file" />
</Unit>
<Unit filename="../gui/Resources/ConfigIcon_Plugins.h" />
<Unit filename="../gui/Resources/ConfigIcon_Plugins.png">
<Option compile="1" />
<Option weight="0" />
<Option compiler="gcc" use="1" buildCommand="$(SvnRootDir)/tools/bin2app.sh $(SvnRootDir) $file" />
</Unit>
<Unit filename="../gui/Resources/ConfigIcon_Speedhacks.h" />
<Unit filename="../gui/Resources/ConfigIcon_Speedhacks.png">
<Option compile="1" />
<Option weight="0" />
<Option compiler="gcc" use="1" buildCommand="$(SvnRootDir)/tools/bin2app.sh $(SvnRootDir) $file" />
</Unit>
<Unit filename="../gui/Resources/ConfigIcon_Video.h" />
<Unit filename="../gui/Resources/ConfigIcon_Video.png">
<Option compile="1" />
<Option weight="0" />
<Option compiler="gcc" use="1" buildCommand="$(SvnRootDir)/tools/bin2app.sh $(SvnRootDir) $file" />
</Unit>
<Unit filename="../gui/Resources/Dualshock.h" />
<Unit filename="../gui/Resources/Dualshock.jpg">
<Option compile="1" />
<Option weight="0" />
<Option compiler="gcc" use="1" buildCommand="$(SvnRootDir)/tools/bin2app.sh $(SvnRootDir) $file" />
</Unit>
<Unit filename="../gui/Resources/EmbeddedImage.h" />
<Unit filename="../gui/Saveslots.cpp" />
<Unit filename="../gui/i18n.cpp" />
<Unit filename="../gui/i18n.h" />
<Unit filename="../gui/wxHelpers.cpp" />
<Unit filename="../gui/wxHelpers.h" />
<Unit filename="../ps2/BiosTools.cpp" />
<Unit filename="../ps2/BiosTools.h" />
<Unit filename="../ps2/GIFpath.cpp" />
<Unit filename="../ps2/Iop/IopHwRead.cpp" />
<Unit filename="../ps2/Iop/IopHwWrite.cpp" />
<Unit filename="../ps2/Iop/IopHw_Internal.h" />
<Unit filename="../vtlb.cpp" />
<Unit filename="../vtlb.h" />
<Unit filename="../x86/BaseblockEx.cpp" />
<Unit filename="../x86/BaseblockEx.h" />
<Unit filename="../x86/aR3000A.S" />
<Unit filename="../x86/aVUzerorec.S" />
<Unit filename="../x86/aVif.S" />
<Unit filename="../x86/iCOP0.cpp" />
<Unit filename="../x86/iCOP0.h" />
<Unit filename="../x86/iCOP2.cpp" />
<Unit filename="../x86/iCore.cpp" />
<Unit filename="../x86/iCore.h" />
<Unit filename="../x86/iFPU.cpp" />
<Unit filename="../x86/iFPU.h" />
<Unit filename="../x86/iFPUd.cpp" />
<Unit filename="../x86/iMMI.cpp" />
<Unit filename="../x86/iMMI.h" />
<Unit filename="../x86/iMisc.cpp" />
<Unit filename="../x86/iR3000A.cpp" />
<Unit filename="../x86/iR3000A.h" />
<Unit filename="../x86/iR3000Atables.cpp" />
<Unit filename="../x86/iR5900.h" />
<Unit filename="../x86/iR5900Arit.h" />
<Unit filename="../x86/iR5900AritImm.h" />
<Unit filename="../x86/iR5900Branch.h" />
<Unit filename="../x86/iR5900Jump.h" />
<Unit filename="../x86/iR5900LoadStore.h" />
<Unit filename="../x86/iR5900Misc.cpp" />
<Unit filename="../x86/iR5900Move.h" />
<Unit filename="../x86/iR5900MultDiv.h" />
<Unit filename="../x86/iR5900Shift.h" />
<Unit filename="../x86/iVU0micro.cpp" />
<Unit filename="../x86/iVU1micro.cpp" />
<Unit filename="../x86/iVif.cpp">
<Option compiler="gcc" use="0" buildCommand="gcc $options -S $includes -c $file -o $object" />
</Unit>
<Unit filename="../x86/ir5900tables.cpp" />
<Unit filename="../x86/ix86-32/aR5900-32.S" />
<Unit filename="../x86/ix86-32/iCore-32.cpp" />
<Unit filename="../x86/ix86-32/iR5900-32.cpp" />
<Unit filename="../x86/ix86-32/iR5900Arit.cpp" />
<Unit filename="../x86/ix86-32/iR5900AritImm.cpp" />
<Unit filename="../x86/ix86-32/iR5900Branch.cpp" />
<Unit filename="../x86/ix86-32/iR5900Jump.cpp" />
<Unit filename="../x86/ix86-32/iR5900LoadStore.cpp" />
<Unit filename="../x86/ix86-32/iR5900Move.cpp" />
<Unit filename="../x86/ix86-32/iR5900MultDiv.cpp" />
<Unit filename="../x86/ix86-32/iR5900Shift.cpp" />
<Unit filename="../x86/ix86-32/iR5900Templates.cpp" />
<Unit filename="../x86/ix86-32/recVTLB.cpp" />
<Unit filename="../x86/microVU.cpp" />
<Unit filename="../x86/microVU.h" />
<Unit filename="../x86/microVU_Alloc.inl" />
<Unit filename="../x86/microVU_Analyze.inl" />
<Unit filename="../x86/microVU_Branch.inl" />
<Unit filename="../x86/microVU_Compile.inl" />
<Unit filename="../x86/microVU_Execute.inl" />
<Unit filename="../x86/microVU_Flags.inl" />
<Unit filename="../x86/microVU_IR.h" />
<Unit filename="../x86/microVU_Log.inl" />
<Unit filename="../x86/microVU_Lower.inl" />
<Unit filename="../x86/microVU_Macro.inl" />
<Unit filename="../x86/microVU_Misc.h" />
<Unit filename="../x86/microVU_Misc.inl" />
<Unit filename="../x86/microVU_Tables.inl" />
<Unit filename="../x86/microVU_Upper.inl" />
<Unit filename="../x86/sVU_Debug.h" />
<Unit filename="../x86/sVU_Lower.cpp" />
<Unit filename="../x86/sVU_Micro.cpp" />
<Unit filename="../x86/sVU_Micro.h" />
<Unit filename="../x86/sVU_Upper.cpp" />
<Unit filename="../x86/sVU_zerorec.cpp" />
<Unit filename="../x86/sVU_zerorec.h" />
<Extensions>
<envvars />
<code_completion>
<search_path add="/usr/include/wx-2.8" />
</code_completion>
<lib_finder disable_auto="1" />
<debugger />
</Extensions>
</Project>
</CodeBlocks_project_file>
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="pcsx2" />
<Option platforms="Windows;Unix;" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option platforms="Windows;Unix;" />
<Option output="$(SvnRootDir)/bin/pcsx2-dbg" prefix_auto="1" extension_auto="1" />
<Option working_dir="$(SvnRootDir)/bin/" />
<Option object_output="./.objs/debug" />
<Option external_deps="../../tools/bin/bin2cpp;" />
<Option type="0" />
<Option compiler="gcc" />
<Compiler>
<Add option="-g" />
<Add option="`wx-config --version=2.8 --static=no --unicode=yes --debug=yes --cflags`" />
<Add option="-DPCSX2_DEVBUILD" />
<Add option="-DPCSX2_DEBUG" />
</Compiler>
<ResourceCompiler>
<Add directory="$(ProjectRootDir)/gui" />
</ResourceCompiler>
<Linker>
<Add option="`wx-config --version=2.8 --static=no --unicode=yes --debug=yes --libs`" />
<Add library="$(SvnRootDir)/deps/debug/zlib.a" />
<Add library="$(SvnRootDir)/deps/debug/libx86emitter.a" />
<Add library="$(SvnRootDir)/deps/debug/libUtilities.a" />
</Linker>
</Target>
<Target title="Devel">
<Option platforms="Windows;Unix;" />
<Option output="$(SvnRootDir)/bin/pcsx2-dev" prefix_auto="1" extension_auto="1" />
<Option working_dir="$(SvnRootDir)/bin/" />
<Option object_output="./.objs/devel" />
<Option external_deps="../../tools/bin/bin2cpp;" />
<Option type="0" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
<Add option="-W" />
<Add option="`wx-config --version=2.8 --static=no --unicode=yes --debug=yes --cflags`" />
<Add option="-DNDEBUG" />
<Add option="-DPCSX2_DEVBUILD" />
<Add option="-DPCSX2_DEVEL" />
</Compiler>
<ResourceCompiler>
<Add directory="$(ProjectRootDir)/gui" />
</ResourceCompiler>
<Linker>
<Add option="`wx-config --version=2.8 --static=no --unicode=yes --debug=yes --libs`" />
<Add library="$(SvnRootDir)/deps/devel/zlib.a" />
<Add library="$(SvnRootDir)/deps/devel/libx86emitter.a" />
<Add library="$(SvnRootDir)/deps/devel/libUtilities.a" />
</Linker>
</Target>
<Target title="Release">
<Option platforms="Windows;Unix;" />
<Option output="$(SvnRootDir)/bin/pcsx2" prefix_auto="1" extension_auto="1" />
<Option working_dir="$(SvnRootDir)/bin/" />
<Option object_output="./.objs/release" />
<Option external_deps="../../tools/bin/bin2cpp;" />
<Option type="0" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
<Add option="`wx-config --version=2.8 --static=no --unicode=yes --debug=no --cflags`" />
<Add option="-DNDEBUG" />
</Compiler>
<ResourceCompiler>
<Add directory="$(ProjectRootDir)/gui" />
</ResourceCompiler>
<Linker>
<Add option="-s" />
<Add option="`wx-config --version=2.8 --static=no --unicode=yes --debug=no --libs`" />
<Add library="$(SvnRootDir)/deps/release/zlib.a" />
<Add library="$(SvnRootDir)/deps/release/libx86emitter.a" />
<Add library="$(SvnRootDir)/deps/release/libUtilities.a" />
</Linker>
</Target>
<Environment>
<Variable name="SvnRootDir" value="../../" />
<Variable name="ProjectRootDir" value='&quot;$(SvnRootDir)/pcsx2/&quot;' />
<Variable name="CommonDir" value='&quot;$(SvnRootDir)/common/&quot;' />
</Environment>
</Build>
<Compiler>
<Add option="-Wno-format" />
<Add option="-Wno-unused-parameter" />
<Add option="-Wno-unused-value" />
<Add option="-Wunused-variable" />
<Add option="-fno-guess-branch-probability" />
<Add option="-fno-dse" />
<Add option="-fno-tree-dse" />
<Add option="-pipe -msse -msse2" />
<Add option="-mpreferred-stack-boundary=2" />
<Add option="-DWX_PRECOMP" />
<Add directory="$(SvnRootDir)/common/include/" />
<Add directory="$(SvnRootDir)/3rdparty/" />
<Add directory="$(ProjectRootDir)" />
<Add directory="$(ProjectRootDir)/gui" />
<Add directory="$(ProjectRootDir)/x86" />
</Compiler>
<Unit filename="../../common/include/PS2Edefs.h" />
<Unit filename="../../common/include/PS2Etypes.h" />
<Unit filename="../../common/include/Pcsx2Api.h" />
<Unit filename="../../common/include/Pcsx2Defs.h" />
<Unit filename="../../common/include/Pcsx2Types.h" />
<Unit filename="../../common/include/PluginCallbacks.h" />
<Unit filename="../../common/include/wx/folderdesc.txt" />
<Unit filename="../CDVD/CDVD.cpp" />
<Unit filename="../CDVD/CDVD.h" />
<Unit filename="../CDVD/CDVD_internal.h" />
<Unit filename="../CDVD/CDVDaccess.cpp" />
<Unit filename="../CDVD/CDVDaccess.h" />
<Unit filename="../CDVD/CDVDisoReader.cpp" />
<Unit filename="../CDVD/CDVDisoReader.h" />
<Unit filename="../CDVD/CdRom.cpp" />
<Unit filename="../CDVD/CdRom.h" />
<Unit filename="../CDVD/IsoFScdvd.h" />
<Unit filename="../CDVD/IsoFSdrv.cpp" />
<Unit filename="../CDVD/IsoFSdrv.h" />
<Unit filename="../CDVD/IsoFStools.cpp" />
<Unit filename="../CDVD/IsoFStools.h" />
<Unit filename="../CDVD/IsoFileFormats.cpp" />
<Unit filename="../CDVD/IsoFileFormats.h" />
<Unit filename="../CDVD/IsoFileTools.cpp" />
<Unit filename="../CDVD/IsoFileTools.h" />
<Unit filename="../COP0.cpp" />
<Unit filename="../COP2.cpp" />
<Unit filename="../Cache.cpp" />
<Unit filename="../Cache.h" />
<Unit filename="../Common.h" />
<Unit filename="../Config.h" />
<Unit filename="../Counters.cpp" />
<Unit filename="../Counters.h" />
<Unit filename="../DebugTools/Debug.h" />
<Unit filename="../DebugTools/DisASM.h" />
<Unit filename="../DebugTools/DisR3000A.cpp" />
<Unit filename="../DebugTools/DisR5900.cpp" />
<Unit filename="../DebugTools/DisR5900asm.cpp" />
<Unit filename="../DebugTools/DisVU0Micro.cpp" />
<Unit filename="../DebugTools/DisVU1Micro.cpp" />
<Unit filename="../DebugTools/DisVUmicro.h" />
<Unit filename="../DebugTools/DisVUops.h" />
<Unit filename="../Docs/ChangeLog.txt" />
<Unit filename="../Docs/License.txt" />
<Unit filename="../Docs/devblog.txt" />
<Unit filename="../Dump.cpp" />
<Unit filename="../Dump.h" />
<Unit filename="../Elfheader.cpp" />
<Unit filename="../Elfheader.h" />
<Unit filename="../FPU.cpp" />
<Unit filename="../FiFo.cpp" />
<Unit filename="../GS.cpp" />
<Unit filename="../GS.h" />
<Unit filename="../GSState.cpp" />
<Unit filename="../Gif.cpp" />
<Unit filename="../Gif.h" />
<Unit filename="../HostGui.h" />
<Unit filename="../Hw.cpp" />
<Unit filename="../Hw.h" />
<Unit filename="../HwRead.cpp" />
<Unit filename="../HwWrite.cpp" />
<Unit filename="../IPU/IPU.cpp" />
<Unit filename="../IPU/IPU.h" />
<Unit filename="../IPU/acoroutine.S" />
<Unit filename="../IPU/coroutine.cpp" />
<Unit filename="../IPU/coroutine.h" />
<Unit filename="../IPU/mpeg2lib/Idct.cpp" />
<Unit filename="../IPU/mpeg2lib/Mpeg.cpp" />
<Unit filename="../IPU/mpeg2lib/Mpeg.h" />
<Unit filename="../IPU/mpeg2lib/Vlc.h" />
<Unit filename="../IPU/yuv2rgb.cpp" />
<Unit filename="../IPU/yuv2rgb.h" />
<Unit filename="../Interpreter.cpp" />
<Unit filename="../IopBios.cpp" />
<Unit filename="../IopBios.h" />
<Unit filename="../IopBios2.h" />
<Unit filename="../IopCommon.h" />
<Unit filename="../IopCounters.cpp" />
<Unit filename="../IopCounters.h" />
<Unit filename="../IopDma.cpp" />
<Unit filename="../IopDma.h" />
<Unit filename="../IopHw.cpp" />
<Unit filename="../IopHw.h" />
<Unit filename="../IopMem.cpp" />
<Unit filename="../IopMem.h" />
<Unit filename="../IopSio2.cpp" />
<Unit filename="../IopSio2.h" />
<Unit filename="LnxHostSys.cpp" />
<Unit filename="LnxKeyCodes.cpp">
<Option compiler="gcc" use="1" buildCommand="$compiler $options $includes `pkg-config gtk+-2.0 --cflags` -c $file -o $object" />
</Unit>
<Unit filename="../MMI.cpp" />
<Unit filename="../MTGS.cpp" />
<Unit filename="../Memory.cpp" />
<Unit filename="../Memory.h" />
<Unit filename="../NakedAsm.h" />
<Unit filename="../Patch.cpp" />
<Unit filename="../Patch.h" />
<Unit filename="../PathDefs.h" />
<Unit filename="../Pcsx2Config.cpp" />
<Unit filename="../PluginManager.cpp" />
<Unit filename="../Plugins.h" />
<Unit filename="../PrecompiledHeader.h" />
<Unit filename="../R3000A.cpp" />
<Unit filename="../R3000A.h" />
<Unit filename="../R3000AInterpreter.cpp" />
<Unit filename="../R3000AOpcodeTables.cpp" />
<Unit filename="../R5900.cpp" />
<Unit filename="../R5900.h" />
<Unit filename="../R5900Exceptions.h" />
<Unit filename="../R5900OpcodeImpl.cpp" />
<Unit filename="../R5900OpcodeTables.cpp" />
<Unit filename="../R5900OpcodeTables.h" />
<Unit filename="../RecoverySystem.cpp" />
<Unit filename="../SPR.cpp" />
<Unit filename="../SPR.h" />
<Unit filename="../SamplProf.h" />
<Unit filename="../SaveState.cpp" />
<Unit filename="../SaveState.h" />
<Unit filename="../Sif.cpp" />
<Unit filename="../Sif.h" />
<Unit filename="../Sifcmd.h" />
<Unit filename="../Sio.cpp" />
<Unit filename="../Sio.h" />
<Unit filename="../SourceLog.cpp" />
<Unit filename="../Stats.cpp" />
<Unit filename="../Stats.h" />
<Unit filename="../StringUtils.h" />
<Unit filename="../System.cpp" />
<Unit filename="../System.h" />
<Unit filename="../System/SysThreads.cpp" />
<Unit filename="../System/SysThreads.h" />
<Unit filename="../Tags.h" />
<Unit filename="../Utilities/AsciiFile.h" />
<Unit filename="../Utilities/FileUtils.cpp" />
<Unit filename="../Utilities/folderdesc.txt" />
<Unit filename="../VU.h" />
<Unit filename="../VU0.cpp" />
<Unit filename="../VU0micro.cpp" />
<Unit filename="../VU0microInterp.cpp" />
<Unit filename="../VU1micro.cpp" />
<Unit filename="../VU1microInterp.cpp" />
<Unit filename="../VUflags.cpp" />
<Unit filename="../VUflags.h" />
<Unit filename="../VUmicro.h" />
<Unit filename="../VUmicroMem.cpp" />
<Unit filename="../VUops.cpp" />
<Unit filename="../VUops.h" />
<Unit filename="../Vif.cpp" />
<Unit filename="../Vif.h" />
<Unit filename="../Vif0Dma.cpp" />
<Unit filename="../Vif1Dma.cpp" />
<Unit filename="../VifDma.cpp" />
<Unit filename="../VifDma.h" />
<Unit filename="../VifDma_internal.h" />
<Unit filename="../gui/AdvancedDialog.cpp" />
<Unit filename="../gui/AdvancedDialog.h" />
<Unit filename="../gui/App.h" />
<Unit filename="../gui/AppAssert.cpp" />
<Unit filename="../gui/AppConfig.cpp" />
<Unit filename="../gui/AppConfig.h" />
<Unit filename="../gui/AppCoreThread.cpp" />
<Unit filename="../gui/AppInit.cpp" />
<Unit filename="../gui/AppMain.cpp" />
<Unit filename="../gui/AppRes.cpp" />
<Unit filename="../gui/CheckedStaticBox.cpp" />
<Unit filename="../gui/CheckedStaticBox.h" />
<Unit filename="../gui/ConsoleLogger.cpp" />
<Unit filename="../gui/ConsoleLogger.h" />
<Unit filename="../gui/Dialogs/AboutBoxDialog.cpp" />
<Unit filename="../gui/Dialogs/ConfigurationDialog.cpp" />
<Unit filename="../gui/Dialogs/ConfigurationDialog.h" />
<Unit filename="../gui/Dialogs/ConfirmationDialogs.cpp" />
<Unit filename="../gui/Dialogs/FirstTimeWizard.cpp" />
<Unit filename="../gui/Dialogs/ImportSettingsDialog.cpp" />
<Unit filename="../gui/Dialogs/LogOptionsDialog.cpp" />
<Unit filename="../gui/Dialogs/LogOptionsDialog.h" />
<Unit filename="../gui/Dialogs/ModalPopups.h" />
<Unit filename="../gui/Dialogs/PickUserModeDialog.cpp" />
<Unit filename="../gui/FrameForGS.cpp" />
<Unit filename="../gui/GlobalCommands.cpp" />
<Unit filename="../gui/IniInterface.cpp" />
<Unit filename="../gui/IniInterface.h" />
<Unit filename="../gui/MainFrame.cpp" />
<Unit filename="../gui/MainFrame.h" />
<Unit filename="../gui/MainMenuClicks.cpp" />
<Unit filename="../gui/MemoryCardFile.cpp" />
<Unit filename="../gui/Panels/AudioPanel.cpp" />
<Unit filename="../gui/Panels/BiosSelectorPanel.cpp" />
<Unit filename="../gui/Panels/ConfigurationPanels.h" />
<Unit filename="../gui/Panels/CpuPanel.cpp" />
<Unit filename="../gui/Panels/DirPickerPanel.cpp" />
<Unit filename="../gui/Panels/GameFixesPanel.cpp" />
<Unit filename="../gui/Panels/MiscPanelStuff.cpp" />
<Unit filename="../gui/Panels/PathsPanel.cpp" />
<Unit filename="../gui/Panels/PluginSelectorPanel.cpp" />
<Unit filename="../gui/Panels/SpeedhacksPanel.cpp" />
<Unit filename="../gui/Panels/VideoPanel.cpp" />
<Unit filename="../gui/Plugins.cpp" />
<Unit filename="../gui/Resources/AppIcon16.h" />
<Unit filename="../gui/Resources/AppIcon16.png">
<Option compile="1" />
<Option weight="0" />
<Option compiler="gcc" use="1" buildCommand="$(SvnRootDir)/tools/bin2app.sh $(SvnRootDir) $file" />
</Unit>
<Unit filename="../gui/Resources/AppIcon32.h" />
<Unit filename="../gui/Resources/AppIcon32.png">
<Option compile="1" />
<Option weight="0" />
<Option compiler="gcc" use="1" buildCommand="$(SvnRootDir)/tools/bin2app.sh $(SvnRootDir) $file" />
</Unit>
<Unit filename="../gui/Resources/AppIcon64.h" />
<Unit filename="../gui/Resources/AppIcon64.png">
<Option compile="1" />
<Option weight="0" />
<Option compiler="gcc" use="1" buildCommand="$(SvnRootDir)/tools/bin2app.sh $(SvnRootDir) $file" />
</Unit>
<Unit filename="../gui/Resources/BackgroundLogo.h" />
<Unit filename="../gui/Resources/BackgroundLogo.png">
<Option compile="1" />
<Option weight="0" />
<Option compiler="gcc" use="1" buildCommand="$(SvnRootDir)/tools/bin2app.sh $(SvnRootDir) $file" />
</Unit>
<Unit filename="../gui/Resources/ConfigIcon_Cpu.h" />
<Unit filename="../gui/Resources/ConfigIcon_Cpu.png">
<Option compile="1" />
<Option weight="0" />
<Option compiler="gcc" use="1" buildCommand="$(SvnRootDir)/tools/bin2app.sh $(SvnRootDir) $file" />
</Unit>
<Unit filename="../gui/Resources/ConfigIcon_Gamefixes.h" />
<Unit filename="../gui/Resources/ConfigIcon_Gamefixes.png">
<Option compile="1" />
<Option weight="0" />
<Option compiler="gcc" use="1" buildCommand="$(SvnRootDir)/tools/bin2app.sh $(SvnRootDir) $file" />
</Unit>
<Unit filename="../gui/Resources/ConfigIcon_Paths.h" />
<Unit filename="../gui/Resources/ConfigIcon_Paths.png">
<Option compile="1" />
<Option weight="0" />
<Option compiler="gcc" use="1" buildCommand="$(SvnRootDir)/tools/bin2app.sh $(SvnRootDir) $file" />
</Unit>
<Unit filename="../gui/Resources/ConfigIcon_Plugins.h" />
<Unit filename="../gui/Resources/ConfigIcon_Plugins.png">
<Option compile="1" />
<Option weight="0" />
<Option compiler="gcc" use="1" buildCommand="$(SvnRootDir)/tools/bin2app.sh $(SvnRootDir) $file" />
</Unit>
<Unit filename="../gui/Resources/ConfigIcon_Speedhacks.h" />
<Unit filename="../gui/Resources/ConfigIcon_Speedhacks.png">
<Option compile="1" />
<Option weight="0" />
<Option compiler="gcc" use="1" buildCommand="$(SvnRootDir)/tools/bin2app.sh $(SvnRootDir) $file" />
</Unit>
<Unit filename="../gui/Resources/ConfigIcon_Video.h" />
<Unit filename="../gui/Resources/ConfigIcon_Video.png">
<Option compile="1" />
<Option weight="0" />
<Option compiler="gcc" use="1" buildCommand="$(SvnRootDir)/tools/bin2app.sh $(SvnRootDir) $file" />
</Unit>
<Unit filename="../gui/Resources/Dualshock.h" />
<Unit filename="../gui/Resources/Dualshock.jpg">
<Option compile="1" />
<Option weight="0" />
<Option compiler="gcc" use="1" buildCommand="$(SvnRootDir)/tools/bin2app.sh $(SvnRootDir) $file" />
</Unit>
<Unit filename="../gui/Resources/EmbeddedImage.h" />
<Unit filename="../gui/Saveslots.cpp" />
<Unit filename="../gui/i18n.cpp" />
<Unit filename="../gui/i18n.h" />
<Unit filename="../gui/wxHelpers.cpp" />
<Unit filename="../gui/wxHelpers.h" />
<Unit filename="../ps2/BiosTools.cpp" />
<Unit filename="../ps2/BiosTools.h" />
<Unit filename="../ps2/GIFpath.cpp" />
<Unit filename="../ps2/Iop/IopHwRead.cpp" />
<Unit filename="../ps2/Iop/IopHwWrite.cpp" />
<Unit filename="../ps2/Iop/IopHw_Internal.h" />
<Unit filename="../vtlb.cpp" />
<Unit filename="../vtlb.h" />
<Unit filename="../x86/BaseblockEx.cpp" />
<Unit filename="../x86/BaseblockEx.h" />
<Unit filename="../x86/aR3000A.S" />
<Unit filename="../x86/aVUzerorec.S" />
<Unit filename="../x86/aVif.S" />
<Unit filename="../x86/iCOP0.cpp" />
<Unit filename="../x86/iCOP0.h" />
<Unit filename="../x86/iCOP2.cpp" />
<Unit filename="../x86/iCore.cpp" />
<Unit filename="../x86/iCore.h" />
<Unit filename="../x86/iFPU.cpp" />
<Unit filename="../x86/iFPU.h" />
<Unit filename="../x86/iFPUd.cpp" />
<Unit filename="../x86/iMMI.cpp" />
<Unit filename="../x86/iMMI.h" />
<Unit filename="../x86/iMisc.cpp" />
<Unit filename="../x86/iR3000A.cpp" />
<Unit filename="../x86/iR3000A.h" />
<Unit filename="../x86/iR3000Atables.cpp" />
<Unit filename="../x86/iR5900.h" />
<Unit filename="../x86/iR5900Arit.h" />
<Unit filename="../x86/iR5900AritImm.h" />
<Unit filename="../x86/iR5900Branch.h" />
<Unit filename="../x86/iR5900Jump.h" />
<Unit filename="../x86/iR5900LoadStore.h" />
<Unit filename="../x86/iR5900Misc.cpp" />
<Unit filename="../x86/iR5900Move.h" />
<Unit filename="../x86/iR5900MultDiv.h" />
<Unit filename="../x86/iR5900Shift.h" />
<Unit filename="../x86/iVU0micro.cpp" />
<Unit filename="../x86/iVU1micro.cpp" />
<Unit filename="../x86/iVif.cpp">
<Option compiler="gcc" use="0" buildCommand="gcc $options -S $includes -c $file -o $object" />
</Unit>
<Unit filename="../x86/ir5900tables.cpp" />
<Unit filename="../x86/ix86-32/aR5900-32.S" />
<Unit filename="../x86/ix86-32/iCore-32.cpp" />
<Unit filename="../x86/ix86-32/iR5900-32.cpp" />
<Unit filename="../x86/ix86-32/iR5900Arit.cpp" />
<Unit filename="../x86/ix86-32/iR5900AritImm.cpp" />
<Unit filename="../x86/ix86-32/iR5900Branch.cpp" />
<Unit filename="../x86/ix86-32/iR5900Jump.cpp" />
<Unit filename="../x86/ix86-32/iR5900LoadStore.cpp" />
<Unit filename="../x86/ix86-32/iR5900Move.cpp" />
<Unit filename="../x86/ix86-32/iR5900MultDiv.cpp" />
<Unit filename="../x86/ix86-32/iR5900Shift.cpp" />
<Unit filename="../x86/ix86-32/iR5900Templates.cpp" />
<Unit filename="../x86/ix86-32/recVTLB.cpp" />
<Unit filename="../x86/microVU.cpp" />
<Unit filename="../x86/microVU.h" />
<Unit filename="../x86/microVU_Alloc.inl" />
<Unit filename="../x86/microVU_Analyze.inl" />
<Unit filename="../x86/microVU_Branch.inl" />
<Unit filename="../x86/microVU_Compile.inl" />
<Unit filename="../x86/microVU_Execute.inl" />
<Unit filename="../x86/microVU_Flags.inl" />
<Unit filename="../x86/microVU_IR.h" />
<Unit filename="../x86/microVU_Log.inl" />
<Unit filename="../x86/microVU_Lower.inl" />
<Unit filename="../x86/microVU_Macro.inl" />
<Unit filename="../x86/microVU_Misc.h" />
<Unit filename="../x86/microVU_Misc.inl" />
<Unit filename="../x86/microVU_Tables.inl" />
<Unit filename="../x86/microVU_Upper.inl" />
<Unit filename="../x86/sVU_Debug.h" />
<Unit filename="../x86/sVU_Lower.cpp" />
<Unit filename="../x86/sVU_Micro.cpp" />
<Unit filename="../x86/sVU_Micro.h" />
<Unit filename="../x86/sVU_Upper.cpp" />
<Unit filename="../x86/sVU_zerorec.cpp" />
<Unit filename="../x86/sVU_zerorec.h" />
<Extensions>
<envvars />
<code_completion>
<search_path add="/usr/include/wx-2.8" />
</code_completion>
<lib_finder disable_auto="1" />
<debugger />
</Extensions>
</Project>
</CodeBlocks_project_file>

View File

@ -88,7 +88,7 @@ std::list<uint> ringposStack;
#endif
mtgsThreadObject::mtgsThreadObject() :
SysSuspendableThread()
SysThreadBase()
, m_RingPos( 0 )
, m_WritePos( 0 )
@ -244,8 +244,8 @@ void mtgsThreadObject::ExecuteTaskInThread()
pthread_cleanup_push( _clean_close_gs, this );
while( true )
{
m_sem_event.Wait(); // ... because this does a cancel test itself..
StateCheck( false ); // false disables cancel test here!
m_sem_event.WaitRaw(); // ... because this does a cancel test itself..
StateCheckInThread( false ); // false disables cancel test here!
m_RingBufferIsBusy = true;
@ -282,7 +282,7 @@ void mtgsThreadObject::ExecuteTaskInThread()
m_lock_RingRestart.Lock();
m_lock_RingRestart.Unlock();
StateCheck( false ); // disable cancel since the above locks are cancelable already
StateCheckInThread( false ); // disable cancel since the above locks are cancelable already
continue;
case GS_RINGTYPE_P1:
@ -435,7 +435,8 @@ void mtgsThreadObject::WaitGS()
{
pxAssertDev( !IsSelf(), "This method is only allowed from threads *not* named MTGS." );
if( !pxAssertDev( m_ExecMode == ExecMode_Running, "MTGS Warning! WaitGS issued on a suspended/paused thread." ) ) return;
if( m_ExecMode == ExecMode_NoThreadYet || !IsRunning() ) return;
if( !pxAssertDev( IsOpen(), "MTGS Warning! WaitGS issued on a closed thread." ) ) return;
// FIXME : Use semaphores instead of spinwaits.
SetEvent();
@ -790,7 +791,7 @@ void mtgsThreadObject::SendGameCRC( u32 crc )
void mtgsThreadObject::WaitForOpen()
{
if( !gsIsOpened )
m_sem_OpenDone.WaitGui();
m_sem_OpenDone.Wait();
m_sem_OpenDone.Reset();
}
@ -806,13 +807,5 @@ void mtgsThreadObject::Freeze( int mode, MTGS_FreezeData& data )
else
SendPointerPacket( GS_RINGTYPE_FREEZE, mode, &data );
mtgsWaitGS();
}
// Waits for the GS to empty out the entire ring buffer contents.
// Used primarily for plugin startup/shutdown.
void mtgsWaitGS()
{
mtgsThread.WaitGS();
}

View File

@ -668,7 +668,7 @@ PluginManager::PluginManager( const wxString (&folders)[PluginId_Count] )
{
const PluginsEnum_t pid = pi->id;
Console.WriteLn( "\tBinding %s\t: %s ", tbl_PluginInfo[pid].shortname, folders[pid].ToUTF8().data() );
Console.WriteLn( "\tBinding %s\t: %s ", tbl_PluginInfo[pid].shortname, folders[pid].ToUTF8() );
if( folders[pid].IsEmpty() )
throw Exception::InvalidArgument( "Empty plugin filename." );
@ -701,6 +701,8 @@ PluginManager::PluginManager( const wxString (&folders)[PluginId_Count] )
// (leave pointer null and do not generate error)
} while( ++pi, pi->shortname != NULL );
CDVDapi_Plugin.newDiskCB( cdvdNewDiskCB );
// Hack for PAD's stupid parameter passed on Init
PADinit = (_PADinit)m_info[PluginId_PAD].CommonBindings.Init;
m_info[PluginId_PAD].CommonBindings.Init = _hack_PADinit;
@ -1003,7 +1005,7 @@ void PluginManager::Init()
//
void PluginManager::Shutdown()
{
mtgsThread.Cancel(); // speedier shutdown!
mtgsThread.Cancel(); // cancel it for speedier shutdown!
Close();
DbgCon.Status( "Shutting down plugins..." );

View File

@ -58,8 +58,8 @@ R5900Exception::BaseExcept::~BaseExcept() throw (){}
void cpuReset()
{
if( mtgsThread.IsExecMode_Running() )
mtgsWaitGS(); // GS better be done processing before we reset the EE, just in case.
if( mtgsThread.IsOpen() )
mtgsThread.WaitGS(); // GS better be done processing before we reset the EE, just in case.
cpuIsInitialized = true;

View File

@ -29,12 +29,12 @@ static NonblockingMutex state_buffer_lock;
// This boolean is to keep the system from resuming emulation until the current state has completely
// uploaded or downloaded itself. It is only modified from the main thread, and should only be read
// form the main thread.
bool sys_resume_lock = false;
// from the main thread.
int sys_resume_lock = 0;
static FnType_OnThreadComplete* Callback_FreezeFinished = NULL;
static void StateThread_OnAppStatus( void* thr, const enum AppStatusEvent& stat )
static void StateThread_OnAppStatus( void* thr, const enum AppEventType& stat )
{
if( (thr == NULL) || (stat != AppStatus_Exiting) ) return;
((PersistentThread*)thr)->Cancel();
@ -54,7 +54,7 @@ class _BaseStateThread : public PersistentThread
typedef PersistentThread _parent;
protected:
EventListenerBinding<AppStatusEvent> m_bind_OnExit;
EventListenerBinding<AppEventType> m_bind_OnExit;
public:
virtual ~_BaseStateThread() throw()
@ -64,7 +64,7 @@ public:
protected:
_BaseStateThread( const char* name, FnType_OnThreadComplete* onFinished ) :
m_bind_OnExit( wxGetApp().Source_AppStatus(), EventListener<AppStatusEvent>( this, StateThread_OnAppStatus ) )
m_bind_OnExit( wxGetApp().Source_AppStatus(), EventListener<AppEventType>( this, StateThread_OnAppStatus ) )
{
Callback_FreezeFinished = onFinished;
m_name = L"StateThread::" + fromUTF8(name);
@ -105,7 +105,7 @@ protected:
{
_parent::OnStart();
sys_resume_lock = true;
++sys_resume_lock;
CoreThread.Pause();
}
@ -142,7 +142,7 @@ protected:
throw Exception::RuntimeError( "ThawState request made, but no valid state exists!" );
}
sys_resume_lock = true;
++sys_resume_lock;
CoreThread.Pause();
}
@ -186,7 +186,7 @@ protected:
void OnStart()
{
_parent::OnStart();
m_gzfp = gzopen( toUTF8(m_filename), "wb" );
m_gzfp = gzopen( m_filename.ToUTF8(), "wb" );
if( m_gzfp == NULL )
throw Exception::CreateStream( m_filename, "Cannot create savestate file for writing." );
}
@ -251,7 +251,7 @@ protected:
{
_parent::OnStart();
m_gzfp = gzopen( toUTF8(m_filename), "rb" );
m_gzfp = gzopen( m_filename.ToUTF8(), "rb" );
if( m_gzfp == NULL )
throw Exception::CreateStream( m_filename, "Cannot open savestate file for reading." );
}
@ -284,7 +284,7 @@ protected:
void Pcsx2App::OnFreezeThreadFinished( wxCommandEvent& evt )
{
// clear the OnFreezeFinsihed to NULL now, in case of error.
// clear the OnFreezeFinished to NULL now, in case of error.
// (but only actually run it if no errors occur)
FnType_OnThreadComplete* fn_tmp = Callback_FreezeFinished;
Callback_FreezeFinished = NULL;
@ -293,7 +293,7 @@ void Pcsx2App::OnFreezeThreadFinished( wxCommandEvent& evt )
ScopedPtr<PersistentThread> thr( (PersistentThread*)evt.GetClientData() );
if( !pxAssertDev( thr != NULL, "NULL thread handle on freeze finished?" ) ) return;
state_buffer_lock.Release();
sys_resume_lock = false;
--sys_resume_lock;
thr->RethrowException();
}

View File

@ -28,32 +28,32 @@
static __threadlocal SysCoreThread* tls_coreThread = NULL;
// --------------------------------------------------------------------------------------
// SysSuspendableThread *External Thread* Implementations
// SysThreadBase *External Thread* Implementations
// (Called form outside the context of this thread)
// --------------------------------------------------------------------------------------
SysSuspendableThread::SysSuspendableThread() :
SysThreadBase::SysThreadBase() :
m_ExecMode( ExecMode_NoThreadYet )
, m_lock_ExecMode()
, m_ExecModeMutex()
, m_ResumeEvent()
, m_SuspendEvent()
, m_ResumeProtection( false )
, m_resume_guard( 0 )
{
}
SysSuspendableThread::~SysSuspendableThread() throw()
SysThreadBase::~SysThreadBase() throw()
{
}
void SysSuspendableThread::Start()
void SysThreadBase::Start()
{
_parent::Start();
m_ExecMode = ExecMode_Suspending;
m_ExecMode = ExecMode_Closing;
m_sem_event.Post();
}
void SysSuspendableThread::OnStart()
void SysThreadBase::OnStart()
{
if( !pxAssertDev( m_ExecMode == ExecMode_NoThreadYet, "SysSustainableThread:Start(): Invalid execution mode" ) ) return;
@ -63,9 +63,8 @@ void SysSuspendableThread::OnStart()
_parent::OnStart();
}
// Pauses the emulation state at the next PS2 vsync, and returns control to the calling
// thread; or does nothing if the core is already suspended. Calling this thread from the
// Core thread will result in deadlock.
// Suspends emulation and closes the emulation state (including plugins) at the next PS2 vsync,
// and returns control to the calling thread; or does nothing if the core is already suspended.
//
// Parameters:
// isNonblocking - if set to true then the function will not block for emulation suspension.
@ -78,61 +77,78 @@ void SysSuspendableThread::OnStart()
// suspended.
//
// Exceptions:
// CancelEvent - thrown if the thread is already in a Paused state. Because actions that
// pause emulation typically rely on plugins remaining loaded/active, Suspension must
// cansel itself forcefully or risk crashing whatever other action is in progress.
// CancelEvent - thrown if the thread is already in a Paused or Closing state. Because
// actions that pause emulation typically rely on plugins remaining loaded/active,
// Suspension must cansel itself forcefully or risk crashing whatever other action is
// in progress.
//
bool SysSuspendableThread::Suspend( bool isBlocking )
bool SysThreadBase::Suspend( bool isBlocking )
{
if( IsSelf() || !IsRunning() ) return false;
// shortcut ExecMode check to avoid deadlocking on redundant calls to Suspend issued
// from Resume or OnResumeReady code.
if( m_ExecMode == ExecMode_Closed ) return false;
bool retval = false;
{
ScopedLock locker( m_lock_ExecMode );
ScopedLock locker( m_ExecModeMutex );
if( m_ExecMode == ExecMode_Suspended )
return false;
// Check again -- status could have changed since above.
if( m_ExecMode == ExecMode_Closed ) return false;
if( m_ExecMode == ExecMode_Pausing || m_ExecMode == ExecMode_Paused )
throw Exception::CancelEvent( "Another thread is pausing the VM state." );
if( m_ExecMode == ExecMode_Running )
if( m_ExecMode == ExecMode_Opened )
{
m_ExecMode = ExecMode_Suspending;
m_ExecMode = ExecMode_Closing;
retval = true;
}
pxAssertDev( m_ExecMode == ExecMode_Suspending, "ExecMode should be nothing other than Suspending..." );
pxAssertDev( m_ExecMode == ExecMode_Closing, "ExecMode should be nothing other than Closing..." );
m_SuspendEvent.Reset();
m_sem_event.Post();
}
m_SuspendEvent.Reset();
m_sem_event.Post();
if( isBlocking ) m_SuspendEvent.WaitGui();
if( isBlocking ) m_SuspendEvent.Wait();
return retval;
}
bool SysSuspendableThread::Pause()
// Returns:
// The previous suspension state; true if the thread was running or false if it was
// closed, not running, or paused.
//
bool SysThreadBase::Pause()
{
if( IsSelf() || !IsRunning() ) return false;
// shortcut ExecMode check to avoid deadlocking on redundant calls to Suspend issued
// from Resume or OnResumeReady code.
if( (m_ExecMode == ExecMode_Closed) || (m_ExecMode == ExecMode_Paused) ) return false;
bool retval = false;
{
ScopedLock locker( m_lock_ExecMode );
ScopedLock locker( m_ExecModeMutex );
if( (m_ExecMode == ExecMode_Suspended) || (m_ExecMode == ExecMode_Paused) ) return false;
// Check again -- status could have changed since above.
if( (m_ExecMode == ExecMode_Closed) || (m_ExecMode == ExecMode_Paused) ) return false;
if( m_ExecMode == ExecMode_Running )
if( m_ExecMode == ExecMode_Opened )
{
m_ExecMode = ExecMode_Pausing;
retval = true;
}
pxAssertDev( m_ExecMode == ExecMode_Pausing, "ExecMode should be nothing other than Pausing..." );
m_SuspendEvent.Reset();
m_sem_event.Post();
}
m_SuspendEvent.Reset();
m_sem_event.Post();
m_SuspendEvent.WaitGui();
m_SuspendEvent.Wait();
return retval;
}
@ -140,73 +156,93 @@ bool SysSuspendableThread::Pause()
// Resumes the core execution state, or does nothing is the core is already running. If
// settings were changed, resets will be performed as needed and emulation state resumed from
// memory savestates.
//
// Note that this is considered a non-blocking action. Most times the state is safely resumed
// on return, but in the case of re-entrant or nested message handling the function may return
// before the thread has resumed. If you need explicit behavior tied to the completion of the
// Resume, you'll need to bind callbacks to either OnResumeReady or OnResumeInThread.
//
// Exceptions (can occur on first call only):
// PluginInitError - thrown if a plugin fails init (init is performed on the current thread
// on the first time the thread is resumed from it's initial idle state)
// ThreadCreationError - Insufficient system resources to create thread.
//
void SysSuspendableThread::Resume()
void SysThreadBase::Resume()
{
if( IsSelf() ) return;
if( m_ExecMode == ExecMode_Opened ) return;
if( !pxAssert( g_plugins != NULL ) ) return;
ScopedLock locker( m_ExecModeMutex );
// Recursion guard is needed because of the non-blocking Wait if the state
// is Suspending/Closing. Processed events could recurse into Resume, and we'll
// want to silently ignore them.
RecursionGuard guard( m_resume_guard );
if( guard.IsReentrant() ) return;
switch( m_ExecMode )
{
ScopedLock locker( m_lock_ExecMode );
case ExecMode_Opened: return;
switch( m_ExecMode )
{
case ExecMode_Running: return;
case ExecMode_NoThreadYet:
Start();
m_ExecMode = ExecMode_Closing;
// fall through...
case ExecMode_NoThreadYet:
Start();
m_ExecMode = ExecMode_Suspending;
// fall through...
case ExecMode_Closing:
case ExecMode_Pausing:
// we need to make sure and wait for the emuThread to enter a fully suspended
// state before continuing...
case ExecMode_Suspending:
case ExecMode_Pausing:
// we need to make sure and wait for the emuThread to enter a fully suspended
// state before continuing...
locker.Unlock(); // no deadlocks please, thanks. :)
m_SuspendEvent.WaitGui();
break;
}
locker.Unlock(); // no deadlocks please, thanks. :)
++sys_resume_lock;
m_SuspendEvent.Wait();
--sys_resume_lock;
locker.Lock();
// The entire state coming out of a Wait is indeterminate because of user input
// and pending messages being handled. If something doesn't feel right, we should
// abort.
if( (m_ExecMode != ExecMode_Closed) && (m_ExecMode != ExecMode_Paused) ) return;
if( g_plugins == NULL ) return;
break;
}
pxAssertDev( (m_ExecMode == ExecMode_Suspended) || (m_ExecMode == ExecMode_Paused),
"SysSuspendableThread is not in a suspended/paused state? wtf!" );
pxAssertDev( (m_ExecMode == ExecMode_Closed) || (m_ExecMode == ExecMode_Paused),
"SysThreadBase is not in a closed/paused state? wtf!" );
m_ResumeProtection = true;
OnResumeReady();
m_ResumeProtection = false;
m_ExecMode = ExecMode_Running;
m_ExecMode = ExecMode_Opened;
m_ResumeEvent.Post();
}
// --------------------------------------------------------------------------------------
// SysSuspendableThread *Worker* Implementations
// SysThreadBase *Worker* Implementations
// (Called from the context of this thread only)
// --------------------------------------------------------------------------------------
void SysSuspendableThread::OnCleanupInThread()
void SysThreadBase::OnCleanupInThread()
{
ScopedLock locker( m_lock_ExecMode );
ScopedLock locker( m_ExecModeMutex );
m_ExecMode = ExecMode_NoThreadYet;
_parent::OnCleanupInThread();
}
void SysSuspendableThread::StateCheck( bool isCancelable )
void SysThreadBase::StateCheckInThread( bool isCancelable )
{
// Shortcut for the common case, to avoid unnecessary Mutex locks:
if( m_ExecMode == ExecMode_Running )
if( m_ExecMode == ExecMode_Opened )
{
if( isCancelable ) TestCancel();
return;
}
// Oh, seems we need a full lock, because something special is happening!
ScopedLock locker( m_lock_ExecMode );
ScopedLock locker( m_ExecModeMutex );
switch( m_ExecMode )
{
@ -219,7 +255,7 @@ void SysSuspendableThread::StateCheck( bool isCancelable )
break;
#endif
case ExecMode_Running:
case ExecMode_Opened:
// Yup, need this a second time. Variable state could have changed while we
// were trying to acquire the lock above.
if( isCancelable )
@ -236,26 +272,26 @@ void SysSuspendableThread::StateCheck( bool isCancelable )
// fallthrough...
case ExecMode_Paused:
m_lock_ExecMode.Unlock();
m_ExecModeMutex.Unlock();
while( m_ExecMode == ExecMode_Paused )
m_ResumeEvent.WaitGui();
m_ResumeEvent.WaitRaw();
OnResumeInThread( false );
break;
// -------------------------------------
case ExecMode_Suspending:
case ExecMode_Closing:
{
OnSuspendInThread();
m_ExecMode = ExecMode_Suspended;
m_ExecMode = ExecMode_Closed;
m_SuspendEvent.Post();
}
// fallthrough...
case ExecMode_Suspended:
m_lock_ExecMode.Unlock();
while( m_ExecMode == ExecMode_Suspended )
m_ResumeEvent.WaitGui();
case ExecMode_Closed:
m_ExecModeMutex.Unlock();
while( m_ExecMode == ExecMode_Closed )
m_ResumeEvent.WaitRaw();
OnResumeInThread( true );
break;
@ -330,8 +366,7 @@ void SysCoreThread::ApplySettings( const Pcsx2Config& src )
{
if( src == EmuConfig ) return;
// Suspend only if ResumeProtection is false:
const bool resumeWhenDone = !m_ResumeProtection && Suspend();
const bool resumeWhenDone = Suspend();
m_resetRecompilers = ( src.Cpu != EmuConfig.Cpu ) || ( src.Gamefixes != EmuConfig.Gamefixes ) || ( src.Speedhacks != EmuConfig.Speedhacks );
m_resetProfilers = (src.Profiler != EmuConfig.Profiler );
@ -416,8 +451,8 @@ void SysCoreThread::ExecuteTaskInThread()
{
tls_coreThread = this;
m_sem_event.Wait();
StateCheck();
m_sem_event.WaitRaw();
StateCheckInThread();
CpuExecute();
}

View File

@ -31,39 +31,71 @@ public:
};
class SysSuspendableThread : public PersistentThread, public virtual ISysThread
class SysThreadBase : public PersistentThread, public virtual ISysThread
{
typedef PersistentThread _parent;
protected:
// Important: The order of these enumerations matters. All "not-open" statuses must
// be listed before ExecMode_Closed, since there are "optimized" tests that rely on the
// assumption that "ExecMode <= ExecMode_Closed" equates to a closed thread status.
enum ExecutionMode
{
// Thread has not been created yet. Typically this is the same as IsRunning()
// returning FALSE.
ExecMode_NoThreadYet,
ExecMode_Running,
ExecMode_Suspending,
ExecMode_Suspended,
// Close signal has been sent to the thread, but the thread's response is still
// pending (thread is busy/running).
ExecMode_Closing,
// Thread is safely paused, with plugins in a "closed" state, and waiting for a
// resume/open signal.
ExecMode_Closed,
// Thread is active and running, with pluigns in an "open" state.
ExecMode_Opened,
// Pause signal has been sent to the thread, but the thread's response is still
// pending (thread is busy/running).
ExecMode_Pausing,
// Thread is safely paused, with plugins in an "open" state, and waiting for a
// resume/open signal.
ExecMode_Paused,
};
volatile ExecutionMode m_ExecMode;
MutexLock m_lock_ExecMode;
MutexLock m_ExecModeMutex;
Semaphore m_ResumeEvent;
Semaphore m_SuspendEvent;
bool m_ResumeProtection;
public:
explicit SysSuspendableThread();
virtual ~SysSuspendableThread() throw();
int m_resume_guard;
bool IsExecMode_Running() const { return m_ExecMode == ExecMode_Running; }
public:
explicit SysThreadBase();
virtual ~SysThreadBase() throw();
// Thread safety for IsOpen / IsClosed: The execution mode can change at any time on
// any thread, so the actual status may have already changed by the time this function
// returns its result. Typically this isn't of major concern. However if you need
// more assured execution mode status, issue a lock against the ExecutionModeMutex()
// first.
bool IsOpen() const
{
return m_ExecMode > ExecMode_Closed;
}
bool IsClosed() const { return !IsOpen(); }
ExecutionMode GetExecutionMode() const { return m_ExecMode; }
MutexLock& ExecutionModeMutex() { return m_ExecModeMutex; }
virtual bool Suspend( bool isBlocking = true );
virtual void Resume();
virtual bool Pause();
virtual void StateCheck( bool isCancelable = true );
virtual void StateCheckInThread( bool isCancelable = true );
virtual void OnCleanupInThread();
// This function is called by Resume immediately prior to releasing the suspension of
@ -79,21 +111,21 @@ protected:
virtual void Start();
// Extending classes should implement this, but should not call it. The parent class
// handles invocation by the following guidelines: Called *in thread* from StateCheck()
// handles invocation by the following guidelines: Called *in thread* from StateCheckInThread()
// prior to suspending the thread (ie, when Suspend() has been called on a separate
// thread, requesting this thread suspend itself temporarily). After this is called,
// the thread enters a waiting state on the m_ResumeEvent semaphore.
virtual void OnSuspendInThread()=0;
// Extending classes should implement this, but should not call it. The parent class
// handles invocation by the following guidelines: Called *in thread* from StateCheck()
// handles invocation by the following guidelines: Called *in thread* from StateCheckInThread()
// prior to pausing the thread (ie, when Pause() has been called on a separate thread,
// requesting this thread pause itself temporarily). After this is called, the thread
// enters a waiting state on the m_ResumeEvent semaphore.
virtual void OnPauseInThread()=0;
// Extending classes should implement this, but should not call it. The parent class
// handles invocation by the following guidelines: Called from StateCheck() after the
// handles invocation by the following guidelines: Called from StateCheckInThread() after the
// thread has been suspended and then subsequently resumed.
// Parameter:
// isSuspended - set to TRUE if the thread is returning from a suspended state, or
@ -104,9 +136,9 @@ protected:
// --------------------------------------------------------------------------------------
// EECoreThread class
// --------------------------------------------------------------------------------------
class SysCoreThread : public SysSuspendableThread
class SysCoreThread : public SysThreadBase
{
typedef SysSuspendableThread _parent;
typedef SysThreadBase _parent;
protected:
bool m_resetRecompilers;
@ -141,3 +173,5 @@ protected:
virtual void OnCleanupInThread();
virtual void ExecuteTaskInThread();
};
extern int sys_resume_lock;

View File

@ -728,7 +728,7 @@ void vif1TransferFromMemory()
{
if (size > 1)
{
mtgsWaitGS();
mtgsThread.WaitGS();
GSreadFIFO((u64*)&PS2MEM_HW[0x5000]);
}
pMem[0] = psHu64(VIF1_FIFO);
@ -738,7 +738,7 @@ void vif1TransferFromMemory()
}
else
{
mtgsWaitGS();
mtgsThread.WaitGS();
GSreadFIFO2(pMem, vif1ch->qwc);
// set incase read

View File

@ -22,8 +22,9 @@
#include <wx/apptrait.h>
#include "Utilities/Listeners.h"
#include "IniInterface.h"
class IniInterface;
//class IniInterface;
class MainEmuFrame;
class GSFrame;
class ConsoleLogFrame;
@ -40,9 +41,6 @@ class AppCoreThread;
typedef void FnType_OnThreadComplete(const wxCommandEvent& evt);
#define AllowFromMainThreadOnly() \
pxAssertMsg( wxThread::IsMain(), "Thread affinity violation: Call allowed from main thread only." )
BEGIN_DECLARE_EVENT_TYPES()
DECLARE_EVENT_TYPE( pxEVT_SemaphorePing, -1 )
DECLARE_EVENT_TYPE( pxEVT_OpenModalDialog, -1 )
@ -159,7 +157,7 @@ enum DialogIdentifiers
DialogId_About,
};
enum AppStatusEvent
enum AppEventType
{
// Maybe this will be expanded upon later..?
AppStatus_Exiting
@ -309,6 +307,23 @@ struct MsgboxEventResult
}
};
// --------------------------------------------------------------------------------------
// AppIniSaver / AppIniLoader
// --------------------------------------------------------------------------------------
class AppIniSaver : public IniSaver
{
public:
AppIniSaver();
virtual ~AppIniSaver() {}
};
class AppIniLoader : public IniLoader
{
public:
AppIniLoader();
virtual ~AppIniLoader() {}
};
// --------------------------------------------------------------------------------------
// Pcsx2App - main wxApp class
// --------------------------------------------------------------------------------------
@ -390,7 +405,7 @@ public:
ConsoleLogFrame* GetProgramLog();
void ProgramLog_CountMsg();
void ProgramLog_PostEvent( wxEvent& evt );
void EnableConsoleLogging() const;
void EnableAllLogging() const;
void DisableWindowLogging() const;
void DisableDiskLogging() const;
void OnProgramLogClosed();
@ -402,12 +417,16 @@ public:
protected:
CmdEvt_Source m_evtsrc_CorePluginStatus;
CmdEvt_Source m_evtsrc_CoreThreadStatus;
EventSource<AppStatusEvent> m_evtsrc_AppStatus;
EventSource<int> m_evtsrc_SettingsApplied;
EventSource<IniInterface> m_evtsrc_SettingsLoadSave;
EventSource<AppEventType> m_evtsrc_AppStatus;
public:
CmdEvt_Source& Source_CoreThreadStatus() { return m_evtsrc_CoreThreadStatus; }
CmdEvt_Source& Source_CorePluginStatus() { return m_evtsrc_CorePluginStatus; }
EventSource<AppStatusEvent>& Source_AppStatus() { return m_evtsrc_AppStatus; }
EventSource<int>& Source_SettingsApplied() { return m_evtsrc_SettingsApplied; }
EventSource<IniInterface>& Source_SettingsLoadSave() { return m_evtsrc_SettingsLoadSave; }
EventSource<AppEventType>& Source_AppStatus() { return m_evtsrc_AppStatus; }
protected:
void InitDefaultGlobalAccelerators();
@ -453,6 +472,7 @@ protected:
enum CoreThreadStatus
{
CoreStatus_Indeterminate,
CoreStatus_Resumed,
CoreStatus_Suspended,
CoreStatus_Stopped,
@ -471,11 +491,14 @@ public:
virtual bool Suspend( bool isBlocking=true );
virtual void Resume();
virtual void StateCheck( bool isCancelable=true );
virtual void StateCheckInThread( bool isCancelable=true );
virtual void ApplySettings( const Pcsx2Config& src );
protected:
virtual void OnResumeReady();
virtual void OnResumeInThread( bool IsSuspended );
virtual void OnSuspendInThread();
virtual void OnCleanupInThread();
virtual void ExecuteTaskInThread();
};
@ -514,8 +537,6 @@ DECLARE_APP(Pcsx2App)
// External App-related Globals and Shortcuts
// --------------------------------------------------------------------------------------
extern bool sys_resume_lock;
extern int EnumeratePluginsInFolder( const wxDirName& searchPath, wxArrayString* dest );
extern void LoadPluginsPassive( FnType_OnThreadComplete* onComplete );
extern void LoadPluginsImmediate();
@ -523,7 +544,7 @@ extern void UnloadPlugins();
extern void AppLoadSettings();
extern void AppSaveSettings();
extern void AppApplySettings( const AppConfig* oldconf=NULL );
extern void AppApplySettings( const AppConfig* oldconf=NULL, bool saveOnSuccess=false );
extern bool SysHasValidState();

View File

@ -96,7 +96,7 @@ void Pcsx2App::OnAssertFailure( const wxChar *file, int line, const wxChar *func
// make life easier for people using VC++ IDE by using this format, which allows double-click
// response times from the Output window...
dbgmsg.Printf( L"%s(%d) : assertion failed%s%s: %s", file, line,
dbgmsg.Printf( L"%s(%d) : assertion failed%s%s: %s\n", file, line,
(func==NULL) ? wxEmptyString : L" in ",
(func==NULL) ? wxEmptyString : func,
message.c_str()

View File

@ -375,8 +375,7 @@ void AppConfig::LoadSaveMemcards( IniInterface& ini )
}
}
// ------------------------------------------------------------------------
void AppConfig::LoadSave( IniInterface& ini )
void AppConfig::LoadSaveRootItems( IniInterface& ini )
{
AppConfig defaults;
@ -388,11 +387,16 @@ void AppConfig::LoadSave( IniInterface& ini )
IniEntry( Listbook_ImageSize );
IniEntry( Toolbar_ImageSize );
IniEntry( Toolbar_ShowLabels );
IniEntry( CurrentIso );
ini.EnumEntry( L"CdvdSource", CdvdSource, CDVD_SourceLabels, defaults.CdvdSource );
}
// ------------------------------------------------------------------------
void AppConfig::LoadSave( IniInterface& ini )
{
LoadSaveRootItems( ini );
LoadSaveMemcards( ini );
// Process various sub-components:
@ -508,6 +512,30 @@ wxFileConfig* OpenFileConfig( const wxString& filename )
return new wxFileConfig( wxEmptyString, wxEmptyString, filename, wxEmptyString, wxCONFIG_USE_RELATIVE_PATH );
}
void RelocateLogfile()
{
g_Conf->Folders.Logs.Mkdir();
wxString newlogname( Path::Combine( g_Conf->Folders.Logs.ToString(), L"emuLog.txt" ) );
if( (emuLog != NULL) && (emuLogName != newlogname) )
{
Console.Status( "\nRelocating Logfile...\n\tFrom: %s\n\tTo : %s\n", emuLogName.c_str(), newlogname.c_str() );
wxGetApp().DisableDiskLogging();
fclose( emuLog );
emuLog = NULL;
}
if( emuLog == NULL )
{
emuLogName = newlogname;
emuLog = fopen( emuLogName.ToUTF8(), "wb" );
}
wxGetApp().EnableAllLogging();
}
// Parameters:
// overwrite - this option forces the current settings to overwrite any existing settings that might
// be saved to the configured ini/settings folder.
@ -517,35 +545,32 @@ void AppConfig_OnChangedSettingsFolder( bool overwrite )
PathDefs::GetDocuments().Mkdir();
PathDefs::GetSettings().Mkdir();
// Allow wx to use our config, and enforces auto-cleanup as well
if( overwrite )
{
if( !wxRemoveFile( GetSettingsFilename() ) )
throw Exception::AccessDenied( "Failed to overwrite settings; permission to file was denied." );
}
//if( GetAppConfig() != NULL )
// wxGetApp().Source_SettingsChanged().Dispatch( SettingsEvt_IniClosing );
// Bind into wxConfigBase to allow wx to use our config internally, and delete whatever
// comes out (cleans up prev config, if one).
delete wxConfigBase::Set( OpenFileConfig( GetSettingsFilename() ) );
wxConfigBase::Get()->SetRecordDefaults();
GetAppConfig()->SetRecordDefaults();
//wxGetApp().Source_SettingsChanged().Dispatch( SettingsEvt_IniOpening );
if( !overwrite )
AppLoadSettings();
AppApplySettings();
sMainFrame.ReloadRecentLists();
g_Conf->Folders.Logs.Mkdir();
wxString newlogname( Path::Combine( g_Conf->Folders.Logs.ToString(), L"emuLog.txt" ) );
wxGetApp().DisableDiskLogging();
if( emuLog != NULL )
{
if( emuLogName != newlogname )
{
fclose( emuLog );
emuLog = NULL;
}
}
if( emuLog == NULL )
{
emuLogName = newlogname;
emuLog = fopen( toUTF8(emuLogName), "wb" );
}
wxGetApp().EnableConsoleLogging();
}
// Returns the current application configuration file. This is preferred over using
// wxConfigBase::GetAppConfig(), since it defaults to *not* creating a config file
// automatically (which is typically highly undesired behavior in our system)
wxConfigBase* GetAppConfig()
{
return wxConfigBase::Get( false );
}

View File

@ -19,6 +19,7 @@
#include "CDVD/CDVDaccess.h"
class IniInterface;
class wxConfigBase;
class wxFileConfig;
extern bool UseAdminMode; // dictates if the program uses /home/user or /cwd for the program data
@ -164,6 +165,7 @@ public:
void LoadSaveUserMode( IniInterface& ini, const wxString& cwdhash );
void LoadSave( IniInterface& ini );
void LoadSaveRootItems( IniInterface& ini );
void LoadSaveMemcards( IniInterface& ini );
};
@ -176,6 +178,8 @@ struct ConfigOverrides
extern ConfigOverrides OverrideOptions;
extern wxFileConfig* OpenFileConfig( const wxString& filename );
extern void RelocateLogfile();
extern void AppConfig_OnChangedSettingsFolder( bool overwrite = false );
extern wxConfigBase* GetAppConfig();
extern ScopedPtr<AppConfig> g_Conf;

View File

@ -31,9 +31,9 @@ bool AppCoreThread::Suspend( bool isBlocking )
{
bool retval = _parent::Suspend( isBlocking );
wxCommandEvent evt( pxEVT_CoreThreadStatus );
/*wxCommandEvent evt( pxEVT_CoreThreadStatus );
evt.SetInt( CoreStatus_Suspended );
wxGetApp().AddPendingEvent( evt );
wxGetApp().AddPendingEvent( evt );*/
// Clear the sticky key statuses, because hell knows what'll change while the PAD
// plugin is suspended.
@ -50,12 +50,24 @@ void AppCoreThread::Resume()
// Thread control (suspend / resume) should only be performed from the main/gui thread.
if( !AllowFromMainThreadOnly() ) return;
if( sys_resume_lock )
if( sys_resume_lock > 0 )
{
Console.WriteLn( "SysResume: State is locked, ignoring Resume request!" );
return;
}
_parent::Resume();
if( m_ExecMode != ExecMode_Opened )
{
// Resume failed for some reason, so update GUI statuses and post a message to
// try again on the resume.
wxCommandEvent evt( pxEVT_CoreThreadStatus );
evt.SetInt( CoreStatus_Suspended );
wxGetApp().AddPendingEvent( evt );
sApp.SysExecute();
}
}
void AppCoreThread::OnResumeReady()
@ -65,11 +77,25 @@ void AppCoreThread::OnResumeReady()
if( GSopen2 != NULL )
wxGetApp().OpenGsFrame();
_parent::OnResumeReady();
}
void AppCoreThread::OnResumeInThread( bool isSuspended )
{
_parent::OnResumeInThread( isSuspended );
wxCommandEvent evt( pxEVT_CoreThreadStatus );
evt.SetInt( CoreStatus_Resumed );
wxGetApp().AddPendingEvent( evt );
}
_parent::OnResumeReady();
void AppCoreThread::OnSuspendInThread()
{
_parent::OnSuspendInThread();
wxCommandEvent evt( pxEVT_CoreThreadStatus );
evt.SetInt( CoreStatus_Suspended );
wxGetApp().AddPendingEvent( evt );
}
// Called whenever the thread has terminated, for either regular or irregular reasons.
@ -88,9 +114,9 @@ void AppCoreThread::OnCleanupInThread()
extern int TranslateGDKtoWXK( u32 keysym );
#endif
void AppCoreThread::StateCheck( bool isCancelable )
void AppCoreThread::StateCheckInThread( bool isCancelable )
{
_parent::StateCheck( isCancelable );
_parent::StateCheckInThread( isCancelable );
if( !pxAssert(g_plugins!=NULL) ) return;
const keyEvent* ev = PADkeyEvent();
@ -124,7 +150,7 @@ void AppCoreThread::StateCheck( bool isCancelable )
// suspended. If the thread has mot been suspended, this call will fail *silently*.
void AppCoreThread::ApplySettings( const Pcsx2Config& src )
{
if( m_ExecMode != ExecMode_Suspended ) return;
if( m_ExecMode != ExecMode_Closed ) return;
if( src == EmuConfig ) return;
// Re-entry guard protects against cases where code wants to manually set core settings

View File

@ -118,6 +118,10 @@ void Pcsx2App::ReadUserModeSettings()
AppSaveSettings();
}
}
// force a reset here to unload plugins loaded by the wizard. If we don't do this
// the recompilers might fail to allocate the memory they need to function.
SysReset();
}
void Pcsx2App::OnInitCmdLine( wxCmdLineParser& parser )
@ -203,7 +207,7 @@ typedef void (wxEvtHandler::*pxMessageBoxEventFunction)(pxMessageBoxEvent&);
bool Pcsx2App::OnInit()
{
g_Conf = new AppConfig();
EnableConsoleLogging();
EnableAllLogging();
wxInitAllImageHandlers();
if( !wxApp::OnInit() ) return false;
@ -260,7 +264,7 @@ bool Pcsx2App::OnInit()
}
m_ProgramLogBox = new ConsoleLogFrame( m_MainFrame, L"PCSX2 Program Log", g_Conf->ProgLogBox );
EnableConsoleLogging();
EnableAllLogging();
SetTopWindow( m_MainFrame ); // not really needed...
SetExitOnFrameDelete( true ); // but being explicit doesn't hurt...
@ -316,6 +320,7 @@ bool Pcsx2App::OnInit()
catch( Exception::StartupAborted& ex )
{
Console.Notice( ex.FormatDiagnosticMessage() );
CleanupMess();
return false;
}
// ----------------------------------------------------------------------------
@ -347,6 +352,9 @@ void Pcsx2App::CleanupMess()
// during the wxApp destructor. -- air
// FIXME: performing a wxYield() here may fix that problem. -- air
while( wxGetLocale() != NULL )
delete wxGetLocale();
}
Pcsx2App::Pcsx2App() :
@ -369,6 +377,9 @@ Pcsx2App::~Pcsx2App()
// to happen here in the destructor.
CleanupMess();
delete wxConfigBase::Set( NULL );
Console_SetActiveHandler( ConsoleWriter_Null );
if( emuLog != NULL )
@ -377,6 +388,8 @@ Pcsx2App::~Pcsx2App()
emuLog = NULL;
}
}
// ------------------------------------------------------------------------------------------
// Using the MSVCRT to track memory leaks:
// ------------------------------------------------------------------------------------------
@ -403,6 +416,6 @@ struct CrtDebugBreak
}
};
//CrtDebugBreak breakAt( 157 );
//CrtDebugBreak breakAt( 20603 );
#endif

View File

@ -293,9 +293,6 @@ int Pcsx2App::OnExit()
if( g_Conf )
AppSaveSettings();
while( wxGetLocale() != NULL )
delete wxGetLocale();
return wxApp::OnExit();
}
@ -311,7 +308,7 @@ MainEmuFrame& Pcsx2App::GetMainFrame() const
return *m_MainFrame;
}
void AppApplySettings( const AppConfig* oldconf )
void AppApplySettings( const AppConfig* oldconf, bool saveOnSuccess )
{
AllowFromMainThreadOnly();
@ -324,6 +321,8 @@ void AppApplySettings( const AppConfig* oldconf )
g_Conf->EmuOptions.BiosFilename = g_Conf->FullpathToBios();
RelocateLogfile();
bool resume = CoreThread.Suspend();
// Update the compression attribute on the Memcards folder.
@ -343,34 +342,44 @@ void AppApplySettings( const AppConfig* oldconf )
}
}
sApp.Source_SettingsApplied().Dispatch( 0 );
CoreThread.ApplySettings( g_Conf->EmuOptions );
if( resume )
CoreThread.Resume();
if( saveOnSuccess )
AppSaveSettings();
}
static wxFileConfig _dud_config;
AppIniSaver::AppIniSaver() :
IniSaver( (GetAppConfig() != NULL) ? *GetAppConfig() : _dud_config )
{
}
AppIniLoader::AppIniLoader() :
IniLoader( (GetAppConfig() != NULL) ? *GetAppConfig() : _dud_config )
{
}
void AppLoadSettings()
{
wxConfigBase* conf = wxConfigBase::Get( false );
if( NULL == conf ) return;
if( !AllowFromMainThreadOnly() ) return;
IniLoader loader( *conf );
AppIniLoader loader;
g_Conf->LoadSave( loader );
if( HasMainFrame() )
GetMainFrame().LoadRecentIsoList( *conf );
wxGetApp().Source_SettingsLoadSave().Dispatch( loader );
}
void AppSaveSettings()
{
wxConfigBase* conf = wxConfigBase::Get( false );
if( NULL == conf ) return;
if( !AllowFromMainThreadOnly() ) return;
IniSaver saver( *conf );
AppIniSaver saver;
g_Conf->LoadSave( saver );
if( HasMainFrame() )
GetMainFrame().SaveRecentIsoList( *conf );
wxGetApp().Source_SettingsLoadSave().Dispatch( saver );
}
void Pcsx2App::OpenGsFrame()
@ -413,28 +422,30 @@ void Pcsx2App::OnMainFrameClosed()
static int _sysexec_cdvdsrc_type = -1;
static void OnSysExecuteAfterPlugins( const wxCommandEvent& loadevt )
static void _sendmsg_SysExecute()
{
if( !wxGetApp().m_CorePlugins ) return;
wxCommandEvent execevt( pxEVT_SysExecute );
execevt.SetInt( _sysexec_cdvdsrc_type );
wxGetApp().AddPendingEvent( execevt );
}
static void OnSysExecuteAfterPlugins( const wxCommandEvent& loadevt )
{
if( (wxTheApp == NULL) || !((Pcsx2App*)wxTheApp)->m_CorePlugins ) return;
_sendmsg_SysExecute();
}
// Executes the emulator using a saved/existing virtual machine state and currently
// configured CDVD source device.
void Pcsx2App::SysExecute()
{
_sysexec_cdvdsrc_type = -1;
if( !m_CorePlugins )
{
LoadPluginsPassive( OnSysExecuteAfterPlugins );
return;
}
wxCommandEvent evt( pxEVT_SysExecute );
evt.SetInt( -1 );
AddPendingEvent( evt );
_sendmsg_SysExecute();
}
// Executes the specified cdvd source and optional elf file. This command performs a
@ -442,20 +453,18 @@ void Pcsx2App::SysExecute()
// sources.
void Pcsx2App::SysExecute( CDVD_SourceType cdvdsrc )
{
_sysexec_cdvdsrc_type = (int)cdvdsrc;
if( !m_CorePlugins )
{
LoadPluginsPassive( OnSysExecuteAfterPlugins );
return;
}
wxCommandEvent evt( pxEVT_SysExecute );
evt.SetInt( (int)cdvdsrc );
AddPendingEvent( evt );
_sendmsg_SysExecute();
}
void Pcsx2App::OnSysExecute( wxCommandEvent& evt )
{
if( sys_resume_lock )
if( sys_resume_lock > 0 )
{
Console.WriteLn( "SysExecute: State is locked, ignoring Execute request!" );
return;
@ -465,16 +474,18 @@ void Pcsx2App::OnSysExecute( wxCommandEvent& evt )
// it, because apparently too much stuff is going on and the emulation states are wonky.
if( !m_CorePlugins ) return;
if( evt.GetInt() != -1 ) SysReset(); else CoreThread.Suspend();
if( evt.GetInt() != -1 ) CoreThread.Reset(); else CoreThread.Suspend();
CDVDsys_SetFile( CDVDsrc_Iso, g_Conf->CurrentIso );
if( evt.GetInt() != -1 ) CDVDsys_ChangeSource( (CDVD_SourceType)evt.GetInt() );
CoreThread.Resume();
}
// Full system reset stops the core thread and unloads all core plugins *completely*.
void Pcsx2App::SysReset()
{
CoreThread.Reset();
m_CorePlugins = NULL;
}
// Returns true if there is a "valid" virtual machine state from the user's perspective. This

View File

@ -521,7 +521,7 @@ void ConsoleLogFrame::CountMessage()
wxCommandEvent evt( wxEVT_SemaphoreWait );
GetEventHandler()->AddPendingEvent( evt );
m_semaphore.Wait();
m_semaphore.WaitRaw();
}
}
}
@ -594,12 +594,12 @@ static void __concall ConsoleToFile_Newline()
static void __concall ConsoleToFile_DoWrite( const wxString& fmt )
{
_immediate_logger( toUTF8(fmt) );
_immediate_logger( fmt.ToUTF8() );
}
static void __concall ConsoleToFile_DoWriteLn( const wxString& fmt )
{
_immediate_logger( toUTF8(fmt) );
_immediate_logger( fmt.ToUTF8() );
ConsoleToFile_Newline();
if( emuLog != NULL )
@ -702,7 +702,7 @@ static const IConsoleWriter ConsoleWriter_WindowAndFile =
ConsoleToWindow_ClearColor,
};
void Pcsx2App::EnableConsoleLogging() const
void Pcsx2App::EnableAllLogging() const
{
if( emuLog )
Console_SetActiveHandler( (m_ProgramLogBox!=NULL) ? (IConsoleWriter&)ConsoleWriter_WindowAndFile : (IConsoleWriter&)ConsoleWriter_File );

View File

@ -0,0 +1,223 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 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 <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "System.h"
#include "App.h"
#include "ModalPopups.h"
using namespace wxHelpers;
bool ConfButtons::Allows( wxWindowID id ) const
{
switch( id )
{
case wxID_OK: return HasOK();
case wxID_CANCEL: return HasCancel();
case wxID_APPLY: return HasApply();
case wxID_YES: return HasYes();
case wxID_NO: return HasNo();
case wxID_YESTOALL: return HasYes() && AllowsToAll();
case wxID_NOTOALL: return HasNo() && AllowsToAll();
case wxID_ABORT: return HasAbort();
case wxID_RETRY: return HasRetry();
// [TODO] : maybe add in an Ignore All?
case wxID_IGNORE: return HasIgnore();
}
return false;
}
static wxString ResultToString( int result )
{
switch( result )
{
case wxID_OK: return L"ok";
case wxID_CANCEL: return L"cancel";
case wxID_APPLY: return L"apply";
case wxID_YES: return L"yes";
case wxID_NO: return L"no";
case wxID_YESTOALL: return L"yestoall";
case wxID_NOTOALL: return L"notoall";
case wxID_ABORT: return L"abort";
case wxID_RETRY: return L"retry";
// [TODO] : maybe add in an Ignore All?
case wxID_IGNORE: return L"ignore";
}
return wxEmptyString;
}
static wxWindowID ParseThatResult( const wxString& src, const ConfButtons& validTypes )
{
if( !pxAssert( !src.IsEmpty() ) ) return wxID_ANY;
static const wxWindowID retvals[] =
{
wxID_OK, wxID_CANCEL, wxID_APPLY,
wxID_YES, wxID_NO,
wxID_YESTOALL, wxID_NOTOALL,
wxID_ABORT, wxID_RETRY, wxID_IGNORE,
};
for( int i=0; i<ArraySize( retvals ); ++i )
{
if( (validTypes.Allows( retvals[i] )) && (src == ResultToString(retvals[i])) )
return retvals[i];
}
return wxID_ANY;
}
wxWindowID Dialogs::IssueConfirmation( wxWindow* parent, const wxString& disablerKey, const ConfButtons& type, const wxString& title, const wxString& msg )
{
wxConfigBase* cfg = GetAppConfig();
if( cfg != NULL )
{
cfg->SetPath( L"/PopupDisablers" );
bool recdef = cfg->IsRecordingDefaults();
cfg->SetRecordDefaults( false );
wxString result = cfg->Read( disablerKey, L"enabled" );
cfg->SetRecordDefaults( recdef );
cfg->SetPath( L"/" );
result.LowerCase();
wxArrayString split;
SplitString( split, result, L"," );
// if only one param (no comma!?) then assume the entry is invalid and force a
// re-display of the dialog.
if( split.Count() > 1 )
{
result = split[0];
if( result == L"disabled" || result == L"off" || result == L"no" )
{
int result = ParseThatResult( split[1], type );
if( result != wxID_ANY ) return result;
}
}
}
Dialogs::ExtensibleConfirmation confirmDlg( parent, type, title, msg );
if( cfg == NULL ) return confirmDlg.ShowModal();
// Add an option that allows the user to disable this popup from showing again.
// (and if the config hasn't been initialized yet, then assume the dialog as non-disablable)
wxBoxSizer& cboxPad = *new wxBoxSizer( wxHORIZONTAL );
wxCheckBox& DisablerCtrl(
AddCheckBoxTo( &confirmDlg, cboxPad, _("Do not show this dialog again."))
);
confirmDlg.GetExtensibleSizer().Add( &cboxPad, wxSizerFlags().Centre() );
if( type != ConfButtons().OK() )
DisablerCtrl.SetToolTip(_("Disables this popup and whatever response you select here will be automatically used from now on."));
else
DisablerCtrl.SetToolTip(_("The popup will not be shown again. This setting can be undone from the settings panels."));
confirmDlg.Fit();
int modalResult = confirmDlg.ShowModal();
wxString cfgResult = ResultToString( modalResult );
if( DisablerCtrl.IsChecked() && !cfgResult.IsEmpty() )
{
cfg->SetPath( L"/PopupDisablers" );
cfg->Write( disablerKey, L"disabled," + cfgResult );
cfg->SetPath( L"/" );
}
return modalResult;
}
Dialogs::ExtensibleConfirmation::ExtensibleConfirmation( wxWindow* parent, const ConfButtons& type, const wxString& title, const wxString& msg ) :
wxDialogWithHelpers( parent, wxID_ANY, title, false )
, m_ExtensibleSizer( *new wxBoxSizer( wxVERTICAL ) )
, m_ButtonSizer( *new wxBoxSizer( wxHORIZONTAL ) )
{
wxBoxSizer& mainsizer( *new wxBoxSizer(wxVERTICAL) );
// Add the message padded some (StdCenter gives us a 5 pt padding). Helps emphasize it a bit.
wxBoxSizer& msgPadSizer( *new wxBoxSizer(wxVERTICAL) );
AddStaticText( msgPadSizer, msg, wxALIGN_CENTRE, 444 );
mainsizer.Add( &msgPadSizer, SizerFlags::StdCenter() );
mainsizer.Add( &m_ExtensibleSizer, wxSizerFlags().Centre() );
// Populate the Button Sizer.
// We prefer this over the built-in wxWidgets ButtonSizer stuff used for other types of
// dialogs because we offer more button types, and we don't want the MSW default behavior
// of right-justified buttons.
#ifdef __WXGTK__
// GTK+ / Linux inverts OK/CANCEL order -- cancel / no first, OK / Yes later. >_<
if( type.HasCancel() )
AddActionButton( wxID_CANCEL );
if( type.HasNo() )
{
AddActionButton( wxID_NO );
if( type.AllowsToAll() ) AddActionButton( wxID_NOTOALL );
}
if( type.HasOK() || type.HasYes() ) // Extra space between Affirm and Cancel Actions
m_ButtonSizer.Add(0, 0, 1, wxEXPAND, 0);
#endif
if( type.HasOK() )
AddActionButton( wxID_OK );
if( type.HasYes() )
{
AddActionButton( wxID_YES );
if( type.AllowsToAll() )
AddActionButton( wxID_YESTOALL );
}
#ifndef __WXGTK__
if( type.HasNo() || type.HasCancel() ) // Extra space between Affirm and Cancel Actions
m_ButtonSizer.Add(0, 0, 1, wxEXPAND, 0);
if( type.HasNo() )
{
AddActionButton( wxID_NO );
if( type.AllowsToAll() )
AddActionButton( wxID_NOTOALL );
}
if( type.HasCancel() )
AddActionButton( wxID_CANCEL );
#endif
mainsizer.Add( &m_ButtonSizer, SizerFlags::StdCenter() );
SetSizerAndFit( &mainsizer, true );
CenterOnScreen();
}
void Dialogs::ExtensibleConfirmation::AddActionButton( wxWindowID id )
{
m_ButtonSizer.Add( new wxButton( this, id ), SizerFlags::StdButton() )->SetProportion( 6 );
}

View File

@ -64,6 +64,60 @@ protected:
virtual void OnDoubleClicked( wxCommandEvent& evt );
};
class ConfButtons
{
protected:
BITFIELD32()
bool
m_OK:1,
m_Cancel:1,
m_Yes:1,
m_No:1,
m_AllowToAll:1,
m_Apply:1,
m_Abort:1,
m_Retry:1,
m_Ignore:1;
BITFIELD_END
public:
ConfButtons() : bitset( 0 ) { }
ConfButtons& OK() { m_OK = true; return *this; }
ConfButtons& Cancel() { m_Cancel = true; return *this; }
ConfButtons& Apply() { m_Apply = true; return *this; }
ConfButtons& Yes() { m_Yes = true; return *this; }
ConfButtons& No() { m_No = true; return *this; }
ConfButtons& ToAll() { m_AllowToAll = true; return *this; }
ConfButtons& Abort() { m_Abort = true; return *this; }
ConfButtons& Retry() { m_Retry = true; return *this; }
ConfButtons& Ignore() { m_Ignore = true; return *this; }
bool HasOK() const { return m_OK; }
bool HasCancel() const { return m_Cancel; }
bool HasApply() const { return m_Apply; }
bool HasYes() const { return m_Yes; }
bool HasNo() const { return m_No; }
bool AllowsToAll() const{ return m_AllowToAll; }
bool HasAbort() const { return m_Abort; }
bool HasRetry() const { return m_Retry; }
bool HasIgnore() const { return m_Ignore; }
bool Allows( wxWindowID id ) const;
bool operator ==( const ConfButtons& right ) const
{
return OpEqu( bitset );
}
bool operator !=( const ConfButtons& right ) const
{
return !OpEqu( bitset );
}
};
namespace Dialogs
{
class AboutBoxDialog: public wxDialogWithHelpers
@ -76,6 +130,7 @@ namespace Dialogs
//wxStaticBitmap m_bitmap_logo;
wxStaticBitmap m_bitmap_dualshock;
};
class PickUserModeDialog : public wxDialogWithHelpers
{
@ -103,5 +158,22 @@ namespace Dialogs
void OnOverwrite_Click( wxCommandEvent& evt );
};
class ExtensibleConfirmation : public wxDialogWithHelpers
{
protected:
wxBoxSizer& m_ExtensibleSizer;
wxBoxSizer& m_ButtonSizer;
public:
ExtensibleConfirmation( wxWindow* parent, const ConfButtons& type, const wxString& title, const wxString& msg );
virtual ~ExtensibleConfirmation() throw() {}
wxBoxSizer& GetExtensibleSizer() const { return m_ExtensibleSizer; }
protected:
void AddActionButton( wxWindowID id );
};
wxWindowID IssueConfirmation( wxWindow* parent, const wxString& disablerKey, const ConfButtons& type, const wxString& title, const wxString& msg );
}

View File

@ -89,19 +89,14 @@ void MainEmuFrame::UpdateIsoSrcFile()
GetMenuBar()->SetLabel( MenuId_Src_Iso, label );
}
void MainEmuFrame::LoadRecentIsoList( wxConfigBase& conf )
void MainEmuFrame::LoadSaveRecentIsoList( IniInterface& conf )
{
if( m_RecentIsoList )
m_RecentIsoList->Load( conf );
if( conf.IsLoading() )
m_RecentIsoList->Load( conf.GetConfig() );
else
m_RecentIsoList->Save( conf.GetConfig() );
}
void MainEmuFrame::SaveRecentIsoList( wxConfigBase& conf )
{
if( m_RecentIsoList )
m_RecentIsoList->Load( conf );
}
// ------------------------------------------------------------------------
// Video / Audio / Pad "Extensible" Menus
// ------------------------------------------------------------------------
@ -260,13 +255,36 @@ void MainEmuFrame::InitLogBoxPosition( AppConfig::ConsoleLogOptions& conf )
}
}
static void OnCoreThreadStatusChanged( void* obj, const wxCommandEvent& evt )
void MainEmuFrame::OnCoreThreadStatusChanged( void* obj, const wxCommandEvent& evt )
{
if( obj == NULL ) return;
MainEmuFrame* mframe = (MainEmuFrame*)obj;
mframe->ApplyCoreStatus();
}
void MainEmuFrame::OnCorePluginStatusChanged( void* obj, const wxCommandEvent& evt )
{
if( obj == NULL ) return;
MainEmuFrame* mframe = (MainEmuFrame*)obj;
mframe->ApplyCoreStatus();
}
void MainEmuFrame::OnSettingsApplied( void* obj, const int& evt )
{
if( obj == NULL ) return;
MainEmuFrame* mframe = (MainEmuFrame*)obj;
mframe->ApplySettings();
}
void MainEmuFrame::OnSettingsLoadSave( void* obj, const IniInterface& evt )
{
if( obj == NULL ) return;
MainEmuFrame* mframe = (MainEmuFrame*)obj;
// FIXME: Evil const cast hack!
mframe->LoadSaveRecentIsoList( const_cast<IniInterface&>(evt) );
}
// ------------------------------------------------------------------------
MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title):
wxFrame(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE & ~(wxMAXIMIZE_BOX | wxRESIZE_BORDER) ),
@ -295,7 +313,10 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title):
m_MenuItem_Console( *new wxMenuItem( &m_menuMisc, MenuId_Console, L"Show Console", wxEmptyString, wxITEM_CHECK ) ),
m_Listener_CoreThreadStatus( wxGetApp().Source_CoreThreadStatus(), CmdEvt_Listener( this, OnCoreThreadStatusChanged ) )
m_Listener_CoreThreadStatus( wxGetApp().Source_CoreThreadStatus(), CmdEvt_Listener( this, OnCoreThreadStatusChanged ) ),
m_Listener_CorePluginStatus( wxGetApp().Source_CorePluginStatus(), CmdEvt_Listener( this, OnCorePluginStatusChanged ) ),
m_Listener_SettingsApplied( wxGetApp().Source_SettingsApplied(), EventListener<int>( this, OnSettingsApplied ) ),
m_Listener_SettingsLoadSave( wxGetApp().Source_SettingsLoadSave(), EventListener<IniInterface>( this, OnSettingsLoadSave ) )
{
// ------------------------------------------------------------------------
// Initial menubar setup. This needs to be done first so that the menu bar's visible size
@ -471,8 +492,8 @@ MainEmuFrame::~MainEmuFrame() throw()
{
try
{
if( m_RecentIsoList )
m_RecentIsoList->Save( *wxConfigBase::Get( false ) );
if( m_RecentIsoList && GetAppConfig() )
m_RecentIsoList->Save( *GetAppConfig() );
}
DESTRUCTOR_CATCHALL
}
@ -485,7 +506,7 @@ void MainEmuFrame::ReloadRecentLists()
// the recent file count has been changed, and it's a helluva lot easier than trying
// to make a clone copy of this complex object. ;)
wxConfigBase* cfg = wxConfigBase::Get( false );
wxConfigBase* cfg = GetAppConfig();
pxAssert( cfg != NULL );
if( m_RecentIsoList )
@ -495,6 +516,14 @@ void MainEmuFrame::ReloadRecentLists()
cfg->Flush();
}
void MainEmuFrame::ApplyCoreStatus()
{
GetMenuBar()->Enable( MenuId_Sys_SuspendResume, SysHasValidState() );
GetMenuBar()->Enable( MenuId_Sys_Reset, SysHasValidState() || (g_plugins!=NULL) );
GetMenuBar()->SetLabel( MenuId_Sys_SuspendResume, CoreThread.IsOpen() ? _("Suspend") : _("Resume") );
}
void MainEmuFrame::ApplySettings()
{
GetMenuBar()->Check( MenuId_SkipBiosToggle, g_Conf->EmuOptions.SkipBiosSplash );
@ -502,10 +531,6 @@ void MainEmuFrame::ApplySettings()
GetMenuBar()->Check( MenuId_Config_Multitap0Toggle, g_Conf->EmuOptions.MultitapPort0_Enabled );
GetMenuBar()->Check( MenuId_Config_Multitap1Toggle, g_Conf->EmuOptions.MultitapPort1_Enabled );
GetMenuBar()->Enable( MenuId_Sys_SuspendResume, SysHasValidState() );
GetMenuBar()->SetLabel( MenuId_Sys_SuspendResume, CoreThread.IsExecMode_Running() ? _("Suspend") :_("Resume") );
if( m_RecentIsoList )
{
if( m_RecentIsoList->GetMaxFiles() != g_Conf->RecentFileCount )

View File

@ -64,7 +64,10 @@ protected:
wxMenuItem& m_MenuItem_Console;
CmdEvt_ListenerBinding m_Listener_CoreThreadStatus;
CmdEvt_ListenerBinding m_Listener_CoreThreadStatus;
CmdEvt_ListenerBinding m_Listener_CorePluginStatus;
EventListenerBinding<int> m_Listener_SettingsApplied;
EventListenerBinding<IniInterface> m_Listener_SettingsLoadSave;
// ------------------------------------------------------------------------
// MainEmuFrame Constructors and Member Methods
@ -79,13 +82,18 @@ public:
bool IsPaused() const { return GetMenuBar()->IsChecked( MenuId_Sys_SuspendResume ); }
void UpdateIsoSrcFile();
void UpdateIsoSrcSelection();
void ApplySettings();
void ReloadRecentLists();
void LoadRecentIsoList( wxConfigBase& conf );
void SaveRecentIsoList( wxConfigBase& conf );
protected:
static void OnCoreThreadStatusChanged( void* obj, const wxCommandEvent& evt );
static void OnCorePluginStatusChanged( void* obj, const wxCommandEvent& evt );
static void OnSettingsApplied( void* obj, const int& evt );
static void MainEmuFrame::OnSettingsLoadSave( void* obj, const IniInterface& evt );
void LoadSaveRecentIsoList( IniInterface& conf );
void ApplySettings();
void ApplyCoreStatus();
void InitLogBoxPosition( AppConfig::ConsoleLogOptions& conf );
void OnCloseWindow(wxCloseEvent& evt);

View File

@ -27,18 +27,12 @@ using namespace Dialogs;
void MainEmuFrame::Menu_ConfigSettings_Click(wxCommandEvent &event)
{
if( Dialogs::ConfigurationDialog( this ).ShowModal() )
{
AppSaveSettings();
}
Dialogs::ConfigurationDialog( this ).ShowModal();
}
void MainEmuFrame::Menu_SelectBios_Click(wxCommandEvent &event)
{
if( Dialogs::BiosSelectorDialog( this ).ShowModal() )
{
AppSaveSettings();
}
Dialogs::BiosSelectorDialog( this ).ShowModal();
}
void MainEmuFrame::Menu_CdvdSource_Click( wxCommandEvent &event )
@ -150,10 +144,11 @@ void MainEmuFrame::Menu_SkipBiosToggle_Click( wxCommandEvent &event )
{
g_Conf->EmuOptions.SkipBiosSplash = GetMenuBar()->IsChecked( MenuId_SkipBiosToggle );
wxConfigBase* conf = wxConfigBase::Get( false );
if( NULL == conf ) return;
IniSaver saver( *conf );
g_Conf->EmuOptions.LoadSave( saver );
if( wxConfigBase* conf = GetAppConfig() )
{
IniSaver saver( *conf );
g_Conf->EmuOptions.LoadSave( saver );
}
}
void MainEmuFrame::Menu_OpenELF_Click(wxCommandEvent &event)
@ -191,8 +186,17 @@ void MainEmuFrame::Menu_SuspendResume_Click(wxCommandEvent &event)
{
if( !SysHasValidState() ) return;
if( !CoreThread.Suspend() )
CoreThread.Resume();
// Note: We manually update the menu here, even though it'll be updated again
// when the thread "officially" suspends or resumes (via listener callback), because
// the callback is tied to the actual thread status
if( CoreThread.Suspend() )
GetMenuBar()->SetLabel( MenuId_Sys_SuspendResume, _("Resume") );
else
{
sApp.SysExecute();
GetMenuBar()->SetLabel( MenuId_Sys_SuspendResume, _("Suspend") );
}
}
void MainEmuFrame::Menu_SysReset_Click(wxCommandEvent &event)
@ -204,6 +208,8 @@ void MainEmuFrame::Menu_SysReset_Click(wxCommandEvent &event)
if( resume )
sApp.SysExecute();
GetMenuBar()->Enable( MenuId_Sys_Reset, resume );
}
void MainEmuFrame::Menu_ConfigPlugin_Click(wxCommandEvent &event)
@ -229,9 +235,10 @@ void MainEmuFrame::Menu_ConfigPlugin_Click(wxCommandEvent &event)
LoadPluginsImmediate();
if( g_plugins == NULL ) return;
bool resume = CoreThread.Suspend();
wxWindowDisabler disabler;
//ScopedWindowDisable disabler( this );
g_plugins->Configure( pid );
if( resume ) CoreThread.Resume();
}
void MainEmuFrame::Menu_Debug_Open_Click(wxCommandEvent &event)

View File

@ -51,22 +51,27 @@ namespace Exception
//
class CannotApplySettings : public BaseException
{
public:
bool IsVerbose;
protected:
Panels::BaseApplicableConfigPanel* m_Panel;
public:
DEFINE_EXCEPTION_COPYTORS( CannotApplySettings )
explicit CannotApplySettings( Panels::BaseApplicableConfigPanel* thispanel, const char* msg=wxLt("Cannot apply new settings, one of the settings is invalid.") )
explicit CannotApplySettings( Panels::BaseApplicableConfigPanel* thispanel, const char* msg=wxLt("Cannot apply new settings, one of the settings is invalid."), bool isVerbose = true )
{
BaseException::InitBaseEx( msg );
m_Panel = thispanel;
IsVerbose = isVerbose;
}
explicit CannotApplySettings( Panels::BaseApplicableConfigPanel* thispanel, const wxString& msg_eng, const wxString& msg_xlt )
{
BaseException::InitBaseEx( msg_eng, msg_xlt );
m_Panel = thispanel;
IsVerbose = true;
}
Panels::BaseApplicableConfigPanel* GetPanel()

View File

@ -85,8 +85,7 @@ bool Panels::StaticApplyState::ApplyPage( int pageid, bool saveOnSuccess )
// Note: apply first, then save -- in case the apply fails.
AppApplySettings( &confcopy );
if( saveOnSuccess ) AppSaveSettings();
AppApplySettings( &confcopy, saveOnSuccess );
}
catch( Exception::CannotApplySettings& ex )
{
@ -95,10 +94,13 @@ bool Panels::StaticApplyState::ApplyPage( int pageid, bool saveOnSuccess )
UseDefaultSettingsFolder = oldUseDefSet;
*g_Conf = confcopy;
wxMessageBox( ex.FormatDisplayMessage(), _("Cannot apply settings...") );
if( ex.IsVerbose )
{
wxMessageBox( ex.FormatDisplayMessage(), _("Cannot apply settings...") );
if( ex.GetPanel() != NULL )
ex.GetPanel()->SetFocusToMe();
if( ex.GetPanel() != NULL )
ex.GetPanel()->SetFocusToMe();
}
retval = false;
}
@ -170,7 +172,7 @@ Panels::LanguageSelectionPanel::LanguageSelectionPanel( wxWindow& parent, int id
int size = m_langs.size();
int cursel = 0;
wxString* compiled = new wxString[size];
ScopedArray<wxString> compiled( size ); //, L"Compiled Language Names" );
wxString configLangName( wxLocale::GetLanguageName( wxLANGUAGE_DEFAULT ) );
for( int i=0; i<size; ++i )
@ -181,7 +183,7 @@ Panels::LanguageSelectionPanel::LanguageSelectionPanel( wxWindow& parent, int id
}
m_picker = new wxComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
size, compiled, wxCB_READONLY | wxCB_SORT );
size, compiled.GetPtr(), wxCB_READONLY | wxCB_SORT );
m_picker->SetSelection( cursel );
wxBoxSizer& s_lang = *new wxBoxSizer( wxHORIZONTAL );

View File

@ -18,6 +18,7 @@
#include "Plugins.h"
#include "Utilities/ScopedPtr.h"
#include "ConfigurationPanels.h"
#include "Dialogs/ModalPopups.h"
#include <wx/dynlib.h>
#include <wx/dir.h>
@ -276,6 +277,8 @@ void Panels::PluginSelectorPanel::Apply()
// user never entered plugins panel? Skip application since combo boxes are invalid/uninitialized.
if( !m_FileList ) return;
AppConfig curconf( *g_Conf );
for( int i=0; i<NumPluginTypes; ++i )
{
int sel = m_ComponentBoxes.Get(i).GetSelection();
@ -304,7 +307,7 @@ void Panels::PluginSelectorPanel::Apply()
// the whole plugin system needs to be re-loaded.
const PluginInfo* pi = tbl_PluginInfo; do {
if( g_Conf->FullpathTo( pi->id ) != g_Conf->FullpathTo( pi->id ) )
if( g_Conf->FullpathTo( pi->id ) != curconf.FullpathTo( pi->id ) )
break;
} while( ++pi, pi->shortname != NULL );
@ -313,6 +316,21 @@ void Panels::PluginSelectorPanel::Apply()
if( CoreThread.IsRunning() )
{
// [TODO] : Post notice that this shuts down existing emulation, and may not safely recover.
int result = Dialogs::IssueConfirmation( this, L"PluginSelector:ConfirmShutdown", ConfButtons().OK().Cancel(),
_("Shutdown PS2 virtual machine?"),
pxE( ".Popup:PluginSelector:ConfirmShutdown",
L"Warning! Changing plugins requires a complete shutdown and reset of the PS2 virtual machine. "
L"PCSX2 will attempt to save and restore the state, but if the newly selected plugins are "
L"incompatible the recovery may fail, and current progress will be lost."
L"\n\n"
L"Are you sure you want to apply settings now?"
)
);
if( result == wxID_CANCEL )
throw Exception::CannotApplySettings( this, "Cannot apply settings: canceled by user because plugins changed while the emulation state was active.", false );
}
sApp.SysReset();
@ -358,12 +376,17 @@ void Panels::PluginSelectorPanel::DoRefresh()
return;
}
// Disable all controls until enumeration is complete.
// Disable all controls until enumeration is complete
m_ComponentBoxes.Hide();
// (including next button if it's a Wizard)
wxWindow* forwardButton = GetGrandParent()->FindWindow( wxID_FORWARD );
if( forwardButton != NULL )
forwardButton->Disable();
// Show status bar for plugin enumeration. Use a pending event so that
// the window's size can get initialized properly before trying to custom-
// fit the status panel to it.
m_ComponentBoxes.Hide();
wxCommandEvent evt( pxEVT_ShowStatusBar );
GetEventHandler()->AddPendingEvent( evt );
@ -415,8 +438,10 @@ void Panels::PluginSelectorPanel::OnConfigure_Clicked( wxCommandEvent& evt )
wxDynamicLibrary dynlib( (*m_FileList)[(int)m_ComponentBoxes.Get(pid).GetClientData(sel)] );
if( PluginConfigureFnptr configfunc = (PluginConfigureFnptr)dynlib.GetSymbol( tbl_PluginInfo[pid].GetShortname() + L"configure" ) )
{
bool resume = CoreThread.Suspend();
wxWindowDisabler disabler;
configfunc();
if( resume ) CoreThread.Resume();
}
}
@ -447,6 +472,10 @@ void Panels::PluginSelectorPanel::OnEnumComplete( wxCommandEvent& evt )
m_ComponentBoxes.Show();
m_StatusPanel.Hide();
m_StatusPanel.Reset();
wxWindow* forwardButton = GetGrandParent()->FindWindow( wxID_FORWARD );
if( forwardButton != NULL )
forwardButton->Enable();
}

View File

@ -1816,10 +1816,6 @@
RelativePath="..\..\gui\IniInterface.cpp"
>
</File>
<File
RelativePath="..\..\..\common\include\Utilities\Listeners.h"
>
</File>
<File
RelativePath="..\..\gui\MainFrame.cpp"
>
@ -1871,6 +1867,10 @@
RelativePath="..\..\gui\Dialogs\ConfigurationDialog.h"
>
</File>
<File
RelativePath="..\..\gui\Dialogs\ConfirmationDialogs.cpp"
>
</File>
<File
RelativePath="..\..\gui\Dialogs\FirstTimeWizard.cpp"
>

View File

@ -123,7 +123,6 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "wx", "wx", "{62BF822E-6A12-49A8-BE8C-C55A9BCA24DA}"
ProjectSection(SolutionItems) = preProject
common\include\wx\folderdesc.txt = common\include\wx\folderdesc.txt
common\include\wx\scopedptr.h = common\include\wx\scopedptr.h
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bin2cpp", "tools\bin2cpp\bin2c.vcproj", "{677B7D11-D5E1-40B3-88B1-9A4DF83D2213}"