mirror of https://github.com/mgba-emu/mgba.git
Save initialization type and metadata magic number
This commit is contained in:
parent
ff200093ca
commit
220d836f13
|
@ -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}")
|
||||
|
|
|
@ -41,7 +41,7 @@ void GBARRContextDestroy(struct GBA* gba) {
|
|||
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 @@ bool GBARRSetStream(struct GBARRContext* rr, struct VDir* 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 @@ enum GBARRTag _readTag(struct GBARRContext* rr, struct VFile* vf) {
|
|||
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 @@ bool _emitTag(struct GBARRContext* rr, struct VFile* vf, uint8_t 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);
|
||||
|
|
|
@ -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 @@ enum GBARRTag {
|
|||
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 @@ struct GBARRContext {
|
|||
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 @@ struct GBARRContext {
|
|||
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*);
|
||||
|
|
|
@ -127,7 +127,8 @@ static void _GBASDLHandleKeypress(struct GBAThread* context, struct GBASDLEvents
|
|||
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 @@ static void _GBASDLHandleKeypress(struct GBAThread* context, struct GBASDLEvents
|
|||
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);
|
||||
|
|
Loading…
Reference in New Issue