Save initialization type and metadata magic number
Jeffrey Pfau jeffrey@endrift.com
Mon, 04 Aug 2014 00:52:58 -0700
4 files changed,
76 insertions(+),
12 deletions(-)
M
CMakeLists.txt
→
CMakeLists.txt
@@ -20,16 +20,18 @@ include_directories(${CMAKE_SOURCE_DIR}/src/arm)
include_directories(${CMAKE_SOURCE_DIR}/src/gba) include_directories(${CMAKE_SOURCE_DIR}/src) +set(BUILD_PGO CACHE BOOL "Build with profiling-guided optimization") +set(PGO_STAGE_2 CACHE BOOL "Rebuild for profiling-guided optimization after profiles have been generated") set(PGO_DIR "/tmp/gba-pgo/" CACHE PATH "Profiling-guided optimization profiles path") -mark_as_advanced(PGO_DIR) +mark_as_advanced(BUILD_PGO PGO_STAGE_2 PGO_DIR) set(PGO_PRE_FLAGS "-pg -fprofile-generate=${PGO_DIR}") set(PGO_POST_FLAGS "-fprofile-use=${PGO_DIR}") -if(PGO_STAGE EQUAL 1) +if(BUILD_PGO AND NOT PGO_STAGE_2) set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${PGO_PRE_FLAGS}") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PGO_PRE_FLAGS}") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${PGO_PRE_FLAGS}") -elseif(PGO_STAGE EQUAL 2) +elseif(BUILD_PGO AND PGO_STAGE_2) set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${PGO_POST_FLAGS}") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PGO_POST_FLAGS}") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${PGO_POST_FLAGS}")
M
src/gba/gba-rr.c
→
src/gba/gba-rr.c
@@ -41,7 +41,7 @@ free(gba->rr);
gba->rr = 0; } -bool GBARRSetStream(struct GBARRContext* rr, struct VDir* stream) { +bool GBARRInitStream(struct GBARRContext* rr, struct VDir* stream) { if (rr->movieStream && !rr->movieStream->close(rr->movieStream)) { return false; }@@ -54,13 +54,34 @@ rr->streamDir = stream;
rr->metadataFile = rr->streamDir->openFile(rr->streamDir, METADATA_FILENAME, O_CREAT | O_RDWR); if (!_parseMetadata(rr, rr->metadataFile)) { rr->metadataFile->close(rr->metadataFile); - rr->streamDir = 0; rr->metadataFile = 0; + rr->maxStreamId = 1; + } + rr->streamId = 1; + rr->movieStream = 0; + return true; +} + +bool GBARRReinitStream(struct GBARRContext* rr, enum GBARRInitFrom initFrom) { + if (!rr) { return false; } - rr->movieStream = 0; + + if (rr->metadataFile) { + rr->metadataFile->truncate(rr->metadataFile, 0); + } else { + rr->metadataFile = rr->streamDir->openFile(rr->streamDir, METADATA_FILENAME, O_CREAT | O_TRUNC | O_RDWR); + } + _emitMagic(rr, rr->metadataFile); + + rr->initFrom = initFrom; + rr->initFromOffset = rr->metadataFile->seek(rr->metadataFile, 0, SEEK_CUR); + _emitTag(rr, rr->metadataFile, TAG_INIT | initFrom); + rr->streamId = 1; rr->maxStreamId = 1; + rr->maxStreamIdOffset = rr->metadataFile->seek(rr->metadataFile, 0, SEEK_CUR); + _emitTag(rr, rr->metadataFile, 1); return true; }@@ -315,9 +336,20 @@ case TAG_LAG_COUNT:
vf->read(vf, &rr->lagFrames, sizeof(rr->lagFrames)); break; + case TAG_INIT_EX_NIHILO: + rr->initFrom = INIT_EX_NIHILO; + break; + case TAG_INIT_FROM_SAVEGAME: + rr->initFrom = INIT_FROM_SAVEGAME; + break; + case TAG_INIT_FROM_SAVESTATE: + rr->initFrom = INIT_FROM_SAVESTATE; + case TAG_INIT_FROM_BOTH: + rr->initFrom = INIT_FROM_BOTH; + break; + // To be spec'd case TAG_RR_COUNT: - case TAG_INIT_TYPE: case TAG_AUTHOR: case TAG_COMMENT: break;@@ -362,9 +394,22 @@ return vf->write(vf, &tag, sizeof(tag)) == sizeof(tag);
} bool _parseMetadata(struct GBARRContext* rr, struct VFile* vf) { + if (!_verifyMagic(rr, vf)) { + return false; + } while (_readTag(rr, vf) != TAG_EOF) { - if (rr->peekedTag == TAG_MAX_STREAM) { + switch (rr->peekedTag) { + case TAG_MAX_STREAM: rr->maxStreamIdOffset = vf->seek(vf, 0, SEEK_CUR); + break; + case TAG_INIT_EX_NIHILO: + case TAG_INIT_FROM_SAVEGAME: + case TAG_INIT_FROM_SAVESTATE: + case TAG_INIT_FROM_BOTH: + rr->initFromOffset = vf->seek(vf, 0, SEEK_CUR); + break; + default: + break; } } rr->maxStreamIdOffset = vf->seek(vf, 0, SEEK_SET);
M
src/gba/gba-rr.h
→
src/gba/gba-rr.h
@@ -7,6 +7,13 @@ struct GBA;
struct VDir; struct VFile; +enum GBARRInitFrom { + INIT_EX_NIHILO = 0, + INIT_FROM_SAVEGAME = 1, + INIT_FROM_SAVESTATE = 2, + INIT_FROM_BOTH = 3, +}; + enum GBARRTag { // Playback tags TAG_INVALID = 0x00,@@ -25,7 +32,11 @@ // Recording information tags
TAG_FRAME_COUNT = 0x20, TAG_LAG_COUNT = 0x21, TAG_RR_COUNT = 0x22, - TAG_INIT_TYPE = 0x23, + TAG_INIT = 0x24, + TAG_INIT_EX_NIHILO = 0x24 | INIT_EX_NIHILO, + TAG_INIT_FROM_SAVEGAME = 0x24 | INIT_FROM_SAVEGAME, + TAG_INIT_FROM_SAVESTATE = 0x24 | INIT_FROM_SAVESTATE, + TAG_INIT_FROM_BOTH = 0x24 | INIT_FROM_BOTH, // User metadata tags TAG_AUTHOR = 0x30,@@ -47,9 +58,13 @@ // Metadata
uint32_t frames; uint32_t lagFrames; uint32_t streamId; + uint32_t maxStreamId; off_t maxStreamIdOffset; + enum GBARRInitFrom initFrom; + off_t initFromOffset; + // Streaming state struct VDir* streamDir; struct VFile* metadataFile;@@ -63,7 +78,8 @@
void GBARRContextCreate(struct GBA*); void GBARRContextDestroy(struct GBA*); -bool GBARRSetStream(struct GBARRContext*, struct VDir*); +bool GBARRInitStream(struct GBARRContext*, struct VDir*); +bool GBARRReinitStream(struct GBARRContext*, enum GBARRInitFrom); bool GBARRLoadStream(struct GBARRContext*, uint32_t streamId); bool GBARRIncrementStream(struct GBARRContext*); bool GBARRSkipSegment(struct GBARRContext*);
M
src/platform/sdl/sdl-events.c
→
src/platform/sdl/sdl-events.c
@@ -127,7 +127,8 @@ GBAThreadReset(context);
GBAThreadInterrupt(context); GBARRContextCreate(context->gba); if (!GBARRIsRecording(context->gba->rr)) { - GBARRSetStream(context->gba->rr, context->stateDir); + GBARRInitStream(context->gba->rr, context->stateDir); + GBARRReinitStream(context->gba->rr, INIT_FROM_SAVEGAME); GBARRStopPlaying(context->gba->rr); GBARRStartRecording(context->gba->rr); }@@ -139,7 +140,7 @@ if (context->stateDir) {
GBAThreadReset(context); GBAThreadInterrupt(context); GBARRContextCreate(context->gba); - GBARRSetStream(context->gba->rr, context->stateDir); + GBARRInitStream(context->gba->rr, context->stateDir); GBARRStopRecording(context->gba->rr); GBARRStartPlaying(context->gba->rr, event->keysym.mod & KMOD_SHIFT); GBAThreadContinue(context);