diff --git a/3rdparty/wxWidgets/include/wx/setup.h b/3rdparty/wxWidgets/include/wx/setup.h
index d824878afb..d629f00dba 100644
--- a/3rdparty/wxWidgets/include/wx/setup.h
+++ b/3rdparty/wxWidgets/include/wx/setup.h
@@ -918,7 +918,7 @@
#define wxUSE_SPLASH 1
// wizards
-#define wxUSE_WIZARDDLG 0
+#define wxUSE_WIZARDDLG 1
// Compile in wxAboutBox() function showing the standard "About" dialog.
//
diff --git a/common/build/Utilities/utilities.vcproj b/common/build/Utilities/utilities.vcproj
index 3d50126e04..c0f2589441 100644
--- a/common/build/Utilities/utilities.vcproj
+++ b/common/build/Utilities/utilities.vcproj
@@ -400,6 +400,10 @@
RelativePath="..\..\include\Utilities\SafeArray.h"
>
+
+
diff --git a/common/include/Pcsx2Defs.h b/common/include/Pcsx2Defs.h
index 2393544493..851c533254 100644
--- a/common/include/Pcsx2Defs.h
+++ b/common/include/Pcsx2Defs.h
@@ -173,10 +173,10 @@
//
#ifdef _MSC_VER
-# define PCSX2_ALIGNED(alig,x) __declspec(align(alig)) x
-# define PCSX2_ALIGNED_EXTERN(alig,x) extern __declspec(align(alig)) x
-# define PCSX2_ALIGNED16(x) __declspec(align(16)) x
-# define PCSX2_ALIGNED16_EXTERN(x) extern __declspec(align(16)) x
+# define PCSX2_ALIGNED(alig,x) __declspec(align(alig)) x
+# define PCSX2_ALIGNED_EXTERN(alig,x) extern __declspec(align(alig)) x
+# define PCSX2_ALIGNED16(x) __declspec(align(16)) x
+# define PCSX2_ALIGNED16_EXTERN(x) extern __declspec(align(16)) x
# define __naked __declspec(naked)
# define __unused /*unused*/
diff --git a/common/include/Utilities/SafeArray.h b/common/include/Utilities/SafeArray.h
index b3b613fb55..1b43cad806 100644
--- a/common/include/Utilities/SafeArray.h
+++ b/common/include/Utilities/SafeArray.h
@@ -31,39 +31,31 @@ extern void pcsx2_aligned_free(void* pmem);
# define _aligned_realloc pcsx2_aligned_realloc
#endif
-//////////////////////////////////////////////////////////////
-// Safe deallocation macros -- always check pointer validity (non-null)
-// and set pointer to null on deallocation.
+//////////////////////////////////////////////////////////////////////////////////////////
+// Safe deallocation macros -- checks pointer validity (non-null) when needed, and sets
+// pointer to null after deallocation.
#define safe_delete( ptr ) \
- if( ptr != NULL ) { \
- delete ptr; \
- ptr = NULL; \
- }
+ ((void) (delete ptr), ptr = NULL)
#define safe_delete_array( ptr ) \
- if( ptr != NULL ) { \
- delete[] ptr; \
- ptr = NULL; \
- }
+ ((void) (delete[] ptr), ptr = NULL)
+// fixme: I'm pretty sure modern libc implementations under gcc and msvc check null status
+// inside free(), meaning we shouldn't have to do it ourselves. But legacy implementations
+// didn't always check, so best to be cautious unless absolutely certain it's being covered on
+// all ported platforms.
#define safe_free( ptr ) \
- if( ptr != NULL ) { \
- free( ptr ); \
- ptr = NULL; \
- }
+ ((void) (( ( ptr != NULL ) && (free( ptr ), !!0) ), ptr = NULL))
+// Implementation note: all known implementations of _aligned_free check the pointer for
+// NULL status (our implementation under GCC, and microsoft's under MSVC), so no need to
+// do it here.
#define safe_aligned_free( ptr ) \
- if( ptr != NULL ) { \
- _aligned_free( ptr ); \
- ptr = NULL; \
- }
+ ((void) ( _aligned_free( ptr ), ptr = NULL ))
#define SafeSysMunmap( ptr, size ) \
- if( ptr != NULL ) { \
- HostSys::Munmap( (uptr)ptr, size ); \
- ptr = NULL; \
- }
+ ((void) ( HostSys::Munmap( (uptr)ptr, size ), ptr = NULL ))
//////////////////////////////////////////////////////////////////////////////////////////
diff --git a/common/include/Utilities/ScopedPtr.h b/common/include/Utilities/ScopedPtr.h
new file mode 100644
index 0000000000..8b0722c478
--- /dev/null
+++ b/common/include/Utilities/ScopedPtr.h
@@ -0,0 +1,4 @@
+#pragma once
+
+#include
+#include
diff --git a/common/include/wx/folderdesc.txt b/common/include/wx/folderdesc.txt
new file mode 100644
index 0000000000..9988adbdcd
--- /dev/null
+++ b/common/include/wx/folderdesc.txt
@@ -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
+
+If/when PCSX2 upgrades to wx2.9/3.0 these files will be removed and the wxWidgets
+distribution files will automatically be used instead.
diff --git a/common/include/wx/scopedarray.h b/common/include/wx/scopedarray.h
new file mode 100644
index 0000000000..2a697fedc6
--- /dev/null
+++ b/common/include/wx/scopedarray.h
@@ -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 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::*unspecified_bool_type)() const;
+ operator unspecified_bool_type() const
+ {
+ return m_array ? &wxScopedArray::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&);
+ wxScopedArray& operator=(const wxScopedArray&);
+};
diff --git a/common/include/wx/scopedptr.h b/common/include/wx/scopedptr.h
new file mode 100644
index 0000000000..ce88d4e40e
--- /dev/null
+++ b/common/include/wx/scopedptr.h
@@ -0,0 +1,99 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name: wx/scopedptr.h
+// Purpose: scoped smart pointer class
+// Author: Jesse Lovelace
+// 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 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::*unspecified_bool_type)() const;
+
+ operator unspecified_bool_type() const
+ {
+ return m_ptr ? &wxScopedPtr::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&);
+ wxScopedPtr& operator=(const wxScopedPtr&);
+};
diff --git a/pcsx2/Config.h b/pcsx2/Config.h
index ef7e598f0a..23fe962d36 100644
--- a/pcsx2/Config.h
+++ b/pcsx2/Config.h
@@ -36,6 +36,13 @@ enum PluginsEnum_t
// equality operators.
#define OpEqu( field ) (field == right.field)
+// Macro used for removing some of the redtape involved in defining bitfield/union helpers.
+//
+#define BITFIELD32() \
+ union { \
+ u32 bitset; \
+ struct {
+
//------------ DEFAULT sseMXCSR VALUES ---------------
#define DEFAULT_sseMXCSR 0xffc0 //FPU rounding > DaZ, FtZ, "chop"
#define DEFAULT_sseVUMXCSR 0xffc0 //VU rounding > DaZ, FtZ, "chop"
@@ -58,72 +65,57 @@ class Pcsx2Config
public:
struct ProfilerOptions
{
- union
- {
- struct
- {
- bool
- Enabled:1, // universal toggle for the profiler.
- RecBlocks_EE:1, // Enables per-block profiling for the EE recompiler [unimplemented]
- RecBlocks_IOP:1, // Enables per-block profiling for the IOP recompiler [unimplemented]
- RecBlocks_VU0:1, // Enables per-block profiling for the VU0 recompiler [unimplemented]
- RecBlocks_VU1:1; // Enables per-block profiling for the VU1 recompiler [unimplemented]
- };
- u8 bits;
- };
-
- ProfilerOptions() : bits( 0 ) {}
+ BITFIELD32()
+ bool
+ Enabled:1, // universal toggle for the profiler.
+ RecBlocks_EE:1, // Enables per-block profiling for the EE recompiler [unimplemented]
+ RecBlocks_IOP:1, // Enables per-block profiling for the IOP recompiler [unimplemented]
+ RecBlocks_VU0:1, // Enables per-block profiling for the VU0 recompiler [unimplemented]
+ RecBlocks_VU1:1; // Enables per-block profiling for the VU1 recompiler [unimplemented]
+ }; };
+ // Default is Disabled, with all recs enabled underneath.
+ ProfilerOptions() : bitset( 0xfffffffe ) {}
void LoadSave( IniInterface& conf );
bool operator ==( const ProfilerOptions& right ) const
{
- return OpEqu( bits );
+ return OpEqu( bitset );
}
bool operator !=( const ProfilerOptions& right ) const
{
- return !this->operator ==( right );
+ return !OpEqu( bitset );
}
};
-
+
// ------------------------------------------------------------------------
struct RecompilerOptions
{
- union
- {
- struct
- {
- bool
- EnableEE:1,
- EnableIOP:1,
- EnableVU0:1,
- EnableVU1:1;
-
- bool
- UseMicroVU0:1,
- UseMicroVU1:1;
- };
- u8 bits;
- };
+ BITFIELD32()
+ bool
+ EnableEE:1,
+ EnableIOP:1,
+ EnableVU0:1,
+ EnableVU1:1;
+
+ bool
+ UseMicroVU0:1,
+ UseMicroVU1:1;
+ }; };
- RecompilerOptions() : bits( 0 ) { }
-
- void Load( const wxString& srcfile );
- void Load( const wxInputStream& srcstream );
- void Save( const wxString& dstfile );
- void Save( const wxOutputStream& deststream );
-
+ // All recs are enabled by default.
+ RecompilerOptions() : bitset( 0xffffffff ) { }
void LoadSave( IniInterface& conf );
bool operator ==( const RecompilerOptions& right ) const
{
- return OpEqu( bits );
+ return OpEqu( bitset );
}
bool operator !=( const RecompilerOptions& right ) const
{
- return !this->operator ==( right );
+ return !OpEqu( bitset );
}
} Recompiler;
@@ -136,38 +128,27 @@ public:
u32 sseMXCSR;
u32 sseVUMXCSR;
- struct
- {
- union
- {
- bool
- vuOverflow:1,
- vuExtraOverflow:1,
- vuSignOverflow:1,
- vuUnderflow:1;
-
- bool
- fpuOverflow:1,
- fpuExtraOverflow:1,
- fpuFullMode:1;
- };
- u8 bits;
- };
-
- CpuOptions() :
- sseMXCSR( DEFAULT_sseMXCSR )
- , sseVUMXCSR( DEFAULT_sseVUMXCSR )
- , bits( 0 )
- {
- }
+ BITFIELD32()
+ bool
+ vuOverflow:1,
+ vuExtraOverflow:1,
+ vuSignOverflow:1,
+ vuUnderflow:1;
+
+ bool
+ fpuOverflow:1,
+ fpuExtraOverflow:1,
+ fpuFullMode:1;
+ }; };
+ CpuOptions();
void LoadSave( IniInterface& conf );
bool operator ==( const CpuOptions& right ) const
{
return
OpEqu( sseMXCSR ) && OpEqu( sseVUMXCSR ) &&
- OpEqu( bits ) && OpEqu( Recompiler );
+ OpEqu( bitset ) && OpEqu( Recompiler );
}
bool operator !=( const CpuOptions& right ) const
@@ -193,68 +174,59 @@ public:
int ConsecutiveFrames; // number of consecutive frames (fields) to render
int ConsecutiveSkip; // number of consecutive frames (fields) to skip
+ VideoOptions();
void LoadSave( IniInterface& conf );
};
// ------------------------------------------------------------------------
struct GamefixOptions
{
- union
- {
- struct
- {
- bool
- VuAddSubHack:1, // Fix for Tri-ace games, they use an encryption algorithm that requires VU ADDI opcode to be bit-accurate.
- VuClipFlagHack:1, // Fix for Digimon Rumble Arena 2, fixes spinning/hanging on intro-menu.
- FpuCompareHack:1, // Fix for Persona games, maybe others. It's to do with the VU clip flag (again).
- FpuMulHack:1, // Fix for Tales of Destiny hangs.
- XgKickHack:1; // Fix for Erementar Gerad, adds more delay to VU XGkick instructions. Corrects the color of some graphics, but breaks Tri-ace games and others.
- };
- u8 bits;
- };
-
- GamefixOptions() : bits( 0 ) {}
+ BITFIELD32()
+ bool
+ VuAddSubHack:1, // Fix for Tri-ace games, they use an encryption algorithm that requires VU ADDI opcode to be bit-accurate.
+ VuClipFlagHack:1, // Fix for Digimon Rumble Arena 2, fixes spinning/hanging on intro-menu.
+ FpuCompareHack:1, // Fix for Persona games, maybe others. It's to do with the VU clip flag (again).
+ FpuMulHack:1, // Fix for Tales of Destiny hangs.
+ XgKickHack:1; // Fix for Erementar Gerad, adds more delay to VU XGkick instructions. Corrects the color of some graphics, but breaks Tri-ace games and others.
+ }; };
+ // all gamefixes are disabled by default.
+ GamefixOptions() : bitset( 0 ) {}
void LoadSave( IniInterface& conf );
bool operator ==( const GamefixOptions& right ) const
{
- return OpEqu( bits );
+ return OpEqu( bitset );
}
bool operator !=( const GamefixOptions& right ) const
{
- return !this->operator ==( right );
+ return !OpEqu( bitset );
}
};
// ------------------------------------------------------------------------
struct SpeedhackOptions
{
- union
- {
- struct
- {
- int
- EECycleRate:2, // EE cyclerate selector (1.0, 1.5, 2.0)
- VUCycleSteal:3, // VU Cycle Stealer factor (0, 1, 2, or 3)
- IopCycleRate_X2:1, // enables the x2 multiplier of the IOP cyclerate
- IntcStat:1, // tells Pcsx2 to fast-forward through intc_stat waits.
- BIFC0:1, // enables BIFC0 detection and fast-forwarding
-
- vuMinMax:1, // microVU specific MinMax hack; Can cause SPS, Black Screens, etc...
- vuFlagHack:1; // MicroVU specific flag hack; Can cause Infinite loops, SPS, etc...
- };
- u16 bits;
- };
+ BITFIELD32()
+ bool
+ IopCycleRate_X2:1, // enables the x2 multiplier of the IOP cyclerate
+ IntcStat:1, // tells Pcsx2 to fast-forward through intc_stat waits.
+ BIFC0:1, // enables BIFC0 detection and fast-forwarding
+
+ vuMinMax:1, // microVU specific MinMax hack; Can cause SPS, Black Screens, etc...
+ vuFlagHack:1; // MicroVU specific flag hack; Can cause Infinite loops, SPS, etc...
+ }; };
- SpeedhackOptions() : bits( 0 ) {}
+ u8 EECycleRate; // EE cyclerate selector (1.0, 1.5, 2.0)
+ u8 VUCycleSteal; // VU Cycle Stealer factor (0, 1, 2, or 3)
+ SpeedhackOptions();
void LoadSave( IniInterface& conf );
bool operator ==( const SpeedhackOptions& right ) const
{
- return OpEqu( bits );
+ return OpEqu( bitset ) && OpEqu( EECycleRate ) && OpEqu( VUCycleSteal );
}
bool operator !=( const SpeedhackOptions& right ) const
@@ -264,18 +236,22 @@ public:
};
public:
- bool CdvdVerboseReads:1; // enables cdvd read activity verbosely dumped to the console
- bool CdvdDumpBlocks:1; // enables cdvd block dumping
- bool EnablePatches:1; // enables patch detection and application
- // when enabled performs bios stub execution, skipping full sony bios + splash screens
- bool SkipBiosSplash:1;
+ BITFIELD32()
+ bool
+ CdvdVerboseReads:1, // enables cdvd read activity verbosely dumped to the console
+ CdvdDumpBlocks:1, // enables cdvd block dumping
+ EnablePatches:1, // enables patch detection and application
- // Closes the GS/Video port on escape (good for fullscreen activity)
- bool closeGSonEsc:1;
+ // when enabled performs bios stub execution, skipping full sony bios + splash screens
+ SkipBiosSplash:1,
- // enables simulated ejection of memory cards when loading savestates
- bool McdEnableEjection:1;
+ // Closes the GS/Video port on escape (good for fullscreen activity)
+ closeGSonEsc:1,
+
+ // enables simulated ejection of memory cards when loading savestates
+ McdEnableEjection:1;
+ }; };
CpuOptions Cpu;
VideoOptions Video;
@@ -283,12 +259,13 @@ public:
GamefixOptions Gamefixes;
ProfilerOptions Profiler;
+ Pcsx2Config();
+ void LoadSave( IniInterface& ini );
+
void Load( const wxString& srcfile );
void Load( const wxInputStream& srcstream );
void Save( const wxString& dstfile );
void Save( const wxOutputStream& deststream );
-
- void LoadSave( IniInterface& ini );
};
//////////////////////////////////////////////////////////////////////////
diff --git a/pcsx2/Pcsx2Config.cpp b/pcsx2/Pcsx2Config.cpp
index d0768a0345..26d3e1679b 100644
--- a/pcsx2/Pcsx2Config.cpp
+++ b/pcsx2/Pcsx2Config.cpp
@@ -19,91 +19,152 @@
#include "PrecompiledHeader.h"
#include "IniInterface.h"
#include "Config.h"
+#include "GS.h"
+
#include
+// all speedhacks are disabled by default
+Pcsx2Config::SpeedhackOptions::SpeedhackOptions() :
+ bitset( 0 )
+, EECycleRate( 0 )
+, VUCycleSteal( 0 )
+{
+}
+
void Pcsx2Config::SpeedhackOptions::LoadSave( IniInterface& ini )
{
+ SpeedhackOptions defaults;
ini.SetPath( L"Speedhacks" );
- IniBitfield( EECycleRate, 0 );
- IniBitfield( VUCycleSteal, 0 );
- IniBitBool( IopCycleRate_X2, false );
- IniBitBool( IntcStat, false );
- IniBitBool( BIFC0, false );
+ IniBitfield( EECycleRate );
+ IniBitfield( VUCycleSteal );
+ IniBitBool( IopCycleRate_X2 );
+ IniBitBool( IntcStat );
+ IniBitBool( BIFC0 );
ini.SetPath( L".." );
}
void Pcsx2Config::ProfilerOptions::LoadSave( IniInterface& ini )
{
+ ProfilerOptions defaults;
ini.SetPath( L"Profiler" );
- IniBitBool( Enabled, false );
- IniBitBool( RecBlocks_EE, true );
- IniBitBool( RecBlocks_IOP, true );
- IniBitBool( RecBlocks_VU0, true );
- IniBitBool( RecBlocks_VU1, true );
+ IniBitBool( Enabled );
+ IniBitBool( RecBlocks_EE );
+ IniBitBool( RecBlocks_IOP );
+ IniBitBool( RecBlocks_VU0 );
+ IniBitBool( RecBlocks_VU1 );
ini.SetPath( L".." );
}
void Pcsx2Config::RecompilerOptions::LoadSave( IniInterface& ini )
{
+ RecompilerOptions defaults;
ini.SetPath( L"Recompiler" );
- IniBitBool( EnableEE, true );
- IniBitBool( EnableIOP, true );
- IniBitBool( EnableVU0, true );
- IniBitBool( EnableVU1, true );
+ IniBitBool( EnableEE );
+ IniBitBool( EnableIOP );
+ IniBitBool( EnableVU0 );
+ IniBitBool( EnableVU1 );
ini.SetPath( L".." );
}
+Pcsx2Config::CpuOptions::CpuOptions() :
+ bitset( 0 )
+, sseMXCSR( DEFAULT_sseMXCSR )
+, sseVUMXCSR( DEFAULT_sseVUMXCSR )
+{
+ vuOverflow = true;
+ fpuOverflow = true;
+}
+
void Pcsx2Config::CpuOptions::LoadSave( IniInterface& ini )
{
+ CpuOptions defaults;
ini.SetPath( L"CPU" );
- IniEntry( sseMXCSR, DEFAULT_sseMXCSR );
- IniEntry( sseVUMXCSR, DEFAULT_sseVUMXCSR );
+ IniEntry( sseMXCSR );
+ IniEntry( sseVUMXCSR );
- IniBitBool( vuOverflow, true );
- IniBitBool( vuExtraOverflow, false );
- IniBitBool( vuSignOverflow, false );
- IniBitBool( vuUnderflow, false );
+ IniBitBool( vuOverflow );
+ IniBitBool( vuExtraOverflow );
+ IniBitBool( vuSignOverflow );
+ IniBitBool( vuUnderflow );
- IniBitBool( fpuOverflow, true );
- IniBitBool( fpuExtraOverflow, false );
- IniBitBool( fpuFullMode, false );
+ IniBitBool( fpuOverflow );
+ IniBitBool( fpuExtraOverflow );
+ IniBitBool( fpuFullMode );
Recompiler.LoadSave( ini );
ini.SetPath( L".." );
}
+Pcsx2Config::VideoOptions::VideoOptions() :
+ EnableFrameLimiting( false )
+, EnableFrameSkipping( false )
+, DefaultRegionMode( Region_NTSC )
+, FpsTurbo( 60*4 )
+, FpsLimit( 60 )
+, FpsSkip( 55 )
+, ConsecutiveFrames( 2 )
+, ConsecutiveSkip( 1 )
+{
+}
+
void Pcsx2Config::VideoOptions::LoadSave( IniInterface& ini )
{
+ VideoOptions defaults;
ini.SetPath( L"Video" );
+ IniEntry( EnableFrameLimiting );
+ IniEntry( EnableFrameSkipping );
+
+ static const wxChar * const ntsc_pal_str[2] = { L"ntsc", L"pal" };
+ ini.EnumEntry( L"DefaultRegionMode", DefaultRegionMode, ntsc_pal_str, defaults.DefaultRegionMode );
+
+ IniEntry( FpsTurbo );
+ IniEntry( FpsLimit );
+ IniEntry( FpsSkip );
+ IniEntry( ConsecutiveFrames );
+ IniEntry( ConsecutiveSkip );
+
ini.SetPath( L".." );
}
void Pcsx2Config::GamefixOptions::LoadSave( IniInterface& ini )
{
- ini.SetPath( L"Video" );
+ GamefixOptions defaults;
+ ini.SetPath( L"Gamefixes" );
+
+ IniBitBool( VuAddSubHack );
+ IniBitBool( VuClipFlagHack );
+ IniBitBool( FpuCompareHack );
+ IniBitBool( FpuMulHack );
+ IniBitBool( XgKickHack );
ini.SetPath( L".." );
}
+Pcsx2Config::Pcsx2Config() :
+ bitset( 0 )
+{
+}
+
void Pcsx2Config::LoadSave( IniInterface& ini )
{
+ Pcsx2Config defaults;
ini.SetPath( L"EmuCore" );
-
- IniBitBool( CdvdVerboseReads, false );
- IniBitBool( CdvdDumpBlocks, false );
- IniBitBool( EnablePatches, false );
- IniBitBool( closeGSonEsc, false );
- IniBitBool( McdEnableEjection, false );
+ IniBitBool( CdvdVerboseReads );
+ IniBitBool( CdvdDumpBlocks );
+ IniBitBool( EnablePatches );
+
+ IniBitBool( closeGSonEsc );
+ IniBitBool( McdEnableEjection );
// Process various sub-components:
diff --git a/pcsx2/Plugins.cpp b/pcsx2/Plugins.cpp
index be81deb3ce..23d8a6cddf 100644
--- a/pcsx2/Plugins.cpp
+++ b/pcsx2/Plugins.cpp
@@ -18,6 +18,7 @@
#include "PrecompiledHeader.h"
#include "Utilities/RedtapeWindows.h"
+#include "Utilities/ScopedPtr.h"
#include
#include
@@ -46,9 +47,20 @@ const PluginInfo tbl_PluginInfo[] =
};
+int EnumeratePluginsFolder( wxArrayString* dest )
+{
+ wxScopedPtr placebo;
+ wxArrayString* realdest = dest;
+ if( realdest == NULL )
+ placebo.reset( realdest = new wxArrayString() );
+
+ return g_Conf->Folders.Plugins.Exists() ?
+ wxDir::GetAllFiles( g_Conf->Folders.Plugins.ToString(), realdest, wxsFormat( L"*%s", wxDynamicLibrary::GetDllExt()), wxDIR_FILES ) : 0;
+}
+
+
typedef void CALLBACK VoidMethod();
typedef void CALLBACK vMeth(); // shorthand for VoidMethod
-; // extra semicolon fixes VA-X intellisense breakage caused by CALLBACK in the above typedef >_<
// ----------------------------------------------------------------------------
struct LegacyApi_CommonMethod
diff --git a/pcsx2/Plugins.h b/pcsx2/Plugins.h
index 54924566b7..0ce6c012f2 100644
--- a/pcsx2/Plugins.h
+++ b/pcsx2/Plugins.h
@@ -109,6 +109,8 @@ protected:
extern const PluginInfo tbl_PluginInfo[];
extern PluginManager* g_plugins;
+extern int EnumeratePluginsFolder( wxArrayString* dest );
+
void LoadPlugins();
void ReleasePlugins();
diff --git a/pcsx2/gui/AppConfig.cpp b/pcsx2/gui/AppConfig.cpp
index 3c4ed21319..9adb2685be 100644
--- a/pcsx2/gui/AppConfig.cpp
+++ b/pcsx2/gui/AppConfig.cpp
@@ -95,10 +95,7 @@ namespace PathDefs
// share with other programs: screenshots, memory cards, and savestates.
wxDirName GetDocuments()
{
- if( g_Conf->UseAdminMode )
- return (wxDirName)wxGetCwd();
- else
- return (wxDirName)wxStandardPaths::Get().GetDocumentsDir() + (wxDirName)wxGetApp().GetAppName();
+ return (wxDirName)g_Conf->GetDefaultDocumentsFolder();
}
wxDirName GetSnapshots()
@@ -159,6 +156,13 @@ namespace PathDefs
}
};
+wxString AppConfig::GetDefaultDocumentsFolder()
+{
+ if( UseAdminMode )
+ return wxGetCwd();
+ else
+ return Path::Combine( wxStandardPaths::Get().GetDocumentsDir(), wxGetApp().GetAppName() );
+}
const wxDirName& AppConfig::FolderOptions::operator[]( FoldersEnum_t folderidx ) const
{
@@ -345,10 +349,32 @@ wxString AppConfig::FullpathTo( PluginsEnum_t pluginidx ) const
wxString AppConfig::FullpathToBios() const { return Path::Combine( Folders.Bios, BaseFilenames.Bios ); }
wxString AppConfig::FullpathToMcd( uint mcdidx ) const { return Path::Combine( Folders.MemoryCards, Mcd[mcdidx].Filename ); }
+AppConfig::AppConfig() :
+ MainGuiPosition( wxDefaultPosition )
+, LanguageId( wxLANGUAGE_DEFAULT )
+, RecentFileCount( 6 )
+, DeskTheme( L"default" )
+, Listbook_ImageSize( 32 )
+, Toolbar_ImageSize( 24 )
+, Toolbar_ShowLabels( true )
+
+, McdEnableNTFS( true )
+
+, ProgLogBox()
+, Ps2ConBox()
+, Folders()
+, BaseFilenames()
+, EmuOptions()
+, m_IsLoaded( false )
+{
+}
+
// ------------------------------------------------------------------------
void AppConfig::LoadSaveUserMode( IniInterface& ini )
{
- IniEntry( UseAdminMode, false );
+ AppConfig defaults;
+
+ ini.Entry( L"UseAdminMode", UseAdminMode, false );
ini.Entry( L"SettingsPath", Folders.Settings, PathDefs::GetSettings() );
ini.Flush();
@@ -357,18 +383,20 @@ void AppConfig::LoadSaveUserMode( IniInterface& ini )
// ------------------------------------------------------------------------
void AppConfig::LoadSave( IniInterface& ini )
{
- IniEntry( MainGuiPosition, wxDefaultPosition );
- ini.EnumEntry( L"LanguageId", LanguageId );
- IniEntry( RecentFileCount, 6 );
- IniEntry( DeskTheme, L"default" );
- IniEntry( Listbook_ImageSize, 32 );
- IniEntry( Toolbar_ImageSize, 24 );
- IniEntry( Toolbar_ShowLabels, true );
+ AppConfig defaults;
+
+ IniEntry( MainGuiPosition );
+ ini.EnumEntry( L"LanguageId", LanguageId, NULL, defaults.LanguageId );
+ IniEntry( RecentFileCount );
+ IniEntry( DeskTheme );
+ IniEntry( Listbook_ImageSize );
+ IniEntry( Toolbar_ImageSize );
+ IniEntry( Toolbar_ShowLabels );
// Process various sub-components:
ProgLogBox.LoadSave( ini, L"ProgramLog" );
Ps2ConBox.LoadSave( ini, L"Ps2Console" );
-
+
Folders.LoadSave( ini );
BaseFilenames.LoadSave( ini );
@@ -391,14 +419,14 @@ void AppConfig::Apply()
// Ensure existence of necessary documents folders. Plugins and other parts
// of PCSX2 rely on them.
- g_Conf->Folders.MemoryCards.Mkdir();
- g_Conf->Folders.Savestates.Mkdir();
- g_Conf->Folders.Snapshots.Mkdir();
+ Folders.MemoryCards.Mkdir();
+ Folders.Savestates.Mkdir();
+ Folders.Snapshots.Mkdir();
// Update the compression attribute on the Memcards folder.
// Memcards generally compress very well via NTFS compression.
- NTFS_CompressFile( g_Conf->Folders.MemoryCards.ToString(), g_Conf->McdEnableNTFS );
+ NTFS_CompressFile( Folders.MemoryCards.ToString(), McdEnableNTFS );
bool prev = wxLog::EnableLogging( false ); // wx generates verbose errors if languages don't exist, so disable them here.
if( !i18n_SetLanguage( LanguageId ) )
@@ -445,15 +473,25 @@ void AppConfig::Save()
}
// ------------------------------------------------------------------------
+AppConfig::ConsoleLogOptions::ConsoleLogOptions() :
+ Visible( false )
+, AutoDock( true )
+, DisplayPosition( wxDefaultPosition )
+, DisplaySize( wxSize( 540, 540 ) )
+, FontSize( 8 )
+{
+}
+
void AppConfig::ConsoleLogOptions::LoadSave( IniInterface& ini, const wxChar* logger )
{
+ ConsoleLogOptions defaults;
ini.SetPath( logger );
- IniEntry( Visible, false );
- IniEntry( AutoDock, true );
- IniEntry( DisplayPosition, wxDefaultPosition );
- IniEntry( DisplaySize, wxSize( 540, 540 ) );
- IniEntry( FontSize, 8 );
+ IniEntry( Visible );
+ IniEntry( AutoDock );
+ IniEntry( DisplayPosition );
+ IniEntry( DisplaySize );
+ IniEntry( FontSize );
ini.SetPath( L".." );
}
@@ -470,30 +508,45 @@ void AppConfig::FolderOptions::ApplyDefaults()
}
// ------------------------------------------------------------------------
+AppConfig::FolderOptions::FolderOptions() :
+ bitset( 0xffffffff )
+, Plugins( PathDefs::GetPlugins() )
+, Settings( PathDefs::GetSettings() )
+, Bios( PathDefs::GetBios() )
+, Snapshots( PathDefs::GetSnapshots() )
+, Savestates( PathDefs::GetSavestates() )
+, MemoryCards( PathDefs::GetMemoryCards() )
+, Logs( PathDefs::GetLogs() )
+
+, RunIso( PathDefs::GetDocuments() ) // raw default is always the Documents folder.
+{
+}
+
void AppConfig::FolderOptions::LoadSave( IniInterface& ini )
{
+ FolderOptions defaults;
ini.SetPath( L"Folders" );
if( ini.IsSaving() )
ApplyDefaults();
- IniEntry( Plugins, PathDefs::GetPlugins() );
- IniEntry( Settings, PathDefs::GetSettings() );
- IniEntry( Bios, PathDefs::GetBios() );
- IniEntry( Snapshots, PathDefs::GetSnapshots() );
- IniEntry( Savestates, PathDefs::GetSavestates() );
- IniEntry( MemoryCards, PathDefs::GetMemoryCards() );
- IniEntry( Logs, PathDefs::GetLogs() );
+ IniBitBool( UseDefaultPlugins );
+ IniBitBool( UseDefaultSettings );
+ IniBitBool( UseDefaultBios );
+ IniBitBool( UseDefaultSnapshots );
+ IniBitBool( UseDefaultSavestates );
+ IniBitBool( UseDefaultMemoryCards );
+ IniBitBool( UseDefaultLogs );
- IniEntry( RunIso, PathDefs::GetDocuments() ); // raw default is always the Documents folder.
+ IniEntry( Plugins );
+ IniEntry( Settings );
+ IniEntry( Bios );
+ IniEntry( Snapshots );
+ IniEntry( Savestates );
+ IniEntry( MemoryCards );
+ IniEntry( Logs );
- IniBitBool( UseDefaultPlugins, true );
- IniBitBool( UseDefaultSettings, true );
- IniBitBool( UseDefaultBios, true );
- IniBitBool( UseDefaultSnapshots, true );
- IniBitBool( UseDefaultSavestates, true );
- IniBitBool( UseDefaultMemoryCards, true );
- IniBitBool( UseDefaultLogs, true );
+ IniEntry( RunIso );
if( ini.IsLoading() )
ApplyDefaults();
@@ -535,3 +588,29 @@ void AppConfig::FilenameOptions::LoadSave( IniInterface& ini )
ini.SetPath( L".." );
}
+wxFileConfig* OpenFileConfig( const wxString& filename )
+{
+ return new wxFileConfig( wxEmptyString, wxEmptyString, filename, wxEmptyString, wxCONFIG_USE_RELATIVE_PATH );
+}
+
+// Parameters:
+// overwrite - this option forces the current settings to overwrite any existing settings that might
+// be saved to the configured ini/settings folder.
+//
+void AppConfig_ReloadGlobalSettings( bool overwrite )
+{
+ PathDefs::GetDocuments().Mkdir();
+ PathDefs::GetSettings().Mkdir();
+
+ // Allow wx to use our config, and enforces auto-cleanup as well
+ wxString confile( g_Conf->Folders.Settings.Combine( FilenameDefs::GetConfig() ).GetFullPath() );
+ delete wxConfigBase::Set( OpenFileConfig( confile ) );
+ wxConfigBase::Get()->SetRecordDefaults();
+
+ if( !overwrite )
+ g_Conf->Load();
+
+ g_Conf->Apply();
+ g_Conf->Folders.Logs.Mkdir();
+}
+
diff --git a/pcsx2/gui/AppConfig.h b/pcsx2/gui/AppConfig.h
index 98dd52cd6e..5ddbbb4184 100644
--- a/pcsx2/gui/AppConfig.h
+++ b/pcsx2/gui/AppConfig.h
@@ -20,6 +20,8 @@
class IniInterface;
+extern bool UseAdminMode; // dictates if the program uses /home/user or /cwd for the program data
+
//////////////////////////////////////////////////////////////////////////////////////////
// Pcsx2 Application Configuration.
//
@@ -40,12 +42,24 @@ public:
// Size of the font in points.
int FontSize;
+ ConsoleLogOptions();
void LoadSave( IniInterface& conf, const wxChar* title );
};
// ------------------------------------------------------------------------
struct FolderOptions
{
+ BITFIELD32()
+ bool
+ UseDefaultPlugins:1,
+ UseDefaultSettings:1,
+ UseDefaultBios:1,
+ UseDefaultSnapshots:1,
+ UseDefaultSavestates:1,
+ UseDefaultMemoryCards:1,
+ UseDefaultLogs:1;
+ }; };
+
wxDirName
Plugins,
Settings,
@@ -57,15 +71,7 @@ public:
wxDirName RunIso; // last used location for Iso loading.
- bool
- UseDefaultPlugins:1,
- UseDefaultSettings:1,
- UseDefaultBios:1,
- UseDefaultSnapshots:1,
- UseDefaultSavestates:1,
- UseDefaultMemoryCards:1,
- UseDefaultLogs:1;
-
+ FolderOptions();
void LoadSave( IniInterface& conf );
void ApplyDefaults();
@@ -96,7 +102,6 @@ public:
};
public:
- bool UseAdminMode; // dictates if the program uses /home/user or /cwd for the program data
wxPoint MainGuiPosition;
// Current language in use (correlates to a wxWidgets wxLANGUAGE specifier)
@@ -140,12 +145,7 @@ protected:
bool m_IsLoaded;
public:
- AppConfig() :
- Listbook_ImageSize( 32 )
- , Toolbar_ImageSize( 24 )
- , m_IsLoaded( false )
- {
- }
+ AppConfig();
wxString FullpathToBios() const;
wxString FullpathToMcd( uint mcdidx ) const;
@@ -156,8 +156,15 @@ public:
void Apply();
void LoadSaveUserMode( IniInterface& ini );
+ wxString GetDefaultDocumentsFolder();
+
protected:
void LoadSave( IniInterface& ini );
};
+class wxFileConfig; // forward declare.
+
+extern wxFileConfig* OpenFileConfig( const wxString& filename );
+extern void AppConfig_ReloadGlobalSettings( bool overwrite = false );
+
extern AppConfig* g_Conf;
diff --git a/pcsx2/gui/Dialogs/ConfigurationDialog.cpp b/pcsx2/gui/Dialogs/ConfigurationDialog.cpp
index 610d9b2327..fd9462b94c 100644
--- a/pcsx2/gui/Dialogs/ConfigurationDialog.cpp
+++ b/pcsx2/gui/Dialogs/ConfigurationDialog.cpp
@@ -67,15 +67,14 @@ Dialogs::ConfigurationDialog::ConfigurationDialog( wxWindow* parent, int id ) :
m_listbook.AddPage( new PluginSelectorPanel( m_listbook, IdealWidth ), _("Plugins"), false, cfgid.Plugins );
g_ApplyState.SetCurrentPage( m_listbook.GetPageCount() );
- m_listbook.AddPage( new PathsPanel( m_listbook, IdealWidth ), _("Folders"), false, cfgid.Paths );
-
+ m_listbook.AddPage( new TabbedPathsPanel( m_listbook, IdealWidth ), _("Folders"), false, cfgid.Paths );
mainSizer.Add( &m_listbook );
AddOkCancel( mainSizer, true );
SetSizerAndFit( &mainSizer );
- Center( wxCENTER_ON_SCREEN | wxBOTH );
+ CenterOnScreen();
Connect( wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ConfigurationDialog::OnOk_Click ) );
Connect( wxID_APPLY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ConfigurationDialog::OnApply_Click ) );
diff --git a/pcsx2/gui/Dialogs/FirstTimeWizard.cpp b/pcsx2/gui/Dialogs/FirstTimeWizard.cpp
new file mode 100644
index 0000000000..6a3aab240d
--- /dev/null
+++ b/pcsx2/gui/Dialogs/FirstTimeWizard.cpp
@@ -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( 0, m_page_usermode ) )
+, m_panel_UsermodeSel( MakeWizWidget( 0, m_page_usermode ) )
+, m_panel_Paths( MakeWizWidget( 0, m_page_usermode ) )
+, m_panel_PluginSel( MakeWizWidget( 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() );
+}
+*/
\ No newline at end of file
diff --git a/pcsx2/gui/Dialogs/ModalPopups.h b/pcsx2/gui/Dialogs/ModalPopups.h
index 62aab9bcea..1f339b6e6e 100644
--- a/pcsx2/gui/Dialogs/ModalPopups.h
+++ b/pcsx2/gui/Dialogs/ModalPopups.h
@@ -18,12 +18,35 @@
#pragma once
-#include
-#include
-
-#include "wxHelpers.h"
#include "Panels/ConfigurationPanels.h"
+#include
+#include
+
+class FirstTimeWizard : public wxWizard
+{
+protected:
+ wxWizardPageSimple& m_page_usermode;
+ //wxWizardPageSimple& m_page_paths;
+ wxWizardPageSimple& m_page_plugins;
+
+ Panels::LanguageSelectionPanel& m_panel_LangSel;
+ Panels::UsermodeSelectionPanel& m_panel_UsermodeSel;
+ Panels::AdvancedPathsPanel& m_panel_Paths;
+ Panels::PluginSelectorPanel& m_panel_PluginSel;
+
+public:
+ FirstTimeWizard( wxWindow* parent );
+ virtual ~FirstTimeWizard();
+
+ wxWizardPage *GetFirstPage() const { return &m_page_usermode; }
+
+protected:
+ virtual void OnPageChanging( wxWizardEvent& evt );
+ virtual void OnPageChanged( wxWizardEvent& evt );
+ virtual void OnUsermodeChanged( wxCommandEvent& evt );
+};
+
namespace Dialogs
{
class AboutBoxDialog: public wxDialog
diff --git a/pcsx2/gui/Dialogs/PickUserModeDialog.cpp b/pcsx2/gui/Dialogs/PickUserModeDialog.cpp
index 259cd227f5..c653652df3 100644
--- a/pcsx2/gui/Dialogs/PickUserModeDialog.cpp
+++ b/pcsx2/gui/Dialogs/PickUserModeDialog.cpp
@@ -26,8 +26,8 @@ using namespace wxHelpers;
Dialogs::PickUserModeDialog::PickUserModeDialog( wxWindow* parent, int id ) :
wxDialogWithHelpers( parent, id, _("PCSX2 First Time configuration"), false )
-, m_panel_usersel( new Panels::UsermodeSelectionPanel( this, 620 ) )
-, m_panel_langsel( new Panels::LanguageSelectionPanel( this, 620 ) )
+, m_panel_usersel( new Panels::UsermodeSelectionPanel( *this, 620, false ) )
+, m_panel_langsel( new Panels::LanguageSelectionPanel( *this, 620 ) )
{
wxBoxSizer& s_main = *new wxBoxSizer( wxVERTICAL );
diff --git a/pcsx2/gui/IniInterface.h b/pcsx2/gui/IniInterface.h
index a3a11c1491..7e28e9d46f 100644
--- a/pcsx2/gui/IniInterface.h
+++ b/pcsx2/gui/IniInterface.h
@@ -151,6 +151,6 @@ protected:
// GCC Note: wxT() macro is required when using string token pasting. For some reason L generates
// syntax errors. >_<
//
-#define IniEntry( varname, defval ) ini.Entry( wxT(#varname), varname, defval )
-#define IniBitfield( varname, defval ) varname = ini.EntryBitfield( wxT(#varname), varname, defval )
-#define IniBitBool( varname, defval ) varname = ini.EntryBitBool( wxT(#varname), !!varname, defval )
+#define IniEntry( varname ) ini.Entry( wxT(#varname), varname, defaults.varname )
+#define IniBitfield( varname ) varname = ini.EntryBitfield( wxT(#varname), varname, defaults.varname )
+#define IniBitBool( varname ) varname = ini.EntryBitBool( wxT(#varname), !!varname, defaults.varname )
diff --git a/pcsx2/gui/Panels/ConfigurationPanels.h b/pcsx2/gui/Panels/ConfigurationPanels.h
index 2c9093d54b..6cc4980689 100644
--- a/pcsx2/gui/Panels/ConfigurationPanels.h
+++ b/pcsx2/gui/Panels/ConfigurationPanels.h
@@ -45,7 +45,7 @@ namespace Exception
{
// --------------------------------------------------------------------------
// Exception used to perform an abort of Apply/Ok action on settings panels.
- // When thrown, the user recieves a popup message containing the information
+ // When thrown, the user receives a popup message containing the information
// specified in the exception message, and is returned to the settings dialog
// to correct the invalid input fields.
//
@@ -79,7 +79,6 @@ namespace Exception
namespace Panels
{
-
typedef std::list PanelApplyList_t;
struct StaticApplyState
@@ -91,9 +90,13 @@ namespace Panels
// this page as their "go here on error" page. (used to take the user to the
// page with the option that failed apply validation).
int CurOwnerPage;
-
+
// TODO : Rename me to CurOwnerBook, or rename the one above to ParentPage.
wxBookCtrlBase* ParentBook;
+
+ // Crappy hack to handle the UseAdminMode option, which can't be part of AppConfig
+ // because AppConfig depends on this value to initialize itself.
+ bool UseAdminMode;
StaticApplyState() :
PanelList()
@@ -106,14 +109,16 @@ namespace Panels
{
CurOwnerPage = page;
}
-
+
void ClearCurrentPage()
{
CurOwnerPage = wxID_NONE;
}
void StartBook( wxBookCtrlBase* book );
+ void StartWizard();
bool ApplyAll();
+ bool ApplyPage( int pageid );
void DoCleanup();
};
@@ -124,8 +129,8 @@ namespace Panels
// window (usually the ConfigurationDialog) when either Ok or Apply is clicked.
//
// Thread Safety: None. This class is only safe when used from the GUI thread, as it uses
- // static vars and assumes that only one Applicableconfig system is available to the
- // use rate any time (ie, a singular modal dialog).
+ // static vars and assumes that only one ApplicableConfig system is available to the
+ // user at any time (ie, a singular modal dialog).
//
class BaseApplicableConfigPanel : public wxPanelWithHelpers
{
@@ -156,6 +161,10 @@ namespace Panels
m_OwnerBook->SetSelection( m_OwnerPage );
}
+ // Returns true if this ConfigPanel belongs to the specified page. Useful for doing
+ // selective application of options for specific pages.
+ bool IsOnPage( int pageid ) { return m_OwnerPage == pageid; }
+
// This method attempts to assign the settings for the panel into the given
// configuration structure (which is typically a copy of g_Conf). If validation
// of form contents fails, the function should throw Exception::CannotApplySettings.
@@ -173,7 +182,7 @@ namespace Panels
public:
virtual ~UsermodeSelectionPanel() { }
- UsermodeSelectionPanel( wxWindow* parent, int idealWidth=wxDefaultCoord );
+ UsermodeSelectionPanel( wxWindow& parent, int idealWidth=wxDefaultCoord, bool isFirstTime = true );
void Apply( AppConfig& conf );
};
@@ -188,7 +197,7 @@ namespace Panels
public:
virtual ~LanguageSelectionPanel() { }
- LanguageSelectionPanel( wxWindow* parent, int idealWidth=wxDefaultCoord );
+ LanguageSelectionPanel( wxWindow& parent, int idealWidth=wxDefaultCoord );
void Apply( AppConfig& conf );
};
@@ -251,53 +260,73 @@ namespace Panels
};
//////////////////////////////////////////////////////////////////////////////////////////
+ // DirPickerPanel
+ // A simple panel which provides a specialized configurable directory picker with a
+ // "[x] Use Default setting" option, which enables or disables the panel.
//
- class PathsPanel : public BaseApplicableConfigPanel
+ class DirPickerPanel : public BaseApplicableConfigPanel
{
protected:
- class DirPickerPanel : public BaseApplicableConfigPanel
- {
- protected:
- FoldersEnum_t m_FolderId;
- wxDirPickerCtrl* m_pickerCtrl;
- wxCheckBox* m_checkCtrl;
-
- public:
- DirPickerPanel( wxWindow* parent, FoldersEnum_t folderid, const wxString& label, const wxString& dialogLabel );
- void Apply( AppConfig& conf );
-
- protected:
- void UseDefaultPath_Click(wxCommandEvent &event);
- void UpdateCheckStatus( bool someNoteworthyBoolean );
- };
-
- class MyBasePanel : public wxPanelWithHelpers
- {
- protected:
- wxBoxSizer& s_main;
-
- public:
- MyBasePanel( wxWindow& parent, int idealWidth=wxDefaultCoord );
-
- protected:
- DirPickerPanel& AddDirPicker( wxBoxSizer& sizer, FoldersEnum_t folderid,
- const wxString& label, const wxString& popupLabel );
- };
-
- class StandardPanel : public MyBasePanel
- {
- public:
- StandardPanel( wxWindow& parent );
- };
-
- class AdvancedPanel : public MyBasePanel
- {
- public:
- AdvancedPanel( wxWindow& parent, int idealWidth );
- };
+ FoldersEnum_t m_FolderId;
+ wxDirPickerCtrl* m_pickerCtrl;
+ wxCheckBox* m_checkCtrl;
public:
- PathsPanel( wxWindow& parent, int idealWidth );
+ DirPickerPanel( wxWindow* parent, FoldersEnum_t folderid, const wxString& label, const wxString& dialogLabel );
+ void Apply( AppConfig& conf );
+ void Reset();
+
+ protected:
+ void UseDefaultPath_Click(wxCommandEvent &event);
+ void UpdateCheckStatus( bool someNoteworthyBoolean );
+ };
+
+ //////////////////////////////////////////////////////////////////////////////////////////
+ //
+ class BasePathsPanel : public wxPanelWithHelpers
+ {
+ protected:
+ wxBoxSizer& s_main;
+
+ public:
+ BasePathsPanel( wxWindow& parent, int idealWidth=wxDefaultCoord );
+ virtual wxSizer& Sizer() { return s_main; }
+
+ protected:
+ DirPickerPanel& AddDirPicker( wxBoxSizer& sizer, FoldersEnum_t folderid,
+ const wxString& label, const wxString& popupLabel );
+ };
+
+ //////////////////////////////////////////////////////////////////////////////////////////
+ //
+ class StandardPathsPanel : public BasePathsPanel
+ {
+ public:
+ StandardPathsPanel( wxWindow& parent );
+ };
+
+ //////////////////////////////////////////////////////////////////////////////////////////
+ //
+ class AdvancedPathsPanel : public BasePathsPanel
+ {
+ protected:
+ DirPickerPanel& m_dirpick_plugins;
+ DirPickerPanel& m_dirpick_settings;
+
+ public:
+ AdvancedPathsPanel( wxWindow& parent, int idealWidth );
+ void Reset();
+ };
+
+ //////////////////////////////////////////////////////////////////////////////////////////
+ // TabbedPathsPanel
+ // This panel is a Tabbed (paged) panel which contains both Standard Paths and Advanced
+ // Paths panels.
+ //
+ class TabbedPathsPanel : public BaseApplicableConfigPanel
+ {
+ public:
+ TabbedPathsPanel( wxWindow& parent, int idealWidth );
void Apply( AppConfig& conf );
};
@@ -368,7 +397,9 @@ namespace Panels
int m_progress;
public:
- StatusPanel( wxWindow* parent, int pluginCount, int biosCount );
+ StatusPanel( wxWindow* parent );
+
+ void SetGaugeLength( int len );
void AdvanceProgress( const wxString& msg );
void Reset();
};
@@ -378,27 +409,30 @@ namespace Panels
// ------------------------------------------------------------------------
protected:
- wxArrayString m_FileList; // list of potential plugin files
- wxArrayString m_BiosList;
+ wxArrayString* m_FileList; // list of potential plugin files
+ wxArrayString* m_BiosList;
StatusPanel& m_StatusPanel;
ComboBoxPanel& m_ComponentBoxes;
- bool m_Uninitialized;
EnumThread* m_EnumeratorThread;
public:
virtual ~PluginSelectorPanel();
PluginSelectorPanel( wxWindow& parent, int idealWidth );
- virtual void OnShow( wxShowEvent& evt );
- virtual void OnRefresh( wxCommandEvent& evt );
virtual void OnProgress( wxCommandEvent& evt );
virtual void OnEnumComplete( wxCommandEvent& evt );
void Apply( AppConfig& conf );
-
+ void OnShow();
+
protected:
+ virtual void OnShow( wxShowEvent& evt );
+ virtual void OnRefresh( wxCommandEvent& evt );
+
void DoRefresh();
- int FileCount() const { return m_FileList.Count(); }
- const wxString& GetFilename( int i ) const { return m_FileList[i]; }
+ bool ValidateEnumerationStatus();
+
+ int FileCount() const { return m_FileList->Count(); }
+ const wxString& GetFilename( int i ) const { return (*m_FileList)[i]; }
friend class EnumThread;
};
}
diff --git a/pcsx2/gui/Panels/MiscPanelStuff.cpp b/pcsx2/gui/Panels/MiscPanelStuff.cpp
index d62bccc198..f552c9b104 100644
--- a/pcsx2/gui/Panels/MiscPanelStuff.cpp
+++ b/pcsx2/gui/Panels/MiscPanelStuff.cpp
@@ -18,6 +18,7 @@
#include "PrecompiledHeader.h"
#include "ConfigurationPanels.h"
+#include "ps2/BiosTools.h"
#include
@@ -43,22 +44,35 @@ void Panels::StaticApplyState::StartBook( wxBookCtrlBase* book )
ParentBook = book;
}
+void Panels::StaticApplyState::StartWizard()
+{
+ DevAssert( ParentBook == NULL, "An ApplicableConfig session is already in progress." );
+}
+
// -----------------------------------------------------------------------
+//
+// Parameters:
+// pageid - identifier of the page to apply settings for. All other pages will be
+// skipped. If pageid is negative (-1) then all pages are applied.
+//
// Returns false if one of the panels fails input validation (in which case dialogs
// should not be closed, etc).
//
-bool Panels::StaticApplyState::ApplyAll()
+bool Panels::StaticApplyState::ApplyPage( int pageid )
{
bool retval = true;
try
{
AppConfig confcopy( *g_Conf );
+ g_ApplyState.UseAdminMode = UseAdminMode;
+
PanelApplyList_t::iterator yay = PanelList.begin();
while( yay != PanelList.end() )
{
//DbgCon::Status( L"Writing settings for: " + (*yay)->GetLabel() );
- (*yay)->Apply( confcopy );
+ if( (pageid < 0) || (*yay)->IsOnPage( pageid ) )
+ (*yay)->Apply( confcopy );
yay++;
}
@@ -66,6 +80,7 @@ bool Panels::StaticApplyState::ApplyAll()
// (conveniently skipping any option application! :D)
*g_Conf = confcopy;
+ UseAdminMode = g_ApplyState.UseAdminMode;
g_Conf->Apply();
g_Conf->Save();
}
@@ -77,28 +92,43 @@ bool Panels::StaticApplyState::ApplyAll()
ex.GetPanel()->SetFocusToMe();
retval = false;
-
}
- return retval;
+ return retval;
+}
+
+// Returns false if one of the panels fails input validation (in which case dialogs
+// should not be closed, etc).
+bool Panels::StaticApplyState::ApplyAll()
+{
+ return ApplyPage( -1 );
}
// -----------------------------------------------------------------------
-Panels::UsermodeSelectionPanel::UsermodeSelectionPanel( wxWindow* parent, int idealWidth ) :
- BaseApplicableConfigPanel( parent, idealWidth )
+Panels::UsermodeSelectionPanel::UsermodeSelectionPanel( wxWindow& parent, int idealWidth, bool isFirstTime ) :
+ BaseApplicableConfigPanel( &parent, idealWidth )
, m_radio_user( NULL )
, m_radio_cwd( NULL )
{
- wxStaticBoxSizer& s_boxer = *new wxStaticBoxSizer( wxVERTICAL, this, _( "Usermode Selection" ) );
- AddStaticText( s_boxer, pxE( ".Panels:Usermode:Explained",
+ const wxString usermodeExplained( pxE( ".Panels:Usermode:Explained",
L"Please select your preferred default location for PCSX2 user-level documents below "
L"(includes memory cards, screenshots, settings, and savestates). "
L"These folder locations can be overridden at any time using the Core Settings panel."
) );
+
+ const wxString usermodeWarning( pxE( ".Panels:Usermode:Warning",
+ L"You can change the preferred default location for PCSX2 user-level documents here "
+ L"(includes memory cards, screenshots, settings, and savestates). "
+ L"This option only affects Standard Paths which are set to use the installation default value."
+ ) );
+
+ wxStaticBoxSizer& s_boxer = *new wxStaticBoxSizer( wxVERTICAL, this, _( "Usermode Selection" ) );
+ AddStaticText( s_boxer, isFirstTime ? usermodeExplained : usermodeWarning );
m_radio_user = &AddRadioButton( s_boxer, _("User Documents (recommended)"), _("Location: ") + wxStandardPaths::Get().GetDocumentsDir() );
s_boxer.AddSpacer( 4 );
- m_radio_cwd = &AddRadioButton( s_boxer, _("Current working folder (intended for developer use only)"), _("Location: ") + wxGetCwd() );
+ m_radio_cwd = &AddRadioButton( s_boxer, _("Current working folder (intended for developer use only)"), _("Location: ") + wxGetCwd(),
+ _("This setting requires administration privlidges from your operating system.") );
s_boxer.AddSpacer( 4 );
SetSizerAndFit( &s_boxer );
@@ -108,12 +138,13 @@ void Panels::UsermodeSelectionPanel::Apply( AppConfig& conf )
{
if( !m_radio_cwd->GetValue() && !m_radio_user->GetValue() )
throw Exception::CannotApplySettings( this, wxLt( "You must select one of the available user modes before proceeding." ) );
- conf.UseAdminMode = m_radio_cwd->GetValue();
+
+ g_ApplyState.UseAdminMode = m_radio_cwd->GetValue();
}
// -----------------------------------------------------------------------
-Panels::LanguageSelectionPanel::LanguageSelectionPanel( wxWindow* parent, int idealWidth ) :
- BaseApplicableConfigPanel( parent, idealWidth )
+Panels::LanguageSelectionPanel::LanguageSelectionPanel( wxWindow& parent, int idealWidth ) :
+ BaseApplicableConfigPanel( &parent, idealWidth )
, m_langs()
, m_picker( NULL )
{
diff --git a/pcsx2/gui/Panels/PathsPanel.cpp b/pcsx2/gui/Panels/PathsPanel.cpp
index d8c27ca7e6..f77e42da11 100644
--- a/pcsx2/gui/Panels/PathsPanel.cpp
+++ b/pcsx2/gui/Panels/PathsPanel.cpp
@@ -25,15 +25,27 @@
using namespace wxHelpers;
static const int BetweenFolderSpace = 5;
+static wxString GetNormalizedConfigFolder( FoldersEnum_t folderId )
+{
+ const bool isDefault = g_Conf->Folders.IsDefault( folderId );
+ wxDirName normalized( isDefault ? g_Conf->Folders[folderId] : PathDefs::Get(folderId) );
+ normalized.Normalize( wxPATH_NORM_ALL );
+ return normalized.ToString();
+}
+
// Pass me TRUE if the default path is to be used, and the DirPcikerCtrl disabled from use.
-void Panels::PathsPanel::DirPickerPanel::UpdateCheckStatus( bool someNoteworthyBoolean )
+void Panels::DirPickerPanel::UpdateCheckStatus( bool someNoteworthyBoolean )
{
m_pickerCtrl->Enable( !someNoteworthyBoolean );
if( someNoteworthyBoolean )
- m_pickerCtrl->SetPath( PathDefs::Get( m_FolderId ).ToString() );
+ {
+ wxDirName normalized( PathDefs::Get( m_FolderId ) );
+ normalized.Normalize( wxPATH_NORM_ALL );
+ m_pickerCtrl->SetPath( normalized.ToString() );
+ }
}
-void Panels::PathsPanel::DirPickerPanel::UseDefaultPath_Click(wxCommandEvent &event)
+void Panels::DirPickerPanel::UseDefaultPath_Click(wxCommandEvent &event)
{
wxASSERT( m_pickerCtrl != NULL && m_checkCtrl != NULL );
UpdateCheckStatus( m_checkCtrl->IsChecked() );
@@ -43,47 +55,50 @@ void Panels::PathsPanel::DirPickerPanel::UseDefaultPath_Click(wxCommandEvent &ev
// If initPath is NULL, then it's assumed the default folder is to be used, which is
// obtained from invoking the specified getDefault() function.
//
-Panels::PathsPanel::DirPickerPanel::DirPickerPanel( wxWindow* parent, FoldersEnum_t folderid,
+Panels::DirPickerPanel::DirPickerPanel( wxWindow* parent, FoldersEnum_t folderid,
const wxString& label, const wxString& dialogLabel ) :
BaseApplicableConfigPanel( parent, wxDefaultCoord )
, m_FolderId( folderid )
{
- const bool isDefault = g_Conf->Folders.IsDefault( m_FolderId );
- wxDirName normalized( isDefault ? g_Conf->Folders[m_FolderId] : PathDefs::Get(m_FolderId) );
- normalized.Normalize();
-
wxStaticBoxSizer& s_box = *new wxStaticBoxSizer( wxVERTICAL, this, label );
// Force the Dir Picker to use a text control. This isn't standard on Linux/GTK but it's much
// more usable, so to hell with standards.
- m_pickerCtrl = new wxDirPickerCtrl( this, wxID_ANY, normalized.ToString(), dialogLabel,
+ m_pickerCtrl = new wxDirPickerCtrl( this, wxID_ANY, GetNormalizedConfigFolder( m_FolderId ), dialogLabel,
wxDefaultPosition, wxDefaultSize, wxDIRP_USE_TEXTCTRL | wxDIRP_DIR_MUST_EXIST
);
s_box.Add( m_pickerCtrl, wxSizerFlags().Border(wxLEFT | wxRIGHT | wxTOP, 5).Expand() );
m_checkCtrl = &AddCheckBox( s_box, _("Use installation default setting") );
+
+ const bool isDefault = g_Conf->Folders.IsDefault( m_FolderId );
m_checkCtrl->SetValue( isDefault );
UpdateCheckStatus( isDefault );
SetSizerAndFit( &s_box );
- Connect( m_checkCtrl->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( PathsPanel::DirPickerPanel::UseDefaultPath_Click ) );
+ Connect( m_checkCtrl->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DirPickerPanel::UseDefaultPath_Click ) );
}
-void Panels::PathsPanel::DirPickerPanel::Apply( AppConfig& conf )
+void Panels::DirPickerPanel::Reset()
+{
+ m_pickerCtrl->SetPath( GetNormalizedConfigFolder( m_FolderId ) );
+}
+
+void Panels::DirPickerPanel::Apply( AppConfig& conf )
{
conf.Folders.Set( m_FolderId, m_pickerCtrl->GetPath(), m_checkCtrl->GetValue() );
}
// ------------------------------------------------------------------------
-Panels::PathsPanel::MyBasePanel::MyBasePanel( wxWindow& parent, int idealWidth ) :
+Panels::BasePathsPanel::BasePathsPanel( wxWindow& parent, int idealWidth ) :
wxPanelWithHelpers( &parent, idealWidth-12 )
, s_main( *new wxBoxSizer( wxVERTICAL ) )
{
}
-Panels::PathsPanel::DirPickerPanel& Panels::PathsPanel::MyBasePanel::AddDirPicker( wxBoxSizer& sizer,
+Panels::DirPickerPanel& Panels::BasePathsPanel::AddDirPicker( wxBoxSizer& sizer,
FoldersEnum_t folderid, const wxString& label, const wxString& popupLabel )
{
DirPickerPanel* dpan = new DirPickerPanel( this, folderid, label, popupLabel );
@@ -92,8 +107,8 @@ Panels::PathsPanel::DirPickerPanel& Panels::PathsPanel::MyBasePanel::AddDirPicke
}
// ------------------------------------------------------------------------
-Panels::PathsPanel::StandardPanel::StandardPanel( wxWindow& parent ) :
- MyBasePanel( parent )
+Panels::StandardPathsPanel::StandardPathsPanel( wxWindow& parent ) :
+ BasePathsPanel( parent )
{
// TODO : Replace the callback mess here with the new FolderId enumeration setup. :)
@@ -146,56 +161,77 @@ Panels::PathsPanel::StandardPanel::StandardPanel( wxWindow& parent ) :
}
// ------------------------------------------------------------------------
-Panels::PathsPanel::AdvancedPanel::AdvancedPanel( wxWindow& parent, int idealWidth ) :
- MyBasePanel( parent, idealWidth-9 )
+Panels::AdvancedPathsPanel::AdvancedPathsPanel( wxWindow& parent, int idealWidth ) :
+ BasePathsPanel( parent, idealWidth-9 )
+
+, m_dirpick_plugins(
+ AddDirPicker( s_main, FolderId_Plugins,
+ _("Plugins folder:"),
+ _("Select a PCSX2 plugins folder")
+ )
+ )
+
+, m_dirpick_settings( (
+ s_main.AddSpacer( BetweenFolderSpace ),
+ AddDirPicker( s_main, FolderId_Settings,
+ _("Settings folder:"),
+ _("Select location to save PCSX2 settings to")
+ )
+ ) )
{
- wxStaticBoxSizer& advanced = *new wxStaticBoxSizer( wxVERTICAL, this, _("Advanced") );
- AddStaticText( advanced, pxE( ".Panels:Folders:Advanced",
- L"Warning!! These advanced options are provided for developers and advanced testers only. "
- L"Changing these settings can cause program errors, so please be weary."
+ m_dirpick_plugins.SetToolTip( pxE( ".Tooltips:Folders:Plugins",
+ L"This is the location where PCSX2 will expect to find its plugins. Plugins found in this folder "
+ L"will be enumerated and are selectable from the Plugins panel."
) );
- AddDirPicker( advanced, FolderId_Plugins,
- _("Plugins:"),
- _("Select folder for PCSX2 plugins") ).
- SetToolTip( pxE( ".Tooltips:Folders:Plugins",
- L"This is the location where PCSX2 will expect to find its plugins. Plugins found in this folder "
- L"will be enumerated and are selectable from the Plugins panel."
- ) );
-
- advanced.AddSpacer( BetweenFolderSpace );
- AddDirPicker( advanced, FolderId_Settings,
- _("Settings:"),
- _("Select a folder for PCSX2 settings/inis") ).
- SetToolTip( pxE( ".Tooltips:Folders:Settings",
- L"This is the folder where PCSX2 saves all settings, including settings generated "
- L"by most plugins.\n\nWarning: Some older versions of plugins may not respect this value."
- ) );
-
- advanced.AddSpacer( 4 );
- advanced.Add( new UsermodeSelectionPanel( this, GetIdealWidth()-9 ), SizerFlags::SubGroup() );
-
- s_main.Add( &advanced, SizerFlags::SubGroup() );
- s_main.AddSpacer( 5 );
+ m_dirpick_settings.SetToolTip( pxE( ".Tooltips:Folders:Settings",
+ L"This is the folder where PCSX2 saves all settings, including settings generated "
+ L"by most plugins.\n\nWarning: Some older versions of plugins may not respect this value."
+ ) );
SetSizerAndFit( &s_main );
}
+void Panels::AdvancedPathsPanel::Reset()
+{
+ m_dirpick_plugins.Reset();
+ m_dirpick_settings.Reset();
+}
+
// ------------------------------------------------------------------------
-Panels::PathsPanel::PathsPanel( wxWindow& parent, int idealWidth ) :
+Panels::TabbedPathsPanel::TabbedPathsPanel( wxWindow& parent, int idealWidth ) :
BaseApplicableConfigPanel( &parent, idealWidth )
{
wxBoxSizer& s_main = *new wxBoxSizer( wxVERTICAL );
wxNotebook& notebook = *new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_BOTTOM | wxNB_FIXEDWIDTH );
- notebook.AddPage( new StandardPanel( notebook ), _("Standard") );
- notebook.AddPage( new AdvancedPanel( notebook, GetIdealWidth() ), _("Advanced") );
+ StandardPathsPanel& stah( *new StandardPathsPanel( notebook ) );
+ AdvancedPathsPanel& apah( *new AdvancedPathsPanel( notebook, GetIdealWidth() ) );
+ notebook.AddPage( &stah, _("Standard") );
+ notebook.AddPage( &apah, _("Advanced") );
+
+ // Advanced Tab uses the Advanced Panel with some extra features.
+ // This is because the extra features are not present on the Wizard version of the Advanced Panel.
+
+ wxStaticBoxSizer& advanced = *new wxStaticBoxSizer( wxVERTICAL, this, _("Advanced") );
+ AddStaticText( advanced, pxE( ".Panels:Folders:Advanced",
+ L"Warning!! These advanced options are provided for developers and advanced testers only. "
+ L"Changing these settings can cause program errors and may require administration privlidges, "
+ L"so please be weary."
+ ) );
+
+ advanced.Add( new UsermodeSelectionPanel( *this, GetIdealWidth()-9 ), SizerFlags::SubGroup() );
+ advanced.AddSpacer( 4 );
+ advanced.Add( &apah.Sizer(), SizerFlags::SubGroup() );
+
+ apah.SetSizer( &advanced, false );
+ apah.Fit();
s_main.Add( ¬ebook, SizerFlags::StdSpace() );
SetSizerAndFit( &s_main );
}
-void Panels::PathsPanel::Apply( AppConfig& conf )
+void Panels::TabbedPathsPanel::Apply( AppConfig& conf )
{
}
diff --git a/pcsx2/gui/Panels/PluginSelectorPanel.cpp b/pcsx2/gui/Panels/PluginSelectorPanel.cpp
index 3d67a83da8..316eb202bb 100644
--- a/pcsx2/gui/Panels/PluginSelectorPanel.cpp
+++ b/pcsx2/gui/Panels/PluginSelectorPanel.cpp
@@ -17,6 +17,7 @@
*/
#include "PrecompiledHeader.h"
+#include "Utilities/ScopedPtr.h"
#include "Plugins.h"
#include "ConfigurationPanels.h"
#include "ps2/BiosTools.h"
@@ -117,9 +118,9 @@ public:
static const wxString failed_separator( L"-------- Unsupported Plugins --------" );
// ------------------------------------------------------------------------
-Panels::PluginSelectorPanel::StatusPanel::StatusPanel( wxWindow* parent, int pluginCount, __unused int biosCount ) :
+Panels::PluginSelectorPanel::StatusPanel::StatusPanel( wxWindow* parent ) :
wxPanelWithHelpers( parent )
-, m_gauge( *new wxGauge( this, wxID_ANY, pluginCount ) )
+, m_gauge( *new wxGauge( this, wxID_ANY, 10 ) )
, m_label( *new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE | wxST_NO_AUTORESIZE ) )
, m_progress( 0 )
{
@@ -132,6 +133,11 @@ Panels::PluginSelectorPanel::StatusPanel::StatusPanel( wxWindow* parent, int plu
SetSizerAndFit( &s_main );
}
+void Panels::PluginSelectorPanel::StatusPanel::SetGaugeLength( int len )
+{
+ m_gauge.SetRange( len );
+}
+
void Panels::PluginSelectorPanel::StatusPanel::AdvanceProgress( const wxString& msg )
{
m_label.SetLabel( msg );
@@ -183,15 +189,14 @@ void Panels::PluginSelectorPanel::ComboBoxPanel::Reset()
// ------------------------------------------------------------------------
Panels::PluginSelectorPanel::PluginSelectorPanel( wxWindow& parent, int idealWidth ) :
BaseApplicableConfigPanel( &parent, idealWidth )
-, m_FileList()
-, m_StatusPanel( *new StatusPanel( this,
- wxDir::GetAllFiles( g_Conf->Folders.Plugins.ToString(), &m_FileList, wxsFormat( L"*%s", wxDynamicLibrary::GetDllExt()), wxDIR_FILES ),
- wxDir::GetAllFiles( g_Conf->Folders.Bios.ToString(), &m_BiosList, L"*.bin", wxDIR_FILES )
- ) )
+, m_FileList( NULL )
+, m_BiosList( NULL )
+, m_StatusPanel( *new StatusPanel( this ) )
, m_ComponentBoxes( *new ComboBoxPanel( this ) )
-, m_Uninitialized( true )
, m_EnumeratorThread( NULL )
{
+ //ValidateEnumerationStatus();
+
wxBoxSizer& s_main = *new wxBoxSizer( wxVERTICAL );
s_main.Add( &m_ComponentBoxes, SizerFlags::StdExpand().ReserveSpaceEvenIfHidden() );
@@ -208,7 +213,7 @@ Panels::PluginSelectorPanel::PluginSelectorPanel( wxWindow& parent, int idealWid
SetSizerAndFit( &s_main );
- Connect( GetId(), wxEVT_SHOW, wxShowEventHandler( PluginSelectorPanel::OnShow ) );
+ Connect( GetId(), wxEVT_SHOW, wxShowEventHandler( PluginSelectorPanel::OnShow ) );
Connect( wxEVT_EnumeratedNext, wxCommandEventHandler( PluginSelectorPanel::OnProgress ) );
Connect( wxEVT_EnumerationFinished, wxCommandEventHandler( PluginSelectorPanel::OnEnumComplete ) );
@@ -222,6 +227,8 @@ Panels::PluginSelectorPanel::~PluginSelectorPanel()
// Kill the thread if it's alive.
safe_delete( m_EnumeratorThread );
+ safe_delete( m_FileList );
+ safe_delete( m_BiosList );
}
void Panels::PluginSelectorPanel::Apply( AppConfig& conf )
@@ -247,7 +254,7 @@ void Panels::PluginSelectorPanel::Apply( AppConfig& conf )
);
}
- wxFileName relative( m_FileList[(int)m_ComponentBoxes.Get(i).GetClientData(sel)] );
+ wxFileName relative( GetFilename((int)m_ComponentBoxes.Get(i).GetClientData(sel)) );
relative.MakeRelativeTo( g_Conf->Folders.Plugins.ToString() );
conf.BaseFilenames.Plugins[tbl_PluginInfo[i].id] = relative.GetFullPath();
}
@@ -266,15 +273,13 @@ void Panels::PluginSelectorPanel::Apply( AppConfig& conf )
)
);
}
- wxFileName relative( m_BiosList[(int)m_ComponentBoxes.GetBios().GetClientData(sel)] );
+ wxFileName relative( (*m_BiosList)[(int)m_ComponentBoxes.GetBios().GetClientData(sel)] );
relative.MakeRelativeTo( g_Conf->Folders.Bios.ToString() );
conf.BaseFilenames.Bios = relative.GetFullPath();
}
void Panels::PluginSelectorPanel::DoRefresh()
{
- m_Uninitialized = false;
-
// Disable all controls until enumeration is complete.
m_ComponentBoxes.Hide();
@@ -284,22 +289,64 @@ void Panels::PluginSelectorPanel::DoRefresh()
safe_delete( m_EnumeratorThread );
m_EnumeratorThread = new EnumThread( *this );
m_EnumeratorThread->Start();
+
+ m_ComponentBoxes.Reset();
+}
+
+bool Panels::PluginSelectorPanel::ValidateEnumerationStatus()
+{
+ bool validated = true;
+
+ // re-enumerate plugins and bioses, and if anything changed then we need to wipe
+ // the contents of the combo boxes and re-enumerate everything.
+
+ // Impl Note: ScopedPtr used so that resources get cleaned up if an exception
+ // occurs during file enumeration.
+ wxScopedPtr pluginlist( new wxArrayString() );
+ wxScopedPtr bioslist( new wxArrayString() );
+
+ int pluggers = EnumeratePluginsFolder( pluginlist.get() );
+
+ if( g_Conf->Folders.Bios.Exists() )
+ wxDir::GetAllFiles( g_Conf->Folders.Bios.ToString(), bioslist.get(), L"*.bin", wxDIR_FILES );
+
+ if( (m_FileList == NULL) || (*pluginlist != *m_FileList) )
+ validated = false;
+
+ if( (m_BiosList == NULL) || (*bioslist != *m_BiosList) )
+ validated = false;
+
+ delete m_FileList;
+ delete m_BiosList;
+ m_FileList = pluginlist.release();
+ m_BiosList = bioslist.release();
+
+ m_StatusPanel.SetGaugeLength( pluggers );
+
+ return validated;
}
// ------------------------------------------------------------------------
+
+// This overload of OnShow is invoked by wizards, since the wxWizard won't raise
+// SHOW events. >_< (only called for show events and not hide events)
+void Panels::PluginSelectorPanel::OnShow()
+{
+ if( !ValidateEnumerationStatus() )
+ DoRefresh();
+}
+
void Panels::PluginSelectorPanel::OnShow( wxShowEvent& evt )
{
evt.Skip();
if( !evt.GetShow() ) return;
- if( !m_Uninitialized ) return;
-
- DoRefresh();
+ OnShow();
}
void Panels::PluginSelectorPanel::OnRefresh( wxCommandEvent& evt )
{
- m_ComponentBoxes.Reset();
+ ValidateEnumerationStatus();
DoRefresh();
}
@@ -314,13 +361,13 @@ void Panels::PluginSelectorPanel::OnEnumComplete( wxCommandEvent& evt )
wxFileName right( g_Conf->FullpathToBios() );
right.MakeRelativeTo( g_Conf->Folders.Plugins.ToString() );
- for( size_t i=0; iGetCount(); ++i )
{
wxString description;
- if( !IsBIOS(m_BiosList[i], description) ) continue;
+ if( !IsBIOS((*m_BiosList)[i], description) ) continue;
int sel = m_ComponentBoxes.GetBios().Append( description, (void*)i );
- wxFileName left( m_BiosList[i] );
+ wxFileName left( (*m_BiosList)[i] );
left.MakeRelativeTo( g_Conf->Folders.Plugins.ToString() );
if( left == right )
@@ -358,15 +405,15 @@ void Panels::PluginSelectorPanel::OnEnumComplete( wxCommandEvent& evt )
void Panels::PluginSelectorPanel::OnProgress( wxCommandEvent& evt )
{
size_t evtidx = evt.GetExtraLong();
- m_StatusPanel.AdvanceProgress( (evtidx < m_FileList.Count()-1) ?
- m_FileList[evtidx + 1] : wxString(_("Completing tasks..."))
+ m_StatusPanel.AdvanceProgress( (evtidx < m_FileList->Count()-1) ?
+ (*m_FileList)[evtidx + 1] : wxString(_("Completing tasks..."))
);
EnumeratedPluginInfo& result( m_EnumeratorThread->Results[evtidx] );
if( result.TypeMask == 0 )
{
- Console::Error( L"Some kinda plugin failure: " + m_FileList[evtidx] );
+ Console::Error( L"Some kinda plugin failure: " + (*m_FileList)[evtidx] );
}
for( int i=0; iFullpathTo(tbl_PluginInfo[i].id) );
left.MakeRelativeTo( g_Conf->Folders.Plugins.ToString() );
diff --git a/pcsx2/gui/main.cpp b/pcsx2/gui/main.cpp
index 2c863466c2..192c2274c0 100644
--- a/pcsx2/gui/main.cpp
+++ b/pcsx2/gui/main.cpp
@@ -21,6 +21,8 @@
#include "MainFrame.h"
#include "Dialogs/ModalPopups.h"
+#include "Utilities/ScopedPtr.h"
+
#include "Resources/EmbeddedImage.h"
#include "Resources/BackgroundLogo.h"
@@ -28,6 +30,7 @@
IMPLEMENT_APP(Pcsx2App)
+bool UseAdminMode = false;
AppConfig* g_Conf = NULL;
wxFileHistory* g_RecentIsoList = NULL;
CoreEmuThread* g_EmuThread = NULL;
@@ -62,64 +65,34 @@ Pcsx2App::Pcsx2App() :
wxFrame* Pcsx2App::GetMainWindow() const { return m_MainFrame; }
-wxFileConfig* OpenConfig( const wxString& filename )
-{
- return new wxFileConfig( wxEmptyString, wxEmptyString, filename, wxEmptyString, wxCONFIG_USE_RELATIVE_PATH );
-}
-
void Pcsx2App::ReadUserModeSettings()
{
wxFileName usermodefile( FilenameDefs::GetUsermodeConfig() );
usermodefile.SetPath( wxGetCwd() );
-
- wxFileConfig* conf_usermode = OpenConfig( usermodefile.GetFullPath() );
+ wxScopedPtr conf_usermode( OpenFileConfig( usermodefile.GetFullPath() ) );
if( !wxFile::Exists( usermodefile.GetFullPath() ) )
{
// first time startup, so give the user the choice of user mode:
- if( Dialogs::PickUserModeDialog( NULL ).ShowModal() == wxID_CANCEL )
- throw Exception::StartupAborted( L"Startup aborted: User cancelled Usermode selection." );
-
+ //if( Dialogs::PickUserModeDialog( NULL ).ShowModal() == wxID_CANCEL )
+ FirstTimeWizard wiz( NULL );
+ if( !wiz.RunWizard( wiz.GetFirstPage() ) )
+ throw Exception::StartupAborted( L"Startup aborted: User canceled FirstTime Wizard." );
+
// Save user's new settings
- if( conf_usermode != NULL )
- {
- IniSaver saver( *conf_usermode );
- g_Conf->LoadSaveUserMode( saver );
- }
+ IniSaver saver( *conf_usermode );
+ g_Conf->LoadSaveUserMode( saver );
+ g_Conf->Save();
}
else
{
// usermode.ini exists -- assume Documents mode, unless the ini explicitly
// specifies otherwise.
- g_Conf->UseAdminMode = false;
+ UseAdminMode = false;
- if( conf_usermode != NULL )
- {
- IniLoader loader( *conf_usermode );
- g_Conf->LoadSaveUserMode( loader );
- }
+ IniLoader loader( *conf_usermode );
+ g_Conf->LoadSaveUserMode( loader );
}
-
- safe_delete( conf_usermode );
-}
-
-// ------------------------------------------------------------------------
-// returns true if a configuration file is present in the current working dir (cwd).
-// returns false if not (in which case the calling code should fall back on using OpenConfigUserLocal())
-//
-bool Pcsx2App::TryOpenConfigCwd()
-{
- ReadUserModeSettings();
-
- wxDirName inipath_cwd( (wxDirName)wxGetCwd() + PathDefs::Base::Settings() );
- if( !inipath_cwd.IsReadable() ) return false;
-
- wxString inifile_cwd( Path::Combine( inipath_cwd, FilenameDefs::GetConfig() ) );
- if( !Path::IsFile( inifile_cwd ) ) return false;
- if( Path::GetFileSize( inifile_cwd ) <= 1 ) return false;
-
- wxConfigBase::Set( OpenConfig( inifile_cwd ) );
- return true;
}
void Pcsx2App::OnInitCmdLine( wxCmdLineParser& parser )
@@ -184,20 +157,9 @@ bool Pcsx2App::OnInit()
try
{
- if( !TryOpenConfigCwd() )
- {
- PathDefs::GetDocuments().Mkdir();
- PathDefs::GetSettings().Mkdir();
+ ReadUserModeSettings();
- // Allow wx to use our config, and enforces auto-cleanup as well
- wxString confile( Path::Combine( PathDefs::GetSettings(), FilenameDefs::GetConfig() ) );
- wxConfigBase::Set( OpenConfig( confile ) );
- wxConfigBase::Get()->SetRecordDefaults();
- }
- g_Conf->Load();
- g_Conf->Apply();
-
- g_Conf->Folders.Logs.Mkdir();
+ AppConfig_ReloadGlobalSettings();
m_MainFrame = new MainEmuFrame( NULL, L"PCSX2" );
m_ProgramLogBox = new ConsoleLogFrame( m_MainFrame, L"PCSX2 Program Log", g_Conf->ProgLogBox );
@@ -216,24 +178,6 @@ bool Pcsx2App::OnInit()
return false;
}
- // Check to see if the user needs to perform initial setup:
-
- /*bool needsConfigured = false;
- const wxString pc( L"Please Configure" );
- for( int pidx=0; pidxBaseFilenames[(PluginsEnum_t)pidx] == pc )
- {
- needsConfigured = true;
- break;
- }
- }
-
- if( needsConfigured )
- {
- Dialogs::ConfigurationDialog( m_MainFrame ).ShowModal();
- }*/
-
Connect( pxEVT_MSGBOX, wxCommandEventHandler( Pcsx2App::OnMessageBox ) );
return true;
diff --git a/pcsx2/ps2/BiosTools.cpp b/pcsx2/ps2/BiosTools.cpp
index 00b38a280d..5145ecf296 100644
--- a/pcsx2/ps2/BiosTools.cpp
+++ b/pcsx2/ps2/BiosTools.cpp
@@ -47,6 +47,18 @@ struct romdir
u32 BiosVersion; // Used in Memory, Misc, CDVD
+// Returns a string message telling the user to consult guides for obtaining a legal BIOS.
+// This message is in a function because it's used as part of several dialogs in PCSX2 (there
+// are multiple variations on the BIOS and BIOS folder checks).
+wxString BIOS_GetMsg_Required()
+{
+ return pxE( ".Popup:BiosDumpRequired",
+ L"PCSX2 requires a PS2 BIOS in order to run. For legal reasons, you *must* obtain \n"
+ L"a BIOS from an actual PS2 unit that you own (borrowing doesn't count).\n"
+ L"Please consult the FAQs and Guides for further instructions."
+ );
+}
+
// Returns the version information of the bios currently loaded into memory.
static u32 GetBiosVersion()
{
@@ -152,11 +164,8 @@ void LoadBIOS()
throw Exception::FileNotFound( Bios,
L"Configured Bios file does not exist",
- pxE( ".Error:BiosNotFound",
- L"The configured BIOS file does not exist, or no BIOS has been configured.\n\n"
- L"PCSX2 requires a PS2 BIOS to run; and the BIOS *must* be obtained from an actual PS2 unit\n"
- L"that you own (borrowing doesn't count). Please consult the FAQs and Guides for further instructions."
- )
+ _("The configured BIOS file does not exist, or no BIOS has been configured.\n\n") +
+ BIOS_GetMsg_Required()
);
}
@@ -189,9 +198,8 @@ bool IsBIOS(const wxString& filename, wxString& description)
break; // found romdir
}
- if ((strcmp(rd.fileName, "RESET") != 0) || (rd.fileSize == 0)) {
+ if ((strcmp(rd.fileName, "RESET") != 0) || (rd.fileSize == 0))
return FALSE; //Unable to locate ROMDIR structure in file or a ioprpXXX.img
- }
bool found = false;
@@ -242,13 +250,13 @@ bool IsBIOS(const wxString& filename, wxString& description)
if (fp.Read( &rd, DIRENTRY_SIZE ) != DIRENTRY_SIZE) break;
}
- fileOffset-=((rd.fileSize + 0x10) & 0xfffffff0) - rd.fileSize;
+ fileOffset -= ((rd.fileSize + 0x10) & 0xfffffff0) - rd.fileSize;
if (found)
{
if ( biosFileSize < (int)fileOffset)
{
- description << ((biosFileSize*100)/(int)fileOffset) << L"%";
+ description += wxsFormat( L" %d%%", ((biosFileSize*100) / (int)fileOffset) );
// we force users to have correct bioses,
// not that lame scph10000 of 513KB ;-)
}
diff --git a/pcsx2/ps2/BiosTools.h b/pcsx2/ps2/BiosTools.h
index af5b50c9ea..23f25e998e 100644
--- a/pcsx2/ps2/BiosTools.h
+++ b/pcsx2/ps2/BiosTools.h
@@ -20,5 +20,6 @@
extern u32 BiosVersion; // Used by CDVD
+extern wxString BIOS_GetMsg_Required();
extern void LoadBIOS();
extern bool IsBIOS(const wxString& filename, wxString& description);
diff --git a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj
index ce37da64b2..075b6d0195 100644
--- a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj
+++ b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj
@@ -1989,6 +1989,10 @@
RelativePath="..\..\gui\Dialogs\ConfigurationDialog.h"
>
+
+
diff --git a/pcsx2_suite_2008.sln b/pcsx2_suite_2008.sln
index fe6ff5186f..2c8ec5f6e8 100644
--- a/pcsx2_suite_2008.sln
+++ b/pcsx2_suite_2008.sln
@@ -117,6 +117,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wxAdv28", "3rdparty\wxWidge
{C34487AF-228A-4D11-8E50-27803DF76873} = {C34487AF-228A-4D11-8E50-27803DF76873}
EndProjectSection
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "wx", "wx", "{62BF822E-6A12-49A8-BE8C-C55A9BCA24DA}"
+ ProjectSection(SolutionItems) = preProject
+ common\include\wx\folderdesc.txt = common\include\wx\folderdesc.txt
+ common\include\wx\scopedarray.h = common\include\wx\scopedarray.h
+ common\include\wx\scopedptr.h = common\include\wx\scopedptr.h
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -601,6 +608,7 @@ Global
{0FADC26C-0E9D-4DD7-84B1-BF4F7754E90C} = {88F517F9-CE1C-4005-9BDF-4481FEB55053}
{A51123F5-9505-4EAE-85E7-D320290A272C} = {88F517F9-CE1C-4005-9BDF-4481FEB55053}
{4639972E-424E-4E13-8B07-CA403C481346} = {88F517F9-CE1C-4005-9BDF-4481FEB55053}
+ {62BF822E-6A12-49A8-BE8C-C55A9BCA24DA} = {0FADC26C-0E9D-4DD7-84B1-BF4F7754E90C}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
AMDCaProjectFile = E:\devpcsx2\fail\wx\CodeAnalyst\pcsx2_suite_2008.caw