updated readme
[andemo] / src / cfgopt.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <ctype.h>
5 #include "cfgopt.h"
6
7 #ifdef NDEBUG
8 /* release default options */
9 #define DEFOPT_FULLSCR  1
10 #define DEFOPT_VSYNC    1
11 #define DEFOPT_MUSIC    1
12 #else
13 /* debug default options */
14 #define DEFOPT_FULLSCR  0
15 #define DEFOPT_VSYNC    1
16 #define DEFOPT_MUSIC    0
17 #endif
18
19 struct options opt = {
20         0,      /* screen name */
21         DEFOPT_FULLSCR,
22         DEFOPT_VSYNC,
23         DEFOPT_MUSIC
24 };
25
26 static const char *usagefmt = "Usage: %s [options]\n"
27         "Options:\n"
28         "  -music/-nomusic      toggle music playback\n"
29         "  -scr,-screen <name>  ignore demoscript, run specific screen\n"
30         "  -fs/-win             run fullscreen/windowed\n"
31         "  -vsync/-novsync      toggle vsync\n"
32         "  -h,-help             print usage and exit\n";
33
34 int parse_args(int argc, char **argv)
35 {
36         int i;
37         char *scrname = 0;
38
39         for(i=1; i<argc; i++) {
40                 if(argv[i][0] == '-') {
41                         if(strcmp(argv[i], "-music") == 0) {
42                                 opt.music = 1;
43                         } else if(strcmp(argv[i], "-nomusic") == 0) {
44                                 opt.music = 0;
45                         } else if(strcmp(argv[i], "-scr") == 0 || strcmp(argv[i], "-screen") == 0) {
46                                 scrname = argv[++i];
47                         } else if(strcmp(argv[i], "-vsync") == 0) {
48                                 opt.vsync = 1;
49                         } else if(strcmp(argv[i], "-novsync") == 0) {
50                                 opt.vsync = 0;
51                         } else if(strcmp(argv[i], "-fs") == 0) {
52                                 opt.fullscreen = 1;
53                         } else if(strcmp(argv[i], "-win") == 0) {
54                                 opt.fullscreen = 0;
55                         } else if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-help") == 0) {
56                                 printf(usagefmt, argv[0]);
57                                 exit(0);
58                         } else {
59                                 fprintf(stderr, "invalid option: %s\n", argv[i]);
60                                 fprintf(stderr, usagefmt, argv[0]);
61                                 return -1;
62                         }
63                 } else {
64                         if(scrname) {
65                                 fprintf(stderr, "unexpected option: %s\n", argv[i]);
66                                 fprintf(stderr, usagefmt, argv[0]);
67                                 return -1;
68                         }
69                         scrname = argv[i];
70                 }
71         }
72
73         if(scrname) {
74                 opt.scrname = scrname;
75         }
76         return 0;
77 }
78
79
80 static char *strip_space(char *s)
81 {
82         int len;
83         char *end;
84
85         while(*s && isspace(*s)) ++s;
86         if(!*s) return 0;
87
88         if((end = strrchr(s, '#'))) {
89                 --end;
90         } else {
91                 len = strlen(s);
92                 end = s + len - 1;
93         }
94
95         while(end > s && isspace(*end)) *end-- = 0;
96         return end > s ? s : 0;
97 }
98
99 static int bool_value(char *s)
100 {
101         char *ptr = s;
102         while(*ptr) {
103                 *ptr = tolower(*ptr);
104                 ++ptr;
105         }
106
107         return strcmp(s, "true") == 0 || strcmp(s, "yes") == 0 || strcmp(s, "1") == 0;
108 }
109
110 int load_config(const char *fname)
111 {
112         FILE *fp;
113         char buf[256];
114         int nline = 0;
115
116         if(!(fp = fopen(fname, "rb"))) {
117                 return 0;       /* just ignore missing config files */
118         }
119
120         while(fgets(buf, sizeof buf, fp)) {
121                 char *line, *key, *value;
122
123                 ++nline;
124                 if(!(line = strip_space(buf))) {
125                         continue;
126                 }
127
128                 if(!(value = strchr(line, '='))) {
129                         fprintf(stderr, "%s:%d invalid key/value pair\n", fname, nline);
130                         return -1;
131                 }
132                 *value++ = 0;
133
134                 if(!(key = strip_space(line)) || !(value = strip_space(value))) {
135                         fprintf(stderr, "%s:%d invalid key/value pair\n", fname, nline);
136                         return -1;
137                 }
138
139                 if(strcmp(line, "music") == 0) {
140                         opt.music = bool_value(value);
141                 } else if(strcmp(line, "screen") == 0) {
142                         opt.scrname = strdup(value);
143                 } else if(strcmp(line, "vsync") == 0) {
144                         opt.vsync = bool_value(value);
145                 } else if(strcmp(line, "fullscreen") == 0) {
146                         opt.fullscreen = bool_value(value);
147                 } else {
148                         fprintf(stderr, "%s:%d invalid option: %s\n", fname, nline, line);
149                         return -1;
150                 }
151         }
152         return 0;
153 }