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