2 // options.cxx -- class to handle command line options
4 // Written by Curtis Olson, started April 1998.
6 // Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
8 // This program is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU General Public License as
10 // published by the Free Software Foundation; either version 2 of the
11 // License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful, but
14 // WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 // (Log is kept at end of this file)
30 #include <math.h> // rint()
32 #include <stdlib.h> // atof(), atoi()
35 #include <Debug/fg_debug.h>
36 #include <Include/fg_zlib.h>
38 #include "options.hxx"
41 // Defined the shared options class here
42 fgOPTIONS current_options;
46 fgOPTIONS::fgOPTIONS( void ) {
47 // set initial values/defaults
49 if ( getenv("FG_ROOT") != NULL ) {
50 // fg_root could be anywhere, so default to environmental
51 // variable $FG_ROOT if it is set.
53 strcpy(fg_root, getenv("FG_ROOT"));
55 // Otherwise, default to a random compiled in location if
56 // $FG_ROOT is not set. This can still be overridden from the
57 // command line or a config file.
60 strcpy(fg_root, "\\FlightGear");
62 strcpy(fg_root, "/usr/local/lib/FlightGear");
67 strcpy(airport_id, "");
89 // Parse an int out of a --foo-bar=n type option
90 static int parse_int(char *arg) {
93 // advance past the '='
94 while ( (arg[0] != '=') && (arg[0] != '\0') ) {
98 if ( arg[0] == '=' ) {
102 printf("parse_int(): arg = %s\n", arg);
106 printf("parse_int(): result = %d\n", result);
112 // Parse an int out of a --foo-bar=n type option
113 static double parse_double(char *arg) {
116 // advance past the '='
117 while ( (arg[0] != '=') && (arg[0] != '\0') ) {
121 if ( arg[0] == '=' ) {
125 printf("parse_double(): arg = %s\n", arg);
129 printf("parse_double(): result = %.4f\n", result);
135 // parse time string in the form of [+-]hh:mm:ss, returns the value in seconds
136 static double parse_time(char *time_str) {
138 double hours, minutes, seconds;
143 // printf("parse_time(): %s\n", time_str);
146 if ( strlen(time_str) ) {
147 if ( time_str[0] == '+' ) {
150 } else if ( time_str[0] == '-' ) {
155 // printf("sign = %d\n", sign);
158 if ( strlen(time_str) ) {
160 while ( (time_str[0] != ':') && (time_str[0] != '\0') ) {
161 num[i] = time_str[0];
165 if ( time_str[0] == ':' ) {
170 // printf("hours = %.2lf\n", hours);
172 result += hours * 3600.0;
176 if ( strlen(time_str) ) {
178 while ( (time_str[0] != ':') && (time_str[0] != '\0') ) {
179 num[i] = time_str[0];
183 if ( time_str[0] == ':' ) {
188 // printf("minutes = %.2lf\n", minutes);
190 result += minutes * 60.0;
194 if ( strlen(time_str) ) {
196 while ( (time_str[0] != ':') && (time_str[0] != '\0') ) {
197 num[i] = time_str[0];
203 // printf("seconds = %.2lf\n", seconds);
208 return(sign * result);
212 // parse time offset command line option
213 static int parse_time_offset(char *time_str) {
218 // printf("time offset = %s\n", time_str);
221 result = (int)rint(parse_time(time_str));
223 result = (int)parse_time(time_str);
226 printf("parse_time_offset(): %d\n", result);
232 // Parse --tile-radius=n type option
234 #define FG_RADIUS_MIN 3
235 #define FG_RADIUS_MAX 9
237 static int parse_tile_radius(char *arg) {
240 radius = parse_int(arg);
242 // radius must be odd
244 if ( radius == ( tmp * 2 ) ) {
248 if ( radius < FG_RADIUS_MIN ) { radius = FG_RADIUS_MIN; }
249 if ( radius > FG_RADIUS_MAX ) { radius = FG_RADIUS_MAX; }
251 printf("parse_tile_radius(): radius = %d\n", radius);
257 // Parse --fov=x.xx type option
259 #define FG_FOV_MIN 0.1
260 #define FG_FOV_MAX 179.9
262 static double parse_fov(char *arg) {
265 fov = parse_double(arg);
267 if ( fov < FG_FOV_MIN ) { fov = FG_FOV_MIN; }
268 if ( fov > FG_FOV_MAX ) { fov = FG_FOV_MAX; }
270 printf("parse_fov(): result = %.4f\n", fov);
276 // Parse a single option
277 int fgOPTIONS::parse_option( char *arg ) {
279 if ( (strcmp(arg, "--help") == 0) ||
280 (strcmp(arg, "-h") == 0) ) {
281 // help/usage request
282 return(FG_OPTIONS_HELP);
283 } else if ( strcmp(arg, "--disable-hud") == 0 ) {
285 } else if ( strcmp(arg, "--enable-hud") == 0 ) {
287 } else if ( strncmp(arg, "--airport-id=", 13) == 0 ) {
289 strncpy(airport_id, arg, 4);
290 } else if ( strncmp(arg, "--fg-root=", 10) == 0 ) {
292 strcpy(fg_root, arg);
293 } else if ( strcmp(arg, "--disable-fog") == 0 ) {
295 } else if ( strcmp(arg, "--enable-fog") == 0 ) {
297 } else if ( strncmp(arg, "--fov=", 6) == 0 ) {
298 fov = parse_fov(arg);
299 } else if ( strcmp(arg, "--disable-fullscreen") == 0 ) {
301 } else if ( strcmp(arg, "--enable-fullscreen") == 0 ) {
303 } else if ( strcmp(arg, "--shading-flat") == 0 ) {
305 } else if ( strcmp(arg, "--shading-smooth") == 0 ) {
307 } else if ( strcmp(arg, "--disable-skyblend") == 0 ) {
309 } else if ( strcmp(arg, "--enable-skyblend") == 0 ) {
311 } else if ( strcmp(arg, "--disable-textures") == 0 ) {
313 } else if ( strcmp(arg, "--enable-textures") == 0 ) {
315 } else if ( strcmp(arg, "--disable-wireframe") == 0 ) {
317 } else if ( strcmp(arg, "--enable-wireframe") == 0 ) {
319 } else if ( strncmp(arg, "--tile-radius=", 14) == 0 ) {
320 tile_radius = parse_tile_radius(arg);
321 } else if ( strncmp(arg, "--time-offset=", 14) == 0 ) {
322 time_offset = parse_time_offset(arg);
324 return(FG_OPTIONS_ERROR);
327 return(FG_OPTIONS_OK);
331 // Parse the command line options
332 int fgOPTIONS::parse_command_line( int argc, char **argv ) {
336 fgPrintf(FG_GENERAL, FG_INFO, "Processing command line arguments\n");
339 fgPrintf(FG_GENERAL, FG_INFO, "argv[%d] = %s\n", i, argv[i]);
341 result = parse_option(argv[i]);
342 if ( (result == FG_OPTIONS_HELP) || (result == FG_OPTIONS_ERROR) ) {
349 return(FG_OPTIONS_OK);
353 // Parse the command line options
354 int fgOPTIONS::parse_config_file( char *path ) {
355 char fgpath[256], line[256];
359 strcpy(fgpath, path);
360 strcat(fgpath, ".gz");
362 // first try "path.gz"
363 if ( (f = fgopen(fgpath, "rb")) == NULL ) {
365 if ( (f = fgopen(path, "rb")) == NULL ) {
366 return(FG_OPTIONS_ERROR);
370 fgPrintf(FG_GENERAL, FG_INFO, "Processing config file: %s\n", path);
372 while ( fggets(f, line, 250) != NULL ) {
373 // strip trailing newline if it exists
375 if ( line[len-1] == '\n' ) {
379 result = parse_option(line);
380 if ( result == FG_OPTIONS_ERROR ) {
381 fgPrintf( FG_GENERAL, FG_EXIT,
382 "Config file parse error: %s '%s'\n", path, line );
387 return(FG_OPTIONS_OK);
391 // Print usage message
392 void fgOPTIONS::usage ( void ) {
393 printf("Usage: fg [ options ... ]\n");
396 printf("General Options:\n");
397 printf("\t--help -h: print usage\n");
398 printf("\t--fg-root=path: specify the root path for all the data files\n");
401 printf("Features:\n");
402 printf("\t--disable-hud: disable heads up display\n");
403 printf("\t--enable-hud: enable heads up display\n");
406 printf("Initial Position:\n");
407 printf("\t--airport-id=ABCD: specify starting postion by airport id\n");
410 printf("Rendering Options:\n");
411 printf("\t--disable-fog: disable fog/haze\n");
412 printf("\t--enable-fog: enable fog/haze\n");
413 printf("\t--fov=xx.x: specify the field of view angle in degrees\n");
414 printf("\t--disable-fullscreen: disable fullscreen mode\n");
415 printf("\t--enable-fullscreen: enable fullscreen mode\n");
416 printf("\t--shading-flat: enable flat shading\n");
417 printf("\t--shading-smooth: enable smooth shading\n");
418 printf("\t--disable-skyblend: disable sky blending\n");
419 printf("\t--enable-skyblend: enable sky blending\n");
420 printf("\t--disable-textures: disable textures\n");
421 printf("\t--enable-textures: enable textures\n");
422 printf("\t--disable-wireframe: disable wireframe drawing mode\n");
423 printf("\t--enable-wireframe: enable wireframe drawing mode\n");
426 printf("Scenery Options:\n");
427 printf("\t--tile-radius=n: specify tile radius, must be odd 3, 5, or 7\n");
430 printf("Time Options:\n");
431 printf("\t--time-offset=[+-]hh:mm:ss: offset local time by this amount\n");
436 fgOPTIONS::~fgOPTIONS( void ) {
441 // Revision 1.9 1998/05/13 18:29:59 curt
442 // Added a keyboard binding to dynamically adjust field of view.
443 // Added a command line option to specify fov.
444 // Adjusted terrain color.
445 // Root path info moved to fgOPTIONS.
446 // Added ability to parse options out of a config file.
448 // Revision 1.8 1998/05/07 23:14:16 curt
449 // Added "D" key binding to set autopilot heading.
450 // Made frame rate calculation average out over last 10 frames.
451 // Borland C++ floating point exception workaround.
452 // Added a --tile-radius=n option.
454 // Revision 1.7 1998/05/06 03:16:25 curt
455 // Added an averaged global frame rate counter.
456 // Added an option to control tile radius.
458 // Revision 1.6 1998/05/03 00:47:32 curt
459 // Added an option to enable/disable full-screen mode.
461 // Revision 1.5 1998/04/30 12:34:19 curt
462 // Added command line rendering options:
463 // enable/disable fog/haze
464 // specify smooth/flat shading
465 // disable sky blending and just use a solid color
466 // enable wireframe drawing mode
468 // Revision 1.4 1998/04/28 01:20:22 curt
469 // Type-ified fgTIME and fgVIEW.
470 // Added a command line option to disable textures.
472 // Revision 1.3 1998/04/26 05:01:19 curt
473 // Added an rint() / HAVE_RINT check.
475 // Revision 1.2 1998/04/25 15:11:12 curt
476 // Added an command line option to set starting position based on airport ID.
478 // Revision 1.1 1998/04/24 00:49:21 curt
479 // Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
480 // Trying out some different option parsing code.
481 // Some code reorganization.