mirror of https://github.com/mgba-emu/mgba.git
Very basic movie saving/loading
This commit is contained in:
parent
c6cd179101
commit
e8a78c9547
|
@ -7,6 +7,8 @@ enum {
|
|||
GBA_RR_BLOCK_SIZE = 1018
|
||||
};
|
||||
|
||||
#define FILE_INPUTS "input.log"
|
||||
|
||||
struct GBARRBlock {
|
||||
union GBARRInput {
|
||||
struct {
|
||||
|
@ -42,6 +44,69 @@ void GBARRContextDestroy(struct GBA* gba) {
|
|||
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) {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "common.h"
|
||||
|
||||
struct GBA;
|
||||
struct VDir;
|
||||
struct VFile;
|
||||
|
||||
struct GBARRContext {
|
||||
|
@ -24,6 +25,9 @@ struct GBARRContext {
|
|||
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*);
|
||||
bool GBARRStartRecording(struct GBA*);
|
||||
|
|
|
@ -128,20 +128,6 @@ static void _GBASDLHandleKeypress(struct GBAThread* context, struct GBASDLEvents
|
|||
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 @@ static void _GBASDLHandleKeypress(struct GBAThread* context, struct GBASDLEvents
|
|||
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;
|
||||
}
|
||||
|
@ -181,6 +188,20 @@ static void _GBASDLHandleKeypress(struct GBAThread* context, struct GBASDLEvents
|
|||
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:
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue