/** * 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, const char **argv) { poptContext poptCon = poptGetContext(NULL, argc, argv, getOptionsTable(), 0); int iOption; #if defined(WZ_OS_MAC) && defined(DEBUG) debug_enable_switch("all"); #endif /* WZ_OS_MAC && DEBUG */ /* loop through command line */ while ((iOption = poptGetNextOpt(poptCon)) > 0 || iOption == POPT_ERROR_BADOPT) { CLI_OPTIONS option = (CLI_OPTIONS)iOption; const char *token; if (iOption == POPT_ERROR_BADOPT) { qFatal("Unrecognized option: %s", poptBadOption(poptCon, 0)); } switch (option) { case CLI_DEBUG: // retrieve the debug section name token = poptGetOptArg(poptCon); if (token == NULL) { qFatal("Usage: --debug=<flag>"); } // Attempt to enable the given debug section if (!debug_enable_switch(token)) { qFatal("Debug flag \"%s\" not found!", token); } break; case CLI_DEBUGFILE: // find the file name token = poptGetOptArg(poptCon); if (token == NULL) { qFatal("Missing debugfile filename?"); } debug_register_callback(debug_callback_file, debug_callback_file_init, debug_callback_file_exit, (void *)token); customDebugfile = true; break; case CLI_FLUSHDEBUGSTDERR: // Tell the debug stderr output callback to always flush its output debugFlushStderr(); break; case CLI_CONFIGDIR: // retrieve the configuration directory token = poptGetOptArg(poptCon); if (token == NULL) { qFatal("Unrecognised configuration directory"); } sstrcpy(configdir, token); break; case CLI_HELP: poptPrintHelp(poptCon, stdout, 0); return false; case CLI_VERSION: printf("Warzone 2100 - %s\n", version_getFormattedVersionString()); return false; default: break; }; } return true; }
/** * 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, const char **argv) { poptContext poptCon = poptGetContext(NULL, argc, argv, getOptionsTable(), 0); int iOption; /* loop through command line */ while ((iOption = poptGetNextOpt(poptCon)) > 0) { const char *token; CLI_OPTIONS option = (CLI_OPTIONS)iOption; switch (option) { case CLI_DEBUG: case CLI_DEBUGFILE: case CLI_FLUSHDEBUGSTDERR: case CLI_CONFIGDIR: case CLI_HELP: case CLI_VERSION: // These options are parsed in ParseCommandLineEarly() already, so ignore them break; case CLI_NOASSERT: kf_NoAssert(); break; // NOTE: The sole purpose of this is to test the crash handler. case CLI_CRASH: CauseCrash = true; NetPlay.bComms = false; sstrcpy(aLevelName, "CAM_3A"); SetGameMode(GS_NORMAL); break; case CLI_DATADIR: // retrieve the quoted path name token = poptGetOptArg(poptCon); if (token == NULL) { qFatal("Unrecognised datadir"); } sstrcpy(datadir, token); break; case CLI_FULLSCREEN: war_setFullscreen(true); break; case CLI_CONNECTTOIP: //get the ip we want to connect with, and go directly to join screen. token = poptGetOptArg(poptCon); if (token == NULL) { qFatal("No IP/hostname given"); } sstrcpy(iptoconnect, token); break; case CLI_HOSTLAUNCH: // go directly to host screen, bypass all others. hostlaunch = true; break; case CLI_GAME: // retrieve the game name token = poptGetOptArg(poptCon); if (token == NULL || (strcmp(token, "CAM_1A") && strcmp(token, "CAM_2A") && strcmp(token, "CAM_3A") && strcmp(token, "TUTORIAL3") && strcmp(token, "FASTPLAY"))) { qFatal("The game parameter requires one of the following keywords:" "CAM_1A, CAM_2A, CAM_3A, TUTORIAL3, or FASTPLAY."); } NetPlay.bComms = false; bMultiPlayer = false; bMultiMessages = false; NetPlay.players[0].allocated = true; if (!strcmp(token, "CAM_1A") || !strcmp(token, "CAM_2A") || !strcmp(token, "CAM_3A")) { game.type = CAMPAIGN; } else { game.type = SKIRMISH; // tutorial is skirmish for some reason } sstrcpy(aLevelName, token); SetGameMode(GS_NORMAL); break; case CLI_MOD_GLOB: { unsigned int i; // retrieve the file name token = poptGetOptArg(poptCon); if (token == NULL) { qFatal("Missing mod name?"); } // Find an empty place in the global_mods list for (i = 0; i < 100 && global_mods[i] != NULL; ++i) {} if (i >= 100 || global_mods[i] != NULL) { qFatal("Too many mods registered! Aborting!"); } global_mods[i] = strdup(token); break; } case CLI_MOD_CA: { unsigned int i; // retrieve the file name token = poptGetOptArg(poptCon); if (token == NULL) { qFatal("Missing mod name?"); } // Find an empty place in the campaign_mods list for (i = 0; i < 100 && campaign_mods[i] != NULL; ++i) {} if (i >= 100 || campaign_mods[i] != NULL) { qFatal("Too many mods registered! Aborting!"); } campaign_mods[i] = strdup(token); break; } case CLI_MOD_MP: { unsigned int i; // retrieve the file name token = poptGetOptArg(poptCon); if (token == NULL) { qFatal("Missing mod name?"); } for (i = 0; i < 100 && multiplay_mods[i] != NULL; ++i) {} if (i >= 100 || multiplay_mods[i] != NULL) { qFatal("Too many mods registered! Aborting!"); } multiplay_mods[i] = strdup(token); break; } case CLI_RESOLUTION: { unsigned int width, height; token = poptGetOptArg(poptCon); if (sscanf(token, "%ix%i", &width, &height) != 2) { qFatal("Invalid parameter specified (format is WIDTHxHEIGHT, e.g. 800x600)"); } if (width < 640) { debug(LOG_ERROR, "Screen width < 640 unsupported, using 640"); width = 640; } if (height < 480) { debug(LOG_ERROR, "Screen height < 480 unsupported, using 480"); height = 480; } // tell the display system of the desired resolution pie_SetVideoBufferWidth(width); pie_SetVideoBufferHeight(height); // and update the configuration war_SetWidth(width); war_SetHeight(height); break; } case CLI_SAVEGAME: // retrieve the game name token = poptGetOptArg(poptCon); if (token == NULL) { qFatal("Unrecognised savegame name"); } snprintf(saveGameName, sizeof(saveGameName), "%s/%s", SaveGamePath, token); SetGameMode(GS_SAVEGAMELOAD); break; case CLI_WINDOW: war_setFullscreen(false); break; case CLI_SHADOWS: setDrawShadows(true); break; case CLI_NOSHADOWS: setDrawShadows(false); break; case CLI_SOUND: war_setSoundEnabled(true); break; case CLI_NOSOUND: war_setSoundEnabled(false); break; case CLI_TEXTURECOMPRESSION: wz_texture_compression = GL_COMPRESSED_RGBA_ARB; break; case CLI_NOTEXTURECOMPRESSION: wz_texture_compression = GL_RGBA; break; }; } return true; }
/** * 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, const char **argv) { poptContext poptCon = poptGetContext(nullptr, argc, argv, getOptionsTable(), 0); int iOption; /* loop through command line */ while ((iOption = poptGetNextOpt(poptCon)) > 0) { const char *token; CLI_OPTIONS option = (CLI_OPTIONS)iOption; switch (option) { case CLI_DEBUG: case CLI_DEBUGFILE: case CLI_FLUSHDEBUGSTDERR: case CLI_CONFIGDIR: case CLI_HELP: case CLI_HELP_ALL: case CLI_VERSION: // These options are parsed in ParseCommandLineEarly() already, so ignore them break; case CLI_NOASSERT: kf_NoAssert(); break; // NOTE: The sole purpose of this is to test the crash handler. case CLI_CRASH: CauseCrash = true; NetPlay.bComms = false; sstrcpy(aLevelName, "CAM_3A"); SetGameMode(GS_NORMAL); break; case CLI_DATADIR: // retrieve the quoted path name token = poptGetOptArg(poptCon); if (token == nullptr) { qFatal("Unrecognised datadir"); } sstrcpy(datadir, token); break; case CLI_FULLSCREEN: war_setFullscreen(true); break; case CLI_CONNECTTOIP: //get the ip we want to connect with, and go directly to join screen. token = poptGetOptArg(poptCon); if (token == nullptr) { qFatal("No IP/hostname given"); } sstrcpy(iptoconnect, token); break; case CLI_HOSTLAUNCH: // go directly to host screen, bypass all others. hostlaunch = 1; break; case CLI_GAME: // retrieve the game name token = poptGetOptArg(poptCon); if (token == nullptr || (strcmp(token, "CAM_1A") && strcmp(token, "CAM_2A") && strcmp(token, "CAM_3A") && strcmp(token, "TUTORIAL3") && strcmp(token, "FASTPLAY"))) { qFatal("The game parameter requires one of the following keywords:" "CAM_1A, CAM_2A, CAM_3A, TUTORIAL3, or FASTPLAY."); } NetPlay.bComms = false; bMultiPlayer = false; bMultiMessages = false; for (int i = 0; i < MAX_PLAYERS; i++) { NET_InitPlayer(i, true, false); } //NET_InitPlayer deallocates Player 0, who must be allocated so that a later invocation of processDebugMappings does not trigger DEBUG mode NetPlay.players[0].allocated = true; if (!strcmp(token, "CAM_1A") || !strcmp(token, "CAM_2A") || !strcmp(token, "CAM_3A")) { game.type = CAMPAIGN; } else { game.type = SKIRMISH; // tutorial is skirmish for some reason } sstrcpy(aLevelName, token); SetGameMode(GS_NORMAL); break; case CLI_MOD_GLOB: { // retrieve the file name token = poptGetOptArg(poptCon); if (token == nullptr) { qFatal("Missing mod name?"); } global_mods.push_back(token); break; } case CLI_MOD_CA: { // retrieve the file name token = poptGetOptArg(poptCon); if (token == nullptr) { qFatal("Missing mod name?"); } campaign_mods.push_back(token); break; } case CLI_MOD_MP: { // retrieve the file name token = poptGetOptArg(poptCon); if (token == nullptr) { qFatal("Missing mod name?"); } multiplay_mods.push_back(token); break; } case CLI_RESOLUTION: { unsigned int width, height; token = poptGetOptArg(poptCon); if (sscanf(token, "%ix%i", &width, &height) != 2) { qFatal("Invalid parameter specified (format is WIDTHxHEIGHT, e.g. 800x600)"); } if (width < 640) { debug(LOG_ERROR, "Screen width < 640 unsupported, using 640"); width = 640; } if (height < 480) { debug(LOG_ERROR, "Screen height < 480 unsupported, using 480"); height = 480; } // tell the display system of the desired resolution pie_SetVideoBufferWidth(width); pie_SetVideoBufferHeight(height); // and update the configuration war_SetWidth(width); war_SetHeight(height); break; } case CLI_LOADSKIRMISH: // retrieve the game name token = poptGetOptArg(poptCon); if (token == nullptr) { qFatal("Unrecognised skirmish savegame name"); } snprintf(saveGameName, sizeof(saveGameName), "%s/skirmish/%s.gam", SaveGamePath, token); SPinit(); bMultiPlayer = true; game.type = SKIRMISH; // tutorial is skirmish for some reason SetGameMode(GS_SAVEGAMELOAD); break; case CLI_LOADCAMPAIGN: // retrieve the game name token = poptGetOptArg(poptCon); if (token == nullptr) { qFatal("Unrecognised campaign savegame name"); } snprintf(saveGameName, sizeof(saveGameName), "%s/campaign/%s.gam", SaveGamePath, token); SPinit(); SetGameMode(GS_SAVEGAMELOAD); break; case CLI_WINDOW: war_setFullscreen(false); break; case CLI_SHADOWS: setDrawShadows(true); break; case CLI_NOSHADOWS: setDrawShadows(false); break; case CLI_SOUND: war_setSoundEnabled(true); break; case CLI_NOSOUND: war_setSoundEnabled(false); break; case CLI_TEXTURECOMPRESSION: wz_texture_compression = true; break; case CLI_NOTEXTURECOMPRESSION: wz_texture_compression = false; break; case CLI_AUTOGAME: wz_autogame = true; break; case CLI_SAVEANDQUIT: token = poptGetOptArg(poptCon); if (token == nullptr || !strchr(token, '/')) { qFatal("Bad savegame name (needs to be a full path)"); } wz_saveandquit = token; break; case CLI_SKIRMISH: hostlaunch = 2; token = poptGetOptArg(poptCon); if (token == nullptr) { qFatal("Bad test key"); } wz_test = token; break; }; } return true; }