wxgui: Added plugin selection dialog (complete with plugin enumeration and an exceedingly fancy progress bar), fixed some menus, added isofile recent lists, and lots more stuff is correctly saved and loaded from the configuration file.

* Dev note: Re-enabled USE_STL in wxWidgets since that's required to ensure thread safety.

git-svn-id: http://pcsx2.googlecode.com/svn/branches/wxgui@1505 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-07-14 06:18:52 +00:00
parent ec10451047
commit 8505e4a7e7
38 changed files with 1147 additions and 327 deletions

View File

@ -127,6 +127,10 @@
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\include\wx\setup.h"
>
</File>
<File
RelativePath="..\..\include\wx\msw\setup.h"
>

View File

@ -204,7 +204,7 @@
// Default is 0
//
// Recommended setting: YMMV
#define wxUSE_STL 0
#define wxUSE_STL 1
// Support for message/error logging. This includes wxLogXXX() functions and
// wxLog and derived classes. Don't set this to 0 unless you really know what

View File

@ -204,7 +204,7 @@
// Default is 0
//
// Recommended setting: YMMV
#define wxUSE_STL 0
#define wxUSE_STL 1
// Support for message/error logging. This includes wxLogXXX() functions and
// wxLog and derived classes. Don't set this to 0 unless you really know what
@ -1155,16 +1155,16 @@
#define wxUSE_LIBPNG 1
// Set to 1 for JPEG format support (requires libjpeg)
#define wxUSE_LIBJPEG 1
#define wxUSE_LIBJPEG 0
// Set to 1 for TIFF format support (requires libtiff)
#define wxUSE_LIBTIFF 1
#define wxUSE_LIBTIFF 0
// Set to 1 for TGA format support (loading only)
#define wxUSE_TGA 1
#define wxUSE_TGA 0
// Set to 1 for GIF format support
#define wxUSE_GIF 1
#define wxUSE_GIF 0
// Set to 1 for PNM format support
#define wxUSE_PNM 1

View File

@ -204,7 +204,7 @@
// Default is 0
//
// Recommended setting: YMMV
#define wxUSE_STL 0
#define wxUSE_STL 1
// Support for message/error logging. This includes wxLogXXX() functions and
// wxLog and derived classes. Don't set this to 0 unless you really know what
@ -963,7 +963,7 @@
#define wxUSE_MDI 0
// Set to 0 to disable document/view architecture
#define wxUSE_DOC_VIEW_ARCHITECTURE 0
#define wxUSE_DOC_VIEW_ARCHITECTURE 1
// Set to 0 to disable MDI document/view architecture
//

View File

@ -201,7 +201,7 @@
// Default is 0
//
// Recommended setting: YMMV
#define wxUSE_STL 0
#define wxUSE_STL 1
// Set wxUSE_EXTENDED_RTTI to 1 to use extended RTTI
//

View File

@ -204,7 +204,7 @@
// Default is 0
//
// Recommended setting: YMMV
#define wxUSE_STL 0
#define wxUSE_STL 1
// Support for message/error logging. This includes wxLogXXX() functions and
// wxLog and derived classes. Don't set this to 0 unless you really know what

View File

@ -18,6 +18,15 @@
#pragma once
// macro provided for tagging translation strings, without actually running them through the
// translator (which the _() does automatically, and sometimes we don't want that). This is
// a shorthand replacement for wxTRANSLATE.
#define wxLt(a) (a)
#ifndef wxASSERT_MSG_A
# define wxASSERT_MSG_A( cond, msg ) wxASSERT_MSG( cond, wxString::FromAscii( msg ).c_str() )
#endif
// must include wx/setup.h first, otherwise we get warnings/errors regarding __LINUX__
#include <wx/setup.h>

View File

