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 #define wxUSE_SPLASH 1
// wizards // wizards
#define wxUSE_WIZARDDLG 0 #define wxUSE_WIZARDDLG 1
// Compile in wxAboutBox() function showing the standard "About" dialog. // Compile in wxAboutBox() function showing the standard "About" dialog.
// //

View File

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

View File

@ -173,10 +173,10 @@
// //
#ifdef _MSC_VER #ifdef _MSC_VER
# define PCSX2_ALIGNED(alig,x) __declspec(align(alig)) x # define PCSX2_ALIGNED(alig,x) __declspec(align(alig)) x
# define PCSX2_ALIGNED_EXTERN(alig,x) extern __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(x) __declspec(align(16)) x
# define PCSX2_ALIGNED16_EXTERN(x) extern __declspec(align(16)) x # define PCSX2_ALIGNED16_EXTERN(x) extern __declspec(align(16)) x
# define __naked __declspec(naked) # define __naked __declspec(naked)
# define __unused /*unused*/ # define __unused /*unused*/

View File

@ -31,39 +31,31 @@ extern void pcsx2_aligned_free(void* pmem);
# define _aligned_realloc pcsx2_aligned_realloc # define _aligned_realloc pcsx2_aligned_realloc
#endif #endif
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Safe deallocation macros -- always check pointer validity (non-null) // Safe deallocation macros -- checks pointer validity (non-null) when needed, and sets
// and set pointer to null on deallocation. // pointer to null after deallocation.
#define safe_delete( ptr ) \ #define safe_delete( ptr ) \
if( ptr != NULL ) { \ ((void) (delete ptr), ptr = NULL)
delete ptr; \
ptr = NULL; \
}
#define safe_delete_array( ptr ) \ #define safe_delete_array( ptr ) \
if( ptr != NULL ) { \ ((void) (delete[] ptr), ptr = NULL)
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 ) \ #define safe_free( ptr ) \
if( ptr != NULL ) { \ ((void) (( ( ptr != NULL ) && (free( ptr ), !!0) ), ptr = NULL))
free( ptr ); \
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 ) \ #define safe_aligned_free( ptr ) \
if( ptr != NULL ) { \ ((void) ( _aligned_free( ptr ), ptr = NULL ))
_aligned_free( ptr ); \
ptr = NULL; \
}
#define SafeSysMunmap( ptr, size ) \ #define SafeSysMunmap( ptr, size ) \
if( ptr != NULL ) { \ ((void) ( HostSys::Munmap( (uptr)ptr, size ), ptr = NULL ))
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. // equality operators.
#define OpEqu( field ) (field == right.field) #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 --------------- //------------ DEFAULT sseMXCSR VALUES ---------------
#define DEFAULT_sseMXCSR 0xffc0 //FPU rounding > DaZ, FtZ, "chop" #define DEFAULT_sseMXCSR 0xffc0 //FPU rounding > DaZ, FtZ, "chop"
#define DEFAULT_sseVUMXCSR 0xffc0 //VU rounding > DaZ, FtZ, "chop" #define DEFAULT_sseVUMXCSR 0xffc0 //VU rounding > DaZ, FtZ, "chop"
@ -58,72 +65,57 @@ class Pcsx2Config
public: public:
struct ProfilerOptions struct ProfilerOptions
{ {
union BITFIELD32()
{ bool
struct Enabled:1, // universal toggle for the profiler.
{ RecBlocks_EE:1, // Enables per-block profiling for the EE recompiler [unimplemented]
bool RecBlocks_IOP:1, // Enables per-block profiling for the IOP recompiler [unimplemented]
Enabled:1, // universal toggle for the profiler. RecBlocks_VU0:1, // Enables per-block profiling for the VU0 recompiler [unimplemented]
RecBlocks_EE:1, // Enables per-block profiling for the EE recompiler [unimplemented] RecBlocks_VU1:1; // Enables per-block profiling for the VU1 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 ) {}
// Default is Disabled, with all recs enabled underneath.
ProfilerOptions() : bitset( 0xfffffffe ) {}
void LoadSave( IniInterface& conf ); void LoadSave( IniInterface& conf );
bool operator ==( const ProfilerOptions& right ) const bool operator ==( const ProfilerOptions& right ) const
{ {
return OpEqu( bits ); return OpEqu( bitset );
} }
bool operator !=( const ProfilerOptions& right ) const bool operator !=( const ProfilerOptions& right ) const
{ {
return !this->operator ==( right ); return !OpEqu( bitset );
} }
}; };
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
struct RecompilerOptions struct RecompilerOptions
{ {
union BITFIELD32()
{ bool
struct EnableEE:1,
{ EnableIOP:1,
bool EnableVU0:1,
EnableEE:1, EnableVU1:1;
EnableIOP:1,
EnableVU0:1, bool
EnableVU1:1; UseMicroVU0:1,
UseMicroVU1:1;
bool }; };
UseMicroVU0:1,
UseMicroVU1:1;
};
u8 bits;
};
RecompilerOptions() : bits( 0 ) { } // All recs are enabled by default.
RecompilerOptions() : bitset( 0xffffffff ) { }
void Load( const wxString& srcfile );
void Load( const wxInputStream& srcstream );
void Save( const wxString& dstfile );
void Save( const wxOutputStream& deststream );
void LoadSave( IniInterface& conf ); void LoadSave( IniInterface& conf );
bool operator ==( const RecompilerOptions& right ) const bool operator ==( const RecompilerOptions& right ) const
{ {
return OpEqu( bits ); return OpEqu( bitset );
} }
bool operator !=( const RecompilerOptions& right ) const bool operator !=( const RecompilerOptions& right ) const
{ {
return !this->operator ==( right ); return !OpEqu( bitset );
} }
} Recompiler; } Recompiler;
@ -136,38 +128,27 @@ public:
u32 sseMXCSR; u32 sseMXCSR;
u32 sseVUMXCSR; u32 sseVUMXCSR;
struct BITFIELD32()
{ bool
union vuOverflow:1,
{ vuExtraOverflow:1,
bool vuSignOverflow:1,
vuOverflow:1, vuUnderflow:1;
vuExtraOverflow:1,
vuSignOverflow:1, bool
vuUnderflow:1; fpuOverflow:1,
fpuExtraOverflow:1,
bool fpuFullMode:1;
fpuOverflow:1, }; };
fpuExtraOverflow:1,
fpuFullMode:1;
};
u8 bits;
};
CpuOptions() :
sseMXCSR( DEFAULT_sseMXCSR )
, sseVUMXCSR( DEFAULT_sseVUMXCSR )
, bits( 0 )
{
}
CpuOptions();
void LoadSave( IniInterface& conf ); void LoadSave( IniInterface& conf );
bool operator ==( const CpuOptions& right ) const bool operator ==( const CpuOptions& right ) const
{ {
return return
OpEqu( sseMXCSR ) && OpEqu( sseVUMXCSR ) && OpEqu( sseMXCSR ) && OpEqu( sseVUMXCSR ) &&
OpEqu( bits ) && OpEqu( Recompiler ); OpEqu( bitset ) && OpEqu( Recompiler );
} }
bool operator !=( const CpuOptions& right ) const bool operator !=( const CpuOptions& right ) const
@ -193,68 +174,59 @@ public:
int ConsecutiveFrames; // number of consecutive frames (fields) to render int ConsecutiveFrames; // number of consecutive frames (fields) to render
int ConsecutiveSkip; // number of consecutive frames (fields) to skip int ConsecutiveSkip; // number of consecutive frames (fields) to skip
VideoOptions();
void LoadSave( IniInterface& conf ); void LoadSave( IniInterface& conf );
}; };
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
struct GamefixOptions struct GamefixOptions
{ {
union BITFIELD32()
{ bool
struct 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.
bool FpuCompareHack:1, // Fix for Persona games, maybe others. It's to do with the VU clip flag (again).
VuAddSubHack:1, // Fix for Tri-ace games, they use an encryption algorithm that requires VU ADDI opcode to be bit-accurate. FpuMulHack:1, // Fix for Tales of Destiny hangs.
VuClipFlagHack:1, // Fix for Digimon Rumble Arena 2, fixes spinning/hanging on intro-menu. 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.
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 ) {}
// all gamefixes are disabled by default.
GamefixOptions() : bitset( 0 ) {}
void LoadSave( IniInterface& conf ); void LoadSave( IniInterface& conf );
bool operator ==( const GamefixOptions& right ) const bool operator ==( const GamefixOptions& right ) const
{ {
return OpEqu( bits ); return OpEqu( bitset );
} }
bool operator !=( const GamefixOptions& right ) const bool operator !=( const GamefixOptions& right ) const
{ {
return !this->operator ==( right ); return !OpEqu( bitset );
} }
}; };
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
struct SpeedhackOptions struct SpeedhackOptions
{ {
union BITFIELD32()
{ bool
struct IopCycleRate_X2:1, // enables the x2 multiplier of the IOP cyclerate
{ IntcStat:1, // tells Pcsx2 to fast-forward through intc_stat waits.
int BIFC0:1, // enables BIFC0 detection and fast-forwarding
EECycleRate:2, // EE cyclerate selector (1.0, 1.5, 2.0)
VUCycleSteal:3, // VU Cycle Stealer factor (0, 1, 2, or 3) vuMinMax:1, // microVU specific MinMax hack; Can cause SPS, Black Screens, etc...
IopCycleRate_X2:1, // enables the x2 multiplier of the IOP cyclerate vuFlagHack:1; // MicroVU specific flag hack; Can cause Infinite loops, SPS, etc...
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;
};
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 ); void LoadSave( IniInterface& conf );
bool operator ==( const SpeedhackOptions& right ) const bool operator ==( const SpeedhackOptions& right ) const
{ {
return OpEqu( bits ); return OpEqu( bitset ) && OpEqu( EECycleRate ) && OpEqu( VUCycleSteal );
} }
bool operator !=( const SpeedhackOptions& right ) const bool operator !=( const SpeedhackOptions& right ) const
@ -264,18 +236,22 @@ public:
}; };
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 BITFIELD32()
bool SkipBiosSplash:1; 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) // when enabled performs bios stub execution, skipping full sony bios + splash screens
bool closeGSonEsc:1; SkipBiosSplash:1,
// enables simulated ejection of memory cards when loading savestates // Closes the GS/Video port on escape (good for fullscreen activity)
bool McdEnableEjection:1; closeGSonEsc:1,
// enables simulated ejection of memory cards when loading savestates
McdEnableEjection:1;
}; };
CpuOptions Cpu; CpuOptions Cpu;
VideoOptions Video; VideoOptions Video;
@ -283,12 +259,13 @@ public:
GamefixOptions Gamefixes; GamefixOptions Gamefixes;
ProfilerOptions Profiler; ProfilerOptions Profiler;
Pcsx2Config();
void LoadSave( IniInterface& ini );
void Load( const wxString& srcfile ); void Load( const wxString& srcfile );
void Load( const wxInputStream& srcstream ); void Load( const wxInputStream& srcstream );
void Save( const wxString& dstfile ); void Save( const wxString& dstfile );
void Save( const wxOutputStream& deststream ); void Save( const wxOutputStream& deststream );
void LoadSave( IniInterface& ini );
}; };
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////

