diff --git a/src/gba/gba-rr.c b/src/gba/gba-rr.c index 79fcee9d2..c47fc8684 100644 --- a/src/gba/gba-rr.c +++ b/src/gba/gba-rr.c @@ -150,6 +150,11 @@ bool GBARRReinitStream(struct GBARRContext* rr, enum GBARRInitFrom initFrom) { _emitTag(rr, rr->metadataFile, TAG_MAX_STREAM); rr->maxStreamIdOffset = rr->metadataFile->seek(rr->metadataFile, 0, SEEK_CUR); rr->metadataFile->write(rr->metadataFile, &rr->maxStreamId, sizeof(rr->maxStreamId)); + + rr->rrCount = 0; + _emitTag(rr, rr->metadataFile, TAG_RR_COUNT); + rr->rrCountOffset = rr->metadataFile->seek(rr->metadataFile, 0, SEEK_CUR); + rr->metadataFile->write(rr->metadataFile, &rr->rrCount, sizeof(rr->rrCount)); return true; } @@ -357,6 +362,13 @@ bool GBARRSkipSegment(struct GBARRContext* rr) { return true; } +bool GBARRMarkRerecord(struct GBARRContext* rr) { + ++rr->rrCount; + rr->metadataFile->seek(rr->metadataFile, rr->rrCountOffset, SEEK_SET); + rr->metadataFile->write(rr->metadataFile, &rr->rrCount, sizeof(rr->rrCount)); + return true; +} + bool _emitMagic(struct GBARRContext* rr, struct VFile* vf) { UNUSED(rr); return vf->write(vf, BINARY_MAGIC, 4) == 4; @@ -399,6 +411,9 @@ enum GBARRTag _readTag(struct GBARRContext* rr, struct VFile* vf) { case TAG_LAG_COUNT: vf->read(vf, &rr->lagFrames, sizeof(rr->lagFrames)); break; + case TAG_RR_COUNT: + vf->read(vf, &rr->rrCount, sizeof(rr->rrCount)); + break; case TAG_INIT_EX_NIHILO: rr->initFrom = INIT_EX_NIHILO; @@ -413,7 +428,6 @@ enum GBARRTag _readTag(struct GBARRContext* rr, struct VFile* vf) { break; // To be spec'd - case TAG_RR_COUNT: case TAG_AUTHOR: case TAG_COMMENT: break; @@ -471,6 +485,9 @@ bool _parseMetadata(struct GBARRContext* rr, struct VFile* vf) { case TAG_INIT_FROM_BOTH: rr->initFromOffset = vf->seek(vf, 0, SEEK_CUR); break; + case TAG_RR_COUNT: + rr->rrCountOffset = vf->seek(vf, 0, SEEK_CUR); + break; default: break; } diff --git a/src/gba/gba-rr.h b/src/gba/gba-rr.h index 1f15cf78c..ad93616d5 100644 --- a/src/gba/gba-rr.h +++ b/src/gba/gba-rr.h @@ -65,6 +65,9 @@ struct GBARRContext { enum GBARRInitFrom initFrom; off_t initFromOffset; + uint32_t rrCount; + off_t rrCountOffset; + struct VFile* savedata; // Streaming state @@ -88,6 +91,7 @@ bool GBARRLoadStream(struct GBARRContext*, uint32_t streamId); bool GBARRIncrementStream(struct GBARRContext*, bool recursive); bool GBARRFinishSegment(struct GBARRContext*); bool GBARRSkipSegment(struct GBARRContext*); +bool GBARRMarkRerecord(struct GBARRContext*); bool GBARRStartPlaying(struct GBARRContext*, bool autorecord); void GBARRStopPlaying(struct GBARRContext*); diff --git a/src/gba/gba-serialize.c b/src/gba/gba-serialize.c index ffcc31e91..dd5aa35ba 100644 --- a/src/gba/gba-serialize.c +++ b/src/gba/gba-serialize.c @@ -86,6 +86,7 @@ void GBADeserialize(struct GBA* gba, struct GBASerializedState* state) { } else { GBARRFinishSegment(gba->rr); } + GBARRMarkRerecord(gba->rr); } else if (GBARRIsPlaying(gba->rr)) { GBARRLoadStream(gba->rr, state->associatedStreamId); GBARRSkipSegment(gba->rr);