Minor user interface cleanups and tweaks; most notable being some better "spam" protection on the console logger.

Details: Console logger now freezes updates for 100ms after every update.  This means it responds quickly to most logs, but limits series of log spams to 10 updates per second.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2978 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2010-05-11 07:17:31 +00:00
parent 2a05b6d449
commit a1870a845b
14 changed files with 371 additions and 357 deletions

View File

@ -339,21 +339,9 @@ bool AppPluginManager::OpenPlugin_GS()
return retval;
}
static int _guard = 0;
// Yay, this plugin is guaranteed to always be opened first and closed last.
void AppPluginManager::ClosePlugin_GS()
{
/*if( GSopen2 == NULL || CloseViewportWithPlugins )
{
// All other plugins must be closed before the GS, because they all rely on
// the GS window handle being valid. The recursion guard will protect this
// function from being called a million times. ;)
RecursionGuard mess( _guard );
if( !mess.IsReentrant() ) Close();
}*/
_parent::ClosePlugin_GS();
if( GetMTGS().IsSelf() && GSopen2 && CloseViewportWithPlugins ) sApp.CloseGsPanel();
}

View File

@ -230,24 +230,17 @@ ConsoleLogFrame::ConsoleLogFrame( MainEmuFrame *parent, const wxString& title, A
: wxFrame(parent, wxID_ANY, title)
, m_conf( options )
, m_TextCtrl( *new pxLogTextCtrl(this) )
, m_timer_FlushLimiter( this )
, m_timer_FlushUnlocker( this )
, m_ColorTable( options.FontSize )
, m_QueueColorSection( L"ConsoleLog::QueueColorSection" )
, m_QueueBuffer( L"ConsoleLog::QueueBuffer" )
, m_threadlogger( EnableThreadedLoggingTest ? new ConsoleTestThread() : NULL )
{
m_flushevent_counter = 0;
m_CurQueuePos = 0;
m_pendingFlushes = 0;
m_WaitingThreadsForFlush = 0;
m_ThreadedLogInQueue = false;
m_pendingFlushMsg = false;
m_ThawThrottle = 0;
m_ThawNeeded = false;
m_ThawPending = false;
m_FlushRefreshLocked = false;
SetIcons( wxGetApp().GetIconBundle() );
@ -329,8 +322,7 @@ ConsoleLogFrame::ConsoleLogFrame( MainEmuFrame *parent, const wxString& title, A
Connect( pxEvt_DockConsole, wxCommandEventHandler (ConsoleLogFrame::OnDockedMove) );
Connect( pxEvt_FlushQueue, wxCommandEventHandler (ConsoleLogFrame::OnFlushEvent) );
Connect( wxEVT_IDLE, wxIdleEventHandler (ConsoleLogFrame::OnIdleEvent) );
Connect( wxEVT_TIMER, wxTimerEventHandler (ConsoleLogFrame::OnFlushLimiterTimer) );
Connect( m_timer_FlushUnlocker.GetId(), wxEVT_TIMER, wxTimerEventHandler (ConsoleLogFrame::OnFlushUnlockerTimer) );
m_item_Deci2 ->Check( g_Conf->EmuOptions.Log.Deci2 );
m_item_StdoutEE ->Check( g_Conf->EmuOptions.Log.StdoutEE );
@ -388,26 +380,27 @@ void ConsoleLogFrame::Write( ConsoleColors color, const wxString& text )
wxCommandEvent evt( pxEvt_FlushQueue );
evt.SetInt( 0 );
if( wxThread::IsMain() )
GetEventHandler()->ProcessEvent( evt );
else
{
GetEventHandler()->AddPendingEvent( evt );
OnFlushEvent( evt );
return;
}
else
GetEventHandler()->AddPendingEvent( evt );
lock.Acquire();
}
++m_pendingFlushes;
if( !wxThread::IsMain() )
{
m_ThreadedLogInQueue = true;
if( m_pendingFlushes > 48 )
// Too many color changes causes huge slowdowns when decorating the rich textview, so
// include a secodary check to avoid having a colorful log spam from killing gui responsiveness.
if( m_CurQueuePos > 0x100000 || m_QueueColorSection.GetLength() > 256 )
{
++m_WaitingThreadsForFlush;
lock.Release();
if( !m_sem_QueueFlushed.Wait( wxTimeSpan( 0,0,0,500 ) ) )
if( !m_sem_QueueFlushed.Wait( wxTimeSpan( 0,0,0,250 ) ) )
{
// Necessary since the main thread could grab the lock and process before
// the above function actually returns (gotta love threading!)
@ -418,7 +411,6 @@ void ConsoleLogFrame::Write( ConsoleColors color, const wxString& text )
{
// give gui thread time to repaint and handle other pending messages.
//pxYield( 1 );
wxGetApp().Ping();
}
}
@ -609,36 +601,8 @@ void ConsoleLogFrame::OnSetTitle( wxCommandEvent& event )
SetTitle( event.GetString() );
}
void ConsoleLogFrame::OnIdleEvent( wxIdleEvent& )
void ConsoleLogFrame::DoFlushEvent( bool isPending )
{
// When the GUI is idle then it's a safe bet we can resume suspended console log
// flushing, on the theory that the user's had a good chance to field user input.
if( m_flushevent_counter > 0 )
{
m_flushevent_counter = 0;
m_timer_FlushLimiter.Stop();
wxCommandEvent sendevt( pxEvt_FlushQueue );
GetEventHandler()->AddPendingEvent( sendevt );
}
}
void ConsoleLogFrame::OnFlushLimiterTimer( wxTimerEvent& )
{
if( m_flushevent_counter == 0 ) return;
m_flushevent_counter = 0;
wxCommandEvent sendevt( pxEvt_FlushQueue );
GetEventHandler()->AddPendingEvent( sendevt );
}
void ConsoleLogFrame::OnFlushEvent( wxCommandEvent& )
{
ScopedLock locker( m_mtx_Queue );
m_pendingFlushMsg = false;
// recursion guard needed due to Mutex lock/acquire code below, which can end up yielding
// to the gui and attempting to process more messages (which in turn would result in re-
// entering this handler).
@ -647,38 +611,11 @@ void ConsoleLogFrame::OnFlushEvent( wxCommandEvent& )
RecursionGuard recguard( recursion_counter );
if( recguard.IsReentrant() ) return;
ScopedLock locker( m_mtx_Queue );
if( m_CurQueuePos != 0 )
{
if( !m_timer_FlushLimiter.IsRunning() )
{
m_timer_FlushLimiter.Start( 500, true );
m_flushevent_counter = 0;
}
else
{
if( m_flushevent_counter >= 1000 )
return;
++m_flushevent_counter;
}
if( m_ThreadedLogInQueue && (m_pendingFlushes < 20) )
{
// Hacky Speedup -->
// Occasionally the EEcore thread can send ups some serious amounts of spam, and
// if we don't sleep the main thread some, the stupid text control refresh will
// drive framerates toward zero as it tries to refresh for every single log.
// This hack checks if a thread has been posting logs and, if so, we "rest" the
// main thread so that other threads can accumulate a more sizable log chunk.
locker.Release();
Sleep( 2 );
locker.Acquire();
}
if( m_CurQueuePos != 0 )
DoFlushQueue();
//m_TextCtrl.Thaw();
DoFlushQueue();
}
// Implementation note: I tried desperately to move this into wxEVT_IDLE, on the theory that
@ -695,6 +632,24 @@ void ConsoleLogFrame::OnFlushEvent( wxCommandEvent& )
int count = m_sem_QueueFlushed.Count();
while( count < 0 ) m_sem_QueueFlushed.Post();
}
m_pendingFlushMsg = isPending;
}
void ConsoleLogFrame::OnFlushUnlockerTimer( wxTimerEvent& )
{
m_FlushRefreshLocked = false;
DoFlushEvent( false );
}
void ConsoleLogFrame::OnFlushEvent( wxCommandEvent& )
{
if( m_FlushRefreshLocked ) return;
DoFlushEvent( true );
m_FlushRefreshLocked = true;
m_timer_FlushUnlocker.Start( 100, true );
}
void ConsoleLogFrame::DoFlushQueue()
@ -710,12 +665,14 @@ void ConsoleLogFrame::DoFlushQueue()
// Manual InsertionPoint tracking avoids a lot of overhead in SetInsertionPointEnd()
wxTextPos insertPoint = m_TextCtrl.GetLastPosition();
// cap at 256k for now...
// fixme - 256k runs well on win32 but appears to be very sluggish on linux (but that could
// cap at 512k for now...
// fixme - 512k runs well on win32 but appears to be very sluggish on linux (but that could
// be a result of my using Xming + CoLinux). Might need platform dependent defaults here. --air
if( (insertPoint + m_CurQueuePos) > 0x40000 )
static const int BufferSize = 0x80000;
if( (insertPoint + m_CurQueuePos) > BufferSize )
{
int toKeep = 0x40000 - m_CurQueuePos;
int toKeep = BufferSize - m_CurQueuePos;
if( toKeep <= 10 )
{
m_TextCtrl.Clear();
@ -723,8 +680,8 @@ void ConsoleLogFrame::DoFlushQueue()
}
else
{
int toRemove = 0x40000 - toKeep;
if( toRemove < 0x10000 ) toRemove = 0x10000;
int toRemove = BufferSize - toKeep;
if( toRemove < BufferSize / 4 ) toRemove = BufferSize;
m_TextCtrl.Remove( 0, toRemove );
insertPoint -= toRemove;
}
@ -732,6 +689,13 @@ void ConsoleLogFrame::DoFlushQueue()
m_TextCtrl.SetInsertionPoint( insertPoint );
// fixme : Writing a lot of colored logs to the console can be quite slow when "spamming"
// is happening, due to the overhead of SetDefaultStyle and WriteText calls. I'm not sure
// if there's a better way to go about this? Using Freeze/Thaw helps a little bit, but it's
// still magnitudes slower than dumping a straight run. --air
if( len > 64 ) m_TextCtrl.Freeze();
for( int i=0; i<len; ++i )
{
if( m_QueueColorSection[i].color != Color_Current )
@ -740,12 +704,12 @@ void ConsoleLogFrame::DoFlushQueue()
m_TextCtrl.WriteText( &m_QueueBuffer[m_QueueColorSection[i].startpoint] );
}
m_TextCtrl.ConcludeIssue( m_pendingFlushes );
if( len > 64 ) m_TextCtrl.Thaw();
m_TextCtrl.ConcludeIssue();
m_QueueColorSection.Clear();
m_CurQueuePos = 0;
m_pendingFlushes = 0;
m_ThreadedLogInQueue= false;
}
ConsoleLogFrame* Pcsx2App::GetProgramLog()

View File

@ -109,7 +109,7 @@ public:
virtual ~pxLogTextCtrl() throw();
bool HasWriteLock() const { return m_FreezeWrites; }
void ConcludeIssue( int lines );
void ConcludeIssue();
#ifdef __WXMSW__
virtual void WriteText(const wxString& text);
@ -173,33 +173,16 @@ protected:
ConLogConfig& m_conf;
pxLogTextCtrl& m_TextCtrl;
wxTimer m_timer_FlushLimiter;
wxTimer m_timer_FlushUnlocker;
ColorArray m_ColorTable;
int m_flushevent_counter;
// this int throttles freeze/thaw of the display, by cycling from -2 to 4, roughly.
// (negative values force thaw, positive values indicate thaw is disabled. This is
// needed because the wxWidgets Thaw implementation uses a belated paint message,
// and if we Freeze on the very next queued message after thawing, the repaint
// never happens)
int m_ThawThrottle;
// If a freeze is executed, this is set true (without this, wx asserts)
bool m_ThawNeeded;
// Set true when a Thaw message is sent (avoids cluttering the message pump with redundant
// requests)
bool m_ThawPending;
bool m_FlushRefreshLocked;
// ----------------------------------------------------------------------------
// Queue State Management Vars
// ----------------------------------------------------------------------------
// This is a counter of the total number of pending flushes across all threads.
// If the value exceeds a threshold, threads begin throttling to avoid deadlocking
// the GUI.
volatile int m_pendingFlushes;
// Boolean indicating if a flush message is already in the Main message queue. Used
// to prevent spamming the main thread with redundant messages.
volatile bool m_pendingFlushMsg;
@ -217,7 +200,7 @@ protected:
// Lock object for accessing or modifying the following three vars:
// m_QueueBuffer, m_QueueColorSelection, m_CurQueuePos
MutexRecursive m_mtx_Queue;
Mutex m_mtx_Queue;
// Describes a series of colored text sections in the m_QueueBuffer.
SafeList<ColorSection> m_QueueColorSection;
@ -271,14 +254,14 @@ protected:
void OnSetTitle( wxCommandEvent& event );
void OnDockedMove( wxCommandEvent& event );
void OnIdleEvent( wxIdleEvent& event );
void OnFlushLimiterTimer( wxTimerEvent& evt );
void OnFlushUnlockerTimer( wxTimerEvent& evt );
void OnFlushEvent( wxCommandEvent& event );
// common part of OnClose() and OnCloseWindow()
virtual void DoClose();
void DoFlushQueue();
void DoFlushEvent( bool isPending );
void OnMoveAround( wxMoveEvent& evt );
void OnResize( wxSizeEvent& evt );
void OnActivate( wxActivateEvent& evt );

View File

@ -24,6 +24,7 @@
#include <wx/filepicker.h>
using namespace Panels;
using namespace pxSizerFlags;
// ----------------------------------------------------------------------------
Dialogs::BiosSelectorDialog::BiosSelectorDialog( wxWindow* parent )
@ -33,15 +34,29 @@ Dialogs::BiosSelectorDialog::BiosSelectorDialog( wxWindow* parent )
m_idealWidth = 500;
Panels::BaseSelectorPanel* selpan = new Panels::BiosSelectorPanel( this );
m_selpan = new Panels::BiosSelectorPanel( this );
*this += selpan | pxSizerFlags::StdExpand();
AddOkCancel( *GetSizer(), false );
*this += m_selpan | StdExpand();
AddOkCancel();
Connect( wxID_OK, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(BiosSelectorDialog::OnOk_Click) );
Connect( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEventHandler(BiosSelectorDialog::OnDoubleClicked) );
}
selpan->OnShown();
bool Dialogs::BiosSelectorDialog::Show( bool show )
{
if( show && m_selpan )
m_selpan->OnShown();
return _parent::Show( show );
}
int Dialogs::BiosSelectorDialog::ShowModal()
{
if( m_selpan )
m_selpan->OnShown();
return _parent::ShowModal();
}
void Dialogs::BiosSelectorDialog::OnOk_Click( wxCommandEvent& evt )

View File

@ -22,6 +22,12 @@
#include "AppCommon.h"
#include "ApplyState.h"
namespace Panels
{
class BaseSelectorPanel;
class MemoryCardListPanel;
}
namespace Dialogs
{
class BaseApplicableDialog : public wxDialogWithHelpers, public IApplyState
@ -91,11 +97,19 @@ namespace Dialogs
// --------------------------------------------------------------------------------------
class McdConfigDialog : public BaseConfigurationDialog
{
typedef BaseApplicableDialog _parent;
protected:
Panels::MemoryCardListPanel* m_panel_mcdlist;
public:
virtual ~McdConfigDialog() throw() {}
McdConfigDialog(wxWindow* parent=NULL);
static const wxChar* GetNameStatic() { return L"Dialog:MemoryCardSettings"; }
virtual bool Show( bool show=true );
virtual int ShowModal();
protected:
virtual wxString& GetConfSettingsTabName() const { return g_Conf->McdSettingsTabName; }
};
@ -121,7 +135,10 @@ namespace Dialogs
// --------------------------------------------------------------------------------------
class BiosSelectorDialog : public BaseApplicableDialog
{
typedef BaseApplicableDialog _parent;
protected:
Panels::BaseSelectorPanel* m_selpan;
public:
virtual ~BiosSelectorDialog() throw() {}
@ -129,6 +146,9 @@ namespace Dialogs
static const wxChar* GetNameStatic() { return L"Dialog:BiosSelector"; }
virtual bool Show( bool show=true );
virtual int ShowModal();
protected:
void OnOk_Click( wxCommandEvent& evt );
void OnDoubleClicked( wxCommandEvent& evt );

View File

@ -1,163 +1,183 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2010 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 "ConfigurationDialog.h"
#include "BaseConfigurationDialog.inl"
#include "ModalPopups.h"
#include "MSWstuff.h"
#include "Panels/ConfigurationPanels.h"
#include "Panels/MemoryCardPanels.h"
using namespace pxSizerFlags;
namespace Panels
{
// Helper class since the 'AddPage' template system needs a single-parameter constructor.
class McdConfigPanel_Multitap2 : public McdConfigPanel_Multitap
{
public:
McdConfigPanel_Multitap2( wxWindow* parent ) : McdConfigPanel_Multitap( parent, 1 ) {}
virtual ~McdConfigPanel_Multitap2() throw() { }
};
}
wxString GetMsg_McdNtfsCompress()
{
return pxE( ".Dialog:Memorycards:NtfsCompress",
L"NTFS compression is built-in, fast, and completely reliable; and typically compresses MemoryCards "
L"very well (this option is highly recommended)."
);
}
Panels::McdConfigPanel_Toggles::McdConfigPanel_Toggles(wxWindow *parent)
: _parent( parent )
{
m_idealWidth -= 48;
m_check_Ejection = new pxCheckBox( this,
_("Auto-eject memorycards when loading savestates"),
pxE( ".Dialog:Memorycards:EnableEjection",
L"Avoids memorycard corruption by forcing games to re-index card contents after "
L"loading from savestates. May not be compatible with all games (Guitar Hero)."
)
);
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2010 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 "ConfigurationDialog.h"
#include "BaseConfigurationDialog.inl"
#include "ModalPopups.h"
#include "MSWstuff.h"
#include "Panels/ConfigurationPanels.h"
#include "Panels/MemoryCardPanels.h"
using namespace pxSizerFlags;
namespace Panels
{
// Helper class since the 'AddPage' template system needs a single-parameter constructor.
class McdConfigPanel_Multitap2 : public McdConfigPanel_Multitap
{
public:
McdConfigPanel_Multitap2( wxWindow* parent ) : McdConfigPanel_Multitap( parent, 1 ) {}
virtual ~McdConfigPanel_Multitap2() throw() { }
};
}
wxString GetMsg_McdNtfsCompress()
{
return pxE( ".Dialog:Memorycards:NtfsCompress",
L"NTFS compression is built-in, fast, and completely reliable; and typically compresses MemoryCards "
L"very well (this option is highly recommended)."
);
}
Panels::McdConfigPanel_Toggles::McdConfigPanel_Toggles(wxWindow *parent)
: _parent( parent )
{
m_idealWidth -= 48;
m_check_Ejection = new pxCheckBox( this,
_("Auto-eject memorycards when loading savestates"),
pxE( ".Dialog:Memorycards:EnableEjection",
L"Avoids memorycard corruption by forcing games to re-index card contents after "
L"loading from savestates. May not be compatible with all games (Guitar Hero)."
)
);
*this += m_check_Ejection | pxExpand;
#ifdef __WXMSW__
m_check_CompressNTFS = new pxCheckBox( this,
_("Enable NTFS Compression on all cards by default."),
GetMsg_McdNtfsCompress()
#ifdef __WXMSW__
m_check_CompressNTFS = new pxCheckBox( this,
_("Enable NTFS Compression on all cards by default."),
GetMsg_McdNtfsCompress()
);
*this += m_check_CompressNTFS | pxExpand;
#endif
}
void Panels::McdConfigPanel_Toggles::Apply()
{
*this += m_check_CompressNTFS | pxExpand;
#endif
}
void Panels::McdConfigPanel_Toggles::Apply()
{
g_Conf->McdEnableEjection = m_check_Ejection->GetValue();
#ifdef __WXMSW__
#ifdef __WXMSW__
g_Conf->McdCompressNTFS = m_check_CompressNTFS->GetValue();
#endif
}
void Panels::McdConfigPanel_Toggles::AppStatusEvent_OnSettingsApplied()
{
#endif
}
void Panels::McdConfigPanel_Toggles::AppStatusEvent_OnSettingsApplied()
{
m_check_Ejection ->SetValue( g_Conf->McdEnableEjection );
#ifdef __WXMSW__
#ifdef __WXMSW__
m_check_CompressNTFS ->SetValue( g_Conf->McdCompressNTFS );
#endif
}
Panels::McdConfigPanel_Standard::McdConfigPanel_Standard(wxWindow *parent) : _parent( parent )
{
m_panel_cardinfo[0] = new MemoryCardInfoPanel( this, 0, 0 );
m_panel_cardinfo[1] = new MemoryCardInfoPanel( this, 1, 0 );
for( uint port=0; port<2; ++port )
{
wxStaticBoxSizer& portSizer( *new wxStaticBoxSizer( wxVERTICAL, this, wxsFormat(_("Port %u"), port+1) ) );
portSizer += m_panel_cardinfo[port] | pxExpand;
*this += portSizer | StdExpand();
}
}
void Panels::McdConfigPanel_Standard::Apply()
{
}
void Panels::McdConfigPanel_Standard::AppStatusEvent_OnSettingsApplied()
{
}
Panels::McdConfigPanel_Multitap::McdConfigPanel_Multitap(wxWindow *parent, int port) : _parent( parent )
{
m_port = port;
m_check_Multitap = new pxCheckBox( this, wxsFormat(_("Enable Multitap on Port %u"), m_port+1) );
m_check_Multitap->SetFont( wxFont( m_check_Multitap->GetFont().GetPointSize()+1, wxFONTFAMILY_MODERN, wxNORMAL, wxNORMAL, false, L"Lucida Console" ) );
Connect( m_check_Multitap->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(McdConfigPanel_Multitap::OnMultitapChecked));
}
void Panels::McdConfigPanel_Multitap::OnMultitapChecked( wxCommandEvent& evt )
{
}
void Panels::McdConfigPanel_Multitap::Apply()
{
}
void Panels::McdConfigPanel_Multitap::AppStatusEvent_OnSettingsApplied()
{
}
using namespace Panels;
using namespace pxSizerFlags;
Dialogs::McdConfigDialog::McdConfigDialog( wxWindow* parent )
: BaseConfigurationDialog( parent, _("MemoryCard Settings - PCSX2"), wxGetApp().GetImgList_Config(), 600 )
{
SetName( GetNameStatic() );
// [TODO] : Discover and use a good multitap port icon! Possibility might be a
// simple 3x memorycards icon, in cascading form.
// (for now everything defaults to the redundant memorycard icon)
const AppImageIds::ConfigIds& cfgid( wxGetApp().GetImgId().Config );
AddPage<McdConfigPanel_Toggles> ( wxLt("Settings"), cfgid.MemoryCard );
AddPage<McdConfigPanel_Standard> ( wxLt("Slots 1/2"), cfgid.MemoryCard );
AddPage<McdConfigPanel_Multitap> ( wxLt("Multitap 1"), cfgid.MemoryCard );
AddPage<McdConfigPanel_Multitap2> ( wxLt("Multitap 2"), cfgid.MemoryCard );
//MSW_ListView_SetIconSpacing( m_listbook, m_idealWidth );
*this += StdPadding;
*this += new wxStaticLine( this ) | pxExpand;
*this += StdPadding;
*this += new MemoryCardListPanel( this ) | pxExpand;
AddOkCancel();
}
#endif
}
Panels::McdConfigPanel_Standard::McdConfigPanel_Standard(wxWindow *parent) : _parent( parent )
{
m_panel_cardinfo[0] = new MemoryCardInfoPanel( this, 0, 0 );
m_panel_cardinfo[1] = new MemoryCardInfoPanel( this, 1, 0 );
for( uint port=0; port<2; ++port )
{
wxStaticBoxSizer& portSizer( *new wxStaticBoxSizer( wxVERTICAL, this, wxsFormat(_("Port %u"), port+1) ) );
portSizer += m_panel_cardinfo[port] | pxExpand;
*this += portSizer | StdExpand();
}
}
void Panels::McdConfigPanel_Standard::Apply()
{
}
void Panels::McdConfigPanel_Standard::AppStatusEvent_OnSettingsApplied()
{
}
Panels::McdConfigPanel_Multitap::McdConfigPanel_Multitap(wxWindow *parent, int port) : _parent( parent )
{
m_port = port;
m_check_Multitap = new pxCheckBox( this, wxsFormat(_("Enable Multitap on Port %u"), m_port+1) );
m_check_Multitap->SetFont( wxFont( m_check_Multitap->GetFont().GetPointSize()+1, wxFONTFAMILY_MODERN, wxNORMAL, wxNORMAL, false, L"Lucida Console" ) );
*this += m_check_Multitap;
Connect( m_check_Multitap->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(McdConfigPanel_Multitap::OnMultitapChecked));
}
void Panels::McdConfigPanel_Multitap::OnMultitapChecked( wxCommandEvent& evt )
{
}
void Panels::McdConfigPanel_Multitap::Apply()
{
}
void Panels::McdConfigPanel_Multitap::AppStatusEvent_OnSettingsApplied()
{
}
using namespace Panels;
using namespace pxSizerFlags;
Dialogs::McdConfigDialog::McdConfigDialog( wxWindow* parent )
: BaseConfigurationDialog( parent, _("MemoryCard Settings - PCSX2"), wxGetApp().GetImgList_Config(), 600 )
{
SetName( GetNameStatic() );
// [TODO] : Discover and use a good multitap port icon! Possibility might be a
// simple 3x memorycards icon, in cascading form.
// (for now everything defaults to the redundant memorycard icon)
const AppImageIds::ConfigIds& cfgid( wxGetApp().GetImgId().Config );
AddPage<McdConfigPanel_Toggles> ( wxLt("Settings"), cfgid.MemoryCard );
AddPage<McdConfigPanel_Standard> ( wxLt("Slots 1/2"), cfgid.MemoryCard );
AddPage<McdConfigPanel_Multitap> ( wxLt("Multitap 1"), cfgid.MemoryCard );
AddPage<McdConfigPanel_Multitap2> ( wxLt("Multitap 2"), cfgid.MemoryCard );
MSW_ListView_SetIconSpacing( m_listbook, m_idealWidth );
m_panel_mcdlist = new MemoryCardListPanel( this );
*this += StdPadding;
*this += new wxStaticLine( this ) | StdExpand();
*this += StdPadding;
*this += m_panel_mcdlist | StdExpand();
AddOkCancel();
}
bool Dialogs::McdConfigDialog::Show( bool show )
{
if( show && m_panel_mcdlist )
m_panel_mcdlist->OnShown();
return _parent::Show( show );
}
int Dialogs::McdConfigDialog::ShowModal()
{
if( m_panel_mcdlist )
m_panel_mcdlist->OnShown();
return _parent::ShowModal();
}

View File

@ -20,6 +20,10 @@
using namespace pxSizerFlags;
using namespace Threading;
// NOTE: Currently unused module. Stuck Threads are not detected or handled at this time,
// though I would like to have something in place in the distant future. --air
Dialogs::StuckThreadDialog::StuckThreadDialog( wxWindow* parent, StuckThreadActionType action, PersistentThread& stuck_thread )
: wxDialogWithHelpers( parent, _("PCSX2 Thread is not responding"), wxVERTICAL )
{

View File

@ -103,31 +103,6 @@ void MainEmuFrame::Menu_ResetAllSettings_Click(wxCommandEvent &event)
}
}
// Old 'auto-restart' method; avoids shutting down the PCSX2 process, but tends to
// be bug prone in odd ways (namely QueryPerformanceFrequency hangs for a number of
// seconds .. wtf?)
/*
m_RestartEmuOnDelete = true;
Destroy();
if( CoreThread.IsRunning() )
{
new RestartEverything_WhenCoreThreadStops();
if( StateCopy_IsBusy() )
{
new CancelCoreThread_WhenSaveStateDone();
throw Exception::CancelEvent( "Savestate in progress, app restart event delayed until action is complete." );
}
CoreThread.Cancel();
}
else
{
WipeSettings();
}
*/
WipeSettings();
wxGetApp().PostMenuAction( MenuId_Exit );
}
@ -328,9 +303,9 @@ void MainEmuFrame::Menu_CdvdSource_Click( wxCommandEvent &event )
switch( event.GetId() )
{
case MenuId_Src_Iso: newsrc = CDVDsrc_Iso; break;
case MenuId_Src_Plugin: newsrc = CDVDsrc_Plugin; break;
case MenuId_Src_NoDisc: newsrc = CDVDsrc_NoDisc; break;
case MenuId_Src_Iso: newsrc = CDVDsrc_Iso; break;
case MenuId_Src_Plugin: newsrc = CDVDsrc_Plugin; break;
case MenuId_Src_NoDisc: newsrc = CDVDsrc_NoDisc; break;
jNO_DEFAULT
}

View File

@ -16,6 +16,8 @@
#include "PrecompiledHeader.h"
#include "ConfigurationPanels.h"
using namespace pxSizerFlags;
Panels::GameFixesPanel::GameFixesPanel( wxWindow* parent ) :
BaseApplicableConfigPanel( parent )
{
@ -60,7 +62,13 @@ Panels::GameFixesPanel::GameFixesPanel( wxWindow* parent ) :
},
{
_("EE timing hack / FFX videos fix - Multi purpose hack. Try if all else fails."),
_("Known to affect following games:\n * Final Fantasy 10 (Fixes FMV)\n * Digital Devil Saga (Fixes FMV and crashes)\n * SSX (Fixes bad graphics and crashes)\n * Resident Evil: Dead Aim (Causes garbled textures)")
pxE( ".Tooltips:Gamefixes:EE Timing Hack",
L"Known to affect following games:\n"
L" * Final Fantasy 10 (Fixes FMV)\n"
L" * Digital Devil Saga (Fixes FMV and crashes)\n"
L" * SSX (Fixes bad graphics and crashes)\n"
L" * Resident Evil: Dead Aim (Causes garbled textures)"
)
}
};
@ -71,21 +79,21 @@ Panels::GameFixesPanel::GameFixesPanel( wxWindow* parent ) :
}
m_check_Enable = new pxCheckBox( this, _("Enable game fixes"),
_("(Warning, can cause compatibility or performance issues!)"));
_("(Warning! Game fixes can cause compatibility or performance issues!)"));
m_check_Enable->SetToolTip(_("The safest way to make sure that all game fixes are completely disabled."));
m_check_Enable ->SetValue( g_Conf->EnableGameFixes );
m_check_Enable->SetValue( g_Conf->EnableGameFixes );
*this += groupSizer | wxSF.Centre();
*this += groupSizer | pxCenter;
*this += m_check_Enable;
*this += new pxStaticHeading( this, pxE( ".Panels:Gamefixes:Compat Warning",
*this += m_check_Enable | StdExpand();
*this += Heading( pxE( ".Panels:Gamefixes:Compat Warning",
L"Enabling game fixes can cause compatibility or performance issues in other games. You "
L"will need to turn off fixes manually when changing games."
));
Connect( m_check_Enable->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( GameFixesPanel::OnEnable_Toggled ) );
EnableStuff();
AppStatusEvent_OnSettingsApplied();
Connect( m_check_Enable->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( GameFixesPanel::OnEnable_Toggled ) );
EnableStuff();
}
// I could still probably get rid of the for loop, but I think this is clearer.

View File

@ -93,8 +93,6 @@ Panels::MemoryCardListPanel::MemoryCardListPanel( wxWindow* parent )
wxButton* button_Create = new wxButton(this, wxID_ANY, _("Create new card..."));
//Connect( m_list_AllKnownCards->GetId(), wxEVT_COMMAND_LEFT_CLICK, MemoryCardsPanel::OnListDrag);
// ------------------------------------
// Sizer / Layout Section
// ------------------------------------
@ -114,8 +112,9 @@ Panels::MemoryCardListPanel::MemoryCardListPanel( wxWindow* parent )
*this += s_buttons | pxExpand;
m_listview->SetMinSize( wxSize( m_idealWidth, 120 ) );
Disable();
Connect( m_listview->GetId(), wxEVT_COMMAND_LIST_BEGIN_DRAG, wxListEventHandler(MemoryCardListPanel::OnListDrag));
Connect( button_Create->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MemoryCardListPanel::OnCreateNewCard));
}
void Panels::MemoryCardListPanel::Apply()
@ -124,7 +123,6 @@ void Panels::MemoryCardListPanel::Apply()
void Panels::MemoryCardListPanel::AppStatusEvent_OnSettingsApplied()
{
}
bool Panels::MemoryCardListPanel::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames)
@ -155,7 +153,7 @@ bool Panels::MemoryCardListPanel::ValidateEnumerationStatus()
if( !m_KnownCards || (*mcdlist != *m_KnownCards) )
validated = false;
m_listview->AssignCardsList( NULL );
m_listview->SetInterface( NULL );
m_KnownCards.SwapPtr( mcdlist );
return validated;
@ -165,9 +163,6 @@ void Panels::MemoryCardListPanel::DoRefresh()
{
if( !m_KnownCards ) return;
//m_listview->ClearAll();
//m_listview->CreateColumns();
for( size_t i=0; i<m_KnownCards->size(); ++i )
{
McdListItem& mcditem( (*m_KnownCards)[i] );
@ -189,5 +184,38 @@ void Panels::MemoryCardListPanel::DoRefresh()
}
}
m_listview->AssignCardsList( m_KnownCards );
m_listview->SetInterface( this );
//m_listview->SetCardCount( m_KnownCards->size() );
}
void Panels::MemoryCardListPanel::OnCreateNewCard(wxCommandEvent& evt)
{
}
void Panels::MemoryCardListPanel::OnListDrag(wxListEvent& evt)
{
wxFileDataObject my_data;
my_data.AddFile( (*m_KnownCards)[m_listview->GetItemData(m_listview->GetFirstSelected())].Filename.GetFullPath() );
wxDropSource dragSource( m_listview );
dragSource.SetData( my_data );
wxDragResult result = dragSource.DoDragDrop();
}
int Panels::MemoryCardListPanel::GetLength() const
{
return m_KnownCards ? m_KnownCards->size() : 0;
}
const McdListItem& Panels::MemoryCardListPanel::Get( int idx ) const
{
pxAssume(!!m_KnownCards);
return (*m_KnownCards)[idx];
}
McdListItem& Panels::MemoryCardListPanel::Get( int idx )
{
pxAssume(!!m_KnownCards);
return (*m_KnownCards)[idx];
}