@ -24,11 +24,12 @@ extern void DevAssert( bool condition, const char* msg );
//////////////////////////////////////////////////////////////////////////////////////////
// This class provides an easy and clean method for ensuring objects are not copyable.
//
class NoncopyableObject
{
protected:
NoncopyableObject() {}
~NoncopyableObject() {}
~NoncopyableObject() {} // intentionally non-virtual (code should never use this as a polymorphic type)
// Programmer's note:
// No need to provide implementations for these methods since they should
@ -119,8 +120,10 @@ namespace Exception
virtual bool IsDelaySlot() const=0;
};
//////////////////////////////////////////////////////////////////////////////////
//
// ---------------------------------------------------------------------------------------
// Generalized Exceptions: RuntimeError / LogicError / AssertionFailure
// ---------------------------------------------------------------------------------------
class RuntimeError : public BaseException
{
public:
@ -128,14 +131,13 @@ namespace Exception
RuntimeError( const RuntimeError& src ) : BaseException( src ) {}
explicit RuntimeError( const char* msg="An unhandled runtime error has occurred, somewhere in the depths of Pcsx2's cluttered brain-matter." ) :
explicit RuntimeError( const char* msg=wxLt("An unhandled runtime error has occurred, somewhere in the depths of Pcsx2's cluttered brain-matter.") ) :
BaseException( msg ) { }
explicit RuntimeError( const wxString& msg_eng, const wxString& msg_xlt ) :
BaseException( msg_eng, msg_xlt ) { }
};
// ------------------------------------------------------------------------
class LogicError : public BaseException
{
public:
@ -143,7 +145,7 @@ namespace Exception
LogicError( const LogicError& src ) : BaseException( src ) {}
explicit LogicError( const char* msg="An unhandled logic error has occurred." ) :
explicit LogicError( const char* msg=wxLt("An unhandled logic error has occurred.") ) :
BaseException( msg ) { }
explicit LogicError( const wxString& msg_eng, const wxString& msg_xlt ) :
@ -153,7 +155,7 @@ namespace Exception
class AssertionFailure : public LogicError
{
public:
explicit AssertionFailure( const char* msg="Assertion Failure" ) :
explicit AssertionFailure( const char* msg=wxLt("Assertion Failure") ) :
LogicError( msg ) {}
explicit AssertionFailure( const wxString& msg_eng, const wxString& msg_xlt ) :
@ -162,22 +164,24 @@ namespace Exception
virtual ~AssertionFailure() throw() {}
};
//////////////////////////////////////////////////////////////////////////////////
//
// ---------------------------------------------------------------------------------------
// OutOfMemory / InvalidOperation / InvalidArgument / IndexBoundsFault / ParseError
// ---------------------------------------------------------------------------------------
class OutOfMemory : public RuntimeError
{
public:
virtual ~OutOfMemory() throw() {}
explicit OutOfMemory( const char* msg="Out of memory" ) :
explicit OutOfMemory( const char* msg=wxLt("Out of memory") ) :
RuntimeError( msg ) {}
explicit OutOfMemory( const wxString& msg_eng, const wxString& msg_xlt=_("Out of memory") ) :
RuntimeError( msg_eng, msg_xlt ) { }
};
// ------------------------------------------------------------------------
// This exception thrown any time an operation is attempted when an object
// is in an uninitialized state.
//
class InvalidOperation : public LogicError
{
public:
@ -189,9 +193,9 @@ namespace Exception
LogicError( msg_eng, msg_xlt ) { }
};
// ------------------------------------------------------------------------
// This exception thrown any time an operation is attempted when an object
// is in an uninitialized state.
//
class InvalidArgument : public LogicError
{
public:
@ -200,13 +204,13 @@ namespace Exception
LogicError( msg )
{
// assertions make debugging easier sometimes. :)
wxASSERT( msg );
wxASSERT_MSG_A( false, msg );
}
};
// ------------------------------------------------------------------------
// Keep those array indexers in bounds when using the SafeArray type, or you'll be
// seeing these.
//
class IndexBoundsFault : public LogicError
{
public:
@ -223,14 +227,13 @@ namespace Exception
BadIndex( index )
{
// assertions make debugging easier sometimes. :)
wxASSERT( L"Index is outside the bounds of an array" );
wxASSERT_MSG( false, L"Index is outside the bounds of an array" );
}
virtual wxString LogMessage() const;
virtual wxString DisplayMessage() const;
};
// ------------------------------------------------------------------------
class ParseError : public RuntimeError
{
public:
@ -239,20 +242,23 @@ namespace Exception
RuntimeError( msg ) {}
};
//////////////////////////////////////////////////////////////////////////////////
//
// ---------------------------------------------------------------------------------------
// Hardware/OS Exceptions:
// HardwareDeficiency / CpuStateShutdown / PluginFailure / ThreadCreationError
// ---------------------------------------------------------------------------------------
class HardwareDeficiency : public RuntimeError
{
public:
explicit HardwareDeficiency( const char* msg="Your machine's hardware is incapable of running Pcsx2. Sorry dood." ) :
explicit HardwareDeficiency( const char* msg=wxLt("Your machine's hardware is incapable of running Pcsx2. Sorry dood.") ) :
RuntimeError( msg ) {}
virtual ~HardwareDeficiency() throw() {}
};
// ------------------------------------------------------------------------
// This exception is thrown by the PS2 emulation (R5900, etc) when bad things happen
// that force the emulation state to terminate. The GUI should handle them by returning
// the user to the GUI.
//
class CpuStateShutdown : public RuntimeError
{
public:
@ -264,7 +270,6 @@ namespace Exception
RuntimeError( msg_eng, msg_xlt.IsEmpty() ? L"Unexpected emulation shutdown" : msg_xlt ) { }
};
// ------------------------------------------------------------------------
class PluginFailure : public RuntimeError
{
public:
@ -280,7 +285,6 @@ namespace Exception
virtual wxString DisplayMessage() const;
};
// ------------------------------------------------------------------------
class ThreadCreationError : public RuntimeError
{
public:
@ -289,12 +293,15 @@ namespace Exception
RuntimeError( msg ) {}
};
//////////////////////////////////////////////////////////////////////////////////
// STREAMING EXCEPTIONS
// ---------------------------------------------------------------------------------------
// Streaming (file) Exceptions:
// Stream / BadStream / CreateStream / FileNotFound / AccessDenied / EndOfStream
// ---------------------------------------------------------------------------------------
// ------------------------------------------------------------------------
// Generic stream error. Contains the name of the stream and a message.
// This exception is usually thrown via derived classes, except in the (rare) case of a generic / unknown error.
// This exception is usually thrown via derived classes, except in the (rare) case of a
// generic / unknown error.
//
class Stream : public RuntimeError
{
public:
@ -322,23 +329,23 @@ namespace Exception
virtual wxString DisplayMessage() const;
};
// ------------------------------------------------------------------------
// A generic base error class for bad streams -- corrupted data, sudden closures, loss of
// connection, or anything else that would indicate a failure to read the data after the
// stream was successfully opened.
//
class BadStream : public Stream
{
public:
virtual ~BadStream() throw() {}
explicit BadStream(
const wxString& objname=wxString(),
const char* msg="File data is corrupted or incomplete, or the stream connection closed unexpectedly"
const char* msg=wxLt("File data is corrupted or incomplete, or the stream connection closed unexpectedly")
) :
Stream( objname, msg ) {}
};
// ------------------------------------------------------------------------
// A generic exception for odd-ball stream creation errors.
//
class CreateStream : public Stream
{
public:
@ -346,18 +353,18 @@ namespace Exception
explicit CreateStream(
const char* objname,
const char* msg="File could not be created or opened" ) :
const char* msg=wxLt("File could not be created or opened") ) :
Stream( wxString::FromAscii( objname ), msg ) {}
explicit CreateStream(
const wxString& objname=wxString(),
const char* msg="File could not be created or opened" ) :
const char* msg=wxLt("File could not be created or opened") ) :
Stream( objname, msg ) {}
};
// ------------------------------------------------------------------------
// Exception thrown when an attempt to open a non-existent file is made.
// (this exception can also mean file permissions are invalid)
//
class FileNotFound : public CreateStream
{
public:
@ -370,7 +377,6 @@ namespace Exception
CreateStream( objname, msg ) {}
};
// ------------------------------------------------------------------------
class AccessDenied : public CreateStream
{
public:
@ -381,21 +387,25 @@ namespace Exception
CreateStream( objname, msg ) {}
};
// ------------------------------------------------------------------------
// Generic End of Stream exception (sometimes an error, and sometimes just used as a
// shortcut for manual feof checks).
// EndOfStream can be used either as an error, or used just as a shortcut for manual
// feof checks.
//
class EndOfStream : public Stream
{
public:
virtual ~EndOfStream() throw() {}
explicit EndOfStream( const wxString& objname, const char* msg="End of file" ) :
explicit EndOfStream( const wxString& objname, const char* msg=wxLt("Unexpected end of file") ) :
Stream( objname, msg ) {}
};
//////////////////////////////////////////////////////////////////////////////////
// SAVESTATE EXCEPTIONS
// ---------------------------------------------------------------------------------------
// Savestate Exceptions:
// BadSavedState / FreezePluginFailure / StateLoadError / UnsupportedStateVersion /
// StateCrcMismatch
// ---------------------------------------------------------------------------------------
// Exception thrown when a corrupted or truncated savestate is encountered.
//
class BadSavedState : public BadStream
{
public:
@ -406,8 +416,8 @@ namespace Exception
BadStream( objname, msg ) {}
};
// ------------------------------------------------------------------------
// Exception thrown by SaveState class when a critical plugin or gzread
//
class FreezePluginFailure : public RuntimeError
{
public:
@ -426,21 +436,21 @@ namespace Exception
virtual wxString DisplayMessage() const;
};
// ------------------------------------------------------------------------
// The savestate code throws Recoverable errors when it fails prior to actually modifying
// A recoverable error thrown when a savestate load fails prior to actually modifying
// the current emulation state. Recoverable errors are always thrown from the SaveState
// object construction (and never from Freeze methods).
class StateLoadError_Recoverable : public RuntimeError
//
class StateLoadError : public RuntimeError
{
public:
virtual ~StateLoadError_Recoverable() throw() {}
explicit StateLoadError_Recoverable( const char* msg="Recoverable savestate load error" ) :
virtual ~StateLoadError() throw() {}
explicit StateLoadError( const char* msg="Recoverable savestate load error" ) :
RuntimeError( msg ) {}
};
// ------------------------------------------------------------------------
// A recoverable exception thrown when the savestate being loaded isn't supported.
class UnsupportedStateVersion : public StateLoadError_Recoverable
//
class UnsupportedStateVersion : public StateLoadError
{
public:
u32 Version; // version number of the unsupported state.
@ -448,7 +458,7 @@ namespace Exception
public:
virtual ~UnsupportedStateVersion() throw() {}
explicit UnsupportedStateVersion( int version ) :
StateLoadError_Recoverable(),
StateLoadError(),
Version( version )
{}
@ -456,11 +466,11 @@ namespace Exception
virtual wxString DisplayMessage() const;
};
// ------------------------------------------------------------------------
// A recoverable exception thrown when the CRC of the savestate does not match the
// CRC returned by the Cdvd driver.
// [feature not implemented yet]
class StateCrcMismatch : public StateLoadError_Recoverable
//
class StateCrcMismatch : public StateLoadError
{
public:
u32 Crc_Savestate;
@ -469,7 +479,7 @@ namespace Exception
public:
virtual ~StateCrcMismatch() throw() {}
explicit StateCrcMismatch( u32 crc_save, u32 crc_cdvd )
: StateLoadError_Recoverable()
: StateLoadError()
, Crc_Savestate( crc_save )
, Crc_Cdvd( crc_cdvd )
{}

View File

@ -18,13 +18,9 @@
#include "PrecompiledHeader.h"
wxLocale* g_EnglishLocale = NULL;
//g_EnglishLocale = new wxLocale( wxLANGUAGE_ENGLISH );
wxString GetEnglish( const char* msg )
{
if( g_EnglishLocale == NULL ) return wxString::FromAscii(msg);
return g_EnglishLocale->GetString( wxString::FromAscii(msg).c_str() );
return wxString::FromAscii(msg);
}
wxString GetTranslation( const char* msg )

View File

@ -45,8 +45,8 @@ namespace Threading
void Thread::Close()
{
if( m_terminated ) return;
pthread_cancel( m_thread );
if( !m_terminated )
pthread_cancel( m_thread );
pthread_join( m_thread, NULL );
}

View File

@ -80,7 +80,7 @@ FILE *_cdvdOpenMechaVer() {
// use the bios filename to get the name of the mecha ver file
// [TODO] : Upgrade this to use std::string!
strcpy(file, g_Conf.Files.Bios().ToAscii().data() );
strcpy(file, g_Conf.FullpathToBios().ToAscii().data() );
ptr = file;
i = (int)strlen(file);
@ -131,7 +131,7 @@ FILE *_cdvdOpenNVM() {
// use the bios filename to get the name of the nvm file
// [TODO] : Upgrade this to use std::string!
strcpy( file, g_Conf.Files.Bios().ToAscii().data() );
strcpy( file, g_Conf.FullpathToBios().ToAscii().data() );
ptr = file;
i = (int)strlen(file);

View File

@ -22,15 +22,14 @@ class IniInterface;
enum PluginsEnum_t
{
Plugin_CDVD = 0,
Plugin_GS,
Plugin_PAD1,
Plugin_PAD2,
Plugin_SPU2,
Plugin_USB,
Plugin_FW,
Plugin_DEV9,
Plugin_Count
PluginId_CDVD = 0,
PluginId_GS,
PluginId_PAD,
PluginId_SPU2,
PluginId_USB,
PluginId_FW,
PluginId_DEV9,
PluginId_Count
};
@ -74,7 +73,7 @@ public:
struct FilenameOptions
{
wxFileName Bios;
wxFileName Plugins[Plugin_Count];
wxFileName Plugins[PluginId_Count];
void LoadSave( IniInterface& conf );
@ -166,29 +165,18 @@ public:
void LoadSave( IniInterface& conf );
};
// ------------------------------------------------------------------------
// Helper functions for returning full pathnames of various Folders and files
//
struct FullpathHelpers
{
FullpathHelpers( const AppConfig& conf ) : m_conf( conf ) {}
const AppConfig& m_conf;
wxString operator[]( PluginsEnum_t pluginidx ) const;
wxString Bios() const;
wxString Mcd( uint mcdidx ) const;
};
public:
AppConfig() : Files( *this )
, Listbook_ImageSize( 32 )
, Toolbar_ImageSize( 32 )
AppConfig() :
Listbook_ImageSize( 32 )
, Toolbar_ImageSize( 24 )
{
}
FullpathHelpers Files;
wxString FullpathToBios() const;
wxString FullpathToMcd( uint mcdidx ) const;
wxString FullpathTo( PluginsEnum_t pluginId ) const;
bool UseAdminMode; // dictates if the program uses /home/user or /cwd for the program data
wxPoint MainGuiPosition;
@ -197,12 +185,14 @@ public:
// Current language in use (correlates to a wxWidgets wxLANGUAGE specifier)
int LanguageId;
int RecentFileCount; // number of files displayed in the Recent Isos list.
// String value describing the desktop theme to use for pcsk2 (icons and background images)
// The theme name is used to look up files in the themes folder (relative to the executable).
wxString DeskTheme;
// Specifies the size of icons used in Listbooks; specifically the PCSX2 Properties dialog box.
// Realisic values range from 96x96 to 24x24.
// Realistic values range from 96x96 to 24x24.
int Listbook_ImageSize;
// Specifies the size of each toolbar icon, in pixels (any value >= 2 is valid, but realistically

114
pcsx2/Linux/HostGui.cpp Normal file
View File

@ -0,0 +1,114 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2009 Pcsx2 Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "PrecompiledHeader.h"
#include <sys/mman.h>
#include <signal.h>
#include "Common.h"
extern void SysPageFaultExceptionFilter( int signal, siginfo_t *info, void * );
extern void __fastcall InstallLinuxExceptionHandler();
extern void __fastcall ReleaseLinuxExceptionHandler();
#define PCSX2_MEM_PROTECT_BEGIN() InstallLinuxExceptionHandler()
#define PCSX2_MEM_PROTECT_END() ReleaseLinuxExceptionHandler()
extern void SignalExit(int sig);
static const uptr m_pagemask = getpagesize()-1;
namespace HostSys
{
void *Mmap(uptr base, u32 size)
{
u8 *Mem;
Mem = (u8*)mmap((uptr*)base, size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
if (Mem == MAP_FAILED) Console::Notice("Mmap Failed!");
return Mem;
}
void Munmap(uptr base, u32 size)
{
munmap((uptr*)base, size);
}
void MemProtect( void* baseaddr, size_t size, PageProtectionMode mode, bool allowExecution )
{
// Breakpoint this to trap potentially inappropriate use of page protection, which would
// be caused by failed aligned directives on global vars.
if( ((uptr)baseaddr & m_pagemask) != 0 )
{
Console::Error(
"*PCSX2/Linux Warning* Inappropriate use of page protection detected.\n"
"\tbaseaddr not page aligned: 0x%08X", params (uptr)baseaddr
);
}
int lnxmode = 0;
// make sure base and size are aligned to the system page size:
size = (size + m_pagemask) & ~m_pagemask;
baseaddr = (void*)( ((uptr)baseaddr) & ~m_pagemask );
switch( mode )
{
case Protect_NoAccess: break;
case Protect_ReadOnly: lnxmode = PROT_READ; break;
case Protect_ReadWrite: lnxmode = PROT_READ | PROT_WRITE; break;
}
if( allowExecution ) lnxmode |= PROT_EXEC;
mprotect( baseaddr, size, lnxmode );
}
}
void InstallLinuxExceptionHandler()
{
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = &SysPageFaultExceptionFilter;
sigaction(SIGSEGV, &sa, NULL);
}
void ReleaseLinuxExceptionHandler()
{
// Code this later.
}
// Linux implementation of SIGSEGV handler. Bind it using sigaction().
void SysPageFaultExceptionFilter( int signal, siginfo_t *info, void * )
{
// get bad virtual address
uptr offset = (u8*)info->si_addr - psM;
DevCon::Status( "Protected memory cleanup. Offset 0x%x", params offset );
if (offset>=Ps2MemSize::Base)
{
// Bad mojo! Completely invalid address.
// Instigate a crash or abort emulation or something.
assert( false );
}
mmap_ClearCpuBlock( offset & ~m_pagemask );
}

View File

@ -92,7 +92,7 @@ void loadBiosRom( const wxChar *ext, u8 *dest, long maxSize )
long filesize;
// Try first a basic extension concatenation (normally results in something like name.bin.rom1)
const wxString Bios( g_Conf.Files.Bios() );
const wxString Bios( g_Conf.FullpathToBios() );
Bios1.Printf( L"%s.%s", Bios.c_str(), ext);
if( (filesize=Path::GetFileSize( Bios1 ) ) <= 0 )
@ -801,7 +801,7 @@ void memReset()
vtlb_VMap(0x00000000,0x00000000,0x20000000);
vtlb_VMapUnmap(0x20000000,0x60000000);
wxString Bios( g_Conf.Files.Bios() );
wxString Bios( g_Conf.FullpathToBios() );
long filesize = Path::GetFileSize( Bios );
if( filesize <= 0 )

View File

@ -61,7 +61,7 @@ bool MemoryCard::IsPresent( uint mcd )
void MemoryCard::Load( uint mcd )
{
jASSUME( mcd < 2 );
wxFileName fname( g_Conf.Files.Mcd( mcd ) );
wxFileName fname( g_Conf.FullpathToMcd( mcd ) );
wxString str( fname.GetFullPath() );
if( !fname.FileExists() )

View File

@ -498,7 +498,7 @@ void ProcessFKeys(int fkey, struct KeyModifiers *keymod)
SysClearExecutionCache();
joe.FreezeAll();
}
catch( Exception::StateLoadError_Recoverable& )
catch( Exception::StateLoadError& )
{
// At this point the cpu hasn't been reset, so we can return
// control to the user safely... (and silently)

View File

@ -147,7 +147,7 @@ namespace Path
extern wxString ReplaceFilename( const wxString& src, const wxString& newfilename );
extern wxString GetFilename( const wxString& src );
extern wxString GetDirectory( const wxString& src );
extern wxString GetFilenameWithoutExt( const string& src );
extern wxString GetFilenameWithoutExt( const wxString& src );
extern wxString GetRootDirectory( const wxString& src );
extern void CreateDirectory( const wxString& src );

View File

@ -218,6 +218,33 @@ DEV9handler dev9Handler;
USBhandler usbHandler;
uptr pDsp;
void PopulateListCtrls( const wxString& plugpath )
{
//if( CheckVersion( "GS", PS2E_LT_GS, PS2E_GS_VERSION ) )
// AddPlugin(hWC_GS, winConfig.GS);
}
// ------------------------------------------------------------------------
int OpenPlugins(const char* pTitleFilename)
{
return 0;
}
void ClosePlugins( bool closegs )
{
}
void ShutdownPlugins()
{
}
void CloseGS()
{
}
#ifdef _not_wxWidgets_Land_
enum PluginTypes
@ -989,22 +1016,4 @@ void PluginsResetGS()
#else
int OpenPlugins(const char* pTitleFilename)
{
return 0;
}
void ClosePlugins( bool closegs )
{
}
void ShutdownPlugins()
{
}
void CloseGS()
{
}
#endif

View File

@ -63,7 +63,9 @@ typedef int BOOL;
#define TRUE 1
#define FALSE 0
#define wxASSERT_MSG_A( cond, msg ) wxASSERT_MSG( cond, wxString::FromAscii(msg).c_str() );
#ifndef wxASSERT_MSG_A
# define wxASSERT_MSG_A( cond, msg ) wxASSERT_MSG( cond, wxString::FromAscii(msg).c_str() );
#endif
//////////////////////////////////////////////////////////////////////////////////////////
// Begin Pcsx2 Includes: Add items here that are local to Pcsx2 but stay relatively
@ -81,7 +83,7 @@ typedef int BOOL;
#include "Utilities/General.h"
#include "x86emitter/tools.h"
////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Compiler/OS specific macros and defines -- Begin Section
#if defined(_MSC_VER)

View File

@ -109,7 +109,7 @@ void SaveState::FreezeAll()
char descin[128];
wxString descout;
IsBIOS( g_Conf.Files.Bios(), descout );
IsBIOS( g_Conf.FullpathToBios(), descout );
memcpy_fast( descin, descout.ToAscii().data(), 128 );
Freeze( descin );

View File

@ -44,7 +44,7 @@ bool States_isSlotUsed(int num)
// The calling function should trap and handle exceptions as needed.
static void _loadStateOrExcept( const wxString& file )
{
gzLoadingState joe( file ); // this'll throw an StateLoadError_Recoverable.
gzLoadingState joe( file ); // this'll throw an StateLoadError.
// Make sure the cpu and plugins are ready to be state-ified!
cpuReset();
@ -64,7 +64,7 @@ void States_Load( const wxString& file )
_loadStateOrExcept( file );
HostGui::Notice( wxsFormat( _("Loaded State %s"), file.c_str() ) );
}
catch( Exception::StateLoadError_Recoverable& ex)
catch( Exception::StateLoadError& ex)
{
Console::Notice( ex.LogMessage() );
@ -103,7 +103,7 @@ void States_Load(int num)
_loadStateOrExcept( file );
HostGui::Notice( wxsFormat( _("Loaded State %d"), num ) );
}
catch( Exception::StateLoadError_Recoverable& ex)
catch( Exception::StateLoadError& ex)
{
Console::Notice( wxsFormat( L"Could not load savestate slot %d.\n\n%s", num, ex.LogMessage().c_str() ) );

View File

@ -21,11 +21,15 @@
#include <wx/wx.h>
#include <wx/fileconf.h>
#include <wx/imaglist.h>
#include <wx/docview.h>
#include "System.h"
class MainEmuFrame;
class IniInterface;
extern wxFileHistory* g_RecentIsoList;
//////////////////////////////////////////////////////////////////////////////////////////
//
class ConsoleLogFrame : public wxFrame, public NoncopyableObject
@ -45,7 +49,6 @@ public:
virtual void OnCloseWindow(wxCloseEvent& event);
virtual void Write( const wxChar* text );
virtual void Write( const char* text );

View File

@ -183,13 +183,13 @@ bool wxDirName::Mkdir()
}
// ------------------------------------------------------------------------
wxString AppConfig::FullpathHelpers::operator[]( PluginsEnum_t pluginidx ) const
wxString AppConfig::FullpathTo( PluginsEnum_t pluginidx ) const
{
return Path::Combine( m_conf.Folders.Plugins, m_conf.BaseFilenames[pluginidx] );
return Path::Combine( Folders.Plugins, BaseFilenames[pluginidx] );
}
wxString AppConfig::FullpathHelpers::Bios() const { return Path::Combine( m_conf.Folders.Bios, m_conf.BaseFilenames.Bios ); }
wxString AppConfig::FullpathHelpers::Mcd( uint mcdidx ) const { return Path::Combine( m_conf.Folders.MemoryCards, m_conf.MemoryCards.Mcd[mcdidx].Filename ); }
wxString AppConfig::FullpathToBios() const { return Path::Combine( Folders.Bios, BaseFilenames.Bios ); }
wxString AppConfig::FullpathToMcd( uint mcdidx ) const { return Path::Combine( Folders.MemoryCards, MemoryCards.Mcd[mcdidx].Filename ); }
// ------------------------------------------------------------------------
// GCC Note: wxT() macro is required when using string token pasting. For some reason L generates
@ -206,62 +206,17 @@ void AppConfig::LoadSaveUserMode( IniInterface& ini )
ini.Flush();
}
// ------------------------------------------------------------------------
//
void i18n_DoPackageCheck( int wxLangId, wxArrayString& destEng, wxArrayString& destTrans )
{
// Note: wx auto-preserves the current locale for us
if( !wxLocale::IsAvailable( wxLangId ) ) return;
wxLocale* locale = new wxLocale( wxLangId, wxLOCALE_CONV_ENCODING );
if( locale->IsOk() && locale->AddCatalog( L"pcsx2ident" ) )
{
// Should be a valid language, so add it to the list.
destEng.Add( wxLocale::GetLanguageName( wxLangId ) );
destTrans.Add( wxGetTranslation( L"NativeName" ) );
}
delete locale;
}
// ------------------------------------------------------------------------
// Finds all valid PCSX2 language packs, and enumerates them for configuration selection.
// Note: On linux there's no easy way to reliably enumerate language packs, since every distro
// could use its own location for installing pcsx2.mo files (wtcrap?). Furthermore wxWidgets
// doesn't give us a public API for checking what the language search paths are. So the only
// safe way to enumerate the languages is by forcibly loading every possible locale in the wx
// database. Anything which hasn't been installed will fail to load.
//
// Because loading and hashing the entire pcsx2 translation for every possible language would
// assinine and slow, I've decided to use a two-file translation system. One file is very
// small and simply contains the name of the language in the language native. The second file
// is loaded only if the user picks it (or if it's the default language of the OS).
//
void i18n_EnumeratePackages( wxArrayString& englishNames, wxArrayString& xlatedNames)
{
for( int li=wxLANGUAGE_UNKNOWN+1; li<wxLANGUAGE_USER_DEFINED; ++li )
{
i18n_DoPackageCheck( li, englishNames, xlatedNames );
}
// Brilliant. Because someone in the wx world didn't think to move wxLANGUAGE_USER_DEFINED
// to a place where it wasn't butt right up against the main languages (like, say, start user
// defined values at 4000 or something?), they had to add new languages in at some arbitrary
// value instead. Let's handle them here:
// fixme: these won't show up in alphabetical order if they're actually present (however
// horribly unlikely that is)... do we care? Probably not.
// Note: These aren't even available in some packaged Linux distros anyway. >_<
//i18n_DoPackageCheck( wxLANGUAGE_VALENCIAN, englishNames, xlatedNames );
//i18n_DoPackageCheck( wxLANGUAGE_SAMI, englishNames, xlatedNames );
}
// ------------------------------------------------------------------------
void AppConfig::LoadSave( IniInterface& ini )
{
IniEntry( MainGuiPosition, wxDefaultPosition );
IniEntry( LanguageId, wxLANGUAGE_DEFAULT );
IniEntry( RecentFileCount, 6 );
IniEntry( DeskTheme, L"default" );
IniEntry( Listbook_ImageSize, 32 );
IniEntry( Toolbar_ImageSize, 24 );
IniEntry( Toolbar_ShowLabels, true );
IniEntry( CdvdVerboseReads, false );
// Process various sub-components:
@ -270,27 +225,40 @@ void AppConfig::LoadSave( IniInterface& ini )
Folders.LoadSave( ini );
BaseFilenames.LoadSave( ini );
if( ini.IsSaving() && (g_RecentIsoList != NULL) )
g_RecentIsoList->Save( ini.GetConfig() );
ini.Flush();
}
// ------------------------------------------------------------------------
// Performs necessary operations to ensure that the current g_Conf settings (and other config-stored
// globals) are applied to the pcsx2 main window and primary emulation subsystems (if active).
//
void AppConfig::Apply()
{
// Language Application:
// Three stages. First we try and configure the requested language. If that fails,
// we fall back on the default language for the user's operating system. If that
// fails we fall back on good old english.
//wxLocale* locale;
if( !i18n_SetLanguage( LanguageId ) )
{
if( !i18n_SetLanguage( wxLANGUAGE_DEFAULT ) )
{
//wxGetTranslation();
i18n_SetLanguage( wxLANGUAGE_ENGLISH );
}
}
// Always perform delete and reload of the Recent Iso List. This handles cases where
// 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 );
wxASSERT( cfg != NULL );
if( g_RecentIsoList != NULL )
g_RecentIsoList->Save( *cfg );
safe_delete( g_RecentIsoList );
g_RecentIsoList = new wxFileHistory( RecentFileCount );
g_RecentIsoList->Load( *cfg );
cfg->Flush();
}
// ------------------------------------------------------------------------
@ -361,8 +329,8 @@ const wxString g_PluginNames[] =
// ------------------------------------------------------------------------
const wxFileName& AppConfig::FilenameOptions::operator[]( PluginsEnum_t pluginidx ) const
{
if( (uint)pluginidx >= Plugin_Count )
throw Exception::IndexBoundsFault( L"Filename[Plugin]", pluginidx, Plugin_Count );
if( (uint)pluginidx >= PluginId_Count )
throw Exception::IndexBoundsFault( L"Filename[Plugin]", pluginidx, PluginId_Count );
return Plugins[pluginidx];
}
@ -373,7 +341,7 @@ void AppConfig::FilenameOptions::LoadSave( IniInterface& ini )
const wxFileName pc( L"Please Configure" );
for( int i=0; i<Plugin_Count; ++i )
for( int i=0; i<PluginId_Count; ++i )
{
ini.Entry( g_PluginNames[i], Plugins[i], pc );
}

View File

@ -26,37 +26,74 @@
#include <wx/bookctrl.h>
#include <wx/artprov.h>
#include <wx/listbook.h>
using namespace wxHelpers;
using namespace Panels;
Dialogs::ConfigurationDialog::ConfigurationDialog( wxWindow* parent, int id ) :
wxDialogWithHelpers( parent, id, _T("PCSX2 Configuration"), true )
{
// configure the orientation of the listbox based on the platform
#if defined(__WXMAC__) || defined(__WXMSW__)
int orient = wxBK_TOP;
static const int s_orient = wxBK_TOP;
#else
int orient = wxBK_LEFT;
static const int s_orient = wxBK_LEFT;
#endif
Dialogs::ConfigurationDialog::ConfigurationDialog( wxWindow* parent, int id ) :
wxDialogWithHelpers( parent, id, _T("PCSX2 Configuration"), true )
, m_listbook( *new wxListbook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, s_orient ) )
{
wxBoxSizer& mainSizer = *new wxBoxSizer( wxVERTICAL );
wxListbook& listbook = *new wxListbook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, orient );
listbook.SetImageList( &wxGetApp().GetImgList_Config() );
m_listbook.SetImageList( &wxGetApp().GetImgList_Config() );
const AppImageIds::ConfigIds& cfgid( wxGetApp().GetImgId().Config );
listbook.AddPage( new PathsPanel( listbook ), L"Paths", false, cfgid.Paths );
listbook.AddPage( new PluginSelectorPanel( listbook ), L"Plugins", false, cfgid.Plugins );
listbook.AddPage( new SpeedHacksPanel( listbook ), L"Speedhacks", true, cfgid.Speedhacks );
listbook.AddPage( new GameFixesPanel( listbook ), L"Game Fixes", false, cfgid.Gamefixes );
m_listbook.AddPage( new PathsPanel( m_listbook ), _("Folders"), false, cfgid.Paths );
m_listbook.AddPage( new PluginSelectorPanel( m_listbook ), _("Plugins"), false, cfgid.Plugins );
m_listbook.AddPage( new SpeedHacksPanel( m_listbook ), _("Speedhacks"), false, cfgid.Speedhacks );
m_listbook.AddPage( new GameFixesPanel( m_listbook ), _("Game Fixes"), false, cfgid.Gamefixes );
mainSizer.Add( &listbook );
mainSizer.Add( &m_listbook );
AddOkCancel( mainSizer, true );
SetSizerAndFit( &mainSizer );
Center( wxCENTER_ON_SCREEN | wxBOTH );
Connect( wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ConfigurationDialog::OnOk_Click ) );
Connect( wxID_APPLY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ConfigurationDialog::OnApply_Click ) );
}
Dialogs::ConfigurationDialog::~ConfigurationDialog()
{
}
bool Dialogs::ConfigurationDialog::ApplySettings()
{
AppConfig confcopy( g_Conf );
int pagecount = m_listbook.GetPageCount();
for( int i=0; i<pagecount; ++i )
{
BaseApplicableConfigPanel* panel = (BaseApplicableConfigPanel*)m_listbook.GetPage(i);
if( !panel->Apply( confcopy ) ) return false;
}
g_Conf = confcopy;
g_Conf.Apply();
g_Conf.Save();
return true;
}
void Dialogs::ConfigurationDialog::OnOk_Click( wxCommandEvent& evt )
{
evt.Skip();
if( ApplySettings() ) Close();
}
void Dialogs::ConfigurationDialog::OnApply_Click( wxCommandEvent& evt )
{
evt.Skip();
ApplySettings();
}

View File

@ -21,6 +21,7 @@
#include <wx/wx.h>
#include <wx/image.h>
#include <wx/propdlg.h>
#include <wx/listbook.h>
#include "wxHelpers.h"
@ -28,12 +29,16 @@ namespace Dialogs
{
class ConfigurationDialog : public wxDialogWithHelpers
{
protected:
wxListbook& m_listbook;
public:
virtual ~ConfigurationDialog();
ConfigurationDialog(wxWindow* parent, int id=wxID_ANY);
protected:
wxImageList* m_ImageList;
public:
bool ApplySettings();
void OnOk_Click( wxCommandEvent& evt );
void OnApply_Click( wxCommandEvent& evt );
};
}

View File

@ -42,6 +42,8 @@ public:
void SetPath( const wxString& path );
void Flush();
wxConfigBase& GetConfig() { return m_Config; }
virtual bool IsLoading() const=0;
bool IsSaving() const { return !IsLoading(); }

View File

@ -28,8 +28,7 @@
using namespace Dialogs;
//////////////////////////////////////////////////////////////////////////////////////////
//
// ------------------------------------------------------------------------
wxMenu* MainEmuFrame::MakeLanguagesMenu() const
{
wxMenu* menuLangs = new wxMenu();
@ -41,6 +40,7 @@ wxMenu* MainEmuFrame::MakeLanguagesMenu() const
return menuLangs;
}
// ------------------------------------------------------------------------
wxMenu* MainEmuFrame::MakeStatesMenu()
{
wxMenu* mnuStates = new wxMenu();
@ -48,24 +48,88 @@ wxMenu* MainEmuFrame::MakeStatesMenu()
m_LoadStatesSubmenu.Append( Menu_State_LoadOther, _T("Other..."), wxEmptyString, wxITEM_NORMAL );
m_SaveStatesSubmenu.Append( Menu_State_SaveOther, _T("Other..."), wxEmptyString, wxITEM_NORMAL );
mnuStates->Append( Menu_State_Load, _T("Load"), &m_LoadStatesSubmenu, wxEmptyString );
mnuStates->Append( Menu_State_Save, _T("Save"), &m_SaveStatesSubmenu, wxEmptyString );
mnuStates->Append( Menu_State_Load, _("Load"), &m_LoadStatesSubmenu, wxEmptyString );
mnuStates->Append( Menu_State_Save, _("Save"), &m_SaveStatesSubmenu, wxEmptyString );
return mnuStates;
}
// ------------------------------------------------------------------------
wxMenu* MainEmuFrame::MakeStatesSubMenu( int baseid ) const
{
wxMenu* mnuSubstates = new wxMenu();
wxString slot( _T("Slot") );
mnuSubstates->Append( baseid, _T("Slot 0"), wxEmptyString, wxITEM_NORMAL );
mnuSubstates->Append( baseid+1, _T("Slot 1"), wxEmptyString, wxITEM_NORMAL );
mnuSubstates->Append( baseid+2, _T("Slot 2"), wxEmptyString, wxITEM_NORMAL );
mnuSubstates->Append( baseid+3, _T("Slot 3"), wxEmptyString, wxITEM_NORMAL );
mnuSubstates->Append( baseid+4, _T("Slot 4"), wxEmptyString, wxITEM_NORMAL );
mnuSubstates->Append( baseid, _("Slot 0"), wxEmptyString, wxITEM_NORMAL );
mnuSubstates->Append( baseid+1, _("Slot 1"), wxEmptyString, wxITEM_NORMAL );
mnuSubstates->Append( baseid+2, _("Slot 2"), wxEmptyString, wxITEM_NORMAL );
mnuSubstates->Append( baseid+3, _("Slot 3"), wxEmptyString, wxITEM_NORMAL );
mnuSubstates->Append( baseid+4, _("Slot 4"), wxEmptyString, wxITEM_NORMAL );
return mnuSubstates;
}
/*struct StringListNode
{
wxString* item;
StringListNode* next;
};*/
// ------------------------------------------------------------------------
wxMenu* MainEmuFrame::MakeIsoMenu()
{
wxMenu* mnuIso = new wxMenu();
mnuIso->Append( Menu_IsoBrowse, _("Browse..."), _("Select an Iso image from your hard drive.") );
//mnuIso->AppendSeparator();
// Add in the recent files!
/*const StringListNode* cruise = g_Conf.RecentIsos;
int i = 0;
int threshold = 15;
while( cruise != NULL && (--threshold >= 0) )
{
wxString ellipsized;
if( cruise->item->Length() > 64 )
{
// Ellipsize it!
wxFileName src( *cruise->item );
ellipsized = src.GetVolume() + wxFileName::GetVolumeSeparator() + wxFileName::GetPathSeparator() + L"...";
const wxArrayString& dirs( src.GetDirs() );
int totalLen = ellipsized.Length();
int i=dirs.Count()-1;
for( ; i; --i )
{
if( totalLen + dirs[i].Length() < 56 )
totalLen += dirs[i];
}
for( ; i<dirs.Count(); ++i )
ellipsized += wxFileName::GetPathSeparator() + dirs[i];
ellipsized += wxFileName::GetPathSeparator() + src.GetFullName();
}
else
ellipsized = *cruise->item;
mnuIso->Append( Menu_Iso_Recent+i, Path::GetFilename( ellipsized ), *cruise->item );
}*/
g_RecentIsoList->UseMenu( mnuIso );
g_RecentIsoList->AddFilesToMenu( mnuIso );
return mnuIso;
}
// ------------------------------------------------------------------------
wxMenu* MainEmuFrame::MakeCdvdMenu()
{
wxMenu* mnuCdvd = new wxMenu();
return mnuCdvd;
}
// ------------------------------------------------------------------------
void MainEmuFrame::PopulateVideoMenu()
{
m_menuVideo.Append( Menu_Video_Basics, _T("Basic Settings..."), wxEmptyString, wxITEM_CHECK );
@ -76,6 +140,7 @@ void MainEmuFrame::PopulateVideoMenu()
m_menuVideo.Append( Menu_Video_Advanced, _T("Advanced..."), wxEmptyString, wxITEM_NORMAL );
}
// ------------------------------------------------------------------------
void MainEmuFrame::PopulateAudioMenu()
{
// Populate options from the plugin here.
@ -83,6 +148,7 @@ void MainEmuFrame::PopulateAudioMenu()
m_menuAudio.Append( Menu_Audio_Advanced, _T("Advanced..."), wxEmptyString, wxITEM_NORMAL );
}
// ------------------------------------------------------------------------
void MainEmuFrame::PopulatePadMenu()
{
// Populate options from the plugin here.
@ -93,6 +159,7 @@ void MainEmuFrame::PopulatePadMenu()
#define ConnectMenu( id, handler ) \
Connect( id, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainEmuFrame::handler) )
// ------------------------------------------------------------------------
void MainEmuFrame::OnMoveAround( wxMoveEvent& evt )
{
if( g_Conf.ConLogBox.AutoDock )
@ -101,15 +168,17 @@ void MainEmuFrame::OnMoveAround( wxMoveEvent& evt )
//evt.Skip();
}
// ------------------------------------------------------------------------
void MainEmuFrame::ConnectMenus()
{
Connect( wxEVT_MOVE, wxMoveEventHandler(MainEmuFrame::OnMoveAround) );
// This just seems a bit more flexible & intuitive to me, if overly verbose.
ConnectMenu( Menu_Config_Settings, Menu_ConfigSettings_Click );
ConnectMenu( Menu_RunWithoutDisc, Menu_RunWithoutDisc_Click );
ConnectMenu( Menu_QuickBootCD, Menu_QuickBootCD_Click );
ConnectMenu( Menu_FullBootCD, Menu_BootCD_Click );
ConnectMenu( Menu_BootNoCD, Menu_BootNoCD_Click );
ConnectMenu( Menu_IsoBrowse, Menu_IsoBrowse_Click );
Connect( wxID_FILE1, wxID_FILE1+20, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainEmuFrame::Menu_IsoRecent_Click) );
ConnectMenu( Menu_RunELF, Menu_OpenELF_Click );
ConnectMenu( Menu_Run_Exit, Menu_Exit_Click );
@ -134,16 +203,18 @@ void MainEmuFrame::ConnectMenus()
ConnectMenu( Menu_About, Menu_ShowAboutBox );
}
// ------------------------------------------------------------------------
void MainEmuFrame::OnLogBoxHidden()
{
g_Conf.ConLogBox.Visible = false;
m_MenuItem_Console.Check( false );
}
// ------------------------------------------------------------------------
MainEmuFrame::MainEmuFrame(wxWindow* parent, int id, const wxString& title, const wxPoint& pos, const wxSize& size, long style):
wxFrame(parent, id, title, pos, size, wxDEFAULT_FRAME_STYLE & ~(wxMAXIMIZE_BOX | wxRESIZE_BORDER) ),
m_logbox( this, L"Pcsx2 Log" ),
m_logbox( this, L"PCSX2 Log" ),
m_statusbar( *CreateStatusBar(2, 0) ),
m_background( this, wxID_ANY, wxGetApp().GetLogoBitmap() ),
@ -173,13 +244,13 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, int id, const wxString& title, cons
// Initial menubar setup. This needs to be done first so that the menu bar's visible size
// can be factored into the window size (which ends up being background+status+menus)
m_menubar.Append( &m_menuRun, L"Run" );
m_menubar.Append( &m_menuConfig, L"Config" );
m_menubar.Append( &m_menuVideo, L"Video" );
m_menubar.Append( &m_menuAudio, L"Audio" );
m_menubar.Append( &m_menuPad, L"Pad" );
m_menubar.Append( &m_menuMisc, L"Misc" );
m_menubar.Append( &m_menuDebug, L"Debug" );
m_menubar.Append( &m_menuRun, _("Run") );
m_menubar.Append( &m_menuConfig, _("Config") );
m_menubar.Append( &m_menuVideo, _("Video") );
m_menubar.Append( &m_menuAudio, _("Audio") );
m_menubar.Append( &m_menuPad, _("Pad") );
m_menubar.Append( &m_menuMisc, _("Misc") );
m_menubar.Append( &m_menuDebug, _("Debug") );
SetMenuBar( &m_menubar );
// ------------------------------------------------------------------------
@ -237,41 +308,49 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, int id, const wxString& title, cons
// ------------------------------------------------------------------------
m_menuRun.Append(Menu_QuickBootCD, _T("Boot CDVD (Quick)"), wxEmptyString, wxITEM_NORMAL);
m_menuRun.Append(Menu_FullBootCD, _T("Boot CDVD (Full)"), wxEmptyString, wxITEM_NORMAL);
m_menuRun.Append(Menu_BootNoCD, _T("Boot without CDVD"), wxEmptyString, wxITEM_NORMAL);
m_menuRun.Append(Menu_RunELF, _T("Run ELF File..."), wxEmptyString, wxITEM_NORMAL);
m_menuRun.Append(Menu_BootIso, _("Run ISO"), MakeIsoMenu(), _("Performs a complete bootup sequence (recommended for best compat)"));
m_menuRun.Append(Menu_BootIsoFast, _("Run ISO (skip Bios)"), MakeIsoMenu(), _("Skips PS2 startup screens when booting; may cause compat issues"));
m_menuRun.Append(Menu_BootQuickCDVD,_("Run CDVD"), MakeCdvdMenu(), _("Skips PS2 init screens when running cdvd images"));
m_menuRun.Append(Menu_BootFullCDVD, _("Run CDVD (skip Bios)"), MakeCdvdMenu(), _("Skips PS2 startup screens when booting; may cause compat issues"));
m_menuRun.Append(Menu_RunWithoutDisc,_("Run without Disc"), _("Use this to access the PS2 system configuration menu"));
m_menuRun.Append(Menu_RunELF, _("Run ELF File..."), wxEmptyString);
m_menuRun.AppendSeparator();
m_menuRun.Append(Menu_SuspendExec, _T("Suspend"), _T("Suspends emulation progress."), wxITEM_NORMAL);
m_menuRun.Append(Menu_ResumeExec, _T("Resume"), _T("Resumes emulation progress."), wxITEM_NORMAL);
m_menuRun.Append(Menu_States, _T("States"), MakeStatesMenu(), wxEmptyString);
m_menuRun.Append(Menu_Reset, _T("Reset"), _T("Resets emulation state and reloads plugins."), wxITEM_NORMAL);
m_menuRun.Append(Menu_SuspendExec, _("Suspend"), _T("Stops emulation dead in its tracks"));
m_menuRun.Append(Menu_ResumeExec, _("Resume"), _T("Resumes suspended emulation"));
m_menuRun.Append(Menu_States, _("States"), MakeStatesMenu(), wxEmptyString);
m_menuRun.Append(Menu_Reset, _("Reset"), _T("Resets emulation state and reloads plugins"));
m_menuRun.AppendSeparator();
m_menuRun.Append(Menu_Run_Exit, _T("Exit"), _T("Closing Pcsx2 may be hazardous to your health"), wxITEM_NORMAL);
m_menuRun.Append(Menu_Run_Exit, _("Exit"), _T("Closing PCSX2 may be hazardous to your health"));
// ------------------------------------------------------------------------
m_menuConfig.Append(Menu_Config_CDVD, _T("Cdvdrom"), wxEmptyString, wxITEM_NORMAL);
m_menuConfig.Append(Menu_Config_DEV9, _T("Dev9"), wxEmptyString, wxITEM_NORMAL);
m_menuConfig.Append(Menu_Config_USB, _T("USB"), wxEmptyString, wxITEM_NORMAL);
m_menuConfig.Append(Menu_Config_FireWire, _T("Firewire"), wxEmptyString, wxITEM_NORMAL);
m_menuConfig.Append(Menu_Config_Settings, _("Settings..."), wxEmptyString);
m_menuConfig.AppendSeparator();
// Query installed "tertiary" plugins for name and menu options.
m_menuConfig.Append(Menu_Config_CDVD, _("CDVD"), wxEmptyString);
m_menuConfig.Append(Menu_Config_DEV9, _("Dev9"), wxEmptyString);
m_menuConfig.Append(Menu_Config_USB, _("USB"), wxEmptyString);
m_menuConfig.Append(Menu_Config_FireWire, _("Firewire"), wxEmptyString);
m_menuConfig.AppendSeparator();
m_menuConfig.Append(Menu_SelectPlugins, _("Plugin Selector..."), wxEmptyString);
m_menuConfig.AppendSeparator();
m_menuConfig.Append(Menu_Config_Memcards, _("Memcards"), _T("Memory card file locations and options"));
m_menuConfig.Append(Menu_Config_Gamefixes, _("Gamefixes"), _T("God of War and TriAce fixes are found here"));
m_menuConfig.Append(Menu_Config_SpeedHacks, _("Speed Hacks"), _T("Options to make Pcsx2 emulate faster, but less accurately"));
m_menuConfig.Append(Menu_Config_Patches, _("Patches"), wxEmptyString);
//m_menuConfig.Append(Menu_Config_Advanced, _("Advanced"), _T("Cpu, Fpu, and Recompiler options."), wxITEM_NORMAL);
// ------------------------------------------------------------------------
PopulateVideoMenu();
PopulateAudioMenu();
PopulatePadMenu();
m_menuConfig.AppendSeparator();
m_menuConfig.Append(Menu_SelectPlugins, _T("Plugin Selector..."), wxEmptyString, wxITEM_NORMAL);
m_menuConfig.AppendSeparator();
m_menuConfig.Append(Menu_Config_Memcards, _T("Memcards"), _T("Memory card file locations and options."), wxITEM_NORMAL);
m_menuConfig.Append(Menu_Config_Gamefixes, _T("Gamefixes"), _T("God of War and TriAce fixes are found here."), wxITEM_NORMAL);
m_menuConfig.Append(Menu_Config_SpeedHacks, _T("Speed Hacks"), _T("Options to make Pcsx2 emulate faster, but less accurately."), wxITEM_NORMAL);
m_menuConfig.Append(Menu_Config_Patches, _T("Patches"), wxEmptyString, wxITEM_NORMAL);
m_menuConfig.Append(Menu_Config_Advanced, _T("Advanced"), _T("Cpu, Fpu, and Recompiler options."), wxITEM_NORMAL);
// ------------------------------------------------------------------------
m_menuMisc.Append( &m_MenuItem_Console );
@ -300,21 +379,28 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, int id, const wxString& title, cons
ConnectMenus();
m_MenuItem_Console.Check( g_Conf.ConLogBox.Visible );
//g_RecentIsoList->AddFileToHistory( L"fail.iso" );
}
void MainEmuFrame::Menu_QuickBootCD_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_ConfigSettings_Click(wxCommandEvent &event)
{
Dialogs::ConfigurationDialog( this ).ShowModal();
}
void MainEmuFrame::Menu_BootCD_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_RunWithoutDisc_Click(wxCommandEvent &event)
{
}
void MainEmuFrame::Menu_BootNoCD_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_IsoBrowse_Click(wxCommandEvent &event)
{
}
void MainEmuFrame::Menu_IsoRecent_Click(wxCommandEvent &event)
{
Console::Status( "%d", params event.GetId() - g_RecentIsoList->GetBaseId() );
Console::WriteLn( Color_Magenta, g_RecentIsoList->GetHistoryFile( event.GetId() - g_RecentIsoList->GetBaseId() ) );
}
void MainEmuFrame::Menu_OpenELF_Click(wxCommandEvent &event)
{

View File

@ -20,6 +20,7 @@
#include <wx/wx.h>
#include <wx/image.h>
#include <wx/docview.h>
#include "App.h"
@ -44,11 +45,14 @@ protected:
Menu_Misc, // Misc options and help!
// Run SubSection
Menu_QuickBootCD = 60, // boots games using the bios stub method (skips power-on checks)
Menu_FullBootCD, // boots games through the bios.
Menu_BootNoCD, // used to enter the bios (subs in cdvdnull)
Menu_BootIsoFast = 20, // Opens Recent Files sub-menu, and boots selected iso using QuickBoot
Menu_BootIso, // Opens Recent Files sub-menu, and boots selected iso using FullBoot
Menu_IsoBrowse, // sub-menu opened up by BootIso
Menu_BootQuickCDVD, // opens a submenu filled by CDVD plugin (usually list of drives)
Menu_BootFullCDVD, // opens a submenu filled by CDVD plugin (usually list of drives)
Menu_RunWithoutDisc, // used to enter the bios (subs in cdvdnull)
Menu_RunELF,
Menu_SuspendExec, // suspends active emulation
Menu_SuspendExec, // suspends active emulation
Menu_ResumeExec, // restores active emulation
Menu_Reset, // Issues a complete reset.
Menu_States, // Opens states submenu
@ -68,11 +72,11 @@ protected:
Menu_Config_USB,
Menu_Config_FireWire,
Menu_Config_Settings,
Menu_Config_Memcards,
Menu_Config_SpeedHacks,
Menu_Config_Gamefixes,
Menu_Config_Patches,
Menu_Config_Advanced,
// Video Subsection
// Top items are Pcsx2-controlled. GS plugin items are inserted beneath.
@ -117,6 +121,9 @@ protected:
wxMenu* MakeStatesMenu();
wxMenu* MakeLanguagesMenu() const;
wxMenu* MakeIsoMenu();
wxMenu* MakeCdvdMenu();
void PopulateVideoMenu();
void PopulateAudioMenu();
void PopulatePadMenu();
@ -149,9 +156,10 @@ protected:
protected:
void OnMoveAround( wxMoveEvent& evt );
void Menu_QuickBootCD_Click(wxCommandEvent &event);
void Menu_BootCD_Click(wxCommandEvent &event);
void Menu_BootNoCD_Click(wxCommandEvent &event);
void Menu_ConfigSettings_Click(wxCommandEvent &event);
void Menu_RunWithoutDisc_Click(wxCommandEvent &event);
void Menu_IsoBrowse_Click(wxCommandEvent &event);
void Menu_IsoRecent_Click(wxCommandEvent &event);
void Menu_OpenELF_Click(wxCommandEvent &event);
void Menu_LoadStateOther_Click(wxCommandEvent &event);

View File

@ -29,19 +29,36 @@
#include "wxHelpers.h"
#include "Utilities/SafeArray.h"
#include "Utilities/Threading.h"
namespace Panels
{
//////////////////////////////////////////////////////////////////////////////////////////
// Extends the Panel class to add an Apply() method, which is invoked from the parent
// window (usually the ConfigurationDialog) when either Ok or Apply is clicked.
//
class SpeedHacksPanel : public wxPanelWithHelpers
class BaseApplicableConfigPanel : public wxPanelWithHelpers
{
public:
SpeedHacksPanel(wxWindow& parent, int id=wxID_ANY);
virtual ~BaseApplicableConfigPanel() { }
BaseApplicableConfigPanel( wxWindow* parent ) :
wxPanelWithHelpers( parent, wxID_ANY ) { }
// This method attempts to assign the settings for the panel into the given
// configuration structure (which is typically a copy of g_Conf). If validation
// of form contents fails, the function returns false.
virtual bool Apply( AppConfig& conf )=0;
};
//////////////////////////////////////////////////////////////////////////////////////////
//
class SpeedHacksPanel : public BaseApplicableConfigPanel
{
public:
SpeedHacksPanel(wxWindow& parent);
bool Apply( AppConfig& conf );
protected:
public:
void IOPCycleDouble_Click(wxCommandEvent &event);
void WaitCycleExt_Click(wxCommandEvent &event);
void INTCSTATSlow_Click(wxCommandEvent &event);
@ -50,14 +67,12 @@ namespace Panels
//////////////////////////////////////////////////////////////////////////////////////////
//
class GameFixesPanel: public wxPanelWithHelpers
class GameFixesPanel: public BaseApplicableConfigPanel
{
public:
GameFixesPanel(wxWindow& parent, int id=wxID_ANY);
GameFixesPanel(wxWindow& parent);
bool Apply( AppConfig& conf );
protected:
public:
void FPUCompareHack_Click(wxCommandEvent &event);
void FPUMultHack_Click(wxCommandEvent &event);
void TriAce_Click(wxCommandEvent &event);
@ -68,7 +83,7 @@ namespace Panels
//////////////////////////////////////////////////////////////////////////////////////////
//
class PathsPanel: public wxPanelWithHelpers
class PathsPanel : public BaseApplicableConfigPanel
{
protected:
class DirPickerPanel : public wxPanelWithHelpers
@ -102,13 +117,6 @@ namespace Panels
{
public:
StandardPanel(wxWindow& parent, int id=wxID_ANY);
protected:
//DirPickerInfo m_BiosPicker;
//DirPickerInfo m_SavestatesPicker;
//DirPickerInfo m_SnapshotsPicker;
//DirPickerInfo m_MemorycardsPicker;
//DirPickerInfo m_LogsPicker;
};
class AdvancedPanel : public MyBasePanel
@ -118,18 +126,105 @@ namespace Panels
};
public:
PathsPanel(wxWindow& parent, int id=wxID_ANY);
PathsPanel(wxWindow& parent);
bool Apply( AppConfig& conf );
};
//////////////////////////////////////////////////////////////////////////////////////////
//
class PluginSelectorPanel: public wxPanelWithHelpers
class PluginSelectorPanel: public BaseApplicableConfigPanel
{
public:
PluginSelectorPanel(wxWindow& parent, int id=wxID_ANY);
protected:
static const int NumPluginTypes = 7;
// ------------------------------------------------------------------------
// PluginSelectorPanel Subclasses
// ------------------------------------------------------------------------
class EnumeratedPluginInfo
{
public:
uint PassedTest; // msk specifying which plugin types passed the mask test.
uint TypeMask; // indicates which combo boxes it should be listed in
wxString Name; // string to be pasted into the combo box
wxString Version[NumPluginTypes];
EnumeratedPluginInfo() :
PassedTest( 0 )
, TypeMask( 0 )
, Name()
{
}
};
class EnumThread : public Threading::Thread
{
public:
EnumeratedPluginInfo* Results; // array of plugin results.
protected:
PluginSelectorPanel& m_master;
volatile bool m_cancel;
public:
virtual ~EnumThread();
EnumThread( PluginSelectorPanel& master );
void Close();
protected:
int Callback();
};
// This panel contains all of the plugin combo boxes. We stick them
// on a panel together so that we can hide/show the whole mess easily.
class ComboBoxPanel : public wxPanelWithHelpers
{
protected:
wxComboBox* m_combobox[NumPluginTypes];
public:
ComboBoxPanel( PluginSelectorPanel* parent );
wxComboBox& Get( int i ) { return *m_combobox[i]; }
void Reset();
};
class StatusPanel : public wxPanelWithHelpers
{
protected:
wxGauge& m_gauge;
wxStaticText& m_label;
int m_progress;
public:
StatusPanel( wxWindow* parent, int pluginCount );
void AdvanceProgress( const wxString& msg );
void Reset();
};
// ------------------------------------------------------------------------
// PluginSelectorPanel Members
// ------------------------------------------------------------------------
protected:
wxArrayString m_FileList; // list of potential plugin files
StatusPanel& m_StatusPanel;
ComboBoxPanel& m_ComboBoxes;
bool m_Uninitialized;
EnumThread* m_EnumeratorThread;
public:
virtual ~PluginSelectorPanel();
PluginSelectorPanel(wxWindow& parent);
virtual void OnShow( wxShowEvent& evt );
virtual void OnRefresh( wxCommandEvent& evt );
virtual void OnProgress( wxCommandEvent& evt );
virtual void OnEnumComplete( wxCommandEvent& evt );
bool Apply( AppConfig& conf );
protected:
void DoRefresh();
int FileCount() const { return m_FileList.Count(); }
const wxString& GetFilename( int i ) const { return m_FileList[i]; }
friend class EnumThread;
};
}

View File

@ -26,8 +26,8 @@ using namespace wxHelpers;
#define FLAG_FPU_Compare 0x4 // Digimon Rumble Arena - IDC_GAMEFIX3
#define FLAG_FPU_MUL 0x8 //Tales of Destiny - IDC_GAMEFIX5
Panels::GameFixesPanel::GameFixesPanel( wxWindow& parent, int id ) :
wxPanelWithHelpers( &parent, id )
Panels::GameFixesPanel::GameFixesPanel( wxWindow& parent ) :
BaseApplicableConfigPanel( &parent )
{
wxStaticText* label_Title = new wxStaticText(
this, wxID_ANY, _T("Some games need special settings.\nConfigure them here."), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE
@ -52,6 +52,11 @@ Panels::GameFixesPanel::GameFixesPanel( wxWindow& parent, int id ) :
Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( GameFixesPanel::GodWar_Click ) );
}
bool Panels::GameFixesPanel::Apply( AppConfig& conf )
{
return true;
}
void Panels::GameFixesPanel::FPUCompareHack_Click(wxCommandEvent &event)
{
//Config.GameFixes |= is_checked ? FLAG_FPU_Compare : 0;

View File

@ -38,7 +38,6 @@ Panels::PathsPanel::DirPickerPanel::DirPickerPanel( wxWindow* parent, const wxDi
wxPanelWithHelpers( parent, wxID_ANY )
, m_GetDefaultFunc( getDefault )
{
Console::Notice( initPath.ToString() );
wxDirName normalized( initPath );
normalized.Normalize();
@ -137,8 +136,8 @@ Panels::PathsPanel::AdvancedPanel::AdvancedPanel( wxWindow& parent, int id ) :
}
// ------------------------------------------------------------------------
Panels::PathsPanel::PathsPanel( wxWindow& parent, int id ) :
wxPanelWithHelpers( &parent, id )
Panels::PathsPanel::PathsPanel( wxWindow& parent ) :
BaseApplicableConfigPanel( &parent )
{
wxBoxSizer& s_main = *new wxBoxSizer( wxVERTICAL );
wxNotebook& notebook = *new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_BOTTOM | wxNB_FIXEDWIDTH );
@ -151,3 +150,7 @@ Panels::PathsPanel::PathsPanel( wxWindow& parent, int id ) :
SetSizerAndFit( &s_main );
}
bool Panels::PathsPanel::Apply( AppConfig& conf )
{
return true;
}

View File

@ -17,11 +17,416 @@
*/
#include "PrecompiledHeader.h"
#include "Plugins.h"
#include "ConfigurationPanels.h"
Panels::PluginSelectorPanel::PluginSelectorPanel( wxWindow& parent, int id ) :
wxPanelWithHelpers( &parent, id )
#include <wx/dynlib.h>
#include <wx/dir.h>
using namespace wxHelpers;
using namespace Threading;
struct PluginInfo
{
const char* shortname;
PluginsEnum_t id;
int typemask;
int version; // minimum version required / supported
};
// Yay, order of this array shouldn't be important. :)
static const PluginInfo tbl_PluginInfo[] =
{
{ "GS", PluginId_GS, PS2E_LT_GS, PS2E_GS_VERSION },
{ "PAD", PluginId_PAD, PS2E_LT_PAD, PS2E_PAD_VERSION },
{ "SPU2", PluginId_SPU2, PS2E_LT_SPU2, PS2E_SPU2_VERSION },
{ "CDVD", PluginId_CDVD, PS2E_LT_CDVD, PS2E_CDVD_VERSION },
{ "DEV9", PluginId_DEV9, PS2E_LT_DEV9, PS2E_DEV9_VERSION },
{ "USB", PluginId_USB, PS2E_LT_USB, PS2E_USB_VERSION },
{ "FW", PluginId_FW, PS2E_LT_FW, PS2E_FW_VERSION },
// SIO is currently unused (legacy?)
//{ "SIO", PluginId_SIO, PS2E_LT_SIO, PS2E_SIO_VERSION }
};
namespace Exception
{
class NotPcsxPlugin : public Stream
{
public:
virtual ~NotPcsxPlugin() throw() {}
explicit NotPcsxPlugin( const wxString& objname ) :
Stream( objname, wxLt("Dynamic library is not a PCSX2 plugin (or is an unsupported m_version)") ) {}
};
};
DECLARE_EVENT_TYPE(wxEVT_EnumeratedNext, -1)
DECLARE_EVENT_TYPE(wxEVT_EnumerationFinished, -1)
DEFINE_EVENT_TYPE(wxEVT_EnumeratedNext)
DEFINE_EVENT_TYPE(wxEVT_EnumerationFinished)
//////////////////////////////////////////////////////////////////////////////////////////
//
class PluginEnumerator
{
protected:
wxString m_plugpath;
wxDynamicLibrary m_plugin;
_PS2EgetLibType m_GetLibType;
_PS2EgetLibName m_GetLibName;
_PS2EgetLibVersion2 m_GetLibVersion2;
u32 m_type;
public:
// Constructor!
//
// Possible Exceptions:
// BadStream - thrown if the provided file is simply not a loadable DLL.
// NotPcsxPlugin - thrown if the DLL is not a PCSX2 plugin, or if it's of an unsupported version.
//
PluginEnumerator( const wxString& plugpath ) :
m_plugpath( plugpath )
, m_plugin()
{
if( !m_plugin.Load( m_plugpath ) )
throw Exception::BadStream( m_plugpath, "File is not a valid dynamic library" );
m_GetLibType = (_PS2EgetLibType)m_plugin.GetSymbol( L"PS2EgetLibType" );
m_GetLibName = (_PS2EgetLibName)m_plugin.GetSymbol( L"PS2EgetLibName" );
m_GetLibVersion2 = (_PS2EgetLibVersion2)m_plugin.GetSymbol( L"PS2EgetLibVersion2" );
if( m_GetLibType == NULL || m_GetLibName == NULL || m_GetLibVersion2 == NULL )
{
throw Exception::NotPcsxPlugin( m_plugpath );
}
m_type = m_GetLibType();
}
// Parameters:
// pluginTypeIndex - Value from 1 to 8 which represents the plugin's index.
//
bool CheckVersion( int pluginTypeIndex ) const
{
const PluginInfo& info( tbl_PluginInfo[pluginTypeIndex] );
if( m_type & info.typemask )
{
int version = m_GetLibVersion2( info.typemask );
if ( ((version >> 16)&0xff) == tbl_PluginInfo[pluginTypeIndex].version )
return true;
Console::Notice("%s Plugin %s: Version %x != %x", params info.shortname, m_plugpath, 0xff&(version >> 16), info.version);
}
return false;
}
bool Test( int pluginTypeIndex ) const
{
// all test functions use the same parameterless API, so just pick one arbitrarily (I pick PAD!)
_PADtest testfunc = (_PADtest)m_plugin.GetSymbol( wxString::FromAscii( tbl_PluginInfo[pluginTypeIndex].shortname ) + L"test" );
if( testfunc == NULL ) return false;
return (testfunc() == 0);
}
wxString GetName() const
{
wxASSERT( m_GetLibName != NULL );
return wxString::FromAscii(m_GetLibName());
}
void GetVersionString( wxString& dest, int pluginTypeIndex ) const
{
const PluginInfo& info( tbl_PluginInfo[pluginTypeIndex] );
int version = m_GetLibVersion2( info.typemask );
dest.Printf( L"%d.%d.%d", (version>>8)&0xff, version&0xff, (version>>24)&0xff );
}
};
static const wxString failed_separator( L"-------- Unsupported Plugins --------" );
// ------------------------------------------------------------------------
Panels::PluginSelectorPanel::StatusPanel::StatusPanel( wxWindow* parent, int pluginCount ) :
wxPanelWithHelpers( parent )
, m_gauge( *new wxGauge( this, wxID_ANY, pluginCount ) )
, m_label( *new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE | wxST_NO_AUTORESIZE ) )
, m_progress( 0 )
{
wxBoxSizer& s_main = *new wxBoxSizer( wxVERTICAL );
AddStaticText( s_main, _( "Enumerating available plugins..." ), 0, wxALIGN_CENTRE );
s_main.Add( &m_gauge, wxSizerFlags().Expand().Border( wxLEFT | wxRIGHT, 32 ) );
s_main.Add( &m_label, SizerFlags::StdExpand() );
SetSizerAndFit( &s_main );
}
void Panels::PluginSelectorPanel::StatusPanel::AdvanceProgress( const wxString& msg )
{
m_label.SetLabel( msg );
m_gauge.SetValue( ++m_progress );
}
void Panels::PluginSelectorPanel::StatusPanel::Reset()
{
m_gauge.SetValue( m_progress = 0 );
m_label.SetLabel( wxEmptyString );
}
// ------------------------------------------------------------------------
Panels::PluginSelectorPanel::ComboBoxPanel::ComboBoxPanel( PluginSelectorPanel* parent ) :
wxPanelWithHelpers( parent )
{
wxFlexGridSizer& s_plugin = *new wxFlexGridSizer( NumPluginTypes, 3, 16, 10 );
s_plugin.SetFlexibleDirection( wxHORIZONTAL );
s_plugin.AddGrowableCol( 1 ); // expands combo boxes to full width.
for( int i=0; i<NumPluginTypes; ++i )
{
s_plugin.Add(
new wxStaticText( this, wxID_ANY, wxString::FromAscii( tbl_PluginInfo[i].shortname ) ),
wxSizerFlags().Border( wxTOP | wxLEFT, 2 )
);
s_plugin.Add(
m_combobox[i] = new wxComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY ),
wxSizerFlags().Expand()
);
s_plugin.Add( new wxButton( this, wxID_ANY, L"Configure..." ) );
}
SetSizerAndFit( &s_plugin );
}
void Panels::PluginSelectorPanel::ComboBoxPanel::Reset()
{
for( int i=0; i<NumPluginTypes; ++i )
m_combobox[i]->Clear();
}
// ------------------------------------------------------------------------
Panels::PluginSelectorPanel::PluginSelectorPanel( wxWindow& parent ) :
BaseApplicableConfigPanel( &parent )
, m_FileList()
, m_StatusPanel( *new StatusPanel( this,
wxDir::GetAllFiles( g_Conf.Folders.Plugins.ToString(), &m_FileList, wxsFormat( L"*%s", wxDynamicLibrary::GetDllExt()), wxDIR_FILES )
) )
, m_ComboBoxes( *new ComboBoxPanel( this ) )
, m_Uninitialized( true )
, m_EnumeratorThread( NULL )
{
wxBoxSizer& s_main = *new wxBoxSizer( wxVERTICAL );
s_main.Add( &m_ComboBoxes, SizerFlags::StdExpand().ReserveSpaceEvenIfHidden() );
s_main.AddSpacer( 4 );
AddStaticText( s_main, _("Tip: Any installed plugins that are not compatible with your hardware or operating system will be listed below a separator."), 388, wxALIGN_CENTRE );
s_main.AddSpacer( 4 );
s_main.Add( &m_StatusPanel, SizerFlags::StdExpand().ReserveSpaceEvenIfHidden() );
// refresh button used for diagnostics... (don't think there's a point to having one otherwise) --air
//wxButton* refresh = new wxButton( this, wxID_ANY, L"Refresh" );
//s_main.Add( refresh );
//Connect( refresh->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PluginSelectorPanel::OnRefresh ) );
SetSizerAndFit( &s_main );
Connect( GetId(), wxEVT_SHOW, wxShowEventHandler( PluginSelectorPanel::OnShow ) );
Connect( wxEVT_EnumeratedNext, wxCommandEventHandler( PluginSelectorPanel::OnProgress ) );
Connect( wxEVT_EnumerationFinished, wxCommandEventHandler( PluginSelectorPanel::OnEnumComplete ) );
}
Panels::PluginSelectorPanel::~PluginSelectorPanel()
{
// Random crashes on null function pointer if we don't clean up the event...
Disconnect( GetId(), wxEVT_SHOW, wxShowEventHandler( PluginSelectorPanel::OnShow ) );
// Kill the thread if it's alive.
safe_delete( m_EnumeratorThread );
}
bool Panels::PluginSelectorPanel::Apply( AppConfig& conf )
{
for( int i=0; i<NumPluginTypes; ++i )
{
int sel = m_ComboBoxes.Get(i).GetSelection();
if( sel == wxNOT_FOUND ) continue;
wxFileName relative( m_FileList[(int)m_ComboBoxes.Get(i).GetClientData(sel)] );
relative.MakeRelativeTo( g_Conf.Folders.Plugins.ToString() );
conf.BaseFilenames.Plugins[tbl_PluginInfo[i].id] = relative.GetFullPath();
}
return true;
}
void Panels::PluginSelectorPanel::DoRefresh()
{
m_Uninitialized = false;
// Disable all controls until enumeration is complete.
m_ComboBoxes.Hide();
m_StatusPanel.Show();
// Use a thread to load plugins.
safe_delete( m_EnumeratorThread );
m_EnumeratorThread = new EnumThread( *this );
m_EnumeratorThread->Start();
}
// ------------------------------------------------------------------------
void Panels::PluginSelectorPanel::OnShow( wxShowEvent& evt )
{
evt.Skip();
if( !evt.GetShow() ) return;
if( !m_Uninitialized ) return;
DoRefresh();
}
void Panels::PluginSelectorPanel::OnRefresh( wxCommandEvent& evt )
{
m_ComboBoxes.Reset();
DoRefresh();
}
void Panels::PluginSelectorPanel::OnEnumComplete( wxCommandEvent& evt )
{
safe_delete( m_EnumeratorThread );
// fixme: Default plugins should be picked based on the timestamp of the DLL or something?
// (for now we just force it to selection zero if nothing's selected)
int emptyBoxes = 0;
for( int i=0; i<NumPluginTypes; ++i )
{
if( m_ComboBoxes.Get(i).GetCount() <= 0 )
emptyBoxes++;
else if( m_ComboBoxes.Get(i).GetSelection() == wxNOT_FOUND )
m_ComboBoxes.Get(i).SetSelection( 0 );
}
if( emptyBoxes > 0 )
{
wxMessageBox( pxE( Msg_Popup_MissingPlugins),
_("PCSX2 Error - Plugin components not found") );
}
m_ComboBoxes.Show();
m_StatusPanel.Hide();
m_StatusPanel.Reset();
}
void Panels::PluginSelectorPanel::OnProgress( wxCommandEvent& evt )
{
size_t evtidx = evt.GetExtraLong();
m_StatusPanel.AdvanceProgress( (evtidx < m_FileList.Count()-1) ?
m_FileList[evtidx + 1] : _("Completing tasks...")
);
EnumeratedPluginInfo& result( m_EnumeratorThread->Results[evtidx] );
for( int i=0; i<NumPluginTypes; ++i )
{
if( result.TypeMask & tbl_PluginInfo[i].typemask )
{
if( result.PassedTest & tbl_PluginInfo[i].typemask )
{
int sel = m_ComboBoxes.Get(i).Append( wxsFormat( L"%s %s [%s]",
result.Name.c_str(), result.Version[i].c_str(), Path::GetFilenameWithoutExt( m_FileList[evtidx] ).c_str() ),
(void*)evtidx
);
wxFileName left( m_FileList[evtidx] );
wxFileName right( g_Conf.FullpathTo(tbl_PluginInfo[i].id) );
left.MakeRelativeTo( g_Conf.Folders.Plugins.ToString() );
right.MakeRelativeTo( g_Conf.Folders.Plugins.ToString() );
Console::WriteLn( left.GetFullPath() );
Console::WriteLn( right.GetFullPath() );
if( left == right )
m_ComboBoxes.Get(i).SetSelection( sel );
}
else
{
// plugin failed the test.
}
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////
// EnumThread Method Implementations
Panels::PluginSelectorPanel::EnumThread::EnumThread( PluginSelectorPanel& master ) :
Thread()
, Results( new EnumeratedPluginInfo[master.FileCount()] )
, m_master( master )
, m_cancel( false )
{
}
Panels::PluginSelectorPanel::EnumThread::~EnumThread()
{
safe_delete_array( Results );
Close();
}
void Panels::PluginSelectorPanel::EnumThread::Close()
{
m_cancel = true;
Threading::Sleep( 1 );
Thread::Close();
}
int Panels::PluginSelectorPanel::EnumThread::Callback()
{
for( int curidx=0; curidx < m_master.FileCount() && !m_cancel; ++curidx )
{
try
{
PluginEnumerator penum( m_master.GetFilename( curidx ) );
EnumeratedPluginInfo& result( Results[curidx] );
result.Name = penum.GetName();
for( int pidx=0; pidx<NumPluginTypes; ++pidx )
{
result.TypeMask |= tbl_PluginInfo[pidx].typemask;
if( penum.CheckVersion( pidx ) )
{
result.PassedTest |= tbl_PluginInfo[pidx].typemask;
penum.GetVersionString( result.Version[pidx], pidx );
}
}
}
catch( Exception::BadStream& ex )
{
Console::Status( ex.LogMessage() );
}
catch( Exception::NotPcsxPlugin& ex )
{
Console::Status( ex.LogMessage() );
}
wxCommandEvent yay( wxEVT_EnumeratedNext );
yay.SetExtraLong( curidx );
m_master.GetEventHandler()->AddPendingEvent( yay );
}
m_master.GetEventHandler()->AddPendingEvent( wxCommandEvent( wxEVT_EnumerationFinished ) );
return 0;
}

View File

@ -24,8 +24,8 @@
using namespace wxHelpers;
Panels::SpeedHacksPanel::SpeedHacksPanel( wxWindow& parent, int id ) :
wxPanelWithHelpers( &parent, id )
Panels::SpeedHacksPanel::SpeedHacksPanel( wxWindow& parent ) :
BaseApplicableConfigPanel( &parent )
{
wxBoxSizer& mainSizer = *new wxBoxSizer( wxVERTICAL );
@ -77,6 +77,11 @@ Panels::SpeedHacksPanel::SpeedHacksPanel( wxWindow& parent, int id ) :
Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( SpeedHacksPanel::IdleLoopFF_Click ) );
}
bool Panels::SpeedHacksPanel::Apply( AppConfig& conf )
{
return true;
}
void Panels::SpeedHacksPanel::IOPCycleDouble_Click(wxCommandEvent &event)
{
//Config.Hacks.IOPCycleDouble = if it is clicked.

View File

@ -41,11 +41,16 @@ const EnglishExpansionEntry m_tbl_English[] =
L"Changing these settings can cause program errors, so please be weary."
},
{ Msg_Tooltips_SettingsPath, wxLt(L"Setting Tooltip:Settings Path"),
{ Msg_Tooltips_SettingsPath, wxLt(L"Settings Tooltip:Settings Path"),
L"This is the folder where PCSX2 saves all settings, including settings generated "
L"by most plugins.\n\nWarning: Some older versions of plugins may not respect this value."
},
{ Msg_Popup_MissingPlugins, wxLt(L"Popup Error:Missing Plugins"),
L"Critical Error: A valid plugin for one or more components of PCSX2 could not be found. "
L"Your installation of PCSX2 is incomplete, and will be unable to run games."
},
// ------------------------------------------------------------------------
// Begin Tooltips Section
// (All following texts are non-critical for a functional PCSX2 translation).
@ -86,6 +91,11 @@ C_ASSERT( ArraySize( m_tbl_English ) == ExpandedMsg_Count );
static HashMap<int,HashedExpansionPair> m_EnglishExpansions( -1, 0xcdcdcd, ArraySize( m_tbl_English ) );
static bool IsEnglish( int id )
{
return ( id == wxLANGUAGE_ENGLISH || id == wxLANGUAGE_ENGLISH_US );
}
// ------------------------------------------------------------------------
// Builds an internal hashtable for English iconized description lookups.
//
@ -101,6 +111,58 @@ void i18n_InitPlainEnglish()
}
}
// ------------------------------------------------------------------------
//
static void i18n_DoPackageCheck( int wxLangId, wxArrayString& destEng, wxArrayString& destTrans )
{
// Note: wx auto-preserves the current locale for us
if( !wxLocale::IsAvailable( wxLangId ) ) return;
wxLocale* locale = new wxLocale( wxLangId, wxLOCALE_CONV_ENCODING );
if( locale->IsOk() && locale->AddCatalog( L"pcsx2ident" ) )
{
// Should be a valid language, so add it to the list.
destEng.Add( wxLocale::GetLanguageName( wxLangId ) );
destTrans.Add( wxGetTranslation( L"NativeName" ) );
}
delete locale;
}
// ------------------------------------------------------------------------
// Finds all valid PCSX2 language packs, and enumerates them for configuration selection.
// Note: On linux there's no easy way to reliably enumerate language packs, since every distro
// could use its own location for installing pcsx2.mo files (wtcrap?). Furthermore wxWidgets
// doesn't give us a public API for checking what the language search paths are. So the only
// safe way to enumerate the languages is by forcibly loading every possible locale in the wx
// database. Anything which hasn't been installed will fail to load.
//
// Because loading and hashing the entire pcsx2 translation for every possible language would
// assinine and slow, I've decided to use a two-file translation system. One file is very
// small and simply contains the name of the language in the language native. The second file
// is loaded only if the user picks it (or if it's the default language of the OS).
//
void i18n_EnumeratePackages( wxArrayString& englishNames, wxArrayString& xlatedNames)
{
for( int li=wxLANGUAGE_UNKNOWN+1; li<wxLANGUAGE_USER_DEFINED; ++li )
{
i18n_DoPackageCheck( li, englishNames, xlatedNames );
}
// Brilliant. Because someone in the wx world didn't think to move wxLANGUAGE_USER_DEFINED
// to a place where it wasn't butt right up against the main languages (like, say, start user
// defined values at 4000 or something?), they had to add new languages in at some arbitrary
// value instead. Let's handle them here:
// fixme: these won't show up in alphabetical order if they're actually present (however
// horribly unlikely that is)... do we care? Probably not.
// Note: These aren't even available in some packaged Linux distros anyway. >_<
//i18n_DoPackageCheck( wxLANGUAGE_VALENCIAN, englishNames, xlatedNames );
//i18n_DoPackageCheck( wxLANGUAGE_SAMI, englishNames, xlatedNames );
}
// ------------------------------------------------------------------------
// PCSX2's Iconized Text Translator.
// This i18n version provides two layers of translated lookups. It puts the key through the
@ -117,7 +179,7 @@ const wxChar* __fastcall pxExpandMsg( ExpandedMsgEnum key )
const HashedExpansionPair& data( m_EnglishExpansions[key] );
int curlangid = wxLocale::GetLanguageInfo( g_Conf.LanguageId )->Language;
if( curlangid == wxLANGUAGE_ENGLISH || curlangid == wxLANGUAGE_ENGLISH_US )
if( IsEnglish( curlangid ) )
return data.Expanded;
const wxChar* retval = wxGetTranslation( data.gettextKey );
@ -166,13 +228,13 @@ bool i18n_SetLanguage( int wxLangId )
return false;
}
if( !locale->AddCatalog( L"pcsx2main" ) ) //, wxLANGUAGE_UNKNOWN, NULL ) )
if( !IsEnglish(wxLangId) && !locale->AddCatalog( L"pcsx2main" ) )
{
Console::Notice( wxsFormat( L"SetLanguage: Cannot find pcsx2main.mo file for language '%s' [%s]",
wxLocale::GetLanguageName( locale->GetLanguage() ).c_str(), locale->GetCanonicalName().c_str() )
);
safe_delete( locale );
return false;
}
//return locale;
return true;
}

