writing a mesh abstraction
[vrtris] / src / opt.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "optcfg.h"
5 #include "opt.h"
6
7
8 struct options def_opt = { 1024, 768, 0, "game" };
9
10 enum {
11         OPTCFG_SIZE,
12         OPTCFG_VR,
13         OPTCFG_FULLSCREEN,
14         OPTCFG_WINDOWED,
15         OPTCFG_SCREEN,
16         OPTCFG_HELP
17 };
18
19 static struct optcfg_option options[] = {
20         // short, long, id, desc
21         {'s', "size", OPTCFG_SIZE, "window size (WxH)"},
22         {0, "vr", OPTCFG_VR, "enable VR mode"},
23         {'f', "fullscreen", OPTCFG_FULLSCREEN, "run in fullscreen mode"},
24         {'w', "windowed", OPTCFG_WINDOWED, "run in windowed mode"},
25         {0, "screen", OPTCFG_SCREEN, "select starting screen"},
26         {'h', "help", OPTCFG_HELP, "print usage and exit"},
27         OPTCFG_OPTIONS_END
28 };
29
30 static int opt_handler(struct optcfg *oc, int opt, void *cls);
31 static int arg_handler(struct optcfg *oc, const char *arg, void *cls);
32
33 static char *argv0;
34
35 int init_options(int argc, char **argv, const char *cfgfile)
36 {
37         struct optcfg *oc;
38
39         /* default options */
40         opt = def_opt;
41
42         argv0 = argv[0];
43
44         oc = optcfg_init(options);
45         optcfg_set_opt_callback(oc, opt_handler, 0);
46         optcfg_set_arg_callback(oc, arg_handler, 0);
47
48         if(cfgfile) {
49                 optcfg_parse_config_file(oc, cfgfile);
50         }
51
52         if(argv && optcfg_parse_args(oc, argc, argv) == -1) {
53                 fprintf(stderr, "invalid option\n");
54                 optcfg_destroy(oc);
55                 return -1;
56         }
57
58         optcfg_destroy(oc);
59         return 0;
60 }
61
62 static int is_enabled(struct optcfg *oc)
63 {
64         int res;
65         optcfg_enabled_value(oc, &res);
66         return res != 0;
67 }
68
69 static int opt_handler(struct optcfg *oc, int optid, void *cls)
70 {
71         char *valstr;
72
73         switch(optid) {
74         case OPTCFG_SIZE:
75                 valstr = optcfg_next_value(oc);
76                 if(!valstr || sscanf(valstr, "%dx%d", &opt.width, &opt.height) != 2) {
77                         fprintf(stderr, "size must be of the form: WIDTHxHEIGHT\n");
78                         return -1;
79                 }
80                 break;
81
82         case OPTCFG_VR:
83                 if(is_enabled(oc)) {
84                         opt.flags |= OPT_VR;
85                 } else {
86                         opt.flags &= ~OPT_VR;
87                 }
88                 break;
89
90         case OPTCFG_FULLSCREEN:
91                 if(is_enabled(oc)) {
92                         opt.flags |= OPT_FULLSCREEN;
93                 } else {
94                         opt.flags &= ~OPT_FULLSCREEN;
95                 }
96                 break;
97
98         case OPTCFG_WINDOWED:
99                 if(is_enabled(oc)) {
100                         opt.flags &= ~OPT_FULLSCREEN;
101                 } else {
102                         opt.flags |= OPT_FULLSCREEN;
103                 }
104                 break;
105
106         case OPTCFG_SCREEN:
107                 if(!(valstr = optcfg_next_value(oc))) {
108                         fprintf(stderr, "screen name missing\n");
109                         return -1;
110                 }
111                 free(opt.start_scr);
112                 if(!(opt.start_scr = malloc(strlen(valstr) + 1))) {
113                         perror("failed to allocate memory");
114                         return -1;
115                 }
116                 strcpy(opt.start_scr, valstr);
117                 break;
118
119         case OPTCFG_HELP:
120                 printf("Usage: %s [options]\nOptions:\n", argv0);
121                 optcfg_print_options(oc);
122                 exit(0);
123         }
124         return 0;
125 }
126
127 static int arg_handler(struct optcfg *oc, const char *arg, void *cls)
128 {
129         fprintf(stderr, "unexpected argument: %s\n", arg);
130         return -1;
131 }