1 /*
2  * CRRCsim - the Charles River Radio Control Club Flight Simulator Project
3  *
4  * Copyright (C) 2004 Kees Lemmens (original author)
5  * Copyright (C) 2004, 2005, 2008 Jens Wilhelm Wulf
6  * Copyright (C) 2005, 2006, 2007, 2008, 2009 Jan Reucker
7  * Copyright (C) 2005 Lionel Cailler
8  * Copyright (C) 2006 Todd Templeton
9  * Copyright (C) 2008 Olivier Bordes
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License version 2
13  * as published by the Free Software Foundation.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330,
23  * Boston, MA 02111-1307, USA.
24  *
25  */
26 
27 
28 #include <unistd.h>
29 
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <ctype.h>
33 
34 #include <crrc_config.h>
35 
36 extern char   *optarg;
37 extern int    optind;
38 
39 #include "../global.h"
40 #include "../crrc_main.h"
41 
42 // Prototypes for local functions
43 static void crrc_version_info();
44 static void crrc_usage(char *progname);
45 
46 #define OPTION_STRING "b:c:d:fg:hi:j:l:m:s:u:vVw:x:y:"
47 
48 /**
49  * Print usage information and exit
50  *
51  * \param progname The name as which the program was called.
52  */
crrc_usage(char * progname)53 static void crrc_usage(char *progname)
54 {
55   fprintf(stderr,"\nUsage  : %s [options] [<plane>]\n",progname);
56   fprintf(stderr,"\nNote that these options override default settings in crrcsim.xml !\n");
57   fprintf(stderr,  "Options:\n");
58   fprintf(stderr,  "         -h             : display this message\n");
59   fprintf(stderr,  "         -l <string>    : location/scenery file with path (e.g. scenery/davis-orig.xml)\n");
60   fprintf(stderr,  "                          Use this option before others, otherwise they might be overwritten.\n");
61   fprintf(stderr,  "         -b <nr:string> : joystick buttonnr function: RESUME|RESET|PAUSE|ZOOMIN|ZOOMOUT|INCTHROTTLE|DECTHROTTLE\n");
62   fprintf(stderr,  "         -c <value>     : color_depth in bits per pixel\n");
63   fprintf(stderr,  "         -d <value>     : wind direction in deg (0-360)\n");
64   fprintf(stderr,  "         -f             : use fullscreen\n");
65   fprintf(stderr,  "         -g <string>    : specify config file\n");
66   fprintf(stderr,  "         -i <string>    : input method : KEYBOARD|MOUSE|JOYSTICK|RCTRAN|SERIAL2|PARALLEL|AUDIO|MNAV|ZHENHUA\n");
67   fprintf(stderr,  "         -m <string>    : mouse x motion : AILERON|RUDDER\n");
68   fprintf(stderr,  "         -s <on/off>    : sound on/off\n");
69   fprintf(stderr,  "         -u <on/off>    : user interface on/off\n");
70   fprintf(stderr,  "         -w <value>     : wind velocity in ft/sec\n");
71   fprintf(stderr,  "         -x <value>     : x_resolution in pixels\n");
72   fprintf(stderr,  "         -y <value>     : y_resolution in pixels\n");
73   fprintf(stderr,  "         -v             : Show input values\n");
74   fprintf(stderr,  "         -v             : Show current field of view\n");
75   fprintf(stderr,  "         -v             : Show frames per second\n");
76   fprintf(stderr,  "         -V             : print version info and exit\n");
77   fprintf(stderr, "\n");
78 }
79 
80 /**
81  * returns
82  *   0  everything OK, let's start
83  *  -1  exit with error
84  */
crrc_checkopts(int argc,char * argv[],SimpleXMLTransfer * cfgfile,T_Config * cfg)85 int crrc_checkopts (int                argc,
86                     char*              argv[],
87                     SimpleXMLTransfer* cfgfile,
88                     T_Config*          cfg)  /* check and set options flags */
89 {
90   int c;
91   int buttonnr;
92   int opt_err = 0;
93   int new_res_x = 0;
94   int new_res_y = 0;
95 
96   while ((c = getopt(argc, argv, OPTION_STRING)) != -1)
97   {
98     switch (c)
99     {
100       case 'b':
101         if (! isdigit(optarg[0]) || optarg[1] != ':')
102         {
103           opt_err = 1;
104           break;
105         }
106         buttonnr=atoi(optarg);
107         if(buttonnr > MAXJOYBUTTON)
108         {
109           fprintf(stderr, "illegal button nr: %d\n", buttonnr);
110           crrc_exit(CRRC_EXIT_FAILURE,"");
111         }
112         optarg += 2;
113         if (strcasecmp(optarg,"RESUME")==0)
114           Global::inputDev->joystick_bind_b[buttonnr] = TInputDev::RESUME;
115         else if (strcasecmp(optarg,"RESET")==0)
116           Global::inputDev->joystick_bind_b[buttonnr] = TInputDev::RESET;
117         else if (strcasecmp(optarg,"PAUSE")==0)
118           Global::inputDev->joystick_bind_b[buttonnr] = TInputDev::PAUSE;
119         else if (strcasecmp(optarg,"DECTHROTTLE")==0)
120           Global::inputDev->joystick_bind_b[buttonnr] = TInputDev::DECTHROTTLE;
121         else if (strcasecmp(optarg,"INCTHROTTLE")==0)
122           Global::inputDev->joystick_bind_b[buttonnr] = TInputDev::INCTHROTTLE;
123         else if (strcasecmp(optarg,"ZOOMIN")==0)
124           Global::inputDev->joystick_bind_b[buttonnr] = TInputDev::ZOOMIN;
125         else if (strcasecmp(optarg,"ZOOMOUT")==0)
126           Global::inputDev->joystick_bind_b[buttonnr] = TInputDev::ZOOMOUT;
127         break;
128       case 'c':
129         cfgfile->setAttributeOverwrite("video.color_depth", optarg);
130         break;
131       case 'd':
132         cfg->wind->setDirection((float)atof(optarg), cfg);
133         break;
134       case 'f':
135         cfgfile->setAttributeOverwrite("video.fullscreen.fUse", "1");
136         break;
137       case 'g':
138         // handled in crrc_main.cpp before this is called
139         break;
140       case 'h':
141         crrc_usage(argv[0]);
142         crrc_exit(CRRC_EXIT_SUCCESS,"");
143         break;
144       case 'i':
145         cfgfile->setAttributeOverwrite("inputMethod.method", optarg);
146         break;
147       case 'l': /* airport location */
148         cfg->setLocation(optarg, cfgfile);
149         break;
150       case 'm':
151         if (strcasecmp(optarg,"AILERON")==0)
152           Global::inputDev->mouse_bind_x = T_AxisMapper::AILERON;
153         else if (strcasecmp(optarg,"RUDDER")==0)
154           Global::inputDev->mouse_bind_x = T_AxisMapper::RUDDER;
155         break;
156       case 's':
157         if      (strcasecmp(optarg,"ON")==0)
158           cfgfile->setAttributeOverwrite("sound.enabled", "1");
159         if      (strcasecmp(optarg,"OFF")==0)
160           cfgfile->setAttributeOverwrite("sound.enabled", "0");
161         break;
162       case 'u':
163         if      (strcasecmp(optarg,"ON")==0)
164           cfgfile->setAttributeOverwrite("video.enabled", "1");
165         if      (strcasecmp(optarg,"OFF")==0)
166           cfgfile->setAttributeOverwrite("video.enabled", "0");
167         break;
168       case 'v':
169         Global::nVerbosity++;
170         break;
171       case 'w':
172         cfg->wind->setVelocity((float)atof(optarg));
173         break;
174       case 'x':
175         new_res_x = atoi(optarg);
176         break;
177       case 'y':
178         new_res_y = atoi(optarg);
179         break;
180       case 'V':
181         // should already be evaluated
182         break;
183       default:
184         opt_err = 1;
185     }
186 
187     if (opt_err)
188     {
189       crrc_usage(argv[0]);
190       return(-1);
191     }
192   }
193 
194   // x and y resolution must be stored after all other flags have
195   // been evaluated to make sure that we really know if the user
196   // wants fullscreen or windowed mode.
197   int use_fullscreen = cfgfile->getInt("video.fullscreen.fUse", 0);
198   if (new_res_x > 0)
199   {
200     if (use_fullscreen)
201     {
202       cfgfile->setAttributeOverwrite("video.resolution.fullscreen.x", new_res_x);
203     }
204     else
205     {
206       cfgfile->setAttributeOverwrite("video.resolution.window.x", new_res_x);
207     }
208   }
209   if (new_res_y > 0)
210   {
211     if (use_fullscreen)
212     {
213       cfgfile->setAttributeOverwrite("video.resolution.fullscreen.y", new_res_y);
214     }
215     else
216     {
217       cfgfile->setAttributeOverwrite("video.resolution.window.y", new_res_y);
218     }
219   }
220 
221   if (argc - optind > 0)
222   {
223     cfgfile->setAttributeOverwrite("airplane.file", argv[optind]);
224   }
225 
226   return 0;
227 }
228 
229 
230 /**
231  * This function checks if the "print version" option
232  * was given on the command line.
233  * \param argc  Number of arguments as passed to main()
234  * \param argv  List of arguments as passed to main()
235  *
236  * \retval true   -V option was found and version info was printed
237  * \retval false  -V option was not found
238  */
crrc_checkversionopt(int argc,char * argv[])239 bool crrc_checkversionopt(int argc, char* argv[])
240 {
241   int c;
242   bool boFoundV = false;
243 
244   while ((c = getopt(argc, argv, OPTION_STRING)) != -1)
245   {
246     if (c == 'V')
247     {
248       crrc_version_info();
249       boFoundV = true;
250     }
251   }
252 
253   // reset option index for the second parser run
254   optind = 1;
255 
256   return boFoundV;
257 }
258 
259 
260 /**
261  * Print version and configuration information
262  */
crrc_version_info()263 static void crrc_version_info()
264 {
265   std::cout << "CRRCsim ";
266 
267   if (std::string(PACKAGE_VERSION).compare("dev") == 0)
268   {
269     std::cout << "(development build, " << __DATE__ << ")";
270   }
271   else
272   {
273     std::cout << PACKAGE_VERSION;
274   }
275   std::cout << std::endl << std::endl;
276 
277   std::cout << "Configuration options:" << std::endl;
278 
279   // Portaudio library options
280   #if PORTAUDIO > 0
281   std::cout << "  audo interface supported (Portaudio V" << PORTAUDIO << ")";
282   #else
283   std::cout << "  audio interface not support";
284   #endif
285   std::cout << std::endl;
286 
287   // Mouse wheel support
288   #ifdef SDL_WITHOUT_MOUSEWHEEL
289   std::cout << "  mouse wheel not supported";
290   #else
291   std::cout << "  mouse wheel supported";
292   #endif
293   std::cout << std::endl;
294 
295   // Wind data import support
296   #if WINDDATA3D > 0
297   std::cout << "  wind data import supported";
298   #else
299   std::cout << "  wind data import not supported";
300   #endif
301   std::cout << std::endl;
302 }
303