View File

@ -25,6 +25,7 @@
enum ExpandedMsgEnum
{
Msg_Dialog_AdvancedPaths,
Msg_Popup_MissingPlugins,
Msg_Tooltips_Savestates,
Msg_Tooltips_Snapshots,

View File

@ -29,6 +29,7 @@
IMPLEMENT_APP(Pcsx2App)
AppConfig g_Conf;
wxFileHistory* g_RecentIsoList = NULL;
Pcsx2App::Pcsx2App() :
m_ConsoleFrame( NULL )

View File

@ -78,7 +78,7 @@ namespace wxHelpers
// Creates a new checkbox and adds it to the specified sizer/parent combo.
// Uses the default spacer setting for adding checkboxes.
//
wxCheckBox& AddCheckBoxTo( wxWindow* parent, wxBoxSizer& sizer, const wxString& label, wxWindowID id )
wxCheckBox& AddCheckBoxTo( wxWindow* parent, wxSizer& sizer, const wxString& label, wxWindowID id )
{
wxCheckBox* retval = new wxCheckBox( parent, id, label );
sizer.Add( retval, SizerFlags::Checkbox() );
@ -90,7 +90,7 @@ namespace wxHelpers
// The first item in a group should pass True for the isFisrt parameter.
// Uses the default spacer setting for checkboxes.
//
wxRadioButton& AddRadioButtonTo( wxWindow* parent, wxBoxSizer& sizer, const wxString& label, wxWindowID id, bool isFirst )
wxRadioButton& AddRadioButtonTo( wxWindow* parent, wxSizer& sizer, const wxString& label, wxWindowID id, bool isFirst )
{
wxRadioButton* retval = new wxRadioButton( parent, id, label, wxDefaultPosition, wxDefaultSize, isFirst ? wxRB_GROUP : 0 );
sizer.Add( retval, SizerFlags::Checkbox() );
@ -109,7 +109,7 @@ namespace wxHelpers
// alignFlags - Either wxALIGN_LEFT, RIGHT, or CENTRE. All other wxStaticText flags are ignored
// or overridden. [default is left alignment]
//
wxStaticText& AddStaticTextTo(wxWindow* parent, wxBoxSizer& sizer, const wxString& label, int size, int alignFlags )
wxStaticText& AddStaticTextTo(wxWindow* parent, wxSizer& sizer, const wxString& label, int size, int alignFlags )
{
// No reason to ever have AutoResize enabled, quite frankly. It just causes layout and centering problems.
alignFlags |= wxST_NO_AUTORESIZE;
@ -170,19 +170,19 @@ wxDialogWithHelpers::wxDialogWithHelpers( wxWindow* parent, int id, const wxStr
// any good.
}
wxCheckBox& wxDialogWithHelpers::AddCheckBox( wxBoxSizer& sizer, const wxString& label, wxWindowID id )
wxCheckBox& wxDialogWithHelpers::AddCheckBox( wxSizer& sizer, const wxString& label, wxWindowID id )
{
return wxHelpers::AddCheckBoxTo( this, sizer, label, id );
}
wxStaticText& wxDialogWithHelpers::AddStaticText(wxBoxSizer& sizer, const wxString& label, int size )
wxStaticText& wxDialogWithHelpers::AddStaticText(wxSizer& sizer, const wxString& label, int size )
{
return wxHelpers::AddStaticTextTo( this, sizer, label, size );
}
void wxDialogWithHelpers::AddOkCancel( wxBoxSizer &sizer, bool hasApply )
void wxDialogWithHelpers::AddOkCancel( wxSizer &sizer, bool hasApply )
{
wxBoxSizer* buttonSizer = &sizer;
wxSizer* buttonSizer = &sizer;
if( m_hasContextHelp )
{
// Add the context-sensitive help button on the caption for the platforms
@ -220,17 +220,17 @@ wxPanelWithHelpers::wxPanelWithHelpers( wxWindow* parent, int id, const wxPoint&
{
}
wxCheckBox& wxPanelWithHelpers::AddCheckBox( wxBoxSizer& sizer, const wxString& label, wxWindowID id )
wxCheckBox& wxPanelWithHelpers::AddCheckBox( wxSizer& sizer, const wxString& label, wxWindowID id )
{
return wxHelpers::AddCheckBoxTo( this, sizer, label, id );
}
wxStaticText& wxPanelWithHelpers::AddStaticText(wxBoxSizer& sizer, const wxString& label, int size, int alignFlags )
wxStaticText& wxPanelWithHelpers::AddStaticText(wxSizer& sizer, const wxString& label, int size, int alignFlags )
{
return wxHelpers::AddStaticTextTo( this, sizer, label, size, alignFlags );
}
wxRadioButton& wxPanelWithHelpers::AddRadioButton( wxBoxSizer& sizer, const wxString& label, const wxString& subtext, wxWindowID id )
wxRadioButton& wxPanelWithHelpers::AddRadioButton( wxSizer& sizer, const wxString& label, const wxString& subtext, wxWindowID id )
{
wxRadioButton& retval = wxHelpers::AddRadioButtonTo( this, sizer, label, id, m_StartNewRadioGroup );
m_StartNewRadioGroup = false;

View File

@ -6,9 +6,9 @@
namespace wxHelpers
{
extern wxCheckBox& AddCheckBoxTo( wxWindow* parent, wxBoxSizer& sizer, const wxString& label, wxWindowID id=wxID_ANY );
extern wxRadioButton& AddRadioButtonTo( wxWindow* parent, wxBoxSizer& sizer, const wxString& label, wxWindowID id=wxID_ANY, bool isFirst = false );
extern wxStaticText& AddStaticTextTo(wxWindow* parent, wxBoxSizer& sizer, const wxString& label, int size=0, int alignFlags=wxALIGN_LEFT );
extern wxCheckBox& AddCheckBoxTo( wxWindow* parent, wxSizer& sizer, const wxString& label, wxWindowID id=wxID_ANY );
extern wxRadioButton& AddRadioButtonTo( wxWindow* parent, wxSizer& sizer, const wxString& label, wxWindowID id=wxID_ANY, bool isFirst = false );
extern wxStaticText& AddStaticTextTo(wxWindow* parent, wxSizer& sizer, const wxString& label, int size=0, int alignFlags=wxALIGN_LEFT );
namespace SizerFlags
{
@ -32,9 +32,9 @@ public:
wxDialogWithHelpers(wxWindow* parent, int id, const wxString& title, bool hasContextHelp, const wxPoint& pos=wxDefaultPosition, const wxSize& size=wxDefaultSize );
protected:
wxCheckBox& AddCheckBox( wxBoxSizer& sizer, const wxString& label, wxWindowID id=wxID_ANY );
wxStaticText& AddStaticText(wxBoxSizer& sizer, const wxString& label, int size=0 );
void AddOkCancel( wxBoxSizer& sizer, bool hasApply=false );
wxCheckBox& AddCheckBox( wxSizer& sizer, const wxString& label, wxWindowID id=wxID_ANY );
wxStaticText& AddStaticText(wxSizer& sizer, const wxString& label, int size=0 );
void AddOkCancel( wxSizer& sizer, bool hasApply=false );
};
//////////////////////////////////////////////////////////////////////////////////////////
@ -45,12 +45,12 @@ protected:
bool m_StartNewRadioGroup;
public:
wxPanelWithHelpers( wxWindow* parent, int id, const wxPoint& pos=wxDefaultPosition, const wxSize& size=wxDefaultSize );
wxPanelWithHelpers( wxWindow* parent, int id=wxID_ANY, const wxPoint& pos=wxDefaultPosition, const wxSize& size=wxDefaultSize );
protected:
wxCheckBox& AddCheckBox( wxBoxSizer& sizer, const wxString& label, wxWindowID id=wxID_ANY );
wxRadioButton& AddRadioButton( wxBoxSizer& sizer, const wxString& label, const wxString& subtext=wxEmptyString, wxWindowID id=wxID_ANY );
wxStaticText& AddStaticText(wxBoxSizer& sizer, const wxString& label, int size=0, int alignFlags=wxALIGN_LEFT );
wxCheckBox& AddCheckBox( wxSizer& sizer, const wxString& label, wxWindowID id=wxID_ANY );
wxRadioButton& AddRadioButton( wxSizer& sizer, const wxString& label, const wxString& subtext=wxEmptyString, wxWindowID id=wxID_ANY );
wxStaticText& AddStaticText(wxSizer& sizer, const wxString& label, int size=0, int alignFlags=wxALIGN_LEFT );
void StartRadioGroup()
{