View File

@ -19,91 +19,152 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "IniInterface.h" #include "IniInterface.h"
#include "Config.h" #include "Config.h"
#include "GS.h"
#include <wx/fileconf.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 ) void Pcsx2Config::SpeedhackOptions::LoadSave( IniInterface& ini )
{ {
SpeedhackOptions defaults;
ini.SetPath( L"Speedhacks" ); ini.SetPath( L"Speedhacks" );
IniBitfield( EECycleRate, 0 ); IniBitfield( EECycleRate );
IniBitfield( VUCycleSteal, 0 ); IniBitfield( VUCycleSteal );
IniBitBool( IopCycleRate_X2, false ); IniBitBool( IopCycleRate_X2 );
IniBitBool( IntcStat, false ); IniBitBool( IntcStat );
IniBitBool( BIFC0, false ); IniBitBool( BIFC0 );
ini.SetPath( L".." ); ini.SetPath( L".." );
} }
void Pcsx2Config::ProfilerOptions::LoadSave( IniInterface& ini ) void Pcsx2Config::ProfilerOptions::LoadSave( IniInterface& ini )
{ {
ProfilerOptions defaults;
ini.SetPath( L"Profiler" ); ini.SetPath( L"Profiler" );
IniBitBool( Enabled, false ); IniBitBool( Enabled );
IniBitBool( RecBlocks_EE, true ); IniBitBool( RecBlocks_EE );
IniBitBool( RecBlocks_IOP, true ); IniBitBool( RecBlocks_IOP );
IniBitBool( RecBlocks_VU0, true ); IniBitBool( RecBlocks_VU0 );
IniBitBool( RecBlocks_VU1, true ); IniBitBool( RecBlocks_VU1 );
ini.SetPath( L".." ); ini.SetPath( L".." );
} }
void Pcsx2Config::RecompilerOptions::LoadSave( IniInterface& ini ) void Pcsx2Config::RecompilerOptions::LoadSave( IniInterface& ini )
{ {
RecompilerOptions defaults;
ini.SetPath( L"Recompiler" ); ini.SetPath( L"Recompiler" );
IniBitBool( EnableEE, true ); IniBitBool( EnableEE );
IniBitBool( EnableIOP, true ); IniBitBool( EnableIOP );
IniBitBool( EnableVU0, true ); IniBitBool( EnableVU0 );
IniBitBool( EnableVU1, true ); IniBitBool( EnableVU1 );
ini.SetPath( L".." ); ini.SetPath( L".." );
} }
Pcsx2Config::CpuOptions::CpuOptions() :
bitset( 0 )
, sseMXCSR( DEFAULT_sseMXCSR )
, sseVUMXCSR( DEFAULT_sseVUMXCSR )
{
vuOverflow = true;
fpuOverflow = true;
}
void Pcsx2Config::CpuOptions::LoadSave( IniInterface& ini ) void Pcsx2Config::CpuOptions::LoadSave( IniInterface& ini )
{ {
CpuOptions defaults;
ini.SetPath( L"CPU" ); ini.SetPath( L"CPU" );
IniEntry( sseMXCSR, DEFAULT_sseMXCSR ); IniEntry( sseMXCSR );
IniEntry( sseVUMXCSR, DEFAULT_sseVUMXCSR ); IniEntry( sseVUMXCSR );
IniBitBool( vuOverflow, true ); IniBitBool( vuOverflow );
IniBitBool( vuExtraOverflow, false ); IniBitBool( vuExtraOverflow );
IniBitBool( vuSignOverflow, false ); IniBitBool( vuSignOverflow );
IniBitBool( vuUnderflow, false ); IniBitBool( vuUnderflow );
IniBitBool( fpuOverflow, true ); IniBitBool( fpuOverflow );
IniBitBool( fpuExtraOverflow, false ); IniBitBool( fpuExtraOverflow );
IniBitBool( fpuFullMode, false ); IniBitBool( fpuFullMode );
Recompiler.LoadSave( ini ); Recompiler.LoadSave( ini );
ini.SetPath( L".." ); 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 ) void Pcsx2Config::VideoOptions::LoadSave( IniInterface& ini )
{ {
VideoOptions defaults;
ini.SetPath( L"Video" ); 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".." ); ini.SetPath( L".." );
} }
void Pcsx2Config::GamefixOptions::LoadSave( IniInterface& ini ) 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".." ); ini.SetPath( L".." );
} }
Pcsx2Config::Pcsx2Config() :
bitset( 0 )
{
}
void Pcsx2Config::LoadSave( IniInterface& ini ) void Pcsx2Config::LoadSave( IniInterface& ini )
{ {
Pcsx2Config defaults;
ini.SetPath( L"EmuCore" ); ini.SetPath( L"EmuCore" );
IniBitBool( CdvdVerboseReads, false );
IniBitBool( CdvdDumpBlocks, false );
IniBitBool( EnablePatches, false );
IniBitBool( closeGSonEsc, false ); IniBitBool( CdvdVerboseReads );
IniBitBool( McdEnableEjection, false ); IniBitBool( CdvdDumpBlocks );
IniBitBool( EnablePatches );
IniBitBool( closeGSonEsc );
IniBitBool( McdEnableEjection );
// Process various sub-components: // Process various sub-components:

View File

@ -18,6 +18,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "Utilities/RedtapeWindows.h" #include "Utilities/RedtapeWindows.h"
#include "Utilities/ScopedPtr.h"
#include <wx/dir.h> #include <wx/dir.h>
#include <wx/file.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 VoidMethod();
typedef void CALLBACK vMeth(); // shorthand for 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 struct LegacyApi_CommonMethod

View File

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

View File

@ -95,10 +95,7 @@ namespace PathDefs
// share with other programs: screenshots, memory cards, and savestates. // share with other programs: screenshots, memory cards, and savestates.
wxDirName GetDocuments() wxDirName GetDocuments()
{ {
if( g_Conf->UseAdminMode ) return (wxDirName)g_Conf->GetDefaultDocumentsFolder();
return (wxDirName)wxGetCwd();
else
return (wxDirName)wxStandardPaths::Get().GetDocumentsDir() + (wxDirName)wxGetApp().GetAppName();
} }
wxDirName GetSnapshots() 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 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::FullpathToBios() const { return Path::Combine( Folders.Bios, BaseFilenames.Bios ); }
wxString AppConfig::FullpathToMcd( uint mcdidx ) const { return Path::Combine( Folders.MemoryCards, Mcd[mcdidx].Filename ); } 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 ) 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.Entry( L"SettingsPath", Folders.Settings, PathDefs::GetSettings() );
ini.Flush(); ini.Flush();
@ -357,18 +383,20 @@ void AppConfig::LoadSaveUserMode( IniInterface& ini )
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void AppConfig::LoadSave( IniInterface& ini ) void AppConfig::LoadSave( IniInterface& ini )
{ {
IniEntry( MainGuiPosition, wxDefaultPosition ); AppConfig defaults;
ini.EnumEntry( L"LanguageId", LanguageId );
IniEntry( RecentFileCount, 6 ); IniEntry( MainGuiPosition );
IniEntry( DeskTheme, L"default" ); ini.EnumEntry( L"LanguageId", LanguageId, NULL, defaults.LanguageId );
IniEntry( Listbook_ImageSize, 32 ); IniEntry( RecentFileCount );
IniEntry( Toolbar_ImageSize, 24 ); IniEntry( DeskTheme );
IniEntry( Toolbar_ShowLabels, true ); IniEntry( Listbook_ImageSize );
IniEntry( Toolbar_ImageSize );
IniEntry( Toolbar_ShowLabels );
// Process various sub-components: // Process various sub-components:
ProgLogBox.LoadSave( ini, L"ProgramLog" ); ProgLogBox.LoadSave( ini, L"ProgramLog" );
Ps2ConBox.LoadSave( ini, L"Ps2Console" ); Ps2ConBox.LoadSave( ini, L"Ps2Console" );
Folders.LoadSave( ini ); Folders.LoadSave( ini );
BaseFilenames.LoadSave( ini ); BaseFilenames.LoadSave( ini );
@ -391,14 +419,14 @@ void AppConfig::Apply()
// Ensure existence of necessary documents folders. Plugins and other parts // Ensure existence of necessary documents folders. Plugins and other parts
// of PCSX2 rely on them. // of PCSX2 rely on them.
g_Conf->Folders.MemoryCards.Mkdir(); Folders.MemoryCards.Mkdir();
g_Conf->Folders.Savestates.Mkdir(); Folders.Savestates.Mkdir();
g_Conf->Folders.Snapshots.Mkdir(); Folders.Snapshots.Mkdir();
// Update the compression attribute on the Memcards folder. // Update the compression attribute on the Memcards folder.
// Memcards generally compress very well via NTFS compression. // 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. bool prev = wxLog::EnableLogging( false ); // wx generates verbose errors if languages don't exist, so disable them here.
if( !i18n_SetLanguage( LanguageId ) ) 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 ) void AppConfig::ConsoleLogOptions::LoadSave( IniInterface& ini, const wxChar* logger )
{ {
ConsoleLogOptions defaults;
ini.SetPath( logger ); ini.SetPath( logger );
IniEntry( Visible, false ); IniEntry( Visible );
IniEntry( AutoDock, true ); IniEntry( AutoDock );
IniEntry( DisplayPosition, wxDefaultPosition ); IniEntry( DisplayPosition );
IniEntry( DisplaySize, wxSize( 540, 540 ) ); IniEntry( DisplaySize );
IniEntry( FontSize, 8 ); IniEntry( FontSize );
ini.SetPath( L".." ); 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 ) void AppConfig::FolderOptions::LoadSave( IniInterface& ini )
{ {
FolderOptions defaults;
ini.SetPath( L"Folders" ); ini.SetPath( L"Folders" );
if( ini.IsSaving() ) if( ini.IsSaving() )
ApplyDefaults(); ApplyDefaults();
IniEntry( Plugins, PathDefs::GetPlugins() ); IniBitBool( UseDefaultPlugins );
IniEntry( Settings, PathDefs::GetSettings() ); IniBitBool( UseDefaultSettings );
IniEntry( Bios, PathDefs::GetBios() ); IniBitBool( UseDefaultBios );
IniEntry( Snapshots, PathDefs::GetSnapshots() ); IniBitBool( UseDefaultSnapshots );
IniEntry( Savestates, PathDefs::GetSavestates() ); IniBitBool( UseDefaultSavestates );
IniEntry( MemoryCards, PathDefs::GetMemoryCards() ); IniBitBool( UseDefaultMemoryCards );
IniEntry( Logs, PathDefs::GetLogs() ); 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 ); IniEntry( RunIso );
IniBitBool( UseDefaultSettings, true );
IniBitBool( UseDefaultBios, true );
IniBitBool( UseDefaultSnapshots, true );
IniBitBool( UseDefaultSavestates, true );
IniBitBool( UseDefaultMemoryCards, true );
IniBitBool( UseDefaultLogs, true );
if( ini.IsLoading() ) if( ini.IsLoading() )
ApplyDefaults(); ApplyDefaults();
@ -535,3 +588,29 @@ void AppConfig::FilenameOptions::LoadSave( IniInterface& ini )
ini.SetPath( L".." ); 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; class IniInterface;
extern bool UseAdminMode; // dictates if the program uses /home/user or /cwd for the program data
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Pcsx2 Application Configuration. // Pcsx2 Application Configuration.
// //
@ -40,12 +42,24 @@ public:
// Size of the font in points. // Size of the font in points.
int FontSize; int FontSize;
ConsoleLogOptions();
void LoadSave( IniInterface& conf, const wxChar* title ); void LoadSave( IniInterface& conf, const wxChar* title );
}; };
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
struct FolderOptions struct FolderOptions
{ {
BITFIELD32()
bool
UseDefaultPlugins:1,
UseDefaultSettings:1,
UseDefaultBios:1,
UseDefaultSnapshots:1,
UseDefaultSavestates:1,
UseDefaultMemoryCards:1,
UseDefaultLogs:1;
}; };
wxDirName wxDirName
Plugins, Plugins,
Settings, Settings,
@ -57,15 +71,7 @@ public:
wxDirName RunIso; // last used location for Iso loading. wxDirName RunIso; // last used location for Iso loading.
bool FolderOptions();
UseDefaultPlugins:1,
UseDefaultSettings:1,
UseDefaultBios:1,
UseDefaultSnapshots:1,
UseDefaultSavestates:1,
UseDefaultMemoryCards:1,
UseDefaultLogs:1;
void LoadSave( IniInterface& conf ); void LoadSave( IniInterface& conf );
void ApplyDefaults(); void ApplyDefaults();
@ -96,7 +102,6 @@ public:
}; };
public: public:
bool UseAdminMode; // dictates if the program uses /home/user or /cwd for the program data
wxPoint MainGuiPosition; wxPoint MainGuiPosition;
// Current language in use (correlates to a wxWidgets wxLANGUAGE specifier) // Current language in use (correlates to a wxWidgets wxLANGUAGE specifier)
@ -140,12 +145,7 @@ protected:
bool m_IsLoaded; bool m_IsLoaded;
public: public:
AppConfig() : AppConfig();
Listbook_ImageSize( 32 )
, Toolbar_ImageSize( 24 )
, m_IsLoaded( false )
{
}
wxString FullpathToBios() const; wxString FullpathToBios() const;
wxString FullpathToMcd( uint mcdidx ) const; wxString FullpathToMcd( uint mcdidx ) const;
@ -156,8 +156,15 @@ public:
void Apply(); void Apply();
void LoadSaveUserMode( IniInterface& ini ); void LoadSaveUserMode( IniInterface& ini );
wxString GetDefaultDocumentsFolder();
protected: protected:
void LoadSave( IniInterface& ini ); 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; 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 ); m_listbook.AddPage( new PluginSelectorPanel( m_listbook, IdealWidth ), _("Plugins"), false, cfgid.Plugins );
g_ApplyState.SetCurrentPage( m_listbook.GetPageCount() ); 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 ); mainSizer.Add( &m_listbook );
AddOkCancel( mainSizer, true ); AddOkCancel( mainSizer, true );
SetSizerAndFit( &mainSizer ); SetSizerAndFit( &mainSizer );
Center( wxCENTER_ON_SCREEN | wxBOTH ); CenterOnScreen();
Connect( wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ConfigurationDialog::OnOk_Click ) ); Connect( wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ConfigurationDialog::OnOk_Click ) );
Connect( wxID_APPLY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ConfigurationDialog::OnApply_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 #pragma once
#include <wx/wx.h>
#include <wx/image.h>
#include "wxHelpers.h"
#include "Panels/ConfigurationPanels.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 namespace Dialogs
{ {
class AboutBoxDialog: public wxDialog class AboutBoxDialog: public wxDialog

View File

@ -26,8 +26,8 @@ using namespace wxHelpers;
Dialogs::PickUserModeDialog::PickUserModeDialog( wxWindow* parent, int id ) : Dialogs::PickUserModeDialog::PickUserModeDialog( wxWindow* parent, int id ) :
wxDialogWithHelpers( parent, id, _("PCSX2 First Time configuration"), false ) wxDialogWithHelpers( parent, id, _("PCSX2 First Time configuration"), false )
, m_panel_usersel( new Panels::UsermodeSelectionPanel( this, 620 ) ) , m_panel_usersel( new Panels::UsermodeSelectionPanel( *this, 620, false ) )
, m_panel_langsel( new Panels::LanguageSelectionPanel( this, 620 ) ) , m_panel_langsel( new Panels::LanguageSelectionPanel( *this, 620 ) )
{ {
wxBoxSizer& s_main = *new wxBoxSizer( wxVERTICAL ); 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 // GCC Note: wxT() macro is required when using string token pasting. For some reason L generates
// syntax errors. >_< // syntax errors. >_<
// //
#define IniEntry( varname, defval ) ini.Entry( wxT(#varname), varname, defval ) #define IniEntry( varname ) ini.Entry( wxT(#varname), varname, defaults.varname )
#define IniBitfield( varname, defval ) varname = ini.EntryBitfield( wxT(#varname), varname, defval ) #define IniBitfield( varname ) varname = ini.EntryBitfield( wxT(#varname), varname, defaults.varname )
#define IniBitBool( varname, defval ) varname = ini.EntryBitBool( wxT(#varname), !!varname, defval ) #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. // 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 // specified in the exception message, and is returned to the settings dialog
// to correct the invalid input fields. // to correct the invalid input fields.
// //
@ -79,7 +79,6 @@ namespace Exception
namespace Panels namespace Panels
{ {
typedef std::list<BaseApplicableConfigPanel*> PanelApplyList_t; typedef std::list<BaseApplicableConfigPanel*> PanelApplyList_t;
struct StaticApplyState struct StaticApplyState
@ -91,9 +90,13 @@ namespace Panels
// this page as their "go here on error" page. (used to take the user to the // this page as their "go here on error" page. (used to take the user to the
// page with the option that failed apply validation). // page with the option that failed apply validation).
int CurOwnerPage; int CurOwnerPage;
// TODO : Rename me to CurOwnerBook, or rename the one above to ParentPage. // TODO : Rename me to CurOwnerBook, or rename the one above to ParentPage.
wxBookCtrlBase* ParentBook; 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() : StaticApplyState() :
PanelList() PanelList()
@ -106,14 +109,16 @@ namespace Panels
{ {
CurOwnerPage = page; CurOwnerPage = page;
} }
void ClearCurrentPage() void ClearCurrentPage()
{ {
CurOwnerPage = wxID_NONE; CurOwnerPage = wxID_NONE;
} }
void StartBook( wxBookCtrlBase* book ); void StartBook( wxBookCtrlBase* book );
void StartWizard();
bool ApplyAll(); bool ApplyAll();
bool ApplyPage( int pageid );
void DoCleanup(); void DoCleanup();
}; };
@ -124,8 +129,8 @@ namespace Panels
// window (usually the ConfigurationDialog) when either Ok or Apply is clicked. // 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 // 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 // static vars and assumes that only one ApplicableConfig system is available to the
// use rate any time (ie, a singular modal dialog). // user at any time (ie, a singular modal dialog).
// //
class BaseApplicableConfigPanel : public wxPanelWithHelpers class BaseApplicableConfigPanel : public wxPanelWithHelpers
{ {
@ -156,6 +161,10 @@ namespace Panels
m_OwnerBook->SetSelection( m_OwnerPage ); 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 // 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 // configuration structure (which is typically a copy of g_Conf). If validation
// of form contents fails, the function should throw Exception::CannotApplySettings. // of form contents fails, the function should throw Exception::CannotApplySettings.
@ -173,7 +182,7 @@ namespace Panels
public: public:
virtual ~UsermodeSelectionPanel() { } virtual ~UsermodeSelectionPanel() { }
UsermodeSelectionPanel( wxWindow* parent, int idealWidth=wxDefaultCoord ); UsermodeSelectionPanel( wxWindow& parent, int idealWidth=wxDefaultCoord, bool isFirstTime = true );
void Apply( AppConfig& conf ); void Apply( AppConfig& conf );
}; };
@ -188,7 +197,7 @@ namespace Panels
public: public:
virtual ~LanguageSelectionPanel() { } virtual ~LanguageSelectionPanel() { }
LanguageSelectionPanel( wxWindow* parent, int idealWidth=wxDefaultCoord ); LanguageSelectionPanel( wxWindow& parent, int idealWidth=wxDefaultCoord );
void Apply( AppConfig& conf ); 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: protected:
class DirPickerPanel : public BaseApplicableConfigPanel FoldersEnum_t m_FolderId;
{ wxDirPickerCtrl* m_pickerCtrl;
protected: wxCheckBox* m_checkCtrl;
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 );
};
public: 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 ); void Apply( AppConfig& conf );
}; };
@ -368,7 +397,9 @@ namespace Panels
int m_progress; int m_progress;
public: public:
StatusPanel( wxWindow* parent, int pluginCount, int biosCount ); StatusPanel( wxWindow* parent );
void SetGaugeLength( int len );
void AdvanceProgress( const wxString& msg ); void AdvanceProgress( const wxString& msg );
void Reset(); void Reset();
}; };
@ -378,27 +409,30 @@ namespace Panels
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
protected: protected:
wxArrayString m_FileList; // list of potential plugin files wxArrayString* m_FileList; // list of potential plugin files
wxArrayString m_BiosList; wxArrayString* m_BiosList;
StatusPanel& m_StatusPanel; StatusPanel& m_StatusPanel;
ComboBoxPanel& m_ComponentBoxes; ComboBoxPanel& m_ComponentBoxes;
bool m_Uninitialized;
EnumThread* m_EnumeratorThread; EnumThread* m_EnumeratorThread;
public: public:
virtual ~PluginSelectorPanel(); virtual ~PluginSelectorPanel();
PluginSelectorPanel( wxWindow& parent, int idealWidth ); PluginSelectorPanel( wxWindow& parent, int idealWidth );
virtual void OnShow( wxShowEvent& evt );
virtual void OnRefresh( wxCommandEvent& evt );
virtual void OnProgress( wxCommandEvent& evt ); virtual void OnProgress( wxCommandEvent& evt );
virtual void OnEnumComplete( wxCommandEvent& evt ); virtual void OnEnumComplete( wxCommandEvent& evt );
void Apply( AppConfig& conf ); void Apply( AppConfig& conf );
void OnShow();
protected: protected:
virtual void OnShow( wxShowEvent& evt );
virtual void OnRefresh( wxCommandEvent& evt );
void DoRefresh(); void DoRefresh();
int FileCount() const { return m_FileList.Count(); } bool ValidateEnumerationStatus();
const wxString& GetFilename( int i ) const { return m_FileList[i]; }
int FileCount() const { return m_FileList->Count(); }
const wxString& GetFilename( int i ) const { return (*m_FileList)[i]; }
friend class EnumThread; friend class EnumThread;
}; };
} }

