Introducing a mostly revamped Tracelog and Console log system. Various console log sources can now be toggled on/off on the fly, allowing end users to enable more verbose logging when they encounter problems. Both console and trace sources can be given automatic prefixing.

DevNotes:  DevCon logs are now available in *Release* builds as well as Devel builds, and can be enabled from the Console window's "Sources" menu.  They are disabled by default in Release builds, and are always enabled regardless of the ini setting in devel builds.  Debug logs are still strictly available in debug builds only.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3609 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2010-08-06 05:46:09 +00:00
parent 411454c03c
commit 912872af80
79 changed files with 2712 additions and 1849 deletions

View File

@ -164,6 +164,7 @@
<Unit filename="../../include/Utilities/StringHelpers.h" />
<Unit filename="../../include/Utilities/Threading.h" />
<Unit filename="../../include/Utilities/ThreadingDialogs.h" />
<Unit filename="../../include/Utilities/TraceLog.h" />
<Unit filename="../../include/Utilities/lnx_memzero.h" />
<Unit filename="../../include/Utilities/pxCheckBox.h" />
<Unit filename="../../include/Utilities/pxEvents.h" />
@ -199,6 +200,7 @@
<Unit filename="../../src/Utilities/pxRadioPanel.cpp" />
<Unit filename="../../src/Utilities/pxStaticText.cpp" />
<Unit filename="../../src/Utilities/pxTextStream.cpp" />
<Unit filename="../../src/Utilities/pxTranslate.cpp" />
<Unit filename="../../src/Utilities/pxWindowTextWriter.cpp" />
<Unit filename="../../src/Utilities/vssprintf.cpp" />
<Unit filename="../../src/Utilities/wxAppWithHelpers.cpp" />

View File

@ -279,6 +279,10 @@
RelativePath="..\..\src\Utilities\pxTextStream.cpp"
>
</File>
<File
RelativePath="..\..\src\Utilities\pxTranslate.cpp"
>
</File>
<File
RelativePath="..\..\src\Utilities\pxWindowTextWriter.cpp"
>
@ -461,6 +465,10 @@
RelativePath="..\..\include\Utilities\StringHelpers.h"
>
</File>
<File
RelativePath="..\..\include\Utilities\TraceLog.h"
>
</File>
<File
RelativePath="..\..\include\Utilities\win_memzero.h"
>

View File

@ -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

View File

@ -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 <wx/string.h>
#include <wx/intl.h>
#include <wx/log.h>
#include "Pcsx2Defs.h"
#include <stdexcept>
#include <cstring> // string.h under c++
#include <cstdio> // stdio.h under c++
@ -168,4 +164,59 @@ public:
#include <vector>
#include <list>
#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"

View File

@ -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") );
};
// ---------------------------------------------------------------------------------------

View File

@ -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

View File

@ -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." );
}
};
}

View File

@ -162,7 +162,7 @@ void Threading::BaseTlsVariable<T>::KillKey()
BaseTlsVariable<T>::_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 >

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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

View File

@ -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 );
}

View File

@ -114,6 +114,7 @@ set(UtilitiesSources
pxRadioPanel.cpp
pxStaticText.cpp
pxTextStream.cpp
pxTranslate.cpp
pxWindowTextWriter.cpp
Semaphore.cpp
StringHelpers.cpp

View File

@ -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 );

View File

@ -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<IConsoleWriter&>(Console)= writer;
#ifdef PCSX2_DEVBUILD
DevCon = writer;
const_cast<IConsoleWriter&>(DevCon) = writer;
#endif
#ifdef PCSX2_DEBUG
DbgCon = writer;
const_cast<IConsoleWriter&>(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;

View File

@ -23,9 +23,9 @@
#include <signal.h>
#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 )

View File

@ -153,7 +153,7 @@ static __releaseinline void format_that_ascii_mess( SafeArray<char>& 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<char>& 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 );
};

View File

@ -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"

View File

@ -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 );

View File

@ -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()

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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 );
}

View File

@ -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<pxThread> 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();
}

View File

