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