View File

@ -56,6 +56,14 @@ struct McdListItem
typedef std::vector<McdListItem> McdList;
class IMemoryCardList
{
public:
virtual int GetLength() const=0;
virtual const McdListItem& Get( int idx ) const=0;
virtual McdListItem& Get( int idx )=0;
};
// --------------------------------------------------------------------------------------
// MemoryCardListView
// --------------------------------------------------------------------------------------
@ -64,7 +72,7 @@ class MemoryCardListView : public wxListView
typedef wxListView _parent;
protected:
McdList* m_KnownCards;
IMemoryCardList* m_CardsList;
public:
virtual ~MemoryCardListView() throw() { }
@ -72,7 +80,12 @@ public:
virtual void OnListDrag(wxListEvent& evt);
virtual void CreateColumns();
virtual void AssignCardsList( McdList* knownCards, int length=0 );
virtual void SetCardCount( int length );
virtual void SetInterface( IMemoryCardList* face )
{
m_CardsList = face;
SetCardCount( m_CardsList ? m_CardsList->GetLength() : 0 );
}
protected:
// Overrides for wxLC_VIRTUAL
@ -90,6 +103,7 @@ namespace Panels
class MemoryCardListPanel
: public BaseSelectorPanel
, public wxFileDropTarget
, public IMemoryCardList
{
protected:
DirPickerPanel* m_FolderPicker;
@ -100,7 +114,14 @@ namespace Panels
virtual ~MemoryCardListPanel() throw() {}
MemoryCardListPanel( wxWindow* parent );
// Interface Implementation for IMemoryCardList
virtual int GetLength() const;
virtual const McdListItem& Get( int idx ) const;
virtual McdListItem& Get( int idx );
protected:
virtual void OnCreateNewCard(wxCommandEvent& evt);
virtual void OnListDrag(wxListEvent& evt);
virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenames);
virtual void Apply();