@ -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<<i)) Console.Write("%s ", mg_zones[i]);
if (cdvd.mg_buffer[0x1C] & (1<<i)) zoneStr += mg_zones[i];
}
Console.Newline();
Console.WriteLn("[MG] ELF_size=0x%X Hdr_size=0x%X unk=0x%X flags=0x%X count=%d zones=%s",
*(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],
zoneStr.c_str()
);
bit_ofs = mg_BIToffset(cdvd.mg_buffer);
@ -1921,7 +1924,7 @@ static void cdvdWrite16(u8 rt) // SCOMMAND
//memcpy(cdvd.mg_kcon, &cdvd.mg_buffer[bit_ofs-0x10], 0x10);
if ((cdvd.mg_buffer[bit_ofs+5] || cdvd.mg_buffer[bit_ofs+6] || cdvd.mg_buffer[bit_ofs+7]) ||
(cdvd.mg_buffer[bit_ofs+4] * 16 + bit_ofs + 8 + 16 != *(u16*)&cdvd.mg_buffer[0x14]))
(cdvd.mg_buffer[bit_ofs+4] * 16 + bit_ofs + 8 + 16 != *(u16*)&cdvd.mg_buffer[0x14]))
{
fail_pol_cal();
break;

View File

@ -181,31 +181,34 @@ isoFile *isoOpen(const char *filename)
iso->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;

View File

@ -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 );

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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))

View File

@ -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;

View File

@ -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;

View File

@ -13,8 +13,7 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#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

View File

@ -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;

View File

@ -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 );
}

View File

@ -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();
}

View File

@ -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 );

View File

@ -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;

View File

@ -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)

View File

@ -199,11 +199,10 @@ static int __Deci2Call(int call, u32 *addr)
pdeciaddr += (d2ptr[4]+0xc) % 16;
const int copylen = std::min<uint>(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;

View File

@ -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)

View File

@ -13,12 +13,18 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
// --------------------------------------------------------------------------------------
// 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 <sys/time.h>
#ifndef _WIN32
# include <sys/time.h>
#endif
#include <cstdarg>
@ -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."));
}

View File

@ -90,13 +90,6 @@ Pcsx2Config::GamefixOptions& SetGameFixConfig()
return const_cast<Pcsx2Config::GamefixOptions&>(EmuConfig.Gamefixes);
}
ConsoleLogFilters& SetConsoleConfig()
{
//DbgCon.WriteLn( "Direct modification of EmuConfig.Log detected" );
AffinityAssert_AllowFrom_MainUI();
return const_cast<ConsoleLogFilters&>(EmuConfig.Log);
}
TraceLogFilters& SetTraceConfig()
{
//DbgCon.WriteLn( "Direct modification of EmuConfig.TraceLog detected" );

View File

@ -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;

View File

@ -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

View File

@ -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<int idx> _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<idx>(pass, (u8*)data, 0);
}
vifOp(vifCode_DirectHL) {
pass3 { DevCon.WriteLn("vifCode_DirectHL"); }
pass3 { VifCodeLog("DirectHL"); }
return _vifCode_Direct<idx>(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<idx>(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<idx>(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;
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
// Old Vif Unpack Code
// Only here for testing/reference
template<const u32 VIFdmanum> 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<u32>(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 <http://www.gnu.org/licenses/>.
*/
#pragma once
// Old Vif Unpack Code
// Only here for testing/reference
template<const u32 VIFdmanum> 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<u32>(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;
}
}
}

View File

@ -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 );

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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<const GlobalCommandDescriptor*>
{
typedef HashTools::Dictionary<const GlobalCommandDescriptor*> _parent;
protected:
public:
using _parent::operator[];
CommandDictionary();
virtual ~CommandDictionary() throw();
};
// --------------------------------------------------------------------------------------
//
// --------------------------------------------------------------------------------------
class AcceleratorDictionary : public HashTools::HashMap<int, const GlobalCommandDescriptor*>
{
typedef HashTools::HashMap<int, const GlobalCommandDescriptor*> _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 <http://www.gnu.org/licenses/>.
*/
#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<const GlobalCommandDescriptor*>
{
typedef HashTools::Dictionary<const GlobalCommandDescriptor*> _parent;
protected:
public:
using _parent::operator[];
CommandDictionary();
virtual ~CommandDictionary() throw();
};
// --------------------------------------------------------------------------------------
//
// --------------------------------------------------------------------------------------
class AcceleratorDictionary : public HashTools::HashMap<int, const GlobalCommandDescriptor*>
{
typedef HashTools::HashMap<int, const GlobalCommandDescriptor*> _parent;
protected:
public:
using _parent::operator[];
AcceleratorDictionary();
virtual ~AcceleratorDictionary() throw();
void Map( const KeyAcceleratorCode& acode, const char *searchfor );
};

View File

@ -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)

View File

@ -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 );

View File

@ -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);
}

