UI: TAB should be remembered now on games that use patches. Improved and simplified some threading logic, and streamlined the vsync handlers a wee bit (they don't really matter for performance, but no point in being sloppy about them either).

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3226 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2010-06-19 02:38:15 +00:00
parent 38139dee34
commit aaedf7ac6e
8 changed files with 176 additions and 157 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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; id<pxEnumEnd; ++id )
{
wxString key( EnumToString(id) );
key += L"Hack";
if (gameDB->keyExists(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 )

View File

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

View File

@ -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; id<pxEnumEnd; ++id )
{
wxString key( EnumToString(id) );
key += L"Hack";
if (gameDB->keyExists(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();
}
}

View File

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