Perf: Ability to load savestates immediately on launch

This commit is contained in:
Jeffrey Pfau 2015-05-31 23:49:31 -07:00
parent d67481c9de
commit 1157ab06d2
2 changed files with 29 additions and 3 deletions

View File

@ -51,6 +51,7 @@ Misc:
- Qt: Unified file opening and saving with last location - Qt: Unified file opening and saving with last location
- Qt: Fix windows being resizable when they shouldn't have been - Qt: Fix windows being resizable when they shouldn't have been
- Qt: Only hide cursor in full screen - Qt: Only hide cursor in full screen
- Perf: Ability to load savestates immediately on launch
0.2.1: (2015-05-13) 0.2.1: (2015-05-13)
Bugfixes: Bugfixes:

View File

@ -7,8 +7,10 @@
#include "gba/supervisor/config.h" #include "gba/supervisor/config.h"
#include "gba/gba.h" #include "gba/gba.h"
#include "gba/renderers/video-software.h" #include "gba/renderers/video-software.h"
#include "gba/serialize.h"
#include "platform/commandline.h" #include "platform/commandline.h"
#include "util/vfs.h"
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
@ -16,27 +18,31 @@
#include <inttypes.h> #include <inttypes.h>
#include <sys/time.h> #include <sys/time.h>
#define PERF_OPTIONS "F:NPS:" #define PERF_OPTIONS "F:L:NPS:"
#define PERF_USAGE \ #define PERF_USAGE \
"\nBenchmark options:\n" \ "\nBenchmark options:\n" \
" -F FRAMES Run for the specified number of FRAMES before exiting\n" \ " -F FRAMES Run for the specified number of FRAMES before exiting\n" \
" -N Disable video rendering entirely\n" \ " -N Disable video rendering entirely\n" \
" -P CSV output, useful for parsing\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 { struct PerfOpts {
bool noVideo; bool noVideo;
bool csv; bool csv;
unsigned duration; unsigned duration;
unsigned frames; unsigned frames;
char* savestate;
}; };
static void _GBAPerfRunloop(struct GBAThread* context, int* frames, bool quiet); static void _GBAPerfRunloop(struct GBAThread* context, int* frames, bool quiet);
static void _GBAPerfShutdown(int signal); static void _GBAPerfShutdown(int signal);
static bool _parsePerfOpts(struct SubParser* parser, struct GBAConfig* config, int option, const char* arg); 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 struct GBAThread* _thread;
static bool _dispatchExiting = false; static bool _dispatchExiting = false;
static struct VFile* _savestate = 0;
int main(int argc, char** argv) { int main(int argc, char** argv) {
signal(SIGINT, _GBAPerfShutdown); signal(SIGINT, _GBAPerfShutdown);
@ -44,7 +50,7 @@ int main(int argc, char** argv) {
struct GBAVideoSoftwareRenderer renderer; struct GBAVideoSoftwareRenderer renderer;
GBAVideoSoftwareRendererCreate(&renderer); GBAVideoSoftwareRendererCreate(&renderer);
struct PerfOpts perfOpts = { false, false, 0, 0 }; struct PerfOpts perfOpts = { false, false, 0, 0, 0 };
struct SubParser subparser = { struct SubParser subparser = {
.usage = PERF_USAGE, .usage = PERF_USAGE,
.parse = _parsePerfOpts, .parse = _parsePerfOpts,
@ -80,6 +86,13 @@ int main(int argc, char** argv) {
if (!perfOpts.noVideo) { if (!perfOpts.noVideo) {
context.renderer = &renderer.d; 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.debugger = createDebugger(&args, &context);
context.overrides = GBAConfigGetOverrides(&config); context.overrides = GBAConfigGetOverrides(&config);
@ -134,6 +147,9 @@ int main(int argc, char** argv) {
} }
cleanup: cleanup:
if (_savestate) {
_savestate->close(_savestate);
}
GBAConfigFreeOpts(&opts); GBAConfigFreeOpts(&opts);
freeArguments(&args); freeArguments(&args);
GBAConfigDeinit(&config); GBAConfigDeinit(&config);
@ -205,7 +221,16 @@ static bool _parsePerfOpts(struct SubParser* parser, struct GBAConfig* config, i
case 'S': case 'S':
opts->duration = strtoul(arg, 0, 10); opts->duration = strtoul(arg, 0, 10);
return !errno; return !errno;
case 'L':
opts->savestate = strdup(arg);
return true;
default: default:
return false; return false;
} }
} }
static void _loadSavestate(struct GBAThread* context) {
GBALoadStateNamed(context->gba, _savestate);
_savestate->close(_savestate);
_savestate = 0;
}