]> git.mxchange.org Git - flightgear.git/blob - Main/options.cxx
Added a keyboard binding to dynamically adjust field of view.
[flightgear.git] / Main / options.cxx
1 //
2 // options.cxx -- class to handle command line options
3 //
4 // Written by Curtis Olson, started April 1998.
5 //
6 // Copyright (C) 1998  Curtis L. Olson  - curt@me.umn.edu
7 //
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.
12 //
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.
17 //
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.
21 //
22 // $Id$
23 // (Log is kept at end of this file)
24
25
26 #ifdef HAVE_CONFIG_H
27 #  include <config.h>
28 #endif
29
30 #include <math.h>            // rint()
31 #include <stdio.h>
32 #include <stdlib.h>          // atof(), atoi()
33 #include <string.h>
34
35 #include <Debug/fg_debug.h>
36 #include <Include/fg_zlib.h>
37
38 #include "options.hxx"
39
40
41 // Defined the shared options class here
42 fgOPTIONS current_options;
43
44
45 // Constructor
46 fgOPTIONS::fgOPTIONS( void ) {
47     // set initial values/defaults
48
49     if ( getenv("FG_ROOT") != NULL ) {
50         // fg_root could be anywhere, so default to environmental
51         // variable $FG_ROOT if it is set.
52
53         strcpy(fg_root, getenv("FG_ROOT"));
54     } else {
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.
58
59 #if defined(WIN32)
60         strcpy(fg_root, "\\FlightGear");
61 #else
62         strcpy(fg_root, "/usr/local/lib/FlightGear");
63 #endif
64     }
65
66     // default airport id
67     strcpy(airport_id, "");
68
69     // Features
70     hud_status = 0;
71
72     // Rendering options
73     fog = 1;
74     fov = 65.0;
75     fullscreen = 0;
76     shading = 1;
77     skyblend = 1;
78     textures = 1;
79     wireframe = 0;
80
81     // Scenery options
82     tile_radius = 7;
83
84     // Time options
85     time_offset = 0;
86 }
87
88
89 // Parse an int out of a --foo-bar=n type option 
90 static int parse_int(char *arg) {
91     int result;
92
93     // advance past the '='
94     while ( (arg[0] != '=') && (arg[0] != '\0') ) {
95         arg++;
96     }
97
98     if ( arg[0] == '=' ) {
99         arg++;
100     }
101
102     printf("parse_int(): arg = %s\n", arg);
103
104     result = atoi(arg);
105
106     printf("parse_int(): result = %d\n", result);
107
108     return(result);
109 }
110
111
112 // Parse an int out of a --foo-bar=n type option 
113 static double parse_double(char *arg) {
114     double result;
115
116     // advance past the '='
117     while ( (arg[0] != '=') && (arg[0] != '\0') ) {
118         arg++;
119     }
120
121     if ( arg[0] == '=' ) {
122         arg++;
123     }
124
125     printf("parse_double(): arg = %s\n", arg);
126
127     result = atof(arg);
128
129     printf("parse_double(): result = %.4f\n", result);
130
131     return(result);
132 }
133
134
135 // parse time string in the form of [+-]hh:mm:ss, returns the value in seconds
136 static double parse_time(char *time_str) {
137     char num[256];
138     double hours, minutes, seconds;
139     double result = 0.0;
140     int sign = 1;
141     int i;
142
143     // printf("parse_time(): %s\n", time_str);
144
145     // check for sign
146     if ( strlen(time_str) ) {
147         if ( time_str[0] == '+' ) {
148             sign = 1;
149             time_str++;
150         } else if ( time_str[0] == '-' ) {
151             sign = -1;
152             time_str++;
153         }
154     }
155     // printf("sign = %d\n", sign);
156
157     // get hours
158     if ( strlen(time_str) ) {
159         i = 0;
160         while ( (time_str[0] != ':') && (time_str[0] != '\0') ) {
161             num[i] = time_str[0];
162             time_str++;
163             i++;
164         }
165         if ( time_str[0] == ':' ) {
166             time_str++;
167         }
168         num[i] = '\0';
169         hours = atof(num);
170         // printf("hours = %.2lf\n", hours);
171
172         result += hours * 3600.0;
173     }
174
175     // get minutes
176     if ( strlen(time_str) ) {
177         i = 0;
178         while ( (time_str[0] != ':') && (time_str[0] != '\0') ) {
179             num[i] = time_str[0];
180             time_str++;
181             i++;
182         }
183         if ( time_str[0] == ':' ) {
184             time_str++;
185         }
186         num[i] = '\0';
187         minutes = atof(num);
188         // printf("minutes = %.2lf\n", minutes);
189
190         result += minutes * 60.0;
191     }
192
193     // get seconds
194     if ( strlen(time_str) ) {
195         i = 0;
196         while ( (time_str[0] != ':') && (time_str[0] != '\0') ) {
197             num[i] = time_str[0];
198             time_str++;
199             i++;
200         }
201         num[i] = '\0';
202         seconds = atof(num);
203         // printf("seconds = %.2lf\n", seconds);
204
205         result += seconds;
206     }
207
208     return(sign * result);
209 }
210
211
212 // parse time offset command line option
213 static int parse_time_offset(char *time_str) {
214     int result;
215
216     time_str += 14;
217
218     // printf("time offset = %s\n", time_str);
219
220 #ifdef HAVE_RINT
221     result = (int)rint(parse_time(time_str));
222 #else
223     result = (int)parse_time(time_str);
224 #endif
225
226     printf("parse_time_offset(): %d\n", result);
227
228     return( result );
229 }
230
231
232 // Parse --tile-radius=n type option 
233
234 #define FG_RADIUS_MIN 3
235 #define FG_RADIUS_MAX 9
236
237 static int parse_tile_radius(char *arg) {
238     int radius, tmp;
239
240     radius = parse_int(arg);
241
242     // radius must be odd
243     tmp = radius / 2;
244     if ( radius == ( tmp * 2 ) ) {
245         radius -= 1;
246     }
247
248     if ( radius < FG_RADIUS_MIN ) { radius = FG_RADIUS_MIN; }
249     if ( radius > FG_RADIUS_MAX ) { radius = FG_RADIUS_MAX; }
250
251     printf("parse_tile_radius(): radius = %d\n", radius);
252
253     return(radius);
254 }
255
256
257 // Parse --fov=x.xx type option 
258
259 #define FG_FOV_MIN 0.1
260 #define FG_FOV_MAX 179.9
261
262 static double parse_fov(char *arg) {
263     double fov;
264
265     fov = parse_double(arg);
266
267     if ( fov < FG_FOV_MIN ) { fov = FG_FOV_MIN; }
268     if ( fov > FG_FOV_MAX ) { fov = FG_FOV_MAX; }
269
270     printf("parse_fov(): result = %.4f\n", fov);
271
272     return(fov);
273 }
274
275
276 // Parse a single option
277 int fgOPTIONS::parse_option( char *arg ) {
278     // General Options
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 ) {
284         hud_status = 0; 
285     } else if ( strcmp(arg, "--enable-hud") == 0 ) {
286         hud_status = 1; 
287     } else if ( strncmp(arg, "--airport-id=", 13) == 0 ) {
288         arg += 13;
289         strncpy(airport_id, arg, 4);
290     } else if ( strncmp(arg, "--fg-root=", 10) == 0 ) {
291         arg += 10;
292         strcpy(fg_root, arg);
293     } else if ( strcmp(arg, "--disable-fog") == 0 ) {
294         fog = 0;        
295     } else if ( strcmp(arg, "--enable-fog") == 0 ) {
296         fog = 1;        
297     } else if ( strncmp(arg, "--fov=", 6) == 0 ) {
298         fov = parse_fov(arg);
299     } else if ( strcmp(arg, "--disable-fullscreen") == 0 ) {
300         fullscreen = 0; 
301     } else if ( strcmp(arg, "--enable-fullscreen") == 0 ) {
302         fullscreen = 1; 
303     } else if ( strcmp(arg, "--shading-flat") == 0 ) {
304         shading = 0;    
305     } else if ( strcmp(arg, "--shading-smooth") == 0 ) {
306         shading = 1;    
307     } else if ( strcmp(arg, "--disable-skyblend") == 0 ) {
308         skyblend = 0;   
309     } else if ( strcmp(arg, "--enable-skyblend") == 0 ) {
310         skyblend = 1;   
311     } else if ( strcmp(arg, "--disable-textures") == 0 ) {
312         textures = 0;   
313     } else if ( strcmp(arg, "--enable-textures") == 0 ) {
314         textures = 1;   
315     } else if ( strcmp(arg, "--disable-wireframe") == 0 ) {
316         wireframe = 0;  
317     } else if ( strcmp(arg, "--enable-wireframe") == 0 ) {
318         wireframe = 1;  
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);
323     } else {
324         return(FG_OPTIONS_ERROR);
325     }
326     
327     return(FG_OPTIONS_OK);
328 }
329
330
331 // Parse the command line options
332 int fgOPTIONS::parse_command_line( int argc, char **argv ) {
333     int i = 1;
334     int result;
335
336     fgPrintf(FG_GENERAL, FG_INFO, "Processing command line arguments\n");
337
338     while ( i < argc ) {
339         fgPrintf(FG_GENERAL, FG_INFO, "argv[%d] = %s\n", i, argv[i]);
340
341         result = parse_option(argv[i]);
342         if ( (result == FG_OPTIONS_HELP) || (result == FG_OPTIONS_ERROR) ) {
343             return(result);
344         }
345
346         i++;
347     }
348     
349     return(FG_OPTIONS_OK);
350 }
351
352
353 // Parse the command line options
354 int fgOPTIONS::parse_config_file( char *path ) {
355     char fgpath[256], line[256];
356     fgFile f;
357     int len, result;
358
359     strcpy(fgpath, path);
360     strcat(fgpath, ".gz");
361
362     // first try "path.gz"
363     if ( (f = fgopen(fgpath, "rb")) == NULL ) {
364         // next try "path"
365         if ( (f = fgopen(path, "rb")) == NULL ) {
366             return(FG_OPTIONS_ERROR);
367         }
368     }
369
370     fgPrintf(FG_GENERAL, FG_INFO, "Processing config file: %s\n", path);
371
372     while ( fggets(f, line, 250) != NULL ) {
373         // strip trailing newline if it exists
374         len = strlen(line);
375         if ( line[len-1] == '\n' ) {
376             line[len-1] = '\0';
377         }
378
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 );
383         }
384     }
385
386     fgclose(f);
387     return(FG_OPTIONS_OK);
388 }
389
390
391 // Print usage message
392 void fgOPTIONS::usage ( void ) {
393     printf("Usage: fg [ options ... ]\n");
394     printf("\n");
395
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");
399     printf("\n");
400
401     printf("Features:\n");
402     printf("\t--disable-hud:  disable heads up display\n");
403     printf("\t--enable-hud:  enable heads up display\n");
404     printf("\n");
405  
406     printf("Initial Position:\n");
407     printf("\t--airport-id=ABCD:  specify starting postion by airport id\n");
408     printf("\n");
409
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");
424     printf("\n");
425
426     printf("Scenery Options:\n");
427     printf("\t--tile-radius=n:  specify tile radius, must be odd 3, 5, or 7\n");
428     printf("\n");
429
430     printf("Time Options:\n");
431     printf("\t--time-offset=[+-]hh:mm:ss:  offset local time by this amount\n");
432 }
433
434
435 // Destructor
436 fgOPTIONS::~fgOPTIONS( void ) {
437 }
438
439
440 // $Log$
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.
447 //
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.
453 //
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.
457 //
458 // Revision 1.6  1998/05/03 00:47:32  curt
459 // Added an option to enable/disable full-screen mode.
460 //
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
467 //
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.
471 //
472 // Revision 1.3  1998/04/26 05:01:19  curt
473 // Added an rint() / HAVE_RINT check.
474 //
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.
477 //
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.
482 //
483 //