diff --git a/pcsx2/CDVD/CDVDaccess.cpp b/pcsx2/CDVD/CDVDaccess.cpp
index 28edebb30d..11f40f4265 100644
--- a/pcsx2/CDVD/CDVDaccess.cpp
+++ b/pcsx2/CDVD/CDVDaccess.cpp
@@ -263,8 +263,7 @@ static void DetectDiskType()
//
void CDVDsys_ChangeSource( CDVD_SourceType type )
{
- if( g_plugins != NULL )
- g_plugins->Close( PluginId_CDVD );
+ GetPluginManager().Close( PluginId_CDVD );
switch( type )
{
diff --git a/pcsx2/DebugTools/Debug.h b/pcsx2/DebugTools/Debug.h
index d40aa91947..5778dbb090 100644
--- a/pcsx2/DebugTools/Debug.h
+++ b/pcsx2/DebugTools/Debug.h
@@ -19,6 +19,7 @@
#pragma once
extern FILE *emuLog;
+extern wxString emuLogName;
extern char* disVU0MicroUF(u32 code, u32 pc);
extern char* disVU0MicroLF(u32 code, u32 pc);
diff --git a/pcsx2/Linux/pcsx2.cbp b/pcsx2/Linux/pcsx2.cbp
index 1abd66c325..3b4ac386b6 100644
--- a/pcsx2/Linux/pcsx2.cbp
+++ b/pcsx2/Linux/pcsx2.cbp
@@ -1,411 +1,412 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pcsx2/MTGS.cpp b/pcsx2/MTGS.cpp
index 479a0ab2c3..54bf053549 100644
--- a/pcsx2/MTGS.cpp
+++ b/pcsx2/MTGS.cpp
@@ -214,7 +214,7 @@ void mtgsThreadObject::Start()
m_sem_InitDone.Wait();
if( m_returncode != 0 ) // means the thread failed to init the GS plugin
- throw Exception::PluginFailure( "GS", wxLt("%s plugin failed to open.") );
+ throw Exception::PluginOpenError( PluginId_GS );
}
mtgsThreadObject::~mtgsThreadObject()
@@ -507,7 +507,7 @@ sptr mtgsThreadObject::ExecuteTask()
GSsetBaseMem( m_gsMem );
GSirqCallback( NULL );
- g_plugins->Open( PluginId_GS );
+ GetPluginManager().Open( PluginId_GS );
Console::WriteLn( "MTGS > GSopen Finished, return code: 0x%x", params m_returncode );
@@ -629,7 +629,7 @@ sptr mtgsThreadObject::ExecuteTask()
{
freezeData* data = (freezeData*)(*(uptr*)&tag.data[1]);
int mode = tag.data[0];
- g_plugins->Freeze( PluginId_GS, mode, data );
+ GetPluginManager().Freeze( PluginId_GS, mode, data );
break;
}
@@ -667,7 +667,7 @@ sptr mtgsThreadObject::ExecuteTask()
break;
case GS_RINGTYPE_QUIT:
- g_plugins->Close( PluginId_GS );
+ GetPluginManager().Close( PluginId_GS );
m_sem_Quitter.Post();
return 0;
diff --git a/pcsx2/Misc.cpp b/pcsx2/Misc.cpp
index 1a985773f9..527b07f5f1 100644
--- a/pcsx2/Misc.cpp
+++ b/pcsx2/Misc.cpp
@@ -210,7 +210,7 @@ void LoadGSState(const wxString& file)
if (ret != 0)
{
delete f;
- throw Exception::PluginFailure( "GS" );
+ throw Exception::PluginOpenError( PluginId_GS );
}
ret = PADopen((void *)&pDsp);
diff --git a/pcsx2/PluginManager.cpp b/pcsx2/PluginManager.cpp
index a26102ab97..bd8d7f5970 100644
--- a/pcsx2/PluginManager.cpp
+++ b/pcsx2/PluginManager.cpp
@@ -527,14 +527,14 @@ PluginManager *g_plugins = NULL;
//////////////////////////////////////////////////////////////////////////////////////////
-Exception::InvalidPluginConfigured::InvalidPluginConfigured( PluginsEnum_t pid, const wxString& objname, const char* eng )
+Exception::PluginLoadError::PluginLoadError( PluginsEnum_t pid, const wxString& objname, const char* eng )
{
BaseException::InitBaseEx( eng );
StreamName = objname;
PluginId = pid;
}
-Exception::InvalidPluginConfigured::InvalidPluginConfigured( PluginsEnum_t pid, const wxString& objname,
+Exception::PluginLoadError::PluginLoadError( PluginsEnum_t pid, const wxString& objname,
const wxString& eng_msg, const wxString& xlt_msg )
{
BaseException::InitBaseEx( eng_msg, xlt_msg );
@@ -542,17 +542,26 @@ Exception::InvalidPluginConfigured::InvalidPluginConfigured( PluginsEnum_t pid,
PluginId = pid;
}
-wxString Exception::PluginFailure::FormatDiagnosticMessage() const
+wxString Exception::PluginLoadError::FormatDiagnosticMessage() const
{
- return wxsFormat(
- L"%s plugin has encountered an error.\n\n",
- plugin_name.c_str()
- ) + m_stacktrace;
+ return wxsFormat( m_message_diag, tbl_PluginInfo[PluginId].GetShortname() ) +
+ L"\n\n" + StreamName;
}
-wxString Exception::PluginFailure::FormatDisplayMessage() const
+wxString Exception::PluginLoadError::FormatDisplayMessage() const
{
- return wxsFormat( m_message_user, plugin_name.c_str() );
+ return wxsFormat( m_message_user, tbl_PluginInfo[PluginId].GetShortname() ) +
+ L"\n\n" + StreamName;
+}
+
+wxString Exception::PluginError::FormatDiagnosticMessage() const
+{
+ return wxsFormat( m_message_diag, tbl_PluginInfo[PluginId].GetShortname() );
+}
+
+wxString Exception::PluginError::FormatDisplayMessage() const
+{
+ return wxsFormat( m_message_user, tbl_PluginInfo[PluginId].GetShortname() );
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -570,14 +579,13 @@ PluginManager::PluginManager( const wxString (&folders)[PluginId_Count] )
m_info[pid].Filename = folders[pid];
if( !wxFile::Exists( folders[pid] ) )
- throw Exception::InvalidPluginConfigured( pid, folders[pid],
- L"Plugin file not found",
- _("The configured plugin file was not found")
+ throw Exception::PluginLoadError( pid, folders[pid],
+ wxLt("The configured %s plugin file was not found")
);
if( !m_info[pid].Lib.Load( folders[pid] ) )
- throw Exception::InvalidPluginConfigured( pid, folders[pid],
- wxLt("Configured plugin file is not a valid dynamic library")
+ throw Exception::PluginLoadError( pid, folders[pid],
+ wxLt("The configured %s plugin file is not a valid dynamic library")
);
// Try to enumerate the new v2.0 plugin interface first.
@@ -625,8 +633,8 @@ void PluginManager::BindCommon( PluginsEnum_t pid )
if( *target == NULL )
{
- throw Exception::InvalidPluginConfigured( pid, m_info[pid].Filename,
- wxLt( "Configured plugin is not a valid PCSX2 plugin, or is for an older unsupported version of PCSX2." ) );
+ throw Exception::PluginLoadError( pid, m_info[pid].Filename,
+ wxLt( "Configured plugin is not a PCSX2 plugin, or is for an older unsupported version of PCSX2." ) );
}
target++;
@@ -650,7 +658,7 @@ void PluginManager::BindRequired( PluginsEnum_t pid )
if( *(current->Dest) == NULL )
{
- throw Exception::InvalidPluginConfigured( pid, m_info[pid].Filename,
+ throw Exception::PluginLoadError( pid, m_info[pid].Filename,
wxLt( "Configured plugin is not a valid PCSX2 plugin, or is for an older unsupported version of PCSX2." ) );
}
@@ -766,7 +774,7 @@ void PluginManager::Open( PluginsEnum_t pid )
case PluginId_DEV9: result = OpenPlugin_DEV9(); break;
}
if( !result )
- throw Exception::PluginFailure( tbl_PluginInfo[pid].shortname, wxLt("%s plugin failed to open.") );
+ throw Exception::PluginOpenError( pid );
m_info[pid].IsOpened = true;
}
@@ -829,7 +837,7 @@ void PluginManager::Init()
if( m_info[pid].IsInitialized ) continue;
m_info[pid].IsInitialized = true;
if( 0 != m_info[pid].CommonBindings.Init() )
- throw Exception::PluginFailure( tbl_PluginInfo[pid].shortname, wxLt( "%s plugin: Initialization Failure" ) );
+ throw Exception::PluginInitError( pid );
}
}
diff --git a/pcsx2/Plugins.h b/pcsx2/Plugins.h
index b43c4eba0c..ce1b53b02a 100644
--- a/pcsx2/Plugins.h
+++ b/pcsx2/Plugins.h
@@ -52,35 +52,57 @@ namespace Exception
BaseException::InitBaseEx( msg );
PluginId = pid;
}
- };
-
- class PluginFailure : public virtual RuntimeError
- {
- public:
- wxString plugin_name; // name of the plugin
-
- public:
- DEFINE_EXCEPTION_COPYTORS( PluginFailure )
-
- explicit PluginFailure( const char* plugin, const char* msg="%s plugin encountered a critical error" )
- {
- BaseException::InitBaseEx( msg );
- plugin_name = wxString::FromUTF8( plugin );
- }
virtual wxString FormatDiagnosticMessage() const;
virtual wxString FormatDisplayMessage() const;
};
- class InvalidPluginConfigured : public virtual PluginError, public virtual BadStream
+ // Plugin load errors occur when initially trying to load plugins durign the
+ // creation of a PluginManager object. The error may either be due to non-existence,
+ // corruption, or incompatible versioning.
+ class PluginLoadError : public virtual PluginError, public virtual BadStream
{
public:
- DEFINE_EXCEPTION_COPYTORS( InvalidPluginConfigured )
+ DEFINE_EXCEPTION_COPYTORS( PluginLoadError )
- InvalidPluginConfigured( PluginsEnum_t pid, const wxString& objname, const char* eng );
+ PluginLoadError( PluginsEnum_t pid, const wxString& objname, const char* eng );
- InvalidPluginConfigured( PluginsEnum_t pid, const wxString& objname,
+ PluginLoadError( PluginsEnum_t pid, const wxString& objname,
const wxString& eng_msg, const wxString& xlt_msg );
+
+ virtual wxString FormatDiagnosticMessage() const;
+ virtual wxString FormatDisplayMessage() const;
+ };
+
+ // Thrown when a plugin fails it's init() callback. The meaning of this error is entirely
+ // dependent on the plugin and, in most cases probably never happens (most plugins do little
+ // more than a couple basic memory reservations during init)
+ class PluginInitError : public virtual PluginError
+ {
+ public:
+ DEFINE_EXCEPTION_COPYTORS( PluginInitError )
+
+ explicit PluginInitError( PluginsEnum_t pid,
+ const char* msg=wxLt("%s plugin failed to initialize. Your system may have insufficient memory or resources needed.") )
+ {
+ BaseException::InitBaseEx( msg );
+ PluginId = pid;
+ }
+ };
+
+ // Plugin failed to open. Typically this is a non-critical error that means the plugin has
+ // not been configured properly by the user, but may also be indicative of a system
+ class PluginOpenError : public virtual PluginError
+ {
+ public:
+ DEFINE_EXCEPTION_COPYTORS( PluginOpenError )
+
+ explicit PluginOpenError( PluginsEnum_t pid,
+ const char* msg=wxLt("%s plugin failed to open. Your computer may have insufficient resources, or incompatible hardware/drivers.") )
+ {
+ BaseException::InitBaseEx( msg );
+ PluginId = pid;
+ }
};
};
diff --git a/pcsx2/SourceLog.cpp b/pcsx2/SourceLog.cpp
index a1c5a24cce..848d61a5ce 100644
--- a/pcsx2/SourceLog.cpp
+++ b/pcsx2/SourceLog.cpp
@@ -35,6 +35,7 @@
using namespace R5900;
FILE *emuLog;
+wxString emuLogName;
#ifdef PCSX2_DEVBUILD
LogSources varLog;
diff --git a/pcsx2/gui/App.h b/pcsx2/gui/App.h
index 9e04a90a18..3a5e470e78 100644
--- a/pcsx2/gui/App.h
+++ b/pcsx2/gui/App.h
@@ -180,6 +180,22 @@ protected:
void OnMessageBox( pxMessageBoxEvent& evt );
void CleanupMess();
void OpenWizardConsole();
+
+ int MainLoop();
+
+ // ----------------------------------------------------------------------------
+ // Override wx default exception handling behavior
+ // ----------------------------------------------------------------------------
+
+ // Just rethrow exceptions in the main loop, so that we can handle them properly in our
+ // custom catch clauses in OnRun(). (ranting note: wtf is the point of this functionality
+ // in wx? Why would anyone ever want a generic catch-all exception handler that *isn't*
+ // the unhandled exception handler? Using this as anything besides a re-throw is terrible
+ // program design and shouldn't even be allowed -- air)
+ bool OnExceptionInMainLoop() { throw; }
+
+ // Just rethrow unhandled exceptions to cause immediate debugger fail.
+ void OnUnhandledException() { throw; }
};
//////////////////////////////////////////////////////////////////////////////////////////
diff --git a/pcsx2/gui/AppConfig.cpp b/pcsx2/gui/AppConfig.cpp
index ea9f72efb2..7c08078a37 100644
--- a/pcsx2/gui/AppConfig.cpp
+++ b/pcsx2/gui/AppConfig.cpp
@@ -22,6 +22,7 @@
#include "Plugins.h"
#include
+#include "DebugTools/Debug.h"
//////////////////////////////////////////////////////////////////////////////////////////
// PathDefs Namespace -- contains default values for various pcsx2 path names and locations.
@@ -630,5 +631,21 @@ void AppConfig_ReloadGlobalSettings( bool overwrite )
g_Conf->Apply();
g_Conf->Folders.Logs.Mkdir();
-}
+ wxString newlogname( Path::Combine( g_Conf->Folders.Logs.ToString(), L"emuLog.txt" ) );
+
+ if( emuLog != NULL )
+ {
+ if( emuLogName != newlogname )
+ {
+ fclose( emuLog );
+ emuLog = NULL;
+ }
+ }
+
+ if( emuLog == NULL )
+ {
+ emuLogName = newlogname;
+ emuLog = fopen( emuLogName.ToUTF8().data(), "wb" );
+ }
+}
diff --git a/pcsx2/gui/AppRes.cpp b/pcsx2/gui/AppRes.cpp
new file mode 100644
index 0000000000..47dc09fff5
--- /dev/null
+++ b/pcsx2/gui/AppRes.cpp
@@ -0,0 +1,167 @@
+/* Pcsx2 - Pc Ps2 Emulator
+ * Copyright (C) 2002-2009 Pcsx2 Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "PrecompiledHeader.h"
+#include "MainFrame.h"
+
+#include
+#include
+
+#include "Resources/EmbeddedImage.h"
+#include "Resources/BackgroundLogo.h"
+
+#include "Resources/ConfigIcon_Cpu.h"
+#include "Resources/ConfigIcon_Video.h"
+#include "Resources/ConfigIcon_Speedhacks.h"
+#include "Resources/ConfigIcon_Gamefixes.h"
+#include "Resources/ConfigIcon_Paths.h"
+#include "Resources/ConfigIcon_Plugins.h"
+
+// ------------------------------------------------------------------------
+const wxImage& LoadImageAny(
+ wxImage& dest, bool useTheme, wxFileName& base, const wxChar* filename, IEmbeddedImage& onFail )
+{
+ if( useTheme )
+ {
+ base.SetName( filename );
+
+ base.SetExt( L"png" );
+ if( base.FileExists() )
+ {
+ if( dest.LoadFile( base.GetFullPath() ) ) return dest;
+ }
+
+ base.SetExt( L"jpg" );
+ if( base.FileExists() )
+ {
+ if( dest.LoadFile( base.GetFullPath() ) ) return dest;
+ }
+
+ base.SetExt( L"bmp" );
+ if( base.FileExists() )
+ {
+ if( dest.LoadFile( base.GetFullPath() ) ) return dest;
+ }
+ }
+
+ return dest = onFail.Get();
+}
+
+// ------------------------------------------------------------------------
+const wxBitmap& Pcsx2App::GetLogoBitmap()
+{
+ if( m_Bitmap_Logo != NULL )
+ return *m_Bitmap_Logo;
+
+ wxFileName mess;
+ bool useTheme = (g_Conf->DeskTheme != L"default");
+
+ if( useTheme )
+ {
+ wxDirName theme( PathDefs::GetThemes() + g_Conf->DeskTheme );
+ wxFileName zipped( theme.GetFilename() );
+
+ zipped.SetExt( L"zip" );
+ if( zipped.FileExists() )
+ {
+ // loading theme from zipfile.
+ //wxFileInputStream stream( zipped.ToString() )
+ //wxZipInputStream zstream( stream );
+
+ Console::Error( "Loading themes from zipfile is not supported yet.\nFalling back on default theme." );
+ }
+
+ // Overrides zipfile settings (fix when zipfile support added)
+ mess = theme.ToString();
+ }
+
+ wxImage img;
+ EmbeddedImage temp; // because gcc can't allow non-const temporaries.
+ LoadImageAny( img, useTheme, mess, L"BackgroundLogo", temp );
+ m_Bitmap_Logo = new wxBitmap( img );
+
+ return *m_Bitmap_Logo;
+}
+
+// ------------------------------------------------------------------------
+wxImageList& Pcsx2App::GetImgList_Config()
+{
+ if( !m_ConfigImagesAreLoaded )
+ {
+ wxFileName mess;
+ bool useTheme = (g_Conf->DeskTheme != L"default");
+
+ if( useTheme )
+ {
+ wxDirName theme( PathDefs::GetThemes() + g_Conf->DeskTheme );
+ mess = theme.ToString();
+ }
+
+ wxImage img;
+
+ // GCC Specific: wxT() macro is required when using string token pasting. For some reason L
+ // generates syntax errors. >_<
+
+ #undef FancyLoadMacro
+ #define FancyLoadMacro( name ) \
+ { \
+ EmbeddedImage temp( g_Conf->Listbook_ImageSize, g_Conf->Listbook_ImageSize ); \
+ m_ImageId.Config.name = m_ConfigImages.Add( LoadImageAny( \
+ img, useTheme, mess, L"ConfigIcon_" wxT(#name), temp ) \
+ ); \
+ }
+
+ FancyLoadMacro( Paths );
+ FancyLoadMacro( Plugins );
+ FancyLoadMacro( Gamefixes );
+ FancyLoadMacro( Speedhacks );
+ FancyLoadMacro( Video );
+ FancyLoadMacro( Cpu );
+ }
+ m_ConfigImagesAreLoaded = true;
+ return m_ConfigImages;
+}
+
+// ------------------------------------------------------------------------
+wxImageList& Pcsx2App::GetImgList_Toolbars()
+{
+ if( m_ToolbarImages == NULL )
+ {
+ const int imgSize = g_Conf->Toolbar_ImageSize ? 64 : 32;
+ m_ToolbarImages = new wxImageList( imgSize, imgSize );
+ wxFileName mess;
+ bool useTheme = (g_Conf->DeskTheme != L"default");
+
+ if( useTheme )
+ {
+ wxDirName theme( PathDefs::GetThemes() + g_Conf->DeskTheme );
+ mess = theme.ToString();
+ }
+
+ wxImage img;
+ #undef FancyLoadMacro
+ #define FancyLoadMacro( name ) \
+ { \
+ EmbeddedImage temp( imgSize, imgSize ); \
+ m_ImageId.Toolbars.name = m_ConfigImages.Add( LoadImageAny( img, useTheme, mess, L"ToolbarIcon" wxT(#name), temp ) ); \
+ }
+
+ }
+ return *m_ToolbarImages;
+}
+
diff --git a/pcsx2/gui/ConsoleLogger.cpp b/pcsx2/gui/ConsoleLogger.cpp
index d763eec7cd..b39076e9e3 100644
--- a/pcsx2/gui/ConsoleLogger.cpp
+++ b/pcsx2/gui/ConsoleLogger.cpp
@@ -314,19 +314,6 @@ void ConsoleLogFrame::ClearColor()
void ConsoleLogFrame::Write( const wxString& text )
{
- // Many platforms still do not provide thread-safe implementations of
- // fputs or printf, so they need to be implemented here.
- // fixme: these really should go in the global message handler but I haven't time to
- // do that right now.
- if( emuLog != NULL )
- fputs( text.ToUTF8().data(), emuLog );
-
- // Linux has a handy dandy universal console...
- // [TODO] make this a configurable option? Do we care? :)
- #ifdef __LINUX__
- printf( (L"PCSX2 > " + text).ToUTF8().data() );
- #endif
-
// remove selection (WriteText is in fact ReplaceSelection)
// TODO : Optimize this to only replace selection if some selection
// messages have been received since the last write.
@@ -568,11 +555,38 @@ void ConsoleLogFrame::DoMessage()
//////////////////////////////////////////////////////////////////////////////////////////
-//
+//
namespace Console
{
// thread-local console color storage.
- __threadlocal Colors th_CurrentColor = DefaultConsoleColor;
+ static __threadlocal Colors th_CurrentColor = DefaultConsoleColor;
+
+ static Threading::MutexLock immediate_log_lock;
+
+ // performs immediate thread-safe (mutex locked) logging to disk and to the Linux console.
+ // Many platforms still do not provide thread-safe implementations of fputs or printf, so
+ // they are implemented here using a mutex lock for maximum safety.
+ static void _immediate_logger( const char* src )
+ {
+ ScopedLock locker( immediate_log_lock );
+
+ if( emuLog != NULL )
+ fputs( src, emuLog ); // fputs does not do automatic newlines, so it's ok!
+
+ // Linux has a handy dandy universal console...
+ // [TODO] make this a configurable option? Do we care? :)
+#ifdef __LINUX__
+ // puts does automatic newlines, which we don't want here
+ fputs( L"PCSX2 > ", stdout );
+ fputs( src, stdout );
+#endif
+
+ }
+
+ static void _immediate_logger( const wxString& src )
+ {
+ _immediate_logger( src.ToUTF8().data() );
+ }
void __fastcall SetTitle( const wxString& title )
{
@@ -593,6 +607,8 @@ namespace Console
bool Newline()
{
+ _immediate_logger( "\n" );
+
wxCommandEvent evt( wxEVT_LOG_Newline );
wxGetApp().ProgramLog_PostEvent( evt );
wxGetApp().ProgramLog_CountMsg();
@@ -602,6 +618,8 @@ namespace Console
bool __fastcall Write( const char* fmt )
{
+ _immediate_logger( fmt );
+
wxCommandEvent evt( wxEVT_LOG_Write );
evt.SetString( wxString::FromAscii( fmt ) );
evt.SetExtraLong( th_CurrentColor );
@@ -613,6 +631,8 @@ namespace Console
bool __fastcall Write( const wxString& fmt )
{
+ _immediate_logger( fmt );
+
wxCommandEvent evt( wxEVT_LOG_Write );
evt.SetString( fmt );
evt.SetExtraLong( th_CurrentColor );
@@ -624,11 +644,14 @@ namespace Console
bool __fastcall WriteLn( const char* fmt )
{
+ const wxString fmtline( wxString::FromAscii( fmt ) + L"\n" );
+ _immediate_logger( fmtline );
+
// Implementation note: I've duplicated Write+Newline behavior here to avoid polluting
// the message pump with lots of erroneous messages (Newlines can be bound into Write message).
wxCommandEvent evt( wxEVT_LOG_Write );
- evt.SetString( wxString::FromAscii( fmt ) + L"\n" );
+ evt.SetString( fmtline );
evt.SetExtraLong( th_CurrentColor );
wxGetApp().ProgramLog_PostEvent( evt );
wxGetApp().ProgramLog_CountMsg();
@@ -638,11 +661,14 @@ namespace Console
bool __fastcall WriteLn( const wxString& fmt )
{
+ const wxString fmtline( fmt + L"\n" );
+ _immediate_logger( fmtline );
+
// Implementation note: I've duplicated Write+Newline behavior here to avoid polluting
// the message pump with lots of erroneous messages (Newlines can be bound into Write message).
wxCommandEvent evt( wxEVT_LOG_Write );
- evt.SetString( fmt + L"\n" );
+ evt.SetString( fmtline );
evt.SetExtraLong( th_CurrentColor );
wxGetApp().ProgramLog_PostEvent( evt );
wxGetApp().ProgramLog_CountMsg();
diff --git a/pcsx2/gui/HostGui.cpp b/pcsx2/gui/HostGui.cpp
index 7e3e8a3502..3e48809e9d 100644
--- a/pcsx2/gui/HostGui.cpp
+++ b/pcsx2/gui/HostGui.cpp
@@ -98,7 +98,7 @@ namespace HostGui
SysSuspend();
StateRecovery::MakeGsOnly();
- g_plugins->Close( PluginId_GS );
+ GetPluginManager().Close( PluginId_GS );
renderswitch = !renderswitch;
StateRecovery::Recover();
diff --git a/pcsx2/gui/MainMenuClicks.cpp b/pcsx2/gui/MainMenuClicks.cpp
index 0bb77450d2..08092b781c 100644
--- a/pcsx2/gui/MainMenuClicks.cpp
+++ b/pcsx2/gui/MainMenuClicks.cpp
@@ -89,6 +89,7 @@ void MainEmuFrame::Menu_RunIso_Click(wxCommandEvent &event)
}
}
+ InitPlugins();
SysExecute( new AppEmuThread( elf_file ), CDVDsrc_Iso );
}
@@ -109,6 +110,7 @@ void MainEmuFrame::Menu_RunWithoutDisc_Click(wxCommandEvent &event)
}
SysEndExecution();
+ InitPlugins();
SysExecute( new AppEmuThread(), CDVDsrc_NoDisc );
}
diff --git a/pcsx2/gui/Panels/PluginSelectorPanel.cpp b/pcsx2/gui/Panels/PluginSelectorPanel.cpp
index c59e71411f..94dd471f19 100644
--- a/pcsx2/gui/Panels/PluginSelectorPanel.cpp
+++ b/pcsx2/gui/Panels/PluginSelectorPanel.cpp
@@ -91,10 +91,7 @@ public:
m_type = m_GetLibType();
}
- // Parameters:
- // pluginTypeIndex - Value from 1 to 8 which represents the plugin's index.
- //
- bool CheckVersion( int pluginTypeIndex ) const
+ bool CheckVersion( PluginsEnum_t pluginTypeIndex ) const
{
const PluginInfo& info( tbl_PluginInfo[pluginTypeIndex] );
if( m_type & info.typemask )
@@ -436,36 +433,37 @@ void Panels::PluginSelectorPanel::EnumThread::Cancel()
sptr Panels::PluginSelectorPanel::EnumThread::ExecuteTask()
{
- DevCon::WriteLn( "Plugin Enumeration Thread started..." );
+ DevCon::Status( "Plugin Enumeration Thread started..." );
Sleep( 10 ); // gives the gui thread some time to refresh
for( int curidx=0; curidx < m_master.FileCount(); ++curidx )
{
if( m_cancel ) return 0;
-
- Results[curidx].TypeMask = 0;
+ DbgCon::WriteLn( L"Enumerating Plugin: " + m_master.GetFilename( curidx ) );
try
{
- PluginEnumerator penum( m_master.GetFilename( curidx ) );
EnumeratedPluginInfo& result( Results[curidx] );
+ result.TypeMask = 0;
+
+ PluginEnumerator penum( m_master.GetFilename( curidx ) );
result.Name = penum.GetName();
- for( int pidx=0; pidxAddPendingEvent( done );
- DevCon::WriteLn( "Plugin Enumeration Thread complete!" );
+ DevCon::Status( "Plugin Enumeration Thread complete!" );
return 0;
}
diff --git a/pcsx2/gui/main.cpp b/pcsx2/gui/main.cpp
index f523b86b04..20c85009a7 100644
--- a/pcsx2/gui/main.cpp
+++ b/pcsx2/gui/main.cpp
@@ -23,14 +23,11 @@
#include "Plugins.h"
#include "Dialogs/ModalPopups.h"
-
#include "Utilities/ScopedPtr.h"
-#include "Resources/EmbeddedImage.h"
-#include "Resources/BackgroundLogo.h"
-
#include
#include
+#include
IMPLEMENT_APP(Pcsx2App)
@@ -310,6 +307,78 @@ void Pcsx2App::CleanupMess()
safe_delete( g_Conf );
}
+static int pxRunningEventLoopCount = 0;
+
+class pxEvtLoop : public wxEventLoop
+{
+protected:
+ struct pxRunningEventLoopCounter
+ {
+ pxRunningEventLoopCounter() { pxRunningEventLoopCount++; }
+ ~pxRunningEventLoopCounter() { pxRunningEventLoopCount--; }
+ };
+
+public:
+ virtual int Run()
+ {
+ // event loops are not recursive, you need to create another loop!
+ wxCHECK_MSG( !IsRunning(), -1, _T("can't reenter a message loop") );
+
+ wxEventLoopActivator activate(wx_static_cast(wxEventLoop *, this));
+
+#if defined(__WXMSW__) && wxUSE_THREADS
+ pxRunningEventLoopCounter evtLoopCounter;
+#endif // __WXMSW__
+
+ while( true )
+ {
+ try
+ {
+ while( !m_shouldExit )
+ {
+ // give ourselves the possibility to do whatever we want!
+ OnNextIteration();
+
+ while( Pending() )
+ {
+ if( !Dispatch() )
+ {
+ m_shouldExit = true;
+ break;
+ }
+ }
+
+ if( wxTheApp )
+ wxTheApp->ProcessIdle();
+ }
+ break;
+ }
+ // ----------------------------------------------------------------------------
+ catch( Exception::PluginError& ex )
+ {
+ }
+ // ----------------------------------------------------------------------------
+ catch( Exception::RuntimeError& ex )
+ {
+ // Runtime errors which have been unhandled should still be safe to recover from,
+ // so lets issue a message to the user and then continue the message pump.
+
+ Console::Error( ex.FormatDiagnosticMessage() );
+ Msgbox::Alert( ex.FormatDisplayMessage() );
+ }
+ }
+ }
+};
+
+// This overload performs universal exception handling for specific types of recoverable
+// errors that can be thrown from a multitude of events.
+int Pcsx2App::MainLoop()
+{
+ assert( m_mainLoop == NULL );
+ m_mainLoop = new pxEvtLoop();
+ return m_mainLoop->Run();
+}
+
// Common exit handler which can be called from any event (though really it should
// be called only from CloseWindow handlers since that's the more appropriate way
// to handle window closures)
@@ -320,6 +389,7 @@ bool Pcsx2App::PrepForExit()
int Pcsx2App::OnExit()
{
+ m_ProgramLogBox = NULL;
MemoryCard::Shutdown();
if( g_Conf != NULL )
@@ -345,146 +415,4 @@ Pcsx2App::~Pcsx2App()
CleanupMess();
}
-#include
-#include
-
-// ------------------------------------------------------------------------
-const wxImage& LoadImageAny(
- wxImage& dest, bool useTheme, wxFileName& base, const wxChar* filename, IEmbeddedImage& onFail )
-{
- if( useTheme )
- {
- base.SetName( filename );
-
- base.SetExt( L"png" );
- if( base.FileExists() )
- {
- if( dest.LoadFile( base.GetFullPath() ) ) return dest;
- }
-
- base.SetExt( L"jpg" );
- if( base.FileExists() )
- {
- if( dest.LoadFile( base.GetFullPath() ) ) return dest;
- }
-
- base.SetExt( L"bmp" );
- if( base.FileExists() )
- {
- if( dest.LoadFile( base.GetFullPath() ) ) return dest;
- }
- }
-
- return dest = onFail.Get();
-}
-
-// ------------------------------------------------------------------------
-const wxBitmap& Pcsx2App::GetLogoBitmap()
-{
- if( m_Bitmap_Logo != NULL )
- return *m_Bitmap_Logo;
-
- wxFileName mess;
- bool useTheme = (g_Conf->DeskTheme != L"default");
-
- if( useTheme )
- {
- wxDirName theme( PathDefs::GetThemes() + g_Conf->DeskTheme );
- wxFileName zipped( theme.GetFilename() );
-
- zipped.SetExt( L"zip" );
- if( zipped.FileExists() )
- {
- // loading theme from zipfile.
- //wxFileInputStream stream( zipped.ToString() )
- //wxZipInputStream zstream( stream );
-
- Console::Error( "Loading themes from zipfile is not supported yet.\nFalling back on default theme." );
- }
-
- // Overrides zipfile settings (fix when zipfile support added)
- mess = theme.ToString();
- }
-
- wxImage img;
- EmbeddedImage temp; // because gcc can't allow non-const temporaries.
- LoadImageAny( img, useTheme, mess, L"BackgroundLogo", temp );
- m_Bitmap_Logo = new wxBitmap( img );
-
- return *m_Bitmap_Logo;
-}
-
-#include "Resources/ConfigIcon_Cpu.h"
-#include "Resources/ConfigIcon_Video.h"
-#include "Resources/ConfigIcon_Speedhacks.h"
-#include "Resources/ConfigIcon_Gamefixes.h"
-#include "Resources/ConfigIcon_Paths.h"
-#include "Resources/ConfigIcon_Plugins.h"
-
-// ------------------------------------------------------------------------
-wxImageList& Pcsx2App::GetImgList_Config()
-{
- if( !m_ConfigImagesAreLoaded )
- {
- wxFileName mess;
- bool useTheme = (g_Conf->DeskTheme != L"default");
-
- if( useTheme )
- {
- wxDirName theme( PathDefs::GetThemes() + g_Conf->DeskTheme );
- mess = theme.ToString();
- }
-
- wxImage img;
-
- // GCC Specific: wxT() macro is required when using string token pasting. For some reason L
- // generates syntax errors. >_<
-
- #undef FancyLoadMacro
- #define FancyLoadMacro( name ) \
- { \
- EmbeddedImage temp( g_Conf->Listbook_ImageSize, g_Conf->Listbook_ImageSize ); \
- m_ImageId.Config.name = m_ConfigImages.Add( LoadImageAny( \
- img, useTheme, mess, L"ConfigIcon_" wxT(#name), temp ) \
- ); \
- }
-
- FancyLoadMacro( Paths );
- FancyLoadMacro( Plugins );
- FancyLoadMacro( Gamefixes );
- FancyLoadMacro( Speedhacks );
- FancyLoadMacro( Video );
- FancyLoadMacro( Cpu );
- }
- m_ConfigImagesAreLoaded = true;
- return m_ConfigImages;
-}
-
-// ------------------------------------------------------------------------
-wxImageList& Pcsx2App::GetImgList_Toolbars()
-{
- if( m_ToolbarImages == NULL )
- {
- const int imgSize = g_Conf->Toolbar_ImageSize ? 64 : 32;
- m_ToolbarImages = new wxImageList( imgSize, imgSize );
- wxFileName mess;
- bool useTheme = (g_Conf->DeskTheme != L"default");
-
- if( useTheme )
- {
- wxDirName theme( PathDefs::GetThemes() + g_Conf->DeskTheme );
- mess = theme.ToString();
- }
-
- wxImage img;
- #undef FancyLoadMacro
- #define FancyLoadMacro( name ) \
- { \
- EmbeddedImage temp( imgSize, imgSize ); \
- m_ImageId.Toolbars.name = m_ConfigImages.Add( LoadImageAny( img, useTheme, mess, L"ToolbarIcon" wxT(#name), temp ) ); \
- }
-
- }
- return *m_ToolbarImages;
-}
diff --git a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj
index c69b4a59dd..2d1ee0bb0b 100644
--- a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj
+++ b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj
@@ -1914,6 +1914,10 @@
RelativePath="..\..\gui\AppConfig.cpp"
>
+
+