src/platform/perf-main.c (view raw)
1#include "gba-thread.h"
2#include "gba.h"
3#include "renderers/video-software.h"
4
5#include <fcntl.h>
6#include <signal.h>
7#include <sys/time.h>
8
9static void _GBAPerfRunloop(struct GBAThread* context, int* frames);
10static void _GBAPerfShutdown(int signal);
11
12static struct GBAThread* _thread;
13
14int main(int argc, char** argv) {
15 signal(SIGINT, _GBAPerfShutdown);
16
17 struct GBAVideoSoftwareRenderer renderer;
18 GBAVideoSoftwareRendererCreate(&renderer);
19
20 struct StartupOptions opts;
21 if (!parseCommandArgs(&opts, argc, argv, PERF_OPTIONS)) {
22 usage(argv[0], PERF_USAGE);
23 return 1;
24 }
25
26 renderer.outputBuffer = malloc(256 * 256 * 4);
27 renderer.outputBufferStride = 256;
28
29 struct GBAThread context = {
30 .renderer = &renderer.d,
31 .sync.videoFrameWait = 0,
32 .sync.audioWait = 0
33 };
34 _thread = &context;
35
36 context.debugger = createDebugger(&opts);
37
38 GBAMapOptionsToContext(&opts, &context);
39
40 GBAThreadStart(&context);
41
42 int frames = opts.perfDuration;
43 time_t start = time(0);
44 _GBAPerfRunloop(&context, &frames);
45 time_t end = time(0);
46 int duration = end - start;
47
48 GBAThreadJoin(&context);
49 close(opts.fd);
50 if (opts.biosFd >= 0) {
51 close(opts.biosFd);
52 }
53 free(context.debugger);
54
55 free(renderer.outputBuffer);
56
57 printf("%u frames in %i seconds: %g fps (%gx)\n", frames, duration, frames / (float) duration, frames / (duration * 60.f));
58
59 return 0;
60}
61
62static void _GBAPerfRunloop(struct GBAThread* context, int* frames) {
63 struct timeval lastEcho;
64 gettimeofday(&lastEcho, 0);
65 int duration = *frames;
66 *frames = 0;
67 int lastFrames = 0;
68 while (context->state < THREAD_EXITING) {
69 if (GBASyncWaitFrameStart(&context->sync, 0)) {
70 ++*frames;
71 ++lastFrames;
72 struct timeval currentTime;
73 long timeDiff;
74 gettimeofday(¤tTime, 0);
75 timeDiff = currentTime.tv_sec - lastEcho.tv_sec;
76 timeDiff *= 1000;
77 timeDiff += (currentTime.tv_usec - lastEcho.tv_usec) / 1000;
78 if (timeDiff >= 1000) {
79 printf("\033[2K\rCurrent FPS: %g (%gx)", lastFrames / (timeDiff / 1000.0f), lastFrames / (float) (60 * (timeDiff / 1000.0f)));
80 fflush(stdout);
81 lastEcho = currentTime;
82 lastFrames = 0;
83 }
84 }
85 GBASyncWaitFrameEnd(&context->sync);
86 if (*frames == duration * 60) {
87 _GBAPerfShutdown(0);
88 }
89 }
90 printf("\033[2K\r");
91}
92
93static void _GBAPerfShutdown(int signal) {
94 (void) (signal);
95 pthread_mutex_lock(&_thread->stateMutex);
96 _thread->state = THREAD_EXITING;
97 pthread_mutex_unlock(&_thread->stateMutex);
98}