1 /*
2 * SDLRoids - An Astroids clone.
3 *
4 * Copyright (c) 2000 David Hedbor <david@hedbor.org>
5 * based on xhyperoid by Russel Marks.
6 * xhyperoid is based on a Win16 game, Hyperoid by Edward Hutchins
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16 *
17 */
18
19 /*
20 * getargs.c - Get / parse command line arguments.
21 */
22
23 #include "config.h"
24 RCSID("$Id: getargs.c,v 1.4 2000/10/25 07:55:34 neotron Exp $");
25
26 #include <stdio.h>
27 #include <string.h>
28 #include <stdlib.h>
29
30 #include "getargs.h"
31 #include "petopt.h"
32
33 /* Storage for boolean variables */
34 int flagargs[NUMARGS];
35
36 static PETOPTS pov[] =
37 {
38 { 'f', POF_NONE, "fullscreen", NULL,
39 "Start in fullscreen mode." },
40 { 'g', POF_STR, "geometry", NULL,
41 "Open a window of the specified size. ARG\n"
42 " is specified as HEIGHTxWIDTH." },
43 { 'b', POF_INT, "benchmark", &ARG_BENCH,
44 "Run in benchmark mode. Display ARG frames\n"
45 " without delay and quit." },
46 { 's', POF_NONE, "nosound", NULL,
47 "Don't initialize the sound." },
48 { 'l', POF_NONE, "list-joysticks",NULL,
49 "Exit after listing all the joysticks." },
50 { 'n', POF_INT, "joynr", &ARG_JOYNUM,
51 "The index of the joystick to use. All\n"
52 " available joysticks are listed\n"
53 " SDLRoids starts." },
54 { 'j', POF_STR, "joystick", NULL,
55 "Force the use of this joystick device. If\n"
56 " valid, it will become joystick 0." },
57 { '0', POF_INT, "fire", &ARG_JFIRE,
58 "Button for firing main guns. Default = 0."},
59 { '1', POF_INT, "shields", &ARG_JSHIELD,
60 "Button for enabling shields. Default=1." },
61 { '2', POF_INT, "bomb", &ARG_JBOMB,
62 "Button for firing smartbomb. Default=2." },
63 { 'h', POF_NONE, "help", NULL,
64 "Print usage information and exit." },
65 { 'v', POF_NONE, "version", NULL,
66 "Print version number and exit." },
67 { -1, 0, NULL, NULL, NULL }
68 };
69
70
71 /*
72 * Parse individual options.
73 * Valid return values:
74 * <0. ...... Some error occured
75 * 0 ....... Option parsed and stored ok
76 * 1 ....... Option parsed, use builtin store function
77 */
parse_option(PETOPT * pp,PETOPTS * pov,const char * arg)78 static int parse_option(PETOPT *pp, PETOPTS *pov, const char *arg)
79 {
80 switch (pov->s)
81 {
82 case 'h':
83 printf("Usage: %s [options]\n\n", pp->argv[0]);
84 petopt_print_usage(pp, stdout);
85 printf("\nShip control keys:\n"
86 " Cursor Left/Right Spin the ship left or right.\n"
87 " Cursor Up/Down Forward or reverse thrust.\n"
88 " Space Fire guns.\n"
89 " Tab Use shields.\n"
90 " s Use smartbomb (kill all enemy ships).\n"
91 "\nOther keys:\n"
92 " Esc or q Quit the game.\n"
93 " Pause Pause / unpause the game.\n"
94 " F1 Start a new game.\n");
95
96 exit(0);
97
98 case 'l':
99 ARG_JLIST=1;
100 return 0;
101 case 'f':
102 ARG_FSCRN=1;
103 return 0;
104 case 's':
105 ARG_NOSND=1;
106 return 0;
107
108 case 'b':
109 printf("Running in benchmark mode (%s frames)\n", arg);
110 return 1;
111
112 case 'v':
113 printf("SDLRoids "VERSION" by David Hedbor <david@hedbor.org>.\n\n"
114 "Based on xhyperoid 1.2 by Russel Marks <russell.marks@ntlworld.com>\n"
115 "which is based on hyperoid 1.1 by Edward Hutchins.\n");
116 exit(0);
117 case 'j':
118 #ifdef HAVE_SETENV
119 setenv("SDL_JOYSTICK_DEVICE", arg, 1);
120 #else
121 fprintf(stderr,
122 "*** setenv() function missing. To change the device\n"
123 "*** set the environment variable SDL_JOYSTICK_DEVICE\n"
124 "*** to the path to your joystick.\n");
125 #endif
126 break;
127 case 'g':
128 if(sscanf(arg, "%dx%d", &ARG_WIDTH, &ARG_HEIGHT) != 2)
129 {
130 fprintf(stderr,
131 "%s: Invalid geometry specification. Should be WIDTHxHEIGHT.\n",
132 pp->argv[0]);
133 exit(2);
134 } else {
135 if(ARG_WIDTH < 30 || ARG_HEIGHT < 30)
136 {
137 fprintf(stderr,
138 "%s: Too small window. Minimum size is 30x30.\n",
139 pp->argv[0]);
140 exit(2);
141 }
142 return 0;
143 }
144 default:
145 return 1;
146 }
147
148 return 0;
149 }
150
print_error(PETOPT * pop,PETOPTS * pov,int err,FILE * fp)151 static int print_error(PETOPT *pop, PETOPTS *pov, int err, FILE *fp)
152 {
153 char buf[3];
154 const char *arg;
155
156
157 if (pop->saved_ci > 0)
158 {
159 buf[0] = '-';
160 buf[1] = pop->argv[pop->saved_ai][pop->saved_ci];
161 buf[2] = '\0';
162 arg = buf;
163 } else {
164 arg = pop->argv[pop->saved_ai];
165 if (arg == NULL)
166 arg = "";
167 }
168
169 switch (err)
170 {
171 case POE_EOF:
172 return 0;
173
174 case POE_OPTION:
175 fprintf(fp, "Unrecognized option: %s.\n"
176 "Run '%s -h' for more information.\n",
177 arg, pop->argv[0]);
178 break;
179
180 case POE_MULTI:
181 fprintf(fp, "%s: Ambiguous option: %s\n",
182 pop->argv[0], arg);
183 break;
184
185 case POE_MISSING:
186 fprintf(fp, "Missing argument for option: %s\n"
187 "Run '%s -h' for more information.\n",
188 arg, pop->argv[0]);
189 break;
190
191 case POE_INVALID:
192 fprintf(fp, "%s: Invalid argument for option: %s\n",
193 pop->argv[0], arg);
194 break;
195
196 case POE_INTERNAL:
197 fprintf(fp, "%s: Internal error parsing option: %s\n",
198 pop->argv[0], arg);
199 break;
200
201 default:
202 fprintf(fp, "%s: Internal options parsing error: #%d\n",
203 pop->argv[0], err);
204 }
205 return -1;
206 }
207
208 /* Get all command line options using petopt */
getargs(int argc,char * argv[])209 void getargs(int argc, char *argv[])
210 {
211 int err;
212 PETOPT *pop;
213 memset(flagargs, 0, sizeof(flagargs));
214 ARG_JSHIELD = 1; /* Default shield button */
215 ARG_JBOMB = 2; /* Default smartbomb button */
216 err = petopt_setup(&pop, 0, argc, argv, pov, parse_option, print_error);
217 if (err)
218 {
219 if (err > 0) fprintf(stderr, "petopt_setup: %s\n", strerror(err));
220 exit(1);
221 }
222 err = petopt_parse(pop, &argc, &argv);
223 if (err)
224 {
225 if (err > 0) fprintf(stderr, "petopt_parse: %s\n", strerror(err));
226 exit(1);
227 }
228
229 err = petopt_cleanup(pop);
230 if (err)
231 {
232 if (err > 0)
233 fprintf(stderr, "petopt_cleanup: %s\n", strerror(err));
234 exit(1);
235 }
236 }
237