/* This file is part of Warzone 2100. Copyright (C) 1999-2004 Eidos Interactive Copyright (C) 2005-2007 Warzone Resurrection Project Warzone 2100 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Warzone 2100 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Warzone 2100; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* * clParse.c * * Parse command line arguments * */ #ifndef _MSC_VER #include #endif // not for .net I should say.. --Qamly #include "lib/framework/frame.h" #include "lib/widget/widget.h" #include "winmain.h" #include "frontend.h" #include "lib/ivis_common/pieclip.h" #include "warzoneconfig.h" #include "clparse.h" #include "lib/ivis_common/piestate.h" #include "loadsave.h" #include "objects.h" #include "advvis.h" #include "multiplay.h" #include "multiint.h" #include "lib/netplay/netplay.h" #include "wrappers.h" #include "cheat.h" #include "init.h" // To set the shadow config: #include "display.h" extern BOOL NETsetupTCPIP(LPVOID *addr, char * machine); extern BOOL scanGameSpyFlags(LPSTR gflag,LPSTR value); extern char SaveGamePath[]; extern char datadir[MAX_PATH]; extern char * global_mods[MAX_MODS]; extern char * campaign_mods[MAX_MODS]; extern char * multiplay_mods[MAX_MODS]; void debug_callback_file( void**, const char * ); void debug_callback_file_init( void** ); void debug_callback_file_exit( void** ); //! Whether to play the intro video BOOL clIntroVideo; //! Let the end user into debug mode.... BOOL bAllowDebugMode = FALSE; //! Early parsing of the commandline /** * First half of the command line parsing. Also see ParseCommandLine() * below. The parameters here are needed early in the boot process, * while the ones in ParseCommandLine can benefit from debugging being * set up first. * \param argc number of arguments given * \param argv string array of the arguments * \return Returns TRUE on success, FALSE on error */ BOOL ParseCommandLineEarly(int argc, char** argv) { char *tokenType; char *token; int i; /* loop through command line */ for (i = 1; i < argc; ++i) { tokenType = argv[i]; if ( stricmp(tokenType, "--version") == 0 ) { #ifdef DEBUG fprintf( stdout, "Warzone 2100 - Version %s - Built %s - DEBUG\n", VERSION, __DATE__ ); #else fprintf( stdout, "Warzone 2100 - Version %s - Built %s\n", VERSION, __DATE__ ); #endif return FALSE; } else if ( stricmp(tokenType, "--help" ) == 0 ) { // Show help fprintf( stdout, "Warzone 2100:\n" " An OpenGL based 3D real time strategy game, scened in post-nuclear warfare\n" "Usage:\n" " warzone2100 [OPTIONS]\n" "Options:\n" " --cheat Run in cheat mode\n" " --datadir DIR Set default datadir to DIR\n" " --debug FLAGS Show debug for FLAGS\n" " --debugfile FILE Log debug output in FILE\n" " --fullscreen Play in fullscreen mode\n" " --help Show this help and exit\n" " --mod MOD Enable global mod MOD\n" " --mod_ca MOD Enable campaign only mod MOD\n" " --mod_mp MOD Enable multiplay only mod MOD\n" " --savegame NAME Load a saved game NAME\n" " --window Play in windowed mode\n" " --version Output version info and exit\n" " --resolution WIDTHxHEIGHT Set the resolution (screen or window)\n" " --(no)shadows Toggles the shadows\n" " --(no)sound Toggles the sound\n" ); return FALSE; } else if ( stricmp(tokenType, "--datadir") == 0 ) { // find the quoted path name token = argv[++i]; if (token == NULL) { debug( LOG_ERROR, "Unrecognised datadir\n" ); return FALSE; } strncpy(datadir, token, sizeof(datadir)); } else if ( stricmp(tokenType, "--debug") == 0 ) { // find the part name token = argv[++i]; if (token == NULL) { debug( LOG_ERROR, "Usage: --debug " ); return FALSE; } if (!debug_enable_switch(token)) { debug(LOG_ERROR, "Debug flag \"%s\" not found!", token); return FALSE; } } else if ( stricmp(tokenType, "--debugfile") == 0 ) { // find the file name token = argv[++i]; if (token == NULL) { debug( LOG_ERROR, "Missing filename?\n" ); abort(); return FALSE; } debug_register_callback( debug_callback_file, debug_callback_file_init, debug_callback_file_exit, (void*)token ); } } return TRUE; } /************************************************************************** **************************************************************************/ //! second half of parsing the commandline /** * Second half of command line parsing. See ParseCommandLineEarly() for * the first half. Note that render mode must come before resolution flag. * \param argc number of arguments given * \param argv string array of the arguments * \return Returns TRUE on success, FALSE on error */ BOOL ParseCommandLine(int argc, char** argv) { char *tokenType=NULL, *token=NULL; unsigned int width=0, height=0; int i = 0, j = 0; /* loop through command line */ for( i = 1; i < argc; ++i) { tokenType = argv[i]; if ( stricmp(tokenType, "--cheat") == 0 ) { fprintf(stdout, " ** DEBUG MODE UNLOCKED! **\n"); bAllowDebugMode = TRUE; } else if ( stricmp( tokenType, "--fullscreen" ) == 0 ) { war_setFullscreen(TRUE); } else if ( stricmp( tokenType, "--game" ) == 0 ) { // find the game name token = argv[++i]; if (token == NULL) { debug( LOG_ERROR, "Unrecognised game name\n" ); abort(); return FALSE; } strncpy(pLevelName, token, 254); SetGameMode(GS_NORMAL); } else if ( stricmp(tokenType, "--mod") == 0 ) { // find the file name token = argv[++i]; if (token == NULL) { debug( LOG_ERROR, "Missing mod name?\n" ); return FALSE; } for( j = 0; global_mods[j] != NULL && j < 100; j++ ); if( global_mods[j] != NULL ) debug( LOG_ERROR, "Too many mods registered! Aborting!" ); global_mods[j] = token; } else if ( stricmp(tokenType, "--mod_ca") == 0 ) { // find the file name token = argv[++i]; if (token == NULL) { debug( LOG_ERROR, "Missing mod name?\n" ); return FALSE; } for( j = 0; campaign_mods[j] != NULL && j < 100; j++ ); if( campaign_mods[j] != NULL ) debug( LOG_ERROR, "Too many mods registered! Aborting!" ); campaign_mods[j] = token; } else if ( stricmp(tokenType, "--mod_mp") == 0 ) { // find the file name token = argv[++i]; if (token == NULL) { debug( LOG_ERROR, "Missing mod name?\n" ); return FALSE; } for( j = 0; multiplay_mods[j] != NULL && j < 100; j++ ); if( multiplay_mods[j] != NULL ) debug( LOG_ERROR, "Too many mods registered! Aborting!" ); multiplay_mods[j] = token; } else if ( stricmp( tokenType, "--savegame" ) == 0 ) { // find the game name token = argv[++i]; if (token == NULL) { debug( LOG_ERROR, "Unrecognised savegame name\n" ); abort(); return FALSE; } strcpy(saveGameName, SaveGamePath); strcat(saveGameName, "/"); strncat(saveGameName, token, 240); SetGameMode(GS_SAVEGAMELOAD); } else if ( stricmp( tokenType, "--shadows" ) == 0 ) { setDrawShadows( TRUE ); } else if ( stricmp( tokenType, "--noshadows" ) == 0 ) { setDrawShadows( FALSE ); } else if ( stricmp( tokenType, "--sound" ) == 0 ) { war_setSoundEnabled( TRUE ); } else if ( stricmp( tokenType, "--nosound" ) == 0 ) { war_setSoundEnabled( FALSE ); } else if ( stricmp( tokenType, "--resolution" ) == 0 ) { token = argv[++i]; if ( sscanf( token, "%ix%i", &width, &height ) != 2 ) { debug( LOG_ERROR, "Invalid resolution\n" ); abort(); return FALSE; } pie_SetVideoBufferWidth( width ); pie_SetVideoBufferHeight( height ); } else if ( stricmp( tokenType, "--window" ) == 0 ) { war_setFullscreen(FALSE); } else if ( stricmp( tokenType, "--intro" ) == 0 ) { SetGameMode(GS_VIDEO_MODE); } else if ( stricmp( tokenType, "--title" ) == 0 ) { SetGameMode(GS_TITLE_SCREEN); } else if ( stricmp( tokenType,"--noTranslucent") == 0 ) { war_SetTranslucent(FALSE); } else if ( stricmp( tokenType,"--noAdditive") == 0) { war_SetAdditive(FALSE); } else if ( stricmp( tokenType,"--noFog") == 0 ) { pie_SetFogCap(FOG_CAP_NO); } else if ( stricmp( tokenType,"--greyFog") == 0 ) { pie_SetFogCap(FOG_CAP_GREY); } else if ( stricmp(tokenType, "--CDA") == 0 ) { war_SetPlayAudioCDs(TRUE); } else if ( stricmp(tokenType, "--noCDA") == 0 ) { war_SetPlayAudioCDs(FALSE); } else if ( stricmp( tokenType,"--seqSmall") == 0 ) { war_SetSeqMode(SEQ_SMALL); } else if ( stricmp( tokenType,"--seqSkip") == 0 ) { war_SetSeqMode(SEQ_SKIP); } else if ( stricmp( tokenType,"--disableLobby") == 0 ) { bDisableLobby = TRUE; } // gamespy flags else if ( stricmp(tokenType, "+host") == 0 // host a multiplayer. || stricmp(tokenType, "+connect") == 0 || stricmp(tokenType, "+name") == 0 || stricmp(tokenType, "+ip") == 0 || stricmp(tokenType, "+maxplayers") == 0 || stricmp(tokenType, "+hostname") == 0) { token = argv[++i]; scanGameSpyFlags(tokenType, token); } // end of gamespy else { // ignore (gamespy requirement) // DBERROR( ("Unrecognised command-line token %s\n", tokenType) ); // return FALSE; } } return TRUE; } // //////////////////////////////////////////////////////// //! gamespy flags BOOL scanGameSpyFlags(LPSTR gflag,LPSTR value) { static UBYTE count = 0; // UDWORD val; LPVOID finalconnection; #if 0 // check for gamespy flag... // if game spy not enabled.... if(!openWarzoneKey()) return FALSE; if(!getWarzoneKeyNumeric("allowGameSpy",&val)) { return TRUE; } closeWarzoneKey(); #endif count++; if(count == 1) { lobbyInitialise(); bDisableLobby = TRUE; // dont reset everything on boot! gameSpy.bGameSpy = TRUE; } if( stricmp( gflag,"+host") == 0) // host a multiplayer. { NetPlay.bHost = 1; game.bytesPerSec = INETBYTESPERSEC; game.packetsPerSec = INETPACKETS; NETsetupTCPIP(&finalconnection,""); NETselectProtocol(finalconnection); } else if( stricmp( gflag,"+connect") == 0) // join a multiplayer. { NetPlay.bHost = 0; game.bytesPerSec = INETBYTESPERSEC; game.packetsPerSec = INETPACKETS; NETsetupTCPIP(&finalconnection,value); NETselectProtocol(finalconnection); // gflag is add to con to. } else if( stricmp( gflag,"+name") == 0) // player name. { strcpy((char *)sPlayer,value); } else if( stricmp( gflag,"+hostname") == 0) // game name. { strcpy(game.name,value); } /*not used from here on.. +ip +maxplayers +game +team +skin +playerid +password tokenType = strtok( NULL, seps ); */ return TRUE; }