all repos — mgba @ 293e0a9c9bcfcea38f91c8668a8e469b99d13828

mGBA Game Boy Advance Emulator

GBA: Rewind now shows the frame after rewinding
Jeffrey Pfau jeffrey@endrift.com
Sun, 12 Apr 2015 20:22:04 -0700
commit

293e0a9c9bcfcea38f91c8668a8e469b99d13828

parent

2a9a738bfb76d540f39d8145d014170d8b095f52

4 files changed, 22 insertions(+), 0 deletions(-)

jump to
M CHANGESCHANGES

@@ -5,6 +5,7 @@ - Ability to mute individual audio channels

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

@@ -256,6 +256,18 @@ state = GBAAllocateState();

thread->rewindBuffer[offset] = 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->rewindBufferWriteOffset = (offset + 1) % thread->rewindBufferCapacity; }

@@ -273,12 +285,15 @@ for (i = 0; i < threadContext->rewindBufferCapacity; ++i) {

GBADeallocateState(threadContext->rewindBuffer[i]); } free(threadContext->rewindBuffer); + free(threadContext->rewindScreenBuffer); } threadContext->rewindBufferCapacity = newCapacity; if (threadContext->rewindBufferCapacity > 0) { threadContext->rewindBuffer = calloc(threadContext->rewindBufferCapacity, sizeof(struct GBASerializedState*)); + threadContext->rewindScreenBuffer = calloc(threadContext->rewindBufferCapacity, VIDEO_VERTICAL_PIXELS * VIDEO_HORIZONTAL_PIXELS * BYTES_PER_PIXEL); } else { threadContext->rewindBuffer = 0; + threadContext->rewindScreenBuffer = 0; } }

@@ -300,6 +315,9 @@ }

thread->rewindBufferSize -= nStates; thread->rewindBufferWriteOffset = offset; 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) {
M src/gba/supervisor/thread.csrc/gba/supervisor/thread.c

@@ -381,6 +381,7 @@ threadContext->sync.videoFrameOn = true;

threadContext->sync.videoFrameSkip = 0; threadContext->rewindBuffer = 0; + threadContext->rewindScreenBuffer = 0; int newCapacity = threadContext->rewindBufferCapacity; int newInterval = threadContext->rewindBufferInterval; threadContext->rewindBufferCapacity = 0;

@@ -531,6 +532,7 @@ GBADeallocateState(threadContext->rewindBuffer[i]);

} } free(threadContext->rewindBuffer); + free(threadContext->rewindScreenBuffer); if (threadContext->rom) { threadContext->rom->close(threadContext->rom);
M src/gba/supervisor/thread.hsrc/gba/supervisor/thread.h

@@ -106,6 +106,7 @@ int rewindBufferInterval;

int rewindBufferNext; struct GBASerializedState** rewindBuffer; int rewindBufferWriteOffset; + uint8_t* rewindScreenBuffer; struct GBACheatDevice* cheats; };