Qt: Resume crashed game when loading a save state

This commit is contained in:
Vicki Pfau 2022-09-11 02:49:04 -07:00
parent 83f0deab1b
commit 5dbe240442
4 changed files with 21 additions and 2 deletions

View File

@ -107,6 +107,7 @@ Misc:
- Qt: Improve cheat parsing (fixes mgba.io/i/2297) - Qt: Improve cheat parsing (fixes mgba.io/i/2297)
- Qt: Change lossless setting to use WavPack audio - Qt: Change lossless setting to use WavPack audio
- Qt: Use FFmpeg to convert additional camera formats, if available - Qt: Use FFmpeg to convert additional camera formats, if available
- Qt: Resume crashed game when loading a save state
- SDL: Support exposing an axis directly as the gyro value (closes mgba.io/i/2531) - SDL: Support exposing an axis directly as the gyro value (closes mgba.io/i/2531)
- Windows: Attach to console if present - Windows: Attach to console if present
- Vita: Add bilinear filtering option (closes mgba.io/i/344) - Vita: Add bilinear filtering option (closes mgba.io/i/344)

View File

@ -101,8 +101,6 @@ struct mCoreThreadInternal {
bool mCoreThreadStart(struct mCoreThread* threadContext); bool mCoreThreadStart(struct mCoreThread* threadContext);
bool mCoreThreadHasStarted(struct mCoreThread* threadContext); bool mCoreThreadHasStarted(struct mCoreThread* threadContext);
bool mCoreThreadHasExited(struct mCoreThread* threadContext); bool mCoreThreadHasExited(struct mCoreThread* threadContext);
bool mCoreThreadHasCrashed(struct mCoreThread* threadContext);
void mCoreThreadMarkCrashed(struct mCoreThread* threadContext);
void mCoreThreadEnd(struct mCoreThread* threadContext); void mCoreThreadEnd(struct mCoreThread* threadContext);
void mCoreThreadReset(struct mCoreThread* threadContext); void mCoreThreadReset(struct mCoreThread* threadContext);
void mCoreThreadJoin(struct mCoreThread* threadContext); void mCoreThreadJoin(struct mCoreThread* threadContext);
@ -122,6 +120,10 @@ void mCoreThreadPauseFromThread(struct mCoreThread* threadContext);
void mCoreThreadWaitFromThread(struct mCoreThread* threadContext); void mCoreThreadWaitFromThread(struct mCoreThread* threadContext);
void mCoreThreadStopWaiting(struct mCoreThread* threadContext); void mCoreThreadStopWaiting(struct mCoreThread* threadContext);
bool mCoreThreadHasCrashed(struct mCoreThread* threadContext);
void mCoreThreadMarkCrashed(struct mCoreThread* threadContext);
void mCoreThreadClearCrashed(struct mCoreThread* threadContext);
void mCoreThreadSetRewinding(struct mCoreThread* threadContext, bool); void mCoreThreadSetRewinding(struct mCoreThread* threadContext, bool);
void mCoreThreadRewindParamsChanged(struct mCoreThread* threadContext); void mCoreThreadRewindParamsChanged(struct mCoreThread* threadContext);

View File

@ -526,6 +526,15 @@ void mCoreThreadMarkCrashed(struct mCoreThread* threadContext) {
MutexUnlock(&threadContext->impl->stateMutex); MutexUnlock(&threadContext->impl->stateMutex);
} }
void mCoreThreadClearCrashed(struct mCoreThread* threadContext) {
MutexLock(&threadContext->impl->stateMutex);
if (threadContext->impl->state == mTHREAD_CRASHED) {
threadContext->impl->state = mTHREAD_REQUEST;
ConditionWake(&threadContext->impl->stateCond);
}
MutexUnlock(&threadContext->impl->stateMutex);
}
void mCoreThreadEnd(struct mCoreThread* threadContext) { void mCoreThreadEnd(struct mCoreThread* threadContext) {
MutexLock(&threadContext->impl->stateMutex); MutexLock(&threadContext->impl->stateMutex);
_waitOnInterrupt(threadContext->impl); _waitOnInterrupt(threadContext->impl);
@ -685,6 +694,10 @@ void mCoreThreadPauseFromThread(struct mCoreThread* threadContext) {
void mCoreThreadSetRewinding(struct mCoreThread* threadContext, bool rewinding) { void mCoreThreadSetRewinding(struct mCoreThread* threadContext, bool rewinding) {
MutexLock(&threadContext->impl->stateMutex); MutexLock(&threadContext->impl->stateMutex);
threadContext->impl->rewinding = rewinding; threadContext->impl->rewinding = rewinding;
if (rewinding && threadContext->impl->state == mTHREAD_CRASHED) {
threadContext->impl->state = mTHREAD_REQUEST;
ConditionWake(&threadContext->impl->stateCond);
}
MutexUnlock(&threadContext->impl->stateMutex); MutexUnlock(&threadContext->impl->stateMutex);
} }

View File

@ -613,6 +613,7 @@ void CoreController::loadState(int slot) {
m_stateSlot = slot; m_stateSlot = slot;
m_backupSaveState.clear(); m_backupSaveState.clear();
} }
mCoreThreadClearCrashed(&m_threadContext);
mCoreThreadRunFunction(&m_threadContext, [](mCoreThread* context) { mCoreThreadRunFunction(&m_threadContext, [](mCoreThread* context) {
CoreController* controller = static_cast<CoreController*>(context->userData); CoreController* controller = static_cast<CoreController*>(context->userData);
if (!controller->m_backupLoadState.isOpen()) { if (!controller->m_backupLoadState.isOpen()) {
@ -632,6 +633,7 @@ void CoreController::loadState(const QString& path, int flags) {
if (flags != -1) { if (flags != -1) {
m_loadStateFlags = flags; m_loadStateFlags = flags;
} }
mCoreThreadClearCrashed(&m_threadContext);
mCoreThreadRunFunction(&m_threadContext, [](mCoreThread* context) { mCoreThreadRunFunction(&m_threadContext, [](mCoreThread* context) {
CoreController* controller = static_cast<CoreController*>(context->userData); CoreController* controller = static_cast<CoreController*>(context->userData);
VFile* vf = VFileDevice::open(controller->m_statePath, O_RDONLY); VFile* vf = VFileDevice::open(controller->m_statePath, O_RDONLY);
@ -660,6 +662,7 @@ void CoreController::loadState(QIODevice* iodev, int flags) {
if (flags != -1) { if (flags != -1) {
m_loadStateFlags = flags; m_loadStateFlags = flags;
} }
mCoreThreadClearCrashed(&m_threadContext);
mCoreThreadRunFunction(&m_threadContext, [](mCoreThread* context) { mCoreThreadRunFunction(&m_threadContext, [](mCoreThread* context) {
CoreController* controller = static_cast<CoreController*>(context->userData); CoreController* controller = static_cast<CoreController*>(context->userData);
VFile* vf = controller->m_stateVf; VFile* vf = controller->m_stateVf;