View File

@ -18,6 +18,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "ConfigurationPanels.h" #include "ConfigurationPanels.h"
#include "ps2/BiosTools.h"
#include <wx/stdpaths.h> #include <wx/stdpaths.h>
@ -43,22 +44,35 @@ void Panels::StaticApplyState::StartBook( wxBookCtrlBase* book )
ParentBook = 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 // Returns false if one of the panels fails input validation (in which case dialogs
// should not be closed, etc). // should not be closed, etc).
// //
bool Panels::StaticApplyState::ApplyAll() bool Panels::StaticApplyState::ApplyPage( int pageid )
{ {
bool retval = true; bool retval = true;
try try
{ {
AppConfig confcopy( *g_Conf ); AppConfig confcopy( *g_Conf );
g_ApplyState.UseAdminMode = UseAdminMode;
PanelApplyList_t::iterator yay = PanelList.begin(); PanelApplyList_t::iterator yay = PanelList.begin();
while( yay != PanelList.end() ) while( yay != PanelList.end() )
{ {
//DbgCon::Status( L"Writing settings for: " + (*yay)->GetLabel() ); //DbgCon::Status( L"Writing settings for: " + (*yay)->GetLabel() );
(*yay)->Apply( confcopy ); if( (pageid < 0) || (*yay)->IsOnPage( pageid ) )
(*yay)->Apply( confcopy );
yay++; yay++;
} }
@ -66,6 +80,7 @@ bool Panels::StaticApplyState::ApplyAll()
// (conveniently skipping any option application! :D) // (conveniently skipping any option application! :D)
*g_Conf = confcopy; *g_Conf = confcopy;
UseAdminMode = g_ApplyState.UseAdminMode;
g_Conf->Apply(); g_Conf->Apply();
g_Conf->Save(); g_Conf->Save();
} }
@ -77,28 +92,43 @@ bool Panels::StaticApplyState::ApplyAll()
ex.GetPanel()->SetFocusToMe(); ex.GetPanel()->SetFocusToMe();
retval = false; 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 ) : Panels::UsermodeSelectionPanel::UsermodeSelectionPanel( wxWindow& parent, int idealWidth, bool isFirstTime ) :
BaseApplicableConfigPanel( parent, idealWidth ) BaseApplicableConfigPanel( &parent, idealWidth )
, m_radio_user( NULL ) , m_radio_user( NULL )
, m_radio_cwd( NULL ) , m_radio_cwd( NULL )
{ {
wxStaticBoxSizer& s_boxer = *new wxStaticBoxSizer( wxVERTICAL, this, _( "Usermode Selection" ) ); const wxString usermodeExplained( pxE( ".Panels:Usermode:Explained",
AddStaticText( s_boxer, pxE( ".Panels:Usermode:Explained",
L"Please select your preferred default location for PCSX2 user-level documents below " L"Please select your preferred default location for PCSX2 user-level documents below "
L"(includes memory cards, screenshots, settings, and savestates). " L"(includes memory cards, screenshots, settings, and savestates). "
L"These folder locations can be overridden at any time using the Core Settings panel." 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() ); m_radio_user = &AddRadioButton( s_boxer, _("User Documents (recommended)"), _("Location: ") + wxStandardPaths::Get().GetDocumentsDir() );
s_boxer.AddSpacer( 4 ); 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 ); s_boxer.AddSpacer( 4 );
SetSizerAndFit( &s_boxer ); SetSizerAndFit( &s_boxer );
@ -108,12 +138,13 @@ void Panels::UsermodeSelectionPanel::Apply( AppConfig& conf )
{ {
if( !m_radio_cwd->GetValue() && !m_radio_user->GetValue() ) 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." ) ); 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 ) : Panels::LanguageSelectionPanel::LanguageSelectionPanel( wxWindow& parent, int idealWidth ) :
BaseApplicableConfigPanel( parent, idealWidth ) BaseApplicableConfigPanel( &parent, idealWidth )
, m_langs() , m_langs()
, m_picker( NULL ) , m_picker( NULL )
{ {

View File

@ -25,15 +25,27 @@
using namespace wxHelpers; using namespace wxHelpers;
static const int BetweenFolderSpace = 5; 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. // 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 ); m_pickerCtrl->Enable( !someNoteworthyBoolean );
if( 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 ); wxASSERT( m_pickerCtrl != NULL && m_checkCtrl != NULL );
UpdateCheckStatus( m_checkCtrl->IsChecked() ); 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 // If initPath is NULL, then it's assumed the default folder is to be used, which is
// obtained from invoking the specified getDefault() function. // 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 ) : const wxString& label, const wxString& dialogLabel ) :
BaseApplicableConfigPanel( parent, wxDefaultCoord ) BaseApplicableConfigPanel( parent, wxDefaultCoord )
, m_FolderId( folderid ) , 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 ); 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 // 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. // 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 wxDefaultPosition, wxDefaultSize, wxDIRP_USE_TEXTCTRL | wxDIRP_DIR_MUST_EXIST
); );
s_box.Add( m_pickerCtrl, wxSizerFlags().Border(wxLEFT | wxRIGHT | wxTOP, 5).Expand() ); s_box.Add( m_pickerCtrl, wxSizerFlags().Border(wxLEFT | wxRIGHT | wxTOP, 5).Expand() );
m_checkCtrl = &AddCheckBox( s_box, _("Use installation default setting") ); m_checkCtrl = &AddCheckBox( s_box, _("Use installation default setting") );
const bool isDefault = g_Conf->Folders.IsDefault( m_FolderId );
m_checkCtrl->SetValue( isDefault ); m_checkCtrl->SetValue( isDefault );
UpdateCheckStatus( isDefault ); UpdateCheckStatus( isDefault );
SetSizerAndFit( &s_box ); 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() ); 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 ) wxPanelWithHelpers( &parent, idealWidth-12 )
, s_main( *new wxBoxSizer( wxVERTICAL ) ) , 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 ) FoldersEnum_t folderid, const wxString& label, const wxString& popupLabel )
{ {
DirPickerPanel* dpan = new DirPickerPanel( this, folderid, label, 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 ) : Panels::StandardPathsPanel::StandardPathsPanel( wxWindow& parent ) :
MyBasePanel( parent ) BasePathsPanel( parent )
{ {
// TODO : Replace the callback mess here with the new FolderId enumeration setup. :) // 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 ) : Panels::AdvancedPathsPanel::AdvancedPathsPanel( wxWindow& parent, int idealWidth ) :
MyBasePanel( parent, idealWidth-9 ) 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") ); m_dirpick_plugins.SetToolTip( pxE( ".Tooltips:Folders:Plugins",
AddStaticText( advanced, pxE( ".Panels:Folders:Advanced", L"This is the location where PCSX2 will expect to find its plugins. Plugins found in this folder "
L"Warning!! These advanced options are provided for developers and advanced testers only. " L"will be enumerated and are selectable from the Plugins panel."
L"Changing these settings can cause program errors, so please be weary."
) ); ) );
AddDirPicker( advanced, FolderId_Plugins, m_dirpick_settings.SetToolTip( pxE( ".Tooltips:Folders:Settings",
_("Plugins:"), L"This is the folder where PCSX2 saves all settings, including settings generated "
_("Select folder for PCSX2 plugins") ). L"by most plugins.\n\nWarning: Some older versions of plugins may not respect this value."
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 );
SetSizerAndFit( &s_main ); 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 ) BaseApplicableConfigPanel( &parent, idealWidth )
{ {
wxBoxSizer& s_main = *new wxBoxSizer( wxVERTICAL ); wxBoxSizer& s_main = *new wxBoxSizer( wxVERTICAL );
wxNotebook& notebook = *new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_BOTTOM | wxNB_FIXEDWIDTH ); wxNotebook& notebook = *new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_BOTTOM | wxNB_FIXEDWIDTH );
notebook.AddPage( new StandardPanel( notebook ), _("Standard") ); StandardPathsPanel& stah( *new StandardPathsPanel( notebook ) );
notebook.AddPage( new AdvancedPanel( notebook, GetIdealWidth() ), _("Advanced") ); 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() ); s_main.Add( &notebook, SizerFlags::StdSpace() );
SetSizerAndFit( &s_main ); 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 "PrecompiledHeader.h"
#include "Utilities/ScopedPtr.h"
#include "Plugins.h" #include "Plugins.h"
#include "ConfigurationPanels.h" #include "ConfigurationPanels.h"
#include "ps2/BiosTools.h" #include "ps2/BiosTools.h"
@ -117,9 +118,9 @@ public:
static const wxString failed_separator( L"-------- Unsupported Plugins --------" ); 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 ) 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_label( *new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE | wxST_NO_AUTORESIZE ) )
, m_progress( 0 ) , m_progress( 0 )
{ {
@ -132,6 +133,11 @@ Panels::PluginSelectorPanel::StatusPanel::StatusPanel( wxWindow* parent, int plu
SetSizerAndFit( &s_main ); SetSizerAndFit( &s_main );
} }
void Panels::PluginSelectorPanel::StatusPanel::SetGaugeLength( int len )
{
m_gauge.SetRange( len );
}
void Panels::PluginSelectorPanel::StatusPanel::AdvanceProgress( const wxString& msg ) void Panels::PluginSelectorPanel::StatusPanel::AdvanceProgress( const wxString& msg )
{ {
m_label.SetLabel( msg ); m_label.SetLabel( msg );
@ -183,15 +189,14 @@ void Panels::PluginSelectorPanel::ComboBoxPanel::Reset()
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
Panels::PluginSelectorPanel::PluginSelectorPanel( wxWindow& parent, int idealWidth ) : Panels::PluginSelectorPanel::PluginSelectorPanel( wxWindow& parent, int idealWidth ) :
BaseApplicableConfigPanel( &parent, idealWidth ) BaseApplicableConfigPanel( &parent, idealWidth )
, m_FileList() , m_FileList( NULL )
, m_StatusPanel( *new StatusPanel( this, , m_BiosList( NULL )
wxDir::GetAllFiles( g_Conf->Folders.Plugins.ToString(), &m_FileList, wxsFormat( L"*%s", wxDynamicLibrary::GetDllExt()), wxDIR_FILES ), , m_StatusPanel( *new StatusPanel( this ) )
wxDir::GetAllFiles( g_Conf->Folders.Bios.ToString(), &m_BiosList, L"*.bin", wxDIR_FILES )
) )
, m_ComponentBoxes( *new ComboBoxPanel( this ) ) , m_ComponentBoxes( *new ComboBoxPanel( this ) )
, m_Uninitialized( true )
, m_EnumeratorThread( NULL ) , m_EnumeratorThread( NULL )
{ {
//ValidateEnumerationStatus();
wxBoxSizer& s_main = *new wxBoxSizer( wxVERTICAL ); wxBoxSizer& s_main = *new wxBoxSizer( wxVERTICAL );
s_main.Add( &m_ComponentBoxes, SizerFlags::StdExpand().ReserveSpaceEvenIfHidden() ); s_main.Add( &m_ComponentBoxes, SizerFlags::StdExpand().ReserveSpaceEvenIfHidden() );
@ -208,7 +213,7 @@ Panels::PluginSelectorPanel::PluginSelectorPanel( wxWindow& parent, int idealWid
SetSizerAndFit( &s_main ); 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_EnumeratedNext, wxCommandEventHandler( PluginSelectorPanel::OnProgress ) );
Connect( wxEVT_EnumerationFinished, wxCommandEventHandler( PluginSelectorPanel::OnEnumComplete ) ); Connect( wxEVT_EnumerationFinished, wxCommandEventHandler( PluginSelectorPanel::OnEnumComplete ) );
@ -222,6 +227,8 @@ Panels::PluginSelectorPanel::~PluginSelectorPanel()
// Kill the thread if it's alive. // Kill the thread if it's alive.
safe_delete( m_EnumeratorThread ); safe_delete( m_EnumeratorThread );
safe_delete( m_FileList );
safe_delete( m_BiosList );
} }
void Panels::PluginSelectorPanel::Apply( AppConfig& conf ) 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() ); relative.MakeRelativeTo( g_Conf->Folders.Plugins.ToString() );
conf.BaseFilenames.Plugins[tbl_PluginInfo[i].id] = relative.GetFullPath(); 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() ); relative.MakeRelativeTo( g_Conf->Folders.Bios.ToString() );
conf.BaseFilenames.Bios = relative.GetFullPath(); conf.BaseFilenames.Bios = relative.GetFullPath();
} }
void Panels::PluginSelectorPanel::DoRefresh() void Panels::PluginSelectorPanel::DoRefresh()
{ {
m_Uninitialized = false;
// Disable all controls until enumeration is complete. // Disable all controls until enumeration is complete.
m_ComponentBoxes.Hide(); m_ComponentBoxes.Hide();
@ -284,22 +289,64 @@ void Panels::PluginSelectorPanel::DoRefresh()
safe_delete( m_EnumeratorThread ); safe_delete( m_EnumeratorThread );
m_EnumeratorThread = new EnumThread( *this ); m_EnumeratorThread = new EnumThread( *this );
m_EnumeratorThread->Start(); 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 ) void Panels::PluginSelectorPanel::OnShow( wxShowEvent& evt )
{ {
evt.Skip(); evt.Skip();
if( !evt.GetShow() ) return; if( !evt.GetShow() ) return;
if( !m_Uninitialized ) return; OnShow();
DoRefresh();
} }
void Panels::PluginSelectorPanel::OnRefresh( wxCommandEvent& evt ) void Panels::PluginSelectorPanel::OnRefresh( wxCommandEvent& evt )
{ {
m_ComponentBoxes.Reset(); ValidateEnumerationStatus();
DoRefresh(); DoRefresh();
} }
@ -314,13 +361,13 @@ void Panels::PluginSelectorPanel::OnEnumComplete( wxCommandEvent& evt )
wxFileName right( g_Conf->FullpathToBios() ); wxFileName right( g_Conf->FullpathToBios() );
right.MakeRelativeTo( g_Conf->Folders.Plugins.ToString() ); 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; 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 ); 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() ); left.MakeRelativeTo( g_Conf->Folders.Plugins.ToString() );
if( left == right ) if( left == right )
@ -358,15 +405,15 @@ void Panels::PluginSelectorPanel::OnEnumComplete( wxCommandEvent& evt )
void Panels::PluginSelectorPanel::OnProgress( wxCommandEvent& evt ) void Panels::PluginSelectorPanel::OnProgress( wxCommandEvent& evt )
{ {
size_t evtidx = evt.GetExtraLong(); size_t evtidx = evt.GetExtraLong();
m_StatusPanel.AdvanceProgress( (evtidx < m_FileList.Count()-1) ? m_StatusPanel.AdvanceProgress( (evtidx < m_FileList->Count()-1) ?
m_FileList[evtidx + 1] : wxString(_("Completing tasks...")) (*m_FileList)[evtidx + 1] : wxString(_("Completing tasks..."))
); );
EnumeratedPluginInfo& result( m_EnumeratorThread->Results[evtidx] ); EnumeratedPluginInfo& result( m_EnumeratorThread->Results[evtidx] );
if( result.TypeMask == 0 ) 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 ) for( int i=0; i<NumPluginTypes; ++i )
@ -376,11 +423,11 @@ void Panels::PluginSelectorPanel::OnProgress( wxCommandEvent& evt )
if( result.PassedTest & tbl_PluginInfo[i].typemask ) if( result.PassedTest & tbl_PluginInfo[i].typemask )
{ {
int sel = m_ComponentBoxes.Get(i).Append( wxsFormat( L"%s %s [%s]", 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 (void*)evtidx
); );
wxFileName left( m_FileList[evtidx] ); wxFileName left( (*m_FileList)[evtidx] );
wxFileName right( g_Conf->FullpathTo(tbl_PluginInfo[i].id) ); wxFileName right( g_Conf->FullpathTo(tbl_PluginInfo[i].id) );
left.MakeRelativeTo( g_Conf->Folders.Plugins.ToString() ); left.MakeRelativeTo( g_Conf->Folders.Plugins.ToString() );

View File

@ -21,6 +21,8 @@
#include "MainFrame.h" #include "MainFrame.h"
#include "Dialogs/ModalPopups.h" #include "Dialogs/ModalPopups.h"
#include "Utilities/ScopedPtr.h"
#include "Resources/EmbeddedImage.h" #include "Resources/EmbeddedImage.h"
#include "Resources/BackgroundLogo.h" #include "Resources/BackgroundLogo.h"
@ -28,6 +30,7 @@
IMPLEMENT_APP(Pcsx2App) IMPLEMENT_APP(Pcsx2App)
bool UseAdminMode = false;
AppConfig* g_Conf = NULL; AppConfig* g_Conf = NULL;
wxFileHistory* g_RecentIsoList = NULL; wxFileHistory* g_RecentIsoList = NULL;
CoreEmuThread* g_EmuThread = NULL; CoreEmuThread* g_EmuThread = NULL;
@ -62,64 +65,34 @@ Pcsx2App::Pcsx2App() :
wxFrame* Pcsx2App::GetMainWindow() const { return m_MainFrame; } 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() void Pcsx2App::ReadUserModeSettings()
{ {
wxFileName usermodefile( FilenameDefs::GetUsermodeConfig() ); wxFileName usermodefile( FilenameDefs::GetUsermodeConfig() );
usermodefile.SetPath( wxGetCwd() ); usermodefile.SetPath( wxGetCwd() );
wxScopedPtr<wxFileConfig> conf_usermode( OpenFileConfig( usermodefile.GetFullPath() ) );
wxFileConfig* conf_usermode = OpenConfig( usermodefile.GetFullPath() );
if( !wxFile::Exists( usermodefile.GetFullPath() ) ) if( !wxFile::Exists( usermodefile.GetFullPath() ) )
{ {
// first time startup, so give the user the choice of user mode: // first time startup, so give the user the choice of user mode:
if( Dialogs::PickUserModeDialog( NULL ).ShowModal() == wxID_CANCEL ) //if( Dialogs::PickUserModeDialog( NULL ).ShowModal() == wxID_CANCEL )
throw Exception::StartupAborted( L"Startup aborted: User cancelled Usermode selection." ); FirstTimeWizard wiz( NULL );
if( !wiz.RunWizard( wiz.GetFirstPage() ) )
throw Exception::StartupAborted( L"Startup aborted: User canceled FirstTime Wizard." );
// Save user's new settings // Save user's new settings
if( conf_usermode != NULL ) IniSaver saver( *conf_usermode );
{ g_Conf->LoadSaveUserMode( saver );
IniSaver saver( *conf_usermode ); g_Conf->Save();
g_Conf->LoadSaveUserMode( saver );
}
} }
else else
{ {
// usermode.ini exists -- assume Documents mode, unless the ini explicitly // usermode.ini exists -- assume Documents mode, unless the ini explicitly
// specifies otherwise. // 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 ) void Pcsx2App::OnInitCmdLine( wxCmdLineParser& parser )
@ -184,20 +157,9 @@ bool Pcsx2App::OnInit()
try try
{ {
if( !TryOpenConfigCwd() ) ReadUserModeSettings();
{
PathDefs::GetDocuments().Mkdir();
PathDefs::GetSettings().Mkdir();
// Allow wx to use our config, and enforces auto-cleanup as well AppConfig_ReloadGlobalSettings();
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();
m_MainFrame = new MainEmuFrame( NULL, L"PCSX2" ); m_MainFrame = new MainEmuFrame( NULL, L"PCSX2" );
m_ProgramLogBox = new ConsoleLogFrame( m_MainFrame, L"PCSX2 Program Log", g_Conf->ProgLogBox ); m_ProgramLogBox = new ConsoleLogFrame( m_MainFrame, L"PCSX2 Program Log", g_Conf->ProgLogBox );
@ -216,24 +178,6 @@ bool Pcsx2App::OnInit()
return false; 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 ) ); Connect( pxEVT_MSGBOX, wxCommandEventHandler( Pcsx2App::OnMessageBox ) );
return true; return true;

View File

@ -47,6 +47,18 @@ struct romdir
u32 BiosVersion; // Used in Memory, Misc, CDVD 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. // Returns the version information of the bios currently loaded into memory.
static u32 GetBiosVersion() static u32 GetBiosVersion()
{ {
@ -152,11 +164,8 @@ void LoadBIOS()
throw Exception::FileNotFound( Bios, throw Exception::FileNotFound( Bios,
L"Configured Bios file does not exist", L"Configured Bios file does not exist",
pxE( ".Error:BiosNotFound", _("The configured BIOS file does not exist, or no BIOS has been configured.\n\n") +
L"The configured BIOS file does not exist, or no BIOS has been configured.\n\n" BIOS_GetMsg_Required()
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."
)
); );
} }
@ -189,9 +198,8 @@ bool IsBIOS(const wxString& filename, wxString& description)
break; // found romdir 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 return FALSE; //Unable to locate ROMDIR structure in file or a ioprpXXX.img
}
bool found = false; bool found = false;
@ -242,13 +250,13 @@ bool IsBIOS(const wxString& filename, wxString& description)
if (fp.Read( &rd, DIRENTRY_SIZE ) != DIRENTRY_SIZE) break; 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 (found)
{ {
if ( biosFileSize < (int)fileOffset) 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, // we force users to have correct bioses,
// not that lame scph10000 of 513KB ;-) // not that lame scph10000 of 513KB ;-)
} }

View File

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

View File

@ -1989,6 +1989,10 @@
RelativePath="..\..\gui\Dialogs\ConfigurationDialog.h" RelativePath="..\..\gui\Dialogs\ConfigurationDialog.h"
> >
</File> </File>
<File
RelativePath="..\..\gui\Dialogs\FirstTimeWizard.cpp"
>
</File>
<File <File
RelativePath="..\..\gui\Dialogs\LogOptionsDialog.cpp" 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} {C34487AF-228A-4D11-8E50-27803DF76873} = {C34487AF-228A-4D11-8E50-27803DF76873}
EndProjectSection EndProjectSection
EndProject 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 Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32 Debug|Win32 = Debug|Win32
@ -601,6 +608,7 @@ Global
{0FADC26C-0E9D-4DD7-84B1-BF4F7754E90C} = {88F517F9-CE1C-4005-9BDF-4481FEB55053} {0FADC26C-0E9D-4DD7-84B1-BF4F7754E90C} = {88F517F9-CE1C-4005-9BDF-4481FEB55053}
{A51123F5-9505-4EAE-85E7-D320290A272C} = {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} {4639972E-424E-4E13-8B07-CA403C481346} = {88F517F9-CE1C-4005-9BDF-4481FEB55053}
{62BF822E-6A12-49A8-BE8C-C55A9BCA24DA} = {0FADC26C-0E9D-4DD7-84B1-BF4F7754E90C}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
AMDCaProjectFile = E:\devpcsx2\fail\wx\CodeAnalyst\pcsx2_suite_2008.caw AMDCaProjectFile = E:\devpcsx2\fail\wx\CodeAnalyst\pcsx2_suite_2008.caw