2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
4 * All source code herein is the property of Volition, Inc. You may not sell
5 * or otherwise commercially exploit the source or things you created based on
10 * $Logfile: /Freespace2/code/Cmdline/cmdline.cpp $
16 * Revision 1.4 2002/06/21 03:34:05 relnev
17 * implemented a stub and fixed a path
19 * Revision 1.3 2002/06/09 04:41:15 relnev
20 * added copyright header
22 * Revision 1.2 2002/05/07 03:16:43 theoddone33
23 * The Great Newline Fix
25 * Revision 1.1.1.1 2002/05/03 03:28:08 root
29 * 8 8/26/99 8:51p Dave
30 * Gave multiplayer TvT messaging a heavy dose of sanity. Cheat codes.
32 * 7 7/15/99 3:07p Dave
33 * 32 bit detection support. Mouse coord commandline.
35 * 6 7/13/99 1:15p Dave
36 * 32 bit support. Whee!
38 * 5 6/22/99 9:37p Dave
41 * 4 1/12/99 5:45p Dave
42 * Moved weapon pipeline in multiplayer to almost exclusively client side.
43 * Very good results. Bandwidth goes down, playability goes up for crappy
44 * connections. Fixed object update problem for ship subsystems.
46 * 3 11/17/98 11:12a Dave
47 * Removed player identification by address. Now assign explicit id #'s.
49 * 2 10/07/98 10:52a Dave
52 * 1 10/07/98 10:48a Dave
54 * 38 10/02/98 3:22p Allender
55 * fix up the -connect option and fix the -port option
57 * 37 9/15/98 4:04p Allender
58 * added back in the -ip_addr command line switch because it needs to be
59 * in the standalone server only executable
61 * 36 9/14/98 11:52a Allender
64 * 35 9/14/98 11:28a Allender
65 * support for server bashing of address when received from client. Added
66 * a cmdline.cfg file to process command line arguments from a file
68 * 34 9/08/98 2:20p Allender
69 * temporary code to force IP address to a specific value.
71 * 33 8/20/98 5:30p Dave
72 * Put in handy multiplayer logfile system. Now need to put in useful
73 * applications of it all over the code.
75 * 32 8/07/98 10:39a Allender
76 * fixed debug standalone problem where stats would continually get sent
77 * to tracker. more debug code to help find stats problem
79 * 31 7/24/98 11:14a Allender
80 * start of new command line options for version 1.04
82 * 30 5/21/98 1:50a Dave
83 * Remove obsolete command line functions. Reduce shield explosion packets
84 * drastically. Tweak PXO screen even more. Fix file xfer system so that
85 * we can guarantee file uniqueness.
87 * 29 5/18/98 9:10p Dave
88 * Put in many new PXO features. Fixed skill level bashing in multiplayer.
89 * Removed several old command line options. Put in network config files.
91 * 28 5/09/98 7:16p Dave
92 * Put in CD checking. Put in standalone host password. Made pilot into
95 * 27 4/23/98 8:27p Allender
96 * basic support for cutscene playback. Into movie code in place. Tech
97 * room can view cutscenes stored in CDROM_dir variable
99 * 26 4/09/98 5:43p Dave
100 * Remove all command line processing from the demo. Began work fixing up
101 * the new multi host options screen.
103 * 25 4/02/98 11:40a Lawrance
104 * check for #ifdef DEMO instead of #ifdef DEMO_RELEASE
106 * 24 4/01/98 5:56p Dave
107 * Fixed a messaging bug which caused msg_all mode in multiplayer not to
108 * work. Compile out a host of multiplayer options not available in the
111 * 23 3/14/98 2:48p Dave
112 * Cleaned up observer joining code. Put in support for file xfers to
113 * ingame joiners (observers or not). Revamped and reinstalled pseudo
116 * 22 2/22/98 12:19p John
117 * Externalized some strings
119 * 21 1/31/98 4:32p Dave
120 * Put in new support for VMT player validation, game logging in and game
123 * 20 12/10/97 4:45p Dave
124 * Added in more detailed support for multiplayer packet lag/loss. Fixed
125 * some multiplayer stuff. Added some controls to the standalone.
127 * 19 12/09/97 6:14p Lawrance
130 * 18 12/01/97 5:10p Dave
131 * Fixed a syntax bug.
133 * 17 12/01/97 4:59p Dave
134 * Synchronized multiplayer debris objects. Put in pilot popup in main
135 * hall. Optimized simulated multiplayer lag module. Fixed a potential
138 * 16 11/28/97 7:04p Dave
139 * Emergency checkin due to big system crash.
141 * 15 11/28/97 5:06p Dave
142 * Put in facilities for simulating multiplayer lag.
144 * 14 11/24/97 5:42p Dave
145 * Fixed a file xfer buffer free/malloc problem. Lengthened command line
146 * switch string parse length.
148 * 13 11/12/97 4:39p Dave
149 * Put in multiplayer campaign support parsing, loading and saving. Made
150 * command-line variables better named. Changed some things on the initial
151 * pilot select screen.
153 * 12 11/11/97 4:54p Dave
154 * Put in support for single vs. multiplayer pilots. Put in initial player
155 * selection screen (no command line option yet). Started work on
156 * multiplayer campaign file save gaming.
158 * 11 11/11/97 11:55a Allender
159 * initialize network at beginning of application. create new call to set
160 * which network protocol to use
162 * 10 9/18/97 10:12p Dave
163 * Added -gimmemedals, which gives the current pilot all the medals in the
166 * 9 9/18/97 9:20a Dave
167 * Minor modifications
169 * 8 9/15/97 11:40p Lawrance
170 * remove demo granularity switch
172 * 7 9/09/97 3:39p Sandeep
173 * warning level 4 bugs
175 * 6 9/03/97 5:03p Lawrance
176 * add support for -nosound command line parm
178 * 5 8/22/97 8:52a Dave
179 * Removed a return statement which would have broken the parser out too
182 * 4 8/21/97 4:55p Dave
183 * Added a switch for multiplayer chat streaming. Added a section for
184 * global command line vars.
186 * 3 8/06/97 2:26p Dave
187 * Made the command line parse more robust. Made it easier to add and
188 * process new command-line switches.
190 * 2 8/04/97 3:13p Dave
191 * Added command line functions. See cmdline.cpp for directions on adding
194 * 1 8/04/97 9:58a Dave
202 #include "linklist.h"
203 #include "systemvars.h"
210 cmdline_parm *next, *prev;
211 char *name; // name of parameter, must start with '-' char
212 char *help; // help text for this parameter
213 char *args; // string value for parameter arguements (NULL if no arguements)
214 int name_found; // true if parameter on command line, otherwise false
216 cmdline_parm(char *name, char *help);
224 // here are the command line parameters that we will be using for FreeSpace
225 cmdline_parm standalone_arg("-standalone", NULL);
226 cmdline_parm nosound_arg("-nosound", NULL);
227 cmdline_parm nomusic_arg("-nomusic", NULL);
228 cmdline_parm startgame_arg("-startgame", NULL);
229 cmdline_parm gamename_arg("-gamename", NULL);
230 cmdline_parm gamepassword_arg("-password", NULL);
231 cmdline_parm gameclosed_arg("-closed", NULL);
232 cmdline_parm gamerestricted_arg("-restricted", NULL);
233 cmdline_parm allowabove_arg("-allowabove", NULL);
234 cmdline_parm allowbelow_arg("-allowbelow", NULL);
235 cmdline_parm port_arg("-port", NULL);
236 cmdline_parm connect_arg("-connect", NULL);
237 cmdline_parm multilog_arg("-multilog", NULL);
238 cmdline_parm server_firing_arg("-oldfire", NULL);
239 cmdline_parm client_dodamage("-clientdamage", NULL);
240 cmdline_parm pof_spew("-pofspew", NULL);
241 cmdline_parm d3d_32bit("-32bit", NULL);
242 cmdline_parm mouse_coords("-coords", NULL);
243 cmdline_parm timeout("-timeout", NULL);
244 cmdline_parm d3d_window("-window", NULL);
246 int Cmdline_multi_stream_chat_to_file = 0;
247 int Cmdline_freespace_no_sound = 0;
248 int Cmdline_freespace_no_music = 0;
249 int Cmdline_gimme_all_medals = 0;
250 int Cmdline_use_last_pilot = 0;
251 int Cmdline_multi_protocol = -1;
252 int Cmdline_cd_check = 1;
253 int Cmdline_start_netgame = 0;
254 int Cmdline_closed_game = 0;
255 int Cmdline_restricted_game = 0;
256 int Cmdline_network_port = -1;
257 char *Cmdline_game_name = NULL;
258 char *Cmdline_game_password = NULL;
259 char *Cmdline_rank_above= NULL;
260 char *Cmdline_rank_below = NULL;
261 char *Cmdline_connect_addr = NULL;
262 int Cmdline_multi_log = 0;
263 int Cmdline_server_firing = 0;
264 int Cmdline_client_dodamage = 0;
265 int Cmdline_spew_pof_info = 0;
266 int Cmdline_force_32bit = 0;
267 int Cmdline_mouse_coords = 0;
268 int Cmdline_timeout = -1;
270 int Cmdline_window = 0;
272 static cmdline_parm Parm_list(NULL, NULL);
273 static int Parm_list_inited = 0;
276 // Return true if this character is an extra char (white space and quotes)
277 int is_extra_space(char ch)
279 return ((ch == ' ') || (ch == '\t') || (ch == 0x0a) || (ch == '\'') || (ch == '\"'));
283 // eliminates all leading and trailing extra chars from a string. Returns pointer passed in.
284 char *drop_extra_chars(char *str)
289 while (str[s] && is_extra_space(str[s]))
294 if (!is_extra_space(str[e])){
302 memmove(str, str + s, e - s + 1);
310 // internal function - copy the value for a parameter agruement into the cmdline_parm arg field
311 void parm_stuff_args(cmdline_parm *parm, char *cmdline)
314 memset(buffer, 0, 1024);
317 cmdline += strlen(parm->name);
319 while ((*cmdline != 0) && (*cmdline != '-')) {
320 *dest++ = *cmdline++;
323 drop_extra_chars(buffer);
325 // mwa 9/14/98 -- made it so that newer command line arguments found will overwrite
327 // Assert(parm->args == NULL);
328 if ( parm->args != NULL ) {
329 delete( parm->args );
333 int size = strlen(buffer) + 1;
335 parm->args = new char[size];
336 memset(parm->args, 0, size);
337 strcpy(parm->args, buffer);
342 // internal function - parse the command line, extracting parameter arguements if they exist
343 // cmdline - command line string passed to the application
344 void os_parse_parms(char *cmdline)
346 // locate command line parameters
348 char *cmdline_offset;
350 for (parmp = GET_FIRST(&Parm_list); parmp !=END_OF_LIST(&Parm_list); parmp = GET_NEXT(parmp) ) {
351 cmdline_offset = strstr(cmdline, parmp->name);
352 if (cmdline_offset) {
353 parmp->name_found = 1;
354 parm_stuff_args(parmp, cmdline_offset);
360 // validate the command line parameters. Display an error if an unrecognized parameter is located.
361 void os_validate_parms(char *cmdline)
364 char seps[] = " ,\t\n";
368 token = strtok(cmdline, seps);
369 while(token != NULL) {
371 if (token[0] == '-') {
373 for (parmp = GET_FIRST(&Parm_list); parmp !=END_OF_LIST(&Parm_list); parmp = GET_NEXT(parmp) ) {
374 if (!stricmp(parmp->name, token)) {
380 if (parm_found == 0) {
381 Error(LOCATION,"Unrecogzined command line parameter %s", token);
385 token = strtok(NULL, seps);
390 // Call once to initialize the command line system
392 // cmdline - command line string passed to the application
393 void os_init_cmdline(char *cmdline)
397 // read the cmdline.cfg file from the data folder, and pass the command line arguments to
398 // the the parse_parms and validate_parms line. Read these first so anything actually on
399 // the command line will take precedence
401 fp = fopen("Data/cmdline.cfg", "rt");
403 fp = fopen("data\\cmdline.cfg", "rt");
406 // if the file exists, get a single line, and deal with it
410 fgets(buf, 1024, fp);
412 // replace the newline character with a NUL:
413 if ( (p = strrchr(buf, '\n')) != NULL ) {
418 os_validate_parms(buf);
424 os_parse_parms(cmdline);
425 os_validate_parms(cmdline);
431 // name_ - name of the parameter, must start with '-' character
432 // help_ - help text for this parameter
433 cmdline_parm::cmdline_parm(char *name_, char *help_)
440 if (Parm_list_inited == 0) {
441 list_init(&Parm_list);
442 Parm_list_inited = 1;
446 list_append(&Parm_list, this);
451 // destructor - frees any allocated memory
452 cmdline_parm::~cmdline_parm()
461 // returns - true if the parameter exists on the command line, otherwise false
462 int cmdline_parm::found()
468 // returns - the interger representation for the parameter arguement
469 int cmdline_parm::get_int()
476 // returns - the float representation for the parameter arguement
477 float cmdline_parm::get_float()
480 return (float)atof(args);
484 // returns - the string value for the parameter arguement
485 char *cmdline_parm::str()
491 // external entry point into this modules
492 int parse_cmdline(char *cmdline)
494 os_init_cmdline(cmdline);
496 // is this a standalone server??
497 if (standalone_arg.found()) {
502 if ( nosound_arg.found() ) {
503 Cmdline_freespace_no_sound = 1;
507 if ( nomusic_arg.found() ) {
508 Cmdline_freespace_no_music = 1;
511 // should we start a network game
512 if ( startgame_arg.found() ) {
513 Cmdline_use_last_pilot = 1;
514 Cmdline_start_netgame = 1;
517 // closed network game
518 if ( gameclosed_arg.found() ) {
519 Cmdline_closed_game = 1;
522 // restircted network game
523 if ( gamerestricted_arg.found() ) {
524 Cmdline_restricted_game = 1;
527 // get the name of the network game
528 if ( gamename_arg.found() ) {
529 Cmdline_game_name = gamename_arg.str();
531 // be sure that this string fits in our limits
532 if ( strlen(Cmdline_game_name) > MAX_GAMENAME_LEN ) {
533 Cmdline_game_name[MAX_GAMENAME_LEN-1] = '\0';
537 // get the password for a pssword game
538 if ( gamepassword_arg.found() ) {
539 Cmdline_game_password = gamepassword_arg.str();
541 // be sure that this string fits in our limits
542 if ( strlen(Cmdline_game_name) > MAX_PASSWD_LEN ) {
543 Cmdline_game_name[MAX_PASSWD_LEN-1] = '\0';
547 // set the rank above/below arguments
548 if ( allowabove_arg.found() ) {
549 Cmdline_rank_above = allowabove_arg.str();
551 if ( allowbelow_arg.found() ) {
552 Cmdline_rank_below = allowbelow_arg.str();
555 // get the port number for games
556 if ( port_arg.found() ) {
557 Cmdline_network_port = port_arg.get_int();
560 // the connect argument specifies to join a game at this particular address
561 if ( connect_arg.found() ) {
562 Cmdline_use_last_pilot = 1;
563 Cmdline_connect_addr = connect_arg.str();
566 // see if the multilog flag was set
567 if ( multilog_arg.found() ){
568 Cmdline_multi_log = 1;
571 // maybe use old-school server-side firing
572 if (server_firing_arg.found() ){
573 Cmdline_server_firing = 1;
576 // maybe use old-school client damage
577 if(client_dodamage.found()){
578 Cmdline_client_dodamage = 1;
582 if(pof_spew.found()){
583 Cmdline_spew_pof_info = 1;
587 if(d3d_32bit.found()){
588 Cmdline_force_32bit = 1;
592 if(mouse_coords.found()){
593 Cmdline_mouse_coords = 1;
598 Cmdline_timeout = timeout.get_int();
602 if(d3d_window.found()){