A couple dozen user interface refinements; notables:

* Implemented GS window hiding on suspend (option was there, but not tied in)
 * Added Frameskipping options
 * Added option for disabling all GS output, for benchmarking EEcore stuffs.


git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2409 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2010-01-04 11:51:09 +00:00
parent d48067acb6
commit f293c2983b
47 changed files with 1955 additions and 1401 deletions

View File

@ -908,7 +908,7 @@ typedef struct _PS2E_ComponentAPI_GS
// This function may be called from either GUI thread or GS thread. Emulators calling
// it from non-GS threads must ensure mutex locking with TakeSnapshot (meaning the
// plugin should be free to disregard threading concerns).
void (PS2E_CALLBACK* SetSnapshotsFolder)( PS2E_THISPTR thisptr, const char* folder );
void (PS2E_CALLBACK* GsSetSnapshotsFolder)( PS2E_THISPTR thisptr, const char* folder );
// TakeSnapshot
// The GS plugin is to save the current frame into the given target image. This
@ -917,7 +917,7 @@ typedef struct _PS2E_ComponentAPI_GS
//
// Returns TRUE if the snapshot succeeded, or FALSE if it failed (contents of dest
// are considered indeterminate and will be ignored by the emu).
BOOL (PS2E_CALLBACK* TakeSnapshot)( PS2E_THISPTR thisptr, PS2E_Image* dest );
BOOL (PS2E_CALLBACK* GsTakeSnapshot)( PS2E_THISPTR thisptr, PS2E_Image* dest );
// OSD_QueueMessage
// Queues a message to the GS for display to the user. The GS can print the message
@ -955,7 +955,7 @@ typedef struct _PS2E_ComponentAPI_GS
// (if any critical errors accumulated during GStransferTags or GStransferImage, they
// should also be handled here by returning FALSE)
//
BOOL (PS2E_CALLBACK* GSvsync)(int field);
BOOL (PS2E_CALLBACK* GsVsync)(int field);
// GSwriteRegs
// Sends a GIFtag and associated register data. This is the main transfer method for all
@ -977,7 +977,7 @@ typedef struct _PS2E_ComponentAPI_GS
//
// nloop - number of loops of register data. Valid range is 1->32767 (upper 17
// bits are always zero). This value will never be zero.
void (PS2E_CALLBACK* GSwriteRegs)(const u128 *pMem, int regcnt, int nloop);
void (PS2E_CALLBACK* GsWriteRegs)(const u128 *pMem, int regcnt, int nloop);
// GSwritePrim
// Starts a new prim by sending the specified value to the PRIM register. The emulator
@ -987,7 +987,7 @@ typedef struct _PS2E_ComponentAPI_GS
// Parameters:
// primData - value to write to the PRIM register. Only the bottom 10 bits are
// valid. Upper bits are always zero.
void (PS2E_CALLBACK* GSwritePrim)(int primData);
void (PS2E_CALLBACK* GsWritePrim)(int primData);
// GSwriteImage
// Uploads new image data. Data uploaded may be in any number of partial chunks, for
@ -997,14 +997,14 @@ typedef struct _PS2E_ComponentAPI_GS
// larger texture buffer, or for games to modify several portions of a single large
// buffer, by using mid-transfer writes to TRXPOS and TRXDIR (TRXPOS writes only become
// effective once TRXDIR has been written).
void (PS2E_CALLBACK* GSwriteImage)(const u128 *pMem, int qwc_cnt);
void (PS2E_CALLBACK* GsWriteImage)(const u128 *pMem, int qwc_cnt);
// GSreadImage
// This special callback is for implementing the Read mode direction of the GIFpath.
// The GS plugin writes the texture data as requested by it's internally managed state
// values for TRXPOS/TRXREG to the buffer provided by pMem. The buffer size is qwc_cnt
// and the GS must not write more than that.
void (PS2E_CALLBACK* GSreadImage)(u128 *pMem, int qwc_cnt);
void (PS2E_CALLBACK* GsReadImage)(u128 *pMem, int qwc_cnt);
void* reserved[8];
@ -1113,7 +1113,7 @@ typedef struct _PS2E_KeyEvent
// PS2E_ComponentAPI_Pad
// --------------------------------------------------------------------------------------
// Thread Safety:
// * Thread affinity is not guaranteed. Even PadKeyEvent may be called from a thrad not
// * Thread affinity is not guaranteed. Even PadKeyEvent may be called from a thread not
// belonging to the active window (the window where the GA is output). Other calls may
// be made from either the main emu thread or an EE/IOP/GS child thread (if the emulator
// uses them).

View File

@ -297,9 +297,9 @@ class wxDialogWithHelpers : public wxDialog
DECLARE_DYNAMIC_CLASS_NO_COPY(wxDialogWithHelpers)
protected:
bool m_hasContextHelp;
int m_idealWidth;
wxBoxSizer* m_extraButtonSizer;
bool m_hasContextHelp;
int m_idealWidth;
wxBoxSizer* m_extraButtonSizer;
public:
wxDialogWithHelpers();
@ -493,6 +493,17 @@ public:
static void SetManualBusyCursor( BusyCursorType busytype );
};
// --------------------------------------------------------------------------------------
// pxFitToDigits
// --------------------------------------------------------------------------------------
// Fits a given text or spinner control to the number of digits requested, since by default
// they're usually way over-sized.
extern void pxFitToDigits( wxWindow* win, int digits );
extern void pxFitToDigits( wxSpinCtrl* win, int digits );
extern wxTextCtrl* CreateNumericalTextCtrl( wxWindow* parent, int digits );
//////////////////////////////////////////////////////////////////////////////////////////////
extern bool pxDialogExists( const wxString& name );
@ -502,7 +513,6 @@ extern wxRect wxGetDisplayArea();
extern wxString pxFormatToolTipText( wxWindow* wind, const wxString& src );
extern void pxSetToolTip( wxWindow* wind, const wxString& src );
extern void pxSetToolTip( wxWindow& wind, const wxString& src );
extern wxFont pxGetFixedFont( int ptsize=8, int weight=wxNORMAL );

View File

@ -84,11 +84,11 @@ int pxStaticText::GetIdealWidth() const
wxWindow* millrun = this->GetParent();
while( (idealWidth == wxDefaultCoord) && millrun != NULL )
{
if( wxIsKindOf( millrun, wxPanelWithHelpers ) )
idealWidth = ((wxPanelWithHelpers*)millrun)->GetIdealWidth();
if( wxPanelWithHelpers* panel = wxDynamicCast( millrun, wxPanelWithHelpers ) )
idealWidth = panel->GetIdealWidth();
else if( wxIsKindOf( millrun, wxDialogWithHelpers ) )
idealWidth = ((wxDialogWithHelpers*)millrun)->GetIdealWidth();
else if( wxDialogWithHelpers* dialog = wxDynamicCast( millrun, wxDialogWithHelpers ) )
idealWidth = dialog->GetIdealWidth();
millrun = millrun->GetParent();
}

View File

@ -20,22 +20,49 @@
#include <wx/cshelp.h>
#include <wx/tooltip.h>
#include <wx/spinctrl.h>
using namespace pxSizerFlags;
// Creates a text control which is right-justified and has it's minimum width configured to suit
// the number of digits requested.
wxTextCtrl* CreateNumericalTextCtrl( wxWindow* parent, int digits )
{
wxTextCtrl* ctrl = new wxTextCtrl( parent, wxID_ANY );
ctrl->SetWindowStyleFlag( wxTE_RIGHT );
pxFitToDigits( ctrl, digits );
return ctrl;
}
// =====================================================================================================
// wxDialogWithHelpers Class Implementations
// =====================================================================================================
void pxFitToDigits( wxWindow* win, int digits )
{
int ex;
win->GetTextExtent( wxString( L'0', digits+1 ), &ex, NULL );
win->SetMinSize( wxSize( ex+10, wxDefaultCoord ) ); // +10 for text control borders/insets and junk.
}
void pxFitToDigits( wxSpinCtrl* win, int digits )
{
// HACK!! The better way would be to create a pxSpinCtrl class that extends wxSpinCtrl and thus
// have access to wxSpinButton::DoGetBestSize(). But since I don't want to do that, we'll just
// make/fake it with a value it's pretty common to Win32/GTK/Mac:
static const int MagicSpinnerSize = 18;
int ex;
win->GetTextExtent( wxString( L'0', digits+1 ), &ex, NULL );
win->SetMinSize( wxSize( ex+10+MagicSpinnerSize, wxDefaultCoord ) ); // +10 for text control borders/insets and junk.
}
bool pxDialogExists( const wxString& name )
{
return wxFindWindowByName( name ) != NULL;
}
// --------------------------------------------------------------------------------------
// wxDialogWithHelpers Implementation
// --------------------------------------------------------------------------------------
// =====================================================================================================
// wxDialogWithHelpers Class Implementations
// =====================================================================================================
IMPLEMENT_DYNAMIC_CLASS(wxDialogWithHelpers, wxDialog)
wxDialogWithHelpers::wxDialogWithHelpers()

View File

@ -386,6 +386,7 @@ struct Pcsx2Config
// forces the MTGS to execute tags/tasks in fully blocking/synchronous
// style. Useful for debugging potential bugs in the MTGS pipeline.
bool SynchronousMTGS;
bool DisableOutput;
bool FrameLimitEnable;
bool FrameSkipEnable;
@ -396,8 +397,8 @@ struct Pcsx2Config
// proper audio playback speed).
int DefaultRegionMode; // 0=NTSC and 1=PAL
int ConsecutiveFrames; // number of consecutive frames (fields) to render
int ConsecutiveSkip; // number of consecutive frames (fields) to skip
int FramesToDraw; // number of consecutive frames (fields) to render
int FramesToSkip; // number of consecutive frames (fields) to skip
Fixed100 LimitScalar;
Fixed100 FramerateNTSC;
@ -410,6 +411,7 @@ struct Pcsx2Config
{
return
OpEqu( SynchronousMTGS ) &&
OpEqu( DisableOutput ) &&
OpEqu( FrameSkipEnable ) &&
OpEqu( FrameLimitEnable ) &&
OpEqu( VsyncEnable ) &&
@ -419,8 +421,8 @@ struct Pcsx2Config
OpEqu( FrameratePAL ) &&
OpEqu( DefaultRegionMode ) &&
OpEqu( ConsecutiveFrames ) &&
OpEqu( ConsecutiveSkip );
OpEqu( FramesToDraw ) &&
OpEqu( FramesToSkip );
}
bool operator !=( const GSOptions& right ) const

View File

