GBA RR: Add support for resets in movies
Jeffrey Pfau jeffrey@endrift.com
Tue, 05 Jan 2016 02:33:25 -0800
6 files changed,
36 insertions(+),
0 deletions(-)
M
CHANGES
→
CHANGES
@@ -52,6 +52,7 @@ - GBA RR: Starting from savestate now embeds the savegame
- Libretro: Add install target for libretro core - 3DS: Update to new ctrulib API - GBA RR: Add preliminary SRAM support for VBM loading + - GBA RR: Add support for resets in movies 0.3.2: (2015-12-16) Bugfixes:
M
src/gba/gba.c
→
src/gba/gba.c
@@ -912,6 +912,13 @@
if (thread->frameCallback) { thread->frameCallback(thread); } + + if (gba->rr && gba->rr->queryReset(gba->rr)) { + // TODO: Clean up reset scheduling + MutexLock(&thread->stateMutex); + thread->state = THREAD_RESETING; + MutexUnlock(&thread->stateMutex); + } } void GBASetBreakpoint(struct GBA* gba, struct ARMComponent* component, uint32_t address, enum ExecutionMode mode, uint32_t* opcode) {
M
src/gba/rr/mgm.c
→
src/gba/rr/mgm.c
@@ -30,6 +30,7 @@
static void GBAMGMNextFrame(struct GBARRContext*); static void GBAMGMLogInput(struct GBARRContext*, uint16_t input); static uint16_t GBAMGMQueryInput(struct GBARRContext*); +static bool GBAMGMQueryReset(struct GBARRContext*); static void GBAMGMStateSaved(struct GBARRContext* rr, struct GBASerializedState* state); static void GBAMGMStateLoaded(struct GBARRContext* rr, const struct GBASerializedState* state);@@ -71,6 +72,7 @@
mgm->d.nextFrame = GBAMGMNextFrame; mgm->d.logInput = GBAMGMLogInput; mgm->d.queryInput = GBAMGMQueryInput; + mgm->d.queryReset = GBAMGMQueryReset; mgm->d.stateSaved = GBAMGMStateSaved; mgm->d.stateLoaded = GBAMGMStateLoaded;@@ -324,6 +326,15 @@ GBALog(0, GBA_LOG_DEBUG, "[RR] Input replay: %03X", mgm->currentInput);
return mgm->currentInput; } +bool GBAMGMQueryReset(struct GBARRContext* rr) { + if (!rr->isPlaying(rr)) { + return 0; + } + + struct GBAMGMContext* mgm = (struct GBAMGMContext*) rr; + return mgm->peekedTag == TAG_RESET; +} + void GBAMGMStateSaved(struct GBARRContext* rr, struct GBASerializedState* state) { struct GBAMGMContext* mgm = (struct GBAMGMContext*) rr; if (rr->isRecording(rr)) {@@ -441,6 +452,7 @@
// Empty markers case TAG_FRAME: case TAG_LAG: + case TAG_RESET: case TAG_BEGIN: case TAG_END: case TAG_INVALID:
M
src/gba/rr/mgm.h
→
src/gba/rr/mgm.h
@@ -20,6 +20,7 @@ TAG_INVALID = 0x00,
TAG_INPUT = 0x01, TAG_FRAME = 0x02, TAG_LAG = 0x03, + TAG_RESET = 0x04, // Stream chunking tags TAG_BEGIN = 0x10,
M
src/gba/rr/rr.h
→
src/gba/rr/rr.h
@@ -33,6 +33,7 @@
void (*nextFrame)(struct GBARRContext*); void (*logInput)(struct GBARRContext*, uint16_t input); uint16_t (*queryInput)(struct GBARRContext*); + bool (*queryReset)(struct GBARRContext*); void (*stateSaved)(struct GBARRContext*, struct GBASerializedState*); void (*stateLoaded)(struct GBARRContext*, const struct GBASerializedState*);
M
src/gba/rr/vbm.c
→
src/gba/rr/vbm.c
@@ -27,6 +27,7 @@ static bool GBAVBMIsRecording(const struct GBARRContext*);
static void GBAVBMNextFrame(struct GBARRContext*); static uint16_t GBAVBMQueryInput(struct GBARRContext*); +static bool GBAVBMQueryReset(struct GBARRContext*); static void GBAVBMStateSaved(struct GBARRContext* rr, struct GBASerializedState* state); static void GBAVBMStateLoaded(struct GBARRContext* rr, const struct GBASerializedState* state);@@ -50,6 +51,7 @@
vbm->d.nextFrame = GBAVBMNextFrame; vbm->d.logInput = 0; vbm->d.queryInput = GBAVBMQueryInput; + vbm->d.queryReset = GBAVBMQueryReset; vbm->d.stateSaved = GBAVBMStateSaved; vbm->d.stateLoaded = GBAVBMStateLoaded;@@ -116,6 +118,18 @@ uint16_t input;
vbm->vbmFile->read(vbm->vbmFile, &input, sizeof(input)); vbm->vbmFile->seek(vbm->vbmFile, -sizeof(input), SEEK_CUR); return input & 0x3FF; +} + +bool GBAVBMQueryReset(struct GBARRContext* rr) { + if (!rr->isPlaying(rr)) { + return false; + } + + struct GBAVBMContext* vbm = (struct GBAVBMContext*) rr; + uint16_t input; + vbm->vbmFile->read(vbm->vbmFile, &input, sizeof(input)); + vbm->vbmFile->seek(vbm->vbmFile, -sizeof(input), SEEK_CUR); + return input & 0x800; } void GBAVBMStateSaved(struct GBARRContext* rr, struct GBASerializedState* state) {