all repos — mgba @ f69d9db9d46322a71761c7f98da21a3da8c5dbe4

mGBA Game Boy Advance Emulator

GBA RR: Add way to play movies from startup
Jeffrey Pfau jeffrey@endrift.com
Thu, 05 Mar 2015 14:10:23 -0800
commit

f69d9db9d46322a71761c7f98da21a3da8c5dbe4

parent

bb77d278dd03ac09f0ef63d5b13aa6ee12f1e6e3

M src/gba/rr/mgm.csrc/gba/rr/mgm.c

@@ -17,6 +17,8 @@ enum {

INVALID_INPUT = 0x8000 }; +static void GBAMGMContextDestroy(struct GBARRContext*); + static bool GBAMGMStartPlaying(struct GBARRContext*, bool autorecord); static void GBAMGMStopPlaying(struct GBARRContext*); static bool GBAMGMStartRecording(struct GBARRContext*);

@@ -56,6 +58,8 @@

void GBAMGMContextCreate(struct GBAMGMContext* mgm) { memset(mgm, 0, sizeof(*mgm)); + mgm->d.destroy = GBAMGMContextDestroy; + mgm->d.startPlaying = GBAMGMStartPlaying; mgm->d.stopPlaying = GBAMGMStopPlaying; mgm->d.startRecording = GBAMGMStartRecording;

@@ -75,19 +79,10 @@ mgm->d.openSavedata = GBAMGMOpenSavedata;

mgm->d.openSavestate = GBAMGMOpenSavestate; } -void GBAMGMContextDestroy(struct GBAMGMContext* mgm) { - if (mgm->d.isPlaying(&mgm->d)) { - mgm->d.stopPlaying(&mgm->d); - } - if (mgm->d.isRecording(&mgm->d)) { - mgm->d.stopRecording(&mgm->d); - } +void GBAMGMContextDestroy(struct GBARRContext* rr) { + struct GBAMGMContext* mgm = (struct GBAMGMContext*) rr; if (mgm->metadataFile) { mgm->metadataFile->close(mgm->metadataFile); - } - if (mgm->d.savedata) { - mgm->d.savedata->close(mgm->d.savedata); - mgm->d.savedata = 0; } }
M src/gba/rr/mgm.hsrc/gba/rr/mgm.h

@@ -75,7 +75,6 @@ uint32_t previously;

}; void GBAMGMContextCreate(struct GBAMGMContext*); -void GBAMGMContextDestroy(struct GBAMGMContext*); bool GBAMGMSetStream(struct GBAMGMContext* mgm, struct VDir* stream); bool GBAMGMCreateStream(struct GBAMGMContext* mgm, enum GBARRInitFrom initFrom);
M src/gba/supervisor/rr.csrc/gba/supervisor/rr.c

@@ -7,7 +7,7 @@ #include "rr.h"

#include "util/vfs.h" -void GBARRSaveState(struct GBA* gba) { +void GBARRInitRecord(struct GBA* gba) { if (!gba || !gba->rr) { return; }

@@ -34,7 +34,7 @@ ARMReset(gba->cpu);

} } -void GBARRLoadState(struct GBA* gba) { +void GBARRInitPlay(struct GBA* gba) { if (!gba || !gba->rr) { return; }

@@ -57,3 +57,17 @@ } else {

ARMReset(gba->cpu); } } + +void GBARRDestroy(struct GBARRContext* rr) { + if (rr->isPlaying(rr)) { + rr->stopPlaying(rr); + } + if (rr->isRecording(rr)) { + rr->stopRecording(rr); + } + if (rr->savedata) { + rr->savedata->close(rr->savedata); + rr->savedata = 0; + } + rr->destroy(rr); +}
M src/gba/supervisor/rr.hsrc/gba/supervisor/rr.h

@@ -20,6 +20,8 @@ INIT_FROM_BOTH = 3,

}; struct GBARRContext { + void (*destroy)(struct GBARRContext*); + bool (*startPlaying)(struct GBARRContext*, bool autorecord); void (*stopPlaying)(struct GBARRContext*); bool (*startRecording)(struct GBARRContext*);

@@ -46,5 +48,10 @@ uint32_t rrCount;

struct VFile* savedata; }; + +void GBARRDestroy(struct GBARRContext*); + +void GBARRInitRecord(struct GBA*); +void GBARRInitPlay(struct GBA*); #endif
M src/gba/supervisor/thread.csrc/gba/supervisor/thread.c

@@ -10,6 +10,7 @@ #include "gba/gba.h"

#include "gba/cheats.h" #include "gba/serialize.h" #include "gba/supervisor/config.h" +#include "gba/rr/mgm.h" #include "debugger/debugger.h"