@ -338,6 +338,7 @@ void gsIrq() {
__forceinline void gsFrameSkip()
{
if( !EmuConfig.GS.FrameSkipEnable ) return;
static int consec_skipped = 0;
@ -349,7 +350,7 @@ __forceinline void gsFrameSkip()
if( isSkipping )
{
++consec_skipped;
if( consec_skipped >= EmuConfig.GS.ConsecutiveSkip )
if( consec_skipped >= EmuConfig.GS.FramesToSkip )
{
consec_skipped = 0;
isSkipping = false;
@ -358,7 +359,7 @@ __forceinline void gsFrameSkip()
else
{
++consec_drawn;
if( consec_drawn >= EmuConfig.GS.ConsecutiveFrames )
if( consec_drawn >= EmuConfig.GS.FramesToDraw )
{
consec_drawn = 0;
isSkipping = true;

File diff suppressed because it is too large Load Diff

View File

@ -280,6 +280,12 @@ void SysMtgsThread::ExecuteTaskInThread()
// ever be modified by this thread.
while( m_RingPos != volatize(m_WritePos))
{
if( EmuConfig.GS.DisableOutput )
{
m_RingPos = m_WritePos;
continue;
}
pxAssert( m_RingPos < RingBufferSize );
const PacketTagType& tag = (PacketTagType&)RingBuffer[m_RingPos];

View File

@ -208,12 +208,13 @@ Pcsx2Config::GSOptions::GSOptions()
{
FrameLimitEnable = true;
FrameSkipEnable = false;
SynchronousMTGS = false;
DisableOutput = false;
DefaultRegionMode = Region_NTSC;
ConsecutiveFrames = 2;
ConsecutiveSkip = 2;
FramesToDraw = 2;
FramesToSkip = 2;
LimitScalar = 1.0;
FramerateNTSC = 59.94;
@ -225,6 +226,9 @@ void Pcsx2Config::GSOptions::LoadSave( IniInterface& ini )
GSOptions defaults;
IniScopedGroup path( ini, L"GS" );
IniEntry( SynchronousMTGS );
IniEntry( DisableOutput );
IniEntry( FrameLimitEnable );
IniEntry( FrameSkipEnable );
IniEntry( VsyncEnable );
@ -236,8 +240,8 @@ void Pcsx2Config::GSOptions::LoadSave( IniInterface& ini )
static const wxChar * const ntsc_pal_str[2] = { L"ntsc", L"pal" };
ini.EnumEntry( L"DefaultRegionMode", DefaultRegionMode, ntsc_pal_str, defaults.DefaultRegionMode );
IniEntry( ConsecutiveFrames );
IniEntry( ConsecutiveSkip );
IniEntry( FramesToDraw );
IniEntry( FramesToSkip );
}
void Pcsx2Config::GamefixOptions::LoadSave( IniInterface& ini )

View File

@ -665,7 +665,7 @@ void SaveStateBase::sioFreeze()
{
for( int port=0; port<2; ++port )
{
for( int slot=0; slot<8; ++slot )
for( int slot=0; slot<4; ++slot )
m_mcdCRCs[port][slot] = SysPlugins.McdGetCRC( port, slot );
}
}
@ -688,7 +688,7 @@ void SaveStateBase::sioFreeze()
for( int port=0; port<2; ++port )
{
for( int slot=0; slot<8; ++slot )
for( int slot=0; slot<4; ++slot )
{
u64 newCRC = SysPlugins.McdGetCRC( port, slot );
if( newCRC != m_mcdCRCs[port][slot] )

View File

@ -85,9 +85,10 @@ enum MenuIdentifiers
MenuId_SkipBiosToggle, // enables the Bios Skip speedhack
MenuId_Sys_SuspendResume, // suspends/resumes active emulation, retains plugin states
MenuId_Sys_SuspendResume, // suspends/resumes active emulation, retains plugin states
MenuId_Sys_Close, // Closes the emulator (states are preserved)
MenuId_Sys_Reset, // Issues a complete reset (wipes preserved states)
MenuId_Sys_Reset, // Issues a complete VM reset (wipes preserved states)
MenuId_Sys_Shutdown, // Closes virtual machine, shuts down plugins, wipes states.
MenuId_Sys_LoadStates, // Opens load states submenu
MenuId_Sys_SaveStates, // Opens save states submenu
MenuId_EnablePatches,
@ -102,7 +103,8 @@ enum MenuIdentifiers
MenuId_State_EndSlotSection = MenuId_State_Save01+20,
// Config Subsection
MenuId_Config_Settings,
MenuId_Config_SysSettings,
MenuId_Config_AppSettings,
MenuId_Config_BIOS,
// Plugin ID order is important. Must match the order in tbl_PluginInfo.
@ -563,6 +565,18 @@ DECLARE_APP(Pcsx2App)
#define sMenuBar \
if( wxMenuBar* __menubar_ = GetMenuBar() ) (*__menubar_)
// --------------------------------------------------------------------------------------
// AppOpenDialog
// --------------------------------------------------------------------------------------
template<typename DialogType>
void AppOpenDialog( wxWindow* parent )
{
if( wxWindow* window = wxFindWindowByName( DialogType::GetNameStatic() ) )
window->SetFocus();
else
(new DialogType( parent ))->Show();
}
// --------------------------------------------------------------------------------------
// SaveSinglePluginHelper
// --------------------------------------------------------------------------------------

View File

@ -32,6 +32,14 @@ class PipeRedirectionBase;
class AppCoreThread;
class pxPingEvent;
// wxWidgets forward declarations
class wxDirPickerCtrl;
class wxFileDirPickerEvent;
class wxListBox;
class wxListbook;
class wxBookCtrlBase;
enum AppEventType
{
// Maybe this will be expanded upon later..?
@ -49,4 +57,3 @@ enum PluginEventType
};
#include "AppConfig.h"
#include "Panels/BaseConfigPanel.h"

View File

@ -323,7 +323,8 @@ wxString AppConfig::FullpathToMcd( uint port, uint slot ) const
AppConfig::AppConfig()
: MainGuiPosition( wxDefaultPosition )
, SettingsTabName( L"Cpu" )
, SysSettingsTabName( L"Cpu" )
, AppSettingsTabName( L"GS Window" )
, DeskTheme( L"default" )
{
LanguageId = wxLANGUAGE_DEFAULT;
@ -391,7 +392,8 @@ void AppConfig::LoadSaveRootItems( IniInterface& ini )
AppConfig defaults;
IniEntry( MainGuiPosition );
IniEntry( SettingsTabName );
IniEntry( SysSettingsTabName );
IniEntry( AppSettingsTabName );
ini.EnumEntry( L"LanguageId", LanguageId, NULL, defaults.LanguageId );
IniEntry( RecentIsoCount );
IniEntry( DeskTheme );
@ -415,30 +417,30 @@ void AppConfig::LoadSave( IniInterface& ini )
// Process various sub-components:
ProgLogBox .LoadSave( ini, L"ProgramLog" );
Ps2ConBox .LoadSave( ini, L"Ps2Console" );
Folders .LoadSave( ini );
BaseFilenames .LoadSave( ini );
GSWindow .LoadSave( ini );
Framerate .LoadSave( ini );
// Load Emulation options and apply some defaults overtop saved items, which are regulated
// by the PCSX2 UI.
EmuOptions.LoadSave( ini );
if( ini.IsLoading() )
EmuOptions.GS.LimitScalar = GSWindow.NominalScalar;
EmuOptions.GS.LimitScalar = Framerate.NominalScalar;
ini.Flush();
}
// ------------------------------------------------------------------------
AppConfig::ConsoleLogOptions::ConsoleLogOptions()
: Visible( false )
, AutoDock( true )
, DisplayPosition( wxDefaultPosition )
: DisplayPosition( wxDefaultPosition )
, DisplaySize( wxSize( 680, 560 ) )
, FontSize( 8 )
{
Visible = false;
AutoDock = true;
FontSize = 8;
}
void AppConfig::ConsoleLogOptions::LoadSave( IniInterface& ini, const wxChar* logger )
@ -540,10 +542,6 @@ void AppConfig::FilenameOptions::LoadSave( IniInterface& ini )
// ------------------------------------------------------------------------
AppConfig::GSWindowOptions::GSWindowOptions()
{
NominalScalar = 1.0;
TurboScalar = 3.0;
SlomoScalar = 0.33;
CloseOnEsc = true;
DefaultToFullscreen = false;
AlwaysHideMouse = false;
@ -561,20 +559,17 @@ void AppConfig::GSWindowOptions::SanityCheck()
{
// Ensure Conformation of various options...
NominalScalar .ConfineTo( 0.05, 10.0 );
TurboScalar .ConfineTo( 0.05, 10.0 );
SlomoScalar .ConfineTo( 0.05, 10.0 );
WindowSize.x = std::max( WindowSize.x, 8 );
WindowSize.x = std::min( WindowSize.x, wxGetDisplayArea().GetWidth()-16 );
WindowSize.y = std::max( WindowSize.y, 8 );
WindowSize.y = std::min( WindowSize.y, wxGetDisplayArea().GetHeight()-48 );
if( !wxGetDisplayArea().Contains( wxRect( WindowPos, WindowSize ) ) )
// Make sure the upper left corner of the window is visible enought o grab and
// move into view:
if( !wxGetDisplayArea().Contains( wxRect( WindowPos, wxSize( 48,48 ) ) ) )
WindowPos = wxDefaultPosition;
if( (uint)AspectRatio >= (uint)AspectRatio_MaxCount )
AspectRatio = AspectRatio_4_3;
}
@ -584,10 +579,6 @@ void AppConfig::GSWindowOptions::LoadSave( IniInterface& ini )
IniScopedGroup path( ini, L"GSWindow" );
GSWindowOptions defaults;
IniEntry( NominalScalar );
IniEntry( TurboScalar );
IniEntry( SlomoScalar );
IniEntry( CloseOnEsc );
IniEntry( DefaultToFullscreen );
IniEntry( AlwaysHideMouse );
@ -603,12 +594,47 @@ void AppConfig::GSWindowOptions::LoadSave( IniInterface& ini )
L"4:3",
L"16:9",
};
ini.EnumEntry( L"AspectRatio", AspectRatio, AspectRatioNames, defaults.AspectRatio );
if( ini.IsLoading() ) SanityCheck();
}
// ----------------------------------------------------------------------------
AppConfig::FramerateOptions::FramerateOptions()
{
NominalScalar = 1.0;
TurboScalar = 3.0;
SlomoScalar = 0.33;
SkipOnLimit = false;
SkipOnTurbo = false;
}
void AppConfig::FramerateOptions::SanityCheck()
{
// Ensure Conformation of various options...
NominalScalar .ConfineTo( 0.05, 10.0 );
TurboScalar .ConfineTo( 0.05, 10.0 );
SlomoScalar .ConfineTo( 0.05, 10.0 );
}
void AppConfig::FramerateOptions::LoadSave( IniInterface& ini )
{
IniScopedGroup path( ini, L"Framerate" );
FramerateOptions defaults;
IniEntry( NominalScalar );
IniEntry( TurboScalar );
IniEntry( SlomoScalar );
IniEntry( SkipOnLimit );
IniEntry( SkipOnTurbo );
}
wxFileConfig* OpenFileConfig( const wxString& filename )
{
return new wxFileConfig( wxEmptyString, wxEmptyString, filename, wxEmptyString, wxCONFIG_USE_RELATIVE_PATH );

View File

@ -135,12 +135,23 @@ public:
wxPoint WindowPos;
bool IsMaximized;
GSWindowOptions();
void LoadSave( IniInterface& conf );
void SanityCheck();
};
struct FramerateOptions
{
bool SkipOnLimit;
bool SkipOnTurbo;
Fixed100 NominalScalar;
Fixed100 TurboScalar;
Fixed100 SlomoScalar;
GSWindowOptions();
FramerateOptions();
void LoadSave( IniInterface& conf );
void SanityCheck();
};
@ -150,7 +161,8 @@ public:
// Because remembering the last used tab on the settings panel is cool (tab is remembered
// by it's UTF/ASCII name).
wxString SettingsTabName;
wxString SysSettingsTabName;
wxString AppSettingsTabName;
// Current language in use (correlates to a wxWidgets wxLANGUAGE specifier)
wxLanguage LanguageId;
@ -185,10 +197,10 @@ public:
McdOptions Mcd[2][4];
ConsoleLogOptions ProgLogBox;
ConsoleLogOptions Ps2ConBox;
FolderOptions Folders;
FilenameOptions BaseFilenames;
GSWindowOptions GSWindow;
FramerateOptions Framerate;
// PCSX2-core emulation options, which are passed to the emu core prior to initiating
// an emulation session. Note these are the options saved into the GUI ini file and

View File

@ -59,6 +59,11 @@ bool AppCoreThread::Suspend( bool isBlocking )
if( !retval || isBlocking )
ScopedBusyCursor::SetDefault( Cursor_NotBusy );
if( g_Conf->GSWindow.CloseOnEsc )
{
sGSFrame.Hide();
}
return retval;
}
@ -127,7 +132,9 @@ void AppCoreThread::OnResumeReady()
AppSaveSettings();
if( GSopen2 != NULL )
wxGetApp().OpenGsFrame();
{
sApp.OpenGsFrame();
}
_parent::OnResumeReady();
}

View File

@ -63,10 +63,10 @@ static bool HandlePluginError( Exception::PluginError& ex )
if( result )
{
g_Conf->SettingsTabName = L"Plugins";
g_Conf->SysSettingsTabName = L"Plugins";
// fixme: Send a message to the panel to select the failed plugin.
if( wxGetApp().IssueModalDialog( Dialogs::ConfigurationDialog::GetNameStatic() ) == wxID_CANCEL )
if( wxGetApp().IssueModalDialog( Dialogs::SysConfigDialog::GetNameStatic() ) == wxID_CANCEL )
return false;
}
return result;
@ -298,8 +298,10 @@ int Pcsx2App::IssueModalDialog( const wxString& dlgName )
{
using namespace Dialogs;
if( dlgName == ConfigurationDialog::GetNameStatic() )
return ConfigurationDialog().ShowModal();
if( dlgName == SysConfigDialog::GetNameStatic() )
return SysConfigDialog().ShowModal();
if( dlgName == AppConfigDialog::GetNameStatic() )
return AppConfigDialog().ShowModal();
if( dlgName == BiosSelectorDialog::GetNameStatic() )
return BiosSelectorDialog().ShowModal();
if( dlgName == LogOptionsDialog::GetNameStatic() )
@ -608,11 +610,12 @@ void AppSaveSettings()
void Pcsx2App::OpenGsFrame()
{
if( m_gsFrame != NULL ) return;
m_gsFrame = new GSFrame( m_MainFrame, L"PCSX2" );
m_gsFrame->SetFocus();
pDsp = (uptr)m_gsFrame->GetViewport()->GetHandle();
if( m_gsFrame == NULL )
{
m_gsFrame = new GSFrame( m_MainFrame, L"PCSX2" );
m_gsFrame->SetFocus();
pDsp = (uptr)m_gsFrame->GetViewport()->GetHandle();
}
m_gsFrame->Show();
// The "in the main window" quickie hack...

176
pcsx2/gui/ApplyState.h Normal file
View File

@ -0,0 +1,176 @@
/* 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 <list>
#include <wx/wizard.h>
#include "AppCommon.h"
class BaseApplicableConfigPanel;
namespace Exception
{
// --------------------------------------------------------------------------
// Exception used to perform an abort of Apply/Ok action on settings panels.
// 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.
//
class CannotApplySettings : public BaseException
{
public:
bool IsVerbose;
protected:
BaseApplicableConfigPanel* m_Panel;
public:
DEFINE_EXCEPTION_COPYTORS( CannotApplySettings )
explicit CannotApplySettings( BaseApplicableConfigPanel* thispanel, const char* msg=wxLt("Cannot apply new settings, one of the settings is invalid."), bool isVerbose = true )
{
BaseException::InitBaseEx( msg );
m_Panel = thispanel;
IsVerbose = isVerbose;
}
explicit CannotApplySettings( BaseApplicableConfigPanel* thispanel, const wxString& msg_eng, const wxString& msg_xlt )
{
BaseException::InitBaseEx( msg_eng, msg_xlt );
m_Panel = thispanel;
IsVerbose = true;
}
BaseApplicableConfigPanel* GetPanel()
{
return m_Panel;
}
};
}
typedef std::list<BaseApplicableConfigPanel*> PanelApplyList_t;
struct ApplyStateStruct
{
// collection of ApplicableConfigPanels that belong to a dialog box.
PanelApplyList_t PanelList;
// Current book page being initialized. Any apply objects created will use
// 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;
ApplyStateStruct()
{
CurOwnerPage = wxID_NONE;
ParentBook = NULL;
}
void SetCurrentPage( int page )
{
CurOwnerPage = page;
}
void ClearCurrentPage()
{
CurOwnerPage = wxID_NONE;
}
void StartBook( wxBookCtrlBase* book );
void StartWizard();
bool ApplyAll();
bool ApplyPage( int pageid );
void DoCleanup() throw();
};
class IApplyState
{
protected:
ApplyStateStruct m_ApplyState;
public:
virtual ApplyStateStruct& GetApplyState() { return m_ApplyState; }
};
// --------------------------------------------------------------------------------------
// BaseApplicableConfigPanel
// --------------------------------------------------------------------------------------
// Extends the Panel class to add an Apply() method, which is invoked from the parent
// window (usually the ConfigurationDialog) when either Ok or Apply is clicked.
//
// 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
// user at any time (ie, a singular modal dialog).
//
class BaseApplicableConfigPanel : public wxPanelWithHelpers
{
protected:
int m_OwnerPage;
wxBookCtrlBase* m_OwnerBook;
EventListenerBinding<int> m_Listener_SettingsApplied;
public:
virtual ~BaseApplicableConfigPanel() throw();
BaseApplicableConfigPanel( wxWindow* parent, wxOrientation orient=wxVERTICAL );
BaseApplicableConfigPanel( wxWindow* parent, wxOrientation orient, const wxString& staticLabel );
int GetOwnerPage() const { return m_OwnerPage; }
wxBookCtrlBase* GetOwnerBook() { return m_OwnerBook; }
void SetFocusToMe();
IApplyState* FindApplyStateManager() const;
// 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.
// If no exceptions are thrown, then the operation is assumed a success. :)
virtual void Apply()=0;
// This method is bound to the ApplySettings event from the PCSX2 app manager.
// Note: This method *will* be called automatically after a successful Apply, but will not
// be called after a failed Apply (canceled due to error).
virtual void OnSettingsChanged()=0;
protected:
static void __evt_fastcall OnSettingsApplied( void* obj, int& evt );
void Init();
};
class ApplicableWizardPage : public wxWizardPageSimple, public IApplyState
{
DECLARE_DYNAMIC_CLASS_NO_COPY(ApplicableWizardPage)
public:
ApplicableWizardPage(
wxWizard* parent=NULL,
wxWizardPage *prev = NULL,
wxWizardPage *next = NULL,
const wxBitmap& bitmap = wxNullBitmap
);
virtual ~ApplicableWizardPage() throw() { m_ApplyState.DoCleanup(); }
};

View File

View File

@ -0,0 +1,173 @@
/* 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 "System.h"
#include "App.h"
#include "ConfigurationDialog.h"
#include "ModalPopups.h"
#include "Panels/ConfigurationPanels.h"
#include "Resources/EmbeddedImage.h"
#include "Resources/ButtonIcon_Camera.h"
#include <wx/artprov.h>
#include <wx/filepicker.h>
#include <wx/listbook.h>
using namespace Panels;
// configure the orientation of the listbox based on the platform
#if defined(__WXMAC__) || defined(__WXMSW__)
static const int s_orient = wxBK_TOP;
#else
static const int s_orient = wxBK_LEFT;
#endif
IMPLEMENT_DYNAMIC_CLASS(Dialogs::BaseApplicableDialog, wxDialogWithHelpers)
Dialogs::BaseApplicableDialog::BaseApplicableDialog( wxWindow* parent, const wxString& title )
: wxDialogWithHelpers( parent, title, false )
{
}
Dialogs::BaseApplicableDialog::BaseApplicableDialog( wxWindow* parent, const wxString& title, wxOrientation sizerOrient )
: wxDialogWithHelpers( parent, title, sizerOrient )
{
}
Dialogs::BaseApplicableDialog::~BaseApplicableDialog() throw()
{
m_ApplyState.DoCleanup();
}
Dialogs::BaseConfigurationDialog::BaseConfigurationDialog( wxWindow* parent, const wxString& title, wxImageList& bookicons, int idealWidth )
: BaseApplicableDialog( parent, title, wxVERTICAL )
, m_listbook( *new wxListbook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, s_orient ) )
{
m_idealWidth = idealWidth;
m_listbook.SetImageList( &bookicons );
m_ApplyState.StartBook( &m_listbook );
wxBitmapButton& screenshotButton( *new wxBitmapButton( this, wxID_SAVE, EmbeddedImage<res_ButtonIcon_Camera>().Get() ) );
screenshotButton.SetToolTip( _("Saves a snapshot of this settings panel to a PNG file.") );
*this += m_listbook;
AddOkCancel( *GetSizer(), true );
*m_extraButtonSizer += screenshotButton;
Connect( wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BaseConfigurationDialog::OnOk_Click ) );
Connect( wxID_CANCEL, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BaseConfigurationDialog::OnCancel_Click ) );
Connect( wxID_APPLY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BaseConfigurationDialog::OnApply_Click ) );
Connect( wxID_SAVE, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BaseConfigurationDialog::OnScreenshot_Click ) );
Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler(BaseConfigurationDialog::OnCloseWindow) );
// ----------------------------------------------------------------------------
// Bind a variety of standard "something probably changed" events. If the user invokes
// any of these, we'll automatically de-gray the Apply button for this dialog box. :)
#define ConnectSomethingChanged( command ) \
Connect( wxEVT_COMMAND_##command, wxCommandEventHandler( BaseConfigurationDialog::OnSomethingChanged ) );
ConnectSomethingChanged( RADIOBUTTON_SELECTED );
ConnectSomethingChanged( COMBOBOX_SELECTED );
ConnectSomethingChanged( CHECKBOX_CLICKED );
ConnectSomethingChanged( BUTTON_CLICKED );
ConnectSomethingChanged( CHOICE_SELECTED );
ConnectSomethingChanged( LISTBOX_SELECTED );
ConnectSomethingChanged( SPINCTRL_UPDATED );
ConnectSomethingChanged( SLIDER_UPDATED );
ConnectSomethingChanged( DIRPICKER_CHANGED );
FindWindow( wxID_APPLY )->Disable();
}
Dialogs::BaseConfigurationDialog::~BaseConfigurationDialog() throw()
{
}
void Dialogs::BaseConfigurationDialog::OnSomethingChanged( wxCommandEvent& evt )
{
evt.Skip();
if( (evt.GetId() != wxID_OK) && (evt.GetId() != wxID_CANCEL) && (evt.GetId() != wxID_APPLY) )
{
FindWindow( wxID_APPLY )->Enable();
}
}
void Dialogs::BaseConfigurationDialog::OnCloseWindow( wxCloseEvent& evt )
{
if( !IsModal() ) Destroy();
evt.Skip();
}
void Dialogs::BaseConfigurationDialog::OnOk_Click( wxCommandEvent& evt )
{
if( m_ApplyState.ApplyAll() )
{
FindWindow( wxID_APPLY )->Disable();
GetConfSettingsTabName() = m_labels[m_listbook.GetSelection()];
AppSaveSettings();
evt.Skip();
}
}
void Dialogs::BaseConfigurationDialog::OnCancel_Click( wxCommandEvent& evt )
{
evt.Skip();
GetConfSettingsTabName() = m_labels[m_listbook.GetSelection()];
}
void Dialogs::BaseConfigurationDialog::OnApply_Click( wxCommandEvent& evt )
{
if( m_ApplyState.ApplyAll() )
FindWindow( wxID_APPLY )->Disable();
GetConfSettingsTabName() = m_labels[m_listbook.GetSelection()];
AppSaveSettings();
}
void Dialogs::BaseConfigurationDialog::OnScreenshot_Click( wxCommandEvent& evt )
{
wxBitmap memBmp;
{
wxWindowDC dc( this );
wxSize dcsize( dc.GetSize() );
wxMemoryDC memDC( memBmp = wxBitmap( dcsize.x, dcsize.y ) );
memDC.Blit( wxPoint(), dcsize, &dc, wxPoint() );
}
wxString filenameDefault;
filenameDefault.Printf( L"pcsx2_settings_%s.png", m_listbook.GetPageText( m_listbook.GetSelection() ).c_str() );
filenameDefault.Replace( L"/", L"-" );
wxString filename( wxFileSelector( _("Save dialog screenshots to..."), g_Conf->Folders.Snapshots.ToString(),
filenameDefault, L"png", NULL, wxFD_SAVE | wxFD_OVERWRITE_PROMPT, this ) );
if( !filename.IsEmpty() )
{
ScopedBusyCursor busy( Cursor_ReallyBusy );
memBmp.SaveFile( filename, wxBITMAP_TYPE_PNG );
}
}

View File

@ -0,0 +1,28 @@
/* 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/listbook.h>
template< typename T >
void Dialogs::BaseConfigurationDialog::AddPage( const char* label, int iconid )
{
const wxString labelstr( fromUTF8( label ) );
const int curidx = m_labels.Add( labelstr );
m_ApplyState.SetCurrentPage( curidx );
m_listbook.AddPage( new T( &m_listbook ), wxGetTranslation( labelstr ),
( labelstr == GetConfSettingsTabName() ), iconid );
}

View File

@ -0,0 +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 "System.h"
#include "App.h"
#include "ConfigurationDialog.h"
#include "ModalPopups.h"
#include "Panels/ConfigurationPanels.h"
#include <wx/filepicker.h>
using namespace Panels;
// ----------------------------------------------------------------------------
Dialogs::BiosSelectorDialog::BiosSelectorDialog( wxWindow* parent )
: BaseApplicableDialog( parent, _("BIOS Selector"), wxVERTICAL )
{
SetName( GetNameStatic() );
m_idealWidth = 500;
Panels::BaseSelectorPanel* selpan = new Panels::BiosSelectorPanel( this );
*this += selpan | pxSizerFlags::StdExpand();
AddOkCancel( *GetSizer(), false );
Connect( wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BiosSelectorDialog::OnOk_Click) );
Connect( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEventHandler(BiosSelectorDialog::OnDoubleClicked) );
selpan->OnShown();
}
void Dialogs::BiosSelectorDialog::OnOk_Click( wxCommandEvent& evt )
{
if( m_ApplyState.ApplyAll() )
{
Close();
evt.Skip();
}
}
void Dialogs::BiosSelectorDialog::OnDoubleClicked( wxCommandEvent& evt )
{
wxWindow* forwardButton = FindWindow( wxID_OK );
if( forwardButton == NULL ) return;
wxCommandEvent nextpg( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK );
nextpg.SetEventObject( forwardButton );
forwardButton->GetEventHandler()->ProcessEvent( nextpg );
}

View File

@ -1,227 +0,0 @@
/* 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 "System.h"
#include "App.h"
#include "ConfigurationDialog.h"
#include "ModalPopups.h"
#include "Panels/ConfigurationPanels.h"
#include "Resources/EmbeddedImage.h"
#include "Resources/ButtonIcon_Camera.h"
#include <wx/artprov.h>
#include <wx/listbook.h>
#include <wx/listctrl.h>
#include <wx/filepicker.h>
//#include "wx/clipbrd.h"
#ifdef __WXMSW__
# include <wx/msw/wrapwin.h> // needed for Vista icon spacing fix.
# include <commctrl.h>
#endif
using namespace Panels;
// configure the orientation of the listbox based on the platform
#if defined(__WXMAC__) || defined(__WXMSW__)
static const int s_orient = wxBK_TOP;
#else
static const int s_orient = wxBK_LEFT;
#endif
template< typename T >
void Dialogs::ConfigurationDialog::AddPage( const char* label, int iconid )
{
const wxString labelstr( fromUTF8( label ) );
const int curidx = m_labels.Add( labelstr );
g_ApplyState.SetCurrentPage( curidx );
m_listbook.AddPage( new T( &m_listbook ), wxGetTranslation( labelstr ),
( labelstr == g_Conf->SettingsTabName ), iconid );
}
Dialogs::ConfigurationDialog::ConfigurationDialog( wxWindow* parent )
: wxDialogWithHelpers( parent, _("PCSX2 Configuration"), true )
, m_listbook( *new wxListbook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, s_orient ) )
{
SetName( GetNameStatic() );
m_idealWidth = 600;
m_listbook.SetImageList( &wxGetApp().GetImgList_Config() );
const AppImageIds::ConfigIds& cfgid( wxGetApp().GetImgId().Config );
g_ApplyState.StartBook( &m_listbook );
AddPage<CpuPanelEE> ( wxLt("EE/IOP"), cfgid.Cpu );
AddPage<CpuPanelVU> ( wxLt("VUs"), cfgid.Cpu );
AddPage<VideoPanel> ( wxLt("GS/Video"), cfgid.Video );
AddPage<SpeedHacksPanel> ( wxLt("Speedhacks"), cfgid.Speedhacks );
AddPage<GameFixesPanel> ( wxLt("Game Fixes"), cfgid.Gamefixes );
AddPage<PluginSelectorPanel>( wxLt("Plugins"), cfgid.Plugins );
AddPage<StandardPathsPanel> ( wxLt("Folders"), cfgid.Paths );
wxBitmapButton& screenshotButton( *new wxBitmapButton( this, wxID_SAVE, EmbeddedImage<res_ButtonIcon_Camera>().Get() ) );
screenshotButton.SetToolTip( _("Saves a snapshot of this settings panel to a PNG file.") );
SetSizer( new wxBoxSizer( wxVERTICAL ) );
*this += m_listbook;
AddOkCancel( *GetSizer(), true );
*m_extraButtonSizer += screenshotButton;
FindWindow( wxID_APPLY )->Disable();
#ifdef __WXMSW__
// Depending on Windows version and user appearance settings, the default icon spacing can be
// way over generous. This little bit of Win32-specific code ensures proper icon spacing, scaled
// to the size of the frame's ideal width.
ListView_SetIconSpacing( (HWND)m_listbook.GetListView()->GetHWND(),
(m_idealWidth-6) / m_listbook.GetPageCount(), g_Conf->Listbook_ImageSize+32 // y component appears to be ignored
);
#endif
Connect( wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ConfigurationDialog::OnOk_Click ) );
Connect( wxID_CANCEL, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ConfigurationDialog::OnCancel_Click ) );
Connect( wxID_APPLY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ConfigurationDialog::OnApply_Click ) );
Connect( wxID_SAVE, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ConfigurationDialog::OnScreenshot_Click ) );
Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler(ConfigurationDialog::OnCloseWindow) );
// ----------------------------------------------------------------------------
// Bind a variety of standard "something probably changed" events. If the user invokes
// any of these, we'll automatically de-gray the Apply button for this dialog box. :)
#define ConnectSomethingChanged( command ) \
Connect( wxEVT_COMMAND_##command, wxCommandEventHandler( ConfigurationDialog::OnSomethingChanged ) );
ConnectSomethingChanged( RADIOBUTTON_SELECTED );
ConnectSomethingChanged( COMBOBOX_SELECTED );
ConnectSomethingChanged( CHECKBOX_CLICKED );
ConnectSomethingChanged( BUTTON_CLICKED );
ConnectSomethingChanged( CHOICE_SELECTED );
ConnectSomethingChanged( LISTBOX_SELECTED );
ConnectSomethingChanged( SPINCTRL_UPDATED );
ConnectSomethingChanged( SLIDER_UPDATED );
ConnectSomethingChanged( DIRPICKER_CHANGED );
}
Dialogs::ConfigurationDialog::~ConfigurationDialog() throw()
{
g_ApplyState.DoCleanup();
}
void Dialogs::ConfigurationDialog::OnCloseWindow( wxCloseEvent& evt )
{
if( !IsModal() ) Destroy();
evt.Skip();
}
void Dialogs::ConfigurationDialog::OnOk_Click( wxCommandEvent& evt )
{
if( g_ApplyState.ApplyAll() )
{
FindWindow( wxID_APPLY )->Disable();
g_Conf->SettingsTabName = m_labels[m_listbook.GetSelection()];
AppSaveSettings();
evt.Skip();
}
}
void Dialogs::ConfigurationDialog::OnCancel_Click( wxCommandEvent& evt )
{
evt.Skip();
g_Conf->SettingsTabName = m_labels[m_listbook.GetSelection()];
}
void Dialogs::ConfigurationDialog::OnApply_Click( wxCommandEvent& evt )
{
if( g_ApplyState.ApplyAll() )
FindWindow( wxID_APPLY )->Disable();
g_Conf->SettingsTabName = m_labels[m_listbook.GetSelection()];
AppSaveSettings();
}
void Dialogs::ConfigurationDialog::OnScreenshot_Click( wxCommandEvent& evt )
{
wxBitmap memBmp;
{
wxWindowDC dc( this );
wxSize dcsize( dc.GetSize() );
wxMemoryDC memDC( memBmp = wxBitmap( dcsize.x, dcsize.y ) );
memDC.Blit( wxPoint(), dcsize, &dc, wxPoint() );
}
wxString filenameDefault;
filenameDefault.Printf( L"pcsx2_settings_%s.png", m_listbook.GetPageText( m_listbook.GetSelection() ).c_str() );
filenameDefault.Replace( L"/", L"-" );
wxString filename( wxFileSelector( _("Save dialog screenshots to..."), g_Conf->Folders.Snapshots.ToString(),
filenameDefault, L"png", NULL, wxFD_SAVE | wxFD_OVERWRITE_PROMPT, this ) );
if( !filename.IsEmpty() )
{
ScopedBusyCursor busy( Cursor_ReallyBusy );
memBmp.SaveFile( filename, wxBITMAP_TYPE_PNG );
}
}
// ----------------------------------------------------------------------------
Dialogs::BiosSelectorDialog::BiosSelectorDialog( wxWindow* parent )
: wxDialogWithHelpers( parent, _("BIOS Selector"), false )
{
SetName( GetNameStatic() );
m_idealWidth = 500;
wxBoxSizer& bleh( *new wxBoxSizer( wxVERTICAL ) );
Panels::BaseSelectorPanel* selpan = new Panels::BiosSelectorPanel( this );
bleh.Add( selpan, pxSizerFlags::StdExpand() );
AddOkCancel( bleh, false );
SetSizerAndFit( &bleh );
Connect( wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( BiosSelectorDialog::OnOk_Click ) );
Connect( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEventHandler(BiosSelectorDialog::OnDoubleClicked) );
selpan->OnShown();
}
void Dialogs::BiosSelectorDialog::OnOk_Click( wxCommandEvent& evt )
{
if( g_ApplyState.ApplyAll() )
{
Close();
evt.Skip();
}
}
void Dialogs::BiosSelectorDialog::OnDoubleClicked( wxCommandEvent& evt )
{
wxWindow* forwardButton = FindWindow( wxID_OK );
if( forwardButton == NULL ) return;
wxCommandEvent nextpg( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK );
nextpg.SetEventObject( forwardButton );
forwardButton->GetEventHandler()->ProcessEvent( nextpg );
}

View File

@ -20,22 +20,38 @@
#include <wx/propdlg.h>
#include "AppCommon.h"
class wxListbook;
#include "ApplyState.h"
namespace Dialogs
{
class ConfigurationDialog : public wxDialogWithHelpers
class BaseApplicableDialog : public wxDialogWithHelpers, public IApplyState
{
protected:
wxListbook& m_listbook;
wxArrayString m_labels;
DECLARE_DYNAMIC_CLASS_NO_COPY(BaseApplicableDialog)
public:
virtual ~ConfigurationDialog() throw();
ConfigurationDialog(wxWindow* parent=NULL);
BaseApplicableDialog() {}
static const wxChar* GetNameStatic() { return L"Dialog:CoreSettings"; }
protected:
BaseApplicableDialog(wxWindow* parent, const wxString& title );
BaseApplicableDialog(wxWindow* parent, const wxString& title, wxOrientation sizerOrient );
public:
virtual ~BaseApplicableDialog() throw();
//ApplyStateStruct& GetApplyState() { return m_ApplyState; }
};
// --------------------------------------------------------------------------------------
// BaseConfigurationDialog
// --------------------------------------------------------------------------------------
class BaseConfigurationDialog : public BaseApplicableDialog
{
protected:
wxListbook& m_listbook;
wxArrayString m_labels;
public:
virtual ~BaseConfigurationDialog() throw();
BaseConfigurationDialog(wxWindow* parent, const wxString& title, wxImageList& bookicons, int idealWidth);
protected:
template< typename T >
@ -45,20 +61,39 @@ namespace Dialogs
void OnCancel_Click( wxCommandEvent& evt );
void OnApply_Click( wxCommandEvent& evt );
void OnScreenshot_Click( wxCommandEvent& evt );
void OnCloseWindow( wxCloseEvent& evt );
virtual void OnSomethingChanged( wxCommandEvent& evt )
{
evt.Skip();
if( (evt.GetId() != wxID_OK) && (evt.GetId() != wxID_CANCEL) && (evt.GetId() != wxID_APPLY) )
{
FindWindow( wxID_APPLY )->Enable();
}
}
virtual void OnSomethingChanged( wxCommandEvent& evt );
virtual wxString& GetConfSettingsTabName() const=0;
};
class BiosSelectorDialog : public wxDialogWithHelpers
class SysConfigDialog : public BaseConfigurationDialog
{
protected:
public:
virtual ~SysConfigDialog() throw() {}
SysConfigDialog(wxWindow* parent=NULL);
static const wxChar* GetNameStatic() { return L"Dialog:CoreSettings"; }
protected:
virtual wxString& GetConfSettingsTabName() const { return g_Conf->SysSettingsTabName; }
};
class AppConfigDialog : public BaseConfigurationDialog
{
protected:
public:
virtual ~AppConfigDialog() throw() {}
AppConfigDialog(wxWindow* parent=NULL);
static const wxChar* GetNameStatic() { return L"Dialog:AppSettings"; }
protected:
virtual wxString& GetConfSettingsTabName() const { return g_Conf->AppSettingsTabName; }
};
class BiosSelectorDialog : public BaseApplicableDialog
{
protected:

View File

@ -24,11 +24,11 @@
using namespace Panels;
using namespace pxSizerFlags;
template< typename T >
static T& MakeWizWidget( int pageid, wxWizardPage* src )
IMPLEMENT_DYNAMIC_CLASS(ApplicableWizardPage, wxWizardPageSimple)
ApplicableWizardPage::ApplicableWizardPage( wxWizard* parent, wxWizardPage* prev, wxWizardPage* next, const wxBitmap& bitmap )
: wxWizardPageSimple( parent, prev, next, bitmap )
{
g_ApplyState.SetCurrentPage( pageid );
return *new T( src, 640 );
}
// ----------------------------------------------------------------------------
@ -53,7 +53,7 @@ Panels::SettingsDirPickerPanel::SettingsDirPickerPanel( wxWindow* parent ) :
// ----------------------------------------------------------------------------
FirstTimeWizard::UsermodePage::UsermodePage( wxWizard* parent ) :
wxWizardPageSimple( (g_ApplyState.SetCurrentPage( 0 ), parent) )
ApplicableWizardPage( parent )
{
SetSizer( new wxBoxSizer( wxVERTICAL ) );
@ -86,13 +86,13 @@ void FirstTimeWizard::UsermodePage::OnUsermodeChanged( wxCommandEvent& evt )
// ----------------------------------------------------------------------------
FirstTimeWizard::FirstTimeWizard( wxWindow* parent )
: wxWizard( (g_ApplyState.StartWizard(), parent), wxID_ANY, _("PCSX2 First Time Configuration") )
, m_page_usermode( *new UsermodePage( this ) )
, m_page_plugins( *new wxWizardPageSimple( this, &m_page_usermode ) )
, m_page_bios( *new wxWizardPageSimple( this, &m_page_plugins ) )
: wxWizard( parent, wxID_ANY, _("PCSX2 First Time Configuration") )
, m_page_usermode ( *new UsermodePage( this ) )
, m_page_plugins ( *new ApplicableWizardPage( this, &m_page_usermode ) )
, m_page_bios ( *new ApplicableWizardPage( this, &m_page_plugins ) )
, m_panel_PluginSel ( MakeWizWidget<PluginSelectorPanel>( 1, &m_page_plugins ) )
, m_panel_BiosSel ( MakeWizWidget<BiosSelectorPanel>( 2, &m_page_bios ) )
, m_panel_PluginSel ( *new PluginSelectorPanel( &m_page_plugins ) )
, m_panel_BiosSel ( *new BiosSelectorPanel( &m_page_bios ) )
{
// Page 2 - Plugins Panel
// Page 3 - Bios Panel
@ -104,14 +104,14 @@ FirstTimeWizard::FirstTimeWizard( wxWindow* parent )
m_page_bios += m_panel_BiosSel | StdExpand();
// Assign page indexes as client data
m_page_usermode.SetClientData ( (void*)0 );
m_page_plugins.SetClientData ( (void*)1 );
m_page_bios.SetClientData ( (void*)2 );
m_page_usermode .SetClientData( (void*)0 );
m_page_plugins .SetClientData( (void*)1 );
m_page_bios .SetClientData( (void*)2 );
// Build the forward chain:
// (backward chain is built during initialization above)
m_page_usermode.SetNext ( &m_page_plugins );
m_page_plugins.SetNext ( &m_page_bios );
m_page_usermode .SetNext( &m_page_plugins );
m_page_plugins .SetNext( &m_page_bios );
GetPageAreaSizer() += m_page_usermode;
GetPageAreaSizer() += m_page_plugins;
@ -122,14 +122,14 @@ FirstTimeWizard::FirstTimeWizard( wxWindow* parent )
Fit();
CenterOnScreen();
Connect( wxEVT_WIZARD_PAGE_CHANGED, wxWizardEventHandler( FirstTimeWizard::OnPageChanged ) );
Connect( wxEVT_WIZARD_PAGE_CHANGING, wxWizardEventHandler( FirstTimeWizard::OnPageChanging ) );
Connect( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEventHandler(FirstTimeWizard::OnDoubleClicked) );
Connect( wxEVT_WIZARD_PAGE_CHANGED, wxWizardEventHandler (FirstTimeWizard::OnPageChanged) );
Connect( wxEVT_WIZARD_PAGE_CHANGING, wxWizardEventHandler (FirstTimeWizard::OnPageChanging) );
Connect( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEventHandler (FirstTimeWizard::OnDoubleClicked) );
}
FirstTimeWizard::~FirstTimeWizard() throw()
{
g_ApplyState.DoCleanup();
}
void FirstTimeWizard::OnDoubleClicked( wxCommandEvent& evt )
@ -155,10 +155,13 @@ void FirstTimeWizard::OnPageChanging( wxWizardEvent& evt )
if( page >= 0 )
{
if( !g_ApplyState.ApplyPage( page ) )
if( ApplicableWizardPage* page = wxDynamicCast( GetCurrentPage(), ApplicableWizardPage ) )
{
evt.Veto();
return;
if( !page->GetApplyState().ApplyAll() )
{
evt.Veto();
return;
}
}
}

View File

@ -22,27 +22,24 @@
using namespace Panels;
Dialogs::LogOptionsDialog::LogOptionsDialog( wxWindow* parent )
: wxDialogWithHelpers( parent, _("Trace Logging"), true )
: BaseApplicableDialog( parent, _("Trace Logging"), wxVERTICAL )
{
SetName( GetNameStatic() );
m_idealWidth = 480;
wxBoxSizer& mainsizer = *new wxBoxSizer( wxVERTICAL );
mainsizer.Add( new LogOptionsPanel( this ) );
*this += new LogOptionsPanel( this );
AddOkCancel( mainsizer, true );
AddOkCancel( *GetSizer(), true );
FindWindow( wxID_APPLY )->Disable();
SetSizerAndFit( &mainsizer, true );
Connect( wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( LogOptionsDialog::OnOk_Click ) );
Connect( wxID_APPLY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( LogOptionsDialog::OnApply_Click ) );
}
void Dialogs::LogOptionsDialog::OnOk_Click( wxCommandEvent& evt )
{
if( g_ApplyState.ApplyAll() )
if( m_ApplyState.ApplyAll() )
{
FindWindow( wxID_APPLY )->Disable();
AppSaveSettings();
@ -54,7 +51,7 @@ void Dialogs::LogOptionsDialog::OnOk_Click( wxCommandEvent& evt )
void Dialogs::LogOptionsDialog::OnApply_Click( wxCommandEvent& evt )
{
if( g_ApplyState.ApplyAll() )
if( m_ApplyState.ApplyAll() )
FindWindow( wxID_APPLY )->Disable();
AppSaveSettings();

View File

@ -16,6 +16,7 @@
#pragma once
#include "App.h"
#include "ConfigurationDialog.h"
#include "Utilities/wxGuiTools.h"
#include "Utilities/CheckedStaticBox.h"
@ -25,7 +26,7 @@ using namespace HashTools;
namespace Dialogs {
class LogOptionsDialog: public wxDialogWithHelpers
class LogOptionsDialog : public BaseApplicableDialog
{
public:
LogOptionsDialog( wxWindow* parent=NULL );
@ -38,4 +39,4 @@ protected:
void OnApply_Click( wxCommandEvent& evt );
};
} // end namespace Dialogs
} // end namespace Dialogs

View File

@ -16,6 +16,7 @@
#pragma once
#include "App.h"
#include "ConfigurationDialog.h"
#include "Panels/ConfigurationPanels.h"
#include <wx/image.h>
@ -26,7 +27,7 @@ static const wxWindowID pxID_CUSTOM = wxID_LOWEST - 1;
class FirstTimeWizard : public wxWizard
{
protected:
class UsermodePage : public wxWizardPageSimple
class UsermodePage : public ApplicableWizardPage
{
protected:
Panels::DirPickerPanel* m_dirpick_settings;
@ -170,7 +171,7 @@ namespace Dialogs
};
class PickUserModeDialog : public wxDialogWithHelpers
class PickUserModeDialog : public BaseApplicableDialog
{
protected:
Panels::UsermodeSelectionPanel* m_panel_usersel;

View File

@ -21,7 +21,7 @@
using namespace Panels;
Dialogs::PickUserModeDialog::PickUserModeDialog( wxWindow* parent )
: wxDialogWithHelpers( parent, _("PCSX2 First Time configuration"), wxVERTICAL )
: BaseApplicableDialog( parent, _("PCSX2 First Time configuration"), wxVERTICAL )
{
m_panel_usersel = new UsermodeSelectionPanel( this, false );
m_panel_langsel = new LanguageSelectionPanel( this );
@ -38,7 +38,7 @@ Dialogs::PickUserModeDialog::PickUserModeDialog( wxWindow* parent )
void Dialogs::PickUserModeDialog::OnOk_Click( wxCommandEvent& evt )
{
if( g_ApplyState.ApplyAll() )
if( m_ApplyState.ApplyAll() )
{
Close();
evt.Skip();

View File

@ -0,0 +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 "System.h"
#include "App.h"
#include "MSWstuff.h"
#include "ConfigurationDialog.h"
#include "BaseConfigurationDialog.inl"
#include "ModalPopups.h"
#include "Panels/ConfigurationPanels.h"
#include <wx/filepicker.h>
using namespace Panels;
Dialogs::SysConfigDialog::SysConfigDialog(wxWindow* parent)
: BaseConfigurationDialog( parent, _("PS2 Settings - PCSX2"), wxGetApp().GetImgList_Config(), 600 )
{
SetName( GetNameStatic() );
const AppImageIds::ConfigIds& cfgid( wxGetApp().GetImgId().Config );
AddPage<CpuPanelEE> ( wxLt("EE/IOP"), cfgid.Cpu );
AddPage<CpuPanelVU> ( wxLt("VUs"), cfgid.Cpu );
AddPage<VideoPanel> ( wxLt("GS"), cfgid.Video );
AddPage<SpeedHacksPanel> ( wxLt("Speedhacks"), cfgid.Speedhacks );
AddPage<GameFixesPanel> ( wxLt("Game Fixes"), cfgid.Gamefixes );
AddPage<PluginSelectorPanel>( wxLt("Plugins"), cfgid.Plugins );
MSW_ListView_SetIconSpacing( m_listbook, m_idealWidth );
// For some reason adding pages un-does the Apply button, so we need to re-disable it here.
FindWindow( wxID_APPLY )->Disable();
}
Dialogs::AppConfigDialog::AppConfigDialog(wxWindow* parent)
: BaseConfigurationDialog( parent, _("Application Settings - PCSX2"), wxGetApp().GetImgList_Config(), 600 )
{
SetName( GetNameStatic() );
const AppImageIds::ConfigIds& cfgid( wxGetApp().GetImgId().Config );
AddPage<GSWindowSettingsPanel> ( wxLt("GS Window"), cfgid.Paths );
AddPage<StandardPathsPanel> ( wxLt("Folders"), cfgid.Paths );
MSW_ListView_SetIconSpacing( m_listbook, GetClientSize().GetWidth() );
// For some reason adding pages un-does the Apply button, so we need to re-disable it here.
FindWindow( wxID_APPLY )->Disable();
}

View File

@ -213,10 +213,16 @@ void __evt_fastcall GSPanel::OnSettingsApplied( void* obj, int& evt )
{
if( obj == NULL ) return;
GSPanel* panel = (GSPanel*)obj;
if( panel->IsBeingDeleted() ) return;
panel->DoResize();
panel->DoShowMouse();
panel->DoSettingsApplied();
}
void GSPanel::DoSettingsApplied()
{
if( IsBeingDeleted() ) return;
DoResize();
DoShowMouse();
Show( !EmuConfig.GS.DisableOutput );
}
// --------------------------------------------------------------------------------------
@ -229,12 +235,19 @@ GSFrame::GSFrame(wxWindow* parent, const wxString& title)
(g_Conf->GSWindow.DisableResizeBorders ? 0 : wxRESIZE_BORDER) | wxCAPTION | wxCLIP_CHILDREN |
wxSYSTEM_MENU | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxCLOSE_BOX
)
, m_Listener_SettingsApplied( wxGetApp().Source_SettingsApplied(), EventListener<int> ( this, OnSettingsApplied ) )
{
SetIcons( wxGetApp().GetIconBundle() );
SetClientSize( g_Conf->GSWindow.WindowSize );
SetBackgroundColour( *wxBLACK );
m_gspanel = new GSPanel( this );
wxStaticText* label = new wxStaticText( this, wxID_ANY, _("GS Output is Disabled!") );
label->SetName(L"OutputDisabledLabel");
label->SetFont( *new wxFont( 20, wxDEFAULT, wxNORMAL, wxBOLD ) );
label->SetForegroundColour( *wxWHITE );
m_gspanel = new GSPanel( this );
//Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler (GSFrame::OnCloseWindow) );
Connect( wxEVT_MOVE, wxMoveEventHandler (GSFrame::OnMove) );
@ -251,8 +264,17 @@ void __evt_fastcall GSFrame::OnSettingsApplied( void* obj, int& evt )
if( obj == NULL ) return;
GSFrame* frame = (GSFrame*)obj;
if( frame->IsBeingDeleted() ) return;
frame->DoSettingsApplied();
}
void GSFrame::DoSettingsApplied()
{
if( IsBeingDeleted() ) return;
ShowFullScreen( g_Conf->GSWindow.DefaultToFullscreen );
Show( !g_Conf->GSWindow.CloseOnEsc || ((g_plugins==NULL) || !SysHasValidState()) );
if( wxStaticText* label = (wxStaticText*)FindWindowByName(L"OutputDisabledLabel") )
label->Show( !EmuConfig.GS.DisableOutput );
}
wxWindow* GSFrame::GetViewport()
@ -289,8 +311,15 @@ void GSFrame::OnMove( wxMoveEvent& evt )
void GSFrame::OnResize( wxSizeEvent& evt )
{
if( IsBeingDeleted() ) return;
if( !IsMaximized() && IsVisible() )
{
g_Conf->GSWindow.WindowSize = GetClientSize();
}
if( wxStaticText* label = (wxStaticText*)FindWindowByName(L"OutputDisabledLabel") )
label->CentreOnParent();
if( GSPanel* gsPanel = (GSPanel*)FindWindowByName(L"GSPanel") )
{

View File

@ -70,7 +70,7 @@ namespace Implementations
SetGSConfig().FrameSkipEnable = g_Conf->EmuOptions.GS.FrameSkipEnable;
if( EmuConfig.GS.FrameSkipEnable )
Console.WriteLn( "(FrameSkipping) Enabled : FrameDraws=%d, FrameSkips=%d", g_Conf->EmuOptions.GS.ConsecutiveFrames, g_Conf->EmuOptions.GS.ConsecutiveSkip );
Console.WriteLn( "(FrameSkipping) Enabled : FrameDraws=%d, FrameSkips=%d", g_Conf->EmuOptions.GS.FramesToDraw, g_Conf->EmuOptions.GS.FramesToSkip );
else
Console.WriteLn( "(FrameSkipping) Disabled." );
}
@ -88,14 +88,14 @@ namespace Implementations
{
GSsetVsync( g_Conf->EmuOptions.GS.VsyncEnable );
g_LimiterMode = Limit_Nominal;
g_Conf->EmuOptions.GS.LimitScalar = g_Conf->GSWindow.NominalScalar;
g_Conf->EmuOptions.GS.LimitScalar = g_Conf->Framerate.NominalScalar;
Console.WriteLn("(FrameLimiter) Turbo DISABLED." );
}
else
{
GSsetVsync( false );
g_LimiterMode = Limit_Turbo;
g_Conf->EmuOptions.GS.LimitScalar = g_Conf->GSWindow.TurboScalar;
g_Conf->EmuOptions.GS.LimitScalar = g_Conf->Framerate.TurboScalar;
Console.WriteLn("(FrameLimiter) Turbo ENABLED." );
}
pauser.Resume();
@ -114,13 +114,13 @@ namespace Implementations
if( g_LimiterMode == Limit_Slomo )
{
g_LimiterMode = Limit_Nominal;
g_Conf->EmuOptions.GS.LimitScalar = g_Conf->GSWindow.NominalScalar;
g_Conf->EmuOptions.GS.LimitScalar = g_Conf->Framerate.NominalScalar;
Console.WriteLn("(FrameLimiter) SlowMotion DISABLED." );
}
else
{
g_LimiterMode = Limit_Slomo;
g_Conf->EmuOptions.GS.LimitScalar = g_Conf->GSWindow.SlomoScalar;
g_Conf->EmuOptions.GS.LimitScalar = g_Conf->Framerate.SlomoScalar;
Console.WriteLn("(FrameLimiter) SlowMotion ENABLED." );
g_Conf->EmuOptions.GS.FrameLimitEnable = true;
}

View File

@ -16,9 +16,12 @@
#include "PrecompiledHeader.h"
#include "MainFrame.h"
#include "MSWstuff.h"
#include <wx/listbook.h>
#include <wx/listctrl.h>
#ifdef __WXMSW__
# include <wx/msw/wrapwin.h> // needed for OutputDebugString
# include <commctrl.h>
#endif
void MSW_SetWindowAfter( WXWidget hwnd, WXWidget hwndAfter )
@ -43,6 +46,19 @@ void MSW_OutputDebugString( const wxString& text )
#endif
}
void MSW_ListView_SetIconSpacing( wxListbook& listbook, int width )
{
#ifdef __WXMSW__
// Depending on Windows version and user appearance settings, the default icon spacing can be
// way over generous. This little bit of Win32-specific code ensures proper icon spacing, scaled
// to the size of the frame's ideal width.
ListView_SetIconSpacing( (HWND)listbook.GetListView()->GetHWND(),
(width / listbook.GetPageCount()) - 6, g_Conf->Listbook_ImageSize+32 // y component appears to be ignored
);
#endif
}
#ifdef __WXMSW__
WXLRESULT GSPanel::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
{

View File

@ -15,8 +15,11 @@
#pragma once
class wxListbook;
extern void MSW_SetWindowAfter( WXWidget hwnd, WXWidget hwndAfter );
extern void MSW_OutputDebugString( const wxString& text );
extern void MSW_ListView_SetIconSpacing( wxListbook& listbook, int width );
extern void pxDwm_Load();
extern void pxDwm_Unload();

View File

@ -132,7 +132,8 @@ void MainEmuFrame::ConnectMenus()
#define ConnectMenuRange( id_start, inc, handler ) \
Connect( id_start, id_start + inc, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainEmuFrame::handler) )
ConnectMenu( MenuId_Config_Settings, Menu_ConfigSettings_Click );
ConnectMenu( MenuId_Config_SysSettings, Menu_ConfigSettings_Click );
ConnectMenu( MenuId_Config_AppSettings, Menu_AppSettings_Click );
ConnectMenu( MenuId_Config_BIOS, Menu_SelectBios_Click );
ConnectMenu( MenuId_Config_Multitap0Toggle, Menu_MultitapToggle_Click );
@ -153,6 +154,7 @@ void MainEmuFrame::ConnectMenus()
ConnectMenu( MenuId_Sys_SuspendResume, Menu_SuspendResume_Click );
ConnectMenu( MenuId_Sys_Reset, Menu_SysReset_Click );
ConnectMenu( MenuId_Sys_Shutdown, Menu_SysShutdown_Click );
ConnectMenu( MenuId_State_LoadOther, Menu_LoadStateOther_Click );
@ -167,7 +169,7 @@ void MainEmuFrame::ConnectMenus()
ConnectMenu( MenuId_Debug_Logging, Menu_Debug_Logging_Click );
ConnectMenu( MenuId_Console, Menu_ShowConsole );
ConnectMenu( MenuId_Console_Stdio, Menu_ShowConsole_Stdio );
ConnectMenu( MenuId_Console_Stdio, Menu_ShowConsole_Stdio );
ConnectMenu( MenuId_CDVD_Info, Menu_PrintCDVD_Info );
ConnectMenu( MenuId_About, Menu_ShowAboutBox );
@ -333,7 +335,6 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title)
// has been set/fit.
InitLogBoxPosition( g_Conf->ProgLogBox );
InitLogBoxPosition( g_Conf->Ps2ConBox );
// ------------------------------------------------------------------------
@ -381,11 +382,15 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title)
m_menuSys.AppendSeparator();
m_menuSys.Append(MenuId_Sys_Reset, _("Reset"),
_("Resets emulation state and re-runs current image"));
_("Resets the VM state and re-runs current CDVD image."));
m_menuSys.Append(MenuId_Sys_Shutdown, _("Shutdown"),
_("Wipes all internal VM states and shuts down plugins."));
// ------------------------------------------------------------------------
m_menuConfig.Append(MenuId_Config_Settings, _("General &Settings") );
m_menuConfig.Append(MenuId_Config_SysSettings, _("System &Settings") );
m_menuConfig.Append(MenuId_Config_AppSettings, _("App Settings") );
m_menuConfig.AppendSeparator();
@ -505,7 +510,8 @@ void MainEmuFrame::ApplyCoreStatus()
susres.SetHelp( _("No emulation state is active; cannot suspend or resume.") );
}
menubar.Enable( MenuId_Sys_Reset, SysHasValidState() || (g_plugins!=NULL) );
menubar.Enable( MenuId_Sys_Reset, true );
menubar.Enable( MenuId_Sys_Shutdown, SysHasValidState() || (g_plugins!=NULL) );
}
void MainEmuFrame::ApplyPluginStatus()

View File

@ -44,13 +44,15 @@ public:
protected:
static void __evt_fastcall OnSettingsApplied( void* obj, int& evt );
#ifdef __WXMSW__
virtual WXLRESULT MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam);
#endif
void InitDefaultAccelerators();
void DoSettingsApplied();
void OnCloseWindow( wxCloseEvent& evt );
void OnResize(wxSizeEvent& event);
void OnShowMouse( wxMouseEvent& evt );
@ -66,7 +68,9 @@ protected:
class GSFrame : public wxFrame
{
protected:
EventListenerBinding<int> m_Listener_SettingsApplied;
GSPanel* m_gspanel;
wxStaticText* m_label_Disabled;
public:
GSFrame(wxWindow* parent, const wxString& title);
@ -79,7 +83,9 @@ protected:
void OnResize( wxSizeEvent& evt );
void OnActivate( wxActivateEvent& evt );
void __evt_fastcall OnSettingsApplied( void* obj, int& evt );
void DoSettingsApplied();
static void __evt_fastcall OnSettingsApplied( void* obj, int& evt );
};
struct PluginMenuAddition
@ -195,6 +201,7 @@ protected:
void OnActivate( wxActivateEvent& evt );
void Menu_ConfigSettings_Click(wxCommandEvent &event);
void Menu_AppSettings_Click(wxCommandEvent &event);
void Menu_SelectBios_Click(wxCommandEvent &event);
void Menu_IsoBrowse_Click(wxCommandEvent &event);
@ -212,6 +219,7 @@ protected:
void Menu_SuspendResume_Click(wxCommandEvent &event);
void Menu_SysReset_Click(wxCommandEvent &event);
void Menu_SysShutdown_Click(wxCommandEvent &event);
void Menu_ConfigPlugin_Click(wxCommandEvent &event);

View File

@ -28,15 +28,6 @@
using namespace Dialogs;
template<typename DialogType>
void AppOpenDialog( wxWindow* parent )
{
if( wxWindow* window = wxFindWindowByName( DialogType::GetNameStatic() ) )
window->SetFocus();
else
(new DialogType( parent ))->Show();
}
extern wxString GetMsg_ConfirmSysReset();
void MainEmuFrame::SaveEmuOptions()
@ -50,7 +41,12 @@ void MainEmuFrame::SaveEmuOptions()
void MainEmuFrame::Menu_ConfigSettings_Click(wxCommandEvent &event)
{
AppOpenDialog<ConfigurationDialog>( this );
AppOpenDialog<SysConfigDialog>( this );
}
void MainEmuFrame::Menu_AppSettings_Click(wxCommandEvent &event)
{
AppOpenDialog<AppConfigDialog>( this );
}
void MainEmuFrame::Menu_SelectBios_Click(wxCommandEvent &event)
@ -73,7 +69,7 @@ void MainEmuFrame::Menu_CdvdSource_Click( wxCommandEvent &event )
CoreThread.ChangeCdvdSource( newSource );
}
// Returns FALSE if the user cancelled the action.
// Returns FALSE if the user canceled the action.
bool MainEmuFrame::_DoSelectIsoBrowser( wxString& result )
{
static const wxChar* isoFilterTypes =
@ -258,17 +254,17 @@ void MainEmuFrame::Menu_SuspendResume_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_SysReset_Click(wxCommandEvent &event)
{
if( !SysHasValidState() ) return;
bool resume = CoreThread.Suspend();
//if( !SysHasValidState() ) return;
sApp.SysReset();
sApp.SysExecute();
//GetMenuBar()->Enable( MenuId_Sys_Reset, true );
}
if( resume )
{
sApp.SysExecute();
}
GetMenuBar()->Enable( MenuId_Sys_Reset, resume );
void MainEmuFrame::Menu_SysShutdown_Click(wxCommandEvent &event)
{
if( !SysHasValidState() ) return;
sApp.SysReset();
GetMenuBar()->Enable( MenuId_Sys_Shutdown, false );
}
void MainEmuFrame::Menu_ConfigPlugin_Click(wxCommandEvent &event)

View File

@ -1,160 +0,0 @@
/* 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 <list>
class wxListBox;
class wxBookCtrlBase;
// Annoyances of C++ forward declarations. Having to type in this red tape mess
// is keeping me from eating a good sandwich right now... >_<
namespace Panels
{
class BaseApplicableConfigPanel;
}
namespace Exception
{
// --------------------------------------------------------------------------
// Exception used to perform an abort of Apply/Ok action on settings panels.
// 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.
//
class CannotApplySettings : public BaseException
{
public:
bool IsVerbose;
protected:
Panels::BaseApplicableConfigPanel* m_Panel;
public:
DEFINE_EXCEPTION_COPYTORS( CannotApplySettings )
explicit CannotApplySettings( Panels::BaseApplicableConfigPanel* thispanel, const char* msg=wxLt("Cannot apply new settings, one of the settings is invalid."), bool isVerbose = true )
{
BaseException::InitBaseEx( msg );
m_Panel = thispanel;
IsVerbose = isVerbose;
}
explicit CannotApplySettings( Panels::BaseApplicableConfigPanel* thispanel, const wxString& msg_eng, const wxString& msg_xlt )
{
BaseException::InitBaseEx( msg_eng, msg_xlt );
m_Panel = thispanel;
IsVerbose = true;
}
Panels::BaseApplicableConfigPanel* GetPanel()
{
return m_Panel;
}
};
}
namespace Panels
{
typedef std::list<BaseApplicableConfigPanel*> PanelApplyList_t;
struct StaticApplyState
{
// Static collection of ApplicableConfigPanels currently available to the user.
PanelApplyList_t PanelList;
// Current book page being initialized. Any apply objects created will use
// 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;
StaticApplyState()
{
CurOwnerPage = wxID_NONE;
ParentBook = NULL;
}
void SetCurrentPage( int page )
{
CurOwnerPage = page;
}
void ClearCurrentPage()
{
CurOwnerPage = wxID_NONE;
}
void StartBook( wxBookCtrlBase* book );
void StartWizard();
bool ApplyAll();
bool ApplyPage( int pageid );
void DoCleanup() throw();
};
extern StaticApplyState g_ApplyState;
// --------------------------------------------------------------------------------------
// BaseApplicableConfigPanel
// --------------------------------------------------------------------------------------
// Extends the Panel class to add an Apply() method, which is invoked from the parent
// window (usually the ConfigurationDialog) when either Ok or Apply is clicked.
//
// 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
// user at any time (ie, a singular modal dialog).
//
class BaseApplicableConfigPanel : public wxPanelWithHelpers
{
protected:
int m_OwnerPage;
wxBookCtrlBase* m_OwnerBook;
EventListenerBinding<int> m_Listener_SettingsApplied;
public:
virtual ~BaseApplicableConfigPanel() throw();
BaseApplicableConfigPanel( wxWindow* parent, wxOrientation orient=wxVERTICAL );
BaseApplicableConfigPanel( wxWindow* parent, wxOrientation orient, const wxString& staticLabel );
int GetOwnerPage() const { return m_OwnerPage; }
wxBookCtrlBase* GetOwnerBook() { return m_OwnerBook; }
void SetFocusToMe();
// 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.
// If no exceptions are thrown, then the operation is assumed a success. :)
virtual void Apply()=0;
// This method is bound to the ApplySettings event from the PCSX2 app manager.
// Note: This method *will* be called automatically after a successful Apply, but will not
// be called after a failed Apply (canceled due to error).
virtual void OnSettingsChanged()=0;
protected:
static void __evt_fastcall OnSettingsApplied( void* obj, int& evt );
void Init();
};
}

View File

@ -26,9 +26,8 @@
#include <wx/spinctrl.h>
#include "AppCommon.h"
#include "ApplyState.h"
class wxDirPickerCtrl;
class wxFileDirPickerEvent;
// --------------------------------------------------------------------------------------
// pxUniformTable
@ -159,7 +158,27 @@ namespace Panels
void OnSettingsChanged();
};
// --------------------------------------------------------------------------------------
// FrameSkipPanel
// --------------------------------------------------------------------------------------
class FrameSkipPanel : public BaseApplicableConfigPanel
{
protected:
wxSpinCtrl* m_spin_FramesToSkip;
wxSpinCtrl* m_spin_FramesToDraw;
//pxCheckBox* m_check_EnableSkip;
//pxCheckBox* m_check_EnableSkipOnTurbo;
pxRadioPanel* m_radio_SkipMode;
public:
FrameSkipPanel( wxWindow* parent );
virtual ~FrameSkipPanel() throw() {}
void Apply();
void OnSettingsChanged();
};
// --------------------------------------------------------------------------------------
// FramelimiterPanel
// --------------------------------------------------------------------------------------
@ -178,12 +197,10 @@ namespace Panels
wxCheckBox* m_TurboSkipEnable;
wxSpinCtrl* m_spin_SkipThreshold;
wxSpinCtrl* m_spin_FramesToSkip;
wxSpinCtrl* m_spin_FramesToDraw;
public:
FramelimiterPanel( wxWindow* parent );
virtual ~FramelimiterPanel() throw() {}
void Apply();
void OnSettingsChanged();
};
@ -200,8 +217,9 @@ namespace Panels
pxCheckBox* m_check_SizeLock;
pxCheckBox* m_check_VsyncEnable;
pxCheckBox* m_check_Fullscreen;
pxCheckBox* m_check_ExclusiveFS;
pxCheckBox* m_check_HideMouse;
wxTextCtrl* m_text_WindowWidth;
wxTextCtrl* m_text_WindowHeight;
@ -216,12 +234,18 @@ namespace Panels
{
protected:
pxCheckBox* m_check_SynchronousGS;
pxCheckBox* m_check_DisableOutput;
wxButton* m_button_OpenWindowSettings;
public:
VideoPanel( wxWindow* parent );
virtual ~VideoPanel() throw() {}
void Apply();
void OnSettingsChanged();
protected:
void OnOpenWindowSettings( wxCommandEvent& evt );
};
//////////////////////////////////////////////////////////////////////////////////////////
@ -325,8 +349,6 @@ namespace Panels
BasePathsPanel( wxWindow* parent );
protected:
DirPickerPanel& AddDirPicker( wxSizer& sizer, FoldersEnum_t folderid,
const wxString& label, const wxString& popupLabel );
};
//////////////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,153 @@
/* 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 "ConfigurationPanels.h"
using namespace pxSizerFlags;
// --------------------------------------------------------------------------------------
// GSWindowSetting Implementation
// --------------------------------------------------------------------------------------
Panels::GSWindowSettingsPanel::GSWindowSettingsPanel( wxWindow* parent )
: BaseApplicableConfigPanel( parent )
{
const wxString aspect_ratio_labels[] =
{
_("Fit to Window/Screen"),
_("Standard (4:3)"),
_("Widescreen (16:9)")
};
m_combo_AspectRatio = new wxComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
ArraySize(aspect_ratio_labels), aspect_ratio_labels, wxCB_READONLY );
m_text_WindowWidth = CreateNumericalTextCtrl( this, 5 );
m_text_WindowHeight = CreateNumericalTextCtrl( this, 5 );
// Linux/Mac note: Exclusive Fullscreen mode is probably Microsoft specific, though
// I'm not yet 100% certain of that.
m_check_SizeLock = new pxCheckBox( this, _("Disable window resize border") );
m_check_HideMouse = new pxCheckBox( this, _("Always hide mouse cursor") );
m_check_CloseGS = new pxCheckBox( this, _("Hide window on suspend") );
m_check_Fullscreen = new pxCheckBox( this, _("Default to fullscreen mode on open") );
m_check_VsyncEnable = new pxCheckBox( this, _("Wait for vsync on refresh") );
m_check_ExclusiveFS = new pxCheckBox( this, _("Use exclusive fullscreen mode (if available)") );
m_check_VsyncEnable->SetToolTip( pxE( ".Tooltips:Video:Vsync",
L"Vsync eliminates screen tearing but typically has a big performance hit. "
L"It usually only applies to fullscreen mode, and may not work with all GS plugins."
) );
m_check_HideMouse->SetToolTip( pxE( ".Tooltips:Video:HideMouse",
L"Check this to force the mouse cursor invisible inside the GS window; useful if using "
L"the mouse as a primary control device for gaming. By default the mouse auto-hides after "
L"2 seconds of inactivity."
) );
m_check_Fullscreen->SetToolTip( pxE( ".Tooltips:Video:Fullscreen",
L"Enables automatic mode switch to fullscreen when starting or resuming emulation. "
L"You can still toggle fullscreen display at any time using alt-enter."
) );
m_check_ExclusiveFS->SetToolTip( pxE( ".Video:FullscreenExclusive",
L"Fullscreen Exclusive Mode may look better on older CRTs and might be a little faster on older video cards, "
L"but typically can lead to memory leaks or random crashes when entering/leaving fullscreen mode."
) );
m_check_CloseGS->SetToolTip( pxE( ".Tooltips:Video:HideGS",
L"Completely closes the often large and bulky GS window when pressing "
L"ESC or suspending the emulator."
) );
// ----------------------------------------------------------------------------
// Layout and Positioning
wxBoxSizer& s_customsize( *new wxBoxSizer( wxHORIZONTAL ) );
s_customsize += m_text_WindowWidth;
s_customsize += Text( L"x" );
s_customsize += m_text_WindowHeight;
wxFlexGridSizer& s_AspectRatio( *new wxFlexGridSizer( 2, StdPadding, StdPadding ) );
//s_AspectRatio.AddGrowableCol( 0 );
s_AspectRatio.AddGrowableCol( 1 );
s_AspectRatio += Text(_("Aspect Ratio:")) | pxMiddle;
s_AspectRatio += m_combo_AspectRatio | pxExpand;
s_AspectRatio += Text(_("Custom Window Size:")) | pxMiddle;
s_AspectRatio += s_customsize | pxAlignRight;
*this += s_AspectRatio | StdExpand();
*this += m_check_SizeLock;
*this += m_check_HideMouse;
*this += m_check_CloseGS;
*this += new wxStaticLine( this ) | StdExpand();
*this += m_check_Fullscreen;
*this += m_check_ExclusiveFS;
*this += m_check_VsyncEnable;
wxBoxSizer* centerSizer = new wxBoxSizer( wxVERTICAL );
*centerSizer += GetSizer() | pxCenter;
SetSizer( centerSizer, false );
OnSettingsChanged();
}
void Panels::GSWindowSettingsPanel::OnSettingsChanged()
{
const AppConfig::GSWindowOptions& conf( g_Conf->GSWindow );
m_check_CloseGS ->SetValue( conf.CloseOnEsc );
m_check_Fullscreen ->SetValue( conf.DefaultToFullscreen );
m_check_HideMouse ->SetValue( conf.AlwaysHideMouse );
m_check_SizeLock ->SetValue( conf.DisableResizeBorders );
m_combo_AspectRatio ->SetSelection( (int)conf.AspectRatio );
m_check_VsyncEnable ->SetValue( g_Conf->EmuOptions.GS.VsyncEnable );
m_text_WindowWidth ->SetValue( wxsFormat( L"%d", conf.WindowSize.GetWidth() ) );
m_text_WindowHeight ->SetValue( wxsFormat( L"%d", conf.WindowSize.GetHeight() ) );
}
void Panels::GSWindowSettingsPanel::Apply()
{
AppConfig::GSWindowOptions& appconf( g_Conf->GSWindow );
Pcsx2Config::GSOptions& gsconf( g_Conf->EmuOptions.GS );
appconf.CloseOnEsc = m_check_CloseGS ->GetValue();
appconf.DefaultToFullscreen = m_check_Fullscreen->GetValue();
appconf.AlwaysHideMouse = m_check_HideMouse ->GetValue();
appconf.DisableResizeBorders = m_check_SizeLock ->GetValue();
appconf.AspectRatio = (AspectRatioType)m_combo_AspectRatio->GetSelection();
gsconf.VsyncEnable = m_check_VsyncEnable->GetValue();
long xr, yr;
if( !m_text_WindowWidth->GetValue().ToLong( &xr ) || !m_text_WindowHeight->GetValue().ToLong( &yr ) )
throw Exception::CannotApplySettings( this,
L"User submitted non-numeric window size parameters!",
_("Invalid window dimensions specified: Size cannot contain non-numeric digits! >_<")
);
appconf.WindowSize.x = xr;
appconf.WindowSize.y = yr;
}

View File

@ -16,6 +16,7 @@
#pragma once
#include "AppCommon.h"
#include "ApplyState.h"
namespace Panels
{

View File

@ -14,37 +14,37 @@
*/
#include "PrecompiledHeader.h"
#include "App.h"
#include "ConfigurationPanels.h"
#include "App.h"
#include "Dialogs/ConfigurationDialog.h"
#include "ps2/BiosTools.h"
#include <wx/stdpaths.h>
#include <wx/bookctrl.h>
Panels::StaticApplyState Panels::g_ApplyState;
using namespace Dialogs;
// -----------------------------------------------------------------------
// This method should be called by the parent dalog box of a configuration
// on dialog destruction. It asserts if the ApplyList hasn't been cleaned up
// and then cleans it up forcefully.
//
void Panels::StaticApplyState::DoCleanup() throw()
void ApplyStateStruct::DoCleanup() throw()
{
pxAssertMsg( PanelList.size() != 0, L"PanelList list hasn't been cleaned up." );
PanelList.clear();
ParentBook = NULL;
}
void Panels::StaticApplyState::StartBook( wxBookCtrlBase* book )
void ApplyStateStruct::StartBook( wxBookCtrlBase* book )
{
pxAssertDev( ParentBook == NULL, "An ApplicableConfig session is already in progress." );
ParentBook = book;
}
void Panels::StaticApplyState::StartWizard()
void ApplyStateStruct::StartWizard()
{
pxAssertDev( ParentBook == NULL, "An ApplicableConfig session is already in progress." );
}
@ -58,7 +58,7 @@ void Panels::StaticApplyState::StartWizard()
// Returns false if one of the panels fails input validation (in which case dialogs
// should not be closed, etc).
//
bool Panels::StaticApplyState::ApplyPage( int pageid )
bool ApplyStateStruct::ApplyPage( int pageid )
{
bool retval = true;
@ -120,7 +120,7 @@ bool Panels::StaticApplyState::ApplyPage( int pageid )
// Returns false if one of the panels fails input validation (in which case dialogs
// should not be closed, etc).
bool Panels::StaticApplyState::ApplyAll()
bool ApplyStateStruct::ApplyAll()
{
return ApplyPage( -1 );
}
@ -128,39 +128,60 @@ bool Panels::StaticApplyState::ApplyAll()
// --------------------------------------------------------------------------------------
// BaseApplicableConfigPanel Implementations
// --------------------------------------------------------------------------------------
Panels::BaseApplicableConfigPanel::~BaseApplicableConfigPanel() throw()
IApplyState* BaseApplicableConfigPanel::FindApplyStateManager() const
{
g_ApplyState.PanelList.remove( this );
wxWindow* millrun = this->GetParent();
while( millrun != NULL )
{
if( BaseApplicableDialog* dialog = wxDynamicCast( millrun, BaseApplicableDialog ) )
return (IApplyState*)dialog;
if( ApplicableWizardPage* wizpage = wxDynamicCast( millrun, ApplicableWizardPage ) )
return (IApplyState*)wizpage;
millrun = millrun->GetParent();
}
return NULL;
}
Panels::BaseApplicableConfigPanel::BaseApplicableConfigPanel( wxWindow* parent, wxOrientation orient )
BaseApplicableConfigPanel::~BaseApplicableConfigPanel() throw()
{
if( IApplyState* iapp = FindApplyStateManager() )
iapp->GetApplyState().PanelList.remove( this );
}
BaseApplicableConfigPanel::BaseApplicableConfigPanel( wxWindow* parent, wxOrientation orient )
: wxPanelWithHelpers( parent, orient )
, m_Listener_SettingsApplied( wxGetApp().Source_SettingsApplied(), EventListener<int>( this, OnSettingsApplied ) )
{
Init();
}
Panels::BaseApplicableConfigPanel::BaseApplicableConfigPanel( wxWindow* parent, wxOrientation orient, const wxString& staticLabel )
BaseApplicableConfigPanel::BaseApplicableConfigPanel( wxWindow* parent, wxOrientation orient, const wxString& staticLabel )
: wxPanelWithHelpers( parent, orient, staticLabel )
, m_Listener_SettingsApplied( wxGetApp().Source_SettingsApplied(), EventListener<int>( this, OnSettingsApplied ) )
{
Init();
}
void Panels::BaseApplicableConfigPanel::SetFocusToMe()
void BaseApplicableConfigPanel::SetFocusToMe()
{
if( (m_OwnerBook == NULL) || (m_OwnerPage == wxID_NONE) ) return;
m_OwnerBook->SetSelection( m_OwnerPage );
}
void Panels::BaseApplicableConfigPanel::Init()
void BaseApplicableConfigPanel::Init()
{
m_OwnerPage = g_ApplyState.CurOwnerPage;
m_OwnerBook = g_ApplyState.ParentBook;
g_ApplyState.PanelList.push_back( this );
if( IApplyState* iapp = FindApplyStateManager() )
{
ApplyStateStruct& applyState( iapp->GetApplyState() );
m_OwnerPage = applyState.CurOwnerPage;
m_OwnerBook = applyState.ParentBook;
applyState.PanelList.push_back( this );
}
}
void __evt_fastcall Panels::BaseApplicableConfigPanel::OnSettingsApplied( void* obj, int& ini )
void __evt_fastcall BaseApplicableConfigPanel::OnSettingsApplied( void* obj, int& ini )
{
if( obj == NULL ) return;
((BaseApplicableConfigPanel*)obj)->OnSettingsChanged();

View File

@ -18,6 +18,8 @@
#include <wx/stdpaths.h>
using namespace pxSizerFlags;
static const int BetweenFolderSpace = 5;
// ------------------------------------------------------------------------
@ -26,56 +28,54 @@ Panels::BasePathsPanel::BasePathsPanel( wxWindow* parent )
{
}
Panels::DirPickerPanel& Panels::BasePathsPanel::AddDirPicker( wxSizer& sizer,
FoldersEnum_t folderid, const wxString& label, const wxString& popupLabel )
{
DirPickerPanel* dpan = new DirPickerPanel( this, folderid, label, popupLabel );
sizer.Add( dpan, pxSizerFlags::SubGroup() );
return *dpan;
}
// ------------------------------------------------------------------------
Panels::StandardPathsPanel::StandardPathsPanel( wxWindow* parent ) :
BasePathsPanel( parent )
{
wxSizer& s_main( *GetSizer() );
s_main.AddSpacer( BetweenFolderSpace );
AddDirPicker( s_main, FolderId_Savestates,
*this += BetweenFolderSpace;
*this += (new DirPickerPanel( this, FolderId_Savestates,
_("Savestates:"),
_("Select folder for Savestates") ).
_("Select folder for Savestates") ))->
SetToolTip( pxE( ".Tooltips:Folders:Savestates",
L"This folder is where PCSX2 records savestates; which are recorded either by using "
L"menus/toolbars, or by pressing F1/F3 (load/save)."
) );
s_main.AddSpacer( BetweenFolderSpace );
AddDirPicker( s_main, FolderId_Snapshots,
)
) | SubGroup();
*this += BetweenFolderSpace;
*this += (new DirPickerPanel( this, FolderId_Snapshots,
_("Snapshots:"),
_("Select a folder for Snapshots") ).
_("Select a folder for Snapshots") ))->
SetToolTip( pxE( ".Tooltips:Folders:Snapshots",
L"This folder is where PCSX2 saves screenshots. Actual screenshot image format and style "
L"may vary depending on the GS plugin being used."
) );
)
) | SubGroup();
s_main.AddSpacer( BetweenFolderSpace );
AddDirPicker( s_main, FolderId_Logs,
*this += BetweenFolderSpace;
*this += (new DirPickerPanel( this, FolderId_Logs,
_("Logs/Dumps:" ),
_("Select a folder for logs/dumps") ).
_("Select a folder for logs/dumps") ))->
SetToolTip( pxE( ".Tooltips:Folders:Logs",
L"This folder is where PCSX2 saves its logfiles and diagnostic dumps. Most plugins will "
L"also adhere to this folder, however some older plugins may ignore it."
) );
)
) | SubGroup();
s_main.AddSpacer( BetweenFolderSpace );
AddDirPicker( s_main, FolderId_MemoryCards,
*this += BetweenFolderSpace;
*this += (new DirPickerPanel( this, FolderId_MemoryCards,
_("Memorycards:"),
_("Select a default Memorycards folder") ).
_("Select a default Memorycards folder") ))->
SetToolTip( pxE( ".Tooltips:Folders:Memorycards",
L"This is the default path where PCSX2 loads or creates its memory cards, and can be "
L"overridden in the MemoryCard Configuration by using absolute filenames."
) );
)
) | SubGroup();
s_main.AddSpacer( 5 );
*this += 5;
GetSizer()->SetMinSize( wxSize( 475, GetSizer()->GetMinSize().GetHeight() ) );
}

View File

@ -523,7 +523,7 @@ void Panels::PluginSelectorPanel::OnConfigure_Clicked( wxCommandEvent& evt )
{
wxWindowDisabler disabler;
SaveSinglePluginHelper helper( pid );
g_plugins->Configure( pid );
configfunc();
}
}

View File

@ -14,46 +14,14 @@
*/
#include "PrecompiledHeader.h"
#include "App.h"
#include "Dialogs/ConfigurationDialog.h"
#include "ConfigurationPanels.h"
#include <wx/spinctrl.h>
using namespace pxSizerFlags;
template< typename WinType >
WinType* FitToDigits( WinType* win, int digits )
{
int ex;
win->GetTextExtent( wxString( L'0', digits+1 ), &ex, NULL );
win->SetMinSize( wxSize( ex+10, wxDefaultCoord ) ); // +10 for text control borders/insets and junk.
return win;
}
template<>
wxSpinCtrl* FitToDigits<wxSpinCtrl>( wxSpinCtrl* win, int digits )
{
// HACK!! The better way would be to create a pxSpinCtrl class that extends wxSpinCtrl and thus
// have access to wxSpinButton::DoGetBestSize(). But since I don't want to do that, we'll just
// make/fake it with a value it's pretty common to Win32/GTK/Mac:
static const int MagicSpinnerSize = 18;
int ex;
win->GetTextExtent( wxString( L'0', digits+1 ), &ex, NULL );
win->SetMinSize( wxSize( ex+10+MagicSpinnerSize, wxDefaultCoord ) ); // +10 for text control borders/insets and junk.
return win;
}
// Creates a text control which is right-justified and has it's minimum width configured to suit the
// number of digits requested.
wxTextCtrl* CreateNumericalTextCtrl( wxWindow* parent, int digits )
{
wxTextCtrl* ctrl = new wxTextCtrl( parent, wxID_ANY );
ctrl->SetWindowStyleFlag( wxTE_RIGHT );
FitToDigits( ctrl, digits );
return ctrl;
}
// --------------------------------------------------------------------------------------
// FramelimiterPanel Implementations
// --------------------------------------------------------------------------------------
@ -69,9 +37,9 @@ Panels::FramelimiterPanel::FramelimiterPanel( wxWindow* parent )
L"be available either."
) );
m_spin_NominalPct = FitToDigits( new wxSpinCtrl( this ), 6 );
m_spin_SlomoPct = FitToDigits( new wxSpinCtrl( this ), 6 );
m_spin_TurboPct = FitToDigits( new wxSpinCtrl( this ), 6 );
pxFitToDigits( m_spin_NominalPct = new wxSpinCtrl( this ), 6 );
pxFitToDigits( m_spin_SlomoPct = new wxSpinCtrl( this ), 6 );
pxFitToDigits( m_spin_TurboPct = new wxSpinCtrl( this ), 6 );
m_text_BaseNtsc = CreateNumericalTextCtrl( this, 7 );
m_text_BasePal = CreateNumericalTextCtrl( this, 7 );
@ -83,11 +51,6 @@ Panels::FramelimiterPanel::FramelimiterPanel( wxWindow* parent )
// ------------------------------------------------------------
// Sizers and Layouts
*this += new pxStaticHeading( this, pxE( ".Framelimiter:Heading",
L"The internal framelimiter regulates the speed of the virtual machine. Adjustment values below are in "
L"percentages of the default region-based framerate, which can also be configured below." )
);
*this += m_check_LimiterDisable;
wxFlexGridSizer& s_spins( *new wxFlexGridSizer( 5 ) );
@ -134,193 +97,28 @@ Panels::FramelimiterPanel::FramelimiterPanel( wxWindow* parent )
*this += s_spins | pxExpand;
*this += s_fps | pxExpand;
OnSettingsChanged();
}
// --------------------------------------------------------------------------------------
// GSWindowSetting Implementation
// --------------------------------------------------------------------------------------
*this += 5;
Panels::GSWindowSettingsPanel::GSWindowSettingsPanel( wxWindow* parent )
: BaseApplicableConfigPanel( parent )
{
const wxString aspect_ratio_labels[] =
{
_("Fit to Window/Screen"),
_("Standard (4:3)"),
_("Widescreen (16:9)")
};
m_combo_AspectRatio = new wxComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
ArraySize(aspect_ratio_labels), aspect_ratio_labels, wxCB_READONLY );
m_text_WindowWidth = CreateNumericalTextCtrl( this, 5 );
m_text_WindowHeight = CreateNumericalTextCtrl( this, 5 );
m_check_SizeLock = new pxCheckBox( this, _("Disable window resize border") );
m_check_HideMouse = new pxCheckBox( this, _("Always hide mouse cursor") );
m_check_CloseGS = new pxCheckBox( this, _("Hide window on suspend") );
m_check_Fullscreen = new pxCheckBox( this, _("Default to Fullscreen") );
m_check_VsyncEnable = new pxCheckBox( this, _("Vsync Enable") );
m_check_VsyncEnable->SetToolTip( pxE( ".Tooltips:Video:Vsync",
L"Vsync eliminates screen tearing but typically has a big performance hit. "
L"It usually only applies to fullscreen mode, and may not work with all GS plugins."
) );
m_check_HideMouse->SetToolTip( pxE( ".Tooltips:Video:HideMouse",
L"Check this to force the mouse cursor invisible inside the GS window; useful if using "
L"the mouse as a primary control device for gaming. By default the mouse auto-hides after "
L"3 seconds of inactivity."
) );
m_check_Fullscreen->SetToolTip( pxE( ".Tooltips:Video:Fullscreen",
L"Enables automatic mode switch to fullscreen when starting or resuming emulation. "
L"You can still toggle fullscreen display at any time using alt-enter."
) );
m_check_CloseGS->SetToolTip( pxE( ".Tooltips:Video:HideGS",
L"Completely closes the often large and bulky GS window when pressing "
L"ESC or suspending the emulator."
) );
// ----------------------------------------------------------------------------
// Layout and Positioning
wxBoxSizer& s_customsize( *new wxBoxSizer( wxHORIZONTAL ) );
s_customsize += m_text_WindowWidth;
s_customsize += Text( L"x" );
s_customsize += m_text_WindowHeight;
wxFlexGridSizer& s_AspectRatio( *new wxFlexGridSizer( 2, StdPadding, StdPadding ) );
//s_AspectRatio.AddGrowableCol( 0 );
s_AspectRatio.AddGrowableCol( 1 );
s_AspectRatio += Text(_("Aspect Ratio:")) | pxMiddle;
s_AspectRatio += m_combo_AspectRatio | pxExpand;
s_AspectRatio += Text(_("Custom Window Size:")) | pxMiddle;
s_AspectRatio += s_customsize | pxAlignRight;
*this += s_AspectRatio | StdExpand();
*this += m_check_SizeLock;
*this += new wxStaticLine( this ) | StdExpand();
*this += m_check_Fullscreen;
*this += m_check_VsyncEnable;
*this += m_check_HideMouse;
*this += m_check_CloseGS;
OnSettingsChanged();
}
// --------------------------------------------------------------------------------------
// VideoPanel Implementation
// --------------------------------------------------------------------------------------
Panels::VideoPanel::VideoPanel( wxWindow* parent ) :
BaseApplicableConfigPanel( parent )
{
wxPanelWithHelpers* left = new wxPanelWithHelpers( this, wxVERTICAL );
wxPanelWithHelpers* right = new wxPanelWithHelpers( this, wxVERTICAL );
left->SetIdealWidth( (left->GetIdealWidth()-12) / 2 );
right->SetIdealWidth( (right->GetIdealWidth()-12) / 2 );
m_check_SynchronousGS = new pxCheckBox( left, _("Synchronized MTGS"),
_("For troubleshooting potential bugs in the MTGS only, as it is potentially very slow.")
*this += Heading( pxE( ".Framelimiter:Heading",
L"The internal framelimiter regulates the speed of the virtual machine. Adjustment values below are in "
L"percentages of the default region-based framerate, which can also be configured below." )
);
m_check_SynchronousGS->SetToolTip(_("Enable this if you think the MTGS is causing crashes or graphical errors."));
GSWindowSettingsPanel* winpan = new GSWindowSettingsPanel( left );
winpan->AddFrame(_("Display/Window"));
FramelimiterPanel* fpan = new FramelimiterPanel( right );
fpan->AddFrame(_("Framelimiter"));
wxFlexGridSizer* s_table = new wxFlexGridSizer( 2 );
s_table->AddGrowableCol( 0 );
s_table->AddGrowableCol( 1 );
*left += winpan | pxExpand;
*right += fpan | pxExpand;
*left += 5;
*left += m_check_SynchronousGS;
*s_table += left | StdExpand();
*s_table += right | StdExpand();
*this += s_table | pxExpand;
OnSettingsChanged();
}
void Panels::VideoPanel::Apply()
{
g_Conf->EmuOptions.GS.SynchronousMTGS = m_check_SynchronousGS->GetValue();
}
void Panels::VideoPanel::OnSettingsChanged()
{
m_check_SynchronousGS->SetValue( g_Conf->EmuOptions.GS.SynchronousMTGS );
}
void Panels::GSWindowSettingsPanel::OnSettingsChanged()
{
const AppConfig::GSWindowOptions& conf( g_Conf->GSWindow );
m_check_CloseGS ->SetValue( conf.CloseOnEsc );
m_check_Fullscreen ->SetValue( conf.DefaultToFullscreen );
m_check_HideMouse ->SetValue( conf.AlwaysHideMouse );
m_check_SizeLock ->SetValue( conf.DisableResizeBorders );
m_combo_AspectRatio ->SetSelection( (int)conf.AspectRatio );
m_check_VsyncEnable ->SetValue( g_Conf->EmuOptions.GS.VsyncEnable );
m_text_WindowWidth ->SetValue( wxsFormat( L"%d", conf.WindowSize.GetWidth() ) );
m_text_WindowHeight ->SetValue( wxsFormat( L"%d", conf.WindowSize.GetHeight() ) );
}
void Panels::GSWindowSettingsPanel::Apply()
{
AppConfig::GSWindowOptions& appconf( g_Conf->GSWindow );
Pcsx2Config::GSOptions& gsconf( g_Conf->EmuOptions.GS );
appconf.CloseOnEsc = m_check_CloseGS ->GetValue();
appconf.DefaultToFullscreen = m_check_Fullscreen->GetValue();
appconf.AlwaysHideMouse = m_check_HideMouse ->GetValue();
appconf.DisableResizeBorders = m_check_SizeLock ->GetValue();
appconf.AspectRatio = (AspectRatioType)m_combo_AspectRatio->GetSelection();
gsconf.VsyncEnable = m_check_VsyncEnable->GetValue();
long xr, yr;
if( !m_text_WindowWidth->GetValue().ToLong( &xr ) || !m_text_WindowHeight->GetValue().ToLong( &yr ) )
throw Exception::CannotApplySettings( this,
L"User submitted non-numeric window size parameters!",
_("Invalid window dimensions specified: Size cannot contain non-numeric digits! >_<")
);
appconf.WindowSize.x = xr;
appconf.WindowSize.y = yr;
}
void Panels::FramelimiterPanel::OnSettingsChanged()
{
const AppConfig::GSWindowOptions& appconf( g_Conf->GSWindow );
const AppConfig::GSWindowOptions& appwin( g_Conf->GSWindow );
const AppConfig::FramerateOptions& appfps( g_Conf->Framerate );
const Pcsx2Config::GSOptions& gsconf( g_Conf->EmuOptions.GS );
m_check_LimiterDisable->SetValue( !gsconf.FrameLimitEnable );
m_spin_NominalPct ->SetValue( appconf.NominalScalar.Raw );
m_spin_TurboPct ->SetValue( appconf.TurboScalar.Raw );
m_spin_SlomoPct ->SetValue( appconf.SlomoScalar.Raw );
m_spin_NominalPct ->SetValue( appfps.NominalScalar.Raw );
m_spin_TurboPct ->SetValue( appfps.TurboScalar.Raw );
m_spin_SlomoPct ->SetValue( appfps.SlomoScalar.Raw );
m_text_BaseNtsc ->SetValue( gsconf.FramerateNTSC.ToString() );
m_text_BasePal ->SetValue( gsconf.FrameratePAL.ToString() );
@ -328,14 +126,14 @@ void Panels::FramelimiterPanel::OnSettingsChanged()
void Panels::FramelimiterPanel::Apply()
{
AppConfig::GSWindowOptions& appconf( g_Conf->GSWindow );
AppConfig::FramerateOptions& appfps( g_Conf->Framerate );
Pcsx2Config::GSOptions& gsconf( g_Conf->EmuOptions.GS );
gsconf.FrameLimitEnable = !m_check_LimiterDisable->GetValue();
appconf.NominalScalar.Raw = m_spin_NominalPct ->GetValue();
appconf.TurboScalar.Raw = m_spin_TurboPct ->GetValue();
appconf.SlomoScalar.Raw = m_spin_SlomoPct ->GetValue();
appfps.NominalScalar.Raw = m_spin_NominalPct ->GetValue();
appfps.TurboScalar.Raw = m_spin_TurboPct ->GetValue();
appfps.SlomoScalar.Raw = m_spin_SlomoPct ->GetValue();
try {
gsconf.FramerateNTSC = Fixed100::FromString( m_text_BaseNtsc->GetValue() );
@ -347,6 +145,211 @@ void Panels::FramelimiterPanel::Apply()
wxLt("Error while parsing either NTSC or PAL framerate settings. Settings must be valid floating point numerics.")
);
}
appconf.SanityCheck();
appfps.SanityCheck();
}
// --------------------------------------------------------------------------------------
// FrameSkipPanel Implementations
// --------------------------------------------------------------------------------------
Panels::FrameSkipPanel::FrameSkipPanel( wxWindow* parent )
: BaseApplicableConfigPanel( parent )
{
/*m_check_EnableSkipOnTurbo = new pxCheckBox( this, _("Use Frameskip for Turbo") );
m_check_EnableSkip = new pxCheckBox( this, _("Use Frameskip"),
_(".") );
m_check_EnableSkip->SetToolTip( pxE( ".Tooltip:Frameskip:Disable",
L""
L""
) );
m_check_EnableSkipOnTurbo->SetToolTip( pxE( ".Tooltip:Framelimiter:UseForTurbo",
L"Recommended option! Since frameskipping glitches typically aren't as annoying when you're "
L" just trying to speed through stuff."
) );*/
const RadioPanelItem FrameskipOptions[] =
{
RadioPanelItem(
_("Disabled [default]")
),
RadioPanelItem(
_("Skip when on Turbo only")
),
RadioPanelItem(
_("Constant skipping"),
wxEmptyString,
_("Normal and Turbo limit rates skip frames. Slow motion mode will still disable frameskipping.")
),
};
m_radio_SkipMode = new pxRadioPanel( this, FrameskipOptions );
//m_radio_SkipMode->SetPaddingHoriz( m_radio_UserMode->GetPaddingHoriz() + 4 );
m_radio_SkipMode->Realize();
pxFitToDigits( m_spin_FramesToDraw = new wxSpinCtrl( this ), 6 );
pxFitToDigits( m_spin_FramesToSkip = new wxSpinCtrl( this ), 6 );
// Set tooltips for spinners.
// ------------------------------------------------------------
// Sizers and Layouts
//*this += m_check_EnableSkipOnTurbo;
//*this += m_check_EnableSkip;
*this += m_radio_SkipMode;
wxFlexGridSizer& s_spins( *new wxFlexGridSizer( 4 ) );
//s_spins.AddGrowableCol( 0 );
s_spins += m_spin_FramesToDraw | wxSF.Border(wxTOP, 3);
s_spins += 10;
s_spins += Text(_("Frames to Draw"));
s_spins += 10;
s_spins += m_spin_FramesToSkip | wxSF.Border(wxTOP, 3);
s_spins += 10;
s_spins += Text(_("Frames to Skip"));
s_spins += 10;
*this += s_spins | StdExpand();
*this += Heading( pxE( ".FrameSkip:Heading",
L"Notice: Due to PS2 hardware design, precise frame skipping is impossible. "
L"Enabling it will cause severe graphical errors in some games, and so it should be considered a speedhack." )
);
OnSettingsChanged();
}
void Panels::FrameSkipPanel::OnSettingsChanged()
{
const AppConfig::FramerateOptions& appfps( g_Conf->Framerate );
const Pcsx2Config::GSOptions& gsconf( g_Conf->EmuOptions.GS );
//m_check_EnableSkip ->SetValue( !appfps.SkipOnLimit );
//m_check_EnableSkipOnTurbo ->SetValue( !appfps.SkipOnTurbo );
m_radio_SkipMode ->SetSelection( appfps.SkipOnLimit ? 2 : (appfps.SkipOnTurbo ? 1 : 0) );
m_spin_FramesToDraw ->SetValue( gsconf.FramesToDraw );
m_spin_FramesToSkip ->SetValue( gsconf.FramesToSkip );
}
void Panels::FrameSkipPanel::Apply()
{
AppConfig::FramerateOptions& appfps( g_Conf->Framerate );
Pcsx2Config::GSOptions& gsconf( g_Conf->EmuOptions.GS );
gsconf.FramesToDraw = m_spin_FramesToDraw->GetValue();
gsconf.FramesToSkip = m_spin_FramesToSkip->GetValue();
switch( m_radio_SkipMode->GetSelection() )
{
case 0:
appfps.SkipOnLimit = false;
appfps.SkipOnTurbo = false;
break;
case 1:
appfps.SkipOnLimit = false;
appfps.SkipOnTurbo = true;
break;
case 2:
appfps.SkipOnLimit = true;
appfps.SkipOnTurbo = true;
break;
}
appfps.SanityCheck();
}
// --------------------------------------------------------------------------------------
// VideoPanel Implementation
// --------------------------------------------------------------------------------------
Panels::VideoPanel::VideoPanel( wxWindow* parent ) :
BaseApplicableConfigPanel( parent )
{
wxPanelWithHelpers* left = new wxPanelWithHelpers( this, wxVERTICAL );
wxPanelWithHelpers* right = new wxPanelWithHelpers( this, wxVERTICAL );
left->SetIdealWidth( (left->GetIdealWidth()) / 2 );
right->SetIdealWidth( (right->GetIdealWidth()-24) / 2 );
m_check_SynchronousGS = new pxCheckBox( right, _("Use Synchronized MTGS"),
_("For troubleshooting potential bugs in the MTGS only, as it is potentially very slow.")
);
m_check_DisableOutput = new pxCheckBox( right, _("Disable all GS output"),
_("Completely disables all GS plugin activity; ideal for benchmarking EEcore components.")
);
m_check_SynchronousGS->SetToolTip(_("Enable this if you think MTGS thread sync is causing crashes or graphical errors."));
m_check_DisableOutput->SetToolTip( pxE( ".Tooltip:Video:DisableOutput",
L"Removes any benchmark noise caused by the MTGS thread or GPU overhead. This option is best used in conjunction with savestates: "
L"save a state at an ideal scene, enable this option, and re-load the savestate.\n\n"
L"Warning: This option can be enabled on-the-fly but typically cannot be disabled on-the-fly (video will typically be garbage)."
) );
m_button_OpenWindowSettings = new wxButton( left, wxID_ANY, _("Open Window Settings...") );
pxSetToolTip( m_button_OpenWindowSettings, _("For editing GS window position, aspect ratio, and other display options.") );
//GSWindowSettingsPanel* winpan = new GSWindowSettingsPanel( left );
//winpan->AddFrame(_("Display/Window"));
FrameSkipPanel* span = new FrameSkipPanel( right );
span->AddFrame(_("Frame Skipping"));
FramelimiterPanel* fpan = new FramelimiterPanel( left );
fpan->AddFrame(_("Framelimiter"));
wxFlexGridSizer* s_table = new wxFlexGridSizer( 2 );
s_table->AddGrowableCol( 0 );
s_table->AddGrowableCol( 1 );
*right += span | pxExpand;
*right += 5;
*right += m_check_SynchronousGS;
*right += m_check_DisableOutput;
*left += fpan | pxExpand;
*left += 5;
*left += m_button_OpenWindowSettings;
*s_table += left | StdExpand();
*s_table += right | StdExpand();
*this += s_table | pxExpand;
Connect( m_button_OpenWindowSettings->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(VideoPanel::OnOpenWindowSettings) );
OnSettingsChanged();
}
void Panels::VideoPanel::OnOpenWindowSettings( wxCommandEvent& evt )
{
AppOpenDialog<Dialogs::AppConfigDialog>( this );
// don't evt.skip, this prevents the Apply button from being activated. :)
}
void Panels::VideoPanel::Apply()
{
g_Conf->EmuOptions.GS.SynchronousMTGS = m_check_SynchronousGS->GetValue();
g_Conf->EmuOptions.GS.DisableOutput = m_check_DisableOutput->GetValue();
}
void Panels::VideoPanel::OnSettingsChanged()
{
m_check_SynchronousGS->SetValue( g_Conf->EmuOptions.GS.SynchronousMTGS );
m_check_DisableOutput->SetValue( g_Conf->EmuOptions.GS.DisableOutput );
}

View File

@ -293,7 +293,7 @@ static __forceinline void gsHandler(const u8* pMem)
if (pMem>=vuMemEnd) pMem -= 0x4000; \
} while(false)
#define aMin(x, y) ((x < y) ? (x) : (y))
#define aMin(x, y) std::min( x, y )
#define subVal(x, y) ((x > y) ? (x-y) : 0 )
// Parameters:

