mirror of https://github.com/mgba-emu/mgba.git
Core: Fix rewinding getting out of sync (fixes #791)
This commit is contained in:
parent
253719d7a1
commit
5167fce4c7
1
CHANGES
1
CHANGES
|
@ -178,6 +178,7 @@ Bugfixes:
|
||||||
- GB Audio: Fix incorrect channel 4 iteration
|
- GB Audio: Fix incorrect channel 4 iteration
|
||||||
- GB Audio: Fix zombie mode bit masking
|
- GB Audio: Fix zombie mode bit masking
|
||||||
- GBA Timer: Fix count-up timing overflowing timer 3
|
- GBA Timer: Fix count-up timing overflowing timer 3
|
||||||
|
- Core: Fix rewinding getting out of sync (fixes mgba.io/i/791)
|
||||||
Misc:
|
Misc:
|
||||||
- Qt: Add language selector
|
- Qt: Add language selector
|
||||||
- GBA Timer: Improve accuracy of timers
|
- GBA Timer: Improve accuracy of timers
|
||||||
|
|
|
@ -31,6 +31,7 @@ struct mCoreRewindContext {
|
||||||
Thread thread;
|
Thread thread;
|
||||||
Condition cond;
|
Condition cond;
|
||||||
Mutex mutex;
|
Mutex mutex;
|
||||||
|
bool ready;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ void mCoreRewindContextInit(struct mCoreRewindContext* context, size_t entries,
|
||||||
context->stateFlags = SAVESTATE_SAVEDATA;
|
context->stateFlags = SAVESTATE_SAVEDATA;
|
||||||
#ifndef DISABLE_THREADING
|
#ifndef DISABLE_THREADING
|
||||||
context->onThread = onThread;
|
context->onThread = onThread;
|
||||||
|
context->ready = false;
|
||||||
if (onThread) {
|
if (onThread) {
|
||||||
MutexInit(&context->mutex);
|
MutexInit(&context->mutex);
|
||||||
ConditionInit(&context->cond);
|
ConditionInit(&context->cond);
|
||||||
|
@ -73,6 +74,7 @@ void mCoreRewindAppend(struct mCoreRewindContext* context, struct mCore* core) {
|
||||||
context->currentState = nextState;
|
context->currentState = nextState;
|
||||||
#ifndef DISABLE_THREADING
|
#ifndef DISABLE_THREADING
|
||||||
if (context->onThread) {
|
if (context->onThread) {
|
||||||
|
context->ready = true;
|
||||||
ConditionWake(&context->cond);
|
ConditionWake(&context->cond);
|
||||||
MutexUnlock(&context->mutex);
|
MutexUnlock(&context->mutex);
|
||||||
return;
|
return;
|
||||||
|
@ -121,6 +123,12 @@ bool mCoreRewindRestore(struct mCoreRewindContext* context, struct mCore* core)
|
||||||
}
|
}
|
||||||
--context->size;
|
--context->size;
|
||||||
|
|
||||||
|
mCoreLoadStateNamed(core, context->previousState, context->stateFlags);
|
||||||
|
if (context->current == 0) {
|
||||||
|
context->current = mCoreRewindPatchesSize(&context->patchMemory);
|
||||||
|
}
|
||||||
|
--context->current;
|
||||||
|
|
||||||
struct PatchFast* patch = mCoreRewindPatchesGetPointer(&context->patchMemory, context->current);
|
struct PatchFast* patch = mCoreRewindPatchesGetPointer(&context->patchMemory, context->current);
|
||||||
size_t size2 = context->previousState->size(context->previousState);
|
size_t size2 = context->previousState->size(context->previousState);
|
||||||
size_t size = context->currentState->size(context->currentState);
|
size_t size = context->currentState->size(context->currentState);
|
||||||
|
@ -129,18 +137,12 @@ bool mCoreRewindRestore(struct mCoreRewindContext* context, struct mCore* core)
|
||||||
}
|
}
|
||||||
void* current = context->currentState->map(context->currentState, size, MAP_READ);
|
void* current = context->currentState->map(context->currentState, size, MAP_READ);
|
||||||
void* previous = context->previousState->map(context->previousState, size, MAP_WRITE);
|
void* previous = context->previousState->map(context->previousState, size, MAP_WRITE);
|
||||||
patch->d.applyPatch(&patch->d, current, size, previous, size);
|
patch->d.applyPatch(&patch->d, previous, size, current, size);
|
||||||
context->currentState->unmap(context->currentState, current, size);
|
context->currentState->unmap(context->currentState, current, size);
|
||||||
context->previousState->unmap(context->previousState, previous, size);
|
context->previousState->unmap(context->previousState, previous, size);
|
||||||
mCoreLoadStateNamed(core, context->previousState, context->stateFlags);
|
|
||||||
struct VFile* nextState = context->previousState;
|
struct VFile* nextState = context->previousState;
|
||||||
context->previousState = context->currentState;
|
context->previousState = context->currentState;
|
||||||
context->currentState = nextState;
|
context->currentState = nextState;
|
||||||
|
|
||||||
if (context->current == 0) {
|
|
||||||
context->current = mCoreRewindPatchesSize(&context->patchMemory);
|
|
||||||
}
|
|
||||||
--context->current;
|
|
||||||
#ifndef DISABLE_THREADING
|
#ifndef DISABLE_THREADING
|
||||||
if (context->onThread) {
|
if (context->onThread) {
|
||||||
MutexUnlock(&context->mutex);
|
MutexUnlock(&context->mutex);
|
||||||
|
@ -154,13 +156,12 @@ THREAD_ENTRY _rewindThread(void* context) {
|
||||||
struct mCoreRewindContext* rewindContext = context;
|
struct mCoreRewindContext* rewindContext = context;
|
||||||
ThreadSetName("Rewind Diff Thread");
|
ThreadSetName("Rewind Diff Thread");
|
||||||
MutexLock(&rewindContext->mutex);
|
MutexLock(&rewindContext->mutex);
|
||||||
struct VFile* state = rewindContext->currentState;
|
|
||||||
while (rewindContext->onThread) {
|
while (rewindContext->onThread) {
|
||||||
if (rewindContext->currentState != state) {
|
while (!rewindContext->ready) {
|
||||||
_rewindDiff(rewindContext);
|
ConditionWait(&rewindContext->cond, &rewindContext->mutex);
|
||||||
state = rewindContext->currentState;
|
|
||||||
}
|
}
|
||||||
ConditionWait(&rewindContext->cond, &rewindContext->mutex);
|
_rewindDiff(rewindContext);
|
||||||
|
rewindContext->ready = false;
|
||||||
}
|
}
|
||||||
MutexUnlock(&rewindContext->mutex);
|
MutexUnlock(&rewindContext->mutex);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue