optionally source assets from URL
[laserbrain_demo] / src / opt.cc
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <optcfg.h>
5 #include "opt.h"
6
7 Options opt;
8
9 Options def_opt = {
10         1280, 800,
11         false,  // vr
12         false,  // fullscreen
13         0,              // scene file
14         true,   // music
15         true,   // reflections
16         0               // data url
17 };
18
19 enum {
20         OPT_SIZE,
21         OPT_VR,
22         OPT_FULLSCREEN,
23         OPT_WINDOWED,
24         OPT_SCENEFILE,
25         OPT_MUSIC,
26         OPT_REFLECT,
27         OPT_DATAURL,
28         OPT_HELP
29 };
30
31 static optcfg_option options[] = {
32         // short, long, id, desc
33         {'s', "size", OPT_SIZE, "window size (WxH)"},
34         {0, "vr", OPT_VR, "enable VR mode"},
35         {'f', "fullscreen", OPT_FULLSCREEN, "run in fullscreen mode"},
36         {'w', "windowed", OPT_WINDOWED, "run in windowed mode"},
37         {0, "scene", OPT_SCENEFILE, "scene file to open"},
38         {'m', "music", OPT_MUSIC, "play background audio"},
39         {'r', "reflect", OPT_REFLECT, "render reflections"},
40         {0, "url", OPT_DATAURL, "data URL"},
41         {'h', "help", OPT_HELP, "print usage and exit"},
42         OPTCFG_OPTIONS_END
43 };
44
45 static int opt_handler(optcfg *oc, int opt, void *cls);
46 static int arg_handler(optcfg *oc, const char *arg, void *cls);
47
48 bool init_options(int argc, char **argv, const char *cfgfile)
49 {
50         // default options
51         opt = def_opt;
52
53         optcfg *oc = optcfg_init(options);
54         optcfg_set_opt_callback(oc, opt_handler, 0);
55         optcfg_set_arg_callback(oc, arg_handler, 0);
56
57         if(cfgfile) {
58                 optcfg_parse_config_file(oc, cfgfile);
59         }
60
61         if(argv && optcfg_parse_args(oc, argc, argv) == -1) {
62                 fprintf(stderr, "invalid option\n");
63                 optcfg_destroy(oc);
64                 return false;
65         }
66
67         optcfg_destroy(oc);
68         return true;
69 }
70
71 static bool is_enabled(optcfg *oc)
72 {
73         int res;
74         optcfg_enabled_value(oc, &res);
75         return res != 0;
76 }
77
78 static int opt_handler(optcfg *oc, int optid, void *cls)
79 {
80         switch(optid) {
81         case OPT_SIZE:
82                 {
83                         char *valstr = optcfg_next_value(oc);
84                         if(!valstr || sscanf(valstr, "%dx%d", &opt.width, &opt.height) != 2) {
85                                 fprintf(stderr, "size must be in the form: WIDTHxHEIGHT\n");
86                                 return -1;
87                         }
88                 }
89                 break;
90
91         case OPT_VR:
92                 opt.vr = is_enabled(oc);
93                 break;
94
95         case OPT_FULLSCREEN:
96                 opt.fullscreen = is_enabled(oc);
97                 break;
98
99         case OPT_WINDOWED:
100                 opt.fullscreen = !is_enabled(oc);
101                 break;
102
103         case OPT_SCENEFILE:
104                 opt.scenefile = strdup(optcfg_next_value(oc));
105                 break;
106
107         case OPT_MUSIC:
108                 opt.music = is_enabled(oc);
109                 break;
110
111         case OPT_REFLECT:
112                 opt.reflect = is_enabled(oc);
113                 break;
114
115         case OPT_DATAURL:
116                 opt.data_url = strdup(optcfg_next_value(oc));
117                 break;
118
119         case OPT_HELP:
120                 printf("Usage: demo [options]\nOptions:\n");
121                 optcfg_print_options(oc);
122                 exit(0);
123         }
124         return 0;
125 }
126
127 static int arg_handler(optcfg *oc, const char *arg, void *cls)
128 {
129         if(opt.scenefile) {
130                 fprintf(stderr, "unexpected argument: %s\n", arg);
131                 return -1;
132         }
133         opt.scenefile = arg;
134         return 0;
135 }