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/gba)
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/src)
|
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")
|
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_PRE_FLAGS "-pg -fprofile-generate=${PGO_DIR}")
|
||||||
set(PGO_POST_FLAGS "-fprofile-use=${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_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${PGO_PRE_FLAGS}")
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${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}")
|
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_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${PGO_POST_FLAGS}")
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${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}")
|
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${PGO_POST_FLAGS}")
|
||||||
|
|
|
@ -41,7 +41,7 @@ void GBARRContextDestroy(struct GBA* gba) {
|
||||||
gba->rr = 0;
|
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)) {
|
if (rr->movieStream && !rr->movieStream->close(rr->movieStream)) {
|
||||||
return false;
|
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);
|
rr->metadataFile = rr->streamDir->openFile(rr->streamDir, METADATA_FILENAME, O_CREAT | O_RDWR);
|
||||||
if (!_parseMetadata(rr, rr->metadataFile)) {
|
if (!_parseMetadata(rr, rr->metadataFile)) {
|
||||||
rr->metadataFile->close(rr->metadataFile);
|
rr->metadataFile->close(rr->metadataFile);
|
||||||
rr->streamDir = 0;
|
|
||||||
rr->metadataFile = 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;
|
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->streamId = 1;
|
||||||
rr->maxStreamId = 1;
|
rr->maxStreamId = 1;
|
||||||
|
rr->maxStreamIdOffset = rr->metadataFile->seek(rr->metadataFile, 0, SEEK_CUR);
|
||||||
|
_emitTag(rr, rr->metadataFile, 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,9 +336,20 @@ enum GBARRTag _readTag(struct GBARRContext* rr, struct VFile* vf) {
|
||||||
vf->read(vf, &rr->lagFrames, sizeof(rr->lagFrames));
|
vf->read(vf, &rr->lagFrames, sizeof(rr->lagFrames));
|
||||||
break;
|
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
|
// To be spec'd
|
||||||
case TAG_RR_COUNT:
|
case TAG_RR_COUNT:
|
||||||
case TAG_INIT_TYPE:
|
|
||||||
case TAG_AUTHOR:
|
case TAG_AUTHOR:
|
||||||
case TAG_COMMENT:
|
case TAG_COMMENT:
|
||||||
break;
|
break;
|
||||||
|
@ -362,9 +394,22 @@ bool _emitTag(struct GBARRContext* rr, struct VFile* vf, uint8_t tag) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _parseMetadata(struct GBARRContext* rr, struct VFile* vf) {
|
bool _parseMetadata(struct GBARRContext* rr, struct VFile* vf) {
|
||||||
|
if (!_verifyMagic(rr, vf)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
while (_readTag(rr, vf) != TAG_EOF) {
|
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);
|
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);
|
rr->maxStreamIdOffset = vf->seek(vf, 0, SEEK_SET);
|
||||||
|
|
|
@ -7,6 +7,13 @@ struct GBA;
|
||||||
struct VDir;
|
struct VDir;
|
||||||
struct VFile;
|
struct VFile;
|
||||||
|
|
||||||
|
enum GBARRInitFrom {
|
||||||
|
INIT_EX_NIHILO = 0,
|
||||||
|
INIT_FROM_SAVEGAME = 1,
|
||||||
|
INIT_FROM_SAVESTATE = 2,
|
||||||
|
INIT_FROM_BOTH = 3,
|
||||||
|
};
|
||||||
|
|
||||||
enum GBARRTag {
|
enum GBARRTag {
|
||||||
// Playback tags
|
// Playback tags
|
||||||
TAG_INVALID = 0x00,
|
TAG_INVALID = 0x00,
|
||||||
|
@ -25,7 +32,11 @@ enum GBARRTag {
|
||||||
TAG_FRAME_COUNT = 0x20,
|
TAG_FRAME_COUNT = 0x20,
|
||||||
TAG_LAG_COUNT = 0x21,
|
TAG_LAG_COUNT = 0x21,
|
||||||
TAG_RR_COUNT = 0x22,
|
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
|
// User metadata tags
|
||||||
TAG_AUTHOR = 0x30,
|
TAG_AUTHOR = 0x30,
|
||||||
|
@ -47,9 +58,13 @@ struct GBARRContext {
|
||||||
uint32_t frames;
|
uint32_t frames;
|
||||||
uint32_t lagFrames;
|
uint32_t lagFrames;
|
||||||
uint32_t streamId;
|
uint32_t streamId;
|
||||||
|
|
||||||
uint32_t maxStreamId;
|
uint32_t maxStreamId;
|
||||||
off_t maxStreamIdOffset;
|
off_t maxStreamIdOffset;
|
||||||
|
|
||||||
|
enum GBARRInitFrom initFrom;
|
||||||
|
off_t initFromOffset;
|
||||||
|
|
||||||
// Streaming state
|
// Streaming state
|
||||||
struct VDir* streamDir;
|
struct VDir* streamDir;
|
||||||
struct VFile* metadataFile;
|
struct VFile* metadataFile;
|
||||||
|
@ -63,7 +78,8 @@ struct GBARRContext {
|
||||||
void GBARRContextCreate(struct GBA*);
|
void GBARRContextCreate(struct GBA*);
|
||||||
void GBARRContextDestroy(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 GBARRLoadStream(struct GBARRContext*, uint32_t streamId);
|
||||||
bool GBARRIncrementStream(struct GBARRContext*);
|
bool GBARRIncrementStream(struct GBARRContext*);
|
||||||
bool GBARRSkipSegment(struct GBARRContext*);
|
bool GBARRSkipSegment(struct GBARRContext*);
|
||||||
|
|
|
@ -127,7 +127,8 @@ static void _GBASDLHandleKeypress(struct GBAThread* context, struct GBASDLEvents
|
||||||
GBAThreadInterrupt(context);
|
GBAThreadInterrupt(context);
|
||||||
GBARRContextCreate(context->gba);
|
GBARRContextCreate(context->gba);
|
||||||
if (!GBARRIsRecording(context->gba->rr)) {
|
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);
|
GBARRStopPlaying(context->gba->rr);
|
||||||
GBARRStartRecording(context->gba->rr);
|
GBARRStartRecording(context->gba->rr);
|
||||||
}
|
}
|
||||||
|
@ -139,7 +140,7 @@ static void _GBASDLHandleKeypress(struct GBAThread* context, struct GBASDLEvents
|
||||||
GBAThreadReset(context);
|
GBAThreadReset(context);
|
||||||
GBAThreadInterrupt(context);
|
GBAThreadInterrupt(context);
|
||||||
GBARRContextCreate(context->gba);
|
GBARRContextCreate(context->gba);
|
||||||
GBARRSetStream(context->gba->rr, context->stateDir);
|
GBARRInitStream(context->gba->rr, context->stateDir);
|
||||||
GBARRStopRecording(context->gba->rr);
|
GBARRStopRecording(context->gba->rr);
|
||||||
GBARRStartPlaying(context->gba->rr, event->keysym.mod & KMOD_SHIFT);
|
GBARRStartPlaying(context->gba->rr, event->keysym.mod & KMOD_SHIFT);
|
||||||
GBAThreadContinue(context);
|
GBAThreadContinue(context);
|
||||||
|
|
Loading…
Reference in New Issue