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