GBA: Rewind now shows the frame after rewinding

This commit is contained in:
Jeffrey Pfau 2015-04-12 20:22:04 -07:00
parent 2a9a738bfb
commit 293e0a9c9b
4 changed files with 22 additions and 0 deletions

View File

@ -5,6 +5,7 @@ Features:
- Palette viewer - Palette viewer
- Volume control - Volume control
- More shortcuts are editable (e.g. quick save/load, solar sensor) - More shortcuts are editable (e.g. quick save/load, solar sensor)
- Rewind now shows the frame after rewinding
Bugfixes: Bugfixes:
- GBA: Fix timers not updating timing when writing to only the reload register - GBA: Fix timers not updating timing when writing to only the reload register
- All: Fix sanitize-deb script not cleaning up after itself - All: Fix sanitize-deb script not cleaning up after itself

View File

@ -256,6 +256,18 @@ void GBARecordFrame(struct GBAThread* thread) {
thread->rewindBuffer[offset] = state; thread->rewindBuffer[offset] = state;
} }
GBASerialize(thread->gba, state); GBASerialize(thread->gba, state);
if (thread->rewindScreenBuffer) {
unsigned stride;
uint8_t* pixels = 0;
thread->gba->video.renderer->getPixels(thread->gba->video.renderer, &stride, (void*) &pixels);
if (pixels) {
size_t y;
for (y = 0; y < VIDEO_VERTICAL_PIXELS; ++y) {
memcpy(&thread->rewindScreenBuffer[(offset * VIDEO_VERTICAL_PIXELS + y) * VIDEO_HORIZONTAL_PIXELS * BYTES_PER_PIXEL], &pixels[y * stride * BYTES_PER_PIXEL], VIDEO_HORIZONTAL_PIXELS * BYTES_PER_PIXEL);
}
}
}
thread->rewindBufferSize = thread->rewindBufferSize == thread->rewindBufferCapacity ? thread->rewindBufferCapacity : thread->rewindBufferSize + 1; thread->rewindBufferSize = thread->rewindBufferSize == thread->rewindBufferCapacity ? thread->rewindBufferCapacity : thread->rewindBufferSize + 1;
thread->rewindBufferWriteOffset = (offset + 1) % thread->rewindBufferCapacity; thread->rewindBufferWriteOffset = (offset + 1) % thread->rewindBufferCapacity;
} }
@ -273,12 +285,15 @@ void GBARewindSettingsChanged(struct GBAThread* threadContext, int newCapacity,
GBADeallocateState(threadContext->rewindBuffer[i]); GBADeallocateState(threadContext->rewindBuffer[i]);
} }
free(threadContext->rewindBuffer); free(threadContext->rewindBuffer);
free(threadContext->rewindScreenBuffer);
} }
threadContext->rewindBufferCapacity = newCapacity; threadContext->rewindBufferCapacity = newCapacity;
if (threadContext->rewindBufferCapacity > 0) { if (threadContext->rewindBufferCapacity > 0) {
threadContext->rewindBuffer = calloc(threadContext->rewindBufferCapacity, sizeof(struct GBASerializedState*)); threadContext->rewindBuffer = calloc(threadContext->rewindBufferCapacity, sizeof(struct GBASerializedState*));
threadContext->rewindScreenBuffer = calloc(threadContext->rewindBufferCapacity, VIDEO_VERTICAL_PIXELS * VIDEO_HORIZONTAL_PIXELS * BYTES_PER_PIXEL);
} else { } else {
threadContext->rewindBuffer = 0; threadContext->rewindBuffer = 0;
threadContext->rewindScreenBuffer = 0;
} }
} }
@ -300,6 +315,9 @@ void GBARewind(struct GBAThread* thread, int nStates) {
thread->rewindBufferSize -= nStates; thread->rewindBufferSize -= nStates;
thread->rewindBufferWriteOffset = offset; thread->rewindBufferWriteOffset = offset;
GBADeserialize(thread->gba, state); GBADeserialize(thread->gba, state);
if (thread->rewindScreenBuffer) {
thread->gba->video.renderer->putPixels(thread->gba->video.renderer, VIDEO_HORIZONTAL_PIXELS, &thread->rewindScreenBuffer[offset * VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL]);
}
} }
void GBARewindAll(struct GBAThread* thread) { void GBARewindAll(struct GBAThread* thread) {

View File

@ -381,6 +381,7 @@ bool GBAThreadStart(struct GBAThread* threadContext) {
threadContext->sync.videoFrameSkip = 0; threadContext->sync.videoFrameSkip = 0;
threadContext->rewindBuffer = 0; threadContext->rewindBuffer = 0;
threadContext->rewindScreenBuffer = 0;
int newCapacity = threadContext->rewindBufferCapacity; int newCapacity = threadContext->rewindBufferCapacity;
int newInterval = threadContext->rewindBufferInterval; int newInterval = threadContext->rewindBufferInterval;
threadContext->rewindBufferCapacity = 0; threadContext->rewindBufferCapacity = 0;
@ -531,6 +532,7 @@ void GBAThreadJoin(struct GBAThread* threadContext) {
} }
} }
free(threadContext->rewindBuffer); free(threadContext->rewindBuffer);
free(threadContext->rewindScreenBuffer);
if (threadContext->rom) { if (threadContext->rom) {
threadContext->rom->close(threadContext->rom); threadContext->rom->close(threadContext->rom);

View File

@ -106,6 +106,7 @@ struct GBAThread {
int rewindBufferNext; int rewindBufferNext;
struct GBASerializedState** rewindBuffer; struct GBASerializedState** rewindBuffer;
int rewindBufferWriteOffset; int rewindBufferWriteOffset;
uint8_t* rewindScreenBuffer;
struct GBACheatDevice* cheats; struct GBACheatDevice* cheats;
}; };