Perf: Ability to load savestates immediately on launch
Jeffrey Pfau jeffrey@endrift.com
Sun, 31 May 2015 23:49:31 -0700
2 files changed,
29 insertions(+),
3 deletions(-)
M
CHANGES
→
CHANGES
@@ -51,6 +51,7 @@ - Qt: Migrate multiplayer window handling into GBAApp
- Qt: Unified file opening and saving with last location - Qt: Fix windows being resizable when they shouldn't have been - Qt: Only hide cursor in full screen + - Perf: Ability to load savestates immediately on launch 0.2.1: (2015-05-13) Bugfixes:
M
src/platform/perf-main.c
→
src/platform/perf-main.c
@@ -7,8 +7,10 @@ #include "gba/supervisor/thread.h"
#include "gba/supervisor/config.h" #include "gba/gba.h" #include "gba/renderers/video-software.h" +#include "gba/serialize.h" #include "platform/commandline.h" +#include "util/vfs.h" #include <errno.h> #include <fcntl.h>@@ -16,27 +18,31 @@ #include <signal.h>
#include <inttypes.h> #include <sys/time.h> -#define PERF_OPTIONS "F:NPS:" +#define PERF_OPTIONS "F:L:NPS:" #define PERF_USAGE \ "\nBenchmark options:\n" \ " -F FRAMES Run for the specified number of FRAMES before exiting\n" \ " -N Disable video rendering entirely\n" \ " -P CSV output, useful for parsing\n" \ - " -S SEC Run for SEC in-game seconds before exiting" + " -S SEC Run for SEC in-game seconds before exiting\n" \ + " -L FILE Load a savestate when starting the test" struct PerfOpts { bool noVideo; bool csv; unsigned duration; unsigned frames; + char* savestate; }; static void _GBAPerfRunloop(struct GBAThread* context, int* frames, bool quiet); static void _GBAPerfShutdown(int signal); static bool _parsePerfOpts(struct SubParser* parser, struct GBAConfig* config, int option, const char* arg); +static void _loadSavestate(struct GBAThread* context); static struct GBAThread* _thread; static bool _dispatchExiting = false; +static struct VFile* _savestate = 0; int main(int argc, char** argv) { signal(SIGINT, _GBAPerfShutdown);@@ -44,7 +50,7 @@
struct GBAVideoSoftwareRenderer renderer; GBAVideoSoftwareRendererCreate(&renderer); - struct PerfOpts perfOpts = { false, false, 0, 0 }; + struct PerfOpts perfOpts = { false, false, 0, 0, 0 }; struct SubParser subparser = { .usage = PERF_USAGE, .parse = _parsePerfOpts,@@ -80,6 +86,13 @@
if (!perfOpts.noVideo) { context.renderer = &renderer.d; } + if (perfOpts.savestate) { + _savestate = VFileOpen(perfOpts.savestate, O_RDONLY); + free(perfOpts.savestate); + } + if (_savestate) { + context.startCallback = _loadSavestate; + } context.debugger = createDebugger(&args, &context); context.overrides = GBAConfigGetOverrides(&config);@@ -134,6 +147,9 @@ printf("%u frames in %" PRIu64 " microseconds: %g fps (%gx)\n", frames, duration, scaledFrames / duration, scaledFrames / (duration * 60.f));
} cleanup: + if (_savestate) { + _savestate->close(_savestate); + } GBAConfigFreeOpts(&opts); freeArguments(&args); GBAConfigDeinit(&config);@@ -205,7 +221,16 @@ return true;
case 'S': opts->duration = strtoul(arg, 0, 10); return !errno; + case 'L': + opts->savestate = strdup(arg); + return true; default: return false; } } + +static void _loadSavestate(struct GBAThread* context) { + GBALoadStateNamed(context->gba, _savestate); + _savestate->close(_savestate); + _savestate = 0; +}