Using the Console Log scrollbars to read back history will automatically throttle emulation temporarily, until the scrollbar is released.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2269 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-11-28 15:44:33 +00:00
parent b0db54ae35
commit 295d751f4a
3 changed files with 154 additions and 63 deletions

View File

@ -74,10 +74,13 @@ IsoDirectory::IsoDirectory(SectorSource& r)
break; break;
case 0xff: case 0xff:
default:
// Null terminator. End of partition information. // Null terminator. End of partition information.
done = true; done = true;
break; break;
default:
Console.Error( "(IsoFS) Unknown partition type ID=%d, encountered at block 0x%x", sector[0], i );
break;
} }
} }
else else

View File

@ -236,25 +236,117 @@ enum MenuIDs_t
MenuID_FontSize_Huge, MenuID_FontSize_Huge,
}; };
void __evt_fastcall pxLogTextCtrl::OnCoreThreadStatusChanged( void* obj, wxCommandEvent& evt )
{
#ifdef __WXMSW__
if( obj == NULL ) return;
pxLogTextCtrl* mframe = (pxLogTextCtrl*)obj;
// WM_VSCROLL makes the scrolling 'smooth' (such that the last line of the log contents
// are always displayed as the last line of the log window). Unfortunately this also
// makes logging very slow, so we only send the message for status changes, so that the
// log aligns itself nicely when we pause emulation or when errors occur.
::SendMessage((HWND)mframe->GetHWND(), WM_VSCROLL, SB_BOTTOM, (LPARAM)NULL);
mframe->m_win32_StupidRefreshTricks = 0;
#endif
}
void __evt_fastcall pxLogTextCtrl::OnCorePluginStatusChanged( void* obj, PluginEventType& evt )
{
#ifdef __WXMSW__
if( obj == NULL ) return;
pxLogTextCtrl* mframe = (pxLogTextCtrl*)obj;
// WM_VSCROLL makes the scrolling 'smooth' (such that the last line of the log contents
// are always displayed as the last line of the log window). Unfortunately this also
// makes logging very slow, so we only send the message for status changes, so that the
// log aligns itself nicely when we pause emulation or when errors occur.
::SendMessage((HWND)mframe->GetHWND(), WM_VSCROLL, SB_BOTTOM, (LPARAM)NULL);
mframe->m_win32_StupidRefreshTricks = 0;
#endif
}
pxLogTextCtrl::pxLogTextCtrl( wxWindow* parent )
: wxTextCtrl( parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
wxTE_MULTILINE | wxHSCROLL | wxTE_READONLY | wxTE_RICH2
)
, m_Listener_CoreThreadStatus ( wxGetApp().Source_CoreThreadStatus(), CmdEvt_Listener ( this, OnCoreThreadStatusChanged ) )
, m_Listener_CorePluginStatus ( wxGetApp().Source_CorePluginStatus(), EventListener<PluginEventType> ( this, OnCorePluginStatusChanged ) )
{
#ifdef __WXMSW__
m_win32_StupidRefreshTricks = 0;
m_win32_LinesPerScroll = 10;
#endif
m_FreezeWrites = false;
Connect( wxEVT_SCROLLWIN_THUMBTRACK, wxScrollWinEventHandler(pxLogTextCtrl::OnThumbTrack) );
Connect( wxEVT_SCROLLWIN_THUMBRELEASE, wxScrollWinEventHandler(pxLogTextCtrl::OnThumbRelease) );
Connect( wxEVT_SIZE, wxSizeEventHandler(pxLogTextCtrl::OnResize) );
}
void pxLogTextCtrl::OnResize( wxSizeEvent& evt )
{
#ifdef __WXMSW__
// Windows has retarded console window update patterns. This helps smarten them up.
int ctrly = GetSize().y;
int fonty;
GetTextExtent( L"blaH yeah", NULL, &fonty );
m_win32_LinesPerScroll = (int)((ctrly * 0.72) / fonty);
#endif
evt.Skip();
}
void pxLogTextCtrl::OnThumbTrack(wxScrollWinEvent& evt)
{
//Console.Warning( "Thumb Tracking!!!" );
m_FreezeWrites = true;
evt.Skip();
}
void pxLogTextCtrl::OnThumbRelease(wxScrollWinEvent& evt)
{
//Console.Warning( "Thumb Releasing!!!" );
m_FreezeWrites = false;
evt.Skip();
}
void pxLogTextCtrl::DoFlushUpdate()
{
#ifdef __WXMSW__
// EM_LINESCROLL avoids weird errors when the buffer reaches "max" and starts
// clearing old history:
::SendMessage((HWND)GetHWND(), EM_LINESCROLL, 0, 0xfffffff);
if( ++m_win32_StupidRefreshTricks > m_win32_LinesPerScroll )
{
m_win32_StupidRefreshTricks = 0;
::SendMessage((HWND)GetHWND(), WM_VSCROLL, SB_BOTTOM, (LPARAM)NULL);
}
#endif
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
ConsoleLogFrame::ConsoleLogFrame( MainEmuFrame *parent, const wxString& title, AppConfig::ConsoleLogOptions& options ) ConsoleLogFrame::ConsoleLogFrame( MainEmuFrame *parent, const wxString& title, AppConfig::ConsoleLogOptions& options )
: wxFrame(parent, wxID_ANY, title) : wxFrame(parent, wxID_ANY, title)
, m_conf( options ) , m_conf( options )
, m_TextCtrl( *new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, , m_TextCtrl( *new pxLogTextCtrl(this) )
wxTE_MULTILINE | wxHSCROLL | wxTE_READONLY | wxTE_RICH2 ) )
, m_ColorTable( options.FontSize ) , m_ColorTable( options.FontSize )
, m_QueueColorSection( L"ConsoleLog::QueueColorSection" ) , m_QueueColorSection( L"ConsoleLog::QueueColorSection" )
, m_QueueBuffer( L"ConsoleLog::QueueBuffer" ) , m_QueueBuffer( L"ConsoleLog::QueueBuffer" )
, m_threadlogger( EnableThreadedLoggingTest ? new ConsoleTestThread() : NULL ) , m_threadlogger( EnableThreadedLoggingTest ? new ConsoleTestThread() : NULL )
, m_Listener_CoreThreadStatus ( wxGetApp().Source_CoreThreadStatus(), CmdEvt_Listener ( this, OnCoreThreadStatusChanged ) )
, m_Listener_CorePluginStatus ( wxGetApp().Source_CorePluginStatus(), EventListener<PluginEventType> ( this, OnCorePluginStatusChanged ) )
{ {
m_CurQueuePos = 0; m_CurQueuePos = 0;
m_pendingFlushes = 0; m_pendingFlushes = 0;
m_WaitingThreadsForFlush = 0; m_WaitingThreadsForFlush = 0;
m_ThreadedLogInQueue = false; m_ThreadedLogInQueue = false;
m_pendingFlushMsg = false;
m_ThawThrottle = 0; m_ThawThrottle = 0;
m_ThawNeeded = false; m_ThawNeeded = false;
@ -349,8 +441,6 @@ ConsoleLogFrame::~ConsoleLogFrame()
wxGetApp().OnProgramLogClosed(); wxGetApp().OnProgramLogClosed();
} }
int m_pendingFlushes = 0;
// Implementation note: Calls SetColor and Write( text ). Override those virtuals // Implementation note: Calls SetColor and Write( text ). Override those virtuals
// and this one will magically follow suite. :) // and this one will magically follow suite. :)
void ConsoleLogFrame::Write( ConsoleColors color, const wxString& text ) void ConsoleLogFrame::Write( ConsoleColors color, const wxString& text )
@ -382,11 +472,12 @@ void ConsoleLogFrame::Write( ConsoleColors color, const wxString& text )
// example). So let's hackfix it so that an alternate message is posted if the queue is // example). So let's hackfix it so that an alternate message is posted if the queue is
// "piling up." // "piling up."
if( m_pendingFlushes == 0 ) if( !m_pendingFlushMsg )
{ {
wxCommandEvent evt( wxEVT_FlushQueue ); wxCommandEvent evt( wxEVT_FlushQueue );
evt.SetInt( 0 ); evt.SetInt( 0 );
GetEventHandler()->AddPendingEvent( evt ); GetEventHandler()->AddPendingEvent( evt );
m_pendingFlushMsg = true;
} }
++m_pendingFlushes; ++m_pendingFlushes;
@ -559,7 +650,6 @@ void ConsoleLogFrame::OnFontSize( wxCommandEvent& evt )
// TODO: Process the attributes of each character and upgrade the font size, // TODO: Process the attributes of each character and upgrade the font size,
// while still retaining color and bold settings... (might be slow but then // while still retaining color and bold settings... (might be slow but then
// it hardly matters being a once-in-a-bluemoon action). // it hardly matters being a once-in-a-bluemoon action).
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -577,40 +667,13 @@ void ConsoleLogFrame::OnIdleEvent( wxIdleEvent& evt )
//::SendMessage((HWND)m_TextCtrl.GetHWND(), WM_VSCROLL, SB_BOTTOM, (LPARAM)NULL); //::SendMessage((HWND)m_TextCtrl.GetHWND(), WM_VSCROLL, SB_BOTTOM, (LPARAM)NULL);
} }
void __evt_fastcall ConsoleLogFrame::OnCoreThreadStatusChanged( void* obj, wxCommandEvent& evt )
{
#ifdef __WXMSW__
if( obj == NULL ) return;
ConsoleLogFrame* mframe = (ConsoleLogFrame*)obj;
// WM_VSCROLL makes the scrolling 'smooth' (such that the last line of the log contents
// are always displayed as the last line of the log window). Unfortunately this also
// makes logging very slow, so we only send the message for status changes, so that the
// log aligns itself nicely when we pause emulation or when errors occur.
::SendMessage((HWND)mframe->m_TextCtrl.GetHWND(), WM_VSCROLL, SB_BOTTOM, (LPARAM)NULL);
#endif
}
void __evt_fastcall ConsoleLogFrame::OnCorePluginStatusChanged( void* obj, PluginEventType& evt )
{
#ifdef __WXMSW__
if( obj == NULL ) return;
ConsoleLogFrame* mframe = (ConsoleLogFrame*)obj;
// WM_VSCROLL makes the scrolling 'smooth' (such that the last line of the log contents
// are always displayed as the last line of the log window). Unfortunately this also
// makes logging very slow, so we only send the message for status changes, so that the
// log aligns itself nicely when we pause emulation or when errors occur.
::SendMessage((HWND)mframe->m_TextCtrl.GetHWND(), WM_VSCROLL, SB_BOTTOM, (LPARAM)NULL);
#endif
}
void ConsoleLogFrame::OnFlushEvent( wxCommandEvent& evt ) void ConsoleLogFrame::OnFlushEvent( wxCommandEvent& evt )
{ {
ScopedLock locker( m_QueueLock ); ScopedLock locker( m_QueueLock );
m_pendingFlushMsg = false;
if( m_TextCtrl.HasWriteLock() ) return;
if( m_CurQueuePos != 0 ) if( m_CurQueuePos != 0 )
{ {
if( m_ThreadedLogInQueue && (m_pendingFlushes < 20) ) if( m_ThreadedLogInQueue && (m_pendingFlushes < 20) )
@ -628,12 +691,8 @@ void ConsoleLogFrame::OnFlushEvent( wxCommandEvent& evt )
} }
DoFlushQueue(); DoFlushQueue();
m_TextCtrl.DoFlushUpdate();
#ifdef __WXMSW__
// EM_LINESCROLL avoids weird errors when the buffer reaches "max" and starts
// clearing old history:
::SendMessage((HWND)m_TextCtrl.GetHWND(), EM_LINESCROLL, 0, 0xfffffff);
#endif
//m_TextCtrl.Thaw(); //m_TextCtrl.Thaw();
} }
@ -696,10 +755,7 @@ void ConsoleLogFrame::DoFlushQueue()
if( m_QueueColorSection[i].color != Color_Current ) if( m_QueueColorSection[i].color != Color_Current )
m_TextCtrl.SetDefaultStyle( m_ColorTable[m_QueueColorSection[i].color] ); m_TextCtrl.SetDefaultStyle( m_ColorTable[m_QueueColorSection[i].color] );
const wxString passin( &m_QueueBuffer[m_QueueColorSection[i].startpoint] ); m_TextCtrl.WriteText( &m_QueueBuffer[m_QueueColorSection[i].startpoint] );
m_TextCtrl.WriteText( passin );
insertPoint += passin.Length();
} }
// Some reports on Windows7 have corrupted cursor when using insertPoint (or // Some reports on Windows7 have corrupted cursor when using insertPoint (or

