diff --git a/pcsx2/System.h b/pcsx2/System.h index f116cd872b..7836f77d1b 100644 --- a/pcsx2/System.h +++ b/pcsx2/System.h @@ -75,6 +75,8 @@ extern void vSyncDebugStuff( uint frame ); # error PCSX2 - Unsupported operating system platform. #endif +class pxMessageBoxEvent; + ////////////////////////////////////////////////////////////////////////////////////////// // Different types of message boxes that the emulator can employ from the friendly confines // of it's blissful unawareness of whatever GUI it runs under. :) All message boxes exhibit @@ -83,18 +85,18 @@ extern void vSyncDebugStuff( uint frame ); // namespace Msgbox { - extern void OnEvent( wxCommandEvent& evt ); + extern void OnEvent( pxMessageBoxEvent& evt ); - // Pops up an alert Dialog Box with a singular "OK" button. - // Always returns false. Replacement for SysMessage. - extern bool Alert( const wxString& text ); + extern bool Alert( const wxString& text, const wxString& caption=L"PCSX2 Message", int icon=wxICON_EXCLAMATION ); + extern bool OkCancel( const wxString& text, const wxString& caption=L"PCSX2 Message", int icon=0 ); + extern bool YesNo( const wxString& text, const wxString& caption=L"PCSX2 Message", int icon=wxICON_QUESTION ); - // Pops up a dialog box with Ok/Cancel buttons. Returns the result of the inquiry, - // true if OK, false if cancel. - extern bool OkCancel( const wxString& text ); + extern int Assertion( const wxString& text, const wxString& stacktrace ); + extern void Except( const Exception::BaseException& src ); } BEGIN_DECLARE_EVENT_TYPES() DECLARE_EVENT_TYPE( pxEVT_MSGBOX, -1 ); + DECLARE_EVENT_TYPE( pxEVT_CallStackBox, -1 ); END_DECLARE_EVENT_TYPES() diff --git a/pcsx2/gui/App.h b/pcsx2/gui/App.h index 6a8edb5492..018a6e8869 100644 --- a/pcsx2/gui/App.h +++ b/pcsx2/gui/App.h @@ -23,138 +23,19 @@ #include #include +#include + #include "AppConfig.h" #include "System.h" +#include "ConsoleLogger.h" -using namespace Threading; - -class MainEmuFrame; class IniInterface; -class LogWriteEvent; extern wxFileHistory* g_RecentIsoList; -DECLARE_EVENT_TYPE(wxEVT_DockConsole, -1); - extern wxRect wxGetDisplayArea(); extern bool pxIsValidWindowPosition( const wxWindow& window, const wxPoint& windowPos ); -static const bool EnableThreadedLoggingTest = false; //true; - -////////////////////////////////////////////////////////////////////////////////////////// -// ConsoleThreadTest -- useful class for unit testing the thread safety and general performance -// of the console logger. -// -class ConsoleTestThread : public PersistentThread -{ -protected: - volatile bool m_done; - sptr ExecuteTask(); - -public: - ConsoleTestThread() : - m_done( false ) - { - } - - ~ConsoleTestThread() - { - m_done = true; - } -}; - - -////////////////////////////////////////////////////////////////////////////////////////// -// -class ConsoleLogFrame : public wxFrame -{ - DeclareNoncopyableObject(ConsoleLogFrame) - -public: - typedef AppConfig::ConsoleLogOptions ConLogConfig; - -protected: - class ColorArray - { - DeclareNoncopyableObject(ColorArray) - - protected: - SafeArray m_table; - wxTextAttr m_color_default; - - public: - virtual ~ColorArray(); - ColorArray( int fontsize=8 ); - - void Create( int fontsize ); - void Cleanup(); - - void SetFont( const wxFont& font ); - void SetFont( int fontsize ); - - const wxTextAttr& operator[]( Console::Colors coloridx ) const - { - return m_table[(int)coloridx]; - } - }; - -protected: - ConLogConfig m_conf; - wxTextCtrl& m_TextCtrl; - ColorArray m_ColorTable; - Console::Colors m_curcolor; - volatile long m_msgcounter; // used to track queued messages and throttle load placed on the gui message pump - - Semaphore m_semaphore; - - // Threaded log spammer, useful for testing console logging performance. - ConsoleTestThread* m_threadlogger; - -public: - // ctor & dtor - ConsoleLogFrame( MainEmuFrame *pParent, const wxString& szTitle, const ConLogConfig& options ); - virtual ~ConsoleLogFrame(); - - virtual void Write( const wxString& text ); - virtual void SetColor( Console::Colors color ); - virtual void ClearColor(); - virtual void DockedMove(); - - // Retreives the current configuration options settings for this box. - // (settings change if the user moves the window or changes the font size) - const ConLogConfig& GetConfig() const { return m_conf; } - - void Write( Console::Colors color, const wxString& text ); - void Newline(); - void CountMessage(); - void DoMessage(); - -protected: - - // menu callbacks - virtual void OnOpen (wxMenuEvent& event); - virtual void OnClose(wxMenuEvent& event); - virtual void OnSave (wxMenuEvent& event); - virtual void OnClear(wxMenuEvent& event); - - void OnFontSize(wxMenuEvent& event); - - virtual void OnCloseWindow(wxCloseEvent& event); - - void OnWrite( wxCommandEvent& event ); - void OnNewline( wxCommandEvent& event ); - void OnSetTitle( wxCommandEvent& event ); - void OnDockedMove( wxCommandEvent& event ); - void OnSemaphoreWait( wxCommandEvent& event ); - - // common part of OnClose() and OnCloseWindow() - virtual void DoClose(); - - void OnMoveAround( wxMoveEvent& evt ); - void OnResize( wxSizeEvent& evt ); -}; - - ////////////////////////////////////////////////////////////////////////////////////////// // struct AppImageIds @@ -199,6 +80,20 @@ struct AppImageIds } Toolbars; }; +////////////////////////////////////////////////////////////////////////////////////////// +// +class pxAppTraits : public wxGUIAppTraits +{ +#ifdef __WXDEBUG__ +public: + virtual bool ShowAssertDialog(const wxString& msg); + +protected: + virtual wxString GetAssertStackTrace(); +#endif + +}; + ////////////////////////////////////////////////////////////////////////////////////////// // class Pcsx2App : public wxApp @@ -228,6 +123,8 @@ public: bool PrepForExit(); + void OnAssertFailure( const wxChar *file, int line, const wxChar *func, const wxChar *cond, const wxChar *msg ); + const wxBitmap& GetLogoBitmap(); wxImageList& GetImgList_Config(); wxImageList& GetImgList_Toolbars(); @@ -282,8 +179,10 @@ public: protected: void ReadUserModeSettings(); bool TryOpenConfigCwd(); - void OnMessageBox( wxCommandEvent& evt ); + void OnMessageBox( pxMessageBoxEvent& evt ); void CleanupMess(); + + }; DECLARE_APP(Pcsx2App) diff --git a/pcsx2/gui/AppAssert.cpp b/pcsx2/gui/AppAssert.cpp new file mode 100644 index 0000000000..49ca1a1801 --- /dev/null +++ b/pcsx2/gui/AppAssert.cpp @@ -0,0 +1,135 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "PrecompiledHeader.h" +#include "App.h" + +#include + + +static wxString pxGetStackTrace() +{ + wxString stackTrace; + + class StackDump : public wxStackWalker + { + protected: + wxString m_stackTrace; + + public: + StackDump() { } + + const wxString& GetStackTrace() const { return m_stackTrace; } + + protected: + virtual void OnStackFrame(const wxStackFrame& frame) + { + wxString name( frame.GetName() ); + if( name.IsEmpty() ) + name = wxsFormat( L"%p ", frame.GetAddress() ); + + m_stackTrace += wxString::Format( L"[%02d] %-46s ", + wx_truncate_cast(int, frame.GetLevel()), name.c_str() + ); + + if ( frame.HasSourceLocation() ) + m_stackTrace += wxsFormat( L"%s:%d", frame.GetFileName().c_str(), frame.GetLine() ); + + m_stackTrace += L'\n'; + } + }; + + // [TODO] : Replace this with a textbox dialog setup. + static const int maxLines = 20; + + StackDump dump; + dump.Walk(2, maxLines); // don't show OnAssert() call itself + stackTrace = dump.GetStackTrace(); + + const int count = stackTrace.Freq( L'\n' ); + for ( int i = 0; i < count - maxLines; i++ ) + stackTrace = stackTrace.BeforeLast( L'\n' ); + + return stackTrace; +} + +wxString pxAppTraits::GetAssertStackTrace() +{ + return pxGetStackTrace(); +} + +static __threadlocal bool _reentrant_lock = false; + +#ifdef __WXDEBUG__ +// This override of wx's implementation provides thread safe assertion message reporting. If we aren't +// on the main gui thread then the assertion message box needs to be passed off to the main gui thread +// via messages. +void Pcsx2App::OnAssertFailure( const wxChar *file, int line, const wxChar *func, const wxChar *cond, const wxChar *msg ) +{ + if( _reentrant_lock ) + { + // Re-entrant assertions are bad mojo -- trap immediately. + wxTrap(); + } + + _reentrant_lock = true; + + // Used to allow the user to suppress future assertions during this application's session. + static bool disableAsserts = false; + + wxString dbgmsg; + dbgmsg.reserve( 2048 ); + + wxString message; + if( msg == NULL ) + message = cond; + else + message.Printf( L"%s (%s)", msg, cond ); + + // make life easier for people using VC++ IDE by using this format, which allows double-click + // response times from the Output window... + dbgmsg.Printf( L"%s(%d) : assertion failed%s%s: %s", file, line, + (func==NULL) ? L"" : L" in ", + (func==NULL) ? L"" : func, + message.c_str() + ); + + wxString trace( L"Call stack:\n" + pxGetStackTrace() ); + + wxMessageOutputDebug().Printf( dbgmsg ); + Console::Error( dbgmsg ); + Console::WriteLn( trace ); + + int retval = Msgbox::Assertion( dbgmsg, trace ); + + switch( retval ) + { + case wxID_YES: + wxTrap(); + break; + + case wxID_NO: break; + + case wxID_CANCEL: // ignores future assertions. + disableAsserts = true; + break; + } + + _reentrant_lock = false; +} +#endif diff --git a/pcsx2/gui/ConsoleLogger.cpp b/pcsx2/gui/ConsoleLogger.cpp index 9ad5fa5756..c7f8855d85 100644 --- a/pcsx2/gui/ConsoleLogger.cpp +++ b/pcsx2/gui/ConsoleLogger.cpp @@ -25,26 +25,82 @@ #include #include -// This code was 'borrowed' from wxWidgets built in console log class and then heavily -// modified to suite our needs. I would have used some crafty subclassing instead except -// who ever wrote the code of wxWidgets had a peculiar love of the 'private' keyword, -// thus killing any possibility of subclassing in a useful manner. (sigh) +// Custom ConsoleLogger, because the built-in wxWidgets one is poop. BEGIN_DECLARE_EVENT_TYPES() DECLARE_EVENT_TYPE(wxEVT_LOG_Write, -1) DECLARE_EVENT_TYPE(wxEVT_LOG_Newline, -1) DECLARE_EVENT_TYPE(wxEVT_SetTitleText, -1) - DECLARE_EVENT_TYPE(wxEVT_SemaphoreWait, -1); + DECLARE_EVENT_TYPE(wxEVT_SemaphoreWait, -1) END_DECLARE_EVENT_TYPES() DEFINE_EVENT_TYPE(wxEVT_LOG_Write) DEFINE_EVENT_TYPE(wxEVT_LOG_Newline) DEFINE_EVENT_TYPE(wxEVT_SetTitleText) DEFINE_EVENT_TYPE(wxEVT_DockConsole) -DEFINE_EVENT_TYPE(wxEVT_SemaphoreWait); +DEFINE_EVENT_TYPE(wxEVT_SemaphoreWait) using Console::Colors; +// ---------------------------------------------------------------------------- +// +void pxLogConsole::DoLog( wxLogLevel level, const wxChar *szString, time_t t ) +{ + switch ( level ) + { + case wxLOG_Trace: + case wxLOG_Debug: + if( IsDebugBuild ) + { + wxString str; + TimeStamp( &str ); + str += szString; + + #if defined(__WXMSW__) && !defined(__WXMICROWIN__) + // don't prepend debug/trace here: it goes to the + // debug window anyhow + str += wxT("\r\n"); + OutputDebugString(str); + #else + // send them to stderr + wxFprintf(stderr, wxT("[%s] %s\n"), + level == wxLOG_Trace ? wxT("Trace") + : wxT("Debug"), + str.c_str()); + fflush(stderr); + #endif + } + break; + + case wxLOG_FatalError: + // This one is unused by wx, and unused by PCSX2 (we prefer exceptions, thanks). + DevAssert( false, "Stop using FatalError and use assertions or exceptions instead." ); + break; + + case wxLOG_Status: + // Also unsed by wx, and unused by PCSX2 also (we prefer direct API calls to our main window!) + DevAssert( false, "Stop using wxLogStatus just access the Pcsx2App functions directly instead." ); + break; + + case wxLOG_Info: + if ( !GetVerbose() ) return; + // fallthrough! + + case wxLOG_Message: + Console::WriteLn( wxString(L"wx > ") + szString ); + break; + + case wxLOG_Error: + Console::Error( wxString(L"wx > ") + szString ); + break; + + case wxLOG_Warning: + Console::Notice( wxString(L"wx > ") + szString ); + break; + } +} + + // ---------------------------------------------------------------------------- sptr ConsoleTestThread::ExecuteTask() { @@ -603,72 +659,199 @@ namespace Console } } -#define wxEVT_BOX_ALERT 78 +DEFINE_EVENT_TYPE( pxEVT_MSGBOX ); +DEFINE_EVENT_TYPE( pxEVT_CallStackBox ); using namespace Threading; -DEFINE_EVENT_TYPE( pxEVT_MSGBOX ); +// Thread Safety: Must be called from the GUI thread ONLY. +static int pxMessageDialog( const wxString& content, const wxString& caption, long flags ) +{ + if( IsDevBuild && !wxThread::IsMain() ) + throw Exception::InvalidOperation( "Function must be called by the main GUI thread only." ); + + // fixme: If the emulator is currently active and is running in fullscreen mode, then we + // need to either: + // 1) Exit fullscreen mode before issuing the popup. + // 2) Issue the popup with wxSTAY_ON_TOP specified so that the user will see it. + // + // And in either case the emulation should be paused/suspended for the user. + + return wxMessageDialog( NULL, content, caption, flags ).ShowModal(); +} + +// Thread Safety: Must be called from the GUI thread ONLY. +// fixme: this function should use a custom dialog box that has a wxTextCtrl for the callstack, and +// uses fixed-width (modern) fonts. +static int pxCallstackDialog( const wxString& content, const wxString& caption, long flags ) +{ + if( IsDevBuild && !wxThread::IsMain() ) + throw Exception::InvalidOperation( "Function must be called by the main GUI thread only." ); + + return wxMessageDialog( NULL, content, caption, flags ).ShowModal(); +} + +struct MsgboxEventResult +{ + Semaphore WaitForMe; + int result; + + MsgboxEventResult() : + WaitForMe(), result( 0 ) + { + } +}; + +class pxMessageBoxEvent : public wxEvent +{ +protected: + MsgboxEventResult& m_Instdata; + wxString m_Title; + wxString m_Content; + long m_Flags; + +public: + pxMessageBoxEvent() : + wxEvent( 0, pxEVT_MSGBOX ) + , m_Instdata( *(MsgboxEventResult*)NULL ) + , m_Title() + , m_Content() + , m_Flags( 0 ) + { + } + + pxMessageBoxEvent( MsgboxEventResult& instdata, const wxString& title, const wxString& content, long flags ) : + wxEvent( 0, pxEVT_MSGBOX ) + , m_Instdata( instdata ) + , m_Title( title ) + , m_Content( content ) + , m_Flags( flags ) + { + } + + pxMessageBoxEvent( const pxMessageBoxEvent& event ) : + wxEvent( event ) + , m_Instdata( event.m_Instdata ) + , m_Title( event.m_Title ) + , m_Content( event.m_Content ) + , m_Flags( event.m_Flags ) + { + } + + // Thread Safety: Must be called from the GUI thread ONLY. + void DoTheDialog() + { + int result; + + if( m_id == pxEVT_MSGBOX ) + result = pxMessageDialog( m_Content, m_Title, m_Flags ); + else + result = pxCallstackDialog( m_Content, m_Title, m_Flags ); + m_Instdata.result = result; + m_Instdata.WaitForMe.Post(); + } + + virtual wxEvent *Clone() const { return new pxMessageBoxEvent(*this); } + +private: + DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxMessageBoxEvent) +}; + +IMPLEMENT_DYNAMIC_CLASS( pxMessageBoxEvent, wxEvent ) namespace Msgbox { - struct InstanceData - { - Semaphore WaitForMe; - int result; - - InstanceData() : - WaitForMe(), result( 0 ) - { - } - }; - // parameters: // flags - messagebox type flags, such as wxOK, wxCANCEL, etc. // - static int ThreadedMessageBox( int flags, const wxString& text ) + static int ThreadedMessageBox( const wxString& content, const wxString& title, long flags, int boxType=pxEVT_MSGBOX ) { // must pass the message to the main gui thread, and then stall this thread, to avoid // threaded chaos where our thread keeps running while the popup is awaiting input. - InstanceData instdat; - wxCommandEvent tevt( pxEVT_MSGBOX ); - tevt.SetString( text ); - tevt.SetClientData( &instdat ); - tevt.SetExtraLong( flags ); + MsgboxEventResult instdat; + pxMessageBoxEvent tevt( instdat, title, content, flags ); wxGetApp().AddPendingEvent( tevt ); instdat.WaitForMe.WaitNoCancel(); // Important! disable cancellation since we're using local stack vars. return instdat.result; } - void OnEvent( wxCommandEvent& evt ) + void OnEvent( pxMessageBoxEvent& evt ) { - // Must be called from the GUI thread ONLY. - wxASSERT( wxThread::IsMain() ); - - int result = Alert( evt.GetString() ); - InstanceData* instdat = (InstanceData*)evt.GetClientData(); - instdat->result = result; - instdat->WaitForMe.Post(); + evt.DoTheDialog(); } - bool Alert( const wxString& text ) + // Pops up an alert Dialog Box with a singular "OK" button. + // Always returns false. + bool Alert( const wxString& text, const wxString& caption, int icon ) { + icon |= wxOK; if( wxThread::IsMain() ) - wxMessageBox( text, L"Pcsx2 Message", wxOK, wxGetApp().GetTopWindow() ); + pxMessageDialog( text, caption, icon ); else - ThreadedMessageBox( wxOK, text ); + ThreadedMessageBox( text, caption, icon ); return false; } - bool OkCancel( const wxString& text ) + // Pops up a dialog box with Ok/Cancel buttons. Returns the result of the inquiry, + // true if OK, false if cancel. + bool OkCancel( const wxString& text, const wxString& caption, int icon ) { + icon |= wxOK | wxCANCEL; if( wxThread::IsMain() ) { - return wxOK == wxMessageBox( text, L"Pcsx2 Message", wxOK | wxCANCEL, wxGetApp().GetTopWindow() ); + return wxID_OK == pxMessageDialog( text, caption, icon ); } else { - return wxOK == ThreadedMessageBox( wxOK | wxCANCEL, text ); + return wxID_OK == ThreadedMessageBox( text, caption, icon ); } } + + bool YesNo( const wxString& text, const wxString& caption, int icon ) + { + icon |= wxYES_NO; + if( wxThread::IsMain() ) + { + return wxID_YES == pxMessageDialog( text, caption, icon ); + } + else + { + return wxID_YES == ThreadedMessageBox( text, caption, icon ); + } + } + + // [TODO] : This should probably be a fancier looking dialog box with the stacktrace + // displayed inside a wxTextCtrl. + static int CallStack( const wxString& errormsg, const wxString& stacktrace, const wxString& prompt, const wxString& caption, int buttons ) + { + buttons |= wxICON_STOP; + + wxString text( errormsg + L"\n\n" + stacktrace + L"\n" + prompt ); + + if( wxThread::IsMain() ) + { + return pxCallstackDialog( text, caption, buttons ); + } + else + { + return ThreadedMessageBox( text, caption, buttons, pxEVT_CallStackBox ); + } + } + + int Assertion( const wxString& text, const wxString& stacktrace ) + { + return CallStack( text, stacktrace, + L"\nDo you want to stop the program?" + L"\nOr press [Cancel] to suppress further assertions.", + L"PCSX2 Assertion Failure", + wxYES_NO | wxCANCEL + ); + } + + void Except( const Exception::BaseException& src ) + { + CallStack( src.DisplayMessage(), src.LogMessage(), wxEmptyString, L"PCSX2 Unhandled Exception", wxOK ); + } + } diff --git a/pcsx2/gui/ConsoleLogger.h b/pcsx2/gui/ConsoleLogger.h new file mode 100644 index 0000000000..f0ed1ccf5c --- /dev/null +++ b/pcsx2/gui/ConsoleLogger.h @@ -0,0 +1,158 @@ +/* Pcsx2 - Pc Ps2 Emulator + * Copyright (C) 2002-2009 Pcsx2 Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma once + + +DECLARE_EVENT_TYPE(wxEVT_DockConsole, -1); + +static const bool EnableThreadedLoggingTest = false; //true; + +using namespace Threading; + +class MainEmuFrame; +class LogWriteEvent; + + +////////////////////////////////////////////////////////////////////////////////////////// +// pxLogConsole +// This is a custom logging facility that pipes wxLog messages to our very own console +// log window. +// +class pxLogConsole : public wxLog +{ +public: + pxLogConsole() {} + +protected: + virtual void DoLog(wxLogLevel level, const wxChar *szString, time_t t); +}; + +////////////////////////////////////////////////////////////////////////////////////////// +// ConsoleThreadTest -- useful class for unit testing the thread safety and general performance +// of the console logger. +// +class ConsoleTestThread : public PersistentThread +{ +protected: + volatile bool m_done; + sptr ExecuteTask(); + +public: + ConsoleTestThread() : + m_done( false ) + { + } + + ~ConsoleTestThread() + { + m_done = true; + } +}; + + +////////////////////////////////////////////////////////////////////////////////////////// +// +class ConsoleLogFrame : public wxFrame +{ + DeclareNoncopyableObject(ConsoleLogFrame) + +public: + typedef AppConfig::ConsoleLogOptions ConLogConfig; + +protected: + class ColorArray + { + DeclareNoncopyableObject(ColorArray) + + protected: + SafeArray m_table; + wxTextAttr m_color_default; + + public: + virtual ~ColorArray(); + ColorArray( int fontsize=8 ); + + void Create( int fontsize ); + void Cleanup(); + + void SetFont( const wxFont& font ); + void SetFont( int fontsize ); + + const wxTextAttr& operator[]( Console::Colors coloridx ) const + { + return m_table[(int)coloridx]; + } + }; + +protected: + ConLogConfig m_conf; + wxTextCtrl& m_TextCtrl; + ColorArray m_ColorTable; + Console::Colors m_curcolor; + volatile long m_msgcounter; // used to track queued messages and throttle load placed on the gui message pump + + Semaphore m_semaphore; + + // Threaded log spammer, useful for testing console logging performance. + ConsoleTestThread* m_threadlogger; + +public: + // ctor & dtor + ConsoleLogFrame( MainEmuFrame *pParent, const wxString& szTitle, const ConLogConfig& options ); + virtual ~ConsoleLogFrame(); + + virtual void Write( const wxString& text ); + virtual void SetColor( Console::Colors color ); + virtual void ClearColor(); + virtual void DockedMove(); + + // Retrieves the current configuration options settings for this box. + // (settings change if the user moves the window or changes the font size) + const ConLogConfig& GetConfig() const { return m_conf; } + + void Write( Console::Colors color, const wxString& text ); + void Newline(); + void CountMessage(); + void DoMessage(); + +protected: + + // menu callbacks + virtual void OnOpen (wxMenuEvent& event); + virtual void OnClose(wxMenuEvent& event); + virtual void OnSave (wxMenuEvent& event); + virtual void OnClear(wxMenuEvent& event); + + void OnFontSize(wxMenuEvent& event); + + virtual void OnCloseWindow(wxCloseEvent& event); + + void OnWrite( wxCommandEvent& event ); + void OnNewline( wxCommandEvent& event ); + void OnSetTitle( wxCommandEvent& event ); + void OnDockedMove( wxCommandEvent& event ); + void OnSemaphoreWait( wxCommandEvent& event ); + + // common part of OnClose() and OnCloseWindow() + virtual void DoClose(); + + void OnMoveAround( wxMoveEvent& evt ); + void OnResize( wxSizeEvent& evt ); +}; + diff --git a/pcsx2/gui/main.cpp b/pcsx2/gui/main.cpp index 7240c351d1..fde0e8974f 100644 --- a/pcsx2/gui/main.cpp +++ b/pcsx2/gui/main.cpp @@ -141,6 +141,8 @@ bool Pcsx2App::OnCmdLineParsed(wxCmdLineParser& parser) return true; } +typedef void (wxEvtHandler::*pxMessageBoxEventFunction)(pxMessageBoxEvent&); + // ------------------------------------------------------------------------ bool Pcsx2App::OnInit() { @@ -150,8 +152,6 @@ bool Pcsx2App::OnInit() g_Conf = new AppConfig(); g_EmuThread = new CoreEmuThread(); - delete wxMessageOutput::Set( new wxMessageOutputDebug() ); - wxLocale::AddCatalogLookupPathPrefix( wxGetCwd() ); // User/Admin Mode Dual Setup: @@ -168,6 +168,7 @@ bool Pcsx2App::OnInit() try { ReadUserModeSettings(); + delete wxLog::SetActiveTarget( new pxLogConsole() ); AppConfig_ReloadGlobalSettings(); @@ -189,12 +190,16 @@ bool Pcsx2App::OnInit() return false; } - Connect( pxEVT_MSGBOX, wxCommandEventHandler( Pcsx2App::OnMessageBox ) ); + #define pxMessageBoxEventThing(func) \ + (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(pxMessageBoxEventFunction, &func ) + + Connect( pxEVT_MSGBOX, pxMessageBoxEventThing( Pcsx2App::OnMessageBox ) ); + Connect( pxEVT_CallStackBox,pxMessageBoxEventThing( Pcsx2App::OnMessageBox ) ); return true; } -void Pcsx2App::OnMessageBox( wxCommandEvent& evt ) +void Pcsx2App::OnMessageBox( pxMessageBoxEvent& evt ) { Msgbox::OnEvent( evt ); } diff --git a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj index 12f756936c..5a77b743ab 100644 --- a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj +++ b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj @@ -1903,7 +1903,7 @@ Name="HostGUI" > - - - - @@ -1942,10 +1934,6 @@ RelativePath="..\..\gui\IniInterface.cpp" > - - @@ -1954,10 +1942,6 @@ RelativePath="..\..\gui\MainFrame.cpp" > - - @@ -1966,10 +1950,6 @@ RelativePath="..\..\gui\wxHelpers.cpp" > - - @@ -2118,6 +2098,38 @@ > + + + + + + + + + + + + + + + +