Very basic movie saving/loading
Jeffrey Pfau jeffrey@endrift.com
Sat, 19 Jul 2014 17:38:25 -0700
3 files changed,
104 insertions(+),
14 deletions(-)
M
src/gba/gba-rr.c
→
src/gba/gba-rr.c
@@ -7,6 +7,8 @@ enum {
GBA_RR_BLOCK_SIZE = 1018 }; +#define FILE_INPUTS "input.log" + struct GBARRBlock { union GBARRInput { struct {@@ -42,6 +44,69 @@ gba->rr->rootBlock = 0;
gba->rr->currentBlock = 0; gba->rr->playbackBlock = 0; free(gba->rr); + gba->rr = 0; +} + +bool GBARRSave(struct GBARRContext* rr, struct VDir* vdir) { + if (!rr) { + return false; + } + + struct VFile* inputs = vdir->openFile(vdir, FILE_INPUTS, O_WRONLY | O_CREAT | O_TRUNC); + if (!inputs) { + return false; + } + + ssize_t written = 0; + struct GBARRBlock* inputBlock; + for (inputBlock = rr->rootBlock; inputBlock; inputBlock = inputBlock->next) { + ssize_t thisWrite = inputs->write(inputs, inputBlock->inputs, sizeof(*inputBlock->inputs) * inputBlock->numInputs); + if (!thisWrite) { + written = -1; + break; + } + written += thisWrite; + } + + if (!inputs->close(inputs)) { + return false; + } + + return written >= 0; +} + +bool GBARRLoad(struct GBARRContext* rr, struct VDir* vdir) { + if (!rr) { + return false; + } + + struct VFile* inputs = vdir->openFile(vdir, FILE_INPUTS, O_RDONLY); + if (!inputs) { + return false; + } + + struct GBARRBlock block; + ssize_t read; + do { + read = inputs->read(inputs, block.inputs, sizeof(block.inputs)); + if (read) { + struct GBARRBlock* newBlock = calloc(1, sizeof(*rr->currentBlock)); + memcpy(newBlock, &block, sizeof(*newBlock)); + if (!rr->rootBlock) { + rr->rootBlock = newBlock; + } + if (rr->currentBlock) { + rr->currentBlock->next = newBlock; + } + rr->currentBlock = newBlock; + } + } while (read > 0); + + if (!inputs->close(inputs)) { + return false; + } + + return read >= 0; } bool GBARRStartPlaying(struct GBA* gba) {
M
src/gba/gba-rr.h
→
src/gba/gba-rr.h
@@ -4,6 +4,7 @@
#include "common.h" struct GBA; +struct VDir; struct VFile; struct GBARRContext {@@ -23,6 +24,9 @@ };
void GBARRContextCreate(struct GBA*); void GBARRContextDestroy(struct GBA*); + +bool GBARRSave(struct GBARRContext*, struct VDir*); +bool GBARRLoad(struct GBARRContext*, struct VDir*); bool GBARRStartPlaying(struct GBA*); void GBARRStopPlaying(struct GBA*);
M
src/platform/sdl/sdl-events.c
→
src/platform/sdl/sdl-events.c
@@ -128,20 +128,6 @@ break;
case SDLK_r: GBAThreadReset(context); break; - case SDLK_t: - GBAThreadReset(context); - GBAThreadInterrupt(context); - GBARRStopPlaying(context->gba); - GBARRStartRecording(context->gba); - GBAThreadContinue(context); - break; - case SDLK_y: - GBAThreadReset(context); - GBAThreadInterrupt(context); - GBARRStopRecording(context->gba); - GBARRStartPlaying(context->gba); - GBAThreadContinue(context); - break; default: break; }@@ -162,6 +148,27 @@ GBAThreadInterrupt(context);
GBASaveState(context->gba, event->keysym.sym - SDLK_F1); GBAThreadContinue(context); break; + case SDLK_t: + if (context->gamedir) { + GBAThreadInterrupt(context); + GBARRStopPlaying(context->gba); + GBARRSave(context->gba->rr, context->gamedir); + GBAThreadContinue(context); + } + break; + case SDLK_y: + if (context->gamedir) { + GBAThreadReset(context); + GBAThreadInterrupt(context); + GBARRStopRecording(context->gba); + GBARRContextDestroy(context->gba); + GBARRContextCreate(context->gba); + if (GBARRLoad(context->gba->rr, context->gamedir)) { + GBARRStartPlaying(context->gba); + } + GBAThreadContinue(context); + } + break; default: break; }@@ -179,6 +186,20 @@ case SDLK_F9:
case SDLK_F10: GBAThreadInterrupt(context); GBALoadState(context->gba, event->keysym.sym - SDLK_F1); + GBAThreadContinue(context); + break; + case SDLK_t: + GBAThreadReset(context); + GBAThreadInterrupt(context); + GBARRStopPlaying(context->gba); + GBARRStartRecording(context->gba); + GBAThreadContinue(context); + break; + case SDLK_y: + GBAThreadReset(context); + GBAThreadInterrupt(context); + GBARRStopRecording(context->gba); + GBARRStartPlaying(context->gba); GBAThreadContinue(context); break; default: