wxgui: All kinds of mess, but still not up to running games yet.

* Borrowed wxScopedPtr from wxWidgets 2.9
 * Fixed up first-time startup procedures and folder selection
 * Implemented most of the rest of the missing configuration options, and cleaned up some ambiguities regarding bool types and bitfields.

git-svn-id: http://pcsx2.googlecode.com/svn/branches/wxgui@1649 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-08-18 19:47:00 +00:00
parent 49144a5331
commit 3c4b1afb49
28 changed files with 1080 additions and 463 deletions

View File

@ -918,7 +918,7 @@
#define wxUSE_SPLASH 1
// wizards
#define wxUSE_WIZARDDLG 0
#define wxUSE_WIZARDDLG 1
// Compile in wxAboutBox() function showing the standard "About" dialog.
//

View File

@ -400,6 +400,10 @@
RelativePath="..\..\include\Utilities\SafeArray.h"
>
</File>
<File
RelativePath="..\..\include\Utilities\ScopedPtr.h"
>
</File>
<File
RelativePath="..\..\include\Utilities\StringHelpers.h"
>

View File

@ -173,10 +173,10 @@
//
#ifdef _MSC_VER
# define PCSX2_ALIGNED(alig,x) __declspec(align(alig)) x
# define PCSX2_ALIGNED_EXTERN(alig,x) extern __declspec(align(alig)) x
# define PCSX2_ALIGNED16(x) __declspec(align(16)) x
# define PCSX2_ALIGNED16_EXTERN(x) extern __declspec(align(16)) x
# define PCSX2_ALIGNED(alig,x) __declspec(align(alig)) x
# define PCSX2_ALIGNED_EXTERN(alig,x) extern __declspec(align(alig)) x
# define PCSX2_ALIGNED16(x) __declspec(align(16)) x
# define PCSX2_ALIGNED16_EXTERN(x) extern __declspec(align(16)) x
# define __naked __declspec(naked)
# define __unused /*unused*/

View File

@ -31,39 +31,31 @@ extern void pcsx2_aligned_free(void* pmem);
# define _aligned_realloc pcsx2_aligned_realloc
#endif
//////////////////////////////////////////////////////////////
// Safe deallocation macros -- always check pointer validity (non-null)
// and set pointer to null on deallocation.
//////////////////////////////////////////////////////////////////////////////////////////
// Safe deallocation macros -- checks pointer validity (non-null) when needed, and sets
// pointer to null after deallocation.
#define safe_delete( ptr ) \
if( ptr != NULL ) { \
delete ptr; \
ptr = NULL; \
}
((void) (delete ptr), ptr = NULL)
#define safe_delete_array( ptr ) \
if( ptr != NULL ) { \
delete[] ptr; \
ptr = NULL; \
}
((void) (delete[] ptr), ptr = NULL)
// fixme: I'm pretty sure modern libc implementations under gcc and msvc check null status
// inside free(), meaning we shouldn't have to do it ourselves. But legacy implementations
// didn't always check, so best to be cautious unless absolutely certain it's being covered on
// all ported platforms.
#define safe_free( ptr ) \
if( ptr != NULL ) { \
free( ptr ); \
ptr = NULL; \
}
((void) (( ( ptr != NULL ) && (free( ptr ), !!0) ), ptr = NULL))
// Implementation note: all known implementations of _aligned_free check the pointer for
// NULL status (our implementation under GCC, and microsoft's under MSVC), so no need to
// do it here.
#define safe_aligned_free( ptr ) \
if( ptr != NULL ) { \
_aligned_free( ptr ); \
ptr = NULL; \
}
((void) ( _aligned_free( ptr ), ptr = NULL ))
#define SafeSysMunmap( ptr, size ) \
if( ptr != NULL ) { \
HostSys::Munmap( (uptr)ptr, size ); \
ptr = NULL; \
}
((void) ( HostSys::Munmap( (uptr)ptr, size ), ptr = NULL ))
//////////////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,4 @@
#pragma once
#include <wx/scopedptr.h>
#include <wx/scopedarray.h>

View File

@ -0,0 +1,13 @@
-------------------------------------------------
include/wx folder -- PCSX2 Common Includes
-------------------------------------------------
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>
If/when PCSX2 upgrades to wx2.9/3.0 these files will be removed and the wxWidgets
distribution files will automatically be used instead.

View File

@ -0,0 +1,63 @@
/////////////////////////////////////////////////////////////////////////////
// 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

@ -0,0 +1,99 @@
/////////////////////////////////////////////////////////////////////////////
// Name: wx/scopedptr.h
// Purpose: scoped smart pointer class
// Author: Jesse Lovelace <jllovela@eos.ncsu.edu>
// Created: 06/01/02
// RCS-ID: $Id: scopedptr.h 60411 2009-04-27 13:59:08Z CE $
// Copyright: (c) Jesse Lovelace and original Boost authors (see below)
// (c) 2009 Vadim Zeitlin
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#pragma once
#include "wx/defs.h"
// This class closely follows the implementation of the boost
// library scoped_ptr and is an adaption for c++ macro's in
// the wxWidgets project. The original authors of the boost
// scoped_ptr are given below with their respective copyrights.
// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
// Copyright (c) 2001, 2002 Peter Dimov
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
// See http://www.boost.org/libs/smart_ptr/scoped_ptr.htm for documentation.
//
// ----------------------------------------------------------------------------
// wxScopedPtr: A scoped pointer
// ----------------------------------------------------------------------------
template <class T>
class wxScopedPtr
{
public:
typedef T element_type;
wxEXPLICIT wxScopedPtr(T * ptr = NULL) : m_ptr(ptr) { }
~wxScopedPtr() { delete m_ptr; }
// test for pointer validity: defining conversion to unspecified_bool_type
// and not more obvious bool to avoid implicit conversions to integer types
typedef T *(wxScopedPtr<T>::*unspecified_bool_type)() const;
operator unspecified_bool_type() const
{
return m_ptr ? &wxScopedPtr<T>::get : NULL;
}
void reset(T * ptr = NULL)
{
if ( ptr != m_ptr )
{
delete m_ptr;
m_ptr = ptr;
}
}
T *release()
{
T *ptr = m_ptr;
m_ptr = NULL;
return ptr;
}
T & operator*() const
{
wxASSERT(m_ptr != NULL);
return *m_ptr;
}
T * operator->() const
{
wxASSERT(m_ptr != NULL);
return m_ptr;
}
T * get() const
{
return m_ptr;
}
void swap(wxScopedPtr& other)
{
T * const tmp = other.m_ptr;
other.m_ptr = m_ptr;
m_ptr = tmp;
}
private:
T * m_ptr;
wxScopedPtr(const wxScopedPtr<T>&);
wxScopedPtr& operator=(const wxScopedPtr<T>&);
};

View File

