diff --git a/pcsx2/System/SysCoreThread.cpp b/pcsx2/System/SysCoreThread.cpp index 6dd9c95ca3..f514537dbc 100644 --- a/pcsx2/System/SysCoreThread.cpp +++ b/pcsx2/System/SysCoreThread.cpp @@ -151,10 +151,16 @@ bool SysCoreThread::HasPendingStateChangeRequest() const void SysCoreThread::_reset_stuff_as_needed() { + // Note that resetting recompilers along with the virtual machine is only really needed + // because of changes to the TLB. We don't actually support the TLB, however, so rec + // resets aren't in fact *needed* ... yet. But might as well, no harm. --air + if( m_resetVirtualMachine || m_resetRecompilers || m_resetProfilers ) { SysClearExecutionCache(); memBindConditionalHandlers(); + SetCPUState( EmuConfig.Cpu.sseMXCSR, EmuConfig.Cpu.sseVUMXCSR ); + m_resetRecompilers = false; m_resetProfilers = false; } @@ -162,18 +168,18 @@ void SysCoreThread::_reset_stuff_as_needed() if( m_resetVirtualMachine ) { DoCpuReset(); + m_resetVirtualMachine = false; - m_resetRecompilers = true; + m_resetVsyncTimers = false; } if( m_resetVsyncTimers ) { UpdateVSyncRate(); frameLimitReset(); + m_resetVsyncTimers = false; } - - SetCPUState( EmuConfig.Cpu.sseMXCSR, EmuConfig.Cpu.sseVUMXCSR ); } void SysCoreThread::DoCpuReset() @@ -205,12 +211,10 @@ void SysCoreThread::GameStartingInThread() if (EmuConfig.EnableCheats) ApplyCheat(0); } -void SysCoreThread::StateCheckInThread() +bool SysCoreThread::StateCheckInThread() { GetMTGS().RethrowException(); - _parent::StateCheckInThread(); - - _reset_stuff_as_needed(); // kinda redundant but could catch unexpected threaded state changes... + return _parent::StateCheckInThread() && (_reset_stuff_as_needed(), true); } // Runs CPU cycles indefinitely, until the user or another thread requests execution to break. diff --git a/pcsx2/System/SysThreadBase.cpp b/pcsx2/System/SysThreadBase.cpp index a002af141c..872938eeea 100644 --- a/pcsx2/System/SysThreadBase.cpp +++ b/pcsx2/System/SysThreadBase.cpp @@ -230,7 +230,16 @@ void SysThreadBase::OnCleanupInThread() void SysThreadBase::OnSuspendInThread() {} void SysThreadBase::OnResumeInThread( bool isSuspended ) {} -void SysThreadBase::StateCheckInThread() +// Tests for Pause and Suspend/Close requests. If the thread is trying to be paused or +// closed, it will enter a wait/holding pattern here in this method until the managing +// thread releases it. Use the return value to detect if changes to the thread's state +// may have been changed (based on the rule that other threads are not allowed to modify +// this thread's state without pausing or closing it first, to prevent race conditions). +// +// Return value: +// TRUE if the thread was paused or closed; FALSE if the thread +// continued execution unimpeded. +bool SysThreadBase::StateCheckInThread() { switch( m_ExecMode ) { @@ -240,14 +249,14 @@ void SysThreadBase::StateCheckInThread() // threads should never have this state set while the thread is in any way // active or alive. (for obvious reasons!!) pxFailDev( "Invalid execution state detected." ); - break; + return false; #endif case ExecMode_Opened: - // Yup, need this a second time. Variable state could have changed while we - // were trying to acquire the lock above. + // Other cases don't need TestCancel() because its built into the various + // threading wait/signal actions. TestCancel(); - break; + return false; // ------------------------------------- case ExecMode_Pausing: @@ -291,4 +300,6 @@ void SysThreadBase::StateCheckInThread() jNO_DEFAULT; } + + return true; } diff --git a/pcsx2/System/SysThreads.h b/pcsx2/System/SysThreads.h index cdc5c0eaa0..aa673c0e08 100644 --- a/pcsx2/System/SysThreads.h +++ b/pcsx2/System/SysThreads.h @@ -119,7 +119,7 @@ protected: // Resume() has a lot of checks and balances to prevent re-entrance and race conditions. virtual void OnResumeReady() {} - virtual void StateCheckInThread(); + virtual bool StateCheckInThread(); virtual void OnCleanupInThread(); virtual void OnStartInThread(); @@ -184,7 +184,7 @@ public: virtual void Cancel( bool isBlocking=true ); virtual bool Cancel( const wxTimeSpan& timeout ); - virtual void StateCheckInThread(); + virtual bool StateCheckInThread(); virtual void VsyncInThread(); virtual void GameStartingInThread(); diff --git a/pcsx2/gui/App.h b/pcsx2/gui/App.h index 753d240ccd..8b15a691fc 100644 --- a/pcsx2/gui/App.h +++ b/pcsx2/gui/App.h @@ -564,12 +564,12 @@ public: void PostAppMethod( FnPtr_Pcsx2App method ); void PostIdleAppMethod( FnPtr_Pcsx2App method ); + void SysApplySettings(); void SysExecute(); void SysExecute( CDVD_SourceType cdvdsrc, const wxString& elf_override=wxEmptyString ); void SysShutdown(); void LogicalVsync(); - void GameStarting(); - + GSFrame& GetGsFrame() const; MainEmuFrame& GetMainFrame() const; diff --git a/pcsx2/gui/AppCoreThread.cpp b/pcsx2/gui/AppCoreThread.cpp index 3dc8c3bf17..f4f6370ab8 100644 --- a/pcsx2/gui/AppCoreThread.cpp +++ b/pcsx2/gui/AppCoreThread.cpp @@ -22,6 +22,10 @@ #include "ps2/BiosTools.h" #include "GS.h" +#include "cdvd/CDVD.h" +#include "Elfheader.h" +#include "Patch.h" + __aligned16 SysMtgsThread mtgsThread; __aligned16 AppCoreThread CoreThread; @@ -144,32 +148,148 @@ void AppCoreThread::ChangeCdvdSource() // TODO: Add a listener for CDVDsource changes? Or should we bother? } -extern int loadGameSettings(IGameDatabase* gameDB=NULL); - -void AppCoreThread::OnResumeReady() +void Pcsx2App::SysApplySettings() { - ApplySettings( g_Conf->EmuOptions ); - loadGameSettings(); + if( InvokeOnMainThread(&Pcsx2App::SysApplySettings) ) return; + CoreThread.ApplySettings( g_Conf->EmuOptions ); CDVD_SourceType cdvdsrc( g_Conf->CdvdSource ); if( cdvdsrc != CDVDsys_GetSourceType() || (cdvdsrc==CDVDsrc_Iso && (CDVDsys_GetFile(cdvdsrc) != g_Conf->CurrentIso)) ) { - m_resetCdvd = true; + CoreThread.ResetCdvd(); } CDVDsys_SetFile( CDVDsrc_Iso, g_Conf->CurrentIso ); +} - AppSaveSettings(); - +void AppCoreThread::OnResumeReady() +{ + wxGetApp().SysApplySettings(); + wxGetApp().PostMethod( AppSaveSettings ); _parent::OnResumeReady(); } +// Load Game Settings found in database +// (game fixes, round modes, clamp modes, etc...) +// Returns number of gamefixes set +static int loadGameSettings(Pcsx2Config& dest, IGameDatabase* gameDB) { + if (!gameDB) gameDB = wxGetApp().GetGameDatabase(); + + if (!gameDB->gameLoaded()) return 0; + + int gf = 0; + + if (gameDB->keyExists("eeRoundMode")) + { + SSE_RoundMode eeRM = (SSE_RoundMode)gameDB->getInt("eeRoundMode"); + if (EnumIsValid(eeRM)) + { + Console.WriteLn("(GameDB) Changing EE/FPU roundmode to %d [%s]", eeRM, EnumToString(eeRM)); + dest.Cpu.sseMXCSR.SetRoundMode(eeRM); + ++gf; + } + } + + if (gameDB->keyExists("vuRoundMode")) + { + SSE_RoundMode vuRM = (SSE_RoundMode)gameDB->getInt("vuRoundMode"); + if (EnumIsValid(vuRM)) + { + Console.WriteLn("(GameDB) Changing VU0/VU1 roundmode to %d [%s]", vuRM, EnumToString(vuRM)); + dest.Cpu.sseVUMXCSR.SetRoundMode(vuRM); + ++gf; + } + } + + if (gameDB->keyExists("eeClampMode")) { + int clampMode = gameDB->getInt("eeClampMode"); + Console.WriteLn("(GameDB) Changing EE/FPU clamp mode [mode=%d]", clampMode); + dest.Recompiler.fpuOverflow = (clampMode >= 1); + dest.Recompiler.fpuExtraOverflow = (clampMode >= 2); + dest.Recompiler.fpuFullMode = (clampMode >= 3); + gf++; + } + + if (gameDB->keyExists("vuClampMode")) { + int clampMode = gameDB->getInt("vuClampMode"); + Console.WriteLn("(GameDB) Changing VU0/VU1 clamp mode [mode=%d]", clampMode); + dest.Recompiler.vuOverflow = (clampMode >= 1); + dest.Recompiler.vuExtraOverflow = (clampMode >= 2); + dest.Recompiler.vuSignOverflow = (clampMode >= 3); + gf++; + } + + for( GamefixId id=GamefixId_FIRST; idkeyExists(key)) + { + bool enableIt = gameDB->getBool(key); + dest.Gamefixes.Set(id, enableIt ); + Console.WriteLn(L"(GameDB) %s Gamefix: " + key, enableIt ? L"Enabled" : L"Disabled" ); + gf++; + } + } + + return gf; +} + void AppCoreThread::ApplySettings( const Pcsx2Config& src ) { Pcsx2Config fixup( src ); - if( !g_Conf->EnableSpeedHacks ) + + wxString gameCRC; + wxString gameSerial; + wxString gamePatch; + wxString gameFixes; + wxString gameCheats; + + // [TODO] : Fix this so that it recognizes and reports BIOS-booting status! + wxString gameName (L"Unknown"); + wxString gameCompat; + + if (ElfCRC) gameCRC.Printf( L"%8.8x", ElfCRC ); + if (!DiscID.IsEmpty()) gameSerial = L" [" + DiscID + L"]"; + + if (IGameDatabase* GameDB = AppHost_GetGameDatabase() ) + { + if (GameDB->gameLoaded()) { + int compat = GameDB->getInt("Compat"); + gameName = GameDB->getString("Name"); + gameName += L" (" + GameDB->getString("Region") + L")"; + gameCompat = L" [Status = "+compatToStringWX(compat)+L"]"; + } + + if (EmuConfig.EnablePatches) { + if (int patches = InitPatches(gameCRC)) { + gamePatch.Printf(L" [%d Patches]", patches); + } + if (int fixes = loadGameSettings(fixup, GameDB)) { + gameFixes.Printf(L" [%d Fixes]", fixes); + } + } + } + + if (EmuConfig.EnableCheats) { + if (int cheats = InitCheats(gameCRC)) { + gameCheats.Printf(L" [%d Cheats]", cheats); + } + } + + Console.SetTitle(gameName+gameSerial+gameCompat+gameFixes+gamePatch+gameCheats); + + const CommandlineOverrides& overrides( wxGetApp().Overrides ); + if( overrides.DisableSpeedhacks || !g_Conf->EnableSpeedHacks ) fixup.Speedhacks = Pcsx2Config::SpeedhackOptions(); - if( !g_Conf->EnableGameFixes ) + + if( overrides.ApplyCustomGamefixes ) + { + for (GamefixId id=GamefixId_FIRST; id < pxEnumEnd; ++id) + fixup.Gamefixes.Set( id, overrides.UseGamefix[id] ); + } + else if( !g_Conf->EnableGameFixes ) fixup.Gamefixes = Pcsx2Config::GamefixOptions(); // Re-entry guard protects against cases where code wants to manually set core settings @@ -241,13 +361,20 @@ void AppCoreThread::VsyncInThread() void AppCoreThread::GameStartingInThread() { - wxGetApp().GameStarting(); + // Simulate a Close/Resume, so that settings get re-applied and the database + // lookups and other game-based detections are done. + + m_ExecMode = ExecMode_Paused; + OnResumeReady(); + _reset_stuff_as_needed(); + m_ExecMode = ExecMode_Opened; + _parent::GameStartingInThread(); } -void AppCoreThread::StateCheckInThread() +bool AppCoreThread::StateCheckInThread() { - _parent::StateCheckInThread(); + return _parent::StateCheckInThread(); } void AppCoreThread::UploadStateCopy( const VmStateBuffer& copy ) diff --git a/pcsx2/gui/AppCoreThread.h b/pcsx2/gui/AppCoreThread.h index b96473178e..2a6e18dc6d 100644 --- a/pcsx2/gui/AppCoreThread.h +++ b/pcsx2/gui/AppCoreThread.h @@ -128,12 +128,14 @@ protected: public: AppCoreThread(); virtual ~AppCoreThread() throw(); + + void ResetCdvd() { m_resetCdvd = true; } virtual void Suspend( bool isBlocking=false ); virtual void Resume(); virtual void Shutdown(); virtual void Cancel( bool isBlocking=true ); - virtual void StateCheckInThread(); + virtual bool StateCheckInThread(); virtual void ChangeCdvdSource(); virtual void ApplySettings( const Pcsx2Config& src ); diff --git a/pcsx2/gui/AppMain.cpp b/pcsx2/gui/AppMain.cpp index 24e3321761..6a538452fd 100644 --- a/pcsx2/gui/AppMain.cpp +++ b/pcsx2/gui/AppMain.cpp @@ -332,128 +332,6 @@ void Pcsx2App::LogicalVsync() } } -// Load Game Settings found in database -// (game fixes, round modes, clamp modes, etc...) -// Returns number of gamefixes set -int loadGameSettings(IGameDatabase* gameDB) { - if (!gameDB) - gameDB = wxGetApp().GetGameDatabase(); - - if(!gameDB->gameLoaded()) return 0; - - Pcsx2Config sysLocal( EmuConfig ); - - int gf = 0; - - bool rm = false; - if (gameDB->keyExists("eeRoundMode")) - { - SSE_RoundMode eeRM = (SSE_RoundMode)gameDB->getInt("eeRoundMode"); - if (EnumIsValid(eeRM)) - { - Console.WriteLn("(GameDB) Changing EE/FPU roundmode to %d [%s]", eeRM, EnumToString(eeRM)); - sysLocal.Cpu.sseMXCSR.SetRoundMode(eeRM); - rm = true; - ++gf; - } - } - - if (gameDB->keyExists("vuRoundMode")) - { - SSE_RoundMode vuRM = (SSE_RoundMode)gameDB->getInt("vuRoundMode"); - if (EnumIsValid(vuRM)) - { - Console.WriteLn("(GameDB) Changing VU0/VU1 roundmode to %d [%s]", vuRM, EnumToString(vuRM)); - sysLocal.Cpu.sseVUMXCSR.SetRoundMode(vuRM); - rm = true; - ++gf; - } - } - - if (gameDB->keyExists("eeClampMode")) { - int clampMode = gameDB->getInt("eeClampMode"); - Console.WriteLn("(GameDB) Changing EE/FPU clamp mode [mode=%d]", clampMode); - sysLocal.Recompiler.fpuOverflow = (clampMode >= 1); - sysLocal.Recompiler.fpuExtraOverflow = (clampMode >= 2); - sysLocal.Recompiler.fpuFullMode = (clampMode >= 3); - gf++; - } - - if (gameDB->keyExists("vuClampMode")) { - int clampMode = gameDB->getInt("vuClampMode"); - Console.WriteLn("(GameDB) Changing VU0/VU1 clamp mode [mode=%d]", clampMode); - sysLocal.Recompiler.vuOverflow = (clampMode >= 1); - sysLocal.Recompiler.vuExtraOverflow = (clampMode >= 2); - sysLocal.Recompiler.vuSignOverflow = (clampMode >= 3); - gf++; - } - - for( GamefixId id=GamefixId_FIRST; idkeyExists(key)) - { - bool enableIt = gameDB->getBool(key); - sysLocal.Gamefixes.Set(id, enableIt ); - Console.WriteLn(L"(GameDB) %s Gamefix: " + key, enableIt ? L"Enabled" : L"Disabled" ); - gf++; - } - } - - GetCoreThread().ApplySettings( sysLocal ); - - return gf; -} - -#include "CDVD/CDVD.h" -#include "Elfheader.h" -#include "Patch.h" - - -void Pcsx2App::GameStarting() -{ - if( PostAppMethodMyself( &Pcsx2App::GameStarting ) ) return; - - wxString gameCRC; - wxString gameName (L"Unknown Game (\?\?\?)"); - wxString gameSerial (L" [" + DiscID + L"]"); - wxString gameCompat (L" [Status = Unknown]"); - wxString gamePatch; - wxString gameFixes; - wxString gameCheats; - - if( ElfCRC ) gameCRC.Printf( L"%8.8x", ElfCRC ); - - if (IGameDatabase* GameDB = AppHost_GetGameDatabase() ) - { - if (GameDB->gameLoaded()) { - int compat = GameDB->getInt("Compat"); - gameName = GameDB->getString("Name"); - gameName += L" (" + GameDB->getString("Region") + L")"; - gameCompat = L" [Status = "+compatToStringWX(compat)+L"]"; - } - - if (EmuConfig.EnablePatches) { - if (int patches = InitPatches(gameCRC)) { - gamePatch.Printf(L" [%d Patches]", patches); - } - if (int fixes = loadGameSettings(GameDB)) { - gameFixes.Printf(L" [%d Fixes]", fixes); - } - } - } - - if (EmuConfig.EnableCheats) { - if (int cheats = InitCheats(gameCRC)) { - gameCheats.Printf(L" [Cheats = %d]", cheats); - } - } - - Console.SetTitle(gameName+gameSerial+gameCompat+gameFixes+gamePatch+gameCheats); -} - // ---------------------------------------------------------------------------- // Pcsx2App Event Handlers // ---------------------------------------------------------------------------- @@ -1124,4 +1002,4 @@ AppGameDatabase* Pcsx2App::GetGameDatabase() IGameDatabase* AppHost_GetGameDatabase() { return wxGetApp().GetGameDatabase(); -} +} \ No newline at end of file diff --git a/pcsx2/gui/GlobalCommands.cpp b/pcsx2/gui/GlobalCommands.cpp index 60e8f5ebbf..ed1b55f9c6 100644 --- a/pcsx2/gui/GlobalCommands.cpp +++ b/pcsx2/gui/GlobalCommands.cpp @@ -80,11 +80,8 @@ namespace Implementations g_LimiterMode = Limit_Turbo; g_Conf->EmuOptions.GS.LimitScalar = g_Conf->Framerate.TurboScalar; Console.WriteLn("(FrameLimiter) Turbo + FrameLimit ENABLED." ); - pauser.AllowResume(); - return; } - - if( g_LimiterMode == Limit_Turbo ) + else if( g_LimiterMode == Limit_Turbo ) { GSsetVsync( g_Conf->EmuOptions.GS.VsyncEnable ); g_LimiterMode = Limit_Nominal;