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
|
GBA_RR_BLOCK_SIZE = 1018
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define FILE_INPUTS "input.log"
|
||||||
|
|
||||||
struct GBARRBlock {
|
struct GBARRBlock {
|
||||||
union GBARRInput {
|
union GBARRInput {
|
||||||
struct {
|
struct {
|
||||||
|
@ -42,6 +44,69 @@ void GBARRContextDestroy(struct GBA* gba) {
|
||||||
gba->rr->currentBlock = 0;
|
gba->rr->currentBlock = 0;
|
||||||
gba->rr->playbackBlock = 0;
|
gba->rr->playbackBlock = 0;
|
||||||
free(gba->rr);
|
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) {
|
bool GBARRStartPlaying(struct GBA* gba) {
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
struct GBA;
|
struct GBA;
|
||||||
|
struct VDir;
|
||||||
struct VFile;
|
struct VFile;
|
||||||
|
|
||||||
struct GBARRContext {
|
struct GBARRContext {
|
||||||
|
@ -24,6 +25,9 @@ struct GBARRContext {
|
||||||
void GBARRContextCreate(struct GBA*);
|
void GBARRContextCreate(struct GBA*);
|
||||||
void GBARRContextDestroy(struct GBA*);
|
void GBARRContextDestroy(struct GBA*);
|
||||||
|
|
||||||
|
bool GBARRSave(struct GBARRContext*, struct VDir*);
|
||||||
|
bool GBARRLoad(struct GBARRContext*, struct VDir*);
|
||||||
|
|
||||||
bool GBARRStartPlaying(struct GBA*);
|
bool GBARRStartPlaying(struct GBA*);
|
||||||
void GBARRStopPlaying(struct GBA*);
|
void GBARRStopPlaying(struct GBA*);
|
||||||
bool GBARRStartRecording(struct GBA*);
|
bool GBARRStartRecording(struct GBA*);
|
||||||
|
|
|
@ -128,20 +128,6 @@ static void _GBASDLHandleKeypress(struct GBAThread* context, struct GBASDLEvents
|
||||||
case SDLK_r:
|
case SDLK_r:
|
||||||
GBAThreadReset(context);
|
GBAThreadReset(context);
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -162,6 +148,27 @@ static void _GBASDLHandleKeypress(struct GBAThread* context, struct GBASDLEvents
|
||||||
GBASaveState(context->gba, event->keysym.sym - SDLK_F1);
|
GBASaveState(context->gba, event->keysym.sym - SDLK_F1);
|
||||||
GBAThreadContinue(context);
|
GBAThreadContinue(context);
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -181,6 +188,20 @@ static void _GBASDLHandleKeypress(struct GBAThread* context, struct GBASDLEvents
|
||||||
GBALoadState(context->gba, event->keysym.sym - SDLK_F1);
|
GBALoadState(context->gba, event->keysym.sym - SDLK_F1);
|
||||||
GBAThreadContinue(context);
|
GBAThreadContinue(context);
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue