mirror of https://github.com/mgba-emu/mgba.git
GBA RR: Add support for resets in movies
This commit is contained in:
parent
0e8e55e8ed
commit
76d486cc65
1
CHANGES
1
CHANGES
|
@ -52,6 +52,7 @@ Misc:
|
||||||
- Libretro: Add install target for libretro core
|
- Libretro: Add install target for libretro core
|
||||||
- 3DS: Update to new ctrulib API
|
- 3DS: Update to new ctrulib API
|
||||||
- GBA RR: Add preliminary SRAM support for VBM loading
|
- GBA RR: Add preliminary SRAM support for VBM loading
|
||||||
|
- GBA RR: Add support for resets in movies
|
||||||
|
|
||||||
0.3.2: (2015-12-16)
|
0.3.2: (2015-12-16)
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
|
|
|
@ -912,6 +912,13 @@ void GBAFrameEnded(struct GBA* gba) {
|
||||||
if (thread->frameCallback) {
|
if (thread->frameCallback) {
|
||||||
thread->frameCallback(thread);
|
thread->frameCallback(thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gba->rr && gba->rr->queryReset(gba->rr)) {
|
||||||
|
// TODO: Clean up reset scheduling
|
||||||
|
MutexLock(&thread->stateMutex);
|
||||||
|
thread->state = THREAD_RESETING;
|
||||||
|
MutexUnlock(&thread->stateMutex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBASetBreakpoint(struct GBA* gba, struct ARMComponent* component, uint32_t address, enum ExecutionMode mode, uint32_t* opcode) {
|
void GBASetBreakpoint(struct GBA* gba, struct ARMComponent* component, uint32_t address, enum ExecutionMode mode, uint32_t* opcode) {
|
||||||
|
|
|
@ -30,6 +30,7 @@ static bool GBAMGMIsRecording(const struct GBARRContext*);
|
||||||
static void GBAMGMNextFrame(struct GBARRContext*);
|
static void GBAMGMNextFrame(struct GBARRContext*);
|
||||||
static void GBAMGMLogInput(struct GBARRContext*, uint16_t input);
|
static void GBAMGMLogInput(struct GBARRContext*, uint16_t input);
|
||||||
static uint16_t GBAMGMQueryInput(struct GBARRContext*);
|
static uint16_t GBAMGMQueryInput(struct GBARRContext*);
|
||||||
|
static bool GBAMGMQueryReset(struct GBARRContext*);
|
||||||
|
|
||||||
static void GBAMGMStateSaved(struct GBARRContext* rr, struct GBASerializedState* state);
|
static void GBAMGMStateSaved(struct GBARRContext* rr, struct GBASerializedState* state);
|
||||||
static void GBAMGMStateLoaded(struct GBARRContext* rr, const struct GBASerializedState* state);
|
static void GBAMGMStateLoaded(struct GBARRContext* rr, const struct GBASerializedState* state);
|
||||||
|
@ -71,6 +72,7 @@ void GBAMGMContextCreate(struct GBAMGMContext* mgm) {
|
||||||
mgm->d.nextFrame = GBAMGMNextFrame;
|
mgm->d.nextFrame = GBAMGMNextFrame;
|
||||||
mgm->d.logInput = GBAMGMLogInput;
|
mgm->d.logInput = GBAMGMLogInput;
|
||||||
mgm->d.queryInput = GBAMGMQueryInput;
|
mgm->d.queryInput = GBAMGMQueryInput;
|
||||||
|
mgm->d.queryReset = GBAMGMQueryReset;
|
||||||
|
|
||||||
mgm->d.stateSaved = GBAMGMStateSaved;
|
mgm->d.stateSaved = GBAMGMStateSaved;
|
||||||
mgm->d.stateLoaded = GBAMGMStateLoaded;
|
mgm->d.stateLoaded = GBAMGMStateLoaded;
|
||||||
|
@ -324,6 +326,15 @@ uint16_t GBAMGMQueryInput(struct GBARRContext* rr) {
|
||||||
return mgm->currentInput;
|
return mgm->currentInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GBAMGMQueryReset(struct GBARRContext* rr) {
|
||||||
|
if (!rr->isPlaying(rr)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct GBAMGMContext* mgm = (struct GBAMGMContext*) rr;
|
||||||
|
return mgm->peekedTag == TAG_RESET;
|
||||||
|
}
|
||||||
|
|
||||||
void GBAMGMStateSaved(struct GBARRContext* rr, struct GBASerializedState* state) {
|
void GBAMGMStateSaved(struct GBARRContext* rr, struct GBASerializedState* state) {
|
||||||
struct GBAMGMContext* mgm = (struct GBAMGMContext*) rr;
|
struct GBAMGMContext* mgm = (struct GBAMGMContext*) rr;
|
||||||
if (rr->isRecording(rr)) {
|
if (rr->isRecording(rr)) {
|
||||||
|
@ -441,6 +452,7 @@ enum GBAMGMTag _readTag(struct GBAMGMContext* mgm, struct VFile* vf) {
|
||||||
// Empty markers
|
// Empty markers
|
||||||
case TAG_FRAME:
|
case TAG_FRAME:
|
||||||
case TAG_LAG:
|
case TAG_LAG:
|
||||||
|
case TAG_RESET:
|
||||||
case TAG_BEGIN:
|
case TAG_BEGIN:
|
||||||
case TAG_END:
|
case TAG_END:
|
||||||
case TAG_INVALID:
|
case TAG_INVALID:
|
||||||
|
|
|
@ -20,6 +20,7 @@ enum GBAMGMTag {
|
||||||
TAG_INPUT = 0x01,
|
TAG_INPUT = 0x01,
|
||||||
TAG_FRAME = 0x02,
|
TAG_FRAME = 0x02,
|
||||||
TAG_LAG = 0x03,
|
TAG_LAG = 0x03,
|
||||||
|
TAG_RESET = 0x04,
|
||||||
|
|
||||||
// Stream chunking tags
|
// Stream chunking tags
|
||||||
TAG_BEGIN = 0x10,
|
TAG_BEGIN = 0x10,
|
||||||
|
|
|
@ -33,6 +33,7 @@ struct GBARRContext {
|
||||||
void (*nextFrame)(struct GBARRContext*);
|
void (*nextFrame)(struct GBARRContext*);
|
||||||
void (*logInput)(struct GBARRContext*, uint16_t input);
|
void (*logInput)(struct GBARRContext*, uint16_t input);
|
||||||
uint16_t (*queryInput)(struct GBARRContext*);
|
uint16_t (*queryInput)(struct GBARRContext*);
|
||||||
|
bool (*queryReset)(struct GBARRContext*);
|
||||||
|
|
||||||
void (*stateSaved)(struct GBARRContext*, struct GBASerializedState*);
|
void (*stateSaved)(struct GBARRContext*, struct GBASerializedState*);
|
||||||
void (*stateLoaded)(struct GBARRContext*, const struct GBASerializedState*);
|
void (*stateLoaded)(struct GBARRContext*, const struct GBASerializedState*);
|
||||||
|
|
|
@ -27,6 +27,7 @@ static bool GBAVBMIsRecording(const struct GBARRContext*);
|
||||||
|
|
||||||
static void GBAVBMNextFrame(struct GBARRContext*);
|
static void GBAVBMNextFrame(struct GBARRContext*);
|
||||||
static uint16_t GBAVBMQueryInput(struct GBARRContext*);
|
static uint16_t GBAVBMQueryInput(struct GBARRContext*);
|
||||||
|
static bool GBAVBMQueryReset(struct GBARRContext*);
|
||||||
|
|
||||||
static void GBAVBMStateSaved(struct GBARRContext* rr, struct GBASerializedState* state);
|
static void GBAVBMStateSaved(struct GBARRContext* rr, struct GBASerializedState* state);
|
||||||
static void GBAVBMStateLoaded(struct GBARRContext* rr, const struct GBASerializedState* state);
|
static void GBAVBMStateLoaded(struct GBARRContext* rr, const struct GBASerializedState* state);
|
||||||
|
@ -50,6 +51,7 @@ void GBAVBMContextCreate(struct GBAVBMContext* vbm) {
|
||||||
vbm->d.nextFrame = GBAVBMNextFrame;
|
vbm->d.nextFrame = GBAVBMNextFrame;
|
||||||
vbm->d.logInput = 0;
|
vbm->d.logInput = 0;
|
||||||
vbm->d.queryInput = GBAVBMQueryInput;
|
vbm->d.queryInput = GBAVBMQueryInput;
|
||||||
|
vbm->d.queryReset = GBAVBMQueryReset;
|
||||||
|
|
||||||
vbm->d.stateSaved = GBAVBMStateSaved;
|
vbm->d.stateSaved = GBAVBMStateSaved;
|
||||||
vbm->d.stateLoaded = GBAVBMStateLoaded;
|
vbm->d.stateLoaded = GBAVBMStateLoaded;
|
||||||
|
@ -118,6 +120,18 @@ uint16_t GBAVBMQueryInput(struct GBARRContext* rr) {
|
||||||
return input & 0x3FF;
|
return input & 0x3FF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GBAVBMQueryReset(struct GBARRContext* rr) {
|
||||||
|
if (!rr->isPlaying(rr)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct GBAVBMContext* vbm = (struct GBAVBMContext*) rr;
|
||||||
|
uint16_t input;
|
||||||
|
vbm->vbmFile->read(vbm->vbmFile, &input, sizeof(input));
|
||||||
|
vbm->vbmFile->seek(vbm->vbmFile, -sizeof(input), SEEK_CUR);
|
||||||
|
return input & 0x800;
|
||||||
|
}
|
||||||
|
|
||||||
void GBAVBMStateSaved(struct GBARRContext* rr, struct GBASerializedState* state) {
|
void GBAVBMStateSaved(struct GBARRContext* rr, struct GBASerializedState* state) {
|
||||||
UNUSED(rr);
|
UNUSED(rr);
|
||||||
UNUSED(state);
|
UNUSED(state);
|
||||||
|
|
Loading…
Reference in New Issue