View File

@ -841,6 +841,6 @@ struct CrtDebugBreak
}
};
//CrtDebugBreak breakAt( 909 );
//CrtDebugBreak breakAt( 11549 );
#endif

View File

@ -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.

View File

@ -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; i<srcnt; ++i)
{
if (ConsoleLogSource* log = ConLogSources[i])
{
ini.Entry( log->GetCategory() + 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; i<srcnt; ++i)
{
if (const ConsoleLogSource* log = ConLogSources[i])
{
menuSources.Append( MenuId_LogSource_Start+i, log->Name, 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; i<srcnt; ++i)
{
if (ConsoleLogSource* log = ConLogSources[i])
log->Enabled = true;
}
OnLoggingChanged();
evt.Skip();
}
void ConsoleLogFrame::OnDisableAllLogging(wxCommandEvent& evt)
{
uint srcnt = ArraySize(ConLogSources);
for (uint i=0; i<srcnt; ++i)
{
if (ConsoleLogSource* log = ConLogSources[i])
log->Enabled = 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; i<srcnt; ++i)
{
if (const ConsoleLogSource* log = ConLogSources[i])
{
GetMenuBar()->Check( 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();
}

View File

@ -94,11 +94,8 @@ class pxLogTextCtrl : public wxTextCtrl,
public EventListener_Plugins
{
protected:
//EventListenerHelper_CoreThread<pxLogTextCtrl> m_listener_CoreThread;
//EventListenerHelper_Plugins<pxLogTextCtrl> m_listener_Plugins;
ScopedPtr<ScopedCoreThreadPause> m_IsPaused;
bool m_FreezeWrites;
ScopedPtr<ScopedCoreThreadPause> 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<wxMenuItem*> 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();
};

View File

@ -18,11 +18,10 @@
#include <wx/listbook.h>
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 );
}

View File

@ -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 );

View File

@ -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();

View File

@ -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__

View File

@ -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 );

View File

@ -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();

View File

@ -16,58 +16,31 @@
#include "PrecompiledHeader.h"
#include "LogOptionsPanels.h"
#include "Utilities/IniInterface.h"
#include "DebugTools/Debug.h"
#include <wx/statline.h>
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; i<traceLogCount; ++i)
{
if (SysTraceLog* log = traceLogList[i])
{
pxAssertMsg(log->Name, "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; i<traceLogCount; ++i )
{
if( 0 == ident.CmpNoCase(traceLogList[i]->GetCategory()) )
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; i<traceLogCount; ++i )
{
const SysTraceLog& item = *traceLogList[i];
pxAssertMsg(item.Name, "Trace log without a name!" );
wxStringTokenizer token( item.GetCategory(), L"." );
wxSizer* addsizer = NULL;
wxWindow* addparent = NULL;
const wxString cpu(token.GetNextToken());
if( BaseCpuLogOptionsPanel* cpupanel = GetCpuPanel(cpu))
{
const wxString group(token.GetNextToken());
if( CheckedStaticBox* cpugroup = cpupanel->GetStaticBox(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; i<traceLogCount; ++i)
{
if (!traceLogList[i] || !m_checks[i]) continue;
m_checks[i]->SetValue(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; i<traceLogCount; ++i )
{
if (!traceLogList[i] || !m_checks[i]) continue;
traceLogList[i]->Enabled = 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);
}

View File

@ -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<pxCheckBox*> 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;
};
}

View File

@ -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() );
}

View File

@ -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()

View File

@ -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<LangPackEnumeration> 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 )

View File

@ -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:

View File

@ -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) );

View File

@ -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

View File

@ -106,28 +106,33 @@ void __fastcall iopHwWrite8_Page1( u32 addr, mem8_t val )
IopHwTraceLog<mem8_t>( 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;
}
}

View File

@ -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<T>( 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<T>( addr, val ) )
PSXHW_LOG( temp, modestr, (sizeof (T)) * 8, regname, addr, val );
else
PSXUnkHW_LOG( temp, modestr, (sizeof (T)) * 8, "Unknown", addr, val );
}
} };

View File

@ -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)

View File

@ -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();
}

View File

@ -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:

View File

@ -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);

View File

@ -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);

View File

@ -94,7 +94,7 @@ _f void mVUinit(VURegs* vuRegsPtr, int vuIndex) {
mVU->prog.prog[i] = new deque<microProgram*>();
}
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) {

View File

@ -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

View File

@ -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();
}

View File

@ -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