RR starting from savegame (currently broken) and savestate

This commit is contained in:
Jeffrey Pfau 2014-08-04 23:37:37 -07:00
parent 86a2edbdf1
commit 82b31c46f1
5 changed files with 91 additions and 12 deletions

View File

@ -1,6 +1,7 @@
#include "gba-rr.h"
#include "gba.h"
#include "gba-serialize.h"
#include "util/vfs.h"
#define BINARY_EXT ".dat"
@ -14,6 +15,9 @@ static bool _seekTag(struct GBARRContext* rr, struct VFile* vf, enum GBARRTag ta
static bool _emitTag(struct GBARRContext* rr, struct VFile* vf, uint8_t tag);
static bool _parseMetadata(struct GBARRContext* rr, struct VFile* vf);
static struct VFile* _openSavedata(struct GBARRContext* rr, int flags);
static struct VFile* _openSavestate(struct GBARRContext* rr, int flags);
void GBARRContextCreate(struct GBA* gba) {
if (gba->rr) {
return;
@ -36,21 +40,63 @@ void GBARRContextDestroy(struct GBA* gba) {
if (gba->rr->metadataFile) {
gba->rr->metadataFile->close(gba->rr->metadataFile);
}
if (gba->rr->savedata) {
gba->rr->savedata->close(gba->rr->savedata);
}
free(gba->rr);
gba->rr = 0;
}
void GBARRAlterSavedata(struct GBA* gba) {
void GBARRSaveState(struct GBA* gba) {
if (!gba || !gba->rr) {
return;
}
if (gba->rr->initFrom & INIT_FROM_SAVEGAME) {
// TOOD
if (gba->rr->savedata) {
gba->rr->savedata->close(gba->rr->savedata);
}
gba->rr->savedata = _openSavedata(gba->rr, O_TRUNC | O_CREAT | O_WRONLY);
GBASavedataClone(&gba->memory.savedata, gba->rr->savedata);
gba->rr->savedata->close(gba->rr->savedata);
gba->rr->savedata = _openSavedata(gba->rr, O_RDONLY);
GBASavedataMask(&gba->memory.savedata, gba->rr->savedata);
} else {
GBASavedataMask(&gba->memory.savedata, 0);
}
if (gba->rr->initFrom & INIT_FROM_SAVESTATE) {
struct VFile* vf = _openSavestate(gba->rr, O_TRUNC | O_CREAT | O_RDWR);
GBASaveStateNamed(gba, vf, false);
vf->close(vf);
} else {
ARMReset(gba->cpu);
}
}
void GBARRLoadState(struct GBA* gba) {
if (!gba || !gba->rr) {
return;
}
if (gba->rr->initFrom & INIT_FROM_SAVEGAME) {
if (gba->rr->savedata) {
gba->rr->savedata->close(gba->rr->savedata);
}
gba->rr->savedata = _openSavedata(gba->rr, O_RDONLY);
GBASavedataMask(&gba->memory.savedata, gba->rr->savedata);
} else {
GBASavedataMask(&gba->memory.savedata, 0);
}
if (gba->rr->initFrom & INIT_FROM_SAVESTATE) {
struct VFile* vf = _openSavestate(gba->rr, O_RDONLY);
GBALoadStateNamed(gba, vf);
vf->close(vf);
} else {
ARMReset(gba->cpu);
}
}
bool GBARRInitStream(struct GBARRContext* rr, struct VDir* stream) {
@ -427,3 +473,11 @@ bool _parseMetadata(struct GBARRContext* rr, struct VFile* vf) {
rr->maxStreamIdOffset = vf->seek(vf, 0, SEEK_SET);
return true;
}
struct VFile* _openSavedata(struct GBARRContext* rr, int flags) {
return rr->streamDir->openFile(rr->streamDir, "movie.sav", flags);
}
struct VFile* _openSavestate(struct GBARRContext* rr, int flags) {
return rr->streamDir->openFile(rr->streamDir, "movie.ssm", flags);
}

View File

@ -65,6 +65,8 @@ struct GBARRContext {
enum GBARRInitFrom initFrom;
off_t initFromOffset;
struct VFile* savedata;
// Streaming state
struct VDir* streamDir;
struct VFile* metadataFile;
@ -77,7 +79,8 @@ struct GBARRContext {
void GBARRContextCreate(struct GBA*);
void GBARRContextDestroy(struct GBA*);
void GBARRAlterSavedata(struct GBA*);
void GBARRSaveState(struct GBA*);
void GBARRLoadState(struct GBA*);
bool GBARRInitStream(struct GBARRContext*, struct VDir*);
bool GBARRReinitStream(struct GBARRContext*, enum GBARRInitFrom);

View File

@ -72,6 +72,32 @@ void GBASavedataUnmask(struct GBASavedata* savedata) {
savedata->vf = savedata->realVf;
}
bool GBASavedataClone(struct GBASavedata* savedata, struct VFile* out) {
if (savedata->data) {
switch (savedata->type) {
case SAVEDATA_SRAM:
return out->write(out, savedata->data, SIZE_CART_SRAM) == SIZE_CART_SRAM;
case SAVEDATA_FLASH512:
return out->write(out, savedata->data, SIZE_CART_FLASH512) == SIZE_CART_FLASH512;
case SAVEDATA_FLASH1M:
return out->write(out, savedata->data, SIZE_CART_FLASH1M) == SIZE_CART_FLASH1M;
case SAVEDATA_EEPROM:
return out->write(out, savedata->data, SIZE_CART_EEPROM) == SIZE_CART_EEPROM;
case SAVEDATA_NONE:
return true;
}
} else if (savedata->vf) {
off_t read = 0;
uint8_t buffer[2048];
do {
read = savedata->vf->read(savedata->vf, buffer, sizeof(buffer));
out->write(out, buffer, read);
} while (read == sizeof(buffer));
return read >= 0;
}
return true;
}
void GBASavedataInitFlash(struct GBASavedata* savedata) {
if (savedata->type == SAVEDATA_NONE) {
savedata->type = SAVEDATA_FLASH512;

View File

@ -75,6 +75,7 @@ void GBASavedataDeinit(struct GBASavedata* savedata);
void GBASavedataMask(struct GBASavedata* savedata, struct VFile* vf);
void GBASavedataUnmask(struct GBASavedata* savedata);
bool GBASavedataClone(struct GBASavedata* savedata, struct VFile* out);
void GBASavedataInitFlash(struct GBASavedata* savedata);
void GBASavedataInitEEPROM(struct GBASavedata* savedata);

View File

@ -123,31 +123,26 @@ static void _GBASDLHandleKeypress(struct GBAThread* context, struct GBASDLEvents
break;
case SDLK_t:
if (context->stateDir) {
GBAThreadReset(context);
GBAThreadInterrupt(context);
GBARRContextCreate(context->gba);
if (!GBARRIsRecording(context->gba->rr)) {
GBARRStopPlaying(context->gba->rr);
GBARRInitStream(context->gba->rr, context->stateDir);
GBARRReinitStream(context->gba->rr, INIT_EX_NIHILO);
GBARRStopPlaying(context->gba->rr);
GBARRStartRecording(context->gba->rr);
GBARRAlterSavedata(context->gba);
GBARRSaveState(context->gba);
}
GBAThreadContinue(context);
}
break;
case SDLK_y:
if (context->stateDir) {
GBAThreadReset(context);
GBAThreadInterrupt(context);
GBARRContextCreate(context->gba);
GBARRInitStream(context->gba->rr, context->stateDir);
GBARRStopRecording(context->gba->rr);
GBARRInitStream(context->gba->rr, context->stateDir);
GBARRStartPlaying(context->gba->rr, false);
if (context->gba->rr->initFrom & INIT_FROM_SAVESTATE) {
// TODO
}
GBARRAlterSavedata(context->gba);
GBARRLoadState(context->gba);
GBAThreadContinue(context);
}
break;