@ -36,6 +36,13 @@ enum PluginsEnum_t
// equality operators.
#define OpEqu( field ) (field == right.field)
// Macro used for removing some of the redtape involved in defining bitfield/union helpers.
//
#define BITFIELD32() \
union { \
u32 bitset; \
struct {
//------------ DEFAULT sseMXCSR VALUES ---------------
#define DEFAULT_sseMXCSR 0xffc0 //FPU rounding > DaZ, FtZ, "chop"
#define DEFAULT_sseVUMXCSR 0xffc0 //VU rounding > DaZ, FtZ, "chop"
@ -58,72 +65,57 @@ class Pcsx2Config
public:
struct ProfilerOptions
{
union
{
struct
{
bool
Enabled:1, // universal toggle for the profiler.
RecBlocks_EE:1, // Enables per-block profiling for the EE recompiler [unimplemented]
RecBlocks_IOP:1, // Enables per-block profiling for the IOP recompiler [unimplemented]
RecBlocks_VU0:1, // Enables per-block profiling for the VU0 recompiler [unimplemented]
RecBlocks_VU1:1; // Enables per-block profiling for the VU1 recompiler [unimplemented]
};
u8 bits;
};
ProfilerOptions() : bits( 0 ) {}
BITFIELD32()
bool
Enabled:1, // universal toggle for the profiler.
RecBlocks_EE:1, // Enables per-block profiling for the EE recompiler [unimplemented]
RecBlocks_IOP:1, // Enables per-block profiling for the IOP recompiler [unimplemented]
RecBlocks_VU0:1, // Enables per-block profiling for the VU0 recompiler [unimplemented]
RecBlocks_VU1:1; // Enables per-block profiling for the VU1 recompiler [unimplemented]
}; };
// Default is Disabled, with all recs enabled underneath.
ProfilerOptions() : bitset( 0xfffffffe ) {}
void LoadSave( IniInterface& conf );
bool operator ==( const ProfilerOptions& right ) const
{
return OpEqu( bits );
return OpEqu( bitset );
}
bool operator !=( const ProfilerOptions& right ) const
{
return !this->operator ==( right );
return !OpEqu( bitset );
}
};
// ------------------------------------------------------------------------
struct RecompilerOptions
{
union
{
struct
{
bool
EnableEE:1,
EnableIOP:1,
EnableVU0:1,
EnableVU1:1;
bool
UseMicroVU0:1,
UseMicroVU1:1;
};
u8 bits;
};
BITFIELD32()
bool
EnableEE:1,
EnableIOP:1,
EnableVU0:1,
EnableVU1:1;
bool
UseMicroVU0:1,
UseMicroVU1:1;
}; };
RecompilerOptions() : bits( 0 ) { }
void Load( const wxString& srcfile );
void Load( const wxInputStream& srcstream );
void Save( const wxString& dstfile );
void Save( const wxOutputStream& deststream );
// All recs are enabled by default.
RecompilerOptions() : bitset( 0xffffffff ) { }
void LoadSave( IniInterface& conf );
bool operator ==( const RecompilerOptions& right ) const
{
return OpEqu( bits );
return OpEqu( bitset );
}
bool operator !=( const RecompilerOptions& right ) const
{
return !this->operator ==( right );
return !OpEqu( bitset );
}
} Recompiler;
@ -136,38 +128,27 @@ public:
u32 sseMXCSR;
u32 sseVUMXCSR;
struct
{
union
{
bool
vuOverflow:1,
vuExtraOverflow:1,
vuSignOverflow:1,
vuUnderflow:1;
bool
fpuOverflow:1,
fpuExtraOverflow:1,
fpuFullMode:1;
};
u8 bits;
};
CpuOptions() :
sseMXCSR( DEFAULT_sseMXCSR )
, sseVUMXCSR( DEFAULT_sseVUMXCSR )
, bits( 0 )
{
}
BITFIELD32()
bool
vuOverflow:1,
vuExtraOverflow:1,
vuSignOverflow:1,
vuUnderflow:1;
bool
fpuOverflow:1,
fpuExtraOverflow:1,
fpuFullMode:1;
}; };
CpuOptions();
void LoadSave( IniInterface& conf );
bool operator ==( const CpuOptions& right ) const
{
return
OpEqu( sseMXCSR ) && OpEqu( sseVUMXCSR ) &&
OpEqu( bits ) && OpEqu( Recompiler );
OpEqu( bitset ) && OpEqu( Recompiler );
}
bool operator !=( const CpuOptions& right ) const
@ -193,68 +174,59 @@ public:
int ConsecutiveFrames; // number of consecutive frames (fields) to render
int ConsecutiveSkip; // number of consecutive frames (fields) to skip
VideoOptions();
void LoadSave( IniInterface& conf );
};
// ------------------------------------------------------------------------
struct GamefixOptions
{
union
{
struct
{
bool
VuAddSubHack:1, // Fix for Tri-ace games, they use an encryption algorithm that requires VU ADDI opcode to be bit-accurate.
VuClipFlagHack:1, // Fix for Digimon Rumble Arena 2, fixes spinning/hanging on intro-menu.
FpuCompareHack:1, // Fix for Persona games, maybe others. It's to do with the VU clip flag (again).
FpuMulHack:1, // Fix for Tales of Destiny hangs.
XgKickHack:1; // Fix for Erementar Gerad, adds more delay to VU XGkick instructions. Corrects the color of some graphics, but breaks Tri-ace games and others.
};
u8 bits;
};
GamefixOptions() : bits( 0 ) {}
BITFIELD32()
bool
VuAddSubHack:1, // Fix for Tri-ace games, they use an encryption algorithm that requires VU ADDI opcode to be bit-accurate.
VuClipFlagHack:1, // Fix for Digimon Rumble Arena 2, fixes spinning/hanging on intro-menu.
FpuCompareHack:1, // Fix for Persona games, maybe others. It's to do with the VU clip flag (again).
FpuMulHack:1, // Fix for Tales of Destiny hangs.
XgKickHack:1; // Fix for Erementar Gerad, adds more delay to VU XGkick instructions. Corrects the color of some graphics, but breaks Tri-ace games and others.
}; };
// all gamefixes are disabled by default.
GamefixOptions() : bitset( 0 ) {}
void LoadSave( IniInterface& conf );
bool operator ==( const GamefixOptions& right ) const
{
return OpEqu( bits );
return OpEqu( bitset );
}
bool operator !=( const GamefixOptions& right ) const
{
return !this->operator ==( right );
return !OpEqu( bitset );
}
};
// ------------------------------------------------------------------------
struct SpeedhackOptions
{
union
{
struct
{
int
EECycleRate:2, // EE cyclerate selector (1.0, 1.5, 2.0)
VUCycleSteal:3, // VU Cycle Stealer factor (0, 1, 2, or 3)
IopCycleRate_X2:1, // enables the x2 multiplier of the IOP cyclerate
IntcStat:1, // tells Pcsx2 to fast-forward through intc_stat waits.
BIFC0:1, // enables BIFC0 detection and fast-forwarding
vuMinMax:1, // microVU specific MinMax hack; Can cause SPS, Black Screens, etc...
vuFlagHack:1; // MicroVU specific flag hack; Can cause Infinite loops, SPS, etc...
};
u16 bits;
};
BITFIELD32()
bool
IopCycleRate_X2:1, // enables the x2 multiplier of the IOP cyclerate
IntcStat:1, // tells Pcsx2 to fast-forward through intc_stat waits.
BIFC0:1, // enables BIFC0 detection and fast-forwarding
vuMinMax:1, // microVU specific MinMax hack; Can cause SPS, Black Screens, etc...
vuFlagHack:1; // MicroVU specific flag hack; Can cause Infinite loops, SPS, etc...
}; };
SpeedhackOptions() : bits( 0 ) {}
u8 EECycleRate; // EE cyclerate selector (1.0, 1.5, 2.0)
u8 VUCycleSteal; // VU Cycle Stealer factor (0, 1, 2, or 3)
SpeedhackOptions();
void LoadSave( IniInterface& conf );
bool operator ==( const SpeedhackOptions& right ) const
{
return OpEqu( bits );
return OpEqu( bitset ) && OpEqu( EECycleRate ) && OpEqu( VUCycleSteal );
}
bool operator !=( const SpeedhackOptions& right ) const
@ -264,18 +236,22 @@ public:
};
public:
bool CdvdVerboseReads:1; // enables cdvd read activity verbosely dumped to the console
bool CdvdDumpBlocks:1; // enables cdvd block dumping
bool EnablePatches:1; // enables patch detection and application
// when enabled performs bios stub execution, skipping full sony bios + splash screens
bool SkipBiosSplash:1;
BITFIELD32()
bool
CdvdVerboseReads:1, // enables cdvd read activity verbosely dumped to the console
CdvdDumpBlocks:1, // enables cdvd block dumping
EnablePatches:1, // enables patch detection and application
// Closes the GS/Video port on escape (good for fullscreen activity)
bool closeGSonEsc:1;
// when enabled performs bios stub execution, skipping full sony bios + splash screens
SkipBiosSplash:1,
// enables simulated ejection of memory cards when loading savestates
bool McdEnableEjection:1;
// Closes the GS/Video port on escape (good for fullscreen activity)
closeGSonEsc:1,
// enables simulated ejection of memory cards when loading savestates
McdEnableEjection:1;
}; };
CpuOptions Cpu;
VideoOptions Video;
@ -283,12 +259,13 @@ public:
GamefixOptions Gamefixes;
ProfilerOptions Profiler;
Pcsx2Config();
void LoadSave( IniInterface& ini );
void Load( const wxString& srcfile );
void Load( const wxInputStream& srcstream );
void Save( const wxString& dstfile );
void Save( const wxOutputStream& deststream );
void LoadSave( IniInterface& ini );
};
//////////////////////////////////////////////////////////////////////////

View File

@ -19,91 +19,152 @@
#include "PrecompiledHeader.h"
#include "IniInterface.h"
#include "Config.h"
#include "GS.h"
#include <wx/fileconf.h>
// all speedhacks are disabled by default
Pcsx2Config::SpeedhackOptions::SpeedhackOptions() :
bitset( 0 )
, EECycleRate( 0 )
, VUCycleSteal( 0 )
{
}
void Pcsx2Config::SpeedhackOptions::LoadSave( IniInterface& ini )
{
SpeedhackOptions defaults;
ini.SetPath( L"Speedhacks" );
IniBitfield( EECycleRate, 0 );
IniBitfield( VUCycleSteal, 0 );
IniBitBool( IopCycleRate_X2, false );
IniBitBool( IntcStat, false );
IniBitBool( BIFC0, false );
IniBitfield( EECycleRate );
IniBitfield( VUCycleSteal );
IniBitBool( IopCycleRate_X2 );
IniBitBool( IntcStat );
IniBitBool( BIFC0 );
ini.SetPath( L".." );
}
void Pcsx2Config::ProfilerOptions::LoadSave( IniInterface& ini )
{
ProfilerOptions defaults;
ini.SetPath( L"Profiler" );
IniBitBool( Enabled, false );
IniBitBool( RecBlocks_EE, true );
IniBitBool( RecBlocks_IOP, true );
IniBitBool( RecBlocks_VU0, true );
IniBitBool( RecBlocks_VU1, true );
IniBitBool( Enabled );
IniBitBool( RecBlocks_EE );
IniBitBool( RecBlocks_IOP );
IniBitBool( RecBlocks_VU0 );
IniBitBool( RecBlocks_VU1 );
ini.SetPath( L".." );
}
void Pcsx2Config::RecompilerOptions::LoadSave( IniInterface& ini )
{
RecompilerOptions defaults;
ini.SetPath( L"Recompiler" );
IniBitBool( EnableEE, true );
IniBitBool( EnableIOP, true );
IniBitBool( EnableVU0, true );
IniBitBool( EnableVU1, true );
IniBitBool( EnableEE );
IniBitBool( EnableIOP );
IniBitBool( EnableVU0 );
IniBitBool( EnableVU1 );
ini.SetPath( L".." );
}
Pcsx2Config::CpuOptions::CpuOptions() :
bitset( 0 )
, sseMXCSR( DEFAULT_sseMXCSR )
, sseVUMXCSR( DEFAULT_sseVUMXCSR )
{
vuOverflow = true;
fpuOverflow = true;
}
void Pcsx2Config::CpuOptions::LoadSave( IniInterface& ini )
{
CpuOptions defaults;
ini.SetPath( L"CPU" );
IniEntry( sseMXCSR, DEFAULT_sseMXCSR );
IniEntry( sseVUMXCSR, DEFAULT_sseVUMXCSR );
IniEntry( sseMXCSR );
IniEntry( sseVUMXCSR );
IniBitBool( vuOverflow, true );
IniBitBool( vuExtraOverflow, false );
IniBitBool( vuSignOverflow, false );
IniBitBool( vuUnderflow, false );
IniBitBool( vuOverflow );
IniBitBool( vuExtraOverflow );
IniBitBool( vuSignOverflow );
IniBitBool( vuUnderflow );
IniBitBool( fpuOverflow, true );
IniBitBool( fpuExtraOverflow, false );
IniBitBool( fpuFullMode, false );
IniBitBool( fpuOverflow );
IniBitBool( fpuExtraOverflow );
IniBitBool( fpuFullMode );
Recompiler.LoadSave( ini );
ini.SetPath( L".." );
}
Pcsx2Config::VideoOptions::VideoOptions() :
EnableFrameLimiting( false )
, EnableFrameSkipping( false )
, DefaultRegionMode( Region_NTSC )
, FpsTurbo( 60*4 )
, FpsLimit( 60 )
, FpsSkip( 55 )
, ConsecutiveFrames( 2 )
, ConsecutiveSkip( 1 )
{
}
void Pcsx2Config::VideoOptions::LoadSave( IniInterface& ini )
{
VideoOptions defaults;
ini.SetPath( L"Video" );
IniEntry( EnableFrameLimiting );
IniEntry( EnableFrameSkipping );
static const wxChar * const ntsc_pal_str[2] = { L"ntsc", L"pal" };
ini.EnumEntry( L"DefaultRegionMode", DefaultRegionMode, ntsc_pal_str, defaults.DefaultRegionMode );
IniEntry( FpsTurbo );
IniEntry( FpsLimit );
IniEntry( FpsSkip );
IniEntry( ConsecutiveFrames );
IniEntry( ConsecutiveSkip );
ini.SetPath( L".." );
}
void Pcsx2Config::GamefixOptions::LoadSave( IniInterface& ini )
{
ini.SetPath( L"Video" );
GamefixOptions defaults;
ini.SetPath( L"Gamefixes" );
IniBitBool( VuAddSubHack );
IniBitBool( VuClipFlagHack );
IniBitBool( FpuCompareHack );
IniBitBool( FpuMulHack );
IniBitBool( XgKickHack );
ini.SetPath( L".." );
}
Pcsx2Config::Pcsx2Config() :
bitset( 0 )
{
}
void Pcsx2Config::LoadSave( IniInterface& ini )
{
Pcsx2Config defaults;
ini.SetPath( L"EmuCore" );
IniBitBool( CdvdVerboseReads, false );
IniBitBool( CdvdDumpBlocks, false );
IniBitBool( EnablePatches, false );
IniBitBool( closeGSonEsc, false );
IniBitBool( McdEnableEjection, false );
IniBitBool( CdvdVerboseReads );
IniBitBool( CdvdDumpBlocks );
IniBitBool( EnablePatches );
IniBitBool( closeGSonEsc );
IniBitBool( McdEnableEjection );
// Process various sub-components:

View File

@ -18,6 +18,7 @@
#include "PrecompiledHeader.h"
#include "Utilities/RedtapeWindows.h"
#include "Utilities/ScopedPtr.h"
#include <wx/dir.h>
#include <wx/file.h>
@ -46,9 +47,20 @@ const PluginInfo tbl_PluginInfo[] =
};
int EnumeratePluginsFolder( wxArrayString* dest )
{
wxScopedPtr<wxArrayString> placebo;
wxArrayString* realdest = dest;
if( realdest == NULL )
placebo.reset( realdest = new wxArrayString() );
return g_Conf->Folders.Plugins.Exists() ?
wxDir::GetAllFiles( g_Conf->Folders.Plugins.ToString(), realdest, wxsFormat( L"*%s", wxDynamicLibrary::GetDllExt()), wxDIR_FILES ) : 0;
}
typedef void CALLBACK VoidMethod();
typedef void CALLBACK vMeth(); // shorthand for VoidMethod
; // extra semicolon fixes VA-X intellisense breakage caused by CALLBACK in the above typedef >_<
// ----------------------------------------------------------------------------
struct LegacyApi_CommonMethod

View File

@ -109,6 +109,8 @@ protected:
extern const PluginInfo tbl_PluginInfo[];
extern PluginManager* g_plugins;
extern int EnumeratePluginsFolder( wxArrayString* dest );
void LoadPlugins();
void ReleasePlugins();

View File

@ -95,10 +95,7 @@ namespace PathDefs
// share with other programs: screenshots, memory cards, and savestates.
wxDirName GetDocuments()
{
if( g_Conf->UseAdminMode )
return (wxDirName)wxGetCwd();
else
return (wxDirName)wxStandardPaths::Get().GetDocumentsDir() + (wxDirName)wxGetApp().GetAppName();
return (wxDirName)g_Conf->GetDefaultDocumentsFolder();
}
wxDirName GetSnapshots()
@ -159,6 +156,13 @@ namespace PathDefs
}
};
wxString AppConfig::GetDefaultDocumentsFolder()
{
if( UseAdminMode )
return wxGetCwd();
else
return Path::Combine( wxStandardPaths::Get().GetDocumentsDir(), wxGetApp().GetAppName() );
}
const wxDirName& AppConfig::FolderOptions::operator[]( FoldersEnum_t folderidx ) const
{
@ -345,10 +349,32 @@ wxString AppConfig::FullpathTo( PluginsEnum_t pluginidx ) const
wxString AppConfig::FullpathToBios() const { return Path::Combine( Folders.Bios, BaseFilenames.Bios ); }
wxString AppConfig::FullpathToMcd( uint mcdidx ) const { return Path::Combine( Folders.MemoryCards, Mcd[mcdidx].Filename ); }
AppConfig::AppConfig() :
MainGuiPosition( wxDefaultPosition )
, LanguageId( wxLANGUAGE_DEFAULT )
, RecentFileCount( 6 )
, DeskTheme( L"default" )
, Listbook_ImageSize( 32 )
, Toolbar_ImageSize( 24 )
, Toolbar_ShowLabels( true )
, McdEnableNTFS( true )
, ProgLogBox()
, Ps2ConBox()
, Folders()
, BaseFilenames()
, EmuOptions()
, m_IsLoaded( false )
{
}
// ------------------------------------------------------------------------
void AppConfig::LoadSaveUserMode( IniInterface& ini )
{
IniEntry( UseAdminMode, false );
AppConfig defaults;
ini.Entry( L"UseAdminMode", UseAdminMode, false );
ini.Entry( L"SettingsPath", Folders.Settings, PathDefs::GetSettings() );
ini.Flush();
@ -357,18 +383,20 @@ void AppConfig::LoadSaveUserMode( IniInterface& ini )
// ------------------------------------------------------------------------
void AppConfig::LoadSave( IniInterface& ini )
{
IniEntry( MainGuiPosition, wxDefaultPosition );
ini.EnumEntry( L"LanguageId", LanguageId );
IniEntry( RecentFileCount, 6 );
IniEntry( DeskTheme, L"default" );
IniEntry( Listbook_ImageSize, 32 );
IniEntry( Toolbar_ImageSize, 24 );
IniEntry( Toolbar_ShowLabels, true );
AppConfig defaults;
IniEntry( MainGuiPosition );
ini.EnumEntry( L"LanguageId", LanguageId, NULL, defaults.LanguageId );
IniEntry( RecentFileCount );
IniEntry( DeskTheme );
IniEntry( Listbook_ImageSize );
IniEntry( Toolbar_ImageSize );
IniEntry( Toolbar_ShowLabels );
// Process various sub-components:
ProgLogBox.LoadSave( ini, L"ProgramLog" );
Ps2ConBox.LoadSave( ini, L"Ps2Console" );
Folders.LoadSave( ini );
BaseFilenames.LoadSave( ini );
@ -391,14 +419,14 @@ void AppConfig::Apply()
// Ensure existence of necessary documents folders. Plugins and other parts
// of PCSX2 rely on them.
g_Conf->Folders.MemoryCards.Mkdir();
g_Conf->Folders.Savestates.Mkdir();
g_Conf->Folders.Snapshots.Mkdir();
Folders.MemoryCards.Mkdir();
Folders.Savestates.Mkdir();
Folders.Snapshots.Mkdir();
// Update the compression attribute on the Memcards folder.
// Memcards generally compress very well via NTFS compression.
NTFS_CompressFile( g_Conf->Folders.MemoryCards.ToString(), g_Conf->McdEnableNTFS );
NTFS_CompressFile( Folders.MemoryCards.ToString(), McdEnableNTFS );
bool prev = wxLog::EnableLogging( false ); // wx generates verbose errors if languages don't exist, so disable them here.
if( !i18n_SetLanguage( LanguageId ) )
@ -445,15 +473,25 @@ void AppConfig::Save()
}
// ------------------------------------------------------------------------
AppConfig::ConsoleLogOptions::ConsoleLogOptions() :
Visible( false )
, AutoDock( true )
, DisplayPosition( wxDefaultPosition )
, DisplaySize( wxSize( 540, 540 ) )
, FontSize( 8 )
{
}
void AppConfig::ConsoleLogOptions::LoadSave( IniInterface& ini, const wxChar* logger )
{
ConsoleLogOptions defaults;
ini.SetPath( logger );
IniEntry( Visible, false );
IniEntry( AutoDock, true );
IniEntry( DisplayPosition, wxDefaultPosition );
IniEntry( DisplaySize, wxSize( 540, 540 ) );
IniEntry( FontSize, 8 );
IniEntry( Visible );
IniEntry( AutoDock );
IniEntry( DisplayPosition );
IniEntry( DisplaySize );
IniEntry( FontSize );
ini.SetPath( L".." );
}
@ -470,30 +508,45 @@ void AppConfig::FolderOptions::ApplyDefaults()
}
// ------------------------------------------------------------------------
AppConfig::FolderOptions::FolderOptions() :
bitset( 0xffffffff )
, Plugins( PathDefs::GetPlugins() )
, Settings( PathDefs::GetSettings() )
, Bios( PathDefs::GetBios() )
, Snapshots( PathDefs::GetSnapshots() )
, Savestates( PathDefs::GetSavestates() )
, MemoryCards( PathDefs::GetMemoryCards() )
, Logs( PathDefs::GetLogs() )
, RunIso( PathDefs::GetDocuments() ) // raw default is always the Documents folder.
{
}
void AppConfig::FolderOptions::LoadSave( IniInterface& ini )
{
FolderOptions defaults;
ini.SetPath( L"Folders" );
if( ini.IsSaving() )
ApplyDefaults();
IniEntry( Plugins, PathDefs::GetPlugins() );
IniEntry( Settings, PathDefs::GetSettings() );
IniEntry( Bios, PathDefs::GetBios() );
IniEntry( Snapshots, PathDefs::GetSnapshots() );
IniEntry( Savestates, PathDefs::GetSavestates() );
IniEntry( MemoryCards, PathDefs::GetMemoryCards() );
IniEntry( Logs, PathDefs::GetLogs() );
IniBitBool( UseDefaultPlugins );
IniBitBool( UseDefaultSettings );
IniBitBool( UseDefaultBios );
IniBitBool( UseDefaultSnapshots );
IniBitBool( UseDefaultSavestates );
IniBitBool( UseDefaultMemoryCards );
IniBitBool( UseDefaultLogs );
IniEntry( RunIso, PathDefs::GetDocuments() ); // raw default is always the Documents folder.
IniEntry( Plugins );
IniEntry( Settings );
IniEntry( Bios );
IniEntry( Snapshots );
IniEntry( Savestates );
IniEntry( MemoryCards );
IniEntry( Logs );
IniBitBool( UseDefaultPlugins, true );
IniBitBool( UseDefaultSettings, true );
IniBitBool( UseDefaultBios, true );
IniBitBool( UseDefaultSnapshots, true );
IniBitBool( UseDefaultSavestates, true );
IniBitBool( UseDefaultMemoryCards, true );
IniBitBool( UseDefaultLogs, true );
IniEntry( RunIso );
if( ini.IsLoading() )
ApplyDefaults();
@ -535,3 +588,29 @@ void AppConfig::FilenameOptions::LoadSave( IniInterface& ini )
ini.SetPath( L".." );
}
wxFileConfig* OpenFileConfig( const wxString& filename )
{
return new wxFileConfig( wxEmptyString, wxEmptyString, filename, wxEmptyString, wxCONFIG_USE_RELATIVE_PATH );
}
// Parameters:
// overwrite - this option forces the current settings to overwrite any existing settings that might
// be saved to the configured ini/settings folder.
//
void AppConfig_ReloadGlobalSettings( bool overwrite )
{
PathDefs::GetDocuments().Mkdir();
PathDefs::GetSettings().Mkdir();
// Allow wx to use our config, and enforces auto-cleanup as well
wxString confile( g_Conf->Folders.Settings.Combine( FilenameDefs::GetConfig() ).GetFullPath() );
delete wxConfigBase::Set( OpenFileConfig( confile ) );
wxConfigBase::Get()->SetRecordDefaults();
if( !overwrite )
g_Conf->Load();
g_Conf->Apply();
g_Conf->Folders.Logs.Mkdir();
}

View File

@ -20,6 +20,8 @@
class IniInterface;
extern bool UseAdminMode; // dictates if the program uses /home/user or /cwd for the program data
//////////////////////////////////////////////////////////////////////////////////////////
// Pcsx2 Application Configuration.
//
@ -40,12 +42,24 @@ public:
// Size of the font in points.
int FontSize;
ConsoleLogOptions();
void LoadSave( IniInterface& conf, const wxChar* title );
};
// ------------------------------------------------------------------------
struct FolderOptions
{
BITFIELD32()
bool
UseDefaultPlugins:1,
UseDefaultSettings:1,
UseDefaultBios:1,
UseDefaultSnapshots:1,
UseDefaultSavestates:1,
UseDefaultMemoryCards:1,
UseDefaultLogs:1;
}; };
wxDirName
Plugins,
Settings,
@ -57,15 +71,7 @@ public:
wxDirName RunIso; // last used location for Iso loading.
bool
UseDefaultPlugins:1,
UseDefaultSettings:1,
UseDefaultBios:1,
UseDefaultSnapshots:1,
UseDefaultSavestates:1,
UseDefaultMemoryCards:1,
UseDefaultLogs:1;
FolderOptions();
void LoadSave( IniInterface& conf );
void ApplyDefaults();
@ -96,7 +102,6 @@ public:
};
public:
bool UseAdminMode; // dictates if the program uses /home/user or /cwd for the program data
wxPoint MainGuiPosition;
// Current language in use (correlates to a wxWidgets wxLANGUAGE specifier)
@ -140,12 +145,7 @@ protected:
bool m_IsLoaded;
public:
AppConfig() :
Listbook_ImageSize( 32 )
, Toolbar_ImageSize( 24 )
, m_IsLoaded( false )
{
}
AppConfig();
wxString FullpathToBios() const;
wxString FullpathToMcd( uint mcdidx ) const;
@ -156,8 +156,15 @@ public:
void Apply();
void LoadSaveUserMode( IniInterface& ini );
wxString GetDefaultDocumentsFolder();
protected:
void LoadSave( IniInterface& ini );
};
class wxFileConfig; // forward declare.
extern wxFileConfig* OpenFileConfig( const wxString& filename );
extern void AppConfig_ReloadGlobalSettings( bool overwrite = false );
extern AppConfig* g_Conf;

View File

@ -67,15 +67,14 @@ Dialogs::ConfigurationDialog::ConfigurationDialog( wxWindow* parent, int id ) :
m_listbook.AddPage( new PluginSelectorPanel( m_listbook, IdealWidth ), _("Plugins"), false, cfgid.Plugins );
g_ApplyState.SetCurrentPage( m_listbook.GetPageCount() );
m_listbook.AddPage( new PathsPanel( m_listbook, IdealWidth ), _("Folders"), false, cfgid.Paths );
m_listbook.AddPage( new TabbedPathsPanel( m_listbook, IdealWidth ), _("Folders"), false, cfgid.Paths );
mainSizer.Add( &m_listbook );
AddOkCancel( mainSizer, true );
SetSizerAndFit( &mainSizer );
Center( wxCENTER_ON_SCREEN | wxBOTH );
CenterOnScreen();
Connect( wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ConfigurationDialog::OnOk_Click ) );
Connect( wxID_APPLY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ConfigurationDialog::OnApply_Click ) );

View File

@ -0,0 +1,169 @@
/* 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 "System.h"
#include "Plugins.h"
#include "ModalPopups.h"
#include "Panels/ConfigurationPanels.h"
using namespace wxHelpers;
using namespace Panels;
template< typename T >
static T& MakeWizWidget( int pageid, wxWizardPage& src )
{
g_ApplyState.SetCurrentPage( pageid );
return *new T( src, 620 );
}
FirstTimeWizard::FirstTimeWizard( wxWindow* parent ) :
wxWizard( (g_ApplyState.StartWizard(), parent), wxID_ANY, _("PCSX2 First Time Configuration") )
, m_page_usermode( *new wxWizardPageSimple( this ) )
//, m_page_paths( *new wxWizardPageSimple( this, &m_page_usermode ) )
, m_page_plugins( *new wxWizardPageSimple( this, &m_page_usermode ) )
, m_panel_LangSel( MakeWizWidget<LanguageSelectionPanel>( 0, m_page_usermode ) )
, m_panel_UsermodeSel( MakeWizWidget<UsermodeSelectionPanel>( 0, m_page_usermode ) )
, m_panel_Paths( MakeWizWidget<AdvancedPathsPanel>( 0, m_page_usermode ) )
, m_panel_PluginSel( MakeWizWidget<PluginSelectorPanel>( 1, m_page_plugins ) )
{
// Page 1 - User Mode and Language Selectors
wxBoxSizer& usermodeSizer( *new wxBoxSizer( wxVERTICAL ) );
AddStaticTextTo( &m_page_usermode, usermodeSizer, _("PCSX2 is starting from a new or unknown folder and needs to be configured.") );
usermodeSizer.Add( &m_panel_LangSel, SizerFlags::StdCenter() );
usermodeSizer.Add( &m_panel_UsermodeSel, wxSizerFlags().Expand().Border( wxALL, 8 ) );
//AddStaticTextTo( this, usermodeSizer, _( "Advanced users can optionally configure these folders." ) );
usermodeSizer.AddSpacer( 6 );
usermodeSizer.Add( &m_panel_Paths, wxSizerFlags().Expand().Border( wxALL, 4 ) );
m_page_usermode.SetSizerAndFit( &usermodeSizer );
// Page 2 - Advanced Paths Panel
/*wxBoxSizer& pathsSizer( *new wxBoxSizer( wxVERTICAL ) );
pathsSizer.Add( &m_panel_Paths, SizerFlags::StdExpand() );
m_page_paths.SetSizerAndFit( &pathsSizer );*/
// Page 3 - Plugins Panel
wxBoxSizer& pluginSizer( *new wxBoxSizer( wxVERTICAL ) );
pluginSizer.Add( &m_panel_PluginSel, SizerFlags::StdExpand() );
m_page_plugins.SetSizerAndFit( &pluginSizer );
// Assign page indexes as client data
m_page_usermode.SetClientData ( (void*)0 );
//m_page_paths.SetClientData ( (void*)1 );
m_page_plugins.SetClientData ( (void*)1 );
// Build the forward chain:
// (backward chain is built during initialization above)
m_page_usermode.SetNext ( &m_page_plugins );
//m_page_paths.SetNext ( &m_page_plugins );
GetPageAreaSizer()->Add( &m_page_usermode );
CenterOnScreen();
Connect( wxEVT_WIZARD_PAGE_CHANGED, wxWizardEventHandler( FirstTimeWizard::OnPageChanged ) );
Connect( wxEVT_WIZARD_PAGE_CHANGING, wxWizardEventHandler( FirstTimeWizard::OnPageChanging ) );
Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler(FirstTimeWizard::OnUsermodeChanged) );
}
FirstTimeWizard::~FirstTimeWizard()
{
g_ApplyState.DoCleanup();
}
void FirstTimeWizard::OnPageChanging( wxWizardEvent& evt )
{
//evt.Skip();
if( evt.GetDirection() )
{
// Moving forward:
// Apply settings from the current page...
int page = (int)evt.GetPage()->GetClientData();
if( page >= 0 )
{
if( !g_ApplyState.ApplyPage( page ) )
{
evt.Veto();
return;
}
AppConfig_ReloadGlobalSettings( true ); // ... and overwrite any existing settings
// [TODO] : The user should be prompted if they want to overwrite existing
// settings or import them instead.
}
if( page == 0 )
{
// test plugins folder for validity. If it doesn't exist or is empty then
// the user needs to "try again" :)
if( !g_Conf->Folders.Plugins.Exists() )
{
Msgbox::Alert( _( "The selected plugins folder does not exist. You must select a valid PCSX2 plugins folder that exists and contains plugins." ) );
evt.Veto();
}
else
{
if( 0 == EnumeratePluginsFolder(NULL) )
{
Msgbox::Alert( _( "The selected plugins folder is empty. You must select a valid PCSX2 plugins folder that actually contains plugins." ) );
evt.Veto();
}
}
}
}
}
void FirstTimeWizard::OnPageChanged( wxWizardEvent& evt )
{
// Plugin Selector needs a special OnShow hack, because Wizard child panels don't
// receive any Show events >_<
if( (sptr)evt.GetPage() == (sptr)&m_page_plugins )
m_panel_PluginSel.OnShow();
}
void FirstTimeWizard::OnUsermodeChanged( wxCommandEvent& evt )
{
//wxLogError( L"Awesome" );
m_panel_UsermodeSel.Apply( *g_Conf ); // this assigns the current user mode to g_ApplyState.UseAdminMode
if( g_ApplyState.UseAdminMode == UseAdminMode ) return;
UseAdminMode = g_ApplyState.UseAdminMode;
g_Conf->Folders.ApplyDefaults();
m_panel_Paths.Reset();
}
/*
wxString biosfolder( Path::Combine( conf.GetDefaultDocumentsFolder(), conf.Folders.Bios ) );
if( wxDir::Exists( biosfolder ) )
{
if( wxDir::GetAllFiles( biosfolder, NULL, L"*.bin", wxDIR_FILES ) )
}
if( !wxDir::Exists( biosfolder ) )
{
Msgbox::Alert( ("First Time Installation:\n\n") + BIOS_GetMsg_Required() );
}
*/

View File

@ -18,12 +18,35 @@
#pragma once
#include <wx/wx.h>
#include <wx/image.h>
#include "wxHelpers.h"
#include "Panels/ConfigurationPanels.h"
#include <wx/image.h>
#include <wx/wizard.h>
class FirstTimeWizard : public wxWizard
{
protected:
wxWizardPageSimple& m_page_usermode;
//wxWizardPageSimple& m_page_paths;
wxWizardPageSimple& m_page_plugins;
Panels::LanguageSelectionPanel& m_panel_LangSel;
Panels::UsermodeSelectionPanel& m_panel_UsermodeSel;
Panels::AdvancedPathsPanel& m_panel_Paths;
Panels::PluginSelectorPanel& m_panel_PluginSel;
public:
FirstTimeWizard( wxWindow* parent );
virtual ~FirstTimeWizard();
wxWizardPage *GetFirstPage() const { return &m_page_usermode; }
protected:
virtual void OnPageChanging( wxWizardEvent& evt );
virtual void OnPageChanged( wxWizardEvent& evt );
virtual void OnUsermodeChanged( wxCommandEvent& evt );
};
namespace Dialogs
{
class AboutBoxDialog: public wxDialog

View File

@ -26,8 +26,8 @@ using namespace wxHelpers;
Dialogs::PickUserModeDialog::PickUserModeDialog( wxWindow* parent, int id ) :
wxDialogWithHelpers( parent, id, _("PCSX2 First Time configuration"), false )
, m_panel_usersel( new Panels::UsermodeSelectionPanel( this, 620 ) )
, m_panel_langsel( new Panels::LanguageSelectionPanel( this, 620 ) )
, m_panel_usersel( new Panels::UsermodeSelectionPanel( *this, 620, false ) )
, m_panel_langsel( new Panels::LanguageSelectionPanel( *this, 620 ) )
{
wxBoxSizer& s_main = *new wxBoxSizer( wxVERTICAL );

View File

@ -151,6 +151,6 @@ protected:
// GCC Note: wxT() macro is required when using string token pasting. For some reason L generates
// syntax errors. >_<
//
#define IniEntry( varname, defval ) ini.Entry( wxT(#varname), varname, defval )
#define IniBitfield( varname, defval ) varname = ini.EntryBitfield( wxT(#varname), varname, defval )
#define IniBitBool( varname, defval ) varname = ini.EntryBitBool( wxT(#varname), !!varname, defval )
#define IniEntry( varname ) ini.Entry( wxT(#varname), varname, defaults.varname )
#define IniBitfield( varname ) varname = ini.EntryBitfield( wxT(#varname), varname, defaults.varname )
#define IniBitBool( varname ) varname = ini.EntryBitBool( wxT(#varname), !!varname, defaults.varname )

View File

@ -45,7 +45,7 @@ namespace Exception
{
// --------------------------------------------------------------------------
// Exception used to perform an abort of Apply/Ok action on settings panels.
// When thrown, the user recieves a popup message containing the information
// When thrown, the user receives a popup message containing the information
// specified in the exception message, and is returned to the settings dialog
// to correct the invalid input fields.
//
@ -79,7 +79,6 @@ namespace Exception
namespace Panels
{
typedef std::list<BaseApplicableConfigPanel*> PanelApplyList_t;
struct StaticApplyState
@ -91,9 +90,13 @@ namespace Panels
// this page as their "go here on error" page. (used to take the user to the
// page with the option that failed apply validation).
int CurOwnerPage;
// TODO : Rename me to CurOwnerBook, or rename the one above to ParentPage.
wxBookCtrlBase* ParentBook;
// Crappy hack to handle the UseAdminMode option, which can't be part of AppConfig
// because AppConfig depends on this value to initialize itself.
bool UseAdminMode;
StaticApplyState() :
PanelList()
@ -106,14 +109,16 @@ namespace Panels
{
CurOwnerPage = page;
}
void ClearCurrentPage()
{
CurOwnerPage = wxID_NONE;
}
void StartBook( wxBookCtrlBase* book );
void StartWizard();
bool ApplyAll();
bool ApplyPage( int pageid );
void DoCleanup();
};
@ -124,8 +129,8 @@ namespace Panels
// window (usually the ConfigurationDialog) when either Ok or Apply is clicked.
//
// Thread Safety: None. This class is only safe when used from the GUI thread, as it uses
// static vars and assumes that only one Applicableconfig system is available to the
// use rate any time (ie, a singular modal dialog).
// static vars and assumes that only one ApplicableConfig system is available to the
// user at any time (ie, a singular modal dialog).
//
class BaseApplicableConfigPanel : public wxPanelWithHelpers
{
@ -156,6 +161,10 @@ namespace Panels
m_OwnerBook->SetSelection( m_OwnerPage );
}
// Returns true if this ConfigPanel belongs to the specified page. Useful for doing
// selective application of options for specific pages.
bool IsOnPage( int pageid ) { return m_OwnerPage == pageid; }
// 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 should throw Exception::CannotApplySettings.
@ -173,7 +182,7 @@ namespace Panels
public:
virtual ~UsermodeSelectionPanel() { }
UsermodeSelectionPanel( wxWindow* parent, int idealWidth=wxDefaultCoord );
UsermodeSelectionPanel( wxWindow& parent, int idealWidth=wxDefaultCoord, bool isFirstTime = true );
void Apply( AppConfig& conf );
};
@ -188,7 +197,7 @@ namespace Panels
public:
virtual ~LanguageSelectionPanel() { }
LanguageSelectionPanel( wxWindow* parent, int idealWidth=wxDefaultCoord );
LanguageSelectionPanel( wxWindow& parent, int idealWidth=wxDefaultCoord );
void Apply( AppConfig& conf );
};
@ -251,53 +260,73 @@ namespace Panels
};
//////////////////////////////////////////////////////////////////////////////////////////
// DirPickerPanel
// A simple panel which provides a specialized configurable directory picker with a
// "[x] Use Default setting" option, which enables or disables the panel.
//
class PathsPanel : public BaseApplicableConfigPanel
class DirPickerPanel : public BaseApplicableConfigPanel
{
protected:
class DirPickerPanel : public BaseApplicableConfigPanel
{
protected:
FoldersEnum_t m_FolderId;
wxDirPickerCtrl* m_pickerCtrl;
wxCheckBox* m_checkCtrl;
public:
DirPickerPanel( wxWindow* parent, FoldersEnum_t folderid, const wxString& label, const wxString& dialogLabel );
void Apply( AppConfig& conf );
protected:
void UseDefaultPath_Click(wxCommandEvent &event);
void UpdateCheckStatus( bool someNoteworthyBoolean );
};
class MyBasePanel : public wxPanelWithHelpers
{
protected:
wxBoxSizer& s_main;
public:
MyBasePanel( wxWindow& parent, int idealWidth=wxDefaultCoord );
protected:
DirPickerPanel& AddDirPicker( wxBoxSizer& sizer, FoldersEnum_t folderid,
const wxString& label, const wxString& popupLabel );
};
class StandardPanel : public MyBasePanel
{
public:
StandardPanel( wxWindow& parent );
};
class AdvancedPanel : public MyBasePanel
{
public:
AdvancedPanel( wxWindow& parent, int idealWidth );
};
FoldersEnum_t m_FolderId;
wxDirPickerCtrl* m_pickerCtrl;
wxCheckBox* m_checkCtrl;
public:
PathsPanel( wxWindow& parent, int idealWidth );
DirPickerPanel( wxWindow* parent, FoldersEnum_t folderid, const wxString& label, const wxString& dialogLabel );
void Apply( AppConfig& conf );
void Reset();
protected:
void UseDefaultPath_Click(wxCommandEvent &event);
void UpdateCheckStatus( bool someNoteworthyBoolean );
};
//////////////////////////////////////////////////////////////////////////////////////////
//
class BasePathsPanel : public wxPanelWithHelpers
{
protected:
wxBoxSizer& s_main;
public:
BasePathsPanel( wxWindow& parent, int idealWidth=wxDefaultCoord );
virtual wxSizer& Sizer() { return s_main; }
protected:
DirPickerPanel& AddDirPicker( wxBoxSizer& sizer, FoldersEnum_t folderid,
const wxString& label, const wxString& popupLabel );
};
//////////////////////////////////////////////////////////////////////////////////////////
//
class StandardPathsPanel : public BasePathsPanel
{
public:
StandardPathsPanel( wxWindow& parent );
};
//////////////////////////////////////////////////////////////////////////////////////////
//
class AdvancedPathsPanel : public BasePathsPanel
{
protected:
DirPickerPanel& m_dirpick_plugins;
DirPickerPanel& m_dirpick_settings;
public:
AdvancedPathsPanel( wxWindow& parent, int idealWidth );
void Reset();
};
//////////////////////////////////////////////////////////////////////////////////////////
// TabbedPathsPanel
// This panel is a Tabbed (paged) panel which contains both Standard Paths and Advanced
// Paths panels.
//
class TabbedPathsPanel : public BaseApplicableConfigPanel
{
public:
TabbedPathsPanel( wxWindow& parent, int idealWidth );
void Apply( AppConfig& conf );
};
@ -368,7 +397,9 @@ namespace Panels
int m_progress;
public:
StatusPanel( wxWindow* parent, int pluginCount, int biosCount );
StatusPanel( wxWindow* parent );
void SetGaugeLength( int len );
void AdvanceProgress( const wxString& msg );
void Reset();
};
@ -378,27 +409,30 @@ namespace Panels
// ------------------------------------------------------------------------
protected:
wxArrayString m_FileList; // list of potential plugin files
wxArrayString m_BiosList;
wxArrayString* m_FileList; // list of potential plugin files
wxArrayString* m_BiosList;
StatusPanel& m_StatusPanel;
ComboBoxPanel& m_ComponentBoxes;
bool m_Uninitialized;
EnumThread* m_EnumeratorThread;
public:
virtual ~PluginSelectorPanel();
PluginSelectorPanel( wxWindow& parent, int idealWidth );
virtual void OnShow( wxShowEvent& evt );
virtual void OnRefresh( wxCommandEvent& evt );
virtual void OnProgress( wxCommandEvent& evt );
virtual void OnEnumComplete( wxCommandEvent& evt );
void Apply( AppConfig& conf );
void OnShow();
protected:
virtual void OnShow( wxShowEvent& evt );
virtual void OnRefresh( wxCommandEvent& evt );
void DoRefresh();
int FileCount() const { return m_FileList.Count(); }
const wxString& GetFilename( int i ) const { return m_FileList[i]; }
bool ValidateEnumerationStatus();
int FileCount() const { return m_FileList->Count(); }
const wxString& GetFilename( int i ) const { return (*m_FileList)[i]; }
friend class EnumThread;
};
}

View File

@ -18,6 +18,7 @@
#include "PrecompiledHeader.h"
#include "ConfigurationPanels.h"
#include "ps2/BiosTools.h"
#include <wx/stdpaths.h>
@ -43,22 +44,35 @@ void Panels::StaticApplyState::StartBook( wxBookCtrlBase* book )
ParentBook = book;
}
void Panels::StaticApplyState::StartWizard()
{
DevAssert( ParentBook == NULL, "An ApplicableConfig session is already in progress." );
}
// -----------------------------------------------------------------------
//
// Parameters:
// pageid - identifier of the page to apply settings for. All other pages will be
// skipped. If pageid is negative (-1) then all pages are applied.
//
// Returns false if one of the panels fails input validation (in which case dialogs
// should not be closed, etc).
//
bool Panels::StaticApplyState::ApplyAll()
bool Panels::StaticApplyState::ApplyPage( int pageid )
{
bool retval = true;
try
{
AppConfig confcopy( *g_Conf );
g_ApplyState.UseAdminMode = UseAdminMode;
PanelApplyList_t::iterator yay = PanelList.begin();
while( yay != PanelList.end() )
{
//DbgCon::Status( L"Writing settings for: " + (*yay)->GetLabel() );
(*yay)->Apply( confcopy );
if( (pageid < 0) || (*yay)->IsOnPage( pageid ) )
(*yay)->Apply( confcopy );
yay++;
}
@ -66,6 +80,7 @@ bool Panels::StaticApplyState::ApplyAll()
// (conveniently skipping any option application! :D)
*g_Conf = confcopy;
UseAdminMode = g_ApplyState.UseAdminMode;
g_Conf->Apply();
g_Conf->Save();
}
@ -77,28 +92,43 @@ bool Panels::StaticApplyState::ApplyAll()
ex.GetPanel()->SetFocusToMe();
retval = false;
}
return retval;
return retval;
}
// Returns false if one of the panels fails input validation (in which case dialogs
// should not be closed, etc).
bool Panels::StaticApplyState::ApplyAll()
{
return ApplyPage( -1 );
}
// -----------------------------------------------------------------------
Panels::UsermodeSelectionPanel::UsermodeSelectionPanel( wxWindow* parent, int idealWidth ) :
BaseApplicableConfigPanel( parent, idealWidth )
Panels::UsermodeSelectionPanel::UsermodeSelectionPanel( wxWindow& parent, int idealWidth, bool isFirstTime ) :
BaseApplicableConfigPanel( &parent, idealWidth )
, m_radio_user( NULL )
, m_radio_cwd( NULL )
{
wxStaticBoxSizer& s_boxer = *new wxStaticBoxSizer( wxVERTICAL, this, _( "Usermode Selection" ) );
AddStaticText( s_boxer, pxE( ".Panels:Usermode:Explained",
const wxString usermodeExplained( pxE( ".Panels:Usermode:Explained",
L"Please select your preferred default location for PCSX2 user-level documents below "
L"(includes memory cards, screenshots, settings, and savestates). "
L"These folder locations can be overridden at any time using the Core Settings panel."
) );
const wxString usermodeWarning( pxE( ".Panels:Usermode:Warning",
L"You can change the preferred default location for PCSX2 user-level documents here "
L"(includes memory cards, screenshots, settings, and savestates). "
L"This option only affects Standard Paths which are set to use the installation default value."
) );
wxStaticBoxSizer& s_boxer = *new wxStaticBoxSizer( wxVERTICAL, this, _( "Usermode Selection" ) );
AddStaticText( s_boxer, isFirstTime ? usermodeExplained : usermodeWarning );
m_radio_user = &AddRadioButton( s_boxer, _("User Documents (recommended)"), _("Location: ") + wxStandardPaths::Get().GetDocumentsDir() );
s_boxer.AddSpacer( 4 );
m_radio_cwd = &AddRadioButton( s_boxer, _("Current working folder (intended for developer use only)"), _("Location: ") + wxGetCwd() );
m_radio_cwd = &AddRadioButton( s_boxer, _("Current working folder (intended for developer use only)"), _("Location: ") + wxGetCwd(),
_("This setting requires administration privlidges from your operating system.") );
s_boxer.AddSpacer( 4 );
SetSizerAndFit( &s_boxer );
@ -108,12 +138,13 @@ void Panels::UsermodeSelectionPanel::Apply( AppConfig& conf )
{
if( !m_radio_cwd->GetValue() && !m_radio_user->GetValue() )
throw Exception::CannotApplySettings( this, wxLt( "You must select one of the available user modes before proceeding." ) );
conf.UseAdminMode = m_radio_cwd->GetValue();
g_ApplyState.UseAdminMode = m_radio_cwd->GetValue();
}
// -----------------------------------------------------------------------
Panels::LanguageSelectionPanel::LanguageSelectionPanel( wxWindow* parent, int idealWidth ) :
BaseApplicableConfigPanel( parent, idealWidth )
Panels::LanguageSelectionPanel::LanguageSelectionPanel( wxWindow& parent, int idealWidth ) :
BaseApplicableConfigPanel( &parent, idealWidth )
, m_langs()
, m_picker( NULL )
{

View File

@ -25,15 +25,27 @@
using namespace wxHelpers;
static const int BetweenFolderSpace = 5;
static wxString GetNormalizedConfigFolder( FoldersEnum_t folderId )
{
const bool isDefault = g_Conf->Folders.IsDefault( folderId );
wxDirName normalized( isDefault ? g_Conf->Folders[folderId] : PathDefs::Get(folderId) );
normalized.Normalize( wxPATH_NORM_ALL );
return normalized.ToString();
}
// Pass me TRUE if the default path is to be used, and the DirPcikerCtrl disabled from use.
void Panels::PathsPanel::DirPickerPanel::UpdateCheckStatus( bool someNoteworthyBoolean )
void Panels::DirPickerPanel::UpdateCheckStatus( bool someNoteworthyBoolean )
{
m_pickerCtrl->Enable( !someNoteworthyBoolean );
if( someNoteworthyBoolean )
m_pickerCtrl->SetPath( PathDefs::Get( m_FolderId ).ToString() );
{
wxDirName normalized( PathDefs::Get( m_FolderId ) );
normalized.Normalize( wxPATH_NORM_ALL );
m_pickerCtrl->SetPath( normalized.ToString() );
}
}
void Panels::PathsPanel::DirPickerPanel::UseDefaultPath_Click(wxCommandEvent &event)
void Panels::DirPickerPanel::UseDefaultPath_Click(wxCommandEvent &event)
{
wxASSERT( m_pickerCtrl != NULL && m_checkCtrl != NULL );
UpdateCheckStatus( m_checkCtrl->IsChecked() );
@ -43,47 +55,50 @@ void Panels::PathsPanel::DirPickerPanel::UseDefaultPath_Click(wxCommandEvent &ev
// If initPath is NULL, then it's assumed the default folder is to be used, which is
// obtained from invoking the specified getDefault() function.
//
Panels::PathsPanel::DirPickerPanel::DirPickerPanel( wxWindow* parent, FoldersEnum_t folderid,
Panels::DirPickerPanel::DirPickerPanel( wxWindow* parent, FoldersEnum_t folderid,
const wxString& label, const wxString& dialogLabel ) :
BaseApplicableConfigPanel( parent, wxDefaultCoord )
, m_FolderId( folderid )
{
const bool isDefault = g_Conf->Folders.IsDefault( m_FolderId );
wxDirName normalized( isDefault ? g_Conf->Folders[m_FolderId] : PathDefs::Get(m_FolderId) );
normalized.Normalize();
wxStaticBoxSizer& s_box = *new wxStaticBoxSizer( wxVERTICAL, this, label );
// Force the Dir Picker to use a text control. This isn't standard on Linux/GTK but it's much
// more usable, so to hell with standards.
m_pickerCtrl = new wxDirPickerCtrl( this, wxID_ANY, normalized.ToString(), dialogLabel,
m_pickerCtrl = new wxDirPickerCtrl( this, wxID_ANY, GetNormalizedConfigFolder( m_FolderId ), dialogLabel,
wxDefaultPosition, wxDefaultSize, wxDIRP_USE_TEXTCTRL | wxDIRP_DIR_MUST_EXIST
);
s_box.Add( m_pickerCtrl, wxSizerFlags().Border(wxLEFT | wxRIGHT | wxTOP, 5).Expand() );
m_checkCtrl = &AddCheckBox( s_box, _("Use installation default setting") );
const bool isDefault = g_Conf->Folders.IsDefault( m_FolderId );
m_checkCtrl->SetValue( isDefault );
UpdateCheckStatus( isDefault );
SetSizerAndFit( &s_box );
Connect( m_checkCtrl->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PathsPanel::DirPickerPanel::UseDefaultPath_Click ) );
Connect( m_checkCtrl->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DirPickerPanel::UseDefaultPath_Click ) );
}
void Panels::PathsPanel::DirPickerPanel::Apply( AppConfig& conf )
void Panels::DirPickerPanel::Reset()
{
m_pickerCtrl->SetPath( GetNormalizedConfigFolder( m_FolderId ) );
}
void Panels::DirPickerPanel::Apply( AppConfig& conf )
{
conf.Folders.Set( m_FolderId, m_pickerCtrl->GetPath(), m_checkCtrl->GetValue() );
}
// ------------------------------------------------------------------------
Panels::PathsPanel::MyBasePanel::MyBasePanel( wxWindow& parent, int idealWidth ) :
Panels::BasePathsPanel::BasePathsPanel( wxWindow& parent, int idealWidth ) :
wxPanelWithHelpers( &parent, idealWidth-12 )
, s_main( *new wxBoxSizer( wxVERTICAL ) )
{
}
Panels::PathsPanel::DirPickerPanel& Panels::PathsPanel::MyBasePanel::AddDirPicker( wxBoxSizer& sizer,
Panels::DirPickerPanel& Panels::BasePathsPanel::AddDirPicker( wxBoxSizer& sizer,
FoldersEnum_t folderid, const wxString& label, const wxString& popupLabel )
{
DirPickerPanel* dpan = new DirPickerPanel( this, folderid, label, popupLabel );
@ -92,8 +107,8 @@ Panels::PathsPanel::DirPickerPanel& Panels::PathsPanel::MyBasePanel::AddDirPicke
}
// ------------------------------------------------------------------------
Panels::PathsPanel::StandardPanel::StandardPanel( wxWindow& parent ) :
MyBasePanel( parent )
Panels::StandardPathsPanel::StandardPathsPanel( wxWindow& parent ) :
BasePathsPanel( parent )
{
// TODO : Replace the callback mess here with the new FolderId enumeration setup. :)
@ -146,56 +161,77 @@ Panels::PathsPanel::StandardPanel::StandardPanel( wxWindow& parent ) :
}
// ------------------------------------------------------------------------
Panels::PathsPanel::AdvancedPanel::AdvancedPanel( wxWindow& parent, int idealWidth ) :
MyBasePanel( parent, idealWidth-9 )
Panels::AdvancedPathsPanel::AdvancedPathsPanel( wxWindow& parent, int idealWidth ) :
BasePathsPanel( parent, idealWidth-9 )
, m_dirpick_plugins(
AddDirPicker( s_main, FolderId_Plugins,
_("Plugins folder:"),
_("Select a PCSX2 plugins folder")
)
)
, m_dirpick_settings( (
s_main.AddSpacer( BetweenFolderSpace ),
AddDirPicker( s_main, FolderId_Settings,
_("Settings folder:"),
_("Select location to save PCSX2 settings to")
)
) )
{
wxStaticBoxSizer& advanced = *new wxStaticBoxSizer( wxVERTICAL, this, _("Advanced") );
AddStaticText( advanced, pxE( ".Panels:Folders:Advanced",
L"Warning!! These advanced options are provided for developers and advanced testers only. "
L"Changing these settings can cause program errors, so please be weary."
m_dirpick_plugins.SetToolTip( pxE( ".Tooltips:Folders:Plugins",
L"This is the location where PCSX2 will expect to find its plugins. Plugins found in this folder "
L"will be enumerated and are selectable from the Plugins panel."
) );
AddDirPicker( advanced, FolderId_Plugins,
_("Plugins:"),
_("Select folder for PCSX2 plugins") ).
SetToolTip( pxE( ".Tooltips:Folders:Plugins",
L"This is the location where PCSX2 will expect to find its plugins. Plugins found in this folder "
L"will be enumerated and are selectable from the Plugins panel."
) );
advanced.AddSpacer( BetweenFolderSpace );
AddDirPicker( advanced, FolderId_Settings,
_("Settings:"),
_("Select a folder for PCSX2 settings/inis") ).
SetToolTip( pxE( ".Tooltips:Folders:Settings",
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."
) );
advanced.AddSpacer( 4 );
advanced.Add( new UsermodeSelectionPanel( this, GetIdealWidth()-9 ), SizerFlags::SubGroup() );
s_main.Add( &advanced, SizerFlags::SubGroup() );
s_main.AddSpacer( 5 );
m_dirpick_settings.SetToolTip( pxE( ".Tooltips:Folders:Settings",
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."
) );
SetSizerAndFit( &s_main );
}
void Panels::AdvancedPathsPanel::Reset()
{
m_dirpick_plugins.Reset();
m_dirpick_settings.Reset();
}
// ------------------------------------------------------------------------
Panels::PathsPanel::PathsPanel( wxWindow& parent, int idealWidth ) :
Panels::TabbedPathsPanel::TabbedPathsPanel( wxWindow& parent, int idealWidth ) :
BaseApplicableConfigPanel( &parent, idealWidth )
{
wxBoxSizer& s_main = *new wxBoxSizer( wxVERTICAL );
wxNotebook& notebook = *new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_BOTTOM | wxNB_FIXEDWIDTH );
notebook.AddPage( new StandardPanel( notebook ), _("Standard") );
notebook.AddPage( new AdvancedPanel( notebook, GetIdealWidth() ), _("Advanced") );
StandardPathsPanel& stah( *new StandardPathsPanel( notebook ) );
AdvancedPathsPanel& apah( *new AdvancedPathsPanel( notebook, GetIdealWidth() ) );
notebook.AddPage( &stah, _("Standard") );
notebook.AddPage( &apah, _("Advanced") );
// Advanced Tab uses the Advanced Panel with some extra features.
// This is because the extra features are not present on the Wizard version of the Advanced Panel.
wxStaticBoxSizer& advanced = *new wxStaticBoxSizer( wxVERTICAL, this, _("Advanced") );
AddStaticText( advanced, pxE( ".Panels:Folders:Advanced",
L"Warning!! These advanced options are provided for developers and advanced testers only. "
L"Changing these settings can cause program errors and may require administration privlidges, "
L"so please be weary."
) );
advanced.Add( new UsermodeSelectionPanel( *this, GetIdealWidth()-9 ), SizerFlags::SubGroup() );
advanced.AddSpacer( 4 );
advanced.Add( &apah.Sizer(), SizerFlags::SubGroup() );
apah.SetSizer( &advanced, false );
apah.Fit();
s_main.Add( &notebook, SizerFlags::StdSpace() );
SetSizerAndFit( &s_main );
}
void Panels::PathsPanel::Apply( AppConfig& conf )
void Panels::TabbedPathsPanel::Apply( AppConfig& conf )
{
}

View File

@ -17,6 +17,7 @@
*/
#include "PrecompiledHeader.h"
#include "Utilities/ScopedPtr.h"
#include "Plugins.h"
#include "ConfigurationPanels.h"
#include "ps2/BiosTools.h"
@ -117,9 +118,9 @@ public:
static const wxString failed_separator( L"-------- Unsupported Plugins --------" );
// ------------------------------------------------------------------------
Panels::PluginSelectorPanel::StatusPanel::StatusPanel( wxWindow* parent, int pluginCount, __unused int biosCount ) :
Panels::PluginSelectorPanel::StatusPanel::StatusPanel( wxWindow* parent ) :
wxPanelWithHelpers( parent )
, m_gauge( *new wxGauge( this, wxID_ANY, pluginCount ) )
, m_gauge( *new wxGauge( this, wxID_ANY, 10 ) )
, m_label( *new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE | wxST_NO_AUTORESIZE ) )
, m_progress( 0 )
{
@ -132,6 +133,11 @@ Panels::PluginSelectorPanel::StatusPanel::StatusPanel( wxWindow* parent, int plu
SetSizerAndFit( &s_main );
}
void Panels::PluginSelectorPanel::StatusPanel::SetGaugeLength( int len )
{
m_gauge.SetRange( len );
}
void Panels::PluginSelectorPanel::StatusPanel::AdvanceProgress( const wxString& msg )
{
m_label.SetLabel( msg );
@ -183,15 +189,14 @@ void Panels::PluginSelectorPanel::ComboBoxPanel::Reset()
// ------------------------------------------------------------------------
Panels::PluginSelectorPanel::PluginSelectorPanel( wxWindow& parent, int idealWidth ) :
BaseApplicableConfigPanel( &parent, idealWidth )
, m_FileList()
, m_StatusPanel( *new StatusPanel( this,
wxDir::GetAllFiles( g_Conf->Folders.Plugins.ToString(), &m_FileList, wxsFormat( L"*%s", wxDynamicLibrary::GetDllExt()), wxDIR_FILES ),
wxDir::GetAllFiles( g_Conf->Folders.Bios.ToString(), &m_BiosList, L"*.bin", wxDIR_FILES )
) )
, m_FileList( NULL )
, m_BiosList( NULL )
, m_StatusPanel( *new StatusPanel( this ) )
, m_ComponentBoxes( *new ComboBoxPanel( this ) )
, m_Uninitialized( true )
, m_EnumeratorThread( NULL )
{
//ValidateEnumerationStatus();
wxBoxSizer& s_main = *new wxBoxSizer( wxVERTICAL );
s_main.Add( &m_ComponentBoxes, SizerFlags::StdExpand().ReserveSpaceEvenIfHidden() );
@ -208,7 +213,7 @@ Panels::PluginSelectorPanel::PluginSelectorPanel( wxWindow& parent, int idealWid
SetSizerAndFit( &s_main );
Connect( GetId(), wxEVT_SHOW, wxShowEventHandler( PluginSelectorPanel::OnShow ) );
Connect( GetId(), wxEVT_SHOW, wxShowEventHandler( PluginSelectorPanel::OnShow ) );
Connect( wxEVT_EnumeratedNext, wxCommandEventHandler( PluginSelectorPanel::OnProgress ) );
Connect( wxEVT_EnumerationFinished, wxCommandEventHandler( PluginSelectorPanel::OnEnumComplete ) );
@ -222,6 +227,8 @@ Panels::PluginSelectorPanel::~PluginSelectorPanel()
// Kill the thread if it's alive.
safe_delete( m_EnumeratorThread );
safe_delete( m_FileList );
safe_delete( m_BiosList );
}
void Panels::PluginSelectorPanel::Apply( AppConfig& conf )
@ -247,7 +254,7 @@ void Panels::PluginSelectorPanel::Apply( AppConfig& conf )
);
}
wxFileName relative( m_FileList[(int)m_ComponentBoxes.Get(i).GetClientData(sel)] );
wxFileName relative( GetFilename((int)m_ComponentBoxes.Get(i).GetClientData(sel)) );
relative.MakeRelativeTo( g_Conf->Folders.Plugins.ToString() );
conf.BaseFilenames.Plugins[tbl_PluginInfo[i].id] = relative.GetFullPath();
}
@ -266,15 +273,13 @@ void Panels::PluginSelectorPanel::Apply( AppConfig& conf )
)
);
}
wxFileName relative( m_BiosList[(int)m_ComponentBoxes.GetBios().GetClientData(sel)] );
wxFileName relative( (*m_BiosList)[(int)m_ComponentBoxes.GetBios().GetClientData(sel)] );
relative.MakeRelativeTo( g_Conf->Folders.Bios.ToString() );
conf.BaseFilenames.Bios = relative.GetFullPath();
}
void Panels::PluginSelectorPanel::DoRefresh()
{
m_Uninitialized = false;
// Disable all controls until enumeration is complete.
m_ComponentBoxes.Hide();
@ -284,22 +289,64 @@ void Panels::PluginSelectorPanel::DoRefresh()
safe_delete( m_EnumeratorThread );
m_EnumeratorThread = new EnumThread( *this );
m_EnumeratorThread->Start();
m_ComponentBoxes.Reset();
}
bool Panels::PluginSelectorPanel::ValidateEnumerationStatus()
{
bool validated = true;
// re-enumerate plugins and bioses, and if anything changed then we need to wipe
// the contents of the combo boxes and re-enumerate everything.
// Impl Note: ScopedPtr used so that resources get cleaned up if an exception
// occurs during file enumeration.
wxScopedPtr<wxArrayString> pluginlist( new wxArrayString() );
wxScopedPtr<wxArrayString> bioslist( new wxArrayString() );
int pluggers = EnumeratePluginsFolder( pluginlist.get() );
if( g_Conf->Folders.Bios.Exists() )
wxDir::GetAllFiles( g_Conf->Folders.Bios.ToString(), bioslist.get(), L"*.bin", wxDIR_FILES );
if( (m_FileList == NULL) || (*pluginlist != *m_FileList) )
validated = false;
if( (m_BiosList == NULL) || (*bioslist != *m_BiosList) )
validated = false;
delete m_FileList;
delete m_BiosList;
m_FileList = pluginlist.release();
m_BiosList = bioslist.release();
m_StatusPanel.SetGaugeLength( pluggers );
return validated;
}
// ------------------------------------------------------------------------
// This overload of OnShow is invoked by wizards, since the wxWizard won't raise
// SHOW events. >_< (only called for show events and not hide events)
void Panels::PluginSelectorPanel::OnShow()
{
if( !ValidateEnumerationStatus() )
DoRefresh();
}
void Panels::PluginSelectorPanel::OnShow( wxShowEvent& evt )
{
evt.Skip();
if( !evt.GetShow() ) return;
if( !m_Uninitialized ) return;
DoRefresh();
OnShow();
}
void Panels::PluginSelectorPanel::OnRefresh( wxCommandEvent& evt )
{
m_ComponentBoxes.Reset();
ValidateEnumerationStatus();
DoRefresh();
}
@ -314,13 +361,13 @@ void Panels::PluginSelectorPanel::OnEnumComplete( wxCommandEvent& evt )
wxFileName right( g_Conf->FullpathToBios() );
right.MakeRelativeTo( g_Conf->Folders.Plugins.ToString() );
for( size_t i=0; i<m_BiosList.GetCount(); ++i )
for( size_t i=0; i<m_BiosList->GetCount(); ++i )
{
wxString description;
if( !IsBIOS(m_BiosList[i], description) ) continue;
if( !IsBIOS((*m_BiosList)[i], description) ) continue;
int sel = m_ComponentBoxes.GetBios().Append( description, (void*)i );
wxFileName left( m_BiosList[i] );
wxFileName left( (*m_BiosList)[i] );
left.MakeRelativeTo( g_Conf->Folders.Plugins.ToString() );
if( left == right )
@ -358,15 +405,15 @@ void Panels::PluginSelectorPanel::OnEnumComplete( wxCommandEvent& evt )
void Panels::PluginSelectorPanel::OnProgress( wxCommandEvent& evt )
{
size_t evtidx = evt.GetExtraLong();
m_StatusPanel.AdvanceProgress( (evtidx < m_FileList.Count()-1) ?
m_FileList[evtidx + 1] : wxString(_("Completing tasks..."))
m_StatusPanel.AdvanceProgress( (evtidx < m_FileList->Count()-1) ?
(*m_FileList)[evtidx + 1] : wxString(_("Completing tasks..."))
);
EnumeratedPluginInfo& result( m_EnumeratorThread->Results[evtidx] );
if( result.TypeMask == 0 )
{
Console::Error( L"Some kinda plugin failure: " + m_FileList[evtidx] );
Console::Error( L"Some kinda plugin failure: " + (*m_FileList)[evtidx] );
}
for( int i=0; i<NumPluginTypes; ++i )
@ -376,11 +423,11 @@ void Panels::PluginSelectorPanel::OnProgress( wxCommandEvent& evt )
if( result.PassedTest & tbl_PluginInfo[i].typemask )
{
int sel = m_ComponentBoxes.Get(i).Append( wxsFormat( L"%s %s [%s]",
result.Name.c_str(), result.Version[i].c_str(), Path::GetFilenameWithoutExt( m_FileList[evtidx] ).c_str() ),
result.Name.c_str(), result.Version[i].c_str(), Path::GetFilenameWithoutExt( (*m_FileList)[evtidx] ).c_str() ),
(void*)evtidx
);
wxFileName left( m_FileList[evtidx] );
wxFileName left( (*m_FileList)[evtidx] );
wxFileName right( g_Conf->FullpathTo(tbl_PluginInfo[i].id) );
left.MakeRelativeTo( g_Conf->Folders.Plugins.ToString() );

View File

@ -21,6 +21,8 @@
#include "MainFrame.h"
#include "Dialogs/ModalPopups.h"
#include "Utilities/ScopedPtr.h"
#include "Resources/EmbeddedImage.h"
#include "Resources/BackgroundLogo.h"
@ -28,6 +30,7 @@
IMPLEMENT_APP(Pcsx2App)
bool UseAdminMode = false;
AppConfig* g_Conf = NULL;
wxFileHistory* g_RecentIsoList = NULL;
CoreEmuThread* g_EmuThread = NULL;
@ -62,64 +65,34 @@ Pcsx2App::Pcsx2App() :
wxFrame* Pcsx2App::GetMainWindow() const { return m_MainFrame; }
wxFileConfig* OpenConfig( const wxString& filename )
{
return new wxFileConfig( wxEmptyString, wxEmptyString, filename, wxEmptyString, wxCONFIG_USE_RELATIVE_PATH );
}
void Pcsx2App::ReadUserModeSettings()
{
wxFileName usermodefile( FilenameDefs::GetUsermodeConfig() );
usermodefile.SetPath( wxGetCwd() );
wxFileConfig* conf_usermode = OpenConfig( usermodefile.GetFullPath() );
wxScopedPtr<wxFileConfig> conf_usermode( OpenFileConfig( usermodefile.GetFullPath() ) );
if( !wxFile::Exists( usermodefile.GetFullPath() ) )
{
// first time startup, so give the user the choice of user mode:
if( Dialogs::PickUserModeDialog( NULL ).ShowModal() == wxID_CANCEL )
throw Exception::StartupAborted( L"Startup aborted: User cancelled Usermode selection." );
//if( Dialogs::PickUserModeDialog( NULL ).ShowModal() == wxID_CANCEL )
FirstTimeWizard wiz( NULL );
if( !wiz.RunWizard( wiz.GetFirstPage() ) )
throw Exception::StartupAborted( L"Startup aborted: User canceled FirstTime Wizard." );
// Save user's new settings
if( conf_usermode != NULL )
{
IniSaver saver( *conf_usermode );
g_Conf->LoadSaveUserMode( saver );
}
IniSaver saver( *conf_usermode );
g_Conf->LoadSaveUserMode( saver );
g_Conf->Save();
}
else
{
// usermode.ini exists -- assume Documents mode, unless the ini explicitly
// specifies otherwise.
g_Conf->UseAdminMode = false;
UseAdminMode = false;
if( conf_usermode != NULL )
{
IniLoader loader( *conf_usermode );
g_Conf->LoadSaveUserMode( loader );
}
IniLoader loader( *conf_usermode );
g_Conf->LoadSaveUserMode( loader );
}
safe_delete( conf_usermode );
}
// ------------------------------------------------------------------------
// returns true if a configuration file is present in the current working dir (cwd).
// returns false if not (in which case the calling code should fall back on using OpenConfigUserLocal())
//
bool Pcsx2App::TryOpenConfigCwd()
{
ReadUserModeSettings();
wxDirName inipath_cwd( (wxDirName)wxGetCwd() + PathDefs::Base::Settings() );
if( !inipath_cwd.IsReadable() ) return false;
wxString inifile_cwd( Path::Combine( inipath_cwd, FilenameDefs::GetConfig() ) );
if( !Path::IsFile( inifile_cwd ) ) return false;
if( Path::GetFileSize( inifile_cwd ) <= 1 ) return false;
wxConfigBase::Set( OpenConfig( inifile_cwd ) );
return true;
}
void Pcsx2App::OnInitCmdLine( wxCmdLineParser& parser )
@ -184,20 +157,9 @@ bool Pcsx2App::OnInit()
try
{
if( !TryOpenConfigCwd() )
{
PathDefs::GetDocuments().Mkdir();
PathDefs::GetSettings().Mkdir();
ReadUserModeSettings();
// Allow wx to use our config, and enforces auto-cleanup as well
wxString confile( Path::Combine( PathDefs::GetSettings(), FilenameDefs::GetConfig() ) );
wxConfigBase::Set( OpenConfig( confile ) );
wxConfigBase::Get()->SetRecordDefaults();
}
g_Conf->Load();
g_Conf->Apply();
g_Conf->Folders.Logs.Mkdir();
AppConfig_ReloadGlobalSettings();
m_MainFrame = new MainEmuFrame( NULL, L"PCSX2" );
m_ProgramLogBox = new ConsoleLogFrame( m_MainFrame, L"PCSX2 Program Log", g_Conf->ProgLogBox );
@ -216,24 +178,6 @@ bool Pcsx2App::OnInit()
return false;
}
// Check to see if the user needs to perform initial setup:
/*bool needsConfigured = false;
const wxString pc( L"Please Configure" );
for( int pidx=0; pidx<Plugin_Count; ++pidx )
{
if( g_Conf->BaseFilenames[(PluginsEnum_t)pidx] == pc )
{
needsConfigured = true;
break;
}
}
if( needsConfigured )
{
Dialogs::ConfigurationDialog( m_MainFrame ).ShowModal();
}*/
Connect( pxEVT_MSGBOX, wxCommandEventHandler( Pcsx2App::OnMessageBox ) );
return true;

View File

@ -47,6 +47,18 @@ struct romdir
u32 BiosVersion; // Used in Memory, Misc, CDVD
// Returns a string message telling the user to consult guides for obtaining a legal BIOS.
// This message is in a function because it's used as part of several dialogs in PCSX2 (there
// are multiple variations on the BIOS and BIOS folder checks).
wxString BIOS_GetMsg_Required()
{
return pxE( ".Popup:BiosDumpRequired",
L"PCSX2 requires a PS2 BIOS in order to run. For legal reasons, you *must* obtain \n"
L"a BIOS from an actual PS2 unit that you own (borrowing doesn't count).\n"
L"Please consult the FAQs and Guides for further instructions."
);
}
// Returns the version information of the bios currently loaded into memory.
static u32 GetBiosVersion()
{
@ -152,11 +164,8 @@ void LoadBIOS()
throw Exception::FileNotFound( Bios,
L"Configured Bios file does not exist",
pxE( ".Error:BiosNotFound",
L"The configured BIOS file does not exist, or no BIOS has been configured.\n\n"
L"PCSX2 requires a PS2 BIOS to run; and the BIOS *must* be obtained from an actual PS2 unit\n"
L"that you own (borrowing doesn't count). Please consult the FAQs and Guides for further instructions."
)
_("The configured BIOS file does not exist, or no BIOS has been configured.\n\n") +
BIOS_GetMsg_Required()
);
}
@ -189,9 +198,8 @@ bool IsBIOS(const wxString& filename, wxString& description)
break; // found romdir
}
if ((strcmp(rd.fileName, "RESET") != 0) || (rd.fileSize == 0)) {
if ((strcmp(rd.fileName, "RESET") != 0) || (rd.fileSize == 0))
return FALSE; //Unable to locate ROMDIR structure in file or a ioprpXXX.img
}
bool found = false;
@ -242,13 +250,13 @@ bool IsBIOS(const wxString& filename, wxString& description)
if (fp.Read( &rd, DIRENTRY_SIZE ) != DIRENTRY_SIZE) break;
}
fileOffset-=((rd.fileSize + 0x10) & 0xfffffff0) - rd.fileSize;
fileOffset -= ((rd.fileSize + 0x10) & 0xfffffff0) - rd.fileSize;
if (found)
{
if ( biosFileSize < (int)fileOffset)
{
description << ((biosFileSize*100)/(int)fileOffset) << L"%";
description += wxsFormat( L" %d%%", ((biosFileSize*100) / (int)fileOffset) );
// we force users to have correct bioses,
// not that lame scph10000 of 513KB ;-)
}

View File

@ -20,5 +20,6 @@
extern u32 BiosVersion; // Used by CDVD
extern wxString BIOS_GetMsg_Required();
extern void LoadBIOS();
extern bool IsBIOS(const wxString& filename, wxString& description);

View File

@ -1989,6 +1989,10 @@
RelativePath="..\..\gui\Dialogs\ConfigurationDialog.h"
>
</File>
<File
RelativePath="..\..\gui\Dialogs\FirstTimeWizard.cpp"
>
</File>
<File
RelativePath="..\..\gui\Dialogs\LogOptionsDialog.cpp"
>

View File

@ -117,6 +117,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxAdv28", "3rdparty\wxWidge
{C34487AF-228A-4D11-8E50-27803DF76873} = {C34487AF-228A-4D11-8E50-27803DF76873}
EndProjectSection
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\scopedarray.h = common\include\wx\scopedarray.h
common\include\wx\scopedptr.h = common\include\wx\scopedptr.h
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@ -601,6 +608,7 @@ Global
{0FADC26C-0E9D-4DD7-84B1-BF4F7754E90C} = {88F517F9-CE1C-4005-9BDF-4481FEB55053}
{A51123F5-9505-4EAE-85E7-D320290A272C} = {88F517F9-CE1C-4005-9BDF-4481FEB55053}
{4639972E-424E-4E13-8B07-CA403C481346} = {88F517F9-CE1C-4005-9BDF-4481FEB55053}
{62BF822E-6A12-49A8-BE8C-C55A9BCA24DA} = {0FADC26C-0E9D-4DD7-84B1-BF4F7754E90C}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
AMDCaProjectFile = E:\devpcsx2\fail\wx\CodeAnalyst\pcsx2_suite_2008.caw