Lots of wee bugfixes to user interface stuffs

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2199 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-11-16 00:40:09 +00:00
parent a4baab103f
commit dd0b49e80d
23 changed files with 842 additions and 744 deletions

View File

@ -1,95 +1,95 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
// ----------------------------------------------------------------------------------------
// pxAssert / pxAssertDev / pxFail / pxFailDev
// ----------------------------------------------------------------------------------------
// Standard debug-ony "nothrow" (pxAssert) and devel-style "throw" (pxAssertDev) style
// assertions. All assertions act as valid conditional statements that return the result
// of the specified conditional; useful for handling failed assertions in a "graceful" fashion
// when utilizing the "ignore" feature of assertion debugging. (Release builds *always* return
// true for assertion success, but no actual assertion check is performed).
//
// Performance: All assertion types optimize into __assume() directives in Release builds.
//
// pxAssertDev is an assertion tool for Devel builds, intended for sanity checking and/or
// bounds checking variables in areas which are not performance critical.
//
// How it works: pxAssertDev throws an exception of type Exception::LogicError if the assertion
// conditional is false. Typically for the end-user, this exception is handled by the general
// exception handler defined by the application, which (should eventually) create some state
// dumps and other information for troubleshooting purposes.
//
// From a debugging environment, you can trap your pxAssertDev by either breakpointing the
// exception throw code in pxOnAssert, or by adding Exception::LogicError to your First-Chance
// Exception catch list (Visual Studio, under the Debug->Exceptions menu/dialog). You should
// have LogicErrors enabled as First-Chance exceptions regardless, so do it now. :)
//
// Credits Notes: These macros are based on a combination of wxASSERT, MSVCRT's assert
// and the ATL's Assertion/Assumption macros. the best of all worlds!
#if defined(PCSX2_DEBUG)
# define pxAssertMsg(cond, msg) ( (!!(cond)) || \
(pxOnAssert(__TFILE__, __LINE__, __WXFUNCTION__, _T(#cond), msg), likely(cond)) )
# define pxAssertDev(cond,msg) pxAssertMsg(cond, msg)
# define pxFail(msg) pxAssertMsg(false, msg)
# define pxFailDev(msg) pxAssertDev(false, msg)
#elif defined(PCSX2_DEVBUILD)
// Devel builds use __assume for standard assertions and call pxOnAssertDevel
// for AssertDev brand assertions (which typically throws a LogicError exception).
# define pxAssertMsg(cond, msg) (__assume(cond), likely(cond))
# define pxAssertDev(cond, msg) ( (!!(cond)) || \
(pxOnAssert(__TFILE__, __LINE__, __WXFUNCTION__, _T(#cond), msg), likely(cond)) )
# define pxFail(msg) (__assume(false), false)
# define pxFailDev(msg ) pxAssertDev(false, msg)
#else
// Release Builds just use __assume as an optimization, and return the conditional
// as a result (which is optimized to nil if unused).
# define pxAssertMsg(cond, msg) (__assume(cond), likely(cond))
# define pxAssertDev(cond, msg) (__assume(cond), likely(cond))
# define pxFail(msg) (__assume(false), false)
# define pxFailDev(msg) (__assume(false), false)
#endif
#define pxAssert(cond) pxAssertMsg(cond, (wxChar*)NULL)
// Performs an unsigned index bounds check, and generates a debug assertion if the check fails.
// For stricter checking in Devel builds as well as debug builds (but possibly slower), use
// IndexBoundsCheckDev.
#define IndexBoundsCheck( objname, idx, sze ) pxAssertMsg( (uint)(idx) < (uint)(sze), \
wxsFormat( L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze) ) )
#define IndexBoundsCheckDev( objname, idx, sze ) pxAssertDev( (uint)(idx) < (uint)(sze), \
wxsFormat( L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze) ) )
extern void pxOnAssert( const wxChar* file, int line, const char* func, const wxChar* cond, const wxChar* msg);
extern void pxOnAssert( const wxChar* file, int line, const char* func, const wxChar* cond, const char* msg);
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
// ----------------------------------------------------------------------------------------
// pxAssert / pxAssertDev / pxFail / pxFailDev
// ----------------------------------------------------------------------------------------
// Standard debug-ony "nothrow" (pxAssert) and devel-style "throw" (pxAssertDev) style
// assertions. All assertions act as valid conditional statements that return the result
// of the specified conditional; useful for handling failed assertions in a "graceful" fashion
// when utilizing the "ignore" feature of assertion debugging. (Release builds *always* return
// true for assertion success, but no actual assertion check is performed).
//
// Performance: All assertion types optimize into __assume() directives in Release builds.
//
// pxAssertDev is an assertion tool for Devel builds, intended for sanity checking and/or
// bounds checking variables in areas which are not performance critical.
//
// How it works: pxAssertDev throws an exception of type Exception::LogicError if the assertion
// conditional is false. Typically for the end-user, this exception is handled by the general
// exception handler defined by the application, which (should eventually) create some state
// dumps and other information for troubleshooting purposes.
//
// From a debugging environment, you can trap your pxAssertDev by either breakpointing the
// exception throw code in pxOnAssert, or by adding Exception::LogicError to your First-Chance
// Exception catch list (Visual Studio, under the Debug->Exceptions menu/dialog). You should
// have LogicErrors enabled as First-Chance exceptions regardless, so do it now. :)
//
// Credits Notes: These macros are based on a combination of wxASSERT, MSVCRT's assert
// and the ATL's Assertion/Assumption macros. the best of all worlds!
#if defined(PCSX2_DEBUG)
# define pxAssertMsg(cond, msg) ( (!!(cond)) || \
(pxOnAssert(__TFILE__, __LINE__, __WXFUNCTION__, _T(#cond), msg), likely(cond)) )
# define pxAssertDev(cond,msg) pxAssertMsg(cond, msg)
# define pxFail(msg) pxAssertMsg(false, msg)
# define pxFailDev(msg) pxAssertDev(false, msg)
#elif defined(PCSX2_DEVBUILD)
// Devel builds use __assume for standard assertions and call pxOnAssertDevel
// for AssertDev brand assertions (which typically throws a LogicError exception).
# define pxAssertMsg(cond, msg) (__assume(cond), likely(cond))
# define pxAssertDev(cond, msg) ( (!!(cond)) || \
(pxOnAssert(__TFILE__, __LINE__, __WXFUNCTION__, _T(#cond), msg), likely(cond)) )
# define pxFail(msg) (__assume(false), false)
# define pxFailDev(msg ) pxAssertDev(false, msg)
#else
// Release Builds just use __assume as an optimization, and return the conditional
// as a result (which is optimized to nil if unused).
# define pxAssertMsg(cond, msg) (__assume(cond), likely(cond))
# define pxAssertDev(cond, msg) (__assume(cond), likely(cond))
# define pxFail(msg) (__assume(false), false)
# define pxFailDev(msg) (__assume(false), false)
#endif
#define pxAssert(cond) pxAssertMsg(cond, (wxChar*)NULL)
// Performs an unsigned index bounds check, and generates a debug assertion if the check fails.
// For stricter checking in Devel builds as well as debug builds (but possibly slower), use
// IndexBoundsCheckDev.
#define IndexBoundsCheck( objname, idx, sze ) pxAssertMsg( (uint)(idx) < (uint)(sze), \
wxsFormat( L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze) ) )
#define IndexBoundsCheckDev( objname, idx, sze ) pxAssertDev( (uint)(idx) < (uint)(sze), \
wxsFormat( L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze) ) )
extern void pxOnAssert( const wxChar* file, int line, const char* func, const wxChar* cond, const wxChar* msg);
extern void pxOnAssert( const wxChar* file, int line, const char* func, const wxChar* cond, const char* msg);

View File

@ -1,90 +1,90 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
// Checks for duplicates before adding the event.
template< typename EvtType >
void EventSource<EvtType>::Add( const ListenerType& listener )
{
if( !pxAssertDev( listener.OnEvent != NULL, "NULL listener callback function." ) ) return;
Handle iter = m_listeners.begin();
while( iter != m_listeners.end() )
{
if( *iter == listener ) return;
++iter;
}
AddFast( listener );
}
template< typename EvtType >
class PredicatesAreTheThingsOfNightmares
{
typedef EventListener< EvtType > ListenerType;
protected:
const void* const m_object_match;
public:
PredicatesAreTheThingsOfNightmares( const void* objmatch ) : m_object_match( objmatch ) { }
bool operator()( const ListenerType& src ) const
{
return src.object == m_object_match;
}
};
// removes all listeners which reference the given object. Use for assuring object deletion.
template< typename EvtType >
void EventSource<EvtType>::RemoveObject( const void* object )
{
m_cache_valid = false;
m_listeners.remove_if( PredicatesAreTheThingsOfNightmares<EvtType>( object ) );
}
template< typename EvtType >
__forceinline void EventSource<EvtType>::_DispatchRaw( ConstIterator iter, const ConstIterator& iend, EvtType& evt )
{
while( iter != iend )
{
try
{
iter->OnEvent( iter->object, evt );
}
catch( Exception::RuntimeError& ex )
{
Console.Error( L"Ignoring runtime error thrown from event listener: " + ex.FormatDiagnosticMessage() );
}
catch( Exception::BaseException& ex )
{
if( IsDevBuild ) throw;
Console.Error( L"Ignoring non-runtime BaseException thrown from event listener: " + ex.FormatDiagnosticMessage() );
}
++iter;
}
}
template< typename EvtType >
void EventSource<EvtType>::Dispatch( EvtType& evt )
{
if( !m_cache_valid )
{
m_cache_copy = m_listeners;
m_cache_valid = true;
}
_DispatchRaw( m_cache_copy.begin(), m_cache_copy.end(), evt );
}
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
// Checks for duplicates before adding the event.
template< typename EvtType >
void EventSource<EvtType>::Add( const ListenerType& listener )
{
if( !pxAssertDev( listener.OnEvent != NULL, "NULL listener callback function." ) ) return;
Handle iter = m_listeners.begin();
while( iter != m_listeners.end() )
{
if( *iter == listener ) return;
++iter;
}
AddFast( listener );
}
template< typename EvtType >
class PredicatesAreTheThingsOfNightmares
{
typedef EventListener< EvtType > ListenerType;
protected:
const void* const m_object_match;
public:
PredicatesAreTheThingsOfNightmares( const void* objmatch ) : m_object_match( objmatch ) { }
bool operator()( const ListenerType& src ) const
{
return src.object == m_object_match;
}
};
// removes all listeners which reference the given object. Use for assuring object deletion.
template< typename EvtType >
void EventSource<EvtType>::RemoveObject( const void* object )
{
m_cache_valid = false;
m_listeners.remove_if( PredicatesAreTheThingsOfNightmares<EvtType>( object ) );
}
template< typename EvtType >
__forceinline void EventSource<EvtType>::_DispatchRaw( ConstIterator iter, const ConstIterator& iend, EvtType& evt )
{
while( iter != iend )
{
try
{
iter->OnEvent( iter->object, evt );
}
catch( Exception::RuntimeError& ex )
{
Console.Error( L"Ignoring runtime error thrown from event listener: " + ex.FormatDiagnosticMessage() );
}
catch( Exception::BaseException& ex )
{
if( IsDevBuild ) throw;
Console.Error( L"Ignoring non-runtime BaseException thrown from event listener: " + ex.FormatDiagnosticMessage() );
}
++iter;
}
}
template< typename EvtType >
void EventSource<EvtType>::Dispatch( EvtType& evt )
{
if( !m_cache_valid )
{
m_cache_copy = m_listeners;
m_cache_valid = true;
}
_DispatchRaw( m_cache_copy.begin(), m_cache_copy.end(), evt );
}

View File

@ -32,7 +32,7 @@ extern const wxRect wxDefaultRect;
// This should prove useful....
#define wxsFormat wxString::Format
extern void SplitString( wxArrayString& dest, const wxString& src, const wxString& delims );
extern void SplitString( wxArrayString& dest, const wxString& src, const wxString& delims, wxStringTokenizerMode mode = wxTOKEN_RET_EMPTY_ALL );
extern void JoinString( wxString& dest, const wxArrayString& src, const wxString& separator );
extern wxString ToString( const wxPoint& src, const wxString& separator=L"," );

View File

@ -1,179 +1,178 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <wx/wx.h>
#include "SafeArray.h"
#include "wxGuiTools.h"
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <wx/wx.h>
#include "SafeArray.h"
#include "wxGuiTools.h"
#include <vector>
// --------------------------------------------------------------------------------------
// RadioPanelItem
// --------------------------------------------------------------------------------------
struct RadioPanelItem
{
wxString Label;
wxString SubText;
wxString ToolTip;
RadioPanelItem( const wxString& label, const wxString& subtext=wxEmptyString, const wxString& tooltip=wxEmptyString )
: Label( label )
, SubText( subtext )
, ToolTip( tooltip )
{
}
RadioPanelItem& SetToolTip( const wxString& tip )
{
ToolTip = tip;
return *this;
}
RadioPanelItem& SetSubText( const wxString& text )
{
SubText = text;
return *this;
}
};
// Used as a cache for the "original" labels and subtexts, so that text can be properly
// wrapped and re-wrapped with multiple calls to OnResize().
struct RadioPanelObjects
{
wxRadioButton* LabelObj;
wxStaticText* SubTextObj;
};
// --------------------------------------------------------------------------------------
// pxRadioPanel
// --------------------------------------------------------------------------------------
// Radio buttons work best when they are created consecutively, and then their subtext
// created in a second sweep (this keeps the radio buttons together in the parent window's
// child list, and avoids potentially unwanted behavior with radio buttons failing to
// group expectedly). Because of this, our radio button helper is shaped as a panel of
// a group of radio butons only, instead of bothering with the lower level per-button
// design. This makes a few other things nicer as well, such as binding a single message
// handler to all radio buttons in the panel.
//
// The SetToolTip API provided by this function applies the tooltip to both both the radio
// button and it's static subtext (if present), and performs word wrapping on platforms
// that need it (eg mswindows).
//
class pxRadioPanel : public wxPanelWithHelpers
{
protected:
typedef std::vector<RadioPanelItem> ButtonArray;
typedef SafeArray<RadioPanelObjects> ButtonObjArray;
ButtonArray m_buttonStrings;
ButtonObjArray m_objects;
bool m_IsRealized;
int m_idealWidth;
wxSize m_padding;
int m_Indentation;
public:
template< int size >
pxRadioPanel( wxPanelWithHelpers* parent, const RadioPanelItem (&src)[size] )
: wxPanelWithHelpers( parent, parent->GetIdealWidth() )
{
Init( src, size );
}
template< int size >
pxRadioPanel( wxDialogWithHelpers* parent, const RadioPanelItem (&src)[size] )
: wxDialogWithHelpers( parent, parent->GetIdealWidth() )
{
Init( src, size );
}
template< int size >
pxRadioPanel( int idealWidth, wxWindow* parent, const RadioPanelItem (&src)[size] )
: wxPanelWithHelpers( parent, idealWidth )
{
Init( src, size );
}
pxRadioPanel( wxPanelWithHelpers* parent )
: wxPanelWithHelpers( parent, parent->GetIdealWidth() )
{
Init();
}
pxRadioPanel( wxDialogWithHelpers* parent )
: wxPanelWithHelpers( parent, parent->GetIdealWidth() )
{
Init();
}
pxRadioPanel( int idealWidth, wxPanelWithHelpers* parent )
: wxPanelWithHelpers( parent, idealWidth )
{
Init();
}
virtual ~pxRadioPanel() throw() {}
void Reset();
void Realize();
wxStaticText* GetSubText( int idx );
const wxStaticText* GetSubText( int idx ) const;
pxRadioPanel& Append( const RadioPanelItem& entry );
pxRadioPanel& SetToolTip( int idx, const wxString& tip );
pxRadioPanel& SetSelection( int idx );
int GetSelection() const;
wxWindowID GetSelectionId() const;
bool IsSelected( int idx ) const;
wxRadioButton* GetButton( int idx );
const wxRadioButton* GetButton( int idx ) const;
int GetPaddingHoriz() const { return m_padding.GetHeight(); }
int GetIndentation() const { return m_Indentation; }
pxRadioPanel& SetPaddingHoriz( int newpad )
{
m_padding.SetHeight( newpad );
return *this;
}
pxRadioPanel& SetIndentation( int newdent )
{
m_Indentation = newdent;
return *this;
}
bool HasSubText( int idx ) const
{
return !m_buttonStrings[idx].SubText.IsEmpty();
}
pxRadioPanel& Append( const wxString& label, const wxString& subtext=wxEmptyString, const wxString& tooltip=wxEmptyString )
{
return Append( RadioPanelItem(label, subtext, tooltip) );
}
protected:
void Init( const RadioPanelItem* srcArray=NULL, int arrsize=0 );
void _setToolTipImmediate( int idx, const wxString &tip );
};
// --------------------------------------------------------------------------------------
// RadioPanelItem
// --------------------------------------------------------------------------------------
struct RadioPanelItem
{
wxString Label;
wxString SubText;
wxString ToolTip;
RadioPanelItem( const wxString& label, const wxString& subtext=wxEmptyString, const wxString& tooltip=wxEmptyString )
: Label( label )
, SubText( subtext )
, ToolTip( tooltip )
{
}
RadioPanelItem& SetToolTip( const wxString& tip )
{
ToolTip = tip;
return *this;
}
RadioPanelItem& SetSubText( const wxString& text )
{
SubText = text;
return *this;
}
};
// Used as a cache for the "original" labels and subtexts, so that text can be properly
// wrapped and re-wrapped with multiple calls to OnResize().
struct RadioPanelObjects
{
wxRadioButton* LabelObj;
wxStaticText* SubTextObj;
};
// --------------------------------------------------------------------------------------
// pxRadioPanel
// --------------------------------------------------------------------------------------
// Radio buttons work best when they are created consecutively, and then their subtext
// created in a second sweep (this keeps the radio buttons together in the parent window's
// child list, and avoids potentially unwanted behavior with radio buttons failing to
// group expectedly). Because of this, our radio button helper is shaped as a panel of
// a group of radio butons only, instead of bothering with the lower level per-button
// design. This makes a few other things nicer as well, such as binding a single message
// handler to all radio buttons in the panel.
//
// The SetToolTip API provided by this function applies the tooltip to both both the radio
// button and it's static subtext (if present), and performs word wrapping on platforms
// that need it (eg mswindows).
//
class pxRadioPanel : public wxPanelWithHelpers
{
protected:
typedef std::vector<RadioPanelItem> ButtonArray;
typedef SafeArray<RadioPanelObjects> ButtonObjArray;
ButtonArray m_buttonStrings;
ButtonObjArray m_objects;
bool m_IsRealized;
wxSize m_padding;
int m_Indentation;
public:
template< int size >
pxRadioPanel( wxPanelWithHelpers* parent, const RadioPanelItem (&src)[size] )
: wxPanelWithHelpers( parent, parent->GetIdealWidth()-24 )
{
Init( src, size );
}
template< int size >
pxRadioPanel( wxDialogWithHelpers* parent, const RadioPanelItem (&src)[size] )
: wxDialogWithHelpers( parent, parent->GetIdealWidth()-24 )
{
Init( src, size );
}
template< int size >
pxRadioPanel( int idealWidth, wxWindow* parent, const RadioPanelItem (&src)[size] )
: wxPanelWithHelpers( parent, idealWidth )
{
Init( src, size );
}
pxRadioPanel( wxPanelWithHelpers* parent )
: wxPanelWithHelpers( parent, parent->GetIdealWidth()-24 )
{
Init();
}
pxRadioPanel( wxDialogWithHelpers* parent )
: wxPanelWithHelpers( parent, parent->GetIdealWidth()-24 )
{
Init();
}
pxRadioPanel( int idealWidth, wxPanelWithHelpers* parent )
: wxPanelWithHelpers( parent, idealWidth )
{
Init();
}
virtual ~pxRadioPanel() throw() {}
void Reset();
void Realize();
wxStaticText* GetSubText( int idx );
const wxStaticText* GetSubText( int idx ) const;
pxRadioPanel& Append( const RadioPanelItem& entry );
pxRadioPanel& SetToolTip( int idx, const wxString& tip );
pxRadioPanel& SetSelection( int idx );
int GetSelection() const;
wxWindowID GetSelectionId() const;
bool IsSelected( int idx ) const;
wxRadioButton* GetButton( int idx );
const wxRadioButton* GetButton( int idx ) const;
int GetPaddingHoriz() const { return m_padding.GetHeight(); }
int GetIndentation() const { return m_Indentation; }
pxRadioPanel& SetPaddingHoriz( int newpad )
{
m_padding.SetHeight( newpad );
return *this;
}
pxRadioPanel& SetIndentation( int newdent )
{
m_Indentation = newdent;
return *this;
}
bool HasSubText( int idx ) const
{
return !m_buttonStrings[idx].SubText.IsEmpty();
}
pxRadioPanel& Append( const wxString& label, const wxString& subtext=wxEmptyString, const wxString& tooltip=wxEmptyString )
{
return Append( RadioPanelItem(label, subtext, tooltip) );
}
protected:
void Init( const RadioPanelItem* srcArray=NULL, int arrsize=0 );
void _setToolTipImmediate( int idx, const wxString &tip );
};

View File

@ -1,64 +1,64 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "../PrecompiledHeader.h"
#include <sys/mman.h>
#include <signal.h>
namespace HostSys
{
static const uptr m_pagemask = getpagesize()-1;
void *Mmap(uptr base, u32 size)
{
u8 *Mem;
Mem = (u8*)mmap((uptr*)base, size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
if (Mem == MAP_FAILED) Console.Warning("Mmap Failed!");
return Mem;
}
void Munmap(uptr base, u32 size)
{
munmap((uptr*)base, size);
}
void MemProtect( void* baseaddr, size_t size, PageProtectionMode mode, bool allowExecution )
{
pxAssertDev( (size & (__pagesize-1)) == 0, wxsFormat(
L"Memory block size must be a multiple of the target platform's page size.\n"
L"\tPage Size: 0x%04x (%d), Block Size: 0x%04x (%d)",
__pagesize, __pagesize, size, size )
);
int lnxmode = 0;
// make sure size is aligned to the system page size:
// Check is redundant against the assertion above, but might as well...
size = (size + m_pagemask) & ~m_pagemask;
switch( mode )
{
case Protect_NoAccess: break;
case Protect_ReadOnly: lnxmode = PROT_READ; break;
case Protect_ReadWrite: lnxmode = PROT_READ | PROT_WRITE; break;
}
if( allowExecution ) lnxmode |= PROT_EXEC;
mprotect( baseaddr, size, lnxmode );
}
}
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "../PrecompiledHeader.h"
#include <sys/mman.h>
#include <signal.h>
namespace HostSys
{
static const uptr m_pagemask = getpagesize()-1;
void *Mmap(uptr base, u32 size)
{
u8 *Mem;
Mem = (u8*)mmap((uptr*)base, size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
if (Mem == MAP_FAILED) Console.Warning("Mmap Failed!");
return Mem;
}
void Munmap(uptr base, u32 size)
{
munmap((uptr*)base, size);
}
void MemProtect( void* baseaddr, size_t size, PageProtectionMode mode, bool allowExecution )
{
pxAssertDev( (size & (__pagesize-1)) == 0, wxsFormat(
L"Memory block size must be a multiple of the target platform's page size.\n"
L"\tPage Size: 0x%04x (%d), Block Size: 0x%04x (%d)",
__pagesize, __pagesize, size, size )
);
int lnxmode = 0;
// make sure size is aligned to the system page size:
// Check is redundant against the assertion above, but might as well...
size = (size + m_pagemask) & ~m_pagemask;
switch( mode )
{
case Protect_NoAccess: break;
case Protect_ReadOnly: lnxmode = PROT_READ; break;
case Protect_ReadWrite: lnxmode = PROT_READ | PROT_WRITE; break;
}
if( allowExecution ) lnxmode |= PROT_EXEC;
mprotect( baseaddr, size, lnxmode );
}
}

View File

@ -41,9 +41,9 @@ void SplitString( SafeList<wxString>& dest, const wxString& src, const wxString&
dest.Add( parts.GetNextToken() );
}
void SplitString( wxArrayString& dest, const wxString& src, const wxString& delims )
void SplitString( wxArrayString& dest, const wxString& src, const wxString& delims, wxStringTokenizerMode mode )
{
wxStringTokenizer parts( src, delims );
wxStringTokenizer parts( src, delims, mode );
while( parts.HasMoreTokens() )
dest.Add( parts.GetNextToken() );
}

View File

@ -1,192 +1,194 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "pxRadioPanel.h"
// ===========================================================================================
// pxRadioPanel Implementations
// ===========================================================================================
#define VerifyRealizedState() \
pxAssertDev( m_IsRealized, "Invalid object state: RadioButtonGroup as not been realized." )
void pxRadioPanel::Init( const RadioPanelItem* srcArray, int arrsize )
{
m_IsRealized = false;
// FIXME: This probably needs to be platform-dependent, and/or based on font size.
m_Indentation = 23;
SetSizer( new wxBoxSizer(wxVERTICAL) );
for( int i=0; i<arrsize; ++i )
Append( srcArray[i] );
}
pxRadioPanel& pxRadioPanel::Append( const RadioPanelItem& entry )
{
m_buttonStrings.push_back( entry );
return *this;
}
void pxRadioPanel::Reset()
{
m_IsRealized = false;
const int numbuttons = m_buttonStrings.size();
if( numbuttons == 0 ) return;
for( int i=0; i<numbuttons; ++i)
{
safe_delete( m_objects[i].LabelObj );
safe_delete( m_objects[i].SubTextObj );
}
m_buttonStrings.clear();
}
void pxRadioPanel::Realize()
{
const int numbuttons = m_buttonStrings.size();
if( numbuttons == 0 ) return;
if( m_IsRealized ) return;
m_IsRealized = true;
m_objects.MakeRoomFor( numbuttons );
// Add all RadioButtons in one pass, and then go back and create all the subtext
// objects. This ensures the radio buttons have consecutive tab order IDs, which
// is the "preferred" method when using grouping features of the native window
// managers (GTK tends to not care either way, but Win32 definitely prefers a
// linear tab order).
// first object has the group flag set to ensure it's the start of a radio group.
m_objects[0].LabelObj = new wxRadioButton( this, wxID_ANY, m_buttonStrings[0].Label, wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
for( int i=1; i<numbuttons; ++i )
m_objects[i].LabelObj = new wxRadioButton( this, wxID_ANY, m_buttonStrings[i].Label );
for( int i=0; i<numbuttons; ++i )
{
m_objects[i].SubTextObj = NULL;
if( m_buttonStrings[i].SubText.IsEmpty() ) continue;
m_objects[i].SubTextObj = new wxStaticText( this, wxID_ANY, m_buttonStrings[i].SubText );
if( (m_idealWidth > 0) && pxAssertMsg( m_idealWidth < 40, "Unusably short text wrapping specified!" ) )
m_objects[i].SubTextObj->Wrap( m_idealWidth - m_Indentation );
}
pxAssert( GetSizer() != NULL );
wxSizer& sizer( *GetSizer() );
for( int i=0; i<numbuttons; ++i )
{
sizer.Add( m_objects[i].LabelObj, pxSizerFlags::StdExpand() );
if( wxStaticText* subobj = m_objects[i].SubTextObj )
{
sizer.Add( subobj, wxSizerFlags().Border( wxLEFT, m_Indentation ) );
sizer.AddSpacer( 9 + m_padding.GetHeight() );
}
if( !m_buttonStrings[i].ToolTip.IsEmpty() )
_setToolTipImmediate( i, m_buttonStrings[i].ToolTip );
}
}
void pxRadioPanel::_setToolTipImmediate( int idx, const wxString &tip )
{
const wxString wrapped( pxFormatToolTipText(this, tip) );
if( wxRadioButton* woot = m_objects[idx].LabelObj )
woot->SetToolTip( wrapped );
if( wxStaticText* woot = m_objects[idx].SubTextObj )
woot->SetToolTip( wrapped );
}
pxRadioPanel& pxRadioPanel::SetToolTip(int idx, const wxString &tip)
{
m_buttonStrings[idx].SetToolTip( tip );
if( m_IsRealized )
_setToolTipImmediate( idx, tip );
return *this;
}
pxRadioPanel& pxRadioPanel::SetSelection( int idx )
{
if( !VerifyRealizedState() ) return *this;
pxAssert( m_objects[idx].LabelObj != NULL );
m_objects[idx].LabelObj->SetValue( true );
return *this;
}
int pxRadioPanel::GetSelection() const
{
if( !VerifyRealizedState() ) return 0;
for( uint i=0; i<m_buttonStrings.size(); ++i )
{
if( wxRadioButton* woot = m_objects[i].LabelObj )
if( woot->GetValue() ) return i;
}
// Technically radio buttons should never allow for a case where none are selected.
// However it *can* happen on some platforms if the program code doesn't explicitly
// select one of the members of the group (which is, as far as I'm concerned, a
// programmer error!). so Assert here in such cases, and return 0 as the assumed
// default, so that calling code has a "valid" return code in release builds.
pxFailDev( "No valid selection was found in this group!" );
return 0;
}
// Returns the wxWindowID for the currently selected radio button.
wxWindowID pxRadioPanel::GetSelectionId() const
{
if( !VerifyRealizedState() ) return 0;
return m_objects[GetSelection()].LabelObj->GetId();
}
bool pxRadioPanel::IsSelected( int idx ) const
{
if( VerifyRealizedState() ) return false;
pxAssert( m_objects[idx].LabelObj != NULL );
return m_objects[idx].LabelObj->GetValue();
}
wxStaticText* pxRadioPanel::GetSubText( int idx )
{
if( VerifyRealizedState() ) return NULL;
return m_objects[idx].SubTextObj;
}
const wxStaticText* pxRadioPanel::GetSubText( int idx ) const
{
if( VerifyRealizedState() ) return NULL;
return m_objects[idx].SubTextObj;
}
wxRadioButton* pxRadioPanel::GetButton( int idx )
{
if( VerifyRealizedState() ) return NULL;
return m_objects[idx].LabelObj;
}
const wxRadioButton* pxRadioPanel::GetButton( int idx ) const
{
if( VerifyRealizedState() ) return NULL;
return m_objects[idx].LabelObj;
}
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2009 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"
#include "pxRadioPanel.h"
// ===========================================================================================
// pxRadioPanel Implementations
// ===========================================================================================
#define VerifyRealizedState() \
pxAssertDev( m_IsRealized, "Invalid object state: RadioButtonGroup as not been realized." )
void pxRadioPanel::Init( const RadioPanelItem* srcArray, int arrsize )
{
m_IsRealized = false;
// FIXME: This probably needs to be platform-dependent, and/or based on font size.
m_Indentation = 23;
SetSizer( new wxBoxSizer(wxVERTICAL) );
for( int i=0; i<arrsize; ++i )
Append( srcArray[i] );
}
pxRadioPanel& pxRadioPanel::Append( const RadioPanelItem& entry )
{
m_buttonStrings.push_back( entry );
return *this;
}
void pxRadioPanel::Reset()
{
m_IsRealized = false;
const int numbuttons = m_buttonStrings.size();
if( numbuttons == 0 ) return;
for( int i=0; i<numbuttons; ++i)
{
safe_delete( m_objects[i].LabelObj );
safe_delete( m_objects[i].SubTextObj );
}
m_buttonStrings.clear();
}
void pxRadioPanel::Realize()
{
//if( )
const int numbuttons = m_buttonStrings.size();
if( numbuttons == 0 ) return;
if( m_IsRealized ) return;
m_IsRealized = true;
m_objects.MakeRoomFor( numbuttons );
// Add all RadioButtons in one pass, and then go back and create all the subtext
// objects. This ensures the radio buttons have consecutive tab order IDs, which
// is the "preferred" method when using grouping features of the native window
// managers (GTK tends to not care either way, but Win32 definitely prefers a
// linear tab order).
// first object has the group flag set to ensure it's the start of a radio group.
m_objects[0].LabelObj = new wxRadioButton( this, wxID_ANY, m_buttonStrings[0].Label, wxDefaultPosition, wxDefaultSize, wxRB_GROUP );
for( int i=1; i<numbuttons; ++i )
m_objects[i].LabelObj = new wxRadioButton( this, wxID_ANY, m_buttonStrings[i].Label );
for( int i=0; i<numbuttons; ++i )
{
m_objects[i].SubTextObj = NULL;
if( m_buttonStrings[i].SubText.IsEmpty() ) continue;
m_objects[i].SubTextObj = new wxStaticText( this, wxID_ANY, m_buttonStrings[i].SubText );
if( (m_idealWidth > 0) && pxAssertMsg( m_idealWidth > 40, "Unusably short text wrapping specified!" ) )
m_objects[i].SubTextObj->Wrap( m_idealWidth - m_Indentation );
}
pxAssert( GetSizer() != NULL );
wxSizer& sizer( *GetSizer() );
for( int i=0; i<numbuttons; ++i )
{
sizer.Add( m_objects[i].LabelObj, pxSizerFlags::StdExpand() );
if( wxStaticText* subobj = m_objects[i].SubTextObj )
{
sizer.Add( subobj, wxSizerFlags().Border( wxLEFT, m_Indentation ) );
sizer.AddSpacer( 9 + m_padding.GetHeight() );
}
if( !m_buttonStrings[i].ToolTip.IsEmpty() )
_setToolTipImmediate( i, m_buttonStrings[i].ToolTip );
}
}
void pxRadioPanel::_setToolTipImmediate( int idx, const wxString &tip )
{
const wxString wrapped( pxFormatToolTipText(this, tip) );
if( wxRadioButton* woot = m_objects[idx].LabelObj )
woot->SetToolTip( wrapped );
if( wxStaticText* woot = m_objects[idx].SubTextObj )
woot->SetToolTip( wrapped );
}
pxRadioPanel& pxRadioPanel::SetToolTip(int idx, const wxString &tip)
{
m_buttonStrings[idx].SetToolTip( tip );
if( m_IsRealized )
_setToolTipImmediate( idx, tip );
return *this;
}
pxRadioPanel& pxRadioPanel::SetSelection( int idx )
{
if( !VerifyRealizedState() ) return *this;
pxAssert( m_objects[idx].LabelObj != NULL );
m_objects[idx].LabelObj->SetValue( true );
return *this;
}
int pxRadioPanel::GetSelection() const
{
if( !VerifyRealizedState() ) return 0;
for( uint i=0; i<m_buttonStrings.size(); ++i )
{
if( wxRadioButton* woot = m_objects[i].LabelObj )
if( woot->GetValue() ) return i;
}
// Technically radio buttons should never allow for a case where none are selected.
// However it *can* happen on some platforms if the program code doesn't explicitly
// select one of the members of the group (which is, as far as I'm concerned, a
// programmer error!). so Assert here in such cases, and return 0 as the assumed
// default, so that calling code has a "valid" return code in release builds.
pxFailDev( "No valid selection was found in this group!" );
return 0;
}
// Returns the wxWindowID for the currently selected radio button.
wxWindowID pxRadioPanel::GetSelectionId() const
{
if( !VerifyRealizedState() ) return 0;
return m_objects[GetSelection()].LabelObj->GetId();
}
bool pxRadioPanel::IsSelected( int idx ) const
{
if( VerifyRealizedState() ) return false;
pxAssert( m_objects[idx].LabelObj != NULL );
return m_objects[idx].LabelObj->GetValue();
}
wxStaticText* pxRadioPanel::GetSubText( int idx )
{
if( VerifyRealizedState() ) return NULL;
return m_objects[idx].SubTextObj;
}
const wxStaticText* pxRadioPanel::GetSubText( int idx ) const
{
if( VerifyRealizedState() ) return NULL;
return m_objects[idx].SubTextObj;
}
wxRadioButton* pxRadioPanel::GetButton( int idx )
{
if( VerifyRealizedState() ) return NULL;
return m_objects[idx].LabelObj;
}
const wxRadioButton* pxRadioPanel::GetButton( int idx ) const
{
if( VerifyRealizedState() ) return NULL;
return m_objects[idx].LabelObj;
}

View File

@ -695,12 +695,12 @@ PluginManager::PluginManager( const wxString (&folders)[PluginId_Count] )
// Fetch plugin name and version information
_PS2EgetLibName GetLibName = (_PS2EgetLibName)m_info[pid].Lib.GetSymbol( L"PS2EgetLibName" );
_PS2EgetLibVersion2 GetLibVersion2 = (_PS2EgetLibVersion2)m_info[pid].Lib.GetSymbol( L"PS2EgetLibVersion2" );
_PS2EgetLibName GetLibName = (_PS2EgetLibName) m_info[pid].Lib.GetSymbol( L"PS2EgetLibName" );
_PS2EgetLibVersion2 GetLibVersion2 = (_PS2EgetLibVersion2) m_info[pid].Lib.GetSymbol( L"PS2EgetLibVersion2" );
if( GetLibName == NULL || GetLibVersion2 == NULL )
throw Exception::PluginLoadError( pid, m_info[pid].Filename,
wxsFormat( L"\nMethod binding failure on GetLibName or GetLibVersion2.\n" ),
L"\nMethod binding failure on GetLibName or GetLibVersion2.\n",
_( "Configured plugin is not a PCSX2 plugin, or is for an older unsupported version of PCSX2." )
);
@ -715,8 +715,16 @@ PluginManager::PluginManager( const wxString (&folders)[PluginId_Count] )
BindRequired( pid );
BindOptional( pid );
// Bind Optional Functions
// (leave pointer null and do not generate error)
// Run Plugin's Functionality Test.
// A lot of plugins don't bother to implement this function and return 0 (success)
// regardless, but some do so let's go ahead and check it. I mean, we're supposed to. :)
int testres = m_info[pi->id].CommonBindings.Test();
if( testres != 0 )
throw Exception::PluginLoadError( pid, m_info[pid].Filename,
wxsFormat( L"Plugin Test failure, return code: %d", testres ),
_( "The plugin reports that your hardware or software/drivers are not supported." )
);
} while( ++pi, pi->shortname != NULL );
CDVDapi_Plugin.newDiskCB( cdvdNewDiskCB );

View File

@ -57,7 +57,7 @@ void SysDetect()
L"Cores = %d physical [%d logical]\n"
L"x86PType = %s\n"
L"x86Flags = %8.8x %8.8x\n"
L"x86EFlags = %8.8x\n",
L"x86EFlags = %8.8x",
fromUTF8( x86caps.VendorName ).c_str(), x86caps.StepID,
fromUTF8( x86caps.FamilyName ).Trim().Trim(false).c_str(),
x86caps.Speed / 1000, x86caps.Speed % 1000,
@ -66,6 +66,8 @@ void SysDetect()
x86caps.Flags, x86caps.Flags2,
x86caps.EFlags
);
Console.Newline();
wxArrayString features[2]; // 2 lines, for readability!
@ -87,8 +89,7 @@ void SysDetect()
JoinString( result[1], features[1], L".. " );
Console.WriteLn( Color_StrongBlack, L"x86 Features Detected:" );
Console.Indent().WriteLn( result[0] + (result[1].IsEmpty() ? L"" : (L"\n" + result[1])) + L"\n" );
Console.Indent().WriteLn( result[0] + (result[1].IsEmpty() ? L"" : (L"\n" + result[1])) );
Console.Newline();
}

View File

@ -305,6 +305,28 @@ struct AppImageIds
} Toolbars;
};
// -------------------------------------------------------------------------------------------
// pxAppResources
// -------------------------------------------------------------------------------------------
// Container class for resources that should (or must) be unloaded prior to the ~wxApp() destructor.
// (typically this object is deleted at OnExit() or just prior to OnExit()).
//
struct pxAppResources
{
AppImageIds ImageId;
ScopedPtr<wxImageList> ConfigImages;
ScopedPtr<wxImageList> ToolbarImages;
ScopedPtr<wxIconBundle> IconBundle;
ScopedPtr<wxBitmap> Bitmap_Logo;
ScopedPtr<wxMenu> RecentIsoMenu;
ScopedPtr<RecentIsoManager> RecentIsoList;
pxAppResources();
~pxAppResources() throw() { }
};
struct MsgboxEventResult
{
Semaphore WaitForMe;
@ -363,15 +385,10 @@ public:
AcceleratorDictionary GlobalAccels;
protected:
wxImageList m_ConfigImages;
ScopedPtr<wxImageList> m_ToolbarImages;
ScopedPtr<wxBitmap> m_Bitmap_Logo;
ScopedPtr<PipeRedirectionBase> m_StdoutRedirHandle;
ScopedPtr<PipeRedirectionBase> m_StderrRedirHandle;
ScopedPtr<wxMenu> m_RecentIsoMenu;
ScopedPtr<RecentIsoList> m_RecentIsoList;
ScopedPtr<pxAppResources> m_Resources;
public:
ScopedPtr<SysCoreAllocations> m_CoreAllocs;
@ -384,9 +401,6 @@ protected:
GSFrame* m_gsFrame;
ConsoleLogFrame* m_ProgramLogBox;
bool m_ConfigImagesAreLoaded;
AppImageIds m_ImageId;
public:
Pcsx2App();
virtual ~Pcsx2App();
@ -402,14 +416,6 @@ public:
void SysExecute( CDVD_SourceType cdvdsrc, const wxString& elf_override=wxEmptyString );
void SysReset();
const wxBitmap& GetLogoBitmap();
wxImageList& GetImgList_Config();
wxImageList& GetImgList_Toolbars();
const AppImageIds& GetImgId() const { return m_ImageId; }
wxMenu& GetRecentIsoMenu() { return *m_RecentIsoMenu; }
RecentIsoList& GetRecentIsoList() { return *m_RecentIsoList; }
MainEmuFrame& GetMainFrame() const;
MainEmuFrame* GetMainFramePtr() const { return m_MainFrame; }
bool HasMainFrame() const { return m_MainFrame != NULL; }
@ -418,6 +424,24 @@ public:
void OnGsFrameClosed();
void OnMainFrameClosed();
// --------------------------------------------------------------------------
// App-wide Resources
// --------------------------------------------------------------------------
// All of these accessors cache the resources on first use and retain them in
// memory until the program exits.
wxMenu& GetRecentIsoMenu();
RecentIsoManager& GetRecentIsoList();
const wxIconBundle& GetIconBundle();
const wxBitmap& GetLogoBitmap();
wxImageList& GetImgList_Config();
wxImageList& GetImgList_Toolbars();
const AppImageIds& GetImgId() const
{
return m_Resources->ImageId;
}
// --------------------------------------------------------------------------
// Overrides of wxApp virtuals:
// --------------------------------------------------------------------------

View File

@ -266,15 +266,13 @@ bool Pcsx2App::OnInit()
InitDefaultGlobalAccelerators();
delete wxLog::SetActiveTarget( new pxLogConsole() );
m_RecentIsoMenu = new wxMenu();
m_RecentIsoMenu->Append( MenuId_IsoBrowse, _("Browse..."), _("Browse for an Iso that is not in your recent history.") );
m_RecentIsoList = new RecentIsoList( m_RecentIsoMenu );
m_Resources = new pxAppResources();
ReadUserModeSettings();
AppConfig_OnChangedSettingsFolder();
m_MainFrame = new MainEmuFrame( NULL, L"PCSX2" );
m_MainFrame->PushEventHandler( m_RecentIsoList );
m_MainFrame = new MainEmuFrame( NULL, L"PCSX2" );
m_MainFrame->PushEventHandler( &GetRecentIsoList() );
if( m_ProgramLogBox )
{
@ -294,7 +292,7 @@ bool Pcsx2App::OnInit()
SysDetect();
AppApplySettings();
#ifdef __WIN32__
#ifdef __WXMSW__
extern void SetupDwmStuff(WXHWND hMainWindow);
SetupDwmStuff(m_MainFrame->GetHWND());
#endif
@ -398,16 +396,12 @@ void Pcsx2App::CleanupMess()
delete wxGetLocale();
}
Pcsx2App::Pcsx2App() :
m_MainFrame( NULL )
, m_gsFrame( NULL )
, m_ProgramLogBox( NULL )
, m_ConfigImages( 32, 32 )
, m_ConfigImagesAreLoaded( false )
, m_ToolbarImages( NULL )
, m_Bitmap_Logo( NULL )
, m_RecentIsoMenu( NULL )
Pcsx2App::Pcsx2App()
{
m_MainFrame = NULL;
m_gsFrame = NULL;
m_ProgramLogBox = NULL;
SetAppName( L"pcsx2" );
BuildCommandHash();
}

View File

@ -364,11 +364,10 @@ int Pcsx2App::OnExit()
if( g_Conf )
AppSaveSettings();
sMainFrame.RemoveEventHandler( m_RecentIsoList );
m_RecentIsoList = NULL;
m_RecentIsoMenu = NULL;
sMainFrame.RemoveEventHandler( &GetRecentIsoList() );
m_Resources = NULL;
return wxApp::OnExit();
}

View File

@ -29,6 +29,10 @@
#include "Resources/ConfigIcon_Paths.h"
#include "Resources/ConfigIcon_Plugins.h"
#include "Resources/AppIcon16.h"
#include "Resources/AppIcon32.h"
#include "Resources/AppIcon64.h"
// ------------------------------------------------------------------------
const wxImage& LoadImageAny(
wxImage& dest, bool useTheme, wxFileName& base, const wxChar* filename, IEmbeddedImage& onFail )
@ -59,11 +63,48 @@ const wxImage& LoadImageAny(
return dest = onFail.Get();
}
pxAppResources::pxAppResources()
{
}
wxMenu& Pcsx2App::GetRecentIsoMenu()
{
if( !m_Resources->RecentIsoMenu )
{
m_Resources->RecentIsoMenu = new wxMenu();
m_Resources->RecentIsoMenu->Append( MenuId_IsoBrowse, _("Browse..."), _("Browse for an Iso that is not in your recent history.") );
}
return *m_Resources->RecentIsoMenu;
}
RecentIsoManager& Pcsx2App::GetRecentIsoList()
{
if( !m_Resources->RecentIsoList )
m_Resources->RecentIsoList = new RecentIsoManager( &GetRecentIsoMenu() );
return *m_Resources->RecentIsoList;
}
const wxIconBundle& Pcsx2App::GetIconBundle()
{
ScopedPtr<wxIconBundle>& bundle( m_Resources->IconBundle );
if( !bundle )
{
bundle = new wxIconBundle();
bundle->AddIcon( EmbeddedImage<res_AppIcon32>().GetIcon() );
bundle->AddIcon( EmbeddedImage<res_AppIcon64>().GetIcon() );
bundle->AddIcon( EmbeddedImage<res_AppIcon16>().GetIcon() );
}
return *bundle;
}
// ------------------------------------------------------------------------
const wxBitmap& Pcsx2App::GetLogoBitmap()
{
if( m_Bitmap_Logo )
return *m_Bitmap_Logo;
ScopedPtr<wxBitmap>& logo( m_Resources->Bitmap_Logo );
if( logo ) return *logo;
wxFileName mess;
bool useTheme = (g_Conf->DeskTheme != L"default");
@ -90,16 +131,18 @@ const wxBitmap& Pcsx2App::GetLogoBitmap()
wxImage img;
EmbeddedImage<res_BackgroundLogo> temp; // because gcc can't allow non-const temporaries.
LoadImageAny( img, useTheme, mess, L"BackgroundLogo", temp );
m_Bitmap_Logo = new wxBitmap( img );
logo = new wxBitmap( img );
return *m_Bitmap_Logo;
return *logo;
}
// ------------------------------------------------------------------------
wxImageList& Pcsx2App::GetImgList_Config()
{
if( !m_ConfigImagesAreLoaded )
ScopedPtr<wxImageList>& images( m_Resources->ConfigImages );
if( !images )
{
images = new wxImageList(32, 32);
wxFileName mess;
bool useTheme = (g_Conf->DeskTheme != L"default");
@ -111,14 +154,14 @@ wxImageList& Pcsx2App::GetImgList_Config()
wxImage img;
// GCC Specific: wxT() macro is required when using string token pasting. For some reason L
// generates syntax errors. >_<
// GCC Specific: wxT() macro is required when using string token pasting. For some
// reason L generates syntax errors. >_<
#undef FancyLoadMacro
#define FancyLoadMacro( name ) \
{ \
EmbeddedImage<res_ConfigIcon_##name> temp( g_Conf->Listbook_ImageSize, g_Conf->Listbook_ImageSize ); \
m_ImageId.Config.name = m_ConfigImages.Add( LoadImageAny( \
m_Resources->ImageId.Config.name = images->Add( LoadImageAny( \
img, useTheme, mess, L"ConfigIcon_" wxT(#name), temp ) \
); \
}
@ -130,17 +173,18 @@ wxImageList& Pcsx2App::GetImgList_Config()
FancyLoadMacro( Video );
FancyLoadMacro( Cpu );
}
m_ConfigImagesAreLoaded = true;
return m_ConfigImages;
return *images;
}
// ------------------------------------------------------------------------
wxImageList& Pcsx2App::GetImgList_Toolbars()
{
if( !m_ToolbarImages )
ScopedPtr<wxImageList>& images( m_Resources->ToolbarImages );
if( !images )
{
const int imgSize = g_Conf->Toolbar_ImageSize ? 64 : 32;
m_ToolbarImages = new wxImageList( imgSize, imgSize );
images = new wxImageList( imgSize, imgSize );
wxFileName mess;
bool useTheme = (g_Conf->DeskTheme != L"default");
@ -155,10 +199,10 @@ wxImageList& Pcsx2App::GetImgList_Toolbars()
#define FancyLoadMacro( name ) \
{ \
EmbeddedImage<res_ToolbarIcon_##name> temp( imgSize, imgSize ); \
m_ImageId.Toolbars.name = m_ConfigImages.Add( LoadImageAny( img, useTheme, mess, L"ToolbarIcon" wxT(#name), temp ) ); \
m_Resources.ImageId.Toolbars.name = images->Add( LoadImageAny( img, useTheme, mess, L"ToolbarIcon" wxT(#name), temp ) ); \
}
}
return *m_ToolbarImages;
return *images;
}

View File

@ -237,26 +237,28 @@ enum MenuIDs_t
};
// ------------------------------------------------------------------------
ConsoleLogFrame::ConsoleLogFrame( MainEmuFrame *parent, const wxString& title, AppConfig::ConsoleLogOptions& options ) :
wxFrame(parent, wxID_ANY, title)
, m_conf( options )
, m_TextCtrl( *new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
ConsoleLogFrame::ConsoleLogFrame( MainEmuFrame *parent, const wxString& title, AppConfig::ConsoleLogOptions& options )
: wxFrame(parent, wxID_ANY, title)
, m_conf( options )
, m_TextCtrl( *new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
wxTE_MULTILINE | wxHSCROLL | wxTE_READONLY | wxTE_RICH2 ) )
, m_ColorTable( options.FontSize )
, m_ColorTable( options.FontSize )
, m_pendingFlushes( 0 )
, m_WaitingThreadsForFlush( 0 )
, m_QueueColorSection( L"ConsoleLog::QueueColorSection" )
, m_QueueBuffer( L"ConsoleLog::QueueBuffer" )
, m_CurQueuePos( false )
, m_ThawThrottle( 0 )
, m_ThawNeeded( false )
, m_ThawPending( false )
, m_QueueColorSection( L"ConsoleLog::QueueColorSection" )
, m_QueueBuffer( L"ConsoleLog::QueueBuffer" )
, m_CurQueuePos( false )
, m_threadlogger( EnableThreadedLoggingTest ? new ConsoleTestThread() : NULL )
, m_threadlogger( EnableThreadedLoggingTest ? new ConsoleTestThread() : NULL )
{
m_pendingFlushes = 0;
m_WaitingThreadsForFlush = 0;
m_ThawThrottle = 0;
m_ThawNeeded = false;
m_ThawPending = false;
SetIcons( wxGetApp().GetIconBundle() );
m_TextCtrl.SetBackgroundColour( wxColor( 230, 235, 242 ) );
m_TextCtrl.SetDefaultStyle( m_ColorTable[DefaultConsoleColor] );
@ -722,14 +724,16 @@ static void __concall ConsoleToWindow_Newline()
template< const IConsoleWriter& secondary >
static void __concall ConsoleToWindow_DoWrite( const wxString& fmt )
{
secondary.DoWrite( fmt );
if( secondary.DoWrite != NULL )
secondary.DoWrite( fmt );
((Pcsx2App&)*wxTheApp).GetProgramLog()->Write( Console.GetColor(), fmt );
}
template< const IConsoleWriter& secondary >
static void __concall ConsoleToWindow_DoWriteLn( const wxString& fmt )
{
secondary.DoWriteLn( fmt );
if( secondary.DoWriteLn != NULL )
secondary.DoWriteLn( fmt );
((Pcsx2App&)*wxTheApp).GetProgramLog()->Write( Console.GetColor(), fmt + L"\n" );
}

View File

@ -45,6 +45,8 @@ void GSFrame::InitDefaultAccelerators()
GSFrame::GSFrame(wxWindow* parent, const wxString& title):
wxFrame(parent, wxID_ANY, title, wxDefaultPosition, wxSize( 640, 480 ), wxDEFAULT_FRAME_STYLE )
{
SetIcons( wxGetApp().GetIconBundle() );
InitDefaultAccelerators();
//new wxStaticText( "" );

View File

@ -20,11 +20,6 @@
#include "Dialogs/ModalPopups.h"
#include "IsoDropTarget.h"
#include "Resources/EmbeddedImage.h"
#include "Resources/AppIcon16.h"
#include "Resources/AppIcon32.h"
#include "Resources/AppIcon64.h"
#include <wx/iconbndl.h>
#if _MSC_VER
@ -314,11 +309,8 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title):
// loses the transparency information when loading bitmaps into icons. But for some reason
// I cannot get it to work despite following various examples to the letter.
wxIconBundle bundle;
bundle.AddIcon( EmbeddedImage<res_AppIcon32>().GetIcon() );
bundle.AddIcon( EmbeddedImage<res_AppIcon64>().GetIcon() );
bundle.AddIcon( EmbeddedImage<res_AppIcon16>().GetIcon() );
SetIcons( bundle );
SetIcons( wxGetApp().GetIconBundle() );
int m_statusbar_widths[] = { (int)(backsize.GetWidth()*0.73), (int)(backsize.GetWidth()*0.25) };
m_statusbar.SetStatusWidths(2, m_statusbar_widths);

View File

@ -77,13 +77,13 @@ Panels::BaseAdvancedCpuOptions::BaseAdvancedCpuOptions( wxWindow& parent, int id
SetSizer( &s_adv );
Connect( wxID_DEFAULT, wxCommandEventHandler( BaseAdvancedCpuOptions::OnRestoreDefaults ) );
Connect( wxID_DEFAULT, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BaseAdvancedCpuOptions::OnRestoreDefaults ) );
}
void Panels::BaseAdvancedCpuOptions::OnRestoreDefaults(wxCommandEvent &evt)
{
m_RoundModePanel->SetSelection( 3 );
m_ClampModePanel->SetSelection( 0 );
m_RoundModePanel->SetSelection( 3 ); // Roundmode chop
m_ClampModePanel->SetSelection( 1 ); // clamp mode normal
m_Option_DAZ->SetValue(true);
m_Option_FTZ->SetValue(true);

View File

@ -126,7 +126,8 @@ void Panels::eeLogOptionsPanel::OnSettingsChanged()
{
const TraceLogFilters& conf( g_Conf->EmuOptions.Trace );
this->SetValue( conf.EE.m_EnableAll );
SetValue( conf.EE.m_EnableAll );
m_disasmPanel->SetValue( conf.EE.m_EnableDisasm );
m_evtPanel->SetValue( conf.EE.m_EnableEvents );
m_hwPanel->SetValue( conf.EE.m_EnableHardware );
@ -160,6 +161,7 @@ void Panels::iopLogOptionsPanel::OnSettingsChanged()
const TraceLogFilters& conf( g_Conf->EmuOptions.Trace );
SetValue( conf.IOP.m_EnableAll );
m_disasmPanel->SetValue( conf.IOP.m_EnableDisasm );
m_evtPanel->SetValue( conf.IOP.m_EnableEvents );
m_hwPanel->SetValue( conf.IOP.m_EnableHardware );
@ -201,12 +203,11 @@ Panels::LogOptionsPanel::LogOptionsPanel(wxWindow* parent, int idealWidth )
m_masterEnabler->SetToolTip( _("On-the-fly hotkey support: Toggle trace logging at any time using F10.") );
s_misc.Add( m_SIF = new pxCheckBox( this, L"SIF (EE<->IOP)" ));
m_SIF->SetToolTip(_("Enables logging of both SIF DMAs and SIF Register activity.") );
s_misc.Add( m_VIFunpack = new pxCheckBox( this, L"VIFunpack" ));
m_VIFunpack->SetToolTip(_("Special detailed logs of VIF packed data handling (does not include VIF control, status, or hwRegs)"));
s_misc.Add( m_GIFtag = new pxCheckBox( this, L"GIFtag" ));
m_SIF->SetToolTip(_("Enables logging of both SIF DMAs and SIF Register activity.") );
m_VIFunpack->SetToolTip(_("Special detailed logs of VIF packed data handling (does not include VIF control, status, or hwRegs)"));
m_GIFtag->SetToolTip(_("(not implemented yet)"));
//s_head.Add( &s_misc, SizerFlags::SubGroup() );
@ -232,7 +233,7 @@ void Panels::LogOptionsPanel::OnSettingsChanged()
m_masterEnabler->SetValue( conf.Enabled );
m_SIF->SetValue( conf.SIF );
SetCheckValue( EE, VIFunpack );
SetCheckValue( EE, GIFtag );

View File

@ -151,16 +151,16 @@ Panels::UsermodeSelectionPanel::UsermodeSelectionPanel( wxWindow& parent, int id
const RadioPanelItem UsermodeOptions[] =
{
RadioPanelItem(
_("User Documents (recommended)"),
_("Location: ") + wxStandardPaths::Get().GetDocumentsDir()
),
RadioPanelItem(
_("Current working folder (intended for developer use only)"),
_("Location: ") + wxGetCwd(),
_("This setting requires administration privileges from your operating system.")
),
RadioPanelItem(
_("User Documents (recommended)"),
_("Location: ") + wxStandardPaths::Get().GetDocumentsDir()
),
};
wxStaticBoxSizer* s_boxer = new wxStaticBoxSizer( wxVERTICAL, this, _( "Usermode Selection" ) );
@ -176,7 +176,7 @@ Panels::UsermodeSelectionPanel::UsermodeSelectionPanel( wxWindow& parent, int id
void Panels::UsermodeSelectionPanel::Apply()
{
UseAdminMode = (m_radio_UserMode->GetSelection() == 0);
UseAdminMode = (m_radio_UserMode->GetSelection() == 1);
}
// -----------------------------------------------------------------------

View File

@ -349,11 +349,13 @@ void Panels::PluginSelectorPanel::Apply()
wxString plugname( tbl_PluginInfo[ex.PluginId].GetShortname() );
throw Exception::CannotApplySettings( this,
// English Log
// Diagnostic
ex.FormatDiagnosticMessage(),
// Translated
wxsFormat( L"The selected %s plugin failed to load.", plugname.c_str() ) + L"\n\n" + GetApplyFailedMsg()
wxsFormat( _("The selected %s plugin failed to load.\n\nReason: %s\n\n"),
plugname.c_str(), ex.FormatDisplayMessage().c_str()
) + GetApplyFailedMsg()
);
}
}

View File

@ -16,22 +16,22 @@
#include "PrecompiledHeader.h"
#include "MainFrame.h"
RecentIsoList::RecentIsoList( wxMenu* menu ) :
RecentIsoManager::RecentIsoManager( wxMenu* menu ) :
m_Menu( menu )
, m_MaxLength( g_Conf->RecentFileCount )
, m_cursel( 0 )
, m_Separator( NULL )
, m_Listener_SettingsLoadSave( wxGetApp().Source_SettingsLoadSave(), EventListener<IniInterface>( this, OnSettingsLoadSave ) )
{
Connect( wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(RecentIsoList::OnChangedSelection) );
Connect( wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(RecentIsoManager::OnChangedSelection) );
}
RecentIsoList::~RecentIsoList() throw()
RecentIsoManager::~RecentIsoManager() throw()
{
Disconnect( wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(RecentIsoList::OnChangedSelection) );
Disconnect( wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(RecentIsoManager::OnChangedSelection) );
}
void RecentIsoList::OnChangedSelection( wxCommandEvent& evt )
void RecentIsoManager::OnChangedSelection( wxCommandEvent& evt )
{
uint cnt = m_Items.size();
uint i=0;
@ -53,7 +53,7 @@ void RecentIsoList::OnChangedSelection( wxCommandEvent& evt )
if( resume ) CoreThread.Resume();
}
void RecentIsoList::RemoveAllFromMenu()
void RecentIsoManager::RemoveAllFromMenu()
{
if( m_Menu == NULL ) return;
@ -73,7 +73,7 @@ void RecentIsoList::RemoveAllFromMenu()
}
}
void RecentIsoList::Repopulate()
void RecentIsoManager::Repopulate()
{
int cnt = m_Items.size();
if( cnt <= 0 ) return;
@ -84,7 +84,7 @@ void RecentIsoList::Repopulate()
InsertIntoMenu( i );
}
void RecentIsoList::Add( const wxString& src )
void RecentIsoManager::Add( const wxString& src )
{
if( src.IsEmpty() ) return;
@ -122,7 +122,7 @@ void RecentIsoList::Add( const wxString& src )
}
}
void RecentIsoList::InsertIntoMenu( int id )
void RecentIsoManager::InsertIntoMenu( int id )
{
if( m_Menu == NULL ) return;
RecentItem& curitem( m_Items[id] );
@ -132,7 +132,7 @@ void RecentIsoList::InsertIntoMenu( int id )
curitem.ItemPtr->Check();
}
void RecentIsoList::DoSettingsLoadSave( IniInterface& ini )
void RecentIsoManager::DoSettingsLoadSave( IniInterface& ini )
{
ini.GetConfig().SetRecordDefaults( false );
@ -168,8 +168,8 @@ void RecentIsoList::DoSettingsLoadSave( IniInterface& ini )
ini.GetConfig().SetRecordDefaults( true );
}
void __evt_fastcall RecentIsoList::OnSettingsLoadSave( void* obj, IniInterface& ini )
void __evt_fastcall RecentIsoManager::OnSettingsLoadSave( void* obj, IniInterface& ini )
{
if( obj == NULL ) return;
((RecentIsoList*)obj)->DoSettingsLoadSave( ini );
((RecentIsoManager*)obj)->DoSettingsLoadSave( ini );
}

View File

@ -16,9 +16,9 @@
#pragma once
// --------------------------------------------------------------------------------------
// RecentIsoList
// RecentIsoManager
// --------------------------------------------------------------------------------------
class RecentIsoList : public wxEvtHandler
class RecentIsoManager : public wxEvtHandler
{
protected:
struct RecentItem
@ -28,10 +28,10 @@ protected:
RecentItem() { ItemPtr = NULL; }
RecentItem( const wxString& src ) :
Filename( src )
, ItemPtr( NULL )
RecentItem( const wxString& src )
: Filename( src )
{
ItemPtr = NULL;
}
};
@ -46,8 +46,8 @@ protected:
EventListenerBinding<IniInterface> m_Listener_SettingsLoadSave;
public:
RecentIsoList( wxMenu* menu );
virtual ~RecentIsoList() throw();
RecentIsoManager( wxMenu* menu );
virtual ~RecentIsoManager() throw();
void RemoveAllFromMenu();
void Repopulate();

View File

@ -378,6 +378,32 @@ EXPORT_C GSconfigure()
EXPORT_C_(INT32) GStest()
{
if(!GSUtil::CheckSSE())
{
return -1;
}
#ifdef _WINDOWS
s_hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
if(!GSUtil::CheckDirectX())
{
if(SUCCEEDED(s_hr))
::CoUninitialize();
s_hr = E_FAIL;
return -1;
}
if(SUCCEEDED(s_hr))
::CoUninitialize();
s_hr = E_FAIL;
#endif
return 0;
}