JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
9a3510bc8bf1e65bcb973f097c576cd0c435f47b
[vor.git] / args.c
1 #include <string.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include "args.h"
5 #include "config.h"
6
7 // Gameplay Variations
8 float opt_bounciness;
9 float opt_gamespeed;
10 float opt_max_lead;
11
12 // Look and Feel
13 int opt_fullscreen;
14 int opt_music;
15 int opt_sound;
16
17 static void
18 show_help(void)
19 {
20         puts("Dodge the rocks until you die.");
21         putchar('\n');
22         puts(" Gameplay Variations:");
23     puts("  -b, --bounciness=N%        Keep N% of speed when hitting edges (default 50%)");
24         puts("  -g, --game-speed=N%        50-200% (default 100%)");
25         putchar('\n');
26         puts(" Look and Feel:");
27         puts("  -f, --full-screen");
28         puts("  -m, --music                Enable music");
29         puts("  -s, --silent               No explosion sounds or music");
30         putchar('\n');
31         puts(" Informational:");
32         puts("  -?, --help                 Give this help list");
33         puts("  -V, --version              Print program version");
34         putchar('\n');
35         puts("Mandatory or optional arguments to long options are also mandatory or optional");
36         puts("for any corresponding short options.");
37         putchar('\n');
38         puts("Report bugs at http://jasonwoof.com/contact.html");
39 }
40
41 int
42 short_opt(char c, char *arg)
43 {
44         int i;
45
46         switch(c) {
47                 case 'b': if(!arg || sscanf(arg, "%d%%", &i) != 1 || i < 0 || i > 100) {
48                                           fprintf(stderr, "bad --bounciness (-b) value (should be 0-100%%)\n\n");
49                                           return 0;
50                                   }
51                                   opt_bounciness = (float)i / 100;
52                                   *arg = 0;
53                                   break;
54                 case 'f': opt_fullscreen = 1; break;
55                 case 'g': if(!arg || sscanf(arg, "%d%%", &i) != 1 || i < 50 || i > 200) {
56                                           fprintf(stderr, "bad --game-speed (-g) value (should be 50-200%%)\n\n");
57                                           return 0;
58                                   }
59                                   opt_gamespeed = (float)i / 100;
60                                   *arg = 0;
61                                   break;
62                 case 'l': if(sscanf(arg, "%f", &opt_max_lead) != 1) {
63                                           fprintf(stderr, "bad --max-lead (-l) value (must be a number)\n\n");
64                                           return 0;
65                                   }
66                                   opt_max_lead *= XSIZE;
67                                   *arg = 0;
68                                   break;
69                 case 'm': opt_music = 1; break;
70                 case 's': opt_sound = 0; opt_music = 0; break;
71                 case 'V':
72                                   printf("Variations on Rockdodger %s\n", VERSION);
73                                   exit(0);
74                 case '?':
75                 case 'h': return 0;
76                 default: 
77                                   fprintf(stderr, "unknown option -%c\n\n", c);
78                                   return 0;
79         }
80         return 1;
81 }
82
83 int
84 parse_short_opts(const char *s, char *arg)
85 {
86         while(s[1]) if(!short_opt(*s++, NULL)) return 0;
87         return short_opt(*s, arg);
88 }
89
90 static char *long_opts[] = {
91         "bounciness", "game-speed",
92         "full-screen", "music", "silent",
93         "help", "version"
94 };
95
96 static char short_opts[] = {
97         'b', 'g',
98         'f', 'm', 's',
99         'h', 'V'
100 };
101
102 int
103 parse_long_opt(const char *s, char *arg)
104 {
105         int i;
106         for(i=0; i<sizeof(short_opts); i++) {
107                 if(strcmp(s, long_opts[i]) == 0)
108                         return short_opt(short_opts[i], arg);
109         }
110         fprintf(stderr, "unknown long option --%s\n\n", s);
111         return 0;
112 }
113
114 void
115 init_opts(void)
116 {
117         // Gameplay Variations
118         opt_bounciness = 0.50; // lose 50% when you hit the screen edge.
119         opt_gamespeed = 1.00; // Run game at full speed.
120         opt_max_lead = 1.00*XSIZE;  // you can get 1 screen ahead.
121
122         // Look and Feel
123         opt_fullscreen = 0;
124         opt_sound = 1;
125         opt_music = 1;
126 }
127
128 int
129 parse_opts(int argc, char *argv[])
130 {
131         int i;
132         char *r;
133
134         init_opts();
135         for(i=1; i<argc; i++) {
136                 char *s, *arg;
137                 s = argv[i]; if(!*s) continue;
138                 if(*s++ != '-') {
139                         fputs("not an option\n\n", stderr);
140                         show_help();
141                         return 0;
142                 }
143
144                 arg = NULL;
145                 for(r=s; *r; r++) if(*r == '=') { *r = 0; arg = r+1; break; }
146                 if(!arg && (i+1 < argc)) arg = argv[i+1];
147
148                 if(*s == '-') {
149                         if(!parse_long_opt(s+1, arg)) { show_help(); return 0; }
150                 } else {
151                    if(!parse_short_opts(s, arg)) { show_help(); return 0; }
152                 }
153         }
154         return 1;
155 }