Permalink
Browse files

Core: Fix rewinding getting out of sync (fixes #791)

  • Loading branch information...
endrift committed Jul 11, 2017
1 parent 253719d commit 5167fce4c70711a221c4179ae245aca19b6f394a
Showing with 15 additions and 12 deletions.
  1. +1 −0 CHANGES
  2. +1 −0 include/mgba/core/rewind.h
  3. +13 −12 src/core/rewind.c
View
@@ -178,6 +178,7 @@ Bugfixes:
- GB Audio: Fix incorrect channel 4 iteration
- GB Audio: Fix zombie mode bit masking
- GBA Timer: Fix count-up timing overflowing timer 3
+ - Core: Fix rewinding getting out of sync (fixes mgba.io/i/791)
Misc:
- Qt: Add language selector
- GBA Timer: Improve accuracy of timers
@@ -31,6 +31,7 @@ struct mCoreRewindContext {
Thread thread;
Condition cond;
Mutex mutex;
+ bool ready;
#endif
};
View
@@ -30,6 +30,7 @@ void mCoreRewindContextInit(struct mCoreRewindContext* context, size_t entries,
context->stateFlags = SAVESTATE_SAVEDATA;
#ifndef DISABLE_THREADING
context->onThread = onThread;
+ context->ready = false;
if (onThread) {
MutexInit(&context->mutex);
ConditionInit(&context->cond);
@@ -73,6 +74,7 @@ void mCoreRewindAppend(struct mCoreRewindContext* context, struct mCore* core) {
context->currentState = nextState;
#ifndef DISABLE_THREADING
if (context->onThread) {
+ context->ready = true;
ConditionWake(&context->cond);
MutexUnlock(&context->mutex);
return;
@@ -121,6 +123,12 @@ bool mCoreRewindRestore(struct mCoreRewindContext* context, struct mCore* core)
}
--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);
size_t size2 = context->previousState->size(context->previousState);
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* 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->previousState->unmap(context->previousState, previous, size);
- mCoreLoadStateNamed(core, context->previousState, context->stateFlags);
struct VFile* nextState = context->previousState;
context->previousState = context->currentState;
context->currentState = nextState;
-
- if (context->current == 0) {
- context->current = mCoreRewindPatchesSize(&context->patchMemory);
- }
- --context->current;
#ifndef DISABLE_THREADING
if (context->onThread) {
MutexUnlock(&context->mutex);
@@ -154,13 +156,12 @@ THREAD_ENTRY _rewindThread(void* context) {
struct mCoreRewindContext* rewindContext = context;
ThreadSetName("Rewind Diff Thread");
MutexLock(&rewindContext->mutex);
- struct VFile* state = rewindContext->currentState;
while (rewindContext->onThread) {
- if (rewindContext->currentState != state) {
- _rewindDiff(rewindContext);
- state = rewindContext->currentState;
+ while (!rewindContext->ready) {
+ ConditionWait(&rewindContext->cond, &rewindContext->mutex);
}
- ConditionWait(&rewindContext->cond, &rewindContext->mutex);
+ _rewindDiff(rewindContext);
+ rewindContext->ready = false;
}
MutexUnlock(&rewindContext->mutex);
return 0;

0 comments on commit 5167fce

Please sign in to comment.