diff --git a/common/build/Utilities/Utilities.cbp b/common/build/Utilities/Utilities.cbp index cfcfeb77ea..ed36cd0093 100644 --- a/common/build/Utilities/Utilities.cbp +++ b/common/build/Utilities/Utilities.cbp @@ -164,6 +164,7 @@ + @@ -199,6 +200,7 @@ + diff --git a/common/build/Utilities/utilities.vcproj b/common/build/Utilities/utilities.vcproj index 2b61dfcd61..993fef8fac 100644 --- a/common/build/Utilities/utilities.vcproj +++ b/common/build/Utilities/utilities.vcproj @@ -279,6 +279,10 @@ RelativePath="..\..\src\Utilities\pxTextStream.cpp" > + + @@ -461,6 +465,10 @@ RelativePath="..\..\include\Utilities\StringHelpers.h" > + + diff --git a/common/include/Utilities/Console.h b/common/include/Utilities/Console.h index c7e7f5e756..12a737c558 100644 --- a/common/include/Utilities/Console.h +++ b/common/include/Utilities/Console.h @@ -17,7 +17,6 @@ #include "StringHelpers.h" - enum ConsoleColors { Color_Current = -1, @@ -72,10 +71,12 @@ static const ConsoleColors DefaultConsoleColor = Color_Default; // struct IConsoleWriter { - // Write implementation for internal use only. - void (__concall *DoWrite)( const wxString& fmt ); + // A direct console write, without tabbing or newlines. Useful to devs who want to do quick + // logging of various junk; but should *not* be used in production code due. + void (__concall *WriteRaw)( const wxString& fmt ); - // WriteLn implementation for internal use only. + // WriteLn implementation for internal use only. Bypasses tabbing, prefixing, and other + // formatting. void (__concall *DoWriteLn)( const wxString& fmt ); // SetColor implementation for internal use only. @@ -83,11 +84,18 @@ struct IConsoleWriter // Special implementation of DoWrite that's pretty much for MSVC use only. // All implementations should map to DoWrite, except Stdio which should map to Null. + // (This avoids circular/recursive stdio output) void (__concall *DoWriteFromStdout)( const wxString& fmt ); void (__concall *Newline)(); void (__concall *SetTitle)( const wxString& title ); + // internal value for indentation of individual lines. Use the Indent() member to invoke. + int _imm_indentation; + + // For internal use only. + wxString _addIndentation( const wxString& src, int glob_indent ) const; + // ---------------------------------------------------------------------------- // Public members; call these to print stuff to console! // @@ -101,31 +109,53 @@ struct IConsoleWriter IConsoleWriter Indent( int tabcount=1 ) const; - bool Write( ConsoleColors color, const char* fmt, ... ) const; + bool FormatV( const char* fmt, va_list args ) const; bool WriteLn( ConsoleColors color, const char* fmt, ... ) const; - bool Write( const char* fmt, ... ) const; bool WriteLn( const char* fmt, ... ) const; bool Error( const char* fmt, ... ) const; bool Warning( const char* fmt, ... ) const; - bool Write( ConsoleColors color, const wxChar* fmt, ... ) const; + bool FormatV( const wxChar* fmt, va_list args ) const; bool WriteLn( ConsoleColors color, const wxChar* fmt, ... ) const; - bool Write( const wxChar* fmt, ... ) const; bool WriteLn( const wxChar* fmt, ... ) const; bool Error( const wxChar* fmt, ... ) const; bool Warning( const wxChar* fmt, ... ) const; - - bool WriteFromStdout( const char* fmt, ... ) const; - bool WriteFromStdout( ConsoleColors color, const char* fmt, ... ) const; - - // internal value for indentation of individual lines. Use the Indent() member to invoke. - int _imm_indentation; - - // For internal use only. - wxString _addIndentation( const wxString& src, int glob_indent ) const; }; -extern IConsoleWriter Console; +// -------------------------------------------------------------------------------------- +// NullConsoleWriter +// -------------------------------------------------------------------------------------- +// Used by Release builds for Debug and Devel writes (DbgCon / DevCon). Inlines to NOPs. :) +// +struct NullConsoleWriter +{ + void WriteRaw( const wxString& fmt ) {} + void DoWriteLn( const wxString& fmt ) {} + void DoSetColor( ConsoleColors color ) {} + void DoWriteFromStdout( const wxString& fmt ) {} + void Newline() {} + void SetTitle( const wxString& title ) {} + + + ConsoleColors GetColor() const { return Color_Current; } + const NullConsoleWriter& SetColor( ConsoleColors color ) const { return *this; } + const NullConsoleWriter& ClearColor() const { return *this; } + const NullConsoleWriter& SetIndent( int tabcount=1 ) const { return *this; } + + NullConsoleWriter Indent( int tabcount=1 ) const { return NullConsoleWriter(); } + + bool FormatV( const char* fmt, va_list args ) const { return false; } + bool WriteLn( ConsoleColors color, const char* fmt, ... ) const { return false; } + bool WriteLn( const char* fmt, ... ) const { return false; } + bool Error( const char* fmt, ... ) const { return false; } + bool Warning( const char* fmt, ... ) const { return false; } + + bool FormatV( const wxChar* fmt, va_list args ) const { return false; } + bool WriteLn( ConsoleColors color, const wxChar* fmt, ... ) const { return false; } + bool WriteLn( const wxChar* fmt, ... ) const { return false; } + bool Error( const wxChar* fmt, ... ) const { return false; } + bool Warning( const wxChar* fmt, ... ) const { return false; } +}; // -------------------------------------------------------------------------------------- // ConsoleIndentScope @@ -143,26 +173,16 @@ class ConsoleIndentScope DeclareNoncopyableObject( ConsoleIndentScope ); protected: - int m_amount; + int m_amount; + bool m_IsScoped; public: // Constructor: The specified number of tabs will be appended to the current indentation // setting. The tabs will be unrolled when the object leaves scope or is destroyed. - ConsoleIndentScope( int tabs=1 ) - { - Console.SetIndent( m_amount = tabs ); - } - - virtual ~ConsoleIndentScope() throw() - { - if( m_amount != 0 ) Console.SetIndent( -m_amount ); - } - - void EndScope() - { - Console.SetIndent( -m_amount ); - m_amount = 0; - } + ConsoleIndentScope( int tabs=1 ); + virtual ~ConsoleIndentScope() throw(); + void EnterScope(); + void LeaveScope(); }; // -------------------------------------------------------------------------------------- @@ -173,19 +193,15 @@ class ConsoleColorScope DeclareNoncopyableObject( ConsoleColorScope ); protected: - ConsoleColors m_old_color; + ConsoleColors m_newcolor; + ConsoleColors m_old_color; + bool m_IsScoped; public: - ConsoleColorScope( ConsoleColors newcolor ) - { - m_old_color = Console.GetColor(); - Console.SetColor( newcolor ); - } - - virtual ~ConsoleColorScope() throw() - { - Console.SetColor( m_old_color ); - } + ConsoleColorScope( ConsoleColors newcolor ); + virtual ~ConsoleColorScope() throw(); + void EnterScope(); + void LeaveScope(); }; // -------------------------------------------------------------------------------------- @@ -202,20 +218,12 @@ protected: int m_tabsize; public: - ConsoleAttrScope( ConsoleColors newcolor, int indent=0 ) - { - m_old_color = Console.GetColor(); - Console.SetIndent( m_tabsize = indent ); - Console.SetColor( newcolor ); - } - - virtual ~ConsoleAttrScope() throw() - { - Console.SetColor( m_old_color ); - Console.SetIndent( -m_tabsize ); - } + ConsoleAttrScope( ConsoleColors newcolor, int indent=0 ); + virtual ~ConsoleAttrScope() throw(); }; +extern const IConsoleWriter Console; + extern void Console_SetActiveHandler( const IConsoleWriter& writer, FILE* flushfp=NULL ); extern const wxString& ConsoleBuffer_Get(); extern void ConsoleBuffer_Clear(); @@ -227,17 +235,20 @@ extern const IConsoleWriter ConsoleWriter_Assert; extern const IConsoleWriter ConsoleWriter_Buffered; extern const IConsoleWriter ConsoleWriter_wxError; +extern const NullConsoleWriter NullCon; + +extern const IConsoleWriter DevConWriter; +extern bool DevConWriterEnabled; + #ifdef PCSX2_DEVBUILD - extern IConsoleWriter DevConWriter; -# define DevCon DevConWriter +# define DevCon DevConWriter #else -# define DevCon 0&&ConsoleWriter_Null +# define DevCon DevConWriterEnabled && DevConWriter #endif #ifdef PCSX2_DEBUG - extern IConsoleWriter DbgConWriter; -# define DbgCon DbgConWriter +extern const IConsoleWriter DbgConWriter; +# define DbgCon DbgConWriter #else -# define DbgCon 0&&ConsoleWriter_Null +# define DbgCon 0&&NullCon #endif - diff --git a/common/include/Utilities/Dependencies.h b/common/include/Utilities/Dependencies.h index 9c02942450..4106611308 100644 --- a/common/include/Utilities/Dependencies.h +++ b/common/include/Utilities/Dependencies.h @@ -16,6 +16,7 @@ #pragma once // Dependencies.h : Contains classes required by all Utilities headers. +// This file is included by most .h files provided by the Utilities class. // -------------------------------------------------------------------------------------- // Forward Declarations Section @@ -30,6 +31,12 @@ class wxSize; extern const wxSize wxDefaultSize; extern const wxPoint wxDefaultPosition; +namespace Threading +{ + class Mutex; + class Semaphore; + class pxThread; +} // This should prove useful.... #define wxsFormat wxString::Format @@ -146,21 +153,10 @@ public: } }; -////////////////////////////////////////////////////////////////////////////////////////// -// macro provided for tagging translation strings, without actually running them through the -// translator (which the _() does automatically, and sometimes we don't want that). This is -// a shorthand replacement for wxTRANSLATE. -// -#ifndef wxLt -# define wxLt(a) a -#endif - #include #include #include -#include "Pcsx2Defs.h" - #include #include // string.h under c++ #include // stdio.h under c++ @@ -168,4 +164,59 @@ public: #include #include +#include "Pcsx2Defs.h" + +// =========================================================================================== +// i18n/Translation Feature Set! +// =========================================================================================== + +extern const wxChar* __fastcall pxExpandMsg( const wxChar* key, const wxChar* englishContent ); +extern const wxChar* __fastcall pxGetTranslation( const wxChar* message ); +extern bool pxIsEnglish( int id ); + +// -------------------------------------------------------------------------------------- +// wxLt(x) [macro] +// -------------------------------------------------------------------------------------- +// macro provided for tagging translation strings, without actually running them through the +// translator (which the _() does automatically, and sometimes we don't want that). This is +// a shorthand replacement for wxTRANSLATE. +// +#ifndef wxLt +# define wxLt(a) wxT(a) +#endif + +// -------------------------------------------------------------------------------------- +// pxE(x) [macro] +// -------------------------------------------------------------------------------------- +// Translation Feature: pxE is used as a method of dereferencing very long english text +// descriptions via a "key" identifier. In this way, the english text can be revised without +// it breaking existing translation bindings. Make sure to add pxE to your PO catalog's +// source code identifiers, and then reference the source code to see what the current +// english version is. +// +// Valid prefix types: +// +// .Panel: Key-based translation of a panel or dialog text; usually either a header or +// checkbox description, by may also include some controls with long labels. +// These have the highest translation priority. +// +// .Popup: Key-based translation of a popup dialog box; either a notice, confirmation, +// or error. These typically have very high translation priority (roughly equal +// or slightly less than pxE_Panel). +// +// .Error Key-based translation of error messages, typically used when throwing exceptions +// that have end-user errors. These are normally (but not always) displayed as popups +// to the user. Translation priority is medium. +// +// .Wizard Key-based translation of a heading, checkbox item, description, or other text +// associated with the First-time wizard. Translation of these items is considered +// lower-priority to most other messages; but equal or higher priority to tooltips. +// +// .Tooltip: Key-based translation of a tooltip for a control on a dialog/panel. Translation +// of these items is typically considered "lowest priority" as they usually provide +// the most tertiary of info to the user. +// + +#define pxE(key, english) pxExpandMsg( wxT(key), english ) + #include "Utilities/Assertions.h" diff --git a/common/include/Utilities/Exceptions.h b/common/include/Utilities/Exceptions.h index 9dd7d77ce6..6d103504c1 100644 --- a/common/include/Utilities/Exceptions.h +++ b/common/include/Utilities/Exceptions.h @@ -76,7 +76,7 @@ namespace Exception wxString& DiagMsg() { return m_message_diag; } wxString& UserMsg() { return m_message_user; } - BaseException& SetBothMsgs( const char* msg_diag ); + BaseException& SetBothMsgs( const wxChar* msg_diag ); BaseException& SetDiagMsg( const wxString& msg_diag ); BaseException& SetUserMsg( const wxString& msg_user ); @@ -143,13 +143,13 @@ public: \ #define DEFINE_EXCEPTION_MESSAGES( classname ) \ public: \ - classname& SetBothMsgs( const char* msg_diag ) { BaseException::SetBothMsgs(msg_diag); return *this; } \ + classname& SetBothMsgs( const wxChar* msg_diag ) { BaseException::SetBothMsgs(msg_diag); return *this; } \ classname& SetDiagMsg( const wxString& msg_diag ) { m_message_diag = msg_diag; return *this; } \ classname& SetUserMsg( const wxString& msg_user ) { m_message_user = msg_user; return *this; } #define DEFINE_RUNTIME_EXCEPTION( classname, parent, message ) \ DEFINE_EXCEPTION_COPYTORS( classname, parent ) \ - classname() { SetDiagMsg(wxT(message)); } \ + classname() { SetDiagMsg(message); } \ DEFINE_EXCEPTION_MESSAGES( classname ) @@ -181,7 +181,7 @@ public: \ // an App message loop we'll still want it to be handled in a reasonably graceful manner. class CancelEvent : public RuntimeError { - DEFINE_RUNTIME_EXCEPTION( CancelEvent, RuntimeError, "No reason given." ) + DEFINE_RUNTIME_EXCEPTION( CancelEvent, RuntimeError, wxLt("No reason given.") ) public: explicit CancelEvent( const wxString& logmsg ) @@ -220,7 +220,7 @@ public: \ class ParseError : public RuntimeError { - DEFINE_RUNTIME_EXCEPTION( ParseError, RuntimeError, "Parse error" ); + DEFINE_RUNTIME_EXCEPTION( ParseError, RuntimeError, wxLt("Parse error") ); }; // --------------------------------------------------------------------------------------- diff --git a/common/include/Utilities/PersistentThread.h b/common/include/Utilities/PersistentThread.h index 15b4f5d9f3..7abc454549 100644 --- a/common/include/Utilities/PersistentThread.h +++ b/common/include/Utilities/PersistentThread.h @@ -99,8 +99,9 @@ namespace Threading Semaphore m_sem_event; // general wait event that's needed by most threads Semaphore m_sem_startup; // startup sync tool - Mutex m_lock_InThread; // used for canceling and closing threads in a deadlock-safe manner - MutexRecursive m_lock_start; // used to lock the Start() code from starting simultaneous threads accidentally. + Mutex m_mtx_InThread; // used for canceling and closing threads in a deadlock-safe manner + MutexRecursive m_mtx_start; // used to lock the Start() code from starting simultaneous threads accidentally. + Mutex m_mtx_ThreadName; volatile long m_detached; // a boolean value which indicates if the m_thread handle is valid volatile long m_running; // set true by Start(), and set false by Cancel(), Block(), etc. @@ -141,9 +142,11 @@ namespace Threading bool IsRunning() const; bool IsSelf() const; - wxString GetName() const; bool HasPendingException() const { return !!m_except; } + wxString GetName() const; + void SetName( const wxString& newname ); + protected: // Extending classes should always implement your own OnStart(), which is called by // Start() once necessary locks have been obtained. Do not override Start() directly diff --git a/common/include/Utilities/Threading.h b/common/include/Utilities/Threading.h index a3fa5261fa..f35a391d9f 100644 --- a/common/include/Utilities/Threading.h +++ b/common/include/Utilities/Threading.h @@ -21,12 +21,46 @@ #include "Pcsx2Defs.h" #include "ScopedPtr.h" +#include "TraceLog.h" #undef Yield // release the burden of windows.h global namespace spam. #define AffinityAssert_AllowFrom_MainUI() \ pxAssertMsg( wxThread::IsMain(), "Thread affinity violation: Call allowed from main thread only." ) +// -------------------------------------------------------------------------------------- +// pxThreadLog / ConsoleLogSource_Threading +// -------------------------------------------------------------------------------------- + +class ConsoleLogSource_Threading : ConsoleLogSource +{ + typedef ConsoleLogSource _parent; + +public: + using _parent::IsEnabled; + + ConsoleLogSource_Threading() + { + Name = L"pxThread"; + Description = wxLt("Threading activity: start, detach, sync, deletion, etc."); + } + + bool Write( const wxString& thrname, const wxChar* msg ) { + return _parent::Write( wxsFormat(L"(thread:%s) ", thrname.c_str()) + msg ); + } + bool Warn( const wxString& thrname, const wxChar* msg ) { + return _parent::Warn( wxsFormat(L"(thread:%s) ", thrname.c_str()) + msg ); + } + bool Error( const wxString& thrname, const wxChar* msg ) { + return _parent::Error( wxsFormat(L"(thread:%s) ", thrname.c_str()) + msg ); + } +}; + +extern ConsoleLogSource_Threading pxConLog_Thread; + +#define pxThreadLog pxConLog_Thread.IsEnabled() && pxConLog_Thread + + // -------------------------------------------------------------------------------------- // PCSX2_THREAD_LOCAL - Defines platform/operating system support for Thread Local Storage // -------------------------------------------------------------------------------------- @@ -104,13 +138,13 @@ namespace Exception explicit ThreadCreationError( Threading::pxThread* _thread ) { m_thread = _thread; - SetBothMsgs( "Thread creation failure. An unspecified error occurred while trying to create the %s thread." ); + SetBothMsgs( L"Thread creation failure. An unspecified error occurred while trying to create the %s thread." ); } explicit ThreadCreationError( Threading::pxThread& _thread ) { m_thread = &_thread; - SetBothMsgs( "Thread creation failure. An unspecified error occurred while trying to create the %s thread." ); + SetBothMsgs( L"Thread creation failure. An unspecified error occurred while trying to create the %s thread." ); } }; } diff --git a/common/include/Utilities/TlsVariable.inl b/common/include/Utilities/TlsVariable.inl index 3a23c3f531..8d7d271051 100644 --- a/common/include/Utilities/TlsVariable.inl +++ b/common/include/Utilities/TlsVariable.inl @@ -162,7 +162,7 @@ void Threading::BaseTlsVariable::KillKey() BaseTlsVariable::_aligned_delete_and_free( pthread_getspecific(m_thread_key) ); pthread_key_delete( m_thread_key ); - m_thread_key = NULL; + m_thread_key = 0; } template< typename T > diff --git a/common/include/Utilities/TraceLog.h b/common/include/Utilities/TraceLog.h new file mode 100644 index 0000000000..13b8096402 --- /dev/null +++ b/common/include/Utilities/TraceLog.h @@ -0,0 +1,246 @@ +/* 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 . + */ + +#pragma once + +#include "Console.h" + +#define TraceLog_ImplementBaseAPI(thistype) \ + thistype& SetDescription( const wxChar* desc ) { \ + Description = desc; \ + return *this; \ + } \ + thistype& SetName( const wxChar* name ) { \ + Name = name; \ + return *this; \ + } \ + thistype& SetShortName( const wxChar* name ) { \ + ShortName = name; \ + return *this; \ + } + +#define ConsoleLog_ImplementBaseAPI(thistype) \ + TraceLog_ImplementBaseAPI(thistype) \ + thistype& SetColor( ConsoleColors color ) { \ + DefaultColor = color; \ + return *this; \ + } + +// -------------------------------------------------------------------------------------- +// BaseTraceLog +// -------------------------------------------------------------------------------------- +class BaseTraceLogAttr +{ +public: + bool Enabled; + + // short name, alphanumerics only: used for saving/loading options. + const wxChar* ShortName; + + // Standard UI name for this log source. Used in menus, options dialogs. + const wxChar* Name; + const wxChar* Description; + +public: + TraceLog_ImplementBaseAPI(BaseTraceLogAttr) + + BaseTraceLogAttr() + { + Enabled = false; + ShortName = NULL; + } + + virtual wxString GetShortName() const { return ShortName ? ShortName : Name; } + virtual wxString GetCategory() const { return wxEmptyString; } + virtual bool IsEnabled() const { return Enabled; } + + const wxChar* GetDescription() const; +}; + +// -------------------------------------------------------------------------------------- +// TextFileTraceLog +// -------------------------------------------------------------------------------------- +// This class is tailored for performance logging to file. It does not support console +// colors or wide/unicode text conversion. +// +class TextFileTraceLog : public BaseTraceLogAttr +{ +protected: + +public: + bool Write( const char* fmt, ... ) const + { + va_list list; + va_start( list, fmt ); + WriteV( fmt, list ); + va_end( list ); + + return false; + } + + bool WriteV( const char *fmt, va_list list ) const + { + FastFormatAscii ascii; + ApplyPrefix(ascii); + ascii.WriteV( fmt, list ); + DoWrite( ascii ); + return false; + } + + virtual void ApplyPrefix( FastFormatAscii& ascii ) const {} + virtual void DoWrite( const char* fmt ) const=0; +}; + + +// -------------------------------------------------------------------------------------- +// ConsoleLogSource +// -------------------------------------------------------------------------------------- +// This class is tailored for logging to console. It applies default console color attributes +// to all writes, and supports both char and wxChar (Ascii and UF8/16) formatting. +// +class ConsoleLogSource : public BaseTraceLogAttr +{ +public: + ConsoleColors DefaultColor; + +public: + ConsoleLog_ImplementBaseAPI(ConsoleLogSource) + + ConsoleLogSource(); + + // Writes to the console using the source's default color. Note that the source's default + // color will always be used, thus ConsoleColorScope() will not be effectual unless the + // console's default color is Color_Default. + bool Write( const char* fmt, ... ) const + { + va_list list; + va_start( list, fmt ); + WriteV( fmt, list ); + va_end( list ); + + return false; + } + + bool Write( const wxChar* fmt, ... ) const + { + va_list list; + va_start( list, fmt ); + WriteV( fmt, list ); + va_end( list ); + + return false; + } + + // Writes to the console using the specified color. This overrides the default color setting + // for this log. + bool Write( ConsoleColors color, const char* fmt, ... ) const + { + va_list list; + va_start( list, fmt ); + WriteV( color, fmt, list ); + va_end( list ); + + return false; + } + + bool Write( ConsoleColors color, const wxChar* fmt, ... ) const + { + va_list list; + va_start( list, fmt ); + WriteV( color, fmt, list ); + va_end( list ); + + return false; + } + + // Writes to the console using bold yellow text -- overrides the log source's default + // color settings. + bool Warn( const wxChar* fmt, ... ) const + { + va_list list; + va_start( list, fmt ); + WriteV( Color_StrongYellow, fmt, list ); + va_end( list ); + + return false; + } + + // Writes to the console using bold red text -- overrides the log source's default + // color settings. + bool Error( const wxChar* fmt, ... ) const + { + va_list list; + va_start( list, fmt ); + WriteV( Color_StrongRed, fmt, list ); + va_end( list ); + + return false; + } + + bool WriteV( const char *fmt, va_list list ) const; + bool WriteV( const wxChar *fmt, va_list list ) const; + + bool WriteV( ConsoleColors color, const char *fmt, va_list list ) const; + bool WriteV( ConsoleColors color, const wxChar *fmt, va_list list ) const; + + virtual void DoWrite( const wxChar* msg ) const + { + Console.DoWriteLn( msg ); + } +}; + +#if 0 +// -------------------------------------------------------------------------------------- +// pxConsoleLogList +// -------------------------------------------------------------------------------------- +struct pxConsoleLogList +{ + uint count; + ConsoleLogSource* source[128]; + + void Add( ConsoleLogSource* trace ) + { + if( !pxAssertDev( count < ArraySize(source), + wxsFormat( L"Trace log initialization list is already maxed out. The tracelog for'%s' will not be enumerable.", trace->Name ) ) + ) return; + + source[count++] = trace; + } + + uint GetCount() const + { + return count; + } + + ConsoleLogSource& operator[]( uint idx ) + { + pxAssumeDev( idx < count, "SysTraceLog index is out of bounds." ); + pxAssume( source[idx] != NULL ); + + return *source[idx]; + } + + const ConsoleLogSource& operator[]( uint idx ) const + { + pxAssumeDev( idx < count, "SysTraceLog index is out of bounds." ); + pxAssume( source[idx] != NULL ); + + return *source[idx]; + } +}; + +extern pxConsoleLogList pxConLogSources_AllKnown; + +#endif diff --git a/common/include/Utilities/wxAppWithHelpers.h b/common/include/Utilities/wxAppWithHelpers.h index 6a4492aeeb..39f2c9165c 100644 --- a/common/include/Utilities/wxAppWithHelpers.h +++ b/common/include/Utilities/wxAppWithHelpers.h @@ -25,6 +25,26 @@ using namespace Threading; class pxSynchronousCommandEvent; +// -------------------------------------------------------------------------------------- +// pxAppLog / ConsoleLogSource_App +// -------------------------------------------------------------------------------------- + +class ConsoleLogSource_App : public ConsoleLogSource +{ + typedef ConsoleLogSource _parent; + +public: + ConsoleLogSource_App() + { + Name = L"App Events"; + Description = wxLt("Includes idle event processing and some other uncommon event usages."); + } +}; + +extern ConsoleLogSource_App pxConLog_App; + +#define pxAppLog pxConLog_App.IsEnabled() && pxConLog_App + // -------------------------------------------------------------------------------------- // ModalButtonPanel @@ -110,7 +130,7 @@ public: bool ProcessEvent( pxActionEvent* evt ); protected: - void IdleEventDispatcher( const wxChar* action ); + void IdleEventDispatcher( const wxChar* action=wxEmptyString ); void OnIdleEvent( wxIdleEvent& evt ); void OnStartIdleEventTimer( wxEvent& evt ); @@ -125,4 +145,5 @@ protected: namespace Msgbox { extern int ShowModal( BaseMessageBoxEvent& evt ); + extern int ShowModal( const wxString& title, const wxString& content, const MsgButtons& buttons ); } diff --git a/common/src/Utilities/CMakeLists.txt b/common/src/Utilities/CMakeLists.txt index 42525e5539..1d5860af99 100644 --- a/common/src/Utilities/CMakeLists.txt +++ b/common/src/Utilities/CMakeLists.txt @@ -114,6 +114,7 @@ set(UtilitiesSources pxRadioPanel.cpp pxStaticText.cpp pxTextStream.cpp + pxTranslate.cpp pxWindowTextWriter.cpp Semaphore.cpp StringHelpers.cpp diff --git a/common/src/Utilities/CheckedStaticBox.cpp b/common/src/Utilities/CheckedStaticBox.cpp index a6c1de3477..200360e72d 100644 --- a/common/src/Utilities/CheckedStaticBox.cpp +++ b/common/src/Utilities/CheckedStaticBox.cpp @@ -22,7 +22,7 @@ CheckedStaticBox::CheckedStaticBox( wxWindow* parent, int orientation, const wxS , ThisSizer( *new wxStaticBoxSizer( orientation, this ) ) { this += ThisToggle; - this += ThisSizer; + this += ThisSizer | pxExpand; // Ensure that the right-side of the static group box isn't too cozy: SetMinWidth( ThisToggle.GetSize().GetWidth() + 32 ); diff --git a/common/src/Utilities/Console.cpp b/common/src/Utilities/Console.cpp index 4229a2e1a7..c95a0c4e71 100644 --- a/common/src/Utilities/Console.cpp +++ b/common/src/Utilities/Console.cpp @@ -15,9 +15,10 @@ #include "PrecompiledHeader.h" #include "Threading.h" +#include "TraceLog.h" #include "TlsVariable.inl" -#include "RedtapeWindows.h" +#include "RedtapeWindows.h" // nneded for OutputDebugString using namespace Threading; @@ -41,7 +42,7 @@ static Mutex m_bufferlock; // used by ConsoleBuffer void Console_SetActiveHandler( const IConsoleWriter& writer, FILE* flushfp ) { pxAssertDev( - (writer.DoWrite != NULL) && (writer.DoWriteLn != NULL) && + (writer.WriteRaw != NULL) && (writer.DoWriteLn != NULL) && (writer.Newline != NULL) && (writer.SetTitle != NULL) && (writer.DoSetColor != NULL), "Invalid IConsoleWriter object! All function pointer interfaces must be implemented." @@ -54,14 +55,28 @@ void Console_SetActiveHandler( const IConsoleWriter& writer, FILE* flushfp ) writer.DoWriteLn( ConsoleBuffer_Get() ); } - Console = writer; + const_cast(Console)= writer; #ifdef PCSX2_DEVBUILD - DevCon = writer; + const_cast(DevCon) = writer; #endif #ifdef PCSX2_DEBUG - DbgCon = writer; + const_cast(DbgCon) = writer; +#endif +} + +// Writes text to the Visual Studio Output window (Microsoft Windows only). +// On all other platforms this pipes to Stdout instead. +void MSW_OutputDebugString( const wxString& text ) +{ +#if defined(__WXMSW__) && !defined(__WXMICROWIN__) + static bool hasDebugger = wxIsDebuggerRunning(); + if( hasDebugger ) OutputDebugString( text ); +#else + // send them to stderr + wxPrintf(L"%s\n", text.c_str()); + fflush(stderr); #endif } @@ -137,30 +152,18 @@ static __forceinline const wxChar* GetLinuxConsoleColor(ConsoleColors color) // One possible default write action at startup and shutdown is to use the stdout. static void __concall ConsoleStdout_DoWrite( const wxString& fmt ) { -#ifdef __WXMSW__ - OutputDebugString( fmt ); -#else - wxPrintf( fmt ); -#endif + MSW_OutputDebugString( fmt ); } // Default write action at startup and shutdown is to use the stdout. static void __concall ConsoleStdout_DoWriteLn( const wxString& fmt ) { -#ifdef __WXMSW__ - OutputDebugString( fmt + L"\n" ); -#else - wxPrintf( fmt + L"\n" ); -#endif + MSW_OutputDebugString( fmt + L"\n" ); } static void __concall ConsoleStdout_Newline() { -#ifdef __WXMSW__ - OutputDebugString( L"\n" ); -#else - wxPrintf( L"\n" ); -#endif + MSW_OutputDebugString( L"\n" ); } static void __concall ConsoleStdout_DoSetColor( ConsoleColors color ) @@ -174,7 +177,7 @@ static void __concall ConsoleStdout_DoSetColor( ConsoleColors color ) static void __concall ConsoleStdout_SetTitle( const wxString& title ) { #ifdef __LINUX__ - wxPrintf(L"\033]0;" + title + L"\007"); + wxPrintf(L"\033]0;%s\007", title.c_str()); #endif } @@ -295,14 +298,14 @@ const IConsoleWriter ConsoleWriter_wxError = }; // ===================================================================================================== -// IConsole Interfaces +// IConsoleWriter Implementations // ===================================================================================================== // (all non-virtual members that do common work and then pass the result through DoWrite // or DoWriteLn) // Parameters: // glob_indent - this parameter is used to specify a global indentation setting. It is used by -// WriteLn function, but defaults to 0 for Notice and Error calls. Local indentation always +// WriteLn function, but defaults to 0 for Warning and Error calls. Local indentation always // applies to all writes. wxString IConsoleWriter::_addIndentation( const wxString& src, int glob_indent=0 ) const { @@ -337,7 +340,10 @@ IConsoleWriter IConsoleWriter::Indent( int tabcount ) const // such as ErrorMsg and Notice. const IConsoleWriter& IConsoleWriter::SetColor( ConsoleColors color ) const { - pxAssertMsg( color >= Color_Current && color < ConsoleColors_Count, "Invalid ConsoleColor specified." ); + // Ignore current color requests since, well, the current color is already set. ;) + if( color == Color_Current ) return *this; + + pxAssertMsg( (color > Color_Current) && (color < ConsoleColors_Count), "Invalid ConsoleColor specified." ); if( conlog_Color != color ) DoSetColor( conlog_Color = color ); @@ -363,38 +369,17 @@ const IConsoleWriter& IConsoleWriter::ClearColor() const // ASCII/UTF8 (char*) // -------------------------------------------------------------------------------------- -bool IConsoleWriter::Write( const char* fmt, ... ) const +bool IConsoleWriter::FormatV( const char* fmt, va_list args ) const { - if( DoWrite == ConsoleNull_DoWrite ) return false; - - va_list args; - va_start(args,fmt); - DoWrite( pxsFmtV(fmt, args) ); - va_end(args); - - return false; -} - -bool IConsoleWriter::Write( ConsoleColors color, const char* fmt, ... ) const -{ - if( DoWrite == ConsoleNull_DoWrite ) return false; - - va_list args; - va_start(args,fmt); - ConsoleColorScope cs( color ); - DoWrite( pxsFmtV(fmt, args) ); - va_end(args); - + DoWriteLn( _addIndentation( pxsFmtV(fmt,args), conlog_Indent ) ); return false; } bool IConsoleWriter::WriteLn( const char* fmt, ... ) const { - if( DoWriteLn == ConsoleNull_DoWriteLn ) return false; - va_list args; va_start(args,fmt); - DoWriteLn( _addIndentation( pxsFmtV(fmt, args), conlog_Indent ) ); + FormatV(fmt, args); va_end(args); return false; @@ -402,11 +387,10 @@ bool IConsoleWriter::WriteLn( const char* fmt, ... ) const bool IConsoleWriter::WriteLn( ConsoleColors color, const char* fmt, ... ) const { - if( DoWriteLn == ConsoleNull_DoWriteLn ) return false; va_list args; va_start(args,fmt); ConsoleColorScope cs( color ); - DoWriteLn( _addIndentation( pxsFmtV(fmt, args), conlog_Indent ) ); + FormatV(fmt, args); va_end(args); return false; @@ -414,12 +398,10 @@ bool IConsoleWriter::WriteLn( ConsoleColors color, const char* fmt, ... ) const bool IConsoleWriter::Error( const char* fmt, ... ) const { - if( DoWriteLn == ConsoleNull_DoWriteLn ) return false; - va_list args; va_start(args,fmt); ConsoleColorScope cs( Color_StrongRed ); - DoWriteLn( _addIndentation( pxsFmtV(fmt, args) ) ); + FormatV(fmt, args); va_end(args); return false; @@ -427,53 +409,30 @@ bool IConsoleWriter::Error( const char* fmt, ... ) const bool IConsoleWriter::Warning( const char* fmt, ... ) const { - if( DoWriteLn == ConsoleNull_DoWriteLn ) return false; - va_list args; va_start(args,fmt); ConsoleColorScope cs( Color_StrongOrange ); - DoWriteLn( _addIndentation( pxsFmtV(fmt, args) ) ); + FormatV(fmt, args); va_end(args); return false; } // -------------------------------------------------------------------------------------- -// FmtWrite Variants - Unicode/UTF16 style +// Write Variants - Unicode/UTF16 style // -------------------------------------------------------------------------------------- -bool IConsoleWriter::Write( const wxChar* fmt, ... ) const +bool IConsoleWriter::FormatV( const wxChar* fmt, va_list args ) const { - if( DoWrite == ConsoleNull_DoWrite ) return false; - - va_list args; - va_start(args,fmt); - DoWrite( pxsFmtV( fmt, args ) ); - va_end(args); - - return false; -} - -bool IConsoleWriter::Write( ConsoleColors color, const wxChar* fmt, ... ) const -{ - if( DoWrite == ConsoleNull_DoWrite ) return false; - - va_list args; - va_start(args,fmt); - ConsoleColorScope cs( color ); - DoWrite( pxsFmtV( fmt, args ) ); - va_end(args); - + DoWriteLn( _addIndentation( pxsFmtV( fmt, args ), conlog_Indent ) ); return false; } bool IConsoleWriter::WriteLn( const wxChar* fmt, ... ) const { - if( DoWriteLn == ConsoleNull_DoWriteLn ) return false; - va_list args; va_start(args,fmt); - DoWriteLn( _addIndentation( pxsFmtV( fmt, args ), conlog_Indent ) ); + FormatV(fmt,args); va_end(args); return false; @@ -481,12 +440,10 @@ bool IConsoleWriter::WriteLn( const wxChar* fmt, ... ) const bool IConsoleWriter::WriteLn( ConsoleColors color, const wxChar* fmt, ... ) const { - if( DoWriteLn == ConsoleNull_DoWriteLn ) return false; - va_list args; va_start(args,fmt); ConsoleColorScope cs( color ); - DoWriteLn( _addIndentation( pxsFmtV( fmt, args ), conlog_Indent ) ); + FormatV(fmt,args); va_end(args); return false; @@ -494,12 +451,10 @@ bool IConsoleWriter::WriteLn( ConsoleColors color, const wxChar* fmt, ... ) cons bool IConsoleWriter::Error( const wxChar* fmt, ... ) const { - if( DoWriteLn == ConsoleNull_DoWriteLn ) return false; - va_list args; va_start(args,fmt); ConsoleColorScope cs( Color_StrongRed ); - DoWriteLn( _addIndentation( pxsFmtV( fmt, args ) ) ); + FormatV(fmt,args); va_end(args); return false; @@ -507,64 +462,156 @@ bool IConsoleWriter::Error( const wxChar* fmt, ... ) const bool IConsoleWriter::Warning( const wxChar* fmt, ... ) const { - if( DoWriteLn == ConsoleNull_DoWriteLn ) return false; - va_list args; va_start(args,fmt); ConsoleColorScope cs( Color_StrongOrange ); - DoWriteLn( _addIndentation( pxsFmtV( fmt, args ) ) ); + FormatV(fmt,args); va_end(args); return false; } // -------------------------------------------------------------------------------------- -// +// ConsoleColorScope / ConsoleIndentScope // -------------------------------------------------------------------------------------- -bool IConsoleWriter::WriteFromStdout( const char* fmt, ... ) const +ConsoleColorScope::ConsoleColorScope( ConsoleColors newcolor ) { - if( DoWriteFromStdout == ConsoleNull_DoWrite ) return false; - - va_list args; - va_start(args,fmt); - DoWrite( pxsFmtV(fmt, args) ); - va_end(args); - - return false; + m_IsScoped = false; + m_newcolor = newcolor; + EnterScope(); } -bool IConsoleWriter::WriteFromStdout( ConsoleColors color, const char* fmt, ... ) const +ConsoleColorScope::~ConsoleColorScope() throw() { - if( DoWriteFromStdout == ConsoleNull_DoWrite ) return false; + LeaveScope(); +} - va_list args; - va_start(args,fmt); - ConsoleColorScope cs( color ); - DoWriteFromStdout( pxsFmtV(fmt, args) ); - va_end(args); +void ConsoleColorScope::EnterScope() +{ + if (!m_IsScoped) + { + m_old_color = Console.GetColor(); + Console.SetColor( m_newcolor ); + m_IsScoped = true; + } +} - return false; +void ConsoleColorScope::LeaveScope() +{ + m_IsScoped = m_IsScoped && (Console.SetColor( m_old_color ), false); +} + +ConsoleIndentScope::ConsoleIndentScope( int tabs ) +{ + m_IsScoped = false; + m_amount = tabs; + EnterScope(); +} + +ConsoleIndentScope::~ConsoleIndentScope() throw() +{ + LeaveScope(); +} + +void ConsoleIndentScope::EnterScope() +{ + m_IsScoped = m_IsScoped || (Console.SetIndent( m_amount ),true); +} + +void ConsoleIndentScope::LeaveScope() +{ + m_IsScoped = m_IsScoped && (Console.SetIndent( -m_amount ),false); +} + + +ConsoleAttrScope::ConsoleAttrScope( ConsoleColors newcolor, int indent ) +{ + m_old_color = Console.GetColor(); + Console.SetIndent( m_tabsize = indent ); + Console.SetColor( newcolor ); +} + +ConsoleAttrScope::~ConsoleAttrScope() throw() +{ + Console.SetColor( m_old_color ); + Console.SetIndent( -m_tabsize ); } // -------------------------------------------------------------------------------------- // Default Writer for C++ init / startup: // -------------------------------------------------------------------------------------- - +// Currently all build types default to Stdout, which is very functional on Linux but not +// always so useful on Windows (which itself lacks a proper stdout console without using +// platform specific code). Under windows Stdout will attempt to write to the IDE Debug +// console, if one is available (such as running pcsx2 via MSVC). If not available, then +// the log message will pretty much be lost into the ether. +// #define _DefaultWriter_ ConsoleWriter_Stdout -// Important! Only Assert and Null console loggers are allowed for initial console targeting. -// Other log targets rely on the static buffer and a threaded mutex lock, which are only valid -// after C++ initialization has finished. - -IConsoleWriter Console = _DefaultWriter_; - -#ifdef PCSX2_DEVBUILD - IConsoleWriter DevConWriter= _DefaultWriter_; -#endif +const IConsoleWriter Console = _DefaultWriter_; +const IConsoleWriter DevConWriter = _DefaultWriter_; +bool DevConWriterEnabled = false; #ifdef PCSX2_DEBUG - IConsoleWriter DbgConWriter= _DefaultWriter_; +const IConsoleWriter DbgConWriter = _DefaultWriter_; #endif +const NullConsoleWriter NullCon = {}; + + +// -------------------------------------------------------------------------------------- +// BaseTraceLogAttr +// -------------------------------------------------------------------------------------- + +// Returns the translated description of this trace log! +const wxChar* BaseTraceLogAttr::GetDescription() const +{ + return (Description!=NULL) ? pxGetTranslation(Description) : wxEmptyString; +} + +// -------------------------------------------------------------------------------------- +// ConsoleLogSource +// -------------------------------------------------------------------------------------- + +// Writes to the console using the specified color. This overrides the default color setting +// for this log. +bool ConsoleLogSource::WriteV( ConsoleColors color, const char *fmt, va_list list ) const +{ + ConsoleColorScope cs(color); + DoWrite( pxsFmtV(fmt,list).GetResult() ); + return false; +} + +bool ConsoleLogSource::WriteV( ConsoleColors color, const wxChar *fmt, va_list list ) const +{ + ConsoleColorScope cs(color); + DoWrite( pxsFmtV(fmt,list) ); + return false; +} + +// Writes to the console using the source's default color. Note that the source's default +// color will always be used, thus ConsoleColorScope() will not be effectual unless the +// console's default color is Color_Default. +bool ConsoleLogSource::WriteV( const char *fmt, va_list list ) const +{ + WriteV( DefaultColor, fmt, list ); + return false; +} + +bool ConsoleLogSource::WriteV( const wxChar *fmt, va_list list ) const +{ + WriteV( DefaultColor, fmt, list ); + return false; +} + +ConsoleLogSource::ConsoleLogSource() +{ + // SourceLogs are usually pretty heavy spam, so default to something + // reasonably non-intrusive: + DefaultColor = Color_Gray; + //pxConLogSources_AllKnown.Add(this); +} + +ConsoleLogSource_Threading pxConLog_Thread; diff --git a/common/src/Utilities/Exceptions.cpp b/common/src/Utilities/Exceptions.cpp index 0bef6fa3b3..4e5fa91e99 100644 --- a/common/src/Utilities/Exceptions.cpp +++ b/common/src/Utilities/Exceptions.cpp @@ -23,9 +23,9 @@ #include #endif -static wxString GetTranslation( const char* msg ) +static wxString GetTranslation( const wxChar* msg ) { - return msg ? wxGetTranslation( fromUTF8(msg) ) : wxEmptyString; + return msg ? wxGetTranslation( msg ) : wxEmptyString; } // ------------------------------------------------------------------------ @@ -97,8 +97,11 @@ void pxTrap() DEVASSERT_INLINE void pxOnAssert( const DiagnosticOrigin& origin, const wxChar* msg ) { + // Recursion guard: Allow at least one recursive call. This is useful because sometimes + // we get meaningless assertions while unwinding stack traces after exceptions have occurred. + RecursionGuard guard( s_assert_guard ); - if( guard.IsReentrant() ) { return wxTrap(); } + if (guard.Counter > 2) { return wxTrap(); } // wxWidgets doesn't come with debug builds on some Linux distros, and other distros make // it difficult to use the debug build (compilation failures). To handle these I've had to @@ -132,10 +135,10 @@ __forceinline void pxOnAssert( const DiagnosticOrigin& origin, const char* msg) BaseException::~BaseException() throw() {} -BaseException& BaseException::SetBothMsgs( const char* msg_diag ) +BaseException& BaseException::SetBothMsgs( const wxChar* msg_diag ) { m_message_user = GetTranslation( msg_diag ); - return SetDiagMsg( fromUTF8(msg_diag) ); + return SetDiagMsg( msg_diag ); } BaseException& BaseException::SetDiagMsg( const wxString& msg_diag ) diff --git a/common/src/Utilities/FastFormatString.cpp b/common/src/Utilities/FastFormatString.cpp index ca968b49a1..9b130d31a0 100644 --- a/common/src/Utilities/FastFormatString.cpp +++ b/common/src/Utilities/FastFormatString.cpp @@ -153,7 +153,7 @@ static __releaseinline void format_that_ascii_mess( SafeArray& buffer, uin // always do it manually buffer[size-1] = '\0'; - if( size >= MaxFormattedStringLength ) break; + if (size >= MaxFormattedStringLength) break; // vsnprintf() may return either -1 (traditional Unix behavior) or the // total number of characters which would have been written if the @@ -189,11 +189,11 @@ static __releaseinline void format_that_unicode_mess( SafeArray& buffer, u // total number of characters which would have been written if the // buffer were large enough (newer standards such as Unix98) - if ( len < 0 ) + if (len < 0) len = size + (size/4); len += writepos; - if ( len < size ) break; + if (len < size) break; buffer.ExactAlloc( (len + 31) * 2 ); }; diff --git a/common/src/Utilities/PrecompiledHeader.h b/common/src/Utilities/PrecompiledHeader.h index 28a7c80c32..b09fb3efd2 100644 --- a/common/src/Utilities/PrecompiledHeader.h +++ b/common/src/Utilities/PrecompiledHeader.h @@ -22,7 +22,7 @@ #include "Assertions.h" #include "MemcpyFast.h" -#include "Console.h" +#include "TraceLog.h" #include "Exceptions.h" #include "SafeArray.h" #include "General.h" diff --git a/common/src/Utilities/ThreadTools.cpp b/common/src/Utilities/ThreadTools.cpp index fe36518ef5..ec6d515bc3 100644 --- a/common/src/Utilities/ThreadTools.cpp +++ b/common/src/Utilities/ThreadTools.cpp @@ -50,13 +50,13 @@ public: } }; -static pthread_key_t curthread_key = NULL; +static pthread_key_t curthread_key = 0; static s32 total_key_count = 0; static bool tkl_destructed = false; static StaticMutex total_key_lock( tkl_destructed ); -static void make_curthread_key() +static void make_curthread_key( const pxThread* thr ) { pxAssumeDev( !tkl_destructed, "total_key_lock is destroyed; program is shutting down; cannot create new thread key." ); @@ -65,8 +65,8 @@ static void make_curthread_key() if( 0 != pthread_key_create(&curthread_key, NULL) ) { - Console.Error( "Thread key creation failed (probably out of memory >_<)" ); - curthread_key = NULL; + pxThreadLog.Error( thr->GetName(), L"Thread key creation failed (probably out of memory >_<)" ); + curthread_key = 0; } } @@ -78,10 +78,10 @@ static void unmake_curthread_key() if( --total_key_count > 0 ) return; - if( curthread_key != NULL ) + if( curthread_key ) pthread_key_delete( curthread_key ); - curthread_key = NULL; + curthread_key = 0; } void Threading::pxTestCancel() @@ -95,7 +95,7 @@ void Threading::pxTestCancel() // test if the NULL thread is the main thread. pxThread* Threading::pxGetCurrentThread() { - return (curthread_key==NULL) ? NULL : (pxThread*)pthread_getspecific( curthread_key ); + return !curthread_key ? NULL : (pxThread*)pthread_getspecific( curthread_key ); } // returns the name of the current thread, or "Unknown" if the thread is neither a pxThread @@ -139,7 +139,9 @@ bool Threading::_WaitGui_RecursionGuard( const wxChar* name ) //if( pxAssertDev( !guard.IsReentrant(), "Recursion during UI-bound threading wait object." ) ) return false; if( !guard.IsReentrant() ) return false; - Console.WriteLn( "(Thread:%s) Yield recursion in %s; opening modal dialog.", pxGetCurrentThreadName().c_str(), name ); + pxThreadLog.Write( pxGetCurrentThreadName(), + wxsFormat(L"Yield recursion in %s; opening modal dialog.", name) + ); return true; } @@ -161,7 +163,7 @@ Threading::pxThread::pxThread( const wxString& name ) m_running = false; m_native_id = 0; - m_native_handle = NULL; + m_native_handle = 0; } // This destructor performs basic "last chance" cleanup, which is a blocking join @@ -175,12 +177,13 @@ Threading::pxThread::~pxThread() throw() { try { - DbgCon.WriteLn( L"(Thread Log) Executing destructor for " + m_name ); + pxThreadLog.Write( GetName(), L"Executing default destructor!" ); if( m_running ) { - DevCon.WriteLn( L"(Thread Log) Waiting for running thread to end..."); - m_lock_InThread.Wait(); + pxThreadLog.Write( GetName(), L"Waiting for running thread to end..."); + m_mtx_InThread.Wait(); + pxThreadLog.Write( GetName(), L"Thread ended gracefully."); } Threading::Sleep( 1 ); Detach(); @@ -193,7 +196,7 @@ bool Threading::pxThread::AffinityAssert_AllowFromSelf( const DiagnosticOrigin& if( IsSelf() ) return true; if( IsDevBuild ) - pxOnAssert( origin, wxsFormat( L"Thread affinity violation: Call allowed from '%s' thread only.", m_name.c_str() ) ); + pxOnAssert( origin, wxsFormat( L"Thread affinity violation: Call allowed from '%s' thread only.", GetName().c_str() ) ); return false; } @@ -203,7 +206,7 @@ bool Threading::pxThread::AffinityAssert_DisallowFromSelf( const DiagnosticOrigi if( !IsSelf() ) return true; if( IsDevBuild ) - pxOnAssert( origin, wxsFormat( L"Thread affinity violation: Call is *not* allowed from '%s' thread.", m_name.c_str() ) ); + pxOnAssert( origin, wxsFormat( L"Thread affinity violation: Call is *not* allowed from '%s' thread.", GetName().c_str() ) ); return false; } @@ -215,9 +218,7 @@ void Threading::pxThread::FrankenMutex( Mutex& mutex ) // Our lock is bupkis, which means the previous thread probably deadlocked. // Let's create a new mutex lock to replace it. - Console.Error( - L"(Thread Log) Possible deadlock detected on restarted mutex belonging to '%s'.", m_name.c_str() - ); + pxThreadLog.Error( GetName(), L"Possible deadlock detected on restarted mutex!" ); } } @@ -230,14 +231,19 @@ void Threading::pxThread::FrankenMutex( Mutex& mutex ) void Threading::pxThread::Start() { // Prevents sudden parallel startup, and or parallel startup + cancel: - ScopedLock startlock( m_lock_start ); - if( m_running ) return; + ScopedLock startlock( m_mtx_start ); + if( m_running ) + { + pxThreadLog.Write(GetName(), L"Start() called on running thread; ignorning..."); + return; + } Detach(); // clean up previous thread handle, if one exists. OnStart(); m_except = NULL; + pxThreadLog.Write(GetName(), L"Calling pthread_create..."); if( pthread_create( &m_thread, NULL, _internal_callback, this ) != 0 ) throw Exception::ThreadCreationError( this ); @@ -259,7 +265,7 @@ void Threading::pxThread::Start() // (this could also be done using operating system specific calls, since any threaded OS has // functions that allow us to see if a thread is running or not, and to block against it even if - // it's been detached -- removing the need for m_lock_InThread and the semaphore wait above. But + // it's been detached -- removing the need for m_mtx_InThread and the semaphore wait above. But // pthreads kinda lacks that stuff, since pthread_join() has no timeout option making it im- // possible to safely block against a running thread) } @@ -282,7 +288,7 @@ bool Threading::pxThread::_basecancel() if( m_detached ) { - Console.Warning( "(Thread Warning) Ignoring attempted cancellation of detached thread." ); + pxThreadLog.Warn(GetName(), L"Ignoring attempted cancellation of detached thread."); return false; } @@ -309,13 +315,13 @@ void Threading::pxThread::Cancel( bool isBlocking ) AffinityAssert_DisallowFromSelf( pxDiagSpot ); // Prevent simultaneous startup and cancel, necessary to avoid - ScopedLock startlock( m_lock_start ); + ScopedLock startlock( m_mtx_start ); if( !_basecancel() ) return; if( isBlocking ) { - WaitOnSelf( m_lock_InThread ); + WaitOnSelf( m_mtx_InThread ); Detach(); } } @@ -325,11 +331,11 @@ bool Threading::pxThread::Cancel( const wxTimeSpan& timespan ) AffinityAssert_DisallowFromSelf( pxDiagSpot ); // Prevent simultaneous startup and cancel: - ScopedLock startlock( m_lock_start ); + ScopedLock startlock( m_mtx_start ); if( !_basecancel() ) return true; - if( !WaitOnSelf( m_lock_InThread, timespan ) ) return false; + if( !WaitOnSelf( m_mtx_InThread, timespan ) ) return false; Detach(); return true; } @@ -348,13 +354,13 @@ bool Threading::pxThread::Cancel( const wxTimeSpan& timespan ) void Threading::pxThread::Block() { AffinityAssert_DisallowFromSelf(pxDiagSpot); - WaitOnSelf( m_lock_InThread ); + WaitOnSelf( m_mtx_InThread ); } bool Threading::pxThread::Block( const wxTimeSpan& timeout ) { AffinityAssert_DisallowFromSelf(pxDiagSpot); - return WaitOnSelf( m_lock_InThread, timeout ); + return WaitOnSelf( m_mtx_InThread, timeout ); } bool Threading::pxThread::IsSelf() const @@ -409,9 +415,7 @@ void Threading::pxThread::_selfRunningTest( const wxChar* name ) const { if( HasPendingException() ) { - Console.Error( L"(Thread:%s) An exception was thrown while waiting on a %s.", - GetName().c_str(), name - ); + pxThreadLog.Error( GetName(), wxsFormat(L"An exception was thrown while waiting on a %s.", name) ); RethrowException(); } @@ -578,7 +582,7 @@ void Threading::pxThread::_ThreadCleanup() { AffinityAssert_AllowFromSelf(pxDiagSpot); _try_virtual_invoke( &pxThread::OnCleanupInThread ); - m_lock_InThread.Release(); + m_mtx_InThread.Release(); // Must set m_running LAST, as thread destructors depend on this value (it is used // to avoid destruction of the thread until all internal data use has stopped. @@ -587,9 +591,16 @@ void Threading::pxThread::_ThreadCleanup() wxString Threading::pxThread::GetName() const { + ScopedLock lock(m_mtx_ThreadName); return m_name; } +void Threading::pxThread::SetName( const wxString& newname ) +{ + ScopedLock lock(m_mtx_ThreadName); + m_name = newname; +} + // This override is called by PeristentThread when the thread is first created, prior to // calling ExecuteTaskInThread, and after the initial InThread lock has been claimed. // This code is also executed within a "safe" environment, where the creating thread is @@ -607,11 +618,11 @@ void Threading::pxThread::OnStartInThread() void Threading::pxThread::_internal_execute() { - m_lock_InThread.Acquire(); + m_mtx_InThread.Acquire(); - _DoSetThreadName( m_name ); - make_curthread_key(); - if( curthread_key != NULL ) + _DoSetThreadName( GetName() ); + make_curthread_key(this); + if( curthread_key ) pthread_setspecific( curthread_key, this ); OnStartInThread(); @@ -624,10 +635,10 @@ void Threading::pxThread::_internal_execute() // running thread has been canceled or detached. void Threading::pxThread::OnStart() { - m_native_handle = NULL; + m_native_handle = 0; m_native_id = 0; - FrankenMutex( m_lock_InThread ); + FrankenMutex( m_mtx_InThread ); m_sem_event.Reset(); m_sem_startup.Reset(); } @@ -636,14 +647,14 @@ void Threading::pxThread::OnStart() // personal implementations. void Threading::pxThread::OnCleanupInThread() { - if( curthread_key != NULL ) + if( curthread_key ) pthread_setspecific( curthread_key, NULL ); unmake_curthread_key(); _platform_specific_OnCleanupInThread(); - m_native_handle = NULL; + m_native_handle = 0; m_native_id = 0; m_evtsrc_OnDelete.Dispatch( 0 ); diff --git a/common/src/Utilities/Windows/WinThreads.cpp b/common/src/Utilities/Windows/WinThreads.cpp index 22cdfb21d6..cb9b7e7eda 100644 --- a/common/src/Utilities/Windows/WinThreads.cpp +++ b/common/src/Utilities/Windows/WinThreads.cpp @@ -80,7 +80,7 @@ u64 Threading::GetThreadTicksPerSecond() u64 Threading::pxThread::GetCpuTime() const { - if( m_native_handle == NULL ) return 0; + if (!m_native_handle) return 0; FileTimeSucks user, kernel; FILETIME dummy; @@ -99,7 +99,7 @@ void Threading::pxThread::_platform_specific_OnStartInThread() m_native_id = (uptr)GetCurrentThreadId(); m_native_handle = (uptr)OpenThread( THREAD_QUERY_INFORMATION, false, (DWORD)m_native_id ); - pxAssertDev( m_native_handle != NULL, wxNullChar ); + pxAssertDev( m_native_handle, wxNullChar ); } void Threading::pxThread::_platform_specific_OnCleanupInThread() diff --git a/common/src/Utilities/pxTranslate.cpp b/common/src/Utilities/pxTranslate.cpp new file mode 100644 index 0000000000..80e53950af --- /dev/null +++ b/common/src/Utilities/pxTranslate.cpp @@ -0,0 +1,92 @@ +/* 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 . + */ + +#include "PrecompiledHeader.h" + +bool pxIsEnglish( int id ) +{ + return ( id == wxLANGUAGE_ENGLISH || id == wxLANGUAGE_ENGLISH_US ); +} + +// -------------------------------------------------------------------------------------- +// pxExpandMsg -- an Iconized Text Translator +// -------------------------------------------------------------------------------------- +// This function provides two layers of translated lookups. It puts the key through the +// current language first and, if the key is not resolved (meaning the language pack doesn't +// have a translation for it), it's put through our own built-in english translation. This +// second step is needed to resolve some of our lengthy UI tooltips and descriptors, which +// use iconized GetText identifiers. +// +// (without this second pass many tooltips would just show up as "Savestate Tooltip" instead +// of something meaningful). +// +// Rationale: Traditional gnu-style gnu_gettext stuff tends to stop translating strings when +// the slightest change to a string is made (including punctuation and possibly even case). +// On long strings especially, this can be unwanted since future revisions of the app may have +// simple tyop fixes that *should not* break existing translations. Furthermore +const wxChar* __fastcall pxExpandMsg( const wxChar* key, const wxChar* englishContent ) +{ +#ifdef PCSX2_DEVBUILD + static const wxChar* tbl_pxE_Prefixes[] = + { + L".Panel:", + L".Popup:", + L".Error:", + L".Wizard:", + L".Tooltip:", + NULL + }; + + // test the prefix of the key for consistency to valid/known prefix types. + const wxChar** prefix = tbl_pxE_Prefixes; + while( *prefix != NULL ) + { + if( wxString(key).StartsWith(*prefix) ) break; + ++prefix; + } + pxAssertDev( *prefix != NULL, + wxsFormat( L"Invalid pxE key prefix in key '%s'. Prefix must be one of the valid prefixes listed in pxExpandMsg.", key ) + ); +#endif + + const wxLanguageInfo* info = (wxGetLocale() != NULL) ? wxLocale::GetLanguageInfo( wxGetLocale()->GetLanguage() ) : NULL; + + if( ( info == NULL ) || pxIsEnglish( info->Language ) ) + return englishContent; + + const wxChar* retval = wxGetTranslation( key ); + + // Check if the translation failed, and fall back on an english lookup. + return ( wxStrcmp( retval, key ) == 0 ) ? englishContent : retval; +} + +// ------------------------------------------------------------------------ +// Alternative implementation for wxGetTranslation. +// This version performs a string length check in devel builds, which issues a warning +// if the string seems too long for gettext lookups. Longer complicated strings should +// usually be implemented used the pxMsgExpand system instead. +// +const wxChar* __fastcall pxGetTranslation( const wxChar* message ) +{ + if( IsDevBuild ) + { + if( wxStrlen( message ) > 128 ) + { + Console.Warning( "pxGetTranslation: Long message detected, maybe use pxE() instead?" ); + Console.WriteLn( Color_Green, L"Message: %s", message ); + } + } + return wxGetTranslation( message ); +} diff --git a/common/src/Utilities/wxAppWithHelpers.cpp b/common/src/Utilities/wxAppWithHelpers.cpp index 33924b4ca8..abd56ade62 100644 --- a/common/src/Utilities/wxAppWithHelpers.cpp +++ b/common/src/Utilities/wxAppWithHelpers.cpp @@ -28,6 +28,7 @@ DEFINE_EVENT_TYPE( pxEvt_SynchronousCommand ); IMPLEMENT_DYNAMIC_CLASS( pxSimpleEvent, wxEvent ) +ConsoleLogSource_App pxConLog_App; void BaseDeletableObject::DoDeletion() { @@ -450,6 +451,7 @@ void wxAppWithHelpers::OnSynchronousCommand( pxSynchronousCommandEvent& evt ) { AffinityAssert_AllowFrom_MainUI(); + pxAppLog.Write(L"(App) Executing command event synchronously..."); evt.SetEventType( evt.GetRealEventType() ); try { @@ -506,33 +508,41 @@ void wxAppWithHelpers::IdleEventDispatcher( const wxChar* action ) lock.Release(); if( !Threading::AllowDeletions() && (deleteMe->GetEventType() == pxEvt_DeleteThread) ) { + // Threads that have active semaphores or mutexes (other threads are waiting on them) cannot + // be deleted because those mutex/sema objects will become invalid and cause the pending + // thread to crash. So we disallow deletions when those waits are in action, and continue + // to postpone the deletion of the thread until such time that it is safe. + + pxThreadLog.Write( ((pxThread*)((wxCommandEvent*)deleteMe.GetPtr())->GetClientData())->GetName(), L"Deletion postponed due to mutex or semaphore dependency." ); postponed.push_back(deleteMe.DetachPtr()); } else { - DbgCon.WriteLn( Color_Gray, L"(AppIdleQueue:%s) -> Dispatching event '%s'", action, deleteMe->GetClassInfo()->GetClassName() ); + pxAppLog.Write( L"(AppIdleQueue%s) Dispatching event '%s'", action, deleteMe->GetClassInfo()->GetClassName() ); ProcessEvent( *deleteMe ); // dereference to prevent auto-deletion by ProcessEvent } lock.Acquire(); } m_IdleEventQueue = postponed; + if( m_IdleEventQueue.size() > 0 ) + pxAppLog.Write( L"(AppIdleQueue%s) %d events postponed due to dependencies.", action, m_IdleEventQueue.size() ); } void wxAppWithHelpers::OnIdleEvent( wxIdleEvent& evt ) { m_IdleEventTimer.Stop(); - IdleEventDispatcher( L"Idle" ); + IdleEventDispatcher(); } void wxAppWithHelpers::OnIdleEventTimeout( wxTimerEvent& evt ) { - IdleEventDispatcher( L"Timeout" ); + IdleEventDispatcher( L"[Timeout]" ); } void wxAppWithHelpers::Ping() { - DbgCon.WriteLn( Color_Gray, L"App Event Ping Requested from %s thread.", pxGetCurrentThreadName().c_str() ); + pxThreadLog.Write( pxGetCurrentThreadName().c_str(), L"App Event Ping Requested." ); SynchronousActionState sync; pxActionEvent evt( sync ); @@ -604,7 +614,7 @@ void wxAppWithHelpers::DeleteObject( BaseDeletableObject& obj ) void wxAppWithHelpers::DeleteThread( pxThread& obj ) { - //pxAssume( obj.IsBeingDeleted() ); + pxThreadLog.Write(obj.GetName(), L"Scheduling for deletion..."); wxCommandEvent evt( pxEvt_DeleteThread ); evt.SetClientData( (void*)&obj ); AddIdleEvent( evt ); @@ -648,8 +658,13 @@ void wxAppWithHelpers::OnDeleteObject( wxCommandEvent& evt ) void wxAppWithHelpers::OnDeleteThread( wxCommandEvent& evt ) { ScopedPtr thr( (pxThread*)evt.GetClientData() ); - if( !thr ) return; + if( !thr ) + { + pxThreadLog.Write( L"null", L"OnDeleteThread: NULL thread object received (and ignored)." ); + return; + } + pxThreadLog.Write(thr->GetName(), (wxString)L"Thread object deleted successfully" + (thr->HasPendingException() ? wxEmptyString : L"[exception pending!]")); thr->RethrowException(); } diff --git a/pcsx2/CDVD/CDVD.cpp b/pcsx2/CDVD/CDVD.cpp index 13330992f3..046741b07e 100644 --- a/pcsx2/CDVD/CDVD.cpp +++ b/pcsx2/CDVD/CDVD.cpp @@ -1897,14 +1897,17 @@ static void cdvdWrite16(u8 rt) // SCOMMAND break; } - Console.Write("[MG] ELF_size=0x%X Hdr_size=0x%X unk=0x%X flags=0x%X count=%d zones=", - *(u32*)&cdvd.mg_buffer[0x10], *(u16*)&cdvd.mg_buffer[0x14], *(u16*)&cdvd.mg_buffer[0x16], - *(u16*)&cdvd.mg_buffer[0x18], *(u16*)&cdvd.mg_buffer[0x1A]); + std::string zoneStr; for (i=0; i<8; i++) { - if (cdvd.mg_buffer[0x1C] & (1<blocks = (u32)((_tellfile(iso->handle) - iso->offset) / (iso->blocksize)); } + const char* isotypename = NULL; switch(iso->type) { - case ISOTYPE_CD: Console.Write("isoOpen(CD): "); break; - case ISOTYPE_DVD: Console.Write("isoOpen(DVD): "); break; - case ISOTYPE_AUDIO: Console.Write("isoOpen(Audio CD): "); break; - case ISOTYPE_DVDDL: Console.Write("isoOpen(DVDDL): "); break; + case ISOTYPE_CD: isotypename = "CD"; break; + case ISOTYPE_DVD: isotypename = "DVD"; break; + case ISOTYPE_AUDIO: isotypename = "Audio CD"; break; + case ISOTYPE_DVDDL: isotypename = "DVDDL"; break; + case ISOTYPE_ILLEGAL: - default: Console.Write("isoOpen(illegal media): "); break; + default: + isotypename = "illegal media"; + break; } - Console.WriteLn("%s ok.", iso->filename); + Console.WriteLn("isoOpen(%s): %s ok.", isotypename, iso->filename); Console.WriteLn("The iso has %u blocks (size %u).", iso->blocks, iso->blocksize); - Console.WriteLn("The isos offset is %d, and the block offset is %d.", iso->offset, iso->blockofs); + Console.WriteLn("The iso offset is %d, and the block offset is %d.", iso->offset, iso->blockofs); return iso; } isoFile *isoCreate(const char *filename, int flags) { - isoFile *iso; char Zfile[256]; - iso = (isoFile*)malloc(sizeof(isoFile)); + isoFile* iso = (isoFile*)malloc(sizeof(isoFile)); if (iso == NULL) return NULL; - memset(iso, 0, sizeof(isoFile)); + memzero(*iso); strcpy(iso->filename, filename); iso->flags = flags; diff --git a/pcsx2/Common.h b/pcsx2/Common.h index 6de39402d2..822c3879eb 100644 --- a/pcsx2/Common.h +++ b/pcsx2/Common.h @@ -29,9 +29,6 @@ static const u32 BIAS = 2; // Bus is half of the actual ps2 speed static const u32 PS2CLK = 294912000; //hz /* 294.912 mhz */ -static const ConsoleColors ConColor_IOP = Color_Yellow; -static const ConsoleColors ConColor_EE = Color_Cyan; - extern wxString ShiftJIS_ConvertString( const char* src ); extern wxString ShiftJIS_ConvertString( const char* src, int maxlen ); diff --git a/pcsx2/Config.h b/pcsx2/Config.h index a15dbea1b2..587660709d 100644 --- a/pcsx2/Config.h +++ b/pcsx2/Config.h @@ -69,66 +69,11 @@ struct TraceFiltersEE BITFIELD32() bool m_EnableAll :1, // Master Enable switch (if false, no logs at all) - - m_Bios :1, // SYSCALL, RPCs, etc. - m_Memory :1, // memory accesses (*all* loads and stores) - m_Cache :1, // Data Cache (Unimplemented) - m_SysCtrl :1, // TLB logs, PERF logs, Debug register logs - - m_VIFunpack :1, - m_GIFtag :1, - m_EnableDisasm :1, - m_R5900 :1, // instructions, branches, and exception vectors (includes COP0) - m_COP0 :1, // System Control instructions - m_COP1 :1, // EE FPU instructions - m_COP2 :1, // VU0 macro mode instructions and pipeline states - m_VU0micro :1, - m_VU1micro :1, - - m_EnableHardware:1, - m_KnownHw :1, // Known and handled HW Registers - m_UnknownHw :1, // Unknown/Unhandled Hardware Registers - m_DMA :1, // DMA Log filter, to allow for filtering HW separate of the verbose Known Registers. - - m_EnableEvents :1, // Enables logging of event-driven activity -- counters, DMAs, etc. - m_Counters :1, // EE's counters! - m_VIF :1, - m_GIF :1, - m_IPU :1, - m_SPR :1; // Scratchpad Ram DMA + m_EnableRegisters:1, + m_EnableEvents :1; // Enables logging of event-driven activity -- counters, DMAs, etc. BITFIELD_END - bool Enabled() const { return m_EnableAll; } - bool DisasmEnabled() const { return m_EnableAll && m_EnableDisasm; } - bool HwEnabled() const { return m_EnableAll && m_EnableHardware; } - bool EventsEnabled() const { return m_EnableAll && m_EnableEvents; } - - bool Bios() const { return m_EnableAll && m_Bios; } - bool Memory() const { return m_EnableAll && m_Memory; } - bool Cache() const { return m_EnableAll && m_Cache; } - bool SysCtrl() const { return m_EnableAll && m_SysCtrl; } - - bool GIFtag() const { return m_EnableAll && m_GIFtag; } - bool VIFunpack() const { return m_EnableAll && m_VIFunpack; } - - bool Counters() const { return EventsEnabled() && m_Counters; } - bool VIF() const { return EventsEnabled() && m_VIF; } - bool GIF() const { return EventsEnabled() && m_GIF; } - bool IPU() const { return EventsEnabled() && m_IPU; } - bool SPR() const { return EventsEnabled() && m_SPR; } - - bool R5900() const { return DisasmEnabled() && m_R5900; } - bool COP0() const { return DisasmEnabled() && m_COP0; } - bool COP1() const { return DisasmEnabled() && m_COP1; } - bool COP2() const { return DisasmEnabled() && m_COP2; } - bool VU0micro() const { return DisasmEnabled() && m_VU0micro; } - bool VU1micro() const { return DisasmEnabled() && m_VU1micro; } - - bool KnownHw() const { return HwEnabled() && m_KnownHw; } - bool UnknownHw() const { return HwEnabled() && m_UnknownHw; } - bool DMA() const { return HwEnabled() && m_DMA; } - TraceFiltersEE() { bitset = 0; @@ -153,53 +98,11 @@ struct TraceFiltersIOP BITFIELD32() bool m_EnableAll :1, // Master Enable switch (if false, no logs at all) - m_Bios :1, // SYSCALL, RPCs, etc. - m_Memory :1, // memory accesses (*all* loads and stores) - m_EnableDisasm :1, - m_R3000A :1, // instructions. branches, and exception vectors - m_COP2 :1, // PS1 Triangle helper (disabled in PS2 mode) - - m_EnableHardware:1, - m_KnownHw :1, // Known and handled HW Registers - m_UnknownHw :1, // Unknown/Unhandled Hardware Registers - m_DMA :1, // DMA Log filter, to allow for filtering HW separate of the verbose Known Registers. - - m_EnableEvents :1, // Enables logging of event-driven activity -- counters, DMAs, etc. - m_Counters :1, // IOP's counters! - m_Memcards :1, - m_PAD :1, - m_SPU2 :1, - m_USB :1, - m_FW :1, - m_CDVD :1, // CDROM or CDVD activity (depends on game media type) - - m_GPU :1; // PS1's GPU (currently unimplemented and uncategorized) + m_EnableRegisters:1, + m_EnableEvents :1; // Enables logging of event-driven activity -- counters, DMAs, etc. BITFIELD_END - bool Enabled() const { return m_EnableAll; } - bool DisasmEnabled() const { return m_EnableAll && m_EnableDisasm; } - bool HwEnabled() const { return m_EnableAll && m_EnableHardware; } - bool EventsEnabled() const { return m_EnableAll && m_EnableEvents; } - - bool Bios() const { return m_EnableAll && m_Bios; } - bool Memory() const { return m_EnableAll && m_Memory; } - - bool Counters() const { return EventsEnabled() && m_Counters; } - bool Memcards() const { return EventsEnabled() && m_Memcards; } - bool PAD() const { return EventsEnabled() && m_PAD; } - bool SPU2() const { return EventsEnabled() && m_SPU2; } - bool USB() const { return EventsEnabled() && m_USB; } - bool FW() const { return EventsEnabled() && m_FW; } - bool CDVD() const { return EventsEnabled() && m_CDVD; } - - bool R3000A() const { return DisasmEnabled() && m_R3000A; } - bool COP2() const { return DisasmEnabled() && m_COP2; } - - bool KnownHw() const { return HwEnabled() && m_KnownHw; } - bool UnknownHw() const { return HwEnabled() && m_UnknownHw; } - bool DMA() const { return HwEnabled() && m_DMA; } - TraceFiltersIOP() { bitset = 0; @@ -229,22 +132,19 @@ struct TraceLogFilters // so I prefer this to help keep them usable. bool Enabled; - bool SIF; // SIF DMA Activity (both EE and IOP sides) - TraceFiltersEE EE; TraceFiltersIOP IOP; TraceLogFilters() { Enabled = false; - SIF = false; } void LoadSave( IniInterface& ini ); bool operator ==( const TraceLogFilters& right ) const { - return OpEqu( Enabled ) && OpEqu( SIF ) && OpEqu( EE ) && OpEqu( IOP ); + return OpEqu( Enabled ) && OpEqu( EE ) && OpEqu( IOP ); } bool operator !=( const TraceLogFilters& right ) const @@ -253,30 +153,6 @@ struct TraceLogFilters } }; -struct ConsoleLogFilters -{ - BITFIELD32() - bool - ELF :1, - Deci2 :1, - StdoutEE :1, - StdoutIOP :1; - BITFIELD_END; - - ConsoleLogFilters(); - void LoadSave( IniInterface& ini ); - - bool operator ==( const ConsoleLogFilters& right ) const - { - return OpEqu( bitset ); - } - - bool operator !=( const ConsoleLogFilters& right ) const - { - return !this->operator ==( right ); - } -}; - // -------------------------------------------------------------------------------------- // Pcsx2Config class // -------------------------------------------------------------------------------------- @@ -540,7 +416,6 @@ struct Pcsx2Config GamefixOptions Gamefixes; ProfilerOptions Profiler; - ConsoleLogFilters Log; TraceLogFilters Trace; wxFileName BiosFilename; @@ -560,11 +435,10 @@ struct Pcsx2Config return OpEqu( bitset ) && OpEqu( Cpu ) && - OpEqu( GS ) && + OpEqu( GS ) && OpEqu( Speedhacks ) && OpEqu( Gamefixes ) && OpEqu( Profiler ) && - OpEqu( Log ) && OpEqu( Trace ) && OpEqu( BiosFilename ); } @@ -580,7 +454,6 @@ extern const Pcsx2Config EmuConfig; Pcsx2Config::GSOptions& SetGSConfig(); Pcsx2Config::RecompilerOptions& SetRecompilerConfig(); Pcsx2Config::GamefixOptions& SetGameFixConfig(); -ConsoleLogFilters& SetConsoleConfig(); TraceLogFilters& SetTraceConfig(); @@ -653,6 +526,3 @@ TraceLogFilters& SetTraceConfig(); // games. Note: currently PS1 games will error out even without this // commented, so this is for development purposes only. #define ENABLE_LOADING_PS1_GAMES 0 - -// Change to 1 to cause all logs to be written to the console. (Very slow) -#define LOG_TO_CONSOLE 0 diff --git a/pcsx2/DebugTools/Debug.h b/pcsx2/DebugTools/Debug.h index 90e82475d5..035fc9cb0b 100644 --- a/pcsx2/DebugTools/Debug.h +++ b/pcsx2/DebugTools/Debug.h @@ -15,6 +15,8 @@ #pragma once +#include "Utilities/TraceLog.h" + extern FILE *emuLog; extern wxString emuLogName; @@ -65,105 +67,299 @@ namespace R3000A extern char* disR3000AF(u32 code, u32 pc); } -#ifdef PCSX2_DEVBUILD +// Default trace log for high volume VM/System logging. +// This log dumps to emuLog.txt directly and has no ability to pipe output +// to the console (due to the console's inability to handle extremely high +// logging volume). +class SysTraceLog : public TextFileTraceLog +{ +public: + const char* PrePrefix; -extern void SourceLog( u16 protocol, u8 source, u32 cpuPc, u32 cpuCycle, const char *fmt, ...); -extern void __Log( const char* fmt, ... ); +public: + TraceLog_ImplementBaseAPI(SysTraceLog) -extern bool SrcLog_CPU( const char* fmt, ... ); -extern bool SrcLog_COP0( const char* fmt, ... ); + void DoWrite( const char *fmt ) const; -extern bool SrcLog_MEM( const char* fmt, ... ); -extern bool SrcLog_HW( const char* fmt, ... ); -extern bool SrcLog_DMA( const char* fmt, ... ); -extern bool SrcLog_BIOS( const char* fmt, ... ); -extern bool SrcLog_VU0( const char* fmt, ... ); + SysTraceLog& SetPrefix( const char* name ) + { + PrePrefix = name; + return *this; + } -extern bool SrcLog_VIF( const char* fmt, ... ); -extern bool SrcLog_VIFUNPACK( const char* fmt, ... ); -extern bool SrcLog_SPR( const char* fmt, ... ); -extern bool SrcLog_GIF( const char* fmt, ... ); -extern bool SrcLog_SIF( const char* fmt, ... ); -extern bool SrcLog_IPU( const char* fmt, ... ); -extern bool SrcLog_VUM( const char* fmt, ... ); -extern bool SrcLog_RPC( const char* fmt, ... ); -extern bool SrcLog_EECNT( const char* fmt, ... ); -extern bool SrcLog_ISOFS( const char* fmt, ... ); +}; -extern bool SrcLog_PSXCPU( const char* fmt, ... ); -extern bool SrcLog_PSXMEM( const char* fmt, ... ); -extern bool SrcLog_PSXHW( const char* fmt, ... ); -extern bool SrcLog_PSXBIOS( const char* fmt, ... ); -extern bool SrcLog_PSXDMA( const char* fmt, ... ); -extern bool SrcLog_PSXCNT( const char* fmt, ... ); +class SysTraceLog_EE : public SysTraceLog +{ +public: + void ApplyPrefix( FastFormatAscii& ascii ) const; + bool IsEnabled() const + { + return EmuConfig.Trace.Enabled && Enabled && EmuConfig.Trace.EE.m_EnableAll; + } + + wxString GetCategory() const { return L"EE"; } +}; + +class SysTraceLog_VIFcode : public SysTraceLog_EE +{ + typedef SysTraceLog_EE _parent; + +public: + void ApplyPrefix( FastFormatAscii& ascii ) const; +}; + +class SysTraceLog_EE_Disasm : public SysTraceLog_EE +{ + typedef SysTraceLog_EE _parent; + +public: + bool IsEnabled() const + { + return _parent::IsEnabled() && EmuConfig.Trace.EE.m_EnableDisasm; + } + + wxString GetCategory() const { return _parent::GetCategory() + L".Disasm"; } +}; + +class SysTraceLog_EE_Registers : public SysTraceLog_EE +{ + typedef SysTraceLog_EE _parent; + +public: + bool IsEnabled() const + { + return _parent::IsEnabled() && EmuConfig.Trace.EE.m_EnableRegisters; + } + + wxString GetCategory() const { return _parent::GetCategory() + L".Registers"; } +}; + +class SysTraceLog_EE_Events : public SysTraceLog_EE +{ + typedef SysTraceLog_EE _parent; + +public: + bool IsEnabled() const + { + return _parent::IsEnabled() && EmuConfig.Trace.EE.m_EnableEvents; + } + + wxString GetCategory() const { return _parent::GetCategory() + L".Events"; } +}; + + +class SysTraceLog_IOP : public SysTraceLog +{ +public: + void ApplyPrefix( FastFormatAscii& ascii ) const; + bool IsEnabled() const + { + return EmuConfig.Trace.Enabled && Enabled && EmuConfig.Trace.IOP.m_EnableAll; + } + + wxString GetCategory() const { return L"IOP"; } +}; + +class SysTraceLog_IOP_Disasm : public SysTraceLog_IOP +{ + typedef SysTraceLog_IOP _parent; + +public: + bool IsEnabled() const + { + return _parent::IsEnabled() && EmuConfig.Trace.IOP.m_EnableDisasm; + } + + wxString GetCategory() const { return _parent::GetCategory() + L".Disasm"; } +}; + +class SysTraceLog_IOP_Registers : public SysTraceLog_IOP +{ + typedef SysTraceLog_IOP _parent; + +public: + bool IsEnabled() const + { + return _parent::IsEnabled() && EmuConfig.Trace.IOP.m_EnableRegisters; + } + + wxString GetCategory() const { return _parent::GetCategory() + L".Registers"; } +}; + +class SysTraceLog_IOP_Events : public SysTraceLog_IOP +{ + typedef SysTraceLog_IOP _parent; + +public: + bool IsEnabled() const + { + return _parent::IsEnabled() && EmuConfig.Trace.IOP.m_EnableEvents; + } + + wxString GetCategory() const { return _parent::GetCategory() + L".Events"; } +}; + +// -------------------------------------------------------------------------------------- +// ConsoleLogFromVM +// -------------------------------------------------------------------------------------- +// Special console logger for Virtual Machine log sources, such as the EE and IOP console +// writes (actual game developer messages and such). These logs do *not* automatically +// append newlines, since the VM generates them manually. +// +class ConsoleLogFromVM : public ConsoleLogSource +{ + typedef ConsoleLogSource _parent; + +public: + ConsoleLog_ImplementBaseAPI(ConsoleLogFromVM) + using _parent::IsEnabled; + + virtual void DoWrite( const wxChar* msg ) const + { + Console.WriteRaw( msg ); + } +}; + +// -------------------------------------------------------------------------------------- +// SysTraceLogPack +// -------------------------------------------------------------------------------------- +struct SysTraceLogPack +{ + // TODO : Sif has special logging needs.. ? + SysTraceLog SIF; + + struct + { + SysTraceLog_EE Bios; + SysTraceLog_EE Memory; + SysTraceLog_EE GIFtag; + SysTraceLog_VIFcode VIFcode; + + SysTraceLog_EE_Disasm R5900; + SysTraceLog_EE_Disasm COP0; + SysTraceLog_EE_Disasm COP1; + SysTraceLog_EE_Disasm COP2; + SysTraceLog_EE_Disasm Cache; + + SysTraceLog_EE_Registers KnownHw; + SysTraceLog_EE_Registers UnknownHw; + SysTraceLog_EE_Registers DMAhw; + SysTraceLog_EE_Registers IPU; + + SysTraceLog_EE_Events DMAC; + SysTraceLog_EE_Events Counters; + SysTraceLog_EE_Events SPR; + + SysTraceLog_EE_Events VIF; + SysTraceLog_EE_Events GIF; + + } EE; + + struct + { + SysTraceLog_IOP Bios; + SysTraceLog_IOP Memcards; + SysTraceLog_IOP PAD; + + SysTraceLog_IOP_Disasm R3000A; + SysTraceLog_IOP_Disasm COP2; + SysTraceLog_IOP_Disasm Memory; + + SysTraceLog_IOP_Registers KnownHw; + SysTraceLog_IOP_Registers UnknownHw; + SysTraceLog_IOP_Registers DMAhw; + + // TODO items to be added, or removed? I can't remember which! --air + //SysTraceLog_IOP_Registers SPU2; + //SysTraceLog_IOP_Registers USB; + //SysTraceLog_IOP_Registers FW; + + SysTraceLog_IOP_Events DMAC; + SysTraceLog_IOP_Events Counters; + SysTraceLog_IOP_Events CDVD; + + } IOP; + + SysTraceLogPack(); +}; + +struct SysConsoleLogPack +{ + ConsoleLogSource ELF; + ConsoleLogSource eeRecPerf; + + ConsoleLogFromVM eeConsole; + ConsoleLogFromVM iopConsole; + ConsoleLogFromVM deci2; + + SysConsoleLogPack(); +}; + + +extern SysTraceLogPack SysTracePack; +extern SysConsoleLogPack SysConsolePack; -extern bool SrcLog_MEMCARDS( const char* fmt, ... ); -extern bool SrcLog_PAD( const char* fmt, ... ); -extern bool SrcLog_CDR( const char* fmt, ... ); -extern bool SrcLog_CDVD( const char* fmt, ... ); -extern bool SrcLog_GPU( const char* fmt, ... ); -extern bool SrcLog_CACHE( const char* fmt, ... ); // Helper macro for cut&paste. Note that we intentionally use a top-level *inline* bitcheck // against Trace.Enabled, to avoid extra overhead in Debug builds when logging is disabled. -#define macTrace EmuConfig.Trace.Enabled && EmuConfig.Trace - -#define CPU_LOG (macTrace.EE.R5900()) && SrcLog_CPU -#define MEM_LOG (macTrace.EE.Memory()) && SrcLog_MEM -#define CACHE_LOG (macTrace.EE.Cache) && SrcLog_CACHE -#define HW_LOG (macTrace.EE.KnownHw()) && SrcLog_HW -#define UnknownHW_LOG (macTrace.EE.KnownHw()) && SrcLog_HW -#define DMA_LOG (macTrace.EE.DMA()) && SrcLog_DMA - -#define BIOS_LOG (macTrace.EE.Bios()) && SrcLog_BIOS -#define VU0_LOG (macTrace.EE.VU0()) && SrcLog_VU0 -#define SysCtrl_LOG (macTrace.EE.SysCtrl()) && SrcLog_COP0 -#define COP0_LOG (macTrace.EE.COP0()) && SrcLog_COP0 -#define VIF_LOG (macTrace.EE.VIF()) && SrcLog_VIF -#define SPR_LOG (macTrace.EE.SPR()) && SrcLog_SPR -#define GIF_LOG (macTrace.EE.GIF()) && SrcLog_GIF -#define SIF_LOG (macTrace.SIF) && SrcLog_SIF -#define IPU_LOG (macTrace.EE.IPU()) && SrcLog_IPU -#define VUM_LOG (macTrace.EE.COP2()) && SrcLog_VUM - -#define EECNT_LOG (macTrace.EE.Counters()) && SrcLog_EECNT -#define VIFUNPACK_LOG (macTrace.EE.VIFunpack()) && SrcLog_VIFUNPACK +// (specifically this allows debug builds to skip havingto resolve all the parameters being +// passed into the function) +#define macTrace(trace) SysTracePack.trace.IsEnabled() && SysTracePack.trace.Write -#define PSXCPU_LOG (macTrace.IOP.R3000A()) && SrcLog_PSXCPU -#define PSXMEM_LOG (macTrace.IOP.Memory()) && SrcLog_PSXMEM -#define PSXHW_LOG (macTrace.IOP.KnownHw()) && SrcLog_PSXHW -#define PSXUnkHW_LOG (macTrace.IOP.UnknownHw()) && SrcLog_PSXHW -#define PSXBIOS_LOG (macTrace.IOP.Bios()) && SrcLog_PSXBIOS -#define PSXDMA_LOG (macTrace.IOP.DMA()) && SrcLog_PSXDMA -#define PSXCNT_LOG (macTrace.IOP.Counters()) && SrcLog_PSXCNT +#ifdef PCSX2_DEVBUILD -#define MEMCARDS_LOG (macTrace.IOP.Memcards()) && SrcLog_MEMCARDS -#define PAD_LOG (macTrace.IOP.PAD()) && SrcLog_PAD -#define GPU_LOG (macTrace.IOP.GPU()) && SrcLog_GPU -#define CDVD_LOG (macTrace.IOP.CDVD()) && SrcLog_CDVD +extern void __Log( const char* fmt, ... ); + +#define SIF_LOG macTrace(SIF) + +#define BIOS_LOG macTrace(EE.Bios) +#define CPU_LOG macTrace(EE.R5900) +#define COP0_LOG macTrace(EE.COP0) +#define VUM_LOG macTrace(EE.COP2) +#define MEM_LOG macTrace(EE.Memory) +#define CACHE_LOG macTrace(EE.Cache) +#define HW_LOG macTrace(EE.KnownHw) +#define UnknownHW_LOG macTrace(EE.UnknownHw) +#define DMA_LOG macTrace(EE.DMAhw) +#define IPU_LOG macTrace(EE.IPU) +#define VIF_LOG macTrace(EE.VIF) +#define SPR_LOG macTrace(EE.SPR) +#define GIF_LOG macTrace(EE.GIF) +#define EECNT_LOG macTrace(EE.Counters) +#define VifCodeLog macTrace(EE.VIFcode) + + +#define PSXBIOS_LOG macTrace(IOP.Bios) +#define PSXCPU_LOG macTrace(IOP.R3000A) +#define PSXMEM_LOG macTrace(IOP.Memory) +#define PSXHW_LOG macTrace(IOP.KnownHw) +#define PSXUnkHW_LOG macTrace(IOP.UnknownHw) +#define PSXDMA_LOG macTrace(IOP.DMAhw) +#define PSXCNT_LOG macTrace(IOP.Counters) +#define MEMCARDS_LOG macTrace(IOP.Memcards) +#define PAD_LOG macTrace(IOP.PAD) +#define GPU_LOG macTrace(IOP.GPU) +#define CDVD_LOG macTrace(IOP.CDVD) #else // PCSX2_DEVBUILD -#define CPU_LOG 0&& -#define MEM_LOG 0&& -#define HW_LOG 0&& -#define DMA_LOG 0&& -#define BIOS_LOG 0&& -#define FPU_LOG 0&& -#define MMI_LOG 0&& -#define VU0_LOG 0&& -#define COP0_LOG 0&& -#define SysCtrl_LOG 0&& +#define CPU_LOG 0&& +#define MEM_LOG 0&& +#define HW_LOG 0&& +#define DMA_LOG 0&& +#define BIOS_LOG 0&& +#define VU0_LOG 0&& +#define COP0_LOG 0&& #define UnknownHW_LOG 0&& -#define VIF_LOG 0&& -#define VIFUNPACK_LOG 0&& -#define SPR_LOG 0&& -#define GIF_LOG 0&& -#define SIF_LOG 0&& -#define IPU_LOG 0&& -#define VUM_LOG 0&& -#define ISOFS_LOG 0&& +#define VIF_LOG 0&& +#define SPR_LOG 0&& +#define GIF_LOG 0&& +#define SIF_LOG 0&& +#define IPU_LOG 0&& +#define VUM_LOG 0&& +#define VifCodeLog 0&& #define PSXCPU_LOG 0&& #define PSXMEM_LOG 0&& @@ -184,4 +380,8 @@ extern bool SrcLog_CACHE( const char* fmt, ... ); #define MEMCARDS_LOG 0&& #endif -#define ELF_LOG (EmuConfig.Log.ELF) && DevCon.WriteLn +#define ELF_LOG SysConsolePack.ELF.IsEnabled() && SysConsolePack.ELF.Write +#define eeRecPerfLog SysConsolePack.eeRecPerf.IsEnabled() && SysConsolePack.eeRecPerf +#define eeConLog SysConsolePack.eeConsole.IsEnabled() && SysConsolePack.eeConsole.Write +#define eeDeci2Log SysConsolePack.deci2.IsEnabled() && SysConsolePack.deci2.Write +#define iopConLog SysConsolePack.iopConsole.IsEnabled() && SysConsolePack.iopConsole.Write diff --git a/pcsx2/Elfheader.cpp b/pcsx2/Elfheader.cpp index 600af38e25..79885fb2fc 100644 --- a/pcsx2/Elfheader.cpp +++ b/pcsx2/Elfheader.cpp @@ -219,7 +219,7 @@ void ElfObject::initElfHeaders() if (machine != NULL) ELF_LOG( "machine: %s", machine ); ELF_LOG("version: %d",header.e_version); - ELF_LOG("entry: %08x",header.e_entry); + ELF_LOG("entry: %08x",header.e_entry); ELF_LOG("flags: %08x",header.e_flags); ELF_LOG("eh size: %08x",header.e_ehsize); ELF_LOG("ph off: %08x",header.e_phoff); diff --git a/pcsx2/FiFo.cpp b/pcsx2/FiFo.cpp index 79ca234fc2..3b13e1792d 100644 --- a/pcsx2/FiFo.cpp +++ b/pcsx2/FiFo.cpp @@ -194,7 +194,7 @@ void __fastcall WriteFIFO_page_7(u32 mem, const mem128_t *value) // All addresses in this page map to 0x7000 and 0x7010: mem &= 0x10; - IPU_LOG( "WriteFIFO/IPU, addr=0x%x", mem ); + IPU_LOG( "WriteFIFO, addr=0x%x", mem ); if( mem == 0 ) { @@ -203,7 +203,7 @@ void __fastcall WriteFIFO_page_7(u32 mem, const mem128_t *value) } else { - IPU_LOG("WriteFIFO IPU_in[%d] <- %8.8X_%8.8X_%8.8X_%8.8X", + IPU_LOG("WriteFIFO in[%d] <- %8.8X_%8.8X_%8.8X_%8.8X", mem/16, ((u32*)value)[3], ((u32*)value)[2], ((u32*)value)[1], ((u32*)value)[0]); //committing every 16 bytes diff --git a/pcsx2/GS.cpp b/pcsx2/GS.cpp index cc7d30e15e..27a8b1083d 100644 --- a/pcsx2/GS.cpp +++ b/pcsx2/GS.cpp @@ -116,7 +116,7 @@ static __forceinline void gsCSRwrite( const tGS_CSR& csr ) if(SIGNAL_IMR_Pending == true) { //DevCon.Warning("Firing pending signal"); - GIF_LOG("GS SIGNAL (pending) data=%x_%x IMR=%x CSRr=%x\n",SIGNAL_Data_Pending[0], SIGNAL_Data_Pending[1], GSIMR, GSCSRr); + GIF_LOG("GS SIGNAL (pending) data=%x_%x IMR=%x CSRr=%x",SIGNAL_Data_Pending[0], SIGNAL_Data_Pending[1], GSIMR, GSCSRr); GSSIGLBLID.SIGID = (GSSIGLBLID.SIGID&~SIGNAL_Data_Pending[1])|(SIGNAL_Data_Pending[0]&SIGNAL_Data_Pending[1]); if (!(GSIMR&0x100)) diff --git a/pcsx2/HwWrite.cpp b/pcsx2/HwWrite.cpp index 1ca6908e8e..71887ae5a4 100644 --- a/pcsx2/HwWrite.cpp +++ b/pcsx2/HwWrite.cpp @@ -163,10 +163,6 @@ static _f void DmaExec16( void (*func)(), u32 mem, u16 value ) ///////////////////////////////////////////////////////////////////////// // Hardware WRITE 8 bit -char sio_buffer[1024]; -int sio_count; - - void hwWrite8(u32 mem, u8 value) { if ((mem >= VIF0_STAT) && (mem < VIF0_FIFO)) { @@ -230,24 +226,30 @@ void hwWrite8(u32 mem, u8 value) //if(value & GIF_MODE_IMT) DevCon.Warning("8bit GIFMODE INT write %x", value); } break; + case SIO_TXFIFO: { - // Terminate lines on CR or full buffers, and ignore \n's if the string contents - // are empty (otherwise terminate on \n too!) - if (( value == '\r' ) || ( sio_count == 1023 ) || - ( value == '\n' && sio_count != 0 )) - { - // Use "%s" below even though it feels indirect -- it's necessary to avoid - // errors if/when games use printf formatting control chars. + static bool iggy_newline = false; + static char sio_buffer[1024]; + static int sio_count; - sio_buffer[sio_count] = 0; - Console.WriteLn( ConColor_EE, L"%s", ShiftJIS_ConvertString(sio_buffer).c_str() ); - sio_count = 0; - } - else if( value != '\n' ) + if (value == '\r') { + iggy_newline = true; + sio_buffer[sio_count++] = '\n'; + } + else if (!iggy_newline || (value != '\n')) + { + iggy_newline = false; sio_buffer[sio_count++] = value; } + + if ((sio_count == ArraySize(sio_buffer)-1) || (sio_buffer[sio_count-1] == '\n')) + { + sio_buffer[sio_count] = 0; + eeConLog( ShiftJIS_ConvertString(sio_buffer) ); + sio_count = 0; + } } break; diff --git a/pcsx2/IPU/IPU.cpp b/pcsx2/IPU/IPU.cpp index e4cc7cb339..8bc73dbc66 100644 --- a/pcsx2/IPU/IPU.cpp +++ b/pcsx2/IPU/IPU.cpp @@ -144,6 +144,81 @@ void SaveStateBase::ipuFreeze() } } +void tIPU_CMD_IDEC::log() const +{ + IPU_LOG("IDEC command."); + + if (FB) IPU_LOG(" Skip %d bits.", FB); + IPU_LOG(" Quantizer step code=0x%X.", QSC); + + if (DTD == 0) + IPU_LOG(" Does not decode DT."); + else + IPU_LOG(" Decodes DT."); + + if (SGN == 0) + IPU_LOG(" No bias."); + else + IPU_LOG(" Bias=128."); + + if (DTE == 1) IPU_LOG(" Dither Enabled."); + if (OFM == 0) + IPU_LOG(" Output format is RGB32."); + else + IPU_LOG(" Output format is RGB16."); + + IPU_LOG(""); +} + +void tIPU_CMD_BDEC::log(int s_bdec) const +{ + IPU_LOG("BDEC(macroblock decode) command %x, num: 0x%x", cpuRegs.pc, s_bdec); + if (FB) IPU_LOG(" Skip 0x%X bits.", FB); + + if (MBI) + IPU_LOG(" Intra MB."); + else + IPU_LOG(" Non-intra MB."); + + if (DCR) + IPU_LOG(" Resets DC prediction value."); + else + IPU_LOG(" Doesn't reset DC prediction value."); + + if (DT) + IPU_LOG(" Use field DCT."); + else + IPU_LOG(" Use frame DCT."); + + IPU_LOG(" Quantizer step=0x%X", QSC); +} + +void tIPU_CMD_CSC::log_from_YCbCr() const +{ + IPU_LOG("CSC(Colorspace conversion from YCbCr) command (%d).", MBC); + if (OFM) + IPU_LOG("Output format is RGB16. "); + else + IPU_LOG("Output format is RGB32. "); + + if (DTE) IPU_LOG("Dithering enabled."); +} + +void tIPU_CMD_CSC::log_from_RGB32() const +{ + IPU_LOG("PACK (Colorspace conversion from RGB32) command."); + + if (OFM) + IPU_LOG("Output format is RGB16. "); + else + IPU_LOG("Output format is INDX4. "); + + if (DTE) IPU_LOG("Dithering enabled."); + + IPU_LOG("Number of macroblocks to be converted: %d", MBC); +} + + __forceinline u32 ipuRead32(u32 mem) { // Note: It's assumed that mem's input value is always in the 0x10002000 page @@ -161,7 +236,7 @@ __forceinline u32 ipuRead32(u32 mem) ipuRegs->ctrl.CBP = coded_block_pattern; if (!ipuRegs->ctrl.BUSY) - IPU_LOG("Ipu read32: IPU_CTRL=0x%08X %x", ipuRegs->ctrl._u32, cpuRegs.pc); + IPU_LOG("read32: IPU_CTRL=0x%08X %x", ipuRegs->ctrl._u32, cpuRegs.pc); return ipuRegs->ctrl._u32; @@ -170,11 +245,11 @@ __forceinline u32 ipuRead32(u32 mem) ipuRegs->ipubp |= g_BP.IFC << 8; ipuRegs->ipubp |= (g_BP.FP /*+ g_BP.bufferhasnew*/) << 16; - IPU_LOG("Ipu read32: IPU_BP=0x%08X", ipuRegs->ipubp); + IPU_LOG("read32: IPU_BP=0x%08X", ipuRegs->ipubp); return ipuRegs->ipubp; default: - IPU_LOG("Ipu read32: Addr=0x%x Value = 0x%08X", mem, *(u32*)(((u8*)ipuRegs) + mem)); + IPU_LOG("read32: Addr=0x%x Value = 0x%08X", mem, *(u32*)(((u8*)ipuRegs) + mem)); } return *(u32*)(((u8*)ipuRegs) + mem); @@ -194,7 +269,7 @@ __forceinline u64 ipuRead64(u32 mem) { ipucase(IPU_CMD): // IPU_CMD if (ipuRegs->cmd.DATA & 0xffffff) - IPU_LOG("Ipu read64: IPU_CMD=BUSY=%x, DATA=%08X", ipuRegs->cmd.BUSY ? 1 : 0, ipuRegs->cmd.DATA); + IPU_LOG("read64: IPU_CMD=BUSY=%x, DATA=%08X", ipuRegs->cmd.BUSY ? 1 : 0, ipuRegs->cmd.DATA); break; ipucase(IPU_CTRL): @@ -206,11 +281,11 @@ __forceinline u64 ipuRead64(u32 mem) break; ipucase(IPU_TOP): // IPU_TOP - IPU_LOG("Ipu read64: IPU_TOP=%x, bp = %d", ipuRegs->top, g_BP.BP); + IPU_LOG("read64: IPU_TOP=%x, bp = %d", ipuRegs->top, g_BP.BP); break; default: - IPU_LOG("Ipu read64: Unknown=%x", mem); + IPU_LOG("read64: Unknown=%x", mem); break; } return *(u64*)(((u8*)ipuRegs) + mem); @@ -245,7 +320,7 @@ __forceinline void ipuWrite32(u32 mem, u32 value) switch (mem) { ipucase(IPU_CMD): // IPU_CMD - IPU_LOG("Ipu write32: IPU_CMD=0x%08X", value); + IPU_LOG("write32: IPU_CMD=0x%08X", value); IPUCMD_WRITE(value); break; @@ -261,11 +336,11 @@ __forceinline void ipuWrite32(u32 mem, u32 value) if (ipuRegs->ctrl.RST) ipuSoftReset(); // RESET - IPU_LOG("Ipu write32: IPU_CTRL=0x%08X", value); + IPU_LOG("write32: IPU_CTRL=0x%08X", value); break; default: - IPU_LOG("Ipu write32: Unknown=%x", mem); + IPU_LOG("write32: Unknown=%x", mem); *(u32*)((u8*)ipuRegs + mem) = value; break; } @@ -284,12 +359,12 @@ __forceinline void ipuWrite64(u32 mem, u64 value) switch (mem) { ipucase(IPU_CMD): - IPU_LOG("Ipu write64: IPU_CMD=0x%08X", value); + IPU_LOG("write64: IPU_CMD=0x%08X", value); IPUCMD_WRITE((u32)value); break; default: - IPU_LOG("Ipu write64: Unknown=%x", mem); + IPU_LOG("write64: Unknown=%x", mem); *(u64*)((u8*)ipuRegs + mem) = value; break; } @@ -318,10 +393,10 @@ static BOOL ipuIDEC(u32 val, bool resume) if (!resume) { - idec.log(); - g_BP.BP += idec.FB;//skip FB bits - //from IPU_CTRL - ipuRegs->ctrl.PCT = I_TYPE; //Intra DECoding;) + idec.log(); + g_BP.BP += idec.FB;//skip FB bits + //from IPU_CTRL + ipuRegs->ctrl.PCT = I_TYPE; //Intra DECoding;) decoder.coding_type = ipuRegs->ctrl.PCT; decoder.mpeg1 = ipuRegs->ctrl.MP1; decoder.q_scale_type = ipuRegs->ctrl.QST; @@ -329,14 +404,14 @@ static BOOL ipuIDEC(u32 val, bool resume) decoder.scantype = ipuRegs->ctrl.AS; decoder.intra_dc_precision = ipuRegs->ctrl.IDP; - //from IDEC value + //from IDEC value decoder.quantizer_scale = idec.QSC; decoder.frame_pred_frame_dct= !idec.DTD; decoder.sgn = idec.SGN; decoder.dte = idec.DTE; decoder.ofm = idec.OFM; - //other stuff + //other stuff decoder.dcr = 1; // resets DC prediction value } @@ -351,10 +426,10 @@ static __forceinline BOOL ipuBDEC(u32 val, bool resume) if (!resume) { - bdec.log(s_bdec); - if (IsDebugBuild) s_bdec++; + bdec.log(s_bdec); + if (IsDebugBuild) s_bdec++; - g_BP.BP += bdec.FB;//skip FB bits + g_BP.BP += bdec.FB;//skip FB bits decoder.coding_type = I_TYPE; decoder.mpeg1 = ipuRegs->ctrl.MP1; decoder.q_scale_type = ipuRegs->ctrl.QST; @@ -362,7 +437,7 @@ static __forceinline BOOL ipuBDEC(u32 val, bool resume) decoder.scantype = ipuRegs->ctrl.AS; decoder.intra_dc_precision = ipuRegs->ctrl.IDP; - //from BDEC value + //from BDEC value decoder.quantizer_scale = decoder.q_scale_type ? non_linear_quantizer_scale [bdec.QSC] : bdec.QSC << 1; decoder.macroblock_modes = bdec.DT ? DCT_TYPE_INTERLACED : 0; decoder.dcr = bdec.DCR; @@ -428,7 +503,7 @@ static BOOL __fastcall ipuVDEC(u32 val) BigEndian(ipuRegs->top, ipuRegs->top); - IPU_LOG("IPU VDEC command data 0x%x(0x%x). Skip 0x%X bits/Table=%d (%s), pct %d", + IPU_LOG("VDEC command data 0x%x(0x%x). Skip 0x%X bits/Table=%d (%s), pct %d", ipuRegs->cmd.DATA, ipuRegs->cmd.DATA >> 16, val & 0x3f, (val >> 26) & 3, (val >> 26) & 1 ? ((val >> 26) & 2 ? "DMV" : "MBT") : (((val >> 26) & 2 ? "MC" : "MBAI")), ipuRegs->ctrl.PCT); return TRUE; @@ -464,7 +539,7 @@ static BOOL ipuSETIQ(u32 val) if (!getBits64((u8*)niq + 8 * ipu_cmd.pos[0], 1)) return FALSE; } - IPU_LOG("Read non-intra quantization matrix from IPU FIFO."); + IPU_LOG("Read non-intra quantization matrix from FIFO."); for (i = 0; i < 8; i++) { IPU_LOG("%02X %02X %02X %02X %02X %02X %02X %02X", @@ -481,7 +556,7 @@ static BOOL ipuSETIQ(u32 val) if (!getBits64((u8*)iq + 8 * ipu_cmd.pos[0], 1)) return FALSE; } - IPU_LOG("Read intra quantization matrix from IPU FIFO."); + IPU_LOG("Read intra quantization matrix from FIFO."); for (i = 0; i < 8; i++) { IPU_LOG("%02X %02X %02X %02X %02X %02X %02X %02X", @@ -500,28 +575,28 @@ static BOOL ipuSETVQ(u32 val) if (!getBits64(((u8*)vqclut) + 8 * ipu_cmd.pos[0], 1)) return FALSE; } - IPU_LOG("IPU SETVQ command.\nRead VQCLUT table from IPU FIFO."); - IPU_LOG( - "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d " - "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d" - "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d " - "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d", - vqclut[0] >> 10, (vqclut[0] >> 5) & 0x1F, vqclut[0] & 0x1F, - vqclut[1] >> 10, (vqclut[1] >> 5) & 0x1F, vqclut[1] & 0x1F, - vqclut[2] >> 10, (vqclut[2] >> 5) & 0x1F, vqclut[2] & 0x1F, - vqclut[3] >> 10, (vqclut[3] >> 5) & 0x1F, vqclut[3] & 0x1F, - vqclut[4] >> 10, (vqclut[4] >> 5) & 0x1F, vqclut[4] & 0x1F, - vqclut[5] >> 10, (vqclut[5] >> 5) & 0x1F, vqclut[5] & 0x1F, - vqclut[6] >> 10, (vqclut[6] >> 5) & 0x1F, vqclut[6] & 0x1F, - vqclut[7] >> 10, (vqclut[7] >> 5) & 0x1F, vqclut[7] & 0x1F, - vqclut[8] >> 10, (vqclut[8] >> 5) & 0x1F, vqclut[8] & 0x1F, - vqclut[9] >> 10, (vqclut[9] >> 5) & 0x1F, vqclut[9] & 0x1F, - vqclut[10] >> 10, (vqclut[10] >> 5) & 0x1F, vqclut[10] & 0x1F, - vqclut[11] >> 10, (vqclut[11] >> 5) & 0x1F, vqclut[11] & 0x1F, - vqclut[12] >> 10, (vqclut[12] >> 5) & 0x1F, vqclut[12] & 0x1F, - vqclut[13] >> 10, (vqclut[13] >> 5) & 0x1F, vqclut[13] & 0x1F, - vqclut[14] >> 10, (vqclut[14] >> 5) & 0x1F, vqclut[14] & 0x1F, - vqclut[15] >> 10, (vqclut[15] >> 5) & 0x1F, vqclut[15] & 0x1F); + IPU_LOG("SETVQ command.\nRead VQCLUT table from FIFO."); + IPU_LOG( + "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d " + "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d" + "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d " + "%02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d %02d:%02d:%02d", + vqclut[0] >> 10, (vqclut[0] >> 5) & 0x1F, vqclut[0] & 0x1F, + vqclut[1] >> 10, (vqclut[1] >> 5) & 0x1F, vqclut[1] & 0x1F, + vqclut[2] >> 10, (vqclut[2] >> 5) & 0x1F, vqclut[2] & 0x1F, + vqclut[3] >> 10, (vqclut[3] >> 5) & 0x1F, vqclut[3] & 0x1F, + vqclut[4] >> 10, (vqclut[4] >> 5) & 0x1F, vqclut[4] & 0x1F, + vqclut[5] >> 10, (vqclut[5] >> 5) & 0x1F, vqclut[5] & 0x1F, + vqclut[6] >> 10, (vqclut[6] >> 5) & 0x1F, vqclut[6] & 0x1F, + vqclut[7] >> 10, (vqclut[7] >> 5) & 0x1F, vqclut[7] & 0x1F, + vqclut[8] >> 10, (vqclut[8] >> 5) & 0x1F, vqclut[8] & 0x1F, + vqclut[9] >> 10, (vqclut[9] >> 5) & 0x1F, vqclut[9] & 0x1F, + vqclut[10] >> 10, (vqclut[10] >> 5) & 0x1F, vqclut[10] & 0x1F, + vqclut[11] >> 10, (vqclut[11] >> 5) & 0x1F, vqclut[11] & 0x1F, + vqclut[12] >> 10, (vqclut[12] >> 5) & 0x1F, vqclut[12] & 0x1F, + vqclut[13] >> 10, (vqclut[13] >> 5) & 0x1F, vqclut[13] & 0x1F, + vqclut[14] >> 10, (vqclut[14] >> 5) & 0x1F, vqclut[14] & 0x1F, + vqclut[15] >> 10, (vqclut[15] >> 5) & 0x1F, vqclut[15] & 0x1F); return TRUE; } @@ -610,7 +685,7 @@ static void ipuSETTH(u32 val) { s_thresh[0] = (val & 0xff); s_thresh[1] = ((val >> 16) & 0xff); - IPU_LOG("IPU SETTH (Set threshold value)command %x.", val&0xff00ff); + IPU_LOG("SETTH (Set threshold value)command %x.", val&0xff00ff); } /////////////////////// @@ -650,7 +725,7 @@ void IPUCMD_WRITE(u32 val) break; case SCE_IPU_FDEC: - IPU_LOG("IPU FDEC command. Skip 0x%X bits, FIFO 0x%X qwords, BP 0x%X, FP %d, CHCR 0x%x, %x", + IPU_LOG("FDEC command. Skip 0x%X bits, FIFO 0x%X qwords, BP 0x%X, FP %d, CHCR 0x%x, %x", val & 0x3f, g_BP.IFC, (int)g_BP.BP, g_BP.FP, ipu1dma->chcr._u32, cpuRegs.pc); g_BP.BP += val & 0x3F; if (ipuFDEC(val)) return; @@ -664,7 +739,7 @@ void IPUCMD_WRITE(u32 val) return; case SCE_IPU_SETIQ: - IPU_LOG("IPU SETIQ command."); + IPU_LOG("SETIQ command."); if (val & 0x3f) IPU_LOG("Skip %d bits.", val & 0x3f); g_BP.BP += val & 0x3F; if (ipuSETIQ(val)) return; @@ -711,8 +786,8 @@ void IPUCMD_WRITE(u32 val) } else { - ipuRegs->topbusy = 0x80000000; - } + ipuRegs->topbusy = 0x80000000; + } } // have to resort to the thread @@ -1011,11 +1086,11 @@ __forceinline u8 __fastcall getBits16(u8 *address, u32 advance) mask = mask | (mask << 8); *(u16*)address = ((~mask & *(u16*)(readpos + 1)) >> (8 - shift)) | (((mask) & *(u16*)readpos) << shift); - } + } else { *(u16*)address = *(u16*)readpos; - } + } if (advance) g_BP.BP += 16; @@ -1034,14 +1109,14 @@ u8 __fastcall getBits8(u8 *address, u32 advance) readpos = readbits + (int)g_BP.BP / 8; if (uint shift = (g_BP.BP & 7)) - { + { mask = (0xff >> shift); *(u8*)address = (((~mask) & readpos[1]) >> (8 - shift)) | (((mask) & *readpos) << shift); - } + } else { *(u8*)address = *(u8*)readpos; - } + } if (advance) g_BP.BP += 8; diff --git a/pcsx2/IPU/IPU.h b/pcsx2/IPU/IPU.h index b7fb57c073..6b403f1320 100644 --- a/pcsx2/IPU/IPU.h +++ b/pcsx2/IPU/IPU.h @@ -13,8 +13,7 @@ * If not, see . */ -#ifndef __IPU_H__ -#define __IPU_H__ +#pragma once #include "IPU_Fifo.h" @@ -130,31 +129,7 @@ union tIPU_CMD_IDEC void set_flags(u32 flags) { _u32 |= flags; } void clear_flags(u32 flags) { _u32 &= ~flags; } void reset() { _u32 = 0; } - void log() - { - IPU_LOG("IPU IDEC command."); - - if (FB) IPU_LOG(" Skip %d bits.", FB); - IPU_LOG(" Quantizer step code=0x%X.", QSC); - - if (DTD == 0) - IPU_LOG(" Does not decode DT."); - else - IPU_LOG(" Decodes DT."); - - if (SGN == 0) - IPU_LOG(" No bias."); - else - IPU_LOG(" Bias=128."); - - if (DTE == 1) IPU_LOG(" Dither Enabled."); - if (OFM == 0) - IPU_LOG(" Output format is RGB32."); - else - IPU_LOG(" Output format is RGB16."); - - IPU_LOG(""); - } + void log() const; }; union tIPU_CMD_BDEC @@ -178,28 +153,7 @@ union tIPU_CMD_BDEC void set_flags(u32 flags) { _u32 |= flags; } void clear_flags(u32 flags) { _u32 &= ~flags; } void reset() { _u32 = 0; } - void log(int s_bdec) - { - IPU_LOG("IPU BDEC(macroblock decode) command %x, num: 0x%x", cpuRegs.pc, s_bdec); - if (FB) IPU_LOG(" Skip 0x%X bits.", FB); - - if (MBI) - IPU_LOG(" Intra MB."); - else - IPU_LOG(" Non-intra MB."); - - if (DCR) - IPU_LOG(" Resets DC prediction value."); - else - IPU_LOG(" Doesn't reset DC prediction value."); - - if (DT) - IPU_LOG(" Use field DCT."); - else - IPU_LOG(" Use frame DCT."); - - IPU_LOG(" Quantizer step=0x%X", QSC); - } + void log(int s_bdec) const; }; union tIPU_CMD_CSC @@ -220,29 +174,8 @@ union tIPU_CMD_CSC void set_flags(u32 flags) { _u32 |= flags; } void clear_flags(u32 flags) { _u32 &= ~flags; } void reset() { _u32 = 0; } - void log_from_YCbCr() - { - IPU_LOG("IPU CSC(Colorspace conversion from YCbCr) command (%d).", MBC); - if (OFM) - IPU_LOG("Output format is RGB16. "); - else - IPU_LOG("Output format is RGB32. "); - - if (DTE) IPU_LOG("Dithering enabled."); - } - void log_from_RGB32() - { - IPU_LOG("IPU PACK (Colorspace conversion from RGB32) command."); - - if (OFM) - IPU_LOG("Output format is RGB16. "); - else - IPU_LOG("Output format is INDX4. "); - - if (DTE) IPU_LOG("Dithering enabled."); - - IPU_LOG("Number of macroblocks to be converted: %d", MBC); - } + void log_from_YCbCr() const; + void log_from_RGB32() const; }; union tIPU_DMA @@ -372,5 +305,3 @@ extern u8 __fastcall getBits32(u8 *address, u32 advance); extern u8 __fastcall getBits16(u8 *address, u32 advance); extern u8 __fastcall getBits8(u8 *address, u32 advance); - -#endif diff --git a/pcsx2/IopBios.cpp b/pcsx2/IopBios.cpp index 65adb6a508..1e9819ab36 100644 --- a/pcsx2/IopBios.cpp +++ b/pcsx2/IopBios.cpp @@ -427,7 +427,7 @@ namespace ioman { #ifdef PCSX2_DEVBUILD if (fd == 1) // stdout { - Console.Write(ConColor_IOP, L"%s", ShiftJIS_ConvertString(Ra1, a2).c_str()); + iopConLog(ShiftJIS_ConvertString(Ra1, a2)); pc = ra; v0 = a2; return 1; @@ -536,9 +536,7 @@ _start: } *ptmp = 0; - // Use "%s" even though it seems indirect: this avoids chaos if/when the IOP decides - // to feed us strings that contain percentages or other printf formatting control chars. - Console.Write( ConColor_IOP, L"%s", ShiftJIS_ConvertString(tmp).c_str(), 1023 ); + iopConLog( ShiftJIS_ConvertString(tmp, 1023) ); pc = ra; return 1; diff --git a/pcsx2/Memory.cpp b/pcsx2/Memory.cpp index 3ad4c7302f..a5bb2e097d 100644 --- a/pcsx2/Memory.cpp +++ b/pcsx2/Memory.cpp @@ -916,8 +916,8 @@ void mmap_MarkCountedRamPage( u32 paddr ) if( m_PageProtectInfo[rampage].Mode == ProtMode_Write ) return; // skip town if we're already protected. - DbgCon.WriteLn( Color_Gray, (m_PageProtectInfo[rampage].Mode == ProtMode_Manual) ? - "dyna_page_reset @ 0x%05x" : "Write-protected page @ 0x%05x", + eeRecPerfLog.Write( (m_PageProtectInfo[rampage].Mode == ProtMode_Manual) ? + "Re-protecting page @ 0x%05x" : "Protected page @ 0x%05x", paddr>>12 ); @@ -926,6 +926,8 @@ void mmap_MarkCountedRamPage( u32 paddr ) } // offset - offset of address relative to psM. +// All recompiled blocks belonging to the page are cleared, and any new blocks recompiled +// from code residing in this page will use manual protection. static __forceinline void mmap_ClearCpuBlock( uint offset ) { int rampage = offset >> 12; @@ -953,9 +955,10 @@ void mmap_PageFaultHandler::OnPageFaultEvent( const PageFaultInfo& info, bool& h // Clears all block tracking statuses, manual protection flags, and write protection. // This does not clear any recompiler blocks. It is assumed (and necessary) for the caller // to ensure the EErec is also reset in conjunction with calling this function. +// (this function is called by default from the eerecReset). void mmap_ResetBlockTracking() { - DevCon.WriteLn( "vtlb/mmap: Block Tracking reset..." ); + //DbgCon.WriteLn( "vtlb/mmap: Block Tracking reset..." ); memzero( m_PageProtectInfo ); HostSys::MemProtect( psM, Ps2MemSize::Base, Protect_ReadWrite ); } diff --git a/pcsx2/Pcsx2Config.cpp b/pcsx2/Pcsx2Config.cpp index 1c6a0f8995..7eaf2ec63f 100644 --- a/pcsx2/Pcsx2Config.cpp +++ b/pcsx2/Pcsx2Config.cpp @@ -27,8 +27,7 @@ void TraceLogFilters::LoadSave( IniInterface& ini ) ScopedIniGroup path( ini, L"TraceLog" ); IniEntry( Enabled ); - IniEntry( SIF ); - + // Retaining backwards compat of the trace log enablers isn't really important, and // doing each one by hand would be murder. So let's cheat and just save it as an int: @@ -44,25 +43,6 @@ Pcsx2Config::SpeedhackOptions::SpeedhackOptions() VUCycleSteal = 0; } -ConsoleLogFilters::ConsoleLogFilters() -{ - ELF = false; - StdoutEE = true; - StdoutIOP = true; - Deci2 = true; -} - -void ConsoleLogFilters::LoadSave( IniInterface& ini ) -{ - ConsoleLogFilters defaults; - ScopedIniGroup path( ini, L"ConsoleLog" ); - - IniBitBool( ELF ); - IniBitBool( StdoutEE ); - IniBitBool( StdoutIOP ); - IniBitBool( Deci2 ); -} - void Pcsx2Config::SpeedhackOptions::LoadSave( IniInterface& ini ) { SpeedhackOptions defaults; @@ -382,7 +362,6 @@ void Pcsx2Config::LoadSave( IniInterface& ini ) Profiler .LoadSave( ini ); Trace .LoadSave( ini ); - Log .LoadSave( ini ); ini.Flush(); } diff --git a/pcsx2/PluginManager.cpp b/pcsx2/PluginManager.cpp index 544bb7beae..446a84c6eb 100644 --- a/pcsx2/PluginManager.cpp +++ b/pcsx2/PluginManager.cpp @@ -948,7 +948,7 @@ void SysCorePlugins::Load( const wxString (&folders)[PluginId_Count] ) pxYield( 2 ); } while( ++pi, pi->shortname != NULL ); - indent.EndScope(); + indent.LeaveScope(); CDVDapi_Plugin.newDiskCB( cdvdNewDiskCB ); diff --git a/pcsx2/Plugins.h b/pcsx2/Plugins.h index 1b93631819..fd2443874b 100644 --- a/pcsx2/Plugins.h +++ b/pcsx2/Plugins.h @@ -62,7 +62,7 @@ namespace Exception class PluginError : public RuntimeError { - DEFINE_RUNTIME_EXCEPTION( PluginError, RuntimeError, "Generic plugin error") + DEFINE_RUNTIME_EXCEPTION( PluginError, RuntimeError, L"Generic plugin error") public: PluginsEnum_t PluginId; diff --git a/pcsx2/PrecompiledHeader.h b/pcsx2/PrecompiledHeader.h index f270ffa315..1684e381ef 100644 --- a/pcsx2/PrecompiledHeader.h +++ b/pcsx2/PrecompiledHeader.h @@ -36,7 +36,7 @@ // translator (which the _() does automatically, and sometimes we don't want that). This is // a shorthand replacement for wxTRANSLATE. #ifndef wxLt -# define wxLt(a) a +# define wxLt(a) wxT(a) #endif #define NOMINMAX // Disables other libs inclusion of their own min/max macros (we use std instead) diff --git a/pcsx2/R5900OpcodeImpl.cpp b/pcsx2/R5900OpcodeImpl.cpp index f688522ce8..aef661f33b 100644 --- a/pcsx2/R5900OpcodeImpl.cpp +++ b/pcsx2/R5900OpcodeImpl.cpp @@ -199,11 +199,10 @@ static int __Deci2Call(int call, u32 *addr) pdeciaddr += (d2ptr[4]+0xc) % 16; const int copylen = std::min(255, d2ptr[1]-0xc); - memcpy(deci2buffer, pdeciaddr, copylen ); + memcpy_fast(deci2buffer, pdeciaddr, copylen ); deci2buffer[copylen] = '\0'; - if( EmuConfig.Log.Deci2 ) - Console.Write( ConColor_EE, L"%s", ShiftJIS_ConvertString(deci2buffer).c_str() ); + eeConLog( ShiftJIS_ConvertString(deci2buffer) ); } ((u32*)PSM(deci2addr))[3] = 0; return 1; @@ -221,8 +220,10 @@ static int __Deci2Call(int call, u32 *addr) return 1; case 0x10://kputs - if( addr != NULL && EmuConfig.Log.Deci2 ) - Console.Write( ConColor_EE, L"%s", ShiftJIS_ConvertString((char*)PSM(*addr)).c_str() ); + if( addr != NULL ) + { + eeDeci2Log( ShiftJIS_ConvertString((char*)PSM(*addr)) ); + } return 1; } @@ -859,14 +860,16 @@ void SYSCALL() if (call == 0x7c) { if(cpuRegs.GPR.n.a0.UL[0] == 0x10) - Console.Write( ConColor_EE, L"%s", ShiftJIS_ConvertString((char*)PSM(memRead32(cpuRegs.GPR.n.a1.UL[0]))).c_str() ); + { + eeConLog( ShiftJIS_ConvertString((char*)PSM(memRead32(cpuRegs.GPR.n.a1.UL[0]))) ); + } else __Deci2Call( cpuRegs.GPR.n.a0.UL[0], (u32*)PSM(cpuRegs.GPR.n.a1.UL[0]) ); } // The only thing this code is used for is the one log message, so don't execute it if we aren't logging bios messages. #ifdef PCSX2_DEVBUILD - if (macTrace.EE.Bios() && (call == 0x77)) + if (SysTracePack.EE.Bios.IsEnabled() && (call == 0x77)) { t_sif_dma_transfer *dmat; //struct t_sif_cmd_header *hdr; diff --git a/pcsx2/Sio.cpp b/pcsx2/Sio.cpp index a1fdc99a68..17f6294fbc 100644 --- a/pcsx2/Sio.cpp +++ b/pcsx2/Sio.cpp @@ -168,13 +168,17 @@ void SIO_CommandWrite(u8 value,int way) { // MEMORY CARD COMMANDS switch (sio.mcdst) { case 1: + { sio.packetsize++; SIO_INT(); if (sio.rdwr) { sio.parp++; return; } sio.parp = 1; + + const char* log_cmdname = ""; + switch (value) { case 0x11: // RESET - PAD_LOG("RESET MEMORY CARD"); + log_cmdname = "Reset1"; sio.bufcount = 8; memset8<0xff>(sio.buf); @@ -183,17 +187,22 @@ void SIO_CommandWrite(u8 value,int way) { sio.mcdst = 99; sio2.packet.recvVal3 = 0x8c; break; + + // FIXME : Why are there two identical cases for resetting the + // memorycard(s)? there doesn't appear to be anything dealing with + // card slots here. --air case 0x12: // RESET + log_cmdname = "Reset2"; sio.bufcount = 8; memset8<0xff>(sio.buf); sio.buf[3] = sio.terminator; sio.buf[2] = '+'; sio.mcdst = 99; - sio2.packet.recvVal3 = 0x8c; - MEMCARDS_LOG("MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value); break; + case 0x81: // COMMIT + log_cmdname = "Commit"; sio.bufcount = 8; memset8<0xff>(sio.buf); sio.mcdst = 99; @@ -205,27 +214,25 @@ void SIO_CommandWrite(u8 value,int way) { sio2.packet.recvVal1 = 0x1600; // Writing else if(sio.mc_command==0x43) sio2.packet.recvVal1 = 0x1700; // Reading } - MEMCARDS_LOG("MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value); break; case 0x21: case 0x22: case 0x23: // SECTOR SET + log_cmdname = "SetSector"; sio.bufcount = 8; sio.mcdst = 99; sio.sector=0; sio.k=0; memset8<0xff>(sio.buf); sio2.packet.recvVal3 = 0x8c; sio.buf[8]=sio.terminator; sio.buf[7]='+'; - MEMCARDS_LOG("MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value); - break; - case 0x24: - MEMCARDS_LOG("MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value); - break; - case 0x25: - MEMCARDS_LOG("MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value); break; + case 0x24: break; + case 0x25: break; + case 0x26: { + log_cmdname = "GetInfo"; + const uint port = sio.GetMemcardIndex(); const uint slot = sio.activeMemcardSlot[port]; @@ -260,66 +267,84 @@ void SIO_CommandWrite(u8 value,int way) { memset8<0xff>(sio.buf); memcpy_fast(&sio.buf[2], &cmd, sizeof(cmd)); sio.buf[12]=sio.terminator; - MEMCARDS_LOG("MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value); } break; case 0x27: case 0x28: case 0xBF: + log_cmdname = "NotSure"; // FIXME !! sio.bufcount = 4; sio.mcdst = 99; sio2.packet.recvVal3 = 0x8b; memset8<0xff>(sio.buf); sio.buf[4]=sio.terminator; sio.buf[3]='+'; - MEMCARDS_LOG("MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value); break; - case 0x42: // WRITE - case 0x43: // READ - case 0x82: - if(value==0x82 && sio.lastsector==sio.sector) sio.mode = 2; - if(value==0x42) sio.mode = 0; - if(value==0x43) sio.lastsector = sio.sector; // Reading + // FIXME ? + // sio.lastsector and sio.mode are unused. + + case 0x42: // WRITE + log_cmdname = "Write"; + //sio.mode = 0; + goto __doReadWrite; + + case 0x43: // READ + log_cmdname = "Read"; + //sio.lastsector = sio.sector; // Reading + goto __doReadWrite; + + case 0x82: + log_cmdname = "Read(?)"; // FIXME !! + //if(sio.lastsector==sio.sector) sio.mode = 2; + + __doReadWrite: sio.bufcount =133; sio.mcdst = 99; memset8<0xff>(sio.buf); sio.buf[133]=sio.terminator; sio.buf[132]='+'; - MEMCARDS_LOG("MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value); - break; + break; + + case 0xf0: case 0xf1: case 0xf2: + log_cmdname = "NoClue"; // FIXME !! sio.mcdst = 99; - MEMCARDS_LOG("MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value); break; + case 0xf3: case 0xf7: + log_cmdname = "NoClueHereEither"; // FIXME !! sio.bufcount = 4; sio.mcdst = 99; memset8<0xff>(sio.buf); sio.buf[4]=sio.terminator; sio.buf[3]='+'; - MEMCARDS_LOG("MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value); break; + case 0x52: + log_cmdname = "FixMe"; // FIXME !! sio.rdwr = 1; memset8<0xff>(sio.buf); sio.buf[sio.bufcount]=sio.terminator; sio.buf[sio.bufcount-1]='+'; - MEMCARDS_LOG("MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value); break; case 0x57: + log_cmdname = "FixMe"; // FIXME !! sio.rdwr = 2; memset8<0xff>(sio.buf); sio.buf[sio.bufcount]=sio.terminator; sio.buf[sio.bufcount-1]='+'; - MEMCARDS_LOG("MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value); break; default: + log_cmdname = "Unknown"; sio.mcdst = 0; memset8<0xff>(sio.buf); sio.buf[sio.bufcount]=sio.terminator; sio.buf[sio.bufcount-1]='+'; - MEMCARDS_LOG("Unknown MC(%d) command 0x%02X", sio.GetMemcardIndex()+1, value); } - sio.mc_command=value; - return; + MEMCARDS_LOG("MC(%d) command 0x%02X [%s]", sio.GetMemcardIndex()+1, value, log_cmdname); + sio.mc_command = value; + } + return; // END CASE 1. + // FURTHER PROCESSING OF THE MEMORY CARD COMMANDS case 99: + { sio.packetsize++; sio.parp++; switch(sio.mc_command) @@ -470,7 +495,8 @@ void SIO_CommandWrite(u8 value,int way) { break; } if (sio.bufcount<=sio.parp) sio.mcdst = 0; - return; + } + return; // END CASE 99. } switch (sio.mtapst) diff --git a/pcsx2/SourceLog.cpp b/pcsx2/SourceLog.cpp index f11319d177..387ae238ef 100644 --- a/pcsx2/SourceLog.cpp +++ b/pcsx2/SourceLog.cpp @@ -13,12 +13,18 @@ * If not, see . */ +// -------------------------------------------------------------------------------------- +// Source / Tracre Logging (high volume logging facilities) +// -------------------------------------------------------------------------------------- +// This module defines functions for performing high-volume diagnostic trace logging. +// Only ASCII versions of these logging functions are provided. Translated messages are +// not supported, and typically all logs are written to disk (ASCII), thus making the +// ASCII versions the more efficient option. + #include "PrecompiledHeader.h" -#ifdef _WIN32 -#include "RDebug/deci2.h" -#else -#include +#ifndef _WIN32 +# include #endif #include @@ -34,131 +40,225 @@ using namespace R5900; FILE *emuLog; wxString emuLogName; -bool enableLogging = TRUE; -int connected=0; +SysTraceLogPack SysTracePack; +SysConsoleLogPack SysConsolePack; -#define SYNC_LOGGING +typedef void Fntype_SrcLogPrefix( FastFormatAscii& dest ); // writes text directly to the logfile, no newlines appended. void __Log( const char* fmt, ... ) { - char tmp[2024]; va_list list; - va_start(list, fmt); - // concatenate the log message after the prefix: - int length = vsprintf(tmp, fmt, list); + if( emuLog != NULL ) + { + fputs( FastFormatAscii().WriteV(fmt,list), emuLog ); + fputs( "\n", emuLog ); + fflush( emuLog ); + } + va_end( list ); - - pxAssertDev( length <= 2020, "Source log buffer overrun" ); - // fixme: should throw an exception here once we have proper exception handling implemented. - -#ifdef PCSX2_DEVBUILD - if( emuLog != NULL ) - { - fputs( tmp, emuLog ); - fputs( "\n", emuLog ); - fflush( emuLog ); - } -#if LOG_TO_CONSOLE - Console.WriteLn(tmp); -#endif -#endif } -static __forceinline void _vSourceLog( u16 protocol, u8 source, u32 cpuPc, u32 cpuCycle, const char *fmt, va_list list ) +void SysTraceLog::DoWrite( const char *msg ) const { - char tmp[2024]; + if( emuLog == NULL ) return; - int prelength = sprintf( tmp, "%c/%8.8lx %8.8lx: ", source, cpuPc, cpuCycle ); - - // concatenate the log message after the prefix: - int length = vsprintf(&tmp[prelength], fmt, list); - pxAssertDev( length <= 2020, "Source log buffer overrun" ); - // fixme: should throw an exception here once we have proper exception handling implemented. - -#ifdef PCSX2_DEVBUILD -#ifdef _WIN32 - // Send log data to the (remote?) debugger. - // (not supported yet in the wxWidgets port) - /*if (connected && logProtocol<0x10) - { - sendTTYP(logProtocol, logSource, tmp); - }*/ -#endif - - if( emuLog != NULL ) - { - fputs( tmp, emuLog ); - fputs( "\n", emuLog ); - fflush( emuLog ); - } -#if LOG_TO_CONSOLE - Console.WriteLn(tmp); -#endif -#endif + fputs( msg, emuLog ); + fputs( "\n", emuLog ); + fflush( emuLog ); } -// Note: This function automatically appends a newline character always! -// (actually it doesn't yet because too much legacy code, will fix soon!) -void SourceLog( u16 protocol, u8 source, u32 cpuPc, u32 cpuCycle, const char *fmt, ...) +void SysTraceLog_EE::ApplyPrefix( FastFormatAscii& ascii ) const { - va_list list; - va_start(list, fmt); - _vSourceLog( protocol, source, cpuPc, cpuCycle, fmt, list ); - va_end(list); + ascii.Write( "%-4s(%8.8lx %8.8lx): ", PrePrefix, cpuRegs.pc, cpuRegs.cycle ); } -// Functions with variable argument lists can't be inlined. -#define IMPLEMENT_SOURCE_LOG( unit, source, protocol ) \ - bool SrcLog_##unit( const char* fmt, ... ) \ - { \ - va_list list; \ - va_start( list, fmt ); \ - _vSourceLog( protocol, source, \ - (source == 'E') ? cpuRegs.pc : psxRegs.pc, \ - (source == 'E') ? cpuRegs.cycle : psxRegs.cycle, fmt, list ); \ - va_end( list ); \ - return false; \ - } \ +void SysTraceLog_IOP::ApplyPrefix( FastFormatAscii& ascii ) const +{ + ascii.Write( "%-4s(%8.8lx %8.8lx): ", PrePrefix, psxRegs.pc, psxRegs.cycle ); +} -IMPLEMENT_SOURCE_LOG( EECNT, 'E', 0 ) -IMPLEMENT_SOURCE_LOG( BIOS, 'E', 0 ) - -IMPLEMENT_SOURCE_LOG( CPU, 'E', 1 ) -IMPLEMENT_SOURCE_LOG( FPU, 'E', 1 ) -IMPLEMENT_SOURCE_LOG( COP0, 'E', 1 ) - -IMPLEMENT_SOURCE_LOG( MEM, 'E', 6 ) -IMPLEMENT_SOURCE_LOG( HW, 'E', 6 ) -IMPLEMENT_SOURCE_LOG( DMA, 'E', 5 ) -IMPLEMENT_SOURCE_LOG( ELF, 'E', 7 ) -IMPLEMENT_SOURCE_LOG( VU0, 'E', 2 ) -IMPLEMENT_SOURCE_LOG( VIF, 'E', 3 ) -IMPLEMENT_SOURCE_LOG( SPR, 'E', 7 ) -IMPLEMENT_SOURCE_LOG( GIF, 'E', 4 ) -IMPLEMENT_SOURCE_LOG( SIF, 'E', 9 ) -IMPLEMENT_SOURCE_LOG( IPU, 'E', 8 ) -IMPLEMENT_SOURCE_LOG( VUM, 'E', 2 ) -IMPLEMENT_SOURCE_LOG( RPC, 'E', 9 ) -IMPLEMENT_SOURCE_LOG( ISOFS, 'E', 9 ) -IMPLEMENT_SOURCE_LOG( VIFUNPACK, 'E', 7 ) - -IMPLEMENT_SOURCE_LOG( PSXCPU, 'I', 1 ) -IMPLEMENT_SOURCE_LOG( PSXMEM, 'I', 6 ) -IMPLEMENT_SOURCE_LOG( PSXHW, 'I', 2 ) -IMPLEMENT_SOURCE_LOG( PSXBIOS, 'I', 0 ) -IMPLEMENT_SOURCE_LOG( PSXDMA, 'I', 5 ) -IMPLEMENT_SOURCE_LOG( PSXCNT, 'I', 4 ) - -IMPLEMENT_SOURCE_LOG( MEMCARDS, 'I', 7 ) -IMPLEMENT_SOURCE_LOG( PAD, 'I', 7 ) -IMPLEMENT_SOURCE_LOG( GTE, 'I', 3 ) -IMPLEMENT_SOURCE_LOG( CDR, 'I', 8 ) -IMPLEMENT_SOURCE_LOG( CDVD, 'I', 8 ) -IMPLEMENT_SOURCE_LOG( CACHE, 'I', 8 ) +void SysTraceLog_VIFcode::ApplyPrefix( FastFormatAscii& ascii ) const +{ + _parent::ApplyPrefix(ascii); + ascii.Write( "vifCode_" ); +} +SysConsoleLogPack::SysConsoleLogPack() +{ + // Console Logging + + ELF.SetShortName(L"ELF") + .SetName(L"ELF") + .SetDescription(wxLt("Dumps detailed information for PS2 executables (ELFs).")); + eeRecPerf.SetShortName(L"EErecPerf") + .SetName(L"EErec Performance") + .SetDescription(wxLt("Logs manual protection, split blocks, and other things that might impact performance.")) + .SetColor(Color_Gray); + + eeConsole.SetShortName(L"EEout") + .SetName(L"EE Console") + .SetDescription(wxLt("Shows the game developer's logging text (EE processor)")) + .SetColor(Color_Cyan); + + iopConsole.SetShortName(L"IOPout") + .SetName(L"IOP Console") + .SetDescription(wxLt("Shows the game developer's logging text (IOP processor)")) + .SetColor(Color_Yellow); + + deci2.SetShortName(L"DECI2") + .SetName(L"DECI2 Console") + .SetDescription(wxLt("Shows DECI2 debugging logs (EE processor)")) + .SetColor(Color_Cyan); +} + +SysTraceLogPack::SysTraceLogPack() +{ + SIF .SetName(L"SIF (EE <-> IOP)") + .SetShortName(L"SIF") + .SetPrefix("SIF") + .SetDescription(wxLt("")); + + // EmotionEngine (EE/R5900) + + EE.Bios .SetName(L"Bios") + .SetPrefix("EE") + .SetDescription(wxLt("SYSCALL and DECI2 activity.")); + + EE.Memory .SetName(L"Memory") + .SetPrefix("eMem") + .SetDescription(wxLt("Direct memory accesses to unknown or unmapped EE memory space.")); + + EE.R5900 .SetName(L"R5900 Core") + .SetShortName(L"R5900") + .SetPrefix("eDis") + .SetDescription(wxLt("Disasm of executing core instructions (excluding COPs and CACHE).")); + + EE.COP0 .SetName(L"COP0") + .SetPrefix("eDis") + .SetDescription(wxLt("Disasm of COP0 instructions (MMU, cpu and dma status, etc).")); + + EE.COP1 .SetName(L"COP1/FPU") + .SetShortName(L"FPU") + .SetPrefix("eDis") + .SetDescription(wxLt("Disasm of the EE's floating point unit (FPU) only.")); + + EE.COP2 .SetName(L"COP2/VUmacro") + .SetShortName(L"VUmacro") + .SetPrefix("eDis") + .SetDescription(wxLt("Disasm of the EE's VU0macro co-processor instructions.")); + + EE.Cache .SetName(L"Cache") + .SetPrefix("eDis") + .SetDescription(wxLt("Execution of EE cache instructions.")); + + EE.KnownHw .SetName(L"Hardware Regs") + .SetShortName(L"HardwareRegs") + .SetPrefix("eReg") + .SetDescription(wxLt("All known hardware register accesses (very slow!); not including sub filter options below.")); + + EE.UnknownHw.SetName(L"Unknown Regs") + .SetShortName(L"UnknownRegs") + .SetPrefix("eReg") + .SetDescription(wxLt("Logs only unknown, unmapped, or unimplemented register accesses.")); + + EE.DMAhw .SetName(L"DMA Regs") + .SetShortName(L"DmaRegs") + .SetPrefix("eReg") + .SetDescription(wxLt("Logs only DMA-related registers.")); + + EE.IPU .SetName(L"IPU") + .SetPrefix("IPU") + .SetDescription(wxLt("IPU activity: hardware registers, decoding operations, DMA status, etc.")); + + EE.GIFtag .SetName(L"GIFtags") + .SetPrefix("GIF") + .SetDescription(wxLt("All GIFtag parse activity; path index, tag type, etc.")); + + EE.VIFcode .SetName(L"VIFcodes") + .SetPrefix("VIF") + .SetDescription(wxLt("All VIFcode processing; command, tag style, interrupts.")); + + EE.SPR .SetName(L"Scratchpad MFIFO") + .SetShortName(L"ScratchpadMFIFO") + .SetPrefix("SPR") + .SetDescription(wxLt("Scratchpad's MFIFO activity.")); + + EE.DMAC .SetName(L"DMA Controller") + .SetShortName(L"DmaController") + .SetPrefix("eDmaC") + .SetDescription(wxLt("Actual data transfer logs, bus right arbitration, stalls, etc.")); + + EE.Counters .SetName(L"Counters") + .SetPrefix("eCnt") + .SetDescription(wxLt("Tracks all EE counters events and some counter register activity.")); + + EE.VIF .SetName(L"VIF") + .SetPrefix("VIF") + .SetDescription(wxLt("Dumps various VIF and VIFcode processing data.")); + + EE.GIF .SetName(L"GIF") + .SetPrefix("GIF") + .SetDescription(wxLt("Dumps various GIF and GIFtag parsing data.")); + + // IOP - Input / Output Processor + + IOP.Bios .SetName(L"Bios") + .SetPrefix("IOP") + .SetDescription(wxLt("SYSCALL and IRX activity.")); + + IOP.Memory .SetName(L"Memory") + .SetPrefix("iMem") + .SetDescription(wxLt("Direct memory accesses to unknown or unmapped IOP memory space.")); + + IOP.R3000A .SetName(L"R3000A Core") + .SetShortName(L"R3000A") + .SetPrefix("iDis") + .SetDescription(wxLt("Disasm of executing core instructions (excluding COPs and CACHE).")); + + IOP.COP2 .SetName(L"COP2/GPU") + .SetShortName(L"COP2") + .SetPrefix("iDis") + .SetDescription(wxLt("Disasm of the IOP's GPU co-processor instructions.")); + + IOP.KnownHw .SetName(L"Hardware Regs") + .SetShortName(L"HardwareRegs") + .SetPrefix("iReg") + .SetDescription(wxLt("All known hardware register accesses, not including the sub-filters below.")); + + IOP.UnknownHw.SetName(L"Unknown Regs") + .SetShortName(L"UnknownRegs") + .SetPrefix("iReg") + .SetDescription(wxLt("Logs only unknown, unmapped, or unimplemented register accesses.")); + + IOP.DMAhw .SetName(L"DMA Regs") + .SetShortName(L"DmaRegs") + .SetPrefix("iReg") + .SetDescription(wxLt("Logs only DMA-related registers.")); + + IOP.Memcards.SetName(L"Memorycards") + .SetPrefix("Mcd") + .SetDescription(wxLt("Memorycard reads, writes, erases, terminators, and other processing.")); + + IOP.PAD .SetName(L"Pad") + .SetPrefix("Pad") + .SetDescription(wxLt("Gamepad activity on the SIO.")); + + IOP.DMAC .SetName(L"DMA Controller") + .SetShortName(L"DmaController") + .SetPrefix("iDmaC") + .SetDescription(wxLt("Actual DMA event processing and data transfer logs.")); + + IOP.Counters.SetName(L"Counters") + .SetPrefix("iCnt") + .SetDescription(wxLt("Tracks all IOP counters events and some counter register activity.")); + + IOP.CDVD .SetName(L"CDVD") + .SetPrefix("CDVD") + .SetDescription(wxLt("Detailed logging of CDVD hardware.")); +} diff --git a/pcsx2/System.cpp b/pcsx2/System.cpp index fbec560ad1..696d55f53c 100644 --- a/pcsx2/System.cpp +++ b/pcsx2/System.cpp @@ -90,13 +90,6 @@ Pcsx2Config::GamefixOptions& SetGameFixConfig() return const_cast(EmuConfig.Gamefixes); } -ConsoleLogFilters& SetConsoleConfig() -{ - //DbgCon.WriteLn( "Direct modification of EmuConfig.Log detected" ); - AffinityAssert_AllowFrom_MainUI(); - return const_cast(EmuConfig.Log); -} - TraceLogFilters& SetTraceConfig() { //DbgCon.WriteLn( "Direct modification of EmuConfig.TraceLog detected" ); diff --git a/pcsx2/Vif0_Dma.cpp b/pcsx2/Vif0_Dma.cpp index 71a6217389..7e76559790 100644 --- a/pcsx2/Vif0_Dma.cpp +++ b/pcsx2/Vif0_Dma.cpp @@ -100,7 +100,7 @@ __forceinline void vif0SetupTransfer() // Transfer dma tag if tte is set - VIF_LOG("vif0 Tag %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx\n", + VIF_LOG("vif0 Tag %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx", ptag[1]._u32, ptag[0]._u32, vif0ch->qwc, ptag->ID, vif0ch->madr, vif0ch->tadr); vif0.inprogress = 0; diff --git a/pcsx2/Vif1_Dma.cpp b/pcsx2/Vif1_Dma.cpp index 95c2fe93c6..d4b33e23b4 100644 --- a/pcsx2/Vif1_Dma.cpp +++ b/pcsx2/Vif1_Dma.cpp @@ -202,7 +202,7 @@ __forceinline void vif1SetupTransfer() vif1c.madr = ptag[1]._u32; //MADR = ADDR field + SPR g_vifCycles += 1; // Add 1 g_vifCycles from the QW read for the tag - VIF_LOG("VIF1 Tag %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx\n", + VIF_LOG("VIF1 Tag %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx", ptag[1]._u32, ptag[0]._u32, vif1c.qwc, ptag->ID, vif1c.madr, vif1c.tadr); if (!vif1.done && ((dmacRegs->ctrl.STD == STD_VIF1) && (ptag->ID == TAG_REFS))) // STD == VIF1 diff --git a/pcsx2/Vif_Codes.cpp b/pcsx2/Vif_Codes.cpp index e9a5c2a9b0..5f3c1798fa 100644 --- a/pcsx2/Vif_Codes.cpp +++ b/pcsx2/Vif_Codes.cpp @@ -110,7 +110,7 @@ void Vif1MskPath3() { vifOp(vifCode_Base) { vif1Only(); pass1 { vif1Regs->base = vif1Regs->code & 0x3ff; vif1.cmd = 0; } - pass3 { DevCon.WriteLn("vifCode_Base"); } + pass3 { VifCodeLog("Base"); } return 0; } @@ -235,12 +235,12 @@ template _f int _vifCode_Direct(int pass, const u8* data, bool isDirect } vifOp(vifCode_Direct) { - pass3 { DevCon.WriteLn("vifCode_Direct"); } + pass3 { VifCodeLog("Direct"); } return _vifCode_Direct(pass, (u8*)data, 0); } vifOp(vifCode_DirectHL) { - pass3 { DevCon.WriteLn("vifCode_DirectHL"); } + pass3 { VifCodeLog("DirectHL"); } return _vifCode_Direct(pass, (u8*)data, 1); } @@ -249,7 +249,7 @@ vifOp(vifCode_Flush) { vif1Only(); vifStruct& vifX = GetVifX; pass1 { vifFlush(idx); vifX.cmd = 0; } - pass3 { DevCon.WriteLn("vifCode_Flush"); } + pass3 { VifCodeLog("Flush"); } return 0; } @@ -272,7 +272,7 @@ vifOp(vifCode_FlushA) { vifX.cmd = 0; } - pass3 { DevCon.WriteLn("vifCode_FlushA"); } + pass3 { VifCodeLog("FlushA"); } return 0; } @@ -280,13 +280,13 @@ vifOp(vifCode_FlushA) { vifOp(vifCode_FlushE) { vifStruct& vifX = GetVifX; pass1 { vifFlush(idx); vifX.cmd = 0; } - pass3 { DevCon.WriteLn("vifCode_FlushE"); } + pass3 { VifCodeLog("FlushE"); } return 0; } vifOp(vifCode_ITop) { pass1 { vifXRegs->itops = vifXRegs->code & 0x3ff; GetVifX.cmd = 0; } - pass3 { DevCon.WriteLn("vifCode_ITop"); } + pass3 { VifCodeLog("ITop"); } return 0; } @@ -297,7 +297,7 @@ vifOp(vifCode_Mark) { vifXRegs->stat.MRK = true; vifX.cmd = 0; } - pass3 { DevCon.WriteLn("vifCode_Mark"); } + pass3 { VifCodeLog("Mark"); } return 0; } @@ -344,28 +344,28 @@ vifOp(vifCode_MPG) { return ret; } } - pass3 { DevCon.WriteLn("vifCode_MPG"); } + pass3 { VifCodeLog("MPG"); } return 0; } vifOp(vifCode_MSCAL) { vifStruct& vifX = GetVifX; pass1 { vifFlush(idx); vuExecMicro(idx, (u16)(vifXRegs->code) << 3); vifX.cmd = 0;} - pass3 { DevCon.WriteLn("vifCode_MSCAL"); } + pass3 { VifCodeLog("MSCAL"); } return 0; } vifOp(vifCode_MSCALF) { vifStruct& vifX = GetVifX; pass1 { vifFlush(idx); vuExecMicro(idx, (u16)(vifXRegs->code) << 3); vifX.cmd = 0; } - pass3 { DevCon.WriteLn("vifCode_MSCALF"); } + pass3 { VifCodeLog("MSCALF"); } return 0; } vifOp(vifCode_MSCNT) { vifStruct& vifX = GetVifX; pass1 { vifFlush(idx); vuExecMicro(idx, -1); vifX.cmd = 0; } - pass3 { DevCon.WriteLn("vifCode_MSCNT"); } + pass3 { VifCodeLog("MSCNT"); } return 0; } @@ -383,13 +383,13 @@ vifOp(vifCode_MskPath3) { } vif1.cmd = 0; } - pass3 { DevCon.WriteLn("vifCode_MskPath3"); } + pass3 { VifCodeLog("MskPath3"); } return 0; } vifOp(vifCode_Nop) { pass1 { GetVifX.cmd = 0; } - pass3 { DevCon.WriteLn("vifCode_Nop"); } + pass3 { VifCodeLog("Nop"); } return 0; } @@ -407,7 +407,7 @@ vifOp(vifCode_Null) { vifX.cmd = 0; } pass2 { Console.Error("Vif%d bad vifcode! [CMD = %x]", idx, vifX.cmd); } - pass3 { DevCon.WriteLn("vifCode_Null"); } + pass3 { VifCodeLog("Null"); } return 0; } @@ -419,7 +419,7 @@ vifOp(vifCode_Offset) { vif1Regs->tops = vif1Regs->base; vif1.cmd = 0; } - pass3 { DevCon.WriteLn("vifCode_Offset"); } + pass3 { VifCodeLog("Offset"); } return 0; } @@ -467,7 +467,7 @@ vifOp(vifCode_STCol) { u32* pmem2 = cols + vifX.tag.addr; return _vifCode_STColRow(data, pmem1, pmem2); } - pass3 { DevCon.WriteLn("vifCode_STCol"); } + pass3 { VifCodeLog("STCol"); } return 0; } @@ -485,7 +485,7 @@ vifOp(vifCode_STRow) { u32* pmem2 = rows + vifX.tag.addr; return _vifCode_STColRow(data, pmem1, pmem2); } - pass3 { DevCon.WriteLn("vifCode_STRow"); } + pass3 { VifCodeLog("STRow"); } return 0; } @@ -496,7 +496,7 @@ vifOp(vifCode_STCycl) { vifXRegs->cycle.wl = (u8)(vifXRegs->code >> 8); vifX.cmd = 0; } - pass3 { DevCon.WriteLn("vifCode_STCycl"); } + pass3 { VifCodeLog("STCycl"); } return 0; } @@ -504,13 +504,13 @@ vifOp(vifCode_STMask) { vifStruct& vifX = GetVifX; pass1 { vifX.tag.size = 1; } pass2 { vifXRegs->mask = data[0]; vifX.tag.size = 0; vifX.cmd = 0; } - pass3 { DevCon.WriteLn("vifCode_STMask"); } + pass3 { VifCodeLog("STMask"); } return 1; } vifOp(vifCode_STMod) { pass1 { vifXRegs->mode = vifXRegs->code & 0x3; GetVifX.cmd = 0; } - pass3 { DevCon.WriteLn("vifCode_STMod"); } + pass3 { VifCodeLog("STMod"); } return 0; } @@ -521,7 +521,7 @@ vifOp(vifCode_Unpack) { return 1; } pass2 { return nVifUnpack(idx, (u8*)data); } - pass3 { DevCon.WriteLn("vifCode_Unpack"); } + pass3 { VifCodeLog("Unpack"); } return 0; } diff --git a/pcsx2/Vif_Unpack.inl b/pcsx2/Vif_Unpack.inl index 59e8d22f8e..ed7825c51d 100644 --- a/pcsx2/Vif_Unpack.inl +++ b/pcsx2/Vif_Unpack.inl @@ -1,159 +1,159 @@ -/* 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 . - */ - -#pragma once - -// Old Vif Unpack Code -// Only here for testing/reference -template void VIFunpack(u32 *data, vifCode *v, u32 size) { - //if (!VIFdmanum) DevCon.WriteLn("vif#%d, size = %d [%x]", VIFdmanum, size, data); - VURegs * VU; - u8 *cdata = (u8*)data; - u32 tempsize = 0; - const u32 memlimit = (VIFdmanum == 0) ? 0x1000 : 0x4000; - - if (VIFdmanum == 0) { - VU = &VU0; - vifRegs = vif0Regs; - vif = &vif0; - } - else { - VU = &VU1; - vifRegs = vif1Regs; - vif = &vif1; - } - - u32 *dest = (u32*)(VU->Mem + v->addr); - - const VIFUnpackFuncTable& ft( VIFfuncTable[ v->cmd & 0x1f ] ); - UNPACKFUNCTYPE func = vif->usn ? ft.funcU : ft.funcS; - - size <<= 2; - - if (vifRegs->cycle.cl >= vifRegs->cycle.wl) { // skipping write - if (v->addr >= memlimit) { - DevCon.Warning("Overflown at the start"); - v->addr &= (memlimit - 1); - dest = (u32*)(VU->Mem + v->addr); - } - - size = std::min(size, vifRegs->num * ft.gsize); //size will always be the same or smaller - - tempsize = v->addr + ((((vifRegs->num-1) / vifRegs->cycle.wl) * - (vifRegs->cycle.cl - vifRegs->cycle.wl)) * 16) + (vifRegs->num * 16); - - //Sanity Check (memory overflow) - if (tempsize > memlimit) { - if (((vifRegs->cycle.cl != vifRegs->cycle.wl) && - ((memlimit + (vifRegs->cycle.cl - vifRegs->cycle.wl) * 16) == tempsize))) { - //It's a red herring, so ignore it! SSE unpacks will be much quicker. - DevCon.WriteLn("what!!!!!!!!!"); - //tempsize = 0; - tempsize = size; - size = 0; - } - else { - DevCon.Warning("VIF%x Unpack ending %x > %x", VIFdmanum, tempsize, VIFdmanum ? 0x4000 : 0x1000); - tempsize = size; - size = 0; - } - } - else { - tempsize = size; - size = 0; - } - if (tempsize) { - int incdest = ((vifRegs->cycle.cl - vifRegs->cycle.wl) << 2) + 4; - size = 0; - int addrstart = v->addr; - //if((tempsize >> 2) != v->size) DevCon.Warning("split when size != tagsize"); - - VIFUNPACK_LOG("sorting tempsize :p, size %d, vifnum %d, addr %x", tempsize, vifRegs->num, v->addr); - - while ((tempsize >= ft.gsize) && (vifRegs->num > 0)) { - if(v->addr >= memlimit) { - DevCon.Warning("Mem limit overflow"); - v->addr &= (memlimit - 1); - dest = (u32*)(VU->Mem + v->addr); - } - - func(dest, (u32*)cdata); - cdata += ft.gsize; - tempsize -= ft.gsize; - - vifRegs->num--; - vif->cl++; - - if (vif->cl == vifRegs->cycle.wl) { - dest += incdest; - v->addr +=(incdest * 4); - vif->cl = 0; - } - else { - dest += 4; - v->addr += 16; - } - } - if (v->addr >= memlimit) { - v->addr &=(memlimit - 1); - dest = (u32*)(VU->Mem + v->addr); - } - v->addr = addrstart; - if(tempsize > 0) size = tempsize; - } - - if (size >= ft.dsize && vifRegs->num > 0) { //Else write what we do have - DevCon.Warning("huh!!!!!!!!!!!!!!!!!!!!!!"); - VIF_LOG("warning, end with size = %d", size); - // unpack one qword - //v->addr += (size / ft.dsize) * 4; - (vif->usn ? ft.oddU : ft.oddS)(dest, (u32*)cdata, size / ft.dsize); - size = 0; - VIFUNPACK_LOG("leftover done, size %d, vifnum %d, addr %x", size, vifRegs->num, v->addr); - } - } - else { // filling write - if(vifRegs->cycle.cl > 0) // Quicker and avoids zero division :P - if((u32)(((size / ft.gsize) / vifRegs->cycle.cl) * vifRegs->cycle.wl) < vifRegs->num) - DevCon.Warning("Filling write warning! %x < %x and CL = %x WL = %x", (size / ft.gsize), vifRegs->num, vifRegs->cycle.cl, vifRegs->cycle.wl); - - DevCon.Warning("filling write %d cl %d, wl %d mask %x mode %x unpacktype %x addr %x", vifRegs->num, vifRegs->cycle.cl, vifRegs->cycle.wl, vifRegs->mask, vifRegs->mode, v->cmd & 0xf, vif->tag.addr); - while (vifRegs->num > 0) { - if (vif->cl == vifRegs->cycle.wl) { - vif->cl = 0; - } - // unpack one qword - if (vif->cl < vifRegs->cycle.cl) { - if(size < ft.gsize) { DevCon.WriteLn("Out of Filling write data!"); break; } - func(dest, (u32*)cdata); - cdata += ft.gsize; - size -= ft.gsize; - vif->cl++; - vifRegs->num--; - if (vif->cl == vifRegs->cycle.wl) { - vif->cl = 0; - } - } - else { - func(dest, (u32*)cdata); - v->addr += 16; - vifRegs->num--; - vif->cl++; - } - dest += 4; - if (vifRegs->num == 0) break; - } - } -} +/* 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 . + */ + +#pragma once + +// Old Vif Unpack Code +// Only here for testing/reference +template void VIFunpack(u32 *data, vifCode *v, u32 size) { + //if (!VIFdmanum) DevCon.WriteLn("vif#%d, size = %d [%x]", VIFdmanum, size, data); + VURegs * VU; + u8 *cdata = (u8*)data; + u32 tempsize = 0; + const u32 memlimit = (VIFdmanum == 0) ? 0x1000 : 0x4000; + + if (VIFdmanum == 0) { + VU = &VU0; + vifRegs = vif0Regs; + vif = &vif0; + } + else { + VU = &VU1; + vifRegs = vif1Regs; + vif = &vif1; + } + + u32 *dest = (u32*)(VU->Mem + v->addr); + + const VIFUnpackFuncTable& ft( VIFfuncTable[ v->cmd & 0x1f ] ); + UNPACKFUNCTYPE func = vif->usn ? ft.funcU : ft.funcS; + + size <<= 2; + + if (vifRegs->cycle.cl >= vifRegs->cycle.wl) { // skipping write + if (v->addr >= memlimit) { + DevCon.Warning("Overflown at the start"); + v->addr &= (memlimit - 1); + dest = (u32*)(VU->Mem + v->addr); + } + + size = std::min(size, vifRegs->num * ft.gsize); //size will always be the same or smaller + + tempsize = v->addr + ((((vifRegs->num-1) / vifRegs->cycle.wl) * + (vifRegs->cycle.cl - vifRegs->cycle.wl)) * 16) + (vifRegs->num * 16); + + //Sanity Check (memory overflow) + if (tempsize > memlimit) { + if (((vifRegs->cycle.cl != vifRegs->cycle.wl) && + ((memlimit + (vifRegs->cycle.cl - vifRegs->cycle.wl) * 16) == tempsize))) { + //It's a red herring, so ignore it! SSE unpacks will be much quicker. + DevCon.WriteLn("what!!!!!!!!!"); + //tempsize = 0; + tempsize = size; + size = 0; + } + else { + DevCon.Warning("VIF%x Unpack ending %x > %x", VIFdmanum, tempsize, VIFdmanum ? 0x4000 : 0x1000); + tempsize = size; + size = 0; + } + } + else { + tempsize = size; + size = 0; + } + if (tempsize) { + int incdest = ((vifRegs->cycle.cl - vifRegs->cycle.wl) << 2) + 4; + size = 0; + int addrstart = v->addr; + //if((tempsize >> 2) != v->size) DevCon.Warning("split when size != tagsize"); + + //DbgCon.WriteLn("sorting tempsize :p, size %d, vifnum %d, addr %x", tempsize, vifRegs->num, v->addr); + + while ((tempsize >= ft.gsize) && (vifRegs->num > 0)) { + if(v->addr >= memlimit) { + DevCon.Warning("Mem limit overflow"); + v->addr &= (memlimit - 1); + dest = (u32*)(VU->Mem + v->addr); + } + + func(dest, (u32*)cdata); + cdata += ft.gsize; + tempsize -= ft.gsize; + + vifRegs->num--; + vif->cl++; + + if (vif->cl == vifRegs->cycle.wl) { + dest += incdest; + v->addr +=(incdest * 4); + vif->cl = 0; + } + else { + dest += 4; + v->addr += 16; + } + } + if (v->addr >= memlimit) { + v->addr &=(memlimit - 1); + dest = (u32*)(VU->Mem + v->addr); + } + v->addr = addrstart; + if(tempsize > 0) size = tempsize; + } + + if (size >= ft.dsize && vifRegs->num > 0) { //Else write what we do have + VIF_LOG("warning, end with size = %d", size); + // unpack one qword + //v->addr += (size / ft.dsize) * 4; + (vif->usn ? ft.oddU : ft.oddS)(dest, (u32*)cdata, size / ft.dsize); + size = 0; + + //DbgCon.WriteLn("leftover done, size %d, vifnum %d, addr %x", size, vifRegs->num, v->addr); + } + } + else { // filling write + if(vifRegs->cycle.cl > 0) // Quicker and avoids zero division :P + if((u32)(((size / ft.gsize) / vifRegs->cycle.cl) * vifRegs->cycle.wl) < vifRegs->num) + DevCon.Warning("Filling write warning! %x < %x and CL = %x WL = %x", (size / ft.gsize), vifRegs->num, vifRegs->cycle.cl, vifRegs->cycle.wl); + + DevCon.Warning("filling write %d cl %d, wl %d mask %x mode %x unpacktype %x addr %x", vifRegs->num, vifRegs->cycle.cl, vifRegs->cycle.wl, vifRegs->mask, vifRegs->mode, v->cmd & 0xf, vif->tag.addr); + while (vifRegs->num > 0) { + if (vif->cl == vifRegs->cycle.wl) { + vif->cl = 0; + } + // unpack one qword + if (vif->cl < vifRegs->cycle.cl) { + if(size < ft.gsize) { DevCon.WriteLn("Out of Filling write data!"); break; } + func(dest, (u32*)cdata); + cdata += ft.gsize; + size -= ft.gsize; + vif->cl++; + vifRegs->num--; + if (vif->cl == vifRegs->cycle.wl) { + vif->cl = 0; + } + } + else { + func(dest, (u32*)cdata); + v->addr += 16; + vifRegs->num--; + vif->cl++; + } + dest += 4; + if (vifRegs->num == 0) break; + } + } +} diff --git a/pcsx2/gui/App.h b/pcsx2/gui/App.h index 05baf9c7b0..b38a5475ae 100644 --- a/pcsx2/gui/App.h +++ b/pcsx2/gui/App.h @@ -156,7 +156,7 @@ namespace Exception // class StartupAborted : public CancelEvent { - DEFINE_RUNTIME_EXCEPTION( StartupAborted, CancelEvent, "Startup initialization was aborted by the user." ) + DEFINE_RUNTIME_EXCEPTION( StartupAborted, CancelEvent, L"Startup initialization was aborted by the user." ) public: StartupAborted( const wxString& reason ) @@ -678,10 +678,6 @@ extern void LoadPluginsImmediate(); extern void UnloadPlugins(); extern void ShutdownPlugins(); -extern void AppLoadSettings(); -extern void AppSaveSettings(); -extern void AppApplySettings( const AppConfig* oldconf=NULL ); - extern bool SysHasValidState(); extern void SysUpdateIsoSrcFile( const wxString& newIsoFile ); extern void SysStatus( const wxString& text ); diff --git a/pcsx2/gui/AppAccelerators.h b/pcsx2/gui/AppAccelerators.h index 0039fee572..f786d7eb66 100644 --- a/pcsx2/gui/AppAccelerators.h +++ b/pcsx2/gui/AppAccelerators.h @@ -1,123 +1,123 @@ -/* 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 . - */ - -#pragma once - -#include "AppCommon.h" -#include "Utilities/HashMap.h" - -// -------------------------------------------------------------------------------------- -// KeyAcceleratorCode -// A custom keyboard accelerator that I like better than wx's wxAcceleratorEntry. -// -------------------------------------------------------------------------------------- -struct KeyAcceleratorCode -{ - union - { - struct - { - u16 keycode; - u16 win:1, // win32 only. - cmd:1, // ctrl in win32, Command in Mac - alt:1, - shift:1; - }; - u32 val32; - }; - - KeyAcceleratorCode() : val32( 0 ) {} - KeyAcceleratorCode( const wxKeyEvent& evt ); - - KeyAcceleratorCode( wxKeyCode code ) - { - val32 = 0; - keycode = code; - } - - KeyAcceleratorCode& Shift() - { - shift = true; - return *this; - } - - KeyAcceleratorCode& Alt() - { - alt = true; - return *this; - } - - KeyAcceleratorCode& Win() - { - win = true; - return *this; - } - - KeyAcceleratorCode& Cmd() - { - cmd = true; - return *this; - } - - wxString ToString() const; -}; - - -// -------------------------------------------------------------------------------------- -// GlobalCommandDescriptor -// Describes a global command which can be invoked from the main GUI or GUI plugins. -// -------------------------------------------------------------------------------------- - -struct GlobalCommandDescriptor -{ - const char* Id; // Identifier string - void (*Invoke)(); // Do it!! Do it NOW!!! - - const char* Fullname; // Name displayed in pulldown menus - const char* Tooltip; // text displayed in toolbar tooltips and menu status bars. - - int ToolbarIconId; // not implemented yet, leave 0 for now. -}; - -// -------------------------------------------------------------------------------------- -// -// -------------------------------------------------------------------------------------- -class CommandDictionary : public HashTools::Dictionary -{ - typedef HashTools::Dictionary _parent; - -protected: - -public: - using _parent::operator[]; - CommandDictionary(); - virtual ~CommandDictionary() throw(); -}; - -// -------------------------------------------------------------------------------------- -// -// -------------------------------------------------------------------------------------- -class AcceleratorDictionary : public HashTools::HashMap -{ - typedef HashTools::HashMap _parent; - -protected: - -public: - using _parent::operator[]; - - AcceleratorDictionary(); - virtual ~AcceleratorDictionary() throw(); - void Map( const KeyAcceleratorCode& acode, const char *searchfor ); -}; +/* 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 . + */ + +#pragma once + +#include "AppCommon.h" +#include "Utilities/HashMap.h" + +// -------------------------------------------------------------------------------------- +// KeyAcceleratorCode +// A custom keyboard accelerator that I like better than wx's wxAcceleratorEntry. +// -------------------------------------------------------------------------------------- +struct KeyAcceleratorCode +{ + union + { + struct + { + u16 keycode; + u16 win:1, // win32 only. + cmd:1, // ctrl in win32, Command in Mac + alt:1, + shift:1; + }; + u32 val32; + }; + + KeyAcceleratorCode() : val32( 0 ) {} + KeyAcceleratorCode( const wxKeyEvent& evt ); + + KeyAcceleratorCode( wxKeyCode code ) + { + val32 = 0; + keycode = code; + } + + KeyAcceleratorCode& Shift() + { + shift = true; + return *this; + } + + KeyAcceleratorCode& Alt() + { + alt = true; + return *this; + } + + KeyAcceleratorCode& Win() + { + win = true; + return *this; + } + + KeyAcceleratorCode& Cmd() + { + cmd = true; + return *this; + } + + wxString ToString() const; +}; + + +// -------------------------------------------------------------------------------------- +// GlobalCommandDescriptor +// -------------------------------------------------------------------------------------- +// Describes a global command which can be invoked from the main GUI or GUI plugins. + +struct GlobalCommandDescriptor +{ + const char* Id; // Identifier string + void (*Invoke)(); // Do it!! Do it NOW!!! + + const wxChar* Fullname; // Name displayed in pulldown menus + const wxChar* Tooltip; // text displayed in toolbar tooltips and menu status bars. + + int ToolbarIconId; // not implemented yet, leave 0 for now. +}; + +// -------------------------------------------------------------------------------------- +// CommandDictionary +// -------------------------------------------------------------------------------------- +class CommandDictionary : public HashTools::Dictionary +{ + typedef HashTools::Dictionary _parent; + +protected: + +public: + using _parent::operator[]; + CommandDictionary(); + virtual ~CommandDictionary() throw(); +}; + +// -------------------------------------------------------------------------------------- +// +// -------------------------------------------------------------------------------------- +class AcceleratorDictionary : public HashTools::HashMap +{ + typedef HashTools::HashMap _parent; + +protected: + +public: + using _parent::operator[]; + + AcceleratorDictionary(); + virtual ~AcceleratorDictionary() throw(); + void Map( const KeyAcceleratorCode& acode, const char *searchfor ); +}; diff --git a/pcsx2/gui/AppConfig.cpp b/pcsx2/gui/AppConfig.cpp index 8e32e74b08..8a0b525c6f 100644 --- a/pcsx2/gui/AppConfig.cpp +++ b/pcsx2/gui/AppConfig.cpp @@ -534,6 +534,7 @@ void AppConfig::LoadSave( IniInterface& ini ) AppConfig::ConsoleLogOptions::ConsoleLogOptions() : DisplayPosition( wxDefaultPosition ) , DisplaySize( wxSize( 680, 560 ) ) + , Theme(L"Default") { Visible = true; AutoDock = true; @@ -550,6 +551,7 @@ void AppConfig::ConsoleLogOptions::LoadSave( IniInterface& ini, const wxChar* lo IniEntry( DisplayPosition ); IniEntry( DisplaySize ); IniEntry( FontSize ); + IniEntry( Theme ); } void AppConfig::FolderOptions::ApplyDefaults() @@ -720,7 +722,6 @@ void AppConfig::FramerateOptions::SanityCheck() SlomoScalar .ConfineTo( 0.05, 10.0 ); } - void AppConfig::FramerateOptions::LoadSave( IniInterface& ini ) { ScopedIniGroup path( ini, L"Framerate" ); @@ -734,7 +735,6 @@ void AppConfig::FramerateOptions::LoadSave( IniInterface& ini ) IniEntry( SkipOnTurbo ); } - wxFileConfig* OpenFileConfig( const wxString& filename ) { return new wxFileConfig( wxEmptyString, wxEmptyString, filename, wxEmptyString, wxCONFIG_USE_RELATIVE_PATH ); @@ -794,6 +794,127 @@ void AppConfig_OnChangedSettingsFolder( bool overwrite ) AppApplySettings(); } +// -------------------------------------------------------------------------------------- +// pxDudConfig +// -------------------------------------------------------------------------------------- +// Used to handle config actions prior to the creation of the ini file (for example, the +// first time wizard). Attempts to save ini settings are simply ignored through this +// class, which allows us to give the user a way to set everything up in the wizard, apply +// settings as usual, and only *save* something once the whole wizard is complete. +// +class pxDudConfig : public wxConfigBase +{ +protected: + wxString m_empty; + +public: + virtual ~pxDudConfig() {} + + virtual void SetPath(const wxString& ) {} + virtual const wxString& GetPath() const { return m_empty; } + + virtual bool GetFirstGroup(wxString& , long& ) const { return false; } + virtual bool GetNextGroup (wxString& , long& ) const { return false; } + virtual bool GetFirstEntry(wxString& , long& ) const { return false; } + virtual bool GetNextEntry (wxString& , long& ) const { return false; } + virtual size_t GetNumberOfEntries(bool ) const { return 0; } + virtual size_t GetNumberOfGroups(bool ) const { return 0; } + + virtual bool HasGroup(const wxString& ) const { return false; } + virtual bool HasEntry(const wxString& ) const { return false; } + + virtual bool Flush(bool ) { return false; } + + virtual bool RenameEntry(const wxString&, const wxString& ) { return false; } + + virtual bool RenameGroup(const wxString&, const wxString& ) { return false; } + + virtual bool DeleteEntry(const wxString&, bool bDeleteGroupIfEmpty = true) { return false; } + virtual bool DeleteGroup(const wxString& ) { return false; } + virtual bool DeleteAll() { return false; } + +protected: + virtual bool DoReadString(const wxString& , wxString *) const { return false; } + virtual bool DoReadLong(const wxString& , long *) const { return false; } + + virtual bool DoWriteString(const wxString& , const wxString& ) { return false; } + virtual bool DoWriteLong(const wxString& , long ) { return false; } +}; + +static pxDudConfig _dud_config; + +// -------------------------------------------------------------------------------------- +// AppIniSaver / AppIniLoader +// -------------------------------------------------------------------------------------- +class AppIniSaver : public IniSaver +{ +public: + AppIniSaver(); + virtual ~AppIniSaver() throw() {} +}; + +class AppIniLoader : public IniLoader +{ +public: + AppIniLoader(); + virtual ~AppIniLoader() throw() {} +}; + +AppIniSaver::AppIniSaver() + : IniSaver( (GetAppConfig() != NULL) ? *GetAppConfig() : _dud_config ) +{ +} + +AppIniLoader::AppIniLoader() + : IniLoader( (GetAppConfig() != NULL) ? *GetAppConfig() : _dud_config ) +{ +} + + +void AppLoadSettings() +{ + if( wxGetApp().Rpc_TryInvoke(AppLoadSettings) ) return; + + AppIniLoader loader; + ConLog_LoadSaveSettings( loader ); + SysTraceLog_LoadSaveSettings( loader ); + g_Conf->LoadSave( loader ); + + if( !wxFile::Exists( g_Conf->CurrentIso ) ) + g_Conf->CurrentIso.clear(); + + sApp.DispatchEvent( loader ); +} + +void AppSaveSettings() +{ + // If multiple SaveSettings messages are requested, we want to ignore most of them. + // Saving settings once when the GUI is idle should be fine. :) + + static u32 isPosted = false; + + if( !wxThread::IsMain() ) + { + if( AtomicExchange(isPosted, true) ) + wxGetApp().PostIdleMethod( AppSaveSettings ); + + return; + } + + if( !wxFile::Exists( g_Conf->CurrentIso ) ) + g_Conf->CurrentIso.clear(); + + sApp.GetRecentIsoManager().Add( g_Conf->CurrentIso ); + + AtomicExchange( isPosted, false ); + + AppIniSaver saver; + g_Conf->LoadSave( saver ); + ConLog_LoadSaveSettings( saver ); + SysTraceLog_LoadSaveSettings( saver ); + sApp.DispatchEvent( saver ); +} + // Returns the current application configuration file. This is preferred over using // wxConfigBase::GetAppConfig(), since it defaults to *not* creating a config file // automatically (which is typically highly undesired behavior in our system) diff --git a/pcsx2/gui/AppConfig.h b/pcsx2/gui/AppConfig.h index 13b9acbfee..ab5a345893 100644 --- a/pcsx2/gui/AppConfig.h +++ b/pcsx2/gui/AppConfig.h @@ -81,6 +81,9 @@ public: // Size of the font in points. int FontSize; + // Color theme by name! + wxString Theme; + ConsoleLogOptions(); void LoadSave( IniInterface& conf, const wxChar* title ); }; @@ -258,6 +261,14 @@ public: void LoadSaveMemcards( IniInterface& ini ); }; +extern void AppLoadSettings(); +extern void AppSaveSettings(); +extern void AppApplySettings( const AppConfig* oldconf=NULL ); + +extern void ConLog_LoadSaveSettings( IniInterface& ini ); +extern void SysTraceLog_LoadSaveSettings( IniInterface& ini ); + + extern wxFileConfig* OpenFileConfig( const wxString& filename ); extern void RelocateLogfile(); extern void AppConfig_OnChangedSettingsFolder( bool overwrite = false ); diff --git a/pcsx2/gui/AppCoreThread.cpp b/pcsx2/gui/AppCoreThread.cpp index 7e4e2c4767..f7913fa4e1 100644 --- a/pcsx2/gui/AppCoreThread.cpp +++ b/pcsx2/gui/AppCoreThread.cpp @@ -94,7 +94,7 @@ static void _Cancel() void AppCoreThread::Cancel( bool isBlocking ) { - if (GetSysExecutorThread().IsRunning() && !GetSysExecutorThread().Rpc_TryInvoke( _Cancel )) + if (GetSysExecutorThread().IsRunning() && !GetSysExecutorThread().Rpc_TryInvoke( _Cancel, L"AppCoreThread::Cancel" )) _parent::Cancel( wxTimeSpan(0, 0, 4, 0) ); } @@ -126,10 +126,10 @@ void AppCoreThread::Suspend( bool isBlocking ) if (IsSelf()) { // this should never fail... - bool result = GetSysExecutorThread().Rpc_TryInvokeAsync( _Suspend ); + bool result = GetSysExecutorThread().Rpc_TryInvokeAsync( _Suspend, L"AppCoreThread::Suspend" ); pxAssert(result); } - else if (!GetSysExecutorThread().Rpc_TryInvoke( _Suspend )) + else if (!GetSysExecutorThread().Rpc_TryInvoke( _Suspend, L"AppCoreThread::Suspend" )) _parent::Suspend(true); } diff --git a/pcsx2/gui/AppInit.cpp b/pcsx2/gui/AppInit.cpp index 7d36249b39..a7dde49ca1 100644 --- a/pcsx2/gui/AppInit.cpp +++ b/pcsx2/gui/AppInit.cpp @@ -841,6 +841,6 @@ struct CrtDebugBreak } }; -//CrtDebugBreak breakAt( 909 ); +//CrtDebugBreak breakAt( 11549 ); #endif diff --git a/pcsx2/gui/AppMain.cpp b/pcsx2/gui/AppMain.cpp index e1c6a19b04..f99455de65 100644 --- a/pcsx2/gui/AppMain.cpp +++ b/pcsx2/gui/AppMain.cpp @@ -647,123 +647,6 @@ void AppApplySettings( const AppConfig* oldconf ) paused_core.AllowResume(); } - -// -------------------------------------------------------------------------------------- -// pxDudConfig -// -------------------------------------------------------------------------------------- -// Used to handle config actions prior to the creation of the ini file (for example, the -// first time wizard). Attempts to save ini settings are simply ignored through this -// class, which allows us to give the user a way to set everything up in the wizard, apply -// settings as usual, and only *save* something once the whole wizard is complete. -// -class pxDudConfig : public wxConfigBase -{ -protected: - wxString m_empty; - -public: - virtual ~pxDudConfig() {} - - virtual void SetPath(const wxString& ) {} - virtual const wxString& GetPath() const { return m_empty; } - - virtual bool GetFirstGroup(wxString& , long& ) const { return false; } - virtual bool GetNextGroup (wxString& , long& ) const { return false; } - virtual bool GetFirstEntry(wxString& , long& ) const { return false; } - virtual bool GetNextEntry (wxString& , long& ) const { return false; } - virtual size_t GetNumberOfEntries(bool ) const { return 0; } - virtual size_t GetNumberOfGroups(bool ) const { return 0; } - - virtual bool HasGroup(const wxString& ) const { return false; } - virtual bool HasEntry(const wxString& ) const { return false; } - - virtual bool Flush(bool ) { return false; } - - virtual bool RenameEntry(const wxString&, const wxString& ) { return false; } - - virtual bool RenameGroup(const wxString&, const wxString& ) { return false; } - - virtual bool DeleteEntry(const wxString&, bool bDeleteGroupIfEmpty = true) { return false; } - virtual bool DeleteGroup(const wxString& ) { return false; } - virtual bool DeleteAll() { return false; } - -protected: - virtual bool DoReadString(const wxString& , wxString *) const { return false; } - virtual bool DoReadLong(const wxString& , long *) const { return false; } - - virtual bool DoWriteString(const wxString& , const wxString& ) { return false; } - virtual bool DoWriteLong(const wxString& , long ) { return false; } -}; - -static pxDudConfig _dud_config; - -// -------------------------------------------------------------------------------------- -// AppIniSaver / AppIniLoader -// -------------------------------------------------------------------------------------- -class AppIniSaver : public IniSaver -{ -public: - AppIniSaver(); - virtual ~AppIniSaver() throw() {} -}; - -class AppIniLoader : public IniLoader -{ -public: - AppIniLoader(); - virtual ~AppIniLoader() throw() {} -}; - -AppIniSaver::AppIniSaver() - : IniSaver( (GetAppConfig() != NULL) ? *GetAppConfig() : _dud_config ) -{ -} - -AppIniLoader::AppIniLoader() - : IniLoader( (GetAppConfig() != NULL) ? *GetAppConfig() : _dud_config ) -{ -} - -void AppLoadSettings() -{ - if( wxGetApp().Rpc_TryInvoke(AppLoadSettings) ) return; - - AppIniLoader loader; - g_Conf->LoadSave( loader ); - - if( !wxFile::Exists( g_Conf->CurrentIso ) ) - g_Conf->CurrentIso.clear(); - - sApp.DispatchEvent( loader ); -} - -void AppSaveSettings() -{ - // If multiple SaveSettings messages are requested, we want to ignore most of them. - // Saving settings once when the GUI is idle should be fine. :) - - static u32 isPosted = false; - - if( !wxThread::IsMain() ) - { - if( AtomicExchange(isPosted, true) ) - wxGetApp().PostIdleMethod( AppSaveSettings ); - - return; - } - - if( !wxFile::Exists( g_Conf->CurrentIso ) ) - g_Conf->CurrentIso.clear(); - - sApp.GetRecentIsoManager().Add( g_Conf->CurrentIso ); - - AtomicExchange( isPosted, false ); - - AppIniSaver saver; - g_Conf->LoadSave( saver ); - sApp.DispatchEvent( saver ); -} - // Invokes the specified Pcsx2App method, or posts the method to the main thread if the calling // thread is not Main. Action is blocking. For non-blocking method execution, use // AppRpc_TryInvokeAsync. diff --git a/pcsx2/gui/ConsoleLogger.cpp b/pcsx2/gui/ConsoleLogger.cpp index 94be3c51ed..db91b3917c 100644 --- a/pcsx2/gui/ConsoleLogger.cpp +++ b/pcsx2/gui/ConsoleLogger.cpp @@ -20,6 +20,7 @@ #include "MSWstuff.h" #include "Utilities/Console.h" +#include "Utilities/IniInterface.h" #include "Utilities/SafeArray.inl" #include "DebugTools/Debug.h" @@ -47,12 +48,11 @@ void pxLogConsole::DoLog( wxLogLevel level, const wxChar *szString, time_t t ) { case wxLOG_Trace: case wxLOG_Debug: - if( IsDebugBuild ) - { - wxString str; - TimeStamp( &str ); - MSW_OutputDebugString( str + szString ); - } + { + wxString str; + TimeStamp( &str ); + MSW_OutputDebugString( str + szString + L"\n" ); + } break; case wxLOG_FatalError: @@ -117,21 +117,21 @@ static bool OpenLogFile(wxFile& file, wxString& filename, wxWindow *parent) strMsg.Printf(L"Append log to file '%s' (choosing [No] will overwrite it)?", filename.c_str()); - switch ( wxMessageBox(strMsg, L"Question", wxICON_QUESTION | wxYES_NO | wxCANCEL) ) + switch ( Msgbox::ShowModal( _("Save log question"), strMsg, MsgButtons().YesNo().Cancel() ) ) { - case wxYES: + case wxID_YES: bAppend = true; break; - case wxNO: + case wxID_NO: bAppend = false; break; - case wxCANCEL: + case wxID_CANCEL: return false; default: - wxFAIL_MSG( L"invalid message box return value" ); + pxFailDev( "invalid message box return value" ); } return ( bAppend ) ? @@ -162,10 +162,6 @@ ConsoleLogFrame::ColorArray::~ColorArray() throw() void ConsoleLogFrame::ColorArray::Create( int fontsize ) { - // pxGetFixedFont selects Andale Mono on Win32, which is nice visually but - // unfortunately has inconsistently spaced bold versions, so it's not good - // for our console. - const wxFont fixed( pxGetFixedFont( fontsize ) ); const wxFont fixedB( pxGetFixedFont( fontsize+1, wxBOLD ) ); @@ -173,30 +169,88 @@ void ConsoleLogFrame::ColorArray::Create( int fontsize ) //const wxFont fixedB( fontsize, wxMODERN, wxNORMAL, wxBOLD ); // Standard R, G, B format: - new (&m_table[Color_Default]) wxTextAttr( wxColor( 0, 0, 0 ), wxNullColour, fixed ); - new (&m_table[Color_Black]) wxTextAttr( wxColor( 0, 0, 0 ), wxNullColour, fixed ); - new (&m_table[Color_Red]) wxTextAttr( wxColor( 128, 0, 0 ), wxNullColour, fixed ); - new (&m_table[Color_Green]) wxTextAttr( wxColor( 0, 128, 0 ), wxNullColour, fixed ); - new (&m_table[Color_Blue]) wxTextAttr( wxColor( 0, 0, 128 ), wxNullColour, fixed ); - new (&m_table[Color_Magenta]) wxTextAttr( wxColor( 160, 0, 160 ), wxNullColour, fixed ); - new (&m_table[Color_Orange]) wxTextAttr( wxColor( 160, 120, 0 ), wxNullColour, fixed ); - new (&m_table[Color_Gray]) wxTextAttr( wxColor( 108, 108, 108 ), wxNullColour, fixed ); + new (&m_table[Color_Default]) wxTextAttr( wxNullColour, wxNullColour, fixed ); + new (&m_table[Color_Black]) wxTextAttr( wxNullColour, wxNullColour, fixed ); + new (&m_table[Color_Red]) wxTextAttr( wxNullColour, wxNullColour, fixed ); + new (&m_table[Color_Green]) wxTextAttr( wxNullColour, wxNullColour, fixed ); + new (&m_table[Color_Blue]) wxTextAttr( wxNullColour, wxNullColour, fixed ); + new (&m_table[Color_Magenta]) wxTextAttr( wxNullColour, wxNullColour, fixed ); + new (&m_table[Color_Orange]) wxTextAttr( wxNullColour, wxNullColour, fixed ); + new (&m_table[Color_Gray]) wxTextAttr( wxNullColour, wxNullColour, fixed ); - new (&m_table[Color_Cyan]) wxTextAttr( wxColor( 128, 180, 180 ), wxNullColour, fixed ); - new (&m_table[Color_Yellow]) wxTextAttr( wxColor( 180, 180, 128 ), wxNullColour, fixed ); - new (&m_table[Color_White]) wxTextAttr( wxColor( 160, 160, 160 ), wxNullColour, fixed ); + new (&m_table[Color_Cyan]) wxTextAttr( wxNullColour, wxNullColour, fixed ); + new (&m_table[Color_Yellow]) wxTextAttr( wxNullColour, wxNullColour, fixed ); + new (&m_table[Color_White]) wxTextAttr( wxNullColour, wxNullColour, fixed ); - new (&m_table[Color_StrongBlack]) wxTextAttr( wxColor( 0, 0, 0 ), wxNullColour, fixedB ); - new (&m_table[Color_StrongRed]) wxTextAttr( wxColor( 128, 0, 0 ), wxNullColour, fixedB ); - new (&m_table[Color_StrongGreen]) wxTextAttr( wxColor( 0, 128, 0 ), wxNullColour, fixedB ); - new (&m_table[Color_StrongBlue]) wxTextAttr( wxColor( 0, 0, 128 ), wxNullColour, fixedB ); - new (&m_table[Color_StrongMagenta]) wxTextAttr( wxColor( 160, 0, 160 ), wxNullColour, fixedB ); - new (&m_table[Color_StrongOrange]) wxTextAttr( wxColor( 160, 120, 0 ), wxNullColour, fixedB ); - new (&m_table[Color_StrongGray]) wxTextAttr( wxColor( 108, 108, 108 ), wxNullColour, fixedB ); + new (&m_table[Color_StrongBlack]) wxTextAttr( wxNullColour, wxNullColour, fixedB ); + new (&m_table[Color_StrongRed]) wxTextAttr( wxNullColour, wxNullColour, fixedB ); + new (&m_table[Color_StrongGreen]) wxTextAttr( wxNullColour, wxNullColour, fixedB ); + new (&m_table[Color_StrongBlue]) wxTextAttr( wxNullColour, wxNullColour, fixedB ); + new (&m_table[Color_StrongMagenta]) wxTextAttr( wxNullColour, wxNullColour, fixedB ); + new (&m_table[Color_StrongOrange]) wxTextAttr( wxNullColour, wxNullColour, fixedB ); + new (&m_table[Color_StrongGray]) wxTextAttr( wxNullColour, wxNullColour, fixedB ); - new (&m_table[Color_StrongCyan]) wxTextAttr( wxColor( 128, 180, 180 ), wxNullColour, fixedB ); - new (&m_table[Color_StrongYellow]) wxTextAttr( wxColor( 180, 180, 128 ), wxNullColour, fixedB ); - new (&m_table[Color_StrongWhite]) wxTextAttr( wxColor( 160, 160, 160 ), wxNullColour, fixedB ); + new (&m_table[Color_StrongCyan]) wxTextAttr( wxNullColour, wxNullColour, fixedB ); + new (&m_table[Color_StrongYellow]) wxTextAttr( wxNullColour, wxNullColour, fixedB ); + new (&m_table[Color_StrongWhite]) wxTextAttr( wxNullColour, wxNullColour, fixedB ); + + SetColorScheme_Light(); +} + +void ConsoleLogFrame::ColorArray::SetColorScheme_Dark() +{ + m_table[Color_Default] .SetTextColour(wxColor( 208, 208, 208 )); + m_table[Color_Black] .SetTextColour(wxColor( 255, 255, 255 )); + m_table[Color_Red] .SetTextColour(wxColor( 180, 0, 0 )); + m_table[Color_Green] .SetTextColour(wxColor( 0, 160, 0 )); + m_table[Color_Blue] .SetTextColour(wxColor( 32, 32, 204 )); + m_table[Color_Magenta] .SetTextColour(wxColor( 160, 0, 160 )); + m_table[Color_Orange] .SetTextColour(wxColor( 160, 120, 0 )); + m_table[Color_Gray] .SetTextColour(wxColor( 128, 128, 128 )); + + m_table[Color_Cyan] .SetTextColour(wxColor( 128, 180, 180 )); + m_table[Color_Yellow] .SetTextColour(wxColor( 180, 180, 128 )); + m_table[Color_White] .SetTextColour(wxColor( 160, 160, 160 )); + + m_table[Color_StrongBlack] .SetTextColour(wxColor( 255, 255, 255 )); + m_table[Color_StrongRed] .SetTextColour(wxColor( 180, 0, 0 )); + m_table[Color_StrongGreen] .SetTextColour(wxColor( 0, 160, 0 )); + m_table[Color_StrongBlue] .SetTextColour(wxColor( 32, 32, 204 )); + m_table[Color_StrongMagenta].SetTextColour(wxColor( 160, 0, 160 )); + m_table[Color_StrongOrange] .SetTextColour(wxColor( 160, 120, 0 )); + m_table[Color_StrongGray] .SetTextColour(wxColor( 128, 128, 128 )); + + m_table[Color_StrongCyan] .SetTextColour(wxColor( 128, 180, 180 )); + m_table[Color_StrongYellow] .SetTextColour(wxColor( 180, 180, 128 )); + m_table[Color_StrongWhite] .SetTextColour(wxColor( 160, 160, 160 )); +} + +void ConsoleLogFrame::ColorArray::SetColorScheme_Light() +{ + m_table[Color_Default] .SetTextColour(wxColor( 0, 0, 0 )); + m_table[Color_Black] .SetTextColour(wxColor( 0, 0, 0 )); + m_table[Color_Red] .SetTextColour(wxColor( 128, 0, 0 )); + m_table[Color_Green] .SetTextColour(wxColor( 0, 128, 0 )); + m_table[Color_Blue] .SetTextColour(wxColor( 0, 0, 128 )); + m_table[Color_Magenta] .SetTextColour(wxColor( 160, 0, 160 )); + m_table[Color_Orange] .SetTextColour(wxColor( 160, 120, 0 )); + m_table[Color_Gray] .SetTextColour(wxColor( 108, 108, 108 )); + + m_table[Color_Cyan] .SetTextColour(wxColor( 128, 180, 180 )); + m_table[Color_Yellow] .SetTextColour(wxColor( 180, 180, 128 )); + m_table[Color_White] .SetTextColour(wxColor( 160, 160, 160 )); + + m_table[Color_StrongBlack] .SetTextColour(wxColor( 0, 0, 0 )); + m_table[Color_StrongRed] .SetTextColour(wxColor( 128, 0, 0 )); + m_table[Color_StrongGreen] .SetTextColour(wxColor( 0, 128, 0 )); + m_table[Color_StrongBlue] .SetTextColour(wxColor( 0, 0, 128 )); + m_table[Color_StrongMagenta].SetTextColour(wxColor( 160, 0, 160 )); + m_table[Color_StrongOrange] .SetTextColour(wxColor( 160, 120, 0 )); + m_table[Color_StrongGray] .SetTextColour(wxColor( 108, 108, 108 )); + + m_table[Color_StrongCyan] .SetTextColour(wxColor( 128, 180, 180 )); + m_table[Color_StrongYellow] .SetTextColour(wxColor( 180, 180, 128 )); + m_table[Color_StrongWhite] .SetTextColour(wxColor( 160, 160, 160 )); } void ConsoleLogFrame::ColorArray::Cleanup() @@ -223,10 +277,19 @@ void ConsoleLogFrame::ColorArray::SetFont( int fontsize ) enum MenuIDs_t { - MenuID_FontSize_Small = 0x10, - MenuID_FontSize_Normal, - MenuID_FontSize_Large, - MenuID_FontSize_Huge, + MenuId_FontSize_Small = 0x10, + MenuId_FontSize_Normal, + MenuId_FontSize_Large, + MenuId_FontSize_Huge, + + MenuId_ColorScheme_Light = 0x20, + MenuId_ColorScheme_Dark, + + MenuId_LogSource_EnableAll = 0x30, + MenuId_LogSource_DisableAll, + MenuId_LogSource_Devel, + + MenuId_LogSource_Start = 0x100 }; #define pxTheApp ((Pcsx2App&)*wxTheApp) @@ -234,7 +297,7 @@ enum MenuIDs_t // -------------------------------------------------------------------------------------- // ScopedLogLock (implementations) // -------------------------------------------------------------------------------------- -class ScopedLogLock : ScopedLock +class ScopedLogLock : public ScopedLock { public: ConsoleLogFrame* WindowPtr; @@ -259,6 +322,45 @@ public: } }; +static ConsoleLogSource* const ConLogSources[] = +{ + (ConsoleLogSource*)&SysConsolePack.eeConsole, + (ConsoleLogSource*)&SysConsolePack.iopConsole, + (ConsoleLogSource*)&SysConsolePack.eeRecPerf, + NULL, + (ConsoleLogSource*)&SysConsolePack.ELF, + NULL, + (ConsoleLogSource*)&pxConLog_Event, + (ConsoleLogSource*)&pxConLog_Thread, +}; + +static const bool ConLogDefaults[] = +{ + true, + true, + false, + true, + false, + false, +}; + +void ConLog_LoadSaveSettings( IniInterface& ini ) +{ + ScopedIniGroup path(ini, L"ConsoleLogSources"); + + ini.Entry( L"Devel", DevConWriterEnabled, false ); + + uint srcnt = ArraySize(ConLogSources); + for (uint i=0; iGetCategory() + L"." + log->GetShortName(), log->Enabled, ConLogDefaults[i] ); + } + } +} + + // -------------------------------------------------------------------------------------- // ConsoleLogFrame (implementations) // -------------------------------------------------------------------------------------- @@ -278,9 +380,22 @@ ConsoleLogFrame::ConsoleLogFrame( MainEmuFrame *parent, const wxString& title, A m_pendingFlushMsg = false; m_FlushRefreshLocked = false; + // create Log menu (contains most options) + wxMenuBar *pMenuBar = new wxMenuBar(); + SetMenuBar( pMenuBar ); SetIcons( wxGetApp().GetIconBundle() ); - m_TextCtrl.SetBackgroundColour( wxColor( 230, 235, 242 ) ); + if (0==m_conf.Theme.CmpNoCase(L"Dark")) + { + m_ColorTable.SetColorScheme_Dark(); + m_TextCtrl.SetBackgroundColour( wxColor( 0, 0, 0 ) ); + } + else //if ((0==m_conf.Theme.CmpNoCase("Default")) || (0==m_conf.Theme.CmpNoCase("Light"))) + { + m_ColorTable.SetColorScheme_Light(); + m_TextCtrl.SetBackgroundColour( wxColor( 230, 235, 242 ) ); + } + m_TextCtrl.SetDefaultStyle( m_ColorTable[DefaultConsoleColor] ); // SetDefaultStyle only sets the style of text in the control. We need to @@ -292,39 +407,52 @@ ConsoleLogFrame::ConsoleLogFrame( MainEmuFrame *parent, const wxString& title, A wxMenu& menuSources (*new wxMenu()); wxMenu& menuFontSizes( menuAppear ); - // create Log menu (contains most options) - wxMenuBar *pMenuBar = new wxMenuBar(); - SetMenuBar( pMenuBar ); - // create Appearance menu and submenus - menuFontSizes.Append( MenuID_FontSize_Small, _("Small"), _("Fits a lot of log in a microcosmically small area."), + menuFontSizes.Append( MenuId_FontSize_Small, _("Small"), _("Fits a lot of log in a microcosmically small area."), wxITEM_RADIO )->Check( options.FontSize == 7 ); - menuFontSizes.Append( MenuID_FontSize_Normal, _("Normal"),_("It's what I use (the programmer guy)."), + menuFontSizes.Append( MenuId_FontSize_Normal, _("Normal"),_("It's what I use (the programmer guy)."), wxITEM_RADIO )->Check( options.FontSize == 8 ); - menuFontSizes.Append( MenuID_FontSize_Large, _("Large"), _("Its nice and readable."), + menuFontSizes.Append( MenuId_FontSize_Large, _("Large"), _("Its nice and readable."), wxITEM_RADIO )->Check( options.FontSize == 10 ); - menuFontSizes.Append( MenuID_FontSize_Huge, _("Huge"), _("In case you have a really high res display."), + menuFontSizes.Append( MenuId_FontSize_Huge, _("Huge"), _("In case you have a really high res display."), wxITEM_RADIO )->Check( options.FontSize == 12 ); + menuFontSizes.AppendSeparator(); + menuFontSizes.Append( MenuId_ColorScheme_Light, _("Light theme"), _("Default soft-tone color scheme."), wxITEM_RADIO ); + menuFontSizes.Append( MenuId_ColorScheme_Dark, _("Dark theme"), _("Classic black color scheme for people who enjoy having text seared into their optic nerves."), wxITEM_RADIO ); + menuAppear.AppendSeparator(); menuAppear.Append( wxID_ANY, _("Always on Top"), _("When checked the log window will be visible over other foreground windows."), wxITEM_CHECK ); - //menuAppear.Append( wxID_ANY, _("Font Size"), &menuFontSizes ); menuLog.Append(wxID_SAVE, _("&Save..."), _("Save log contents to file")); menuLog.Append(wxID_CLEAR, _("C&lear"), _("Clear the log window contents")); menuLog.AppendSeparator(); menuLog.AppendSubMenu( &menuAppear, _("Appearance") ); - menuLog.Append(wxID_ANY, _("Show Legend (unimplemented)"), _("Displays the console color legend.") ); menuLog.AppendSeparator(); menuLog.Append(wxID_CLOSE, _("&Close"), _("Close this log window; contents are preserved")); // Source Selection/Toggle menu - m_item_Deci2 = menuSources.AppendCheckItem( wxID_ANY, _("EE Deci2"), _("Enables debug output from the EEcore.") ); - m_item_StdoutEE = menuSources.AppendCheckItem( wxID_ANY, _("EE StdOut"), _("Enables STDOUT from the EEcore.") ); - m_item_StdoutIOP= menuSources.AppendCheckItem( wxID_ANY, _("IOP StdOut"), _("Enables STDOUT from the IOP.") ); + menuSources.Append( MenuId_LogSource_Devel, _("Dev/Verbose"), _("Shows PCSX2 developer logs"), wxITEM_CHECK ); + menuSources.AppendSeparator(); + + uint srcnt = ArraySize(ConLogSources); + for (uint i=0; iName, log->GetDescription(), wxITEM_CHECK ); + Connect( MenuId_LogSource_Start+i, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(ConsoleLogFrame::OnToggleSource)); + } + else + menuSources.AppendSeparator(); + } + + menuSources.AppendSeparator(); + menuSources.Append( MenuId_LogSource_EnableAll, _("Enable all"), _("Enables all log source filters.") ); + menuSources.Append( MenuId_LogSource_DisableAll, _("Disable all"), _("Disables all log source filters.") ); pMenuBar->Append(&menuLog, _("&Log")); pMenuBar->Append(&menuSources, _("&Sources")); @@ -342,11 +470,12 @@ ConsoleLogFrame::ConsoleLogFrame( MainEmuFrame *parent, const wxString& title, A Connect( wxID_SAVE, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(ConsoleLogFrame::OnSave) ); Connect( wxID_CLEAR, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(ConsoleLogFrame::OnClear) ); - Connect( MenuID_FontSize_Small, MenuID_FontSize_Huge, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( ConsoleLogFrame::OnFontSize ) ); + Connect( MenuId_FontSize_Small, MenuId_FontSize_Huge, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( ConsoleLogFrame::OnFontSize ) ); + Connect( MenuId_ColorScheme_Light, MenuId_ColorScheme_Dark, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( ConsoleLogFrame::OnToggleTheme ) ); - Connect( m_item_Deci2->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( ConsoleLogFrame::OnLogSourceChanged ) ); - Connect( m_item_StdoutEE->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( ConsoleLogFrame::OnLogSourceChanged ) ); - Connect( m_item_StdoutIOP->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( ConsoleLogFrame::OnLogSourceChanged ) ); + Connect( MenuId_LogSource_Devel, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( ConsoleLogFrame::OnToggleSource ) ); + Connect( MenuId_LogSource_EnableAll, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( ConsoleLogFrame::OnEnableAllLogging ) ); + Connect( MenuId_LogSource_DisableAll, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( ConsoleLogFrame::OnDisableAllLogging ) ); Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler (ConsoleLogFrame::OnCloseWindow) ); Connect( wxEVT_MOVE, wxMoveEventHandler (ConsoleLogFrame::OnMoveAround) ); @@ -359,12 +488,19 @@ ConsoleLogFrame::ConsoleLogFrame( MainEmuFrame *parent, const wxString& title, A 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 ); - m_item_StdoutIOP ->Check( g_Conf->EmuOptions.Log.StdoutIOP ); - if( m_threadlogger != NULL ) m_threadlogger->Start(); + + OnLoggingChanged(); + + if (0==m_conf.Theme.CmpNoCase(L"Dark")) + { + pMenuBar->Check(MenuId_ColorScheme_Dark, true); + } + else //if ((0==m_conf.Theme.CmpNoCase("Default")) || (0==m_conf.Theme.CmpNoCase("Light"))) + { + pMenuBar->Check(MenuId_ColorScheme_Light, true); + } } ConsoleLogFrame::~ConsoleLogFrame() @@ -373,6 +509,49 @@ ConsoleLogFrame::~ConsoleLogFrame() wxGetApp().OnProgramLogClosed( GetId() ); } +void ConsoleLogFrame::OnEnableAllLogging(wxCommandEvent& evt) +{ + uint srcnt = ArraySize(ConLogSources); + for (uint i=0; iEnabled = true; + } + + OnLoggingChanged(); + evt.Skip(); +} + +void ConsoleLogFrame::OnDisableAllLogging(wxCommandEvent& evt) +{ + uint srcnt = ArraySize(ConLogSources); + for (uint i=0; iEnabled = false; + } + + OnLoggingChanged(); + evt.Skip(); +} + +void ConsoleLogFrame::OnLoggingChanged() +{ + if (!GetMenuBar()) return; + + if( wxMenuItem* item = GetMenuBar()->FindItem(MenuId_LogSource_Devel) ) + item->Check( DevConWriterEnabled ); + + uint srcnt = ArraySize(ConLogSources); + for (uint i=0; iCheck( MenuId_LogSource_Start+i, log->IsEnabled() ); + } + } +} + // Implementation note: Calls SetColor and Write( text ). Override those virtuals // and this one will magically follow suite. :) bool ConsoleLogFrame::Write( ConsoleColors color, const wxString& text ) @@ -593,24 +772,71 @@ void ConsoleLogFrame::OnClear(wxCommandEvent& WXUNUSED(event)) m_TextCtrl.Clear(); } -void ConsoleLogFrame::OnLogSourceChanged( wxCommandEvent& evt ) +void ConsoleLogFrame::OnToggleSource( wxCommandEvent& evt ) { - g_Conf->EmuOptions.Log.Deci2 = m_item_Deci2 ->IsChecked(); - g_Conf->EmuOptions.Log.StdoutEE = m_item_StdoutEE ->IsChecked(); - g_Conf->EmuOptions.Log.StdoutIOP= m_item_StdoutIOP ->IsChecked(); + evt.Skip(); - CoreThread.ApplySettings( g_Conf->EmuOptions ); + if (!GetMenuBar()) return; + + if (evt.GetId() == MenuId_LogSource_Devel) + { + if( wxMenuItem* item = GetMenuBar()->FindItem(evt.GetId()) ) + DevConWriterEnabled = item->IsChecked(); + + return; + } + + uint srcid = evt.GetId() - MenuId_LogSource_Start; + + if (!pxAssertDev( ArraySize(ConLogSources) > srcid, "Invalid source log index (out of bounds)" )) return; + if (!pxAssertDev( ConLogSources[srcid] != NULL, "Invalid source log index (NULL pointer [separator])" )) return; + + if( wxMenuItem* item = GetMenuBar()->FindItem(evt.GetId()) ) + { + pxAssertDev( item->IsCheckable(), "Uncheckable log source menu item? Seems fishy!" ); + ConLogSources[srcid]->Enabled = item->IsChecked(); + } +} + +void ConsoleLogFrame::OnToggleTheme( wxCommandEvent& evt ) +{ + evt.Skip(); + + const wxChar* newTheme = L"Default"; + + switch( evt.GetId() ) + { + case MenuId_ColorScheme_Light: + newTheme = L"Default"; + m_ColorTable.SetColorScheme_Light(); + m_TextCtrl.SetBackgroundColour( wxColor( 230, 235, 242 ) ); + break; + + case MenuId_ColorScheme_Dark: + newTheme = L"Dark"; + m_ColorTable.SetColorScheme_Dark(); + m_TextCtrl.SetBackgroundColour( wxColor( 24, 24, 24 ) ); + break; + } + + if (0 == m_conf.Theme.CmpNoCase(newTheme)) return; + m_conf.Theme = newTheme; + + m_ColorTable.SetFont( m_conf.FontSize ); + m_TextCtrl.SetDefaultStyle( m_ColorTable[Color_White] ); } void ConsoleLogFrame::OnFontSize( wxCommandEvent& evt ) { + evt.Skip(); + int ptsize = 8; switch( evt.GetId() ) { - case MenuID_FontSize_Small: ptsize = 7; break; - case MenuID_FontSize_Normal: ptsize = 8; break; - case MenuID_FontSize_Large: ptsize = 10; break; - case MenuID_FontSize_Huge: ptsize = 12; break; + case MenuId_FontSize_Small: ptsize = 7; break; + case MenuId_FontSize_Normal: ptsize = 8; break; + case MenuId_FontSize_Large: ptsize = 10; break; + case MenuId_FontSize_Huge: ptsize = 12; break; } if( ptsize == m_conf.FontSize ) return; @@ -780,7 +1006,7 @@ static void __concall ConsoleToFile_Newline() static void __concall ConsoleToFile_DoWrite( const wxString& fmt ) { #ifdef __LINUX__ - if (g_Conf->EmuOptions.ConsoleToStdio) ConsoleWriter_Stdout.DoWrite(fmt); + if (g_Conf->EmuOptions.ConsoleToStdio) ConsoleWriter_Stdout.WriteRaw(fmt); #endif px_fputs( emuLog, fmt.ToUTF8() ); @@ -844,25 +1070,21 @@ static void __concall ConsoleToWindow_Newline() { secondary.Newline(); - bool needsSleep = false; - { - ScopedLogLock locker; - if( locker.WindowPtr ) needsSleep = locker.WindowPtr->Newline(); - } + ScopedLogLock locker; + bool needsSleep = locker.WindowPtr && locker.WindowPtr->Newline(); + locker.Release(); if( needsSleep ) wxGetApp().Ping(); } template< const IConsoleWriter& secondary > static void __concall ConsoleToWindow_DoWrite( const wxString& fmt ) { - if( secondary.DoWrite != NULL ) - secondary.DoWrite( fmt ); + if( secondary.WriteRaw != NULL ) + secondary.WriteRaw( fmt ); - bool needsSleep = false; - { - ScopedLogLock locker; - if( locker.WindowPtr ) needsSleep = locker.WindowPtr->Write( Console.GetColor(), fmt ); - } + ScopedLogLock locker; + bool needsSleep = locker.WindowPtr && locker.WindowPtr->Write( Console.GetColor(), fmt ); + locker.Release(); if( needsSleep ) wxGetApp().Ping(); } @@ -872,11 +1094,9 @@ static void __concall ConsoleToWindow_DoWriteLn( const wxString& fmt ) if( secondary.DoWriteLn != NULL ) secondary.DoWriteLn( fmt ); - bool needsSleep = false; - { - ScopedLogLock locker; - if( locker.WindowPtr ) needsSleep = locker.WindowPtr->Write( Console.GetColor(), fmt + L'\n' ); - } + ScopedLogLock locker; + bool needsSleep = locker.WindowPtr && locker.WindowPtr->Write( Console.GetColor(), fmt + L'\n' ); + locker.Release(); if( needsSleep ) wxGetApp().Ping(); } diff --git a/pcsx2/gui/ConsoleLogger.h b/pcsx2/gui/ConsoleLogger.h index 412491ecd9..8eecb63bb0 100644 --- a/pcsx2/gui/ConsoleLogger.h +++ b/pcsx2/gui/ConsoleLogger.h @@ -94,11 +94,8 @@ class pxLogTextCtrl : public wxTextCtrl, public EventListener_Plugins { protected: - //EventListenerHelper_CoreThread m_listener_CoreThread; - //EventListenerHelper_Plugins m_listener_Plugins; - - ScopedPtr m_IsPaused; - bool m_FreezeWrites; + ScopedPtr m_IsPaused; + bool m_FreezeWrites; public: pxLogTextCtrl(wxWindow* parent); @@ -153,6 +150,9 @@ protected: { return m_table[(int)coloridx]; } + + void SetColorScheme_Dark(); + void SetColorScheme_Light(); }; class ColorSection @@ -217,9 +217,7 @@ protected: // Window and Menu Object Handles // ---------------------------------------------------------------------------- - wxMenuItem* m_item_Deci2; - wxMenuItem* m_item_StdoutEE; - wxMenuItem* m_item_StdoutIOP; + ScopedArray m_sourceChecks; public: // ctor & dtor @@ -237,13 +235,17 @@ public: protected: // menu callbacks - virtual void OnOpen (wxCommandEvent& event); - virtual void OnClose(wxCommandEvent& event); - virtual void OnSave (wxCommandEvent& event); - virtual void OnClear(wxCommandEvent& event); + void OnOpen (wxCommandEvent& event); + void OnClose(wxCommandEvent& event); + void OnSave (wxCommandEvent& event); + void OnClear(wxCommandEvent& event); + void OnEnableAllLogging(wxCommandEvent& event); + void OnDisableAllLogging(wxCommandEvent& event); + + void OnToggleTheme(wxCommandEvent& event); void OnFontSize(wxCommandEvent& event); - void OnLogSourceChanged(wxCommandEvent& event); + void OnToggleSource(wxCommandEvent& event); virtual void OnCloseWindow(wxCloseEvent& event); @@ -254,9 +256,10 @@ protected: void DoFlushQueue(); void DoFlushEvent( bool isPending ); - + void OnMoveAround( wxMoveEvent& evt ); void OnResize( wxSizeEvent& evt ); void OnActivate( wxActivateEvent& evt ); + + void OnLoggingChanged(); }; - diff --git a/pcsx2/gui/Dialogs/BaseConfigurationDialog.inl b/pcsx2/gui/Dialogs/BaseConfigurationDialog.inl index c17d06fb1e..3aca3a124d 100644 --- a/pcsx2/gui/Dialogs/BaseConfigurationDialog.inl +++ b/pcsx2/gui/Dialogs/BaseConfigurationDialog.inl @@ -18,11 +18,10 @@ #include template< typename T > -void Dialogs::BaseConfigurationDialog::AddPage( const char* label, int iconid ) +void Dialogs::BaseConfigurationDialog::AddPage( const wxChar* label, int iconid ) { - const wxString labelstr( fromUTF8( label ) ); - const int curidx = m_labels.Add( labelstr ); + const int curidx = m_labels.Add( label ); m_ApplyState.SetCurrentPage( curidx ); - m_listbook->AddPage( new T( m_listbook ), wxGetTranslation( labelstr ), - ( labelstr == GetConfSettingsTabName() ), iconid ); + m_listbook->AddPage( new T( m_listbook ), wxGetTranslation( label ), + ( 0 == GetConfSettingsTabName().CmpNoCase(label) ), iconid ); } diff --git a/pcsx2/gui/Dialogs/ConfigurationDialog.h b/pcsx2/gui/Dialogs/ConfigurationDialog.h index c783e759d6..e12f36c637 100644 --- a/pcsx2/gui/Dialogs/ConfigurationDialog.h +++ b/pcsx2/gui/Dialogs/ConfigurationDialog.h @@ -57,7 +57,7 @@ namespace Dialogs virtual void SomethingChanged(); template< typename T > - void AddPage( const char* label, int iconid ); + void AddPage( const wxChar* label, int iconid ); protected: void OnSettingsApplied( wxCommandEvent& evt ); diff --git a/pcsx2/gui/ExecutorThread.cpp b/pcsx2/gui/ExecutorThread.cpp index 2976c45ebb..f28cfeb7c7 100644 --- a/pcsx2/gui/ExecutorThread.cpp +++ b/pcsx2/gui/ExecutorThread.cpp @@ -18,6 +18,25 @@ using namespace pxSizerFlags; +// -------------------------------------------------------------------------------------- +// ConsoleLogSource_Event (implementations) +// -------------------------------------------------------------------------------------- + +bool ConsoleLogSource_Event::Write( const pxEvtHandler* evtHandler, const SysExecEvent* evt, const wxChar* msg ) { + return _parent::Write( wxsFormat(L"(%s%s) ", evtHandler->GetEventHandlerName().c_str(), evt->GetEventName().c_str()) + msg ); +} +bool ConsoleLogSource_Event::Warn( const pxEvtHandler* evtHandler, const SysExecEvent* evt, const wxChar* msg ) { + return _parent::Write( wxsFormat(L"(%s%s) ", evtHandler->GetEventHandlerName().c_str(), evt->GetEventName().c_str()) + msg ); +} +bool ConsoleLogSource_Event::Error( const pxEvtHandler* evtHandler, const SysExecEvent* evt, const wxChar* msg ) { + return _parent::Write( wxsFormat(L"(%s%s) ", evtHandler->GetEventHandlerName().c_str(), evt->GetEventName().c_str()) + msg ); +} + +ConsoleLogSource_Event pxConLog_Event; + +// -------------------------------------------------------------------------------------- +// SysExecEvent (implementations) +// -------------------------------------------------------------------------------------- wxString SysExecEvent::GetEventName() const { pxFail( "Warning: Unnamed SysExecutor Event! Please overload GetEventName() in all SysExecEvent derived classes." ); @@ -159,7 +178,8 @@ struct ScopedThreadCancelDisable } }; -void pxEvtHandler::ProcessEvents( pxEvtList& list ) +// isIdle - parameter is useful for logging only (currently) +void pxEvtHandler::ProcessEvents( pxEvtList& list, bool isIdle ) { ScopedLock synclock( m_mtx_pending ); @@ -179,7 +199,9 @@ void pxEvtHandler::ProcessEvents( pxEvtList& list ) synclock.Release(); - DevCon.WriteLn( L"(pxEvtHandler) Executing Event: %s [%s]", deleteMe->GetEventName().c_str(), deleteMe->AllowCancelOnExit() ? L"Cancelable" : L"Noncancelable" ); + pxEvtLog.Write( this, deleteMe, wxsFormat(L"Executing... [%s]%s", + deleteMe->AllowCancelOnExit() ? L"Cancelable" : L"Noncancelable", isIdle ? L"(Idle)" : wxEmptyString) + ); if( deleteMe->AllowCancelOnExit() ) deleteMe->_DoInvokeEvent(); @@ -190,14 +212,16 @@ void pxEvtHandler::ProcessEvents( pxEvtList& list ) } u64 qpc_end = GetCPUTicks(); - DevCon.WriteLn( L"(pxEvtHandler) Event '%s' completed in %ums", deleteMe->GetEventName().c_str(), (u32)(((qpc_end-m_qpc_Start)*1000) / GetTickFrequency()) ); + pxEvtLog.Write( this, deleteMe, wxsFormat(L"Event completed in %ums", + (u32)(((qpc_end-m_qpc_Start)*1000) / GetTickFrequency())) + ); synclock.Acquire(); m_qpc_Start = 0; // lets the main thread know the message completed. } else { - Console.WriteLn( L"(pxEvtHandler) Skipping Event: %s", deleteMe->GetEventName().c_str() ); + pxEvtLog.Write( this, deleteMe, L"Skipping Event: %s" ); deleteMe->PostResult(); } } @@ -205,7 +229,7 @@ void pxEvtHandler::ProcessEvents( pxEvtList& list ) void pxEvtHandler::ProcessIdleEvents() { - ProcessEvents( m_idleEvents ); + ProcessEvents( m_idleEvents, true ); } void pxEvtHandler::ProcessPendingEvents() @@ -214,7 +238,7 @@ void pxEvtHandler::ProcessPendingEvents() } // This method is provided for wxWidgets API conformance. I like to use PostEvent instead -// since it's remenicient of PostMessage in Windows (and behaves rather similarly). +// since it's reminiscent of PostMessage in Windows (and behaves rather similarly). void pxEvtHandler::AddPendingEvent( SysExecEvent& evt ) { PostEvent( evt ); @@ -239,8 +263,8 @@ void pxEvtHandler::PostEvent( SysExecEvent* evt ) ScopedLock synclock( m_mtx_pending ); - //DbgCon.WriteLn( L"(%s) Posting event: %s (queue count=%d)", GetEventHandlerName().c_str(), evt->GetEventName().c_str(), m_pendingEvents.size() ); - + pxEvtLog.Write( this, evt, wxsFormat(L"Posting event! (pending=%d, idle=%d)", m_pendingEvents.size(), m_idleEvents.size()) ); + m_pendingEvents.push_back( sevt.DetachPtr() ); if( m_pendingEvents.size() == 1) m_wakeup.Post(); @@ -263,7 +287,9 @@ void pxEvtHandler::PostIdleEvent( SysExecEvent* evt ) ScopedLock synclock( m_mtx_pending ); - if( m_idleEvents.size() == 0) + pxEvtLog.Write( this, evt, wxsFormat(L"Posting event! (pending=%d, idle=%d) [idle]", m_pendingEvents.size(), m_idleEvents.size()) ); + + if( m_pendingEvents.size() == 0) { m_pendingEvents.push_back( evt ); m_wakeup.Post(); @@ -308,23 +334,24 @@ void pxEvtHandler::ProcessEvent( SysExecEvent* evt ) } } -bool pxEvtHandler::Rpc_TryInvokeAsync( FnType_Void* method ) +bool pxEvtHandler::Rpc_TryInvokeAsync( FnType_Void* method, const wxChar* traceName ) { if( wxThread::GetCurrentId() != m_OwnerThreadId ) { - PostEvent( new SysExecEvent_MethodVoid(method) ); + PostEvent( new SysExecEvent_MethodVoid(method, traceName) ); return true; } return false; } -bool pxEvtHandler::Rpc_TryInvoke( FnType_Void* method ) +bool pxEvtHandler::Rpc_TryInvoke( FnType_Void* method, const wxChar* traceName ) { if( wxThread::GetCurrentId() != m_OwnerThreadId ) { SynchronousActionState sync; - SysExecEvent_MethodVoid evt(method, true); + SysExecEvent_MethodVoid evt(method); + evt.Critical(); evt.SetSyncState( sync ); PostEvent( evt ); sync.WaitForResult(); diff --git a/pcsx2/gui/MSWstuff.cpp b/pcsx2/gui/MSWstuff.cpp index d8be803d10..59b0f6fa77 100644 --- a/pcsx2/gui/MSWstuff.cpp +++ b/pcsx2/gui/MSWstuff.cpp @@ -32,21 +32,6 @@ void MSW_SetWindowAfter( WXWidget hwnd, WXWidget hwndAfter ) #endif } -// Writes text to the Visual Studio Output window (Microsoft Windows only). -// On all other platforms this pipes to StdErr instead. -void MSW_OutputDebugString( const wxString& text ) -{ -#if defined(__WXMSW__) && !defined(__WXMICROWIN__) - // don't prepend debug/trace here: it goes to the - // debug window anyhow - OutputDebugString( text + L"\r\n" ); -#else - // send them to stderr - wxFprintf(stderr, L"%s\n", text.c_str()); - fflush(stderr); -#endif -} - void MSW_ListView_SetIconSpacing( wxListbook& listbook, int width ) { #ifdef __WXMSW__ diff --git a/pcsx2/gui/MessageBoxes.cpp b/pcsx2/gui/MessageBoxes.cpp index ecfb369f2a..5b34674f26 100644 --- a/pcsx2/gui/MessageBoxes.cpp +++ b/pcsx2/gui/MessageBoxes.cpp @@ -163,7 +163,7 @@ namespace Msgbox } } - static int ShowModal( const wxString& title, const wxString& content, const MsgButtons& buttons ) + int ShowModal( const wxString& title, const wxString& content, const MsgButtons& buttons ) { pxMessageBoxEvent tevt( title, content, buttons ); return ShowModal( tevt ); diff --git a/pcsx2/gui/Panels/BaseApplicableConfigPanel.cpp b/pcsx2/gui/Panels/BaseApplicableConfigPanel.cpp index c8c1295991..bdbd4aad1f 100644 --- a/pcsx2/gui/Panels/BaseApplicableConfigPanel.cpp +++ b/pcsx2/gui/Panels/BaseApplicableConfigPanel.cpp @@ -24,7 +24,7 @@ using namespace Dialogs; // ----------------------------------------------------------------------- -// This method should be called by the parent dalog box of a configuration +// This method should be called by the parent dialog box of a configuration // on dialog destruction. It asserts if the ApplyList hasn't been cleaned up // and then cleans it up forcefully. // @@ -94,7 +94,7 @@ bool ApplyStateStruct::ApplyPage( int pageid ) if( ex.IsVerbose ) { - wxMessageBox( ex.FormatDisplayMessage(), _("Cannot apply settings...") ); + Msgbox::Alert( ex.FormatDisplayMessage(), _("Cannot apply settings...") ); if( ex.GetPanel() != NULL ) ex.GetPanel()->SetFocusToMe(); diff --git a/pcsx2/gui/Panels/LogOptionsPanels.cpp b/pcsx2/gui/Panels/LogOptionsPanels.cpp index fa5c71e2af..561afc2d03 100644 --- a/pcsx2/gui/Panels/LogOptionsPanels.cpp +++ b/pcsx2/gui/Panels/LogOptionsPanels.cpp @@ -16,58 +16,31 @@ #include "PrecompiledHeader.h" #include "LogOptionsPanels.h" +#include "Utilities/IniInterface.h" #include "DebugTools/Debug.h" + #include using namespace pxSizerFlags; Panels::eeLogOptionsPanel::eeLogOptionsPanel( LogOptionsPanel* parent ) - : CheckedStaticBox( parent, wxVERTICAL, L"EE Logs" ) + : BaseCpuLogOptionsPanel( parent, L"EE Logs" ) { - SetMinWidth( 260 ); + SetMinWidth( 300 ); + + m_miscGroup = new wxStaticBoxSizer( wxVERTICAL, this, L"General" ); m_disasmPanel = new CheckedStaticBox( this, wxVERTICAL, L"Disasm" ); - m_hwPanel = new CheckedStaticBox( this, wxVERTICAL, L"Hardware" ); + m_hwPanel = new CheckedStaticBox( this, wxVERTICAL, L"Registers" ); m_evtPanel = new CheckedStaticBox( this, wxVERTICAL, L"Events" ); - wxSizer& s_disasm ( m_disasmPanel->ThisSizer ); - wxSizer& s_hw ( m_hwPanel->ThisSizer ); - wxSizer& s_evt ( m_evtPanel->ThisSizer ); - - wxStaticBoxSizer& s_misc = *new wxStaticBoxSizer( wxVERTICAL, this, L"General" ); - wxPanelWithHelpers* m_miscPanel = this; // helper for our newCheckBox macro. - - s_misc.Add( m_Bios = new pxCheckBox( m_miscPanel, L"Bios" ) ); - s_misc.Add( m_Memory = new pxCheckBox( m_miscPanel, L"Memory" ) ); - s_misc.Add( m_Cache = new pxCheckBox( m_miscPanel, L"Cache" )); - s_misc.Add( m_SysCtrl = new pxCheckBox( m_miscPanel, L"SysCtrl / MMU" ) ); - - s_disasm.Add( m_R5900 = new pxCheckBox( m_disasmPanel, L"R5900" )); - s_disasm.Add( m_COP0 = new pxCheckBox( m_disasmPanel, L"COP0 (MMU/SysCtrl)" )); - s_disasm.Add( m_COP1 = new pxCheckBox( m_disasmPanel, L"COP1 (FPU)" )); - s_disasm.Add( m_COP2 = new pxCheckBox( m_disasmPanel, L"COP2 (VU0 macro)" )); - s_disasm.Add( m_VU0micro = new pxCheckBox( m_disasmPanel, L"VU0 micro" )); - s_disasm.Add( m_VU1micro = new pxCheckBox( m_disasmPanel, L"VU1 micro" )); - - s_hw.Add( m_KnownHw = new pxCheckBox( m_hwPanel, L"Registers" )); - s_hw.Add( m_UnknownHw = new pxCheckBox( m_hwPanel, L"Unknown Regs" )); - s_hw.Add( m_DMA = new pxCheckBox( m_hwPanel, L"DMA" )); - - s_evt.Add( m_Counters = new pxCheckBox( m_evtPanel, L"Counters" )); - s_evt.Add( m_VIF = new pxCheckBox( m_evtPanel, L"VIF" )); - s_evt.Add( m_GIF = new pxCheckBox( m_evtPanel, L"GIF" )); - s_evt.Add( m_IPU = new pxCheckBox( m_evtPanel, L"IPU" )); - s_evt.Add( m_SPR = new pxCheckBox( m_evtPanel, L"SPR" )); - - m_Cache->SetToolTip(_("(not implemented yet)")); - wxFlexGridSizer& eeTable( *new wxFlexGridSizer( 2, 5 ) ); eeTable.AddGrowableCol(0); eeTable.AddGrowableCol(1); - eeTable += s_misc | SubGroup(); + eeTable += m_miscGroup | SubGroup(); eeTable += m_hwPanel | SubGroup(); eeTable += m_evtPanel | SubGroup(); eeTable += m_disasmPanel | SubGroup(); @@ -79,46 +52,22 @@ Panels::eeLogOptionsPanel::eeLogOptionsPanel( LogOptionsPanel* parent ) } Panels::iopLogOptionsPanel::iopLogOptionsPanel( LogOptionsPanel* parent ) - : CheckedStaticBox( parent, wxVERTICAL, L"IOP Logs" ) + : BaseCpuLogOptionsPanel( parent, L"IOP Logs" ) { - SetMinWidth( 260 ); + SetMinWidth( 280 ); + + m_miscGroup = new wxStaticBoxSizer( wxVERTICAL, this, L"General" ); m_disasmPanel = new CheckedStaticBox( this, wxVERTICAL, L"Disasm" ); - m_hwPanel = new CheckedStaticBox( this, wxVERTICAL, L"Hardware" ); + m_hwPanel = new CheckedStaticBox( this, wxVERTICAL, L"Registers" ); m_evtPanel = new CheckedStaticBox( this, wxVERTICAL, L"Events" ); - wxSizer& s_disasm ( m_disasmPanel->ThisSizer ); - wxSizer& s_hw ( m_hwPanel->ThisSizer ); - wxSizer& s_evt ( m_evtPanel->ThisSizer ); - - wxStaticBoxSizer& s_misc = *new wxStaticBoxSizer( wxVERTICAL, this, L"General" ); - wxPanelWithHelpers* m_miscPanel = this; // helper for our newCheckBox macro. - - s_misc += m_Bios = new pxCheckBox( m_miscPanel, L"Bios" ); - s_misc += m_Memory = new pxCheckBox( m_miscPanel, L"Memory" ); - s_misc += m_GPU = new pxCheckBox( m_miscPanel, L"GPU (PS1 only)", L"(Not implemented yet)" ); - - s_disasm += m_R3000A = new pxCheckBox( m_disasmPanel, L"R3000A" ); - s_disasm += m_COP2 = new pxCheckBox( m_disasmPanel, L"COP2 (Geometry)" ); - - s_hw += m_KnownHw = new pxCheckBox( m_hwPanel, L"Registers" ); - s_hw += m_UnknownHw = new pxCheckBox( m_hwPanel, L"UnknownRegs" ); - s_hw += m_DMA = new pxCheckBox( m_hwPanel, L"DMA" ); - - s_evt += m_Counters = new pxCheckBox( m_evtPanel, L"Counters" ); - s_evt += m_Memcards = new pxCheckBox( m_evtPanel, L"Memcards" ); - s_evt += m_PAD = new pxCheckBox( m_evtPanel, L"Pad" ); - s_evt += m_SPU2 = new pxCheckBox( m_evtPanel, L"SPU2" ); - s_evt += m_CDVD = new pxCheckBox( m_evtPanel, L"CDVD" ); - s_evt += m_USB = new pxCheckBox( m_evtPanel, L"USB" ); - s_evt += m_FW = new pxCheckBox( m_evtPanel, L"FW" ); - wxFlexGridSizer& iopTable( *new wxFlexGridSizer( 2, 5 ) ); iopTable.AddGrowableCol(0); iopTable.AddGrowableCol(1); - iopTable += s_misc | SubGroup(); + iopTable += m_miscGroup | SubGroup(); iopTable += m_hwPanel | SubGroup(); iopTable += m_evtPanel | SubGroup(); iopTable += m_disasmPanel | SubGroup(); @@ -129,8 +78,24 @@ Panels::iopLogOptionsPanel::iopLogOptionsPanel( LogOptionsPanel* parent ) SetValue( true ); } -#define SetCheckValue( cpu, key ) \ - if( m_##key != NULL ) m_##key->SetValue( conf.cpu.m_##key ); +CheckedStaticBox* Panels::eeLogOptionsPanel::GetStaticBox( const wxString& subgroup ) const +{ + if (0 == subgroup.CmpNoCase( L"Disasm" )) return m_disasmPanel; + if (0 == subgroup.CmpNoCase( L"Registers" )) return m_hwPanel; + if (0 == subgroup.CmpNoCase( L"Events" )) return m_evtPanel; + + return NULL; +} + +CheckedStaticBox* Panels::iopLogOptionsPanel::GetStaticBox( const wxString& subgroup ) const +{ + if (0 == subgroup.CmpNoCase( L"Disasm" )) return m_disasmPanel; + if (0 == subgroup.CmpNoCase( L"Registers" )) return m_hwPanel; + if (0 == subgroup.CmpNoCase( L"Events" )) return m_evtPanel; + + return NULL; +} + void Panels::eeLogOptionsPanel::OnSettingsChanged() { @@ -138,31 +103,9 @@ void Panels::eeLogOptionsPanel::OnSettingsChanged() SetValue( conf.EE.m_EnableAll ); - m_disasmPanel->SetValue( conf.EE.m_EnableDisasm ); - m_evtPanel->SetValue( conf.EE.m_EnableEvents ); - m_hwPanel->SetValue( conf.EE.m_EnableHardware ); - - SetCheckValue( EE, Bios ); - SetCheckValue( EE, Memory ); - SetCheckValue( EE, Cache ); - SetCheckValue( EE, SysCtrl ); - - SetCheckValue( EE, R5900 ); - SetCheckValue( EE, COP0 ); - SetCheckValue( EE, COP1 ); - SetCheckValue( EE, COP2 ); - SetCheckValue(EE, VU0micro); - SetCheckValue(EE, VU1micro); - - SetCheckValue(EE, KnownHw); - SetCheckValue(EE, UnknownHw); - SetCheckValue(EE, DMA); - - SetCheckValue(EE, Counters); - SetCheckValue(EE, VIF); - SetCheckValue(EE, GIF); - SetCheckValue(EE, IPU); - SetCheckValue(EE, SPR); + m_disasmPanel ->SetValue( conf.EE.m_EnableDisasm ); + m_evtPanel ->SetValue( conf.EE.m_EnableEvents ); + m_hwPanel ->SetValue( conf.EE.m_EnableRegisters ); } void Panels::iopLogOptionsPanel::OnSettingsChanged() @@ -171,28 +114,87 @@ void Panels::iopLogOptionsPanel::OnSettingsChanged() SetValue( conf.IOP.m_EnableAll ); - m_disasmPanel->SetValue( conf.IOP.m_EnableDisasm ); - m_evtPanel->SetValue( conf.IOP.m_EnableEvents ); - m_hwPanel->SetValue( conf.IOP.m_EnableHardware ); + m_disasmPanel ->SetValue( conf.IOP.m_EnableDisasm ); + m_evtPanel ->SetValue( conf.IOP.m_EnableEvents ); + m_hwPanel ->SetValue( conf.IOP.m_EnableRegisters ); +} - SetCheckValue(IOP, Bios); - SetCheckValue(IOP, Memory); - SetCheckValue(IOP, GPU); +static SysTraceLog * const traceLogList[] = +{ + &SysTracePack.SIF, - SetCheckValue(IOP, R3000A); - SetCheckValue(IOP, COP2); + &SysTracePack.EE.Bios, + &SysTracePack.EE.Memory, - SetCheckValue(IOP, KnownHw); - SetCheckValue(IOP, UnknownHw); - SetCheckValue(IOP, DMA); + &SysTracePack.EE.R5900, + &SysTracePack.EE.COP0, + &SysTracePack.EE.COP1, + &SysTracePack.EE.COP2, + &SysTracePack.EE.Cache, - SetCheckValue(IOP, Counters); - SetCheckValue(IOP, Memcards); - SetCheckValue(IOP, PAD); - SetCheckValue(IOP, SPU2); - SetCheckValue(IOP, CDVD); - SetCheckValue(IOP, USB); - SetCheckValue(IOP, FW); + &SysTracePack.EE.KnownHw, + &SysTracePack.EE.UnknownHw, + &SysTracePack.EE.DMAhw, + &SysTracePack.EE.IPU, + &SysTracePack.EE.GIFtag, + &SysTracePack.EE.VIFcode, + + &SysTracePack.EE.DMAC, + &SysTracePack.EE.Counters, + &SysTracePack.EE.SPR, + &SysTracePack.EE.VIF, + &SysTracePack.EE.GIF, + + + // IOP Section + + &SysTracePack.IOP.Bios, + &SysTracePack.IOP.Memcards, + &SysTracePack.IOP.PAD, + + &SysTracePack.IOP.R3000A, + &SysTracePack.IOP.COP2, + &SysTracePack.IOP.Memory, + + &SysTracePack.IOP.KnownHw, + &SysTracePack.IOP.UnknownHw, + &SysTracePack.IOP.DMAhw, + &SysTracePack.IOP.DMAC, + &SysTracePack.IOP.Counters, + &SysTracePack.IOP.CDVD, +}; + +static const int traceLogCount = ArraySize(traceLogList); + +void SysTraceLog_LoadSaveSettings( IniInterface& ini ) +{ + ScopedIniGroup path(ini, L"TraceLogSources"); + + for (uint i=0; iName, "Trace log without a name!" ); + ini.Entry( log->GetCategory() + L"." + log->GetShortName(), log->Enabled, false ); + } + } +} + +static bool traceLogEnabled( const wxString& ident ) +{ + // Brute force search for now. not enough different source logs to + // justify using a hash table, and switching over to a "complex" class + // type from the current simple array initializer requires effort to + // avoid C++ global initializer dependency hell. + + for( uint i=0; iGetCategory()) ) + return traceLogList[i]->Enabled; + } + + pxAssertDev( false, wxsFormat(L"Invalid or unknown TraceLog identifier: %s", ident.c_str()) ); + return false; } // -------------------------------------------------------------------------------------- @@ -200,26 +202,54 @@ void Panels::iopLogOptionsPanel::OnSettingsChanged() // -------------------------------------------------------------------------------------- Panels::LogOptionsPanel::LogOptionsPanel(wxWindow* parent ) : BaseApplicableConfigPanel( parent ) - , m_eeSection ( *new eeLogOptionsPanel( this ) ) - , m_iopSection ( *new iopLogOptionsPanel( this ) ) + , m_checks( traceLogCount ) { + wxStaticBoxSizer& s_misc = *new wxStaticBoxSizer( wxHORIZONTAL, this, L"Misc" ); + + m_eeSection = new eeLogOptionsPanel( this ); + m_iopSection = new iopLogOptionsPanel( this ); + + for( uint i = 0; iGetStaticBox(group)) + { + addsizer = &cpugroup->ThisSizer; + addparent = cpugroup; + } + else + { + addsizer = cpupanel->GetMiscGroup(); + addparent = cpupanel; + } + } + else + { + addsizer = &s_misc; + addparent = this; + } + + *addsizer += m_checks[i] = new pxCheckBox( addparent, item.Name ); + if( m_checks[i] && item.Description ) + m_checks[i]->SetToolTip(item.GetDescription()); + } + m_masterEnabler = new pxCheckBox( this, _("Enable Trace Logging"), _("Trace logs are all written to emulog.txt. Toggle trace logging at any time using F10.") ); m_masterEnabler->SetToolTip( _("Warning: Enabling trace logs is typically very slow, and is a leading cause of 'What happened to my FPS?' problems. :)") ); - m_SIF = new pxCheckBox( this, L"SIF (EE<->IOP)" ); - m_VIFunpack = new pxCheckBox( this, L"VIFunpack" ); - m_GIFtag = new pxCheckBox( this, L"GIFtag" ); - m_Elf = new pxCheckBox( this, L"Elves" ); - - m_SIF ->SetToolTip(_("Enables logging of both SIF DMAs and SIF Register activity.") ); - m_VIFunpack ->SetToolTip(_("Special detailed logs of VIF packed data handling (does not include VIF control, status, or hwRegs)")); - m_GIFtag ->SetToolTip(_("(not implemented yet)")); - m_Elf ->SetToolTip(_("Logging of Elf headers.")); - - - wxFlexGridSizer& topSizer = *new wxFlexGridSizer( 2 ); - wxStaticBoxSizer& s_misc = *new wxStaticBoxSizer( wxHORIZONTAL, this, L"Misc" ); + wxFlexGridSizer& topSizer = *new wxFlexGridSizer( 2 ); topSizer.AddGrowableCol(0); topSizer.AddGrowableCol(1); @@ -227,11 +257,6 @@ Panels::LogOptionsPanel::LogOptionsPanel(wxWindow* parent ) topSizer += m_eeSection | StdExpand(); topSizer += m_iopSection | StdExpand(); - s_misc += m_SIF; - s_misc += m_VIFunpack; - s_misc += m_GIFtag; - s_misc += m_Elf; - *this += m_masterEnabler | StdExpand(); *this += new wxStaticLine( this ) | StdExpand().Border(wxLEFT | wxRIGHT, 20); *this += 5; @@ -239,8 +264,14 @@ Panels::LogOptionsPanel::LogOptionsPanel(wxWindow* parent ) *this += s_misc | StdSpace().Centre(); Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(LogOptionsPanel::OnCheckBoxClicked) ); +} - AppStatusEvent_OnSettingsApplied(); +Panels::BaseCpuLogOptionsPanel* Panels::LogOptionsPanel::GetCpuPanel( const wxString& token ) const +{ + if( token == L"EE" ) return m_eeSection; + if( token == L"IOP" ) return m_iopSection; + + return NULL; } void Panels::LogOptionsPanel::AppStatusEvent_OnSettingsApplied() @@ -248,15 +279,15 @@ void Panels::LogOptionsPanel::AppStatusEvent_OnSettingsApplied() TraceLogFilters& conf( g_Conf->EmuOptions.Trace ); m_masterEnabler->SetValue( conf.Enabled ); - m_SIF->SetValue( conf.SIF ); - m_Elf->SetValue( g_Conf->EmuOptions.Log.ELF ); - SetCheckValue( EE, VIFunpack ); - SetCheckValue( EE, GIFtag ); - - m_eeSection.OnSettingsChanged(); - m_iopSection.OnSettingsChanged(); + m_eeSection->OnSettingsChanged(); + m_iopSection->OnSettingsChanged(); + for (uint i=0; iSetValue(traceLogList[i]->Enabled); + } OnUpdateEnableAll(); } @@ -264,13 +295,8 @@ void Panels::LogOptionsPanel::OnUpdateEnableAll() { bool enabled( m_masterEnabler->GetValue() ); - m_SIF->Enable( enabled ); - m_Elf->Enable( enabled ); - m_VIFunpack->Enable( enabled ); - m_GIFtag->Enable( enabled ); - - m_eeSection.Enable( enabled ); - m_iopSection.Enable( enabled ); + m_eeSection->Enable( enabled ); + m_iopSection->Enable( enabled ); } void Panels::LogOptionsPanel::OnCheckBoxClicked(wxCommandEvent &evt) @@ -285,19 +311,20 @@ void Panels::LogOptionsPanel::Apply() if( !m_IsDirty ) return; g_Conf->EmuOptions.Trace.Enabled = m_masterEnabler->GetValue(); - g_Conf->EmuOptions.Trace.SIF = m_SIF->GetValue(); - g_Conf->EmuOptions.Log.ELF = m_Elf->GetValue(); - g_Conf->EmuOptions.Trace.EE.m_VIFunpack = m_VIFunpack->GetValue(); - g_Conf->EmuOptions.Trace.EE.m_GIFtag = m_GIFtag->GetValue(); - - m_eeSection.Apply(); - m_iopSection.Apply(); + m_eeSection->Apply(); + m_iopSection->Apply(); m_IsDirty = false; + + for( uint i = 0; iEnabled = m_checks[i]->IsChecked(); + } } -#define GetSet( name ) conf.name = name->GetValue() +#define GetSet( cpu, name ) SysTracePack.cpu.name.Enabled = m_##name->GetValue() void Panels::eeLogOptionsPanel::Apply() { @@ -305,30 +332,8 @@ void Panels::eeLogOptionsPanel::Apply() conf.m_EnableAll = GetValue(); conf.m_EnableDisasm = m_disasmPanel->GetValue(); - conf.m_EnableHardware = m_hwPanel->GetValue(); + conf.m_EnableRegisters = m_hwPanel->GetValue(); conf.m_EnableEvents = m_evtPanel->GetValue(); - - GetSet(m_Bios); - GetSet(m_Memory); - GetSet(m_Cache); - GetSet(m_SysCtrl); - - GetSet(m_R5900); - GetSet(m_COP0); - GetSet(m_COP1); - GetSet(m_COP2); - GetSet(m_VU0micro); - GetSet(m_VU1micro); - - GetSet(m_KnownHw); - GetSet(m_UnknownHw); - GetSet(m_DMA); - - GetSet(m_Counters); - GetSet(m_VIF); - GetSet(m_GIF); - GetSet(m_SPR); - GetSet(m_IPU); } void Panels::iopLogOptionsPanel::Apply() @@ -337,25 +342,7 @@ void Panels::iopLogOptionsPanel::Apply() conf.m_EnableAll = GetValue(); conf.m_EnableDisasm = m_disasmPanel->GetValue(); - conf.m_EnableHardware = m_hwPanel->GetValue(); + conf.m_EnableRegisters = m_hwPanel->GetValue(); conf.m_EnableEvents = m_evtPanel->GetValue(); - - GetSet(m_Bios); - GetSet(m_Memory); - - GetSet(m_R3000A); - GetSet(m_COP2); - - GetSet(m_KnownHw); - GetSet(m_UnknownHw); - GetSet(m_DMA); - - GetSet(m_Counters); - GetSet(m_Memcards); - GetSet(m_PAD); - GetSet(m_SPU2); - GetSet(m_USB); - GetSet(m_FW); - GetSet(m_CDVD); } diff --git a/pcsx2/gui/Panels/LogOptionsPanels.h b/pcsx2/gui/Panels/LogOptionsPanels.h index 7eacce2bd5..967d6fc2d4 100644 --- a/pcsx2/gui/Panels/LogOptionsPanels.h +++ b/pcsx2/gui/Panels/LogOptionsPanels.h @@ -22,74 +22,50 @@ namespace Panels { class LogOptionsPanel; - class eeLogOptionsPanel : public CheckedStaticBox + class BaseCpuLogOptionsPanel : public CheckedStaticBox { + protected: + wxStaticBoxSizer* m_miscGroup; + public: + BaseCpuLogOptionsPanel( wxWindow* parent, const wxString& title, wxOrientation orient=wxVERTICAL ) + : CheckedStaticBox( parent, orient, title ) {} + + virtual wxStaticBoxSizer* GetMiscGroup() const { return m_miscGroup; } + virtual CheckedStaticBox* GetStaticBox( const wxString& subgroup ) const=0; + }; + + class eeLogOptionsPanel : public BaseCpuLogOptionsPanel + { + protected: CheckedStaticBox* m_disasmPanel; CheckedStaticBox* m_hwPanel; CheckedStaticBox* m_evtPanel; - pxCheckBox* m_Memory; - pxCheckBox* m_Bios; - pxCheckBox* m_Cache; - pxCheckBox* m_SysCtrl; - - pxCheckBox* m_R5900; - pxCheckBox* m_COP0; - pxCheckBox* m_COP1; - pxCheckBox* m_COP2; - pxCheckBox* m_VU0micro; - pxCheckBox* m_VU1micro; - - pxCheckBox* m_KnownHw; - pxCheckBox* m_UnknownHw; - pxCheckBox* m_DMA; - - pxCheckBox* m_Counters; - pxCheckBox* m_VIF; - pxCheckBox* m_GIF; - pxCheckBox* m_SPR; - pxCheckBox* m_IPU; - public: eeLogOptionsPanel( LogOptionsPanel* parent ); virtual ~eeLogOptionsPanel() throw() {} + CheckedStaticBox* GetStaticBox( const wxString& subgroup ) const; + void OnSettingsChanged(); void Apply(); }; - class iopLogOptionsPanel : public CheckedStaticBox + class iopLogOptionsPanel : public BaseCpuLogOptionsPanel { - public: + protected: CheckedStaticBox* m_disasmPanel; CheckedStaticBox* m_hwPanel; CheckedStaticBox* m_evtPanel; - pxCheckBox* m_Bios; - pxCheckBox* m_Memory; - pxCheckBox* m_GPU; - - pxCheckBox* m_R3000A; - pxCheckBox* m_COP2; - - pxCheckBox* m_KnownHw; - pxCheckBox* m_UnknownHw; - pxCheckBox* m_DMA; - - pxCheckBox* m_Counters; - pxCheckBox* m_Memcards; - pxCheckBox* m_PAD; - pxCheckBox* m_SPU2; - pxCheckBox* m_USB; - pxCheckBox* m_FW; - pxCheckBox* m_CDVD; - public: iopLogOptionsPanel( LogOptionsPanel* parent ); virtual ~iopLogOptionsPanel() throw() {} + CheckedStaticBox* GetStaticBox( const wxString& subgroup ) const; + void OnSettingsChanged(); void Apply(); }; @@ -97,15 +73,13 @@ namespace Panels class LogOptionsPanel : public BaseApplicableConfigPanel { protected: - eeLogOptionsPanel& m_eeSection; - iopLogOptionsPanel& m_iopSection; + eeLogOptionsPanel* m_eeSection; + iopLogOptionsPanel* m_iopSection; bool m_IsDirty; // any settings modified since last apply will flag this "true" pxCheckBox* m_masterEnabler; - pxCheckBox* m_SIF; - pxCheckBox* m_Elf; - pxCheckBox* m_VIFunpack; - pxCheckBox* m_GIFtag; + + ScopedArray m_checks; public: LogOptionsPanel( wxWindow* parent ); @@ -115,5 +89,8 @@ namespace Panels void OnUpdateEnableAll(); void OnCheckBoxClicked(wxCommandEvent &event); void Apply(); + + protected: + BaseCpuLogOptionsPanel* GetCpuPanel( const wxString& token ) const; }; } diff --git a/pcsx2/gui/Panels/PluginSelectorPanel.cpp b/pcsx2/gui/Panels/PluginSelectorPanel.cpp index 2f4fc57428..d4772a462e 100644 --- a/pcsx2/gui/Panels/PluginSelectorPanel.cpp +++ b/pcsx2/gui/Panels/PluginSelectorPanel.cpp @@ -90,7 +90,7 @@ public: : m_plugpath( plugpath ) { if( !m_plugin.Load( m_plugpath ) ) - throw Exception::BadStream( m_plugpath ).SetBothMsgs("File is not a valid dynamic library."); + throw Exception::BadStream( m_plugpath ).SetBothMsgs(L"File is not a valid dynamic library."); wxDoNotLogInThisScope please; m_GetLibType = (_PS2EgetLibType)m_plugin.GetSymbol( L"PS2EgetLibType" ); @@ -446,8 +446,8 @@ void Panels::PluginSelectorPanel::AppStatusEvent_OnSettingsApplied() static wxString GetApplyFailedMsg() { return wxsFormat( pxE( ".Error:PluginSelector:ApplyFailed", - L"All plugins must have valid selections for %s to run. If you are unable to make\n" - L"a valid selection due to missing plugins or an incomplete install of %s, then\n" + L"All plugins must have valid selections for %s to run. If you are unable to make " + L"a valid selection due to missing plugins or an incomplete install of %s, then " L"press cancel to close the Configuration panel." ), pxGetAppName().c_str(), pxGetAppName().c_str() ); } diff --git a/pcsx2/gui/i18n.cpp b/pcsx2/gui/i18n.cpp index 0712e6544b..dd56f1b8a4 100644 --- a/pcsx2/gui/i18n.cpp +++ b/pcsx2/gui/i18n.cpp @@ -19,15 +19,10 @@ #include "Utilities/SafeArray.h" -static bool IsEnglish( int id ) -{ - return ( id == wxLANGUAGE_ENGLISH || id == wxLANGUAGE_ENGLISH_US ); -} - LangPackEnumeration::LangPackEnumeration( wxLanguage langId ) : wxLangId( langId ) , englishName( wxLocale::GetLanguageName( wxLangId ) ) - , xlatedName( IsEnglish( wxLangId ) ? wxEmptyString : wxGetTranslation( L"NativeName" ) ) + , xlatedName( pxIsEnglish( wxLangId ) ? wxEmptyString : wxGetTranslation( L"NativeName" ) ) { } @@ -42,8 +37,6 @@ LangPackEnumeration::LangPackEnumeration() } -// ------------------------------------------------------------------------ -// static void i18n_DoPackageCheck( wxLanguage wxLangId, LangPackList& langs ) { // Plain english is a special case that's built in, and we only want it added to the list @@ -51,7 +44,7 @@ static void i18n_DoPackageCheck( wxLanguage wxLangId, LangPackList& langs ) if( wxLangId == wxLANGUAGE_ENGLISH ) langs.push_back( LangPackEnumeration( wxLangId ) ); - if( IsEnglish( wxLangId ) ) return; + if( pxIsEnglish( wxLangId ) ) return; // Note: wx auto-preserves the current locale for us if( !wxLocale::IsAvailable( wxLangId ) ) return; @@ -67,7 +60,6 @@ static void i18n_DoPackageCheck( wxLanguage wxLangId, LangPackList& langs ) delete locale; } -// ------------------------------------------------------------------------ // Finds all valid PCSX2 language packs, and enumerates them for configuration selection. // Note: On linux there's no easy way to reliably enumerate language packs, since every distro // could use its own location for installing pcsx2.mo files (wtcrap?). Furthermore wxWidgets @@ -104,73 +96,6 @@ void i18n_EnumeratePackages( LangPackList& langs ) //i18n_DoPackageCheck( wxLANGUAGE_SAMI, englishNames, xlatedNames ); } -// ------------------------------------------------------------------------ -// PCSX2's Iconized Text Translator. -// This i18n version provides two layers of translated lookups. It puts the key through the -// current language first and, if the key is not resolved (meaning the language pack doesn't -// have a translation for it), it's put through our own built-in english translation. This -// second step is needed to resolve some of our lengthy UI tooltips and descriptors, which -// use iconized GetText identifiers. -// -// (without this second pass many tooltips would just show up as "Savestate Tooltip" instead -// of something meaningful). -// -const wxChar* __fastcall pxExpandMsg( const wxChar* key, const wxChar* englishContent ) -{ -#ifdef PCSX2_DEVBUILD - static const wxChar* tbl_pxE_Prefixes[] = - { - L".Panel:", - L".Popup:", - L".Error:", - L".Wizard:", - L".Tooltip:", - NULL - }; - - // test the prefix of the key for consistency to valid/known prefix types. - const wxChar** prefix = tbl_pxE_Prefixes; - while( *prefix != NULL ) - { - if( wxString(key).StartsWith(*prefix) ) break; - ++prefix; - } - pxAssertDev( *prefix != NULL, - wxsFormat( L"Invalid pxE key prefix in key '%s'. Prefix must be one of the valid prefixes listed in pxExpandMsg.", key ) - ); -#endif - - const wxLanguageInfo* info = wxLocale::GetLanguageInfo( g_Conf->LanguageId ); - - if( ( info == NULL ) || IsEnglish( info->Language ) ) - return englishContent; - - const wxChar* retval = wxGetTranslation( key ); - - // Check if the translation failed, and fall back on an english lookup. - return ( wxStrcmp( retval, key ) == 0 ) ? englishContent : retval; -} - -// ------------------------------------------------------------------------ -// Alternative implementation for wxGetTranslation. -// This version performs a string length check in devel builds, which issues a warning -// if the string seems too long for gettext lookups. Longer complicated strings should -// usually be implemented used the pxMsgExpand system instead. -// -const wxChar* __fastcall pxGetTranslation( const wxChar* message ) -{ - if( IsDevBuild ) - { - if( wxStrlen( message ) > 96 ) - { - Console.Warning( "pxGetTranslation: Long message detected, maybe use pxE() instead?" ); - Console.WriteLn( Color_Green, L"Message: %s", message ); - } - } - return wxGetTranslation( message ); -} - -// ------------------------------------------------------------------------ bool i18n_SetLanguage( int wxLangId ) { if( !wxLocale::IsAvailable( wxLangId ) ) @@ -189,7 +114,7 @@ bool i18n_SetLanguage( int wxLangId ) return false; } - if( !IsEnglish(wxLangId) && !locale->AddCatalog( L"pcsx2main" ) ) + if( !pxIsEnglish(wxLangId) && !locale->AddCatalog( L"pcsx2main" ) ) { /*Console.Warning( L"SetLanguage: Cannot find pcsx2main.mo file for language '%s' [%s]", wxLocale::GetLanguageName( locale->GetLanguage() ).c_str(), locale->GetCanonicalName().c_str() diff --git a/pcsx2/gui/i18n.h b/pcsx2/gui/i18n.h index 8116fbfa54..d60ef53454 100644 --- a/pcsx2/gui/i18n.h +++ b/pcsx2/gui/i18n.h @@ -21,9 +21,9 @@ class LangPackEnumeration { public: - wxLanguage wxLangId; - wxString englishName; - wxString xlatedName; + wxLanguage wxLangId; + wxString englishName; + wxString xlatedName; public: LangPackEnumeration( wxLanguage langId ); @@ -35,37 +35,3 @@ typedef std::vector LangPackList; extern bool i18n_SetLanguage( int wxLangId ); extern void i18n_EnumeratePackages( LangPackList& langs ); -extern const wxChar* __fastcall pxExpandMsg( const wxChar* key, const wxChar* englishContent ); -extern const wxChar* __fastcall pxGetTranslation( const wxChar* message ); - -////////////////////////////////////////////////////////////////////////////////////////// -// Translation Feature: pxE is used as a method of dereferencing very long english text -// descriptions via a "key" identifier. In this way, the english text can be revised without -// it breaking existing translation bindings. Make sure to add pxE to your PO catalog's -// source code identifiers, and then reference the source code to see what the current -// english version is. -// -// Valid prefix types: -// -// .Panel: Key-based translation of a panel or dialog text; usually either a header or -// checkbox description, by may also include some controls with long labels. -// These have the highest translation priority. -// -// .Popup: Key-based translation of a popup dialog box; either a notice, confirmation, -// or error. These typically have very high translation priority (roughly equal -// or slightly less than pxE_Panel). -// -// .Error Key-based translation of error messages, typically used when throwing exceptions -// that have end-user errors. These are normally (but not always) displayed as popups -// to the user. Translation priority is medium. -// -// .Wizard Key-based translation of a heading, checkbox item, description, or other text -// associated with the First-time wizard. Translation of these items is considered -// lower-priority to most other messages; but equal or higher priority to tooltips. -// -// .Tooltip: Key-based translation of a tooltip for a control on a dialog/panel. Translation -// of these items is typically considered "lowest priority" as they usually provide -// the most tertiary of info to the user. -// - -#define pxE(key, english) pxExpandMsg( wxT(key), english ) diff --git a/pcsx2/gui/pxEventThread.h b/pcsx2/gui/pxEventThread.h index 7ceb5f38d1..cb4856b943 100644 --- a/pcsx2/gui/pxEventThread.h +++ b/pcsx2/gui/pxEventThread.h @@ -18,7 +18,39 @@ #include "Utilities/PersistentThread.h" #include "Utilities/pxEvents.h" -// TODO!! Make this system a bit more generic, and then move it to the Utilities library. + +// TODO!! Make the system defined in this header system a bit more generic, and then move +// it to the Utilities library. + +class pxEvtHandler; +class SysExecEvent; + +// -------------------------------------------------------------------------------------- +// pxEvtLog / ConsoleLogSource_Event +// -------------------------------------------------------------------------------------- + +class ConsoleLogSource_Event : ConsoleLogSource +{ + typedef ConsoleLogSource _parent; + +public: + using _parent::IsEnabled; + + ConsoleLogSource_Event() + { + Name = L"PS2vm Events"; + Description = wxLt("Logs events as they are passed to the PS2 virtual machine."); + } + + bool Write( const pxEvtHandler* evtHandler, const SysExecEvent* evt, const wxChar* msg ); + bool Warn( const pxEvtHandler* evtHandler, const SysExecEvent* evt, const wxChar* msg ); + bool Error( const pxEvtHandler* evtHandler, const SysExecEvent* evt, const wxChar* msg ); +}; + +extern ConsoleLogSource_Event pxConLog_Event; + +#define pxEvtLog pxConLog_Event.IsEnabled() && pxConLog_Event + // -------------------------------------------------------------------------------------- // SysExecEvent @@ -108,9 +140,10 @@ class SysExecEvent_MethodVoid : public SysExecEvent protected: FnType_Void* m_method; bool m_IsCritical; + wxString m_TraceName; public: - wxString GetEventName() const { return L"MethodVoid"; } + wxString GetEventName() const { return m_TraceName; } virtual ~SysExecEvent_MethodVoid() throw() {} SysExecEvent_MethodVoid* Clone() const { return new SysExecEvent_MethodVoid( *this ); } @@ -118,12 +151,11 @@ public: bool AllowCancelOnExit() const { return !m_IsCritical; } bool IsCriticalEvent() const { return m_IsCritical; } - // Hacky: I don't really like this Critical parameter mess, but I haven't thought - // of a better solution (yet). - explicit SysExecEvent_MethodVoid( FnType_Void* method = NULL, bool critical=false ) + explicit SysExecEvent_MethodVoid( FnType_Void* method = NULL, const wxChar* traceName=NULL ) + : m_TraceName( traceName ? traceName : L"VoidMethod" ) { m_method = method; - m_IsCritical = critical; + m_IsCritical = false; } SysExecEvent_MethodVoid& Critical() @@ -190,7 +222,7 @@ public: virtual void ShutdownQueue(); bool IsShuttingDown() const { return !!m_Quitting; } - void ProcessEvents( pxEvtList& list ); + void ProcessEvents( pxEvtList& list, bool isIdle=false ); void ProcessPendingEvents(); void ProcessIdleEvents(); void Idle(); @@ -204,8 +236,8 @@ public: void ProcessEvent( SysExecEvent* evt ); void ProcessEvent( SysExecEvent& evt ); - bool Rpc_TryInvokeAsync( FnType_Void* method ); - bool Rpc_TryInvoke( FnType_Void* method ); + bool Rpc_TryInvokeAsync( FnType_Void* method, const wxChar* traceName=NULL ); + bool Rpc_TryInvoke( FnType_Void* method, const wxChar* traceName=NULL ); void SetActiveThread(); protected: @@ -242,14 +274,14 @@ public: void ProcessEvent( SysExecEvent* evt ); void ProcessEvent( SysExecEvent& evt ); - bool Rpc_TryInvokeAsync( void (*evt)() ) + bool Rpc_TryInvokeAsync( void (*evt)(), const wxChar* traceName=NULL ) { - return m_EvtHandler ? m_EvtHandler->Rpc_TryInvokeAsync( evt ) : false; + return m_EvtHandler ? m_EvtHandler->Rpc_TryInvokeAsync( evt, traceName ) : false; } - bool Rpc_TryInvoke( void (*evt)() ) + bool Rpc_TryInvoke( void (*evt)(), const wxChar* traceName=NULL ) { - return m_EvtHandler ? m_EvtHandler->Rpc_TryInvoke( evt ) : false; + return m_EvtHandler ? m_EvtHandler->Rpc_TryInvoke( evt, traceName ) : false; } protected: diff --git a/pcsx2/gui/pxLogTextCtrl.cpp b/pcsx2/gui/pxLogTextCtrl.cpp index 56883973fe..f7a2bc9327 100644 --- a/pcsx2/gui/pxLogTextCtrl.cpp +++ b/pcsx2/gui/pxLogTextCtrl.cpp @@ -39,7 +39,6 @@ pxLogTextCtrl::pxLogTextCtrl( wxWindow* parent ) wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH2 ) { - m_IsPaused = false; m_FreezeWrites = false; Connect( wxEVT_SCROLLWIN_THUMBTRACK, wxScrollWinEventHandler(pxLogTextCtrl::OnThumbTrack) ); diff --git a/pcsx2/ps2/GIFpath.cpp b/pcsx2/ps2/GIFpath.cpp index 24677532c5..4c736bf8aa 100644 --- a/pcsx2/ps2/GIFpath.cpp +++ b/pcsx2/ps2/GIFpath.cpp @@ -164,7 +164,7 @@ static void __fastcall RegHandlerSIGNAL(const u32* data) } else { - GIF_LOG("GS SIGNAL data=%x_%x IMR=%x CSRr=%x\n",data[0], data[1], GSIMR, GSCSRr); + GIF_LOG("GS SIGNAL data=%x_%x IMR=%x CSRr=%x",data[0], data[1], GSIMR, GSCSRr); GSSIGLBLID.SIGID = (GSSIGLBLID.SIGID&~data[1])|(data[0]&data[1]); if (!(GSIMR&0x100)) @@ -184,7 +184,7 @@ static void __fastcall RegHandlerSIGNAL(const u32* data) // static void __fastcall RegHandlerFINISH(const u32* data) { - GIF_LOG("GIFpath FINISH data=%x_%x CSRr=%x\n", data[0], data[1], GSCSRr); + GIF_LOG("GIFpath FINISH data=%x_%x CSRr=%x", data[0], data[1], GSCSRr); // The FINISH bit is set here, and then it will be cleared when all three // logical GIFpaths finish their packets (EOPs) At that time (found below diff --git a/pcsx2/ps2/Iop/IopHwWrite.cpp b/pcsx2/ps2/Iop/IopHwWrite.cpp index 1a9e029b49..0bdc6ca22e 100644 --- a/pcsx2/ps2/Iop/IopHwWrite.cpp +++ b/pcsx2/ps2/Iop/IopHwWrite.cpp @@ -106,28 +106,33 @@ void __fastcall iopHwWrite8_Page1( u32 addr, mem8_t val ) IopHwTraceLog( addr, val, "Write" ); } -static char g_pbuf[1024]; -static int g_pbufi; - void __fastcall iopHwWrite8_Page3( u32 addr, mem8_t val ) { // all addresses are assumed to be prefixed with 0x1f803xxx: pxAssert( (addr >> 12) == 0x1f803 ); - if( addr == 0x1f80380c ) // STDOUT + if( SysConsolePack.iopConsole.IsEnabled() && (addr == 0x1f80380c) ) // STDOUT { - // Terminate lines on CR or full buffers, and ignore \n's if the string contents - // are empty (otherwise terminate on \n too!) - if( ( val == '\r' ) || ( g_pbufi == 1023 ) || - ( val == '\n' && g_pbufi != 0 ) ) + static char pbuf[1024]; + static int pidx; + static bool iggy_newline = false; + + if (val == '\r') { - g_pbuf[g_pbufi] = 0; - Console.WriteLn( ConColor_IOP, L"%s", L"%s", ShiftJIS_ConvertString(g_pbuf).c_str() ); - g_pbufi = 0; + iggy_newline = true; + pbuf[pidx++] = '\n'; } - else if( val != '\n' ) + else if (!iggy_newline || (val != '\n')) { - g_pbuf[g_pbufi++] = val; + iggy_newline = false; + pbuf[pidx++] = val; + } + + if ((pidx == ArraySize(pbuf)-1) || (pbuf[pidx-1] == '\n')) + { + pbuf[pidx] = 0; + iopConLog( ShiftJIS_ConvertString(pbuf) ); + pidx = 0; } } diff --git a/pcsx2/ps2/Iop/IopHw_Internal.h b/pcsx2/ps2/Iop/IopHw_Internal.h index dffce5186e..a22a4db354 100644 --- a/pcsx2/ps2/Iop/IopHw_Internal.h +++ b/pcsx2/ps2/Iop/IopHw_Internal.h @@ -202,19 +202,18 @@ static __releaseinline const char* _log_GetIopHwName( u32 addr, T val ) template< typename T> static __releaseinline void IopHwTraceLog( u32 addr, T val, const char* modestr ) { - if( EmuConfig.Trace.IOP.HwEnabled() ) - { - char temp[] = "Hw%s%d from %s, addr 0x%08x = 0x%0*x"; + if( !EmuConfig.Trace.IOP.m_EnableRegisters ) return; - // Replace the * above with the operand size (this ensures nicely formatted - // zero-fill hex values): - temp[(sizeof temp)-3] = '0' + (sizeof(T)*2); + static char *temp = "Hw%s%d from %s, addr 0x%08x = 0x%0*x"; - if( const char* regname = _log_GetIopHwName( addr, val ) ) - PSXHW_LOG( temp, modestr, (sizeof (T)) * 8, regname, addr, val ); - else - PSXUnkHW_LOG( temp, modestr, (sizeof (T)) * 8, "Unknown", addr, val ); - } + // Replace the * above with the operand size (this ensures nicely formatted + // zero-fill hex values): + temp[(sizeof temp)-3] = '0' + (sizeof(T)*2); + + if( const char* regname = _log_GetIopHwName( addr, val ) ) + PSXHW_LOG( temp, modestr, (sizeof (T)) * 8, regname, addr, val ); + else + PSXUnkHW_LOG( temp, modestr, (sizeof (T)) * 8, "Unknown", addr, val ); } } }; diff --git a/pcsx2/windows/SamplProf.cpp b/pcsx2/windows/SamplProf.cpp index 2c3276975f..74e3dfaf4b 100644 --- a/pcsx2/windows/SamplProf.cpp +++ b/pcsx2/windows/SamplProf.cpp @@ -275,7 +275,7 @@ void ProfilerInit() if (ProfRunning) return; - Console.Write( "Profiler Thread Initializing..." ); + Console.WriteLn( "Profiler Thread Initializing..." ); ProfRunning=true; DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), @@ -289,12 +289,12 @@ void ProfilerInit() hProfThread=CreateThread(0,0,(LPTHREAD_START_ROUTINE)ProfilerThread,0,0,0); SetThreadPriority(hProfThread,THREAD_PRIORITY_HIGHEST); - Console.WriteLn( " Done!" ); + Console.WriteLn( "Profiler Thread Started!" ); } void ProfilerTerm() { - Console.Write( "Profiler Terminating..." ); + Console.WriteLn( "Profiler Terminating..." ); if (!ProfRunning) return; @@ -314,7 +314,7 @@ void ProfilerTerm() CloseHandle( hMtgsThread ); DeleteCriticalSection( &ProfModulesLock ); - Console.WriteLn( " Done!" ); + Console.WriteLn( "Profiler Termination Done!" ); } void ProfilerSetEnabled(bool Enabled) diff --git a/pcsx2/windows/WinConsolePipe.cpp b/pcsx2/windows/WinConsolePipe.cpp index f211706905..8f96fe7b3d 100644 --- a/pcsx2/windows/WinConsolePipe.cpp +++ b/pcsx2/windows/WinConsolePipe.cpp @@ -104,7 +104,9 @@ protected: // ATTENTION: The Console always prints ANSI to the pipe independent if compiled as UNICODE or MBCS! s8_Buf[u32_Read] = 0; - Console.WriteFromStdout( m_color, s8_Buf ); + + ConsoleColorScope cs(m_color); + Console.DoWriteFromStdout( fromUTF8(s8_Buf) ); TestCancel(); } diff --git a/pcsx2/x86/iCOP0.cpp b/pcsx2/x86/iCOP0.cpp index 26aa2bc835..d7248932e0 100644 --- a/pcsx2/x86/iCOP0.cpp +++ b/pcsx2/x86/iCOP0.cpp @@ -188,7 +188,7 @@ void recMFC0( void ) return; } else if(_Rd_ == 24){ - SysCtrl_LOG("MFC0 Breakpoint debug Registers code = %x\n", cpuRegs.code & 0x3FF); + COP0_LOG("MFC0 Breakpoint debug Registers code = %x\n", cpuRegs.code & 0x3FF); return; } _eeOnWriteReg(_Rt_, 1); @@ -242,7 +242,7 @@ void recMTC0() break; case 24: - SysCtrl_LOG("MTC0 Breakpoint debug Registers code = %x\n", cpuRegs.code & 0x3FF); + COP0_LOG("MTC0 Breakpoint debug Registers code = %x\n", cpuRegs.code & 0x3FF); break; default: @@ -291,7 +291,7 @@ void recMTC0() break; case 24: - SysCtrl_LOG("MTC0 Breakpoint debug Registers code = %x\n", cpuRegs.code & 0x3FF); + COP0_LOG("MTC0 Breakpoint debug Registers code = %x\n", cpuRegs.code & 0x3FF); break; default: diff --git a/pcsx2/x86/iR3000A.cpp b/pcsx2/x86/iR3000A.cpp index 56ed697af0..38eb592502 100644 --- a/pcsx2/x86/iR3000A.cpp +++ b/pcsx2/x86/iR3000A.cpp @@ -670,7 +670,7 @@ void psxRecompileCodeConst1(R3000AFNPTR constcode, R3000AFNPTR_INFO noconstcode) const char *funcname = irxImportFuncname(libname, index); irxDEBUG debug = irxImportDebug(libname, index); - if (macTrace.IOP.Bios()) { + if (SysTracePack.IOP.Bios.IsEnabled()) { xMOV(ecx, (uptr)libname); xMOV(edx, index); xPUSH((uptr)funcname); diff --git a/pcsx2/x86/ix86-32/iR5900-32.cpp b/pcsx2/x86/ix86-32/iR5900-32.cpp index f181bf32e3..a5e8eca62c 100644 --- a/pcsx2/x86/ix86-32/iR5900-32.cpp +++ b/pcsx2/x86/ix86-32/iR5900-32.cpp @@ -630,7 +630,7 @@ void recResetEE( void ) //AtomicExchange( eeRecNeedsReset, false ); if( AtomicExchange( eeRecIsReset, true ) ) return; - Console.WriteLn( Color_StrongBlack, "Issuing EE/iR5900-32 Recompiler Reset" ); + Console.WriteLn( Color_StrongBlack, "EE/iR5900-32 Recompiler Reset" ); maxrecmem = 0; @@ -881,8 +881,10 @@ void recClear(u32 addr, u32 size) u32 blockend = pexblock->startpc + pexblock->size * 4; if (pexblock->startpc >= addr && pexblock->startpc < addr + size * 4 || pexblock->startpc < addr && blockend > addr) { - DevCon.Error( "Impossible block clearing failure" ); - pxFailDev( "Impossible block clearing failure" ); + if( !IsDevBuild ) + Console.Error( "Impossible block clearing failure" ); + else + pxAssertDev( false, "Impossible block clearing failure" ); } } @@ -1281,9 +1283,11 @@ static u32 s_recblocks[] = {0}; #endif // Called when a block under manual protection fails it's pre-execution integrity check. +// (meaning the actual code area has been modified -- ie dynamic modules being loaded or, +// less likely, self-modifying code) void __fastcall dyna_block_discard(u32 start,u32 sz) { - DevCon.WriteLn("Discarding Manual Block @ 0x%08X [size=%d]", start, sz*4); + eeRecPerfLog.Write( Color_StrongGray, "Clearing Manual Block @ 0x%08X [size=%d]", start, sz*4); recClear(start, sz); // Stack trick: This function was invoked via a direct jmp, so manually pop the @@ -1296,8 +1300,9 @@ void __fastcall dyna_block_discard(u32 start,u32 sz) #endif } -// called when a block under manual protection has been run enough times to be a -// candidate for being reset under the faster vtlb write protection. +// called when a page under manual protection has been run enough times to be a candidate +// for being reset under the faster vtlb write protection. All blocks in the page are cleared +// and the block is re-assigned for write protection. void __fastcall dyna_page_reset(u32 start,u32 sz) { recClear(start & ~0xfffUL, 0x400); @@ -1353,7 +1358,7 @@ static void __fastcall recRecompile( const u32 startpc ) recResetEE(); } if ( (recConstBufPtr - recConstBuf) >= RECCONSTBUF_SIZE - 64 ) { - DevCon.WriteLn("EE recompiler stack reset"); + Console.WriteLn("EE recompiler stack reset"); recResetEE(); } @@ -1420,7 +1425,7 @@ static void __fastcall recRecompile( const u32 startpc ) willbranch3 = 1; s_nEndBlock = i; - //DevCon.Warning( "Pagesplit @ %08X : size=%d insts", startpc, (i-startpc) / 4 ); + eeRecPerfLog.Write( "Pagesplit @ %08X : size=%d insts", startpc, (i-startpc) / 4 ); break; } @@ -1729,12 +1734,13 @@ StartRecomp: xJC( dyna_page_reset ); // note: clearcnt is measured per-page, not per-block! - //DbgCon.WriteLn( "Manual block @ %08X : size =%3d page/offs = %05X/%03X inpgsz = %d clearcnt = %d", - // startpc, sz, inpage_ptr>>12, inpage_ptr&0xfff, inpage_sz, manual_counter[inpage_ptr >> 12] ); + ConsoleColorScope cs( Color_Gray ); + eeRecPerfLog.Write( "Manual block @ %08X : size =%3d page/offs = 0x%05X/0x%03X inpgsz = %d clearcnt = %d", + startpc, sz, inpage_ptr>>12, inpage_ptr&0xfff, inpage_sz, manual_counter[inpage_ptr >> 12] ); } else { - DbgCon.WriteLn( Color_Gray, "Uncounted Manual block @ 0x%08X : size =%3d page/offs = %05X/%03X inpgsz = %d", + eeRecPerfLog.Write( "Uncounted Manual block @ 0x%08X : size =%3d page/offs = 0x%05X/0x%03X inpgsz = %d", startpc, sz, inpage_ptr>>12, inpage_ptr&0xfff, pgsz, inpage_sz ); } break; @@ -1779,7 +1785,7 @@ StartRecomp: } } - memcpy(&recRAMCopy[HWADDR(startpc) / 4], PSM(startpc), pc - startpc); + memcpy_fast(&recRAMCopy[HWADDR(startpc) / 4], PSM(startpc), pc - startpc); } s_pCurBlock->SetFnptr((uptr)recPtr); diff --git a/pcsx2/x86/microVU.cpp b/pcsx2/x86/microVU.cpp index 70a9a62b9f..b49abeae5c 100644 --- a/pcsx2/x86/microVU.cpp +++ b/pcsx2/x86/microVU.cpp @@ -94,7 +94,7 @@ _f void mVUinit(VURegs* vuRegsPtr, int vuIndex) { mVU->prog.prog[i] = new deque(); } - mVU->dispCache = SysMmapEx(NULL, mVUdispCacheSize, 0, (mVU->index ? "Micro VU1 Dispatcher" : "Micro VU0 Dispatcher")); + mVU->dispCache = SysMmapEx(0, mVUdispCacheSize, 0, (mVU->index ? "Micro VU1 Dispatcher" : "Micro VU0 Dispatcher")); if (!mVU->dispCache) throw Exception::OutOfMemory( mVU->index ? L"Micro VU1 Dispatcher" : L"Micro VU0 Dispatcher" ); memset(mVU->dispCache, 0xcc, mVUdispCacheSize); @@ -179,7 +179,7 @@ void mVUresizeCache(mV, u32 size) { if (mVU->cache) Console.WriteLn(Color_Green, "microVU%d: Attempting to resize Cache [%dmb]", mVU->index, size/_1mb); - u8* cache = SysMmapEx(NULL, size, 0, (mVU->index ? "Micro VU1 RecCache" : "Micro VU0 RecCache")); + u8* cache = SysMmapEx(0, size, 0, (mVU->index ? "Micro VU1 RecCache" : "Micro VU0 RecCache")); if(!cache && !mVU->cache) throw Exception::OutOfMemory( wxsFormat( L"Micro VU%d recompiled code cache", mVU->index) ); if(!cache) { Console.Error("microVU%d Error - Cache Resize Failed...", mVU->index); mVUreset(mVU); return; } if (mVU->cache) { diff --git a/pcsx2/x86/microVU_Compile.inl b/pcsx2/x86/microVU_Compile.inl index 655cdf7ef6..0686a2e3af 100644 --- a/pcsx2/x86/microVU_Compile.inl +++ b/pcsx2/x86/microVU_Compile.inl @@ -35,8 +35,8 @@ void __fastcall mVUbadOp0(mV) { Console.Error("microVU0 Warning: Exiting... Blo void __fastcall mVUbadOp1(mV) { Console.Error("microVU1 Warning: Exiting... Block started with illegal opcode. [%04x] [%x]", xPC, mVU->prog.cur); } void __fastcall mVUwarning0(mV) { Console.Error("microVU0 Warning: Exiting from Possible Infinite Loop [%04x] [%x]", xPC, mVU->prog.cur); } void __fastcall mVUwarning1(mV) { Console.Error("microVU1 Warning: Exiting from Possible Infinite Loop [%04x] [%x]", xPC, mVU->prog.cur); } -void __fastcall mVUprintPC1(u32 PC) { Console.Write("Block PC [%04x] ", PC); } -void __fastcall mVUprintPC2(u32 PC) { Console.Write("[%04x]\n", PC); } +void __fastcall mVUprintPC1(u32 PC) { Console.WriteLn("Block Start PC = 0x%04x", PC); } +void __fastcall mVUprintPC2(u32 PC) { Console.WriteLn("Block End PC = 0x%04x", PC); } //------------------------------------------------------------------ // Helper Functions diff --git a/pcsx2/x86/newVif_BlockBuffer.h b/pcsx2/x86/newVif_BlockBuffer.h index d8fd61eef4..532c613819 100644 --- a/pcsx2/x86/newVif_BlockBuffer.h +++ b/pcsx2/x86/newVif_BlockBuffer.h @@ -32,7 +32,7 @@ protected: u8* mData; // Data Ptr (allocated via SysMmap) void alloc(int size) { - mData = SysMmapEx(NULL, size, 0, "nVif_BlockBuffer"); + mData = SysMmapEx(0, size, 0, "nVif_BlockBuffer"); if (!mData) throw Exception::OutOfMemory(L"nVif recompiled code buffer (nVif_BlockBuffer)"); clear(); } diff --git a/plugins/spu2-x/src/Global.h b/plugins/spu2-x/src/Global.h index c1f42586a4..83400c6f6f 100644 --- a/plugins/spu2-x/src/Global.h +++ b/plugins/spu2-x/src/Global.h @@ -79,19 +79,11 @@ extern void SysMessage(const wchar_t *fmt, ...); // Abbreviated macros for dev/debug only consoles and msgboxes. #ifdef PCSX2_DEVBUILD -# define DevCon Console # define DevMsg MsgBox #else -# define DevCon 0&&Console # define DevMsg #endif -#ifdef PCSX2_DEBUG -# define DbgCon Console -#else -# define DbgCon 0&&Console -#endif - #ifdef PCSX2_DEVBUILD # define SPU2_LOG #endif