fbdev backend works
[retrobench] / src / fbdev / main.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <ctype.h>
5 #include <signal.h>
6 #include <unistd.h>
7 #include <fcntl.h>
8 #include <sys/time.h>
9 #include <sys/mman.h>
10 #include "fbgfx.h"
11 #include "fbevents.h"
12 #include "rbench.h"
13 #include "util.h"
14
15 static void keyb(int key, int pressed, void *cls);
16 static int parse_args(int argc, char **argv);
17
18 static int quit;
19 static void *fbmem;
20
21 int main(int argc, char **argv)
22 {
23         int num_frames = 0;
24         struct timeval tv, tv0;
25         struct fbgfx_vmode *vm;
26
27         read_config("rbench.cfg");
28
29         if(parse_args(argc, argv) == -1) {
30                 return 1;
31         }
32
33         fbgfx_save_video_mode();
34         if(!(fbmem = fbgfx_set_video_mode(opt.width, opt.height, opt.bpp))) {
35                 fprintf(stderr, "failed to set video mode: %dx%d %dbpp\n", opt.width,
36                                 opt.height, opt.bpp);
37                 return 1;
38         }
39         vm = fbgfx_video_mode_info();
40
41         fb_width = vm->width;
42         fb_height = vm->height;
43         fb_bpp = vm->bpp;
44         fb_pitch = vm->pitch;
45         fb_rmask = vm->rmask;
46         fb_gmask = vm->gmask;
47         fb_bmask = vm->bmask;
48         fb_rshift = vm->rshift;
49         fb_gshift = vm->gshift;
50         fb_bshift = vm->bshift;
51
52         if(!(framebuf = malloc(fb_pitch * fb_height))) {
53                 fprintf(stderr, "failed to allocate %dx%d (%d bpp) framebuffer\n",
54                                 fb_width, fb_height, fb_bpp);
55                 return 1;
56         }
57
58         if(fbev_init() == -1) {
59                 goto end;
60         }
61         fbev_keyboard(keyb, 0);
62
63         if(init() == -1) {
64                 goto end;
65         }
66
67         gettimeofday(&tv0, 0);
68
69         for(;;) {
70                 fbev_update();
71                 if(quit) break;
72
73                 gettimeofday(&tv, 0);
74                 time_msec = (tv.tv_sec - tv0.tv_sec) * 1000 + (tv.tv_usec - tv0.tv_usec) / 1000;
75                 num_frames++;
76
77                 redraw();
78                 memcpy(fbmem, framebuf, fb_pitch * fb_height);
79         }
80
81 end:
82         cleanup();
83         fbev_shutdown();
84         fbgfx_restore_video_mode();
85
86         if(num_frames) {
87                 printf("avg framerate: %.1f fps\n", (10000 * num_frames / time_msec) / 10.0f);
88         }
89         return 0;
90 }
91
92 static void keyb(int key, int pressed, void *cls)
93 {
94         if(!pressed) return;
95
96         if(key == 27 || key == 'q' || key == 'Q') {
97                 quit = 1;
98         }
99 }
100
101
102 static const char *usage_str =
103         "Usage: %s [options]\n"
104         "Options:\n"
105         "  -s <WxH>: resolution\n"
106         "  -b <bpp>: color depth\n"
107         "  -h: print usage and exit\n";
108
109 static int parse_args(int argc, char **argv)
110 {
111         int i;
112
113         for(i=1; i<argc; i++) {
114                 if(argv[i][0] == '-') {
115                         if(argv[i][2]) {
116                                 goto inval_arg;
117                         }
118                         switch(argv[i][1]) {
119                         case 's':
120                                 if(!argv[++i] || sscanf(argv[i], "%dx%d", &opt.width, &opt.height) != 2) {
121                                         fprintf(stderr, "-s must be followed by WxH\n");
122                                         return -1;
123                                 }
124                                 break;
125
126                         case 'b':
127                                 if(!argv[++i] || !(opt.bpp = atoi(argv[i]))) {
128                                         fprintf(stderr, "-b must be followed by the color depth\n");
129                                         return -1;
130                                 }
131                                 break;
132
133                         case 'h':
134                                 printf(usage_str, argv[0]);
135                                 exit(0);
136
137                         default:
138                                 goto inval_arg;
139                         }
140                 } else {
141 inval_arg:      fprintf(stderr, "invalid argument: %s\n", argv[i]);
142                         return -1;
143                 }
144         }
145         return 0;
146 }