View File

@ -1924,7 +1924,15 @@
>
</File>
<File
RelativePath="..\..\gui\Dialogs\ConfigurationDialog.cpp"
RelativePath="..\..\gui\Dialogs\BaseConfigurationDialog.cpp"
>
</File>
<File
RelativePath="..\..\gui\Dialogs\BaseConfigurationDialog.inl"
>
</File>
<File
RelativePath="..\..\gui\Dialogs\BiosSelectorDialog.cpp"
>
</File>
<File
@ -1963,6 +1971,10 @@
RelativePath="..\..\gui\Dialogs\PickUserModeDialog.cpp"
>
</File>
<File
RelativePath="..\..\gui\Dialogs\SysConfigDialog.cpp"
>
</File>
</Filter>
<Filter
Name="Resources"
@ -2459,10 +2471,6 @@
RelativePath="..\..\gui\Panels\AudioPanel.cpp"
>
</File>
<File
RelativePath="..\..\gui\Panels\BaseConfigPanel.h"
>
</File>
<File
RelativePath="..\..\gui\Panels\BiosSelectorPanel.cpp"
>
@ -2483,6 +2491,10 @@
RelativePath="..\..\gui\Panels\GameFixesPanel.cpp"
>
</File>
<File
RelativePath="..\..\gui\Panels\GSWindowPanel.cpp"
>
</File>
<File
RelativePath="..\..\gui\Panels\LogOptionsPanels.cpp"
>
@ -2527,6 +2539,10 @@
RelativePath="..\..\gui\AppConfig.h"
>
</File>
<File
RelativePath="..\..\gui\ApplyState.h"
>
</File>
<File
RelativePath="..\..\gui\ConsoleLogger.h"
>

View File

@ -99,7 +99,7 @@ bool StreamException_LogFromErrno( const wxString& streamname, const wxChar* act
}
catch( Exception::Stream& ex )
{
Console.Warning( L"%s: %s", action, ex.FormatDiagnosticMessage().c_str() );
Console.WriteLn( Color_Yellow, L"%s: %s", action, ex.FormatDiagnosticMessage().c_str() );
return true;
}
return false;
@ -114,7 +114,7 @@ bool StreamException_LogLastError( const wxString& streamname, const wxChar* act
}
catch( Exception::Stream& ex )
{
Console.Warning( L"%s: %s", action, ex.FormatDiagnosticMessage().c_str() );
Console.WriteLn( Color_Yellow, L"%s: %s", action, ex.FormatDiagnosticMessage().c_str() );
return true;
}
return false;