@@ -117,6 +118,7 @@ struct Patch patch;

struct GBACheatDevice cheatDevice; struct GBAThread* threadContext = context; struct ARMComponent* components[GBA_COMPONENT_MAX] = {}; + struct GBARRContext* movie = 0; int numComponents = GBA_COMPONENT_MAX; #if !defined(_WIN32) && defined(USE_PTHREADS)

@@ -170,7 +172,32 @@ GBAApplyPatch(&gba, &patch);

} } + if (threadContext->movie) { + struct VDir* movieDir = VDirOpen(threadContext->movie); +#ifdef ENABLE_LIBZIP + if (!movieDir) { + movieDir = VDirOpenZip(threadContext->movie, 0); + } +#endif + if (movieDir) { + struct GBAMGMContext* mgm = malloc(sizeof(*mgm)); + GBAMGMContextCreate(mgm); + if (!GBAMGMSetStream(mgm, movieDir)) { + mgm->d.destroy(&mgm->d); + } else { + movie = &mgm->d; + } + } + } + ARMReset(&cpu); + + if (movie) { + gba.rr = movie; + movie->startPlaying(movie, false); + GBARRInitPlay(&gba); + } + if (threadContext->skipBios) { GBASkipBIOS(&cpu); }

@@ -256,6 +283,11 @@ if (&cheatDevice == threadContext->cheats) {

GBACheatDeviceDestroy(&cheatDevice); } + if (movie) { + movie->destroy(movie); + free(movie); + } + threadContext->sync.videoFrameOn = false; ConditionWake(&threadContext->sync.videoFrameAvailableCond); ConditionWake(&threadContext->sync.audioRequiredCond);

@@ -309,6 +341,7 @@ }

threadContext->fname = args->fname; threadContext->patch = VFileOpen(args->patch, O_RDONLY); threadContext->cheatsFile = VFileOpen(args->cheatsFile, O_RDONLY); + threadContext->movie = args->movie; } bool GBAThreadStart(struct GBAThread* threadContext) {
M src/gba/supervisor/thread.hsrc/gba/supervisor/thread.h

@@ -72,6 +72,7 @@ struct VFile* bios;

struct VFile* patch; struct VFile* cheatsFile; const char* fname; + const char* movie; int activeKeys; struct GBAAVStream* stream; struct Configuration* overrides;
M src/platform/commandline.csrc/platform/commandline.c

@@ -34,8 +34,8 @@ " -f Start full-screen"

static const struct option _options[] = { { "bios", required_argument, 0, 'b' }, - { "cheats", required_argument, 0, 'c' }, - { "dirmode", required_argument, 0, 'D' }, + { "cheats", required_argument, 0, 'c' }, + { "dirmode", required_argument, 0, 'D' }, { "frameskip", required_argument, 0, 's' }, #ifdef USE_CLI_DEBUGGER { "debug", no_argument, 0, 'd' },

@@ -43,6 +43,7 @@ #endif

#ifdef USE_GDB_STUB { "gdb", no_argument, 0, 'g' }, #endif + { "movie", required_argument, 0, 'v' }, { "patch", required_argument, 0, 'p' }, { 0, 0, 0, 0 } };

@@ -52,7 +53,7 @@

bool parseArguments(struct GBAArguments* opts, struct GBAConfig* config, int argc, char* const* argv, struct SubParser* subparser) { int ch; char options[64] = - "b:c:Dl:p:s:" + "b:c:Dl:p:s:v:" #ifdef USE_CLI_DEBUGGER "d" #endif

@@ -101,6 +102,9 @@ break;

case 's': GBAConfigSetDefaultValue(config, "frameskip", optarg); break; + case 'v': + opts->movie = strdup(optarg); + break; default: if (subparser) { if (!subparser->parse(subparser, config, ch, optarg)) {

@@ -125,6 +129,9 @@ opts->fname = 0;

free(opts->patch); opts->patch = 0; + + free(opts->movie); + opts->movie = 0; } void initParserForGraphics(struct SubParser* parser, struct GraphicsOpts* opts) {

@@ -211,6 +218,7 @@ #endif

#ifdef USE_GDB_STUB puts(" -g, --gdb Start GDB session (default port 2345)"); #endif + puts(" -v, --movie FILE Play back a movie of recorded input"); puts(" -p, --patch FILE Apply a specified patch file when running"); puts(" -s, --frameskip N Skip every N frames"); if (extraOptions) {
M src/platform/commandline.hsrc/platform/commandline.h

@@ -26,6 +26,7 @@ char* fname;

char* patch; char* cheatsFile; bool dirmode; + char* movie; enum DebuggerType debuggerType; bool debugAtStart;