View File

@ -86,6 +86,37 @@ public:
} }
}; };
// --------------------------------------------------------------------------------------
// pxLogTextCtrl
// --------------------------------------------------------------------------------------
class pxLogTextCtrl : public wxTextCtrl
{
protected:
CmdEvt_ListenerBinding m_Listener_CoreThreadStatus;
EventListenerBinding<PluginEventType> m_Listener_CorePluginStatus;
#ifdef __WXMSW__
int m_win32_StupidRefreshTricks;
int m_win32_LinesPerScroll;
#endif
bool m_FreezeWrites;
public:
pxLogTextCtrl(wxWindow* parent);
bool HasWriteLock() const { return m_FreezeWrites; }
void DoFlushUpdate();
protected:
virtual void OnThumbTrack(wxScrollWinEvent& event);
virtual void OnThumbRelease(wxScrollWinEvent& event);
virtual void OnResize( wxSizeEvent& evt );
static void __evt_fastcall OnCoreThreadStatusChanged( void* obj, wxCommandEvent& evt );
static void __evt_fastcall OnCorePluginStatusChanged( void* obj, PluginEventType& evt );
};
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// ConsoleLogFrame -- Because the one built in wx is poop. // ConsoleLogFrame -- Because the one built in wx is poop.
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -133,7 +164,7 @@ protected:
protected: protected:
ConLogConfig& m_conf; ConLogConfig& m_conf;
wxTextCtrl& m_TextCtrl; pxLogTextCtrl& m_TextCtrl;
ColorArray m_ColorTable; ColorArray m_ColorTable;
// this int throttles freeze/thaw of the display, by cycling from -2 to 4, roughly. // this int throttles freeze/thaw of the display, by cycling from -2 to 4, roughly.
@ -159,9 +190,16 @@ protected:
// the GUI. // the GUI.
volatile int m_pendingFlushes; 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;
// This is a counter of the number of threads waiting for the Queue to flush. // This is a counter of the number of threads waiting for the Queue to flush.
volatile int m_WaitingThreadsForFlush; volatile int m_WaitingThreadsForFlush;
// Indicates to the main thread if a child thread is actively writing to the log. If
// true the main thread will sleep briefly to allow the child a chance to accumulate
// more messages (helps avoid rapid successive flushes on high volume logging).
volatile bool m_ThreadedLogInQueue; volatile bool m_ThreadedLogInQueue;
// Used by threads waiting on the queue to flush. // Used by threads waiting on the queue to flush.
@ -181,9 +219,6 @@ protected:
// Current write position into the m_QueueBuffer; // Current write position into the m_QueueBuffer;
int m_CurQueuePos; int m_CurQueuePos;
CmdEvt_ListenerBinding m_Listener_CoreThreadStatus;
EventListenerBinding<PluginEventType> m_Listener_CorePluginStatus;
// Threaded log spammer, useful for testing console logging performance. // Threaded log spammer, useful for testing console logging performance.
// (alternatively you can enable Disasm logging in any recompiler and achieve // (alternatively you can enable Disasm logging in any recompiler and achieve
// a similar effect) // a similar effect)
@ -234,8 +269,5 @@ protected:
void OnMoveAround( wxMoveEvent& evt ); void OnMoveAround( wxMoveEvent& evt );
void OnResize( wxSizeEvent& evt ); void OnResize( wxSizeEvent& evt );
static void __evt_fastcall OnCoreThreadStatusChanged( void* obj, wxCommandEvent& evt );
static void __evt_fastcall OnCorePluginStatusChanged( void* obj, PluginEventType& evt );
}; };