View File

@ -35,7 +35,7 @@ enum McdColumnType
McdCol_Formatted,
McdCol_DateModified,
McdCol_DateCreated,
McdCol_Path,
//McdCol_Path,
McdCol_Count
};
@ -55,50 +55,40 @@ void MemoryCardListView::CreateColumns()
{ _("Formatted"), wxLIST_FORMAT_CENTER },
{ _("Last Modified"), wxLIST_FORMAT_LEFT },
{ _("Created On"), wxLIST_FORMAT_LEFT },
{ _("Path"), wxLIST_FORMAT_LEFT }
//{ _("Path"), wxLIST_FORMAT_LEFT }
};
for( int i=0; i<McdCol_Count; ++i )
InsertColumn( i, columns[i].name, columns[i].align, -1 );
}
void MemoryCardListView::AssignCardsList( McdList* knownCards, int length )
void MemoryCardListView::SetCardCount( int length )
{
if( knownCards == NULL ) length = 0;
m_KnownCards = knownCards;
if( !m_CardsList ) length = 0;
SetItemCount( length );
RefreshItems( 0, length );
Refresh();
}
MemoryCardListView::MemoryCardListView( wxWindow* parent )
: wxListView( parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL )
: wxListView( parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_VIRTUAL )
{
m_KnownCards = NULL;
m_CardsList = NULL;
CreateColumns();
//m_KnownCards;
Connect( wxEVT_COMMAND_LIST_BEGIN_DRAG, wxListEventHandler(MemoryCardListView::OnListDrag));
}
void MemoryCardListView::OnListDrag(wxListEvent& evt)
{
evt.Skip();
wxFileDataObject my_data;
my_data.AddFile( (*m_KnownCards)[ GetItemData(GetFirstSelected()) ].Filename.GetFullPath() );
wxDropSource dragSource( this );
dragSource.SetData( my_data );
wxDragResult result = dragSource.DoDragDrop();
}
// return the text for the given column of the given item
wxString MemoryCardListView::OnGetItemText(long item, long column) const
{
if( m_KnownCards == NULL ) return _parent::OnGetItemText(item, column);
if( !m_CardsList ) return _parent::OnGetItemText(item, column);
const McdListItem& it( (*m_KnownCards)[item] );
const McdListItem& it( m_CardsList->Get(item) );
switch( column )
{
@ -113,7 +103,7 @@ wxString MemoryCardListView::OnGetItemText(long item, long column) const
case McdCol_Formatted: return it.IsFormatted ? L"Yes" : L"No";
case McdCol_DateModified: return it.DateModified.FormatDate();
case McdCol_DateCreated: return it.DateModified.FormatDate();
case McdCol_Path: return it.Filename.GetPath();
//case McdCol_Path: return it.Filename.GetPath();
}
pxFail( "Unknown column index in MemoryCardListView -- returning an empty string." );

View File

@ -107,7 +107,7 @@ Panels::SpeedHacksPanel::SpeedHacksPanel( wxWindow* parent )
) );
m_check_Enable = new pxCheckBox( this, _("Enable speedhacks"),
_("(Warning, can cause false FPS readings and many bugs!)"));
_("(Warning! Speedhacks can cause false FPS readings, choppy audio, and many other bugs!)"));
m_check_Enable->SetToolTip(_("The safest way to make sure that all speedhacks are completely disabled."));
m_button_Defaults = new wxButton( this, wxID_DEFAULT, _("Restore Defaults") );
@ -266,8 +266,6 @@ Panels::SpeedHacksPanel::SpeedHacksPanel( wxWindow* parent )
Connect( m_slider_vustealer->GetId(), wxEVT_SCROLL_CHANGED, wxScrollEventHandler( SpeedHacksPanel::VUCycleRate_Scroll ) );
Connect( m_check_Enable->GetId(), wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( SpeedHacksPanel::OnEnable_Toggled ) );
Connect( wxID_DEFAULT, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( SpeedHacksPanel::Defaults_Click ) );
AppStatusEvent_OnSettingsApplied();
}
void Panels::SpeedHacksPanel::EnableStuff()

View File

@ -104,7 +104,7 @@ pxLogTextCtrl::~pxLogTextCtrl() throw()
{
}
void pxLogTextCtrl::ConcludeIssue( int lines )
void pxLogTextCtrl::ConcludeIssue()
{
if( HasWriteLock() ) return;
SetInsertionPointEnd();