void AppCoreThread::GameStartingInThread() { // 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::GameStartingInThread() { // 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(); ClearMcdEjectTimeoutNow(); // probably safe to do this when a game boots, eliminates annoying prompts m_ExecMode = ExecMode_Opened; _parent::GameStartingInThread(); }
// Resumes the core execution state, or does nothing is the core is already running. If // settings were changed, resets will be performed as needed and emulation state resumed from // memory savestates. // // Note that this is considered a non-blocking action. Most times the state is safely resumed // on return, but in the case of re-entrant or nested message handling the function may return // before the thread has resumed. If you need explicit behavior tied to the completion of the // Resume, you'll need to bind callbacks to either OnResumeReady or OnResumeInThread. // // Exceptions: // PluginInitError - thrown if a plugin fails init (init is performed on the current thread // on the first time the thread is resumed from it's initial idle state) // ThreadCreationError - Insufficient system resources to create thread. // void SysThreadBase::Resume() { if( IsSelf() ) return; if( m_ExecMode == ExecMode_Opened ) return; ScopedLock locker( m_ExecModeMutex ); // Implementation Note: // The entire state coming out of a Wait is indeterminate because of user input // and pending messages being handled. So after each call we do some seemingly redundant // sanity checks against m_ExecMode/m_Running status, and if something doesn't feel // right, we should abort; the user may have canceled the action before it even finished. switch( m_ExecMode ) { case ExecMode_Opened: return; case ExecMode_NoThreadYet: { Start(); if( !m_running || (m_ExecMode == ExecMode_NoThreadYet) ) throw Exception::ThreadCreationError(this); if( m_ExecMode == ExecMode_Opened ) return; } // fall through... case ExecMode_Closing: case ExecMode_Pausing: // we need to make sure and wait for the emuThread to enter a fully suspended // state before continuing... m_RunningLock.Wait(); if( !m_running ) return; if( (m_ExecMode != ExecMode_Closed) && (m_ExecMode != ExecMode_Paused) ) return; if( !GetCorePlugins().AreLoaded() ) return; break; case ExecMode_Paused: case ExecMode_Closed: break; } pxAssertDev( (m_ExecMode == ExecMode_Closed) || (m_ExecMode == ExecMode_Paused), "SysThreadBase is not in a closed/paused state? wtf!" ); OnResumeReady(); m_ExecMode = ExecMode_Opened; m_sem_Resume.Post(); }
void AppCoreThread::GameStartingInThread() { // Make AppCoreThread::ApplySettings get verbose again even if we're booting // the same game, by making it think that the current CRC is a new one. curGameKey = L""; // 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(); ClearMcdEjectTimeoutNow(); // probably safe to do this when a game boots, eliminates annoying prompts m_ExecMode = ExecMode_Opened; _parent::GameStartingInThread(); }