/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program 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 3 of the License, or
** (at your option) any later version.
**
** This program 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 this program. If not, see .
*/
////////////////////////////////////////////////////////////////////////////////
// //
// (c) 2001-2003 Electronic Arts Inc. //
// //
////////////////////////////////////////////////////////////////////////////////
#include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine
#include "Common/ArchiveFileSystem.h"
#include "Common/CommandLine.h"
#include "Common/CRCDebug.h"
#include "Common/LocalFileSystem.h"
#include "Common/Version.h"
#include "GameClient/TerrainVisual.h" // for TERRAIN_LOD_MIN definition
#include "GameClient/GameText.h"
#ifdef _INTERNAL
// for occasional debugging...
//#pragma optimize("", off)
//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
#endif
Bool TheDebugIgnoreSyncErrors = FALSE;
extern Int DX8Wrapper_PreserveFPU;
#ifdef DEBUG_CRC
Int TheCRCFirstFrameToLog = -1;
UnsignedInt TheCRCLastFrameToLog = 0xffffffff;
Bool g_keepCRCSaves = FALSE;
Bool g_crcModuleDataFromLogic = FALSE;
Bool g_crcModuleDataFromClient = FALSE;
Bool g_verifyClientCRC = FALSE; // verify that GameLogic CRC doesn't change from client
Bool g_clientDeepCRC = FALSE;
Bool g_logObjectCRCs = FALSE;
#endif
#if defined(_DEBUG) || defined(_INTERNAL)
extern Bool g_useStringFile;
#endif
// Retval is number of cmd-line args eaten
typedef Int (*FuncPtr)( char *args[], int num );
static const UnsignedByte F_NOCASE = 1; // Case-insensitive
struct CommandLineParam
{
const char *name;
FuncPtr func;
};
static void ConvertShortMapPathToLongMapPath(AsciiString &mapName)
{
AsciiString path = mapName;
AsciiString token;
AsciiString actualpath;
if ((path.find('\\') == NULL) && (path.find('/') == NULL))
{
DEBUG_CRASH(("Invalid map name %s", mapName.str()));
return;
}
path.nextToken(&token, "\\/");
while (!token.endsWithNoCase(".map") && (token.getLength() > 0))
{
actualpath.concat(token);
actualpath.concat('\\');
path.nextToken(&token, "\\/");
}
if (!token.endsWithNoCase(".map"))
{
DEBUG_CRASH(("Invalid map name %s", mapName.str()));
}
// remove the .map from the end.
token.removeLastChar();
token.removeLastChar();
token.removeLastChar();
token.removeLastChar();
actualpath.concat(token);
actualpath.concat('\\');
actualpath.concat(token);
actualpath.concat(".map");
mapName = actualpath;
}
//=============================================================================
//=============================================================================
Int parseNoLogOrCrash(char *args[], int)
{
#ifdef ALLOW_DEBUG_UTILS
DEBUG_CRASH(("-NoLogOrCrash not supported in this build\n"));
#endif
return 1;
}
//=============================================================================
//=============================================================================
Int parseWin(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_windowed = true;
}
return 1;
}
//=============================================================================
//=============================================================================
Int parseNoMusic(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_musicOn = false;
}
return 1;
}
//=============================================================================
//=============================================================================
Int parseNoVideo(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_videoOn = false;
}
return 1;
}
//=============================================================================
//=============================================================================
Int parseFPUPreserve(char *args[], int argc)
{
if (argc > 1)
{
DX8Wrapper_PreserveFPU = atoi(args[1]);
}
return 2;
}
#if defined(_DEBUG) || defined(_INTERNAL)
//=============================================================================
//=============================================================================
Int parseUseCSF(char *args[], int)
{
g_useStringFile = FALSE;
return 1;
}
//=============================================================================
//=============================================================================
Int parseNoInputDisable(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_disableScriptedInputDisabling = true;
}
return 1;
}
//=============================================================================
//=============================================================================
Int parseNoFade(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_disableCameraFade = true;
}
return 1;
}
//=============================================================================
//=============================================================================
Int parseNoMilCap(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_disableMilitaryCaption = true;
}
return 1;
}
//=============================================================================
//=============================================================================
Int parseDebugCRCFromFrame(char *args[], int argc)
{
#ifdef DEBUG_CRC
if (argc > 1)
{
TheCRCFirstFrameToLog = atoi(args[1]);
}
#endif
return 2;
}
//=============================================================================
//=============================================================================
Int parseDebugCRCUntilFrame(char *args[], int argc)
{
#ifdef DEBUG_CRC
if (argc > 1)
{
TheCRCLastFrameToLog = atoi(args[1]);
}
#endif
return 2;
}
//=============================================================================
//=============================================================================
Int parseKeepCRCSave(char *args[], int argc)
{
#ifdef DEBUG_CRC
g_keepCRCSaves = TRUE;
#endif
return 1;
}
//=============================================================================
//=============================================================================
Int parseCRCLogicModuleData(char *args[], int argc)
{
#ifdef DEBUG_CRC
g_crcModuleDataFromLogic = TRUE;
#endif
return 1;
}
//=============================================================================
//=============================================================================
Int parseCRCClientModuleData(char *args[], int argc)
{
#ifdef DEBUG_CRC
g_crcModuleDataFromClient = TRUE;
#endif
return 1;
}
//=============================================================================
//=============================================================================
Int parseClientDeepCRC(char *args[], int argc)
{
#ifdef DEBUG_CRC
g_clientDeepCRC = TRUE;
#endif
return 1;
}
//=============================================================================
//=============================================================================
Int parseVerifyClientCRC(char *args[], int argc)
{
#ifdef DEBUG_CRC
g_verifyClientCRC = TRUE;
#endif
return 1;
}
//=============================================================================
//=============================================================================
Int parseLogObjectCRCs(char *args[], int argc)
{
#ifdef DEBUG_CRC
g_logObjectCRCs = TRUE;
#endif
return 1;
}
//=============================================================================
//=============================================================================
Int parseNetCRCInterval(char *args[], int argc)
{
#ifdef DEBUG_CRC
if (argc > 1)
{
NET_CRC_INTERVAL = atoi(args[1]);
}
#endif
return 2;
}
//=============================================================================
//=============================================================================
Int parseReplayCRCInterval(char *args[], int argc)
{
#ifdef DEBUG_CRC
if (argc > 1)
{
REPLAY_CRC_INTERVAL = atoi(args[1]);
}
#endif
return 2;
}
//=============================================================================
//=============================================================================
Int parseNoDraw(char *args[], int argc)
{
#ifdef DEBUG_CRC
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_noDraw = TRUE;
}
#endif
return 1;
}
//=============================================================================
//=============================================================================
Int parseLogToConsole(char *args[], int)
{
DebugSetFlags(DebugGetFlags() | DEBUG_FLAG_LOG_TO_CONSOLE);
return 1;
}
#endif // _DEBUG || _INTERNAL
//=============================================================================
//=============================================================================
Int parseNoAudio(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_audioOn = false;
TheWritableGlobalData->m_speechOn = false;
TheWritableGlobalData->m_soundsOn = false;
TheWritableGlobalData->m_musicOn = false;
}
return 1;
}
//=============================================================================
//=============================================================================
Int parseNoWin(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_windowed = false;
}
return 1;
}
Int parseFullVersion(char *args[], int num)
{
if (TheVersion && num > 1)
{
TheVersion->setShowFullVersion(atoi(args[1]) != 0);
}
return 1;
}
Int parseNoShadows(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_useShadowVolumes = false;
TheWritableGlobalData->m_useShadowDecals = false;
}
return 1;
}
Int parseMapName(char *args[], int num)
{
if (TheWritableGlobalData && num == 2)
{
TheWritableGlobalData->m_mapName.set( args[ 1 ] );
ConvertShortMapPathToLongMapPath(TheWritableGlobalData->m_mapName);
}
return 1;
}
Int parseXRes(char *args[], int num)
{
if (TheWritableGlobalData && num > 1)
{
TheWritableGlobalData->m_xResolution = atoi(args[1]);
return 2;
}
return 1;
}
Int parseYRes(char *args[], int num)
{
if (TheWritableGlobalData && num > 1)
{
TheWritableGlobalData->m_yResolution = atoi(args[1]);
return 2;
}
return 1;
}
#if defined(_DEBUG) || defined(_INTERNAL)
//=============================================================================
//=============================================================================
Int parseLatencyAverage(char *args[], int num)
{
if (TheWritableGlobalData && num > 1)
{
TheWritableGlobalData->m_latencyAverage = atoi(args[1]);
}
return 2;
}
//=============================================================================
//=============================================================================
Int parseLatencyAmplitude(char *args[], int num)
{
if (TheWritableGlobalData && num > 1)
{
TheWritableGlobalData->m_latencyAmplitude = atoi(args[1]);
}
return 2;
}
//=============================================================================
//=============================================================================
Int parseLatencyPeriod(char *args[], int num)
{
if (TheWritableGlobalData && num > 1)
{
TheWritableGlobalData->m_latencyPeriod = atoi(args[1]);
}
return 2;
}
//=============================================================================
//=============================================================================
Int parseLatencyNoise(char *args[], int num)
{
if (TheWritableGlobalData && num > 1)
{
TheWritableGlobalData->m_latencyNoise = atoi(args[1]);
}
return 2;
}
//=============================================================================
//=============================================================================
Int parsePacketLoss(char *args[], int num)
{
if (TheWritableGlobalData && num > 1)
{
TheWritableGlobalData->m_packetLoss = atoi(args[1]);
}
return 2;
}
//=============================================================================
//=============================================================================
Int parseLowDetail(char *args[], int num)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_terrainLOD = TERRAIN_LOD_MIN;
}
return 1;
}
//=============================================================================
//=============================================================================
Int parseNoDynamicLOD(char *args[], int num)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_enableDynamicLOD = FALSE;
}
return 1;
}
//=============================================================================
//=============================================================================
Int parseNoStaticLOD(char *args[], int num)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_enableStaticLOD = FALSE;
}
return 1;
}
//=============================================================================
//=============================================================================
Int parseUseWaveEditor(char *args[], int num)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_usingWaterTrackEditor = TRUE;
}
return 1;
}
//=============================================================================
//=============================================================================
Int parseFPSLimit(char *args[], int num)
{
if (TheWritableGlobalData && num > 1)
{
TheWritableGlobalData->m_framesPerSecondLimit = atoi(args[1]);
}
return 2;
}
//=============================================================================
Int parseNoViewLimit(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_useCameraConstraints = FALSE;
}
return 1;
}
Int parseWireframe(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_wireframe = TRUE;
}
return 1;
}
Int parseShowCollision(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_showCollisionExtents = TRUE;
}
return 1;
}
Int parseNoShowClientPhysics(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_showClientPhysics = FALSE;
}
return 1;
}
Int parseShowTerrainNormals(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_showTerrainNormals = TRUE;
}
return 1;
}
Int parseStateMachineDebug(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_stateMachineDebug = TRUE;
}
return 1;
}
Int parseJabber(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_jabberOn = TRUE;
}
return 1;
}
Int parseMunkee(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_munkeeOn = TRUE;
}
return 1;
}
#endif // defined(_DEBUG) || defined(_INTERNAL)
Int parseScriptDebug(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_scriptDebug = TRUE;
TheWritableGlobalData->m_winCursors = TRUE;
}
return 1;
}
Int parseParticleEdit(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_particleEdit = TRUE;
TheWritableGlobalData->m_winCursors = TRUE;
TheWritableGlobalData->m_windowed = TRUE;
}
return 1;
}
Int parseBuildMapCache(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_buildMapCache = true;
}
return 1;
}
#if defined(_DEBUG) || defined(_INTERNAL) || defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE)
Int parsePreload( char *args[], int num )
{
if( TheWritableGlobalData )
TheWritableGlobalData->m_preloadAssets = TRUE;
return 1;
}
#endif
#if defined(_DEBUG) || defined(_INTERNAL)
Int parseDisplayDebug(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_displayDebug = TRUE;
}
return 1;
}
Int parseFile(char *args[], int num)
{
if (TheWritableGlobalData && num > 1)
{
TheWritableGlobalData->m_initialFile = args[1];
ConvertShortMapPathToLongMapPath(TheWritableGlobalData->m_initialFile);
}
return 2;
}
Int parsePreloadEverything( char *args[], int num )
{
if( TheWritableGlobalData )
{
TheWritableGlobalData->m_preloadAssets = TRUE;
TheWritableGlobalData->m_preloadEverything = TRUE;
}
return 1;
}
Int parseLogAssets( char *args[], int num )
{
if( TheWritableGlobalData )
{
FILE *logfile=fopen("PreloadedAssets.txt","w");
if (logfile) //clear the file
fclose(logfile);
TheWritableGlobalData->m_preloadReport = TRUE;
}
return 1;
}
/// begin stuff for VTUNE
Int parseVTune ( char *args[], int num )
{
if( TheWritableGlobalData )
TheWritableGlobalData->m_vTune = TRUE;
return 1;
}
/// end stuff for VTUNE
#endif // defined(_DEBUG) || defined(_INTERNAL)
//=============================================================================
//=============================================================================
Int parseNoFX(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_useFX = FALSE;
}
return 1;
}
#if defined(_DEBUG) || defined(_INTERNAL)
Int parseNoShroud(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_shroudOn = FALSE;
}
return 1;
}
#endif
Int parseForceBenchmark(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_forceBenchmark = TRUE;
}
return 1;
}
Int parseNoMoveCamera(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_disableCameraMovement = true;
}
return 1;
}
#if defined(_DEBUG) || defined(_INTERNAL)
Int parseNoCinematic(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_disableCameraMovement = true;
TheWritableGlobalData->m_disableMilitaryCaption = true;
TheWritableGlobalData->m_disableCameraFade = true;
TheWritableGlobalData->m_disableScriptedInputDisabling = true;
}
return 1;
}
#endif
Int parseSync(char *args[], int)
{
if (TheWritableGlobalData)
{
TheDebugIgnoreSyncErrors = true;
}
return 1;
}
Int parseNoShellMap(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_shellMapOn = FALSE;
}
return 1;
}
Int parseNoShaders(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_chipSetType = 1; //force to a voodoo card which uses least amount of features.
}
return 1;
}
#if (defined(_DEBUG) || defined(_INTERNAL))
Int parseNoLogo(char *args[], int)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_playIntro = FALSE;
TheWritableGlobalData->m_afterIntro = TRUE;
TheWritableGlobalData->m_playSizzle = FALSE;
}
return 1;
}
#endif
Int parseNoSizzle( char *args[], int )
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_playSizzle = FALSE;
}
return 1;
}
Int parseShellMap(char *args[], int num)
{
if (TheWritableGlobalData && num > 1)
{
TheWritableGlobalData->m_shellMapName = args[1];
}
return 2;
}
Int parseNoWindowAnimation(char *args[], int num)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_animateWindows = FALSE;
}
return 1;
}
Int parseWinCursors(char *args[], int num)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_winCursors = TRUE;
}
return 1;
}
Int parseQuickStart( char *args[], int num )
{
#if (defined(_DEBUG) || defined(_INTERNAL))
parseNoLogo( args, num );
#else
//Kris: Patch 1.01 -- Allow release builds to skip the sizzle video, but still force the EA logo to show up.
//This is for legal reasons.
parseNoSizzle( args, num );
#endif
parseNoShellMap( args, num );
parseNoWindowAnimation( args, num );
return 1;
}
Int parseConstantDebug( char *args[], int num )
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_constantDebugUpdate = TRUE;
}
return 1;
}
#if (defined(_DEBUG) || defined(_INTERNAL))
Int parseExtraLogging( char *args[], int num )
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_extraLogging = TRUE;
}
return 1;
}
#endif
//-allAdvice feature
/*
Int parseAllAdvice( char *args[], int num )
{
if( TheWritableGlobalData )
{
TheWritableGlobalData->m_allAdvice = TRUE;
}
return 1;
}
*/
Int parseShowTeamDot( char *args[], int num )
{
if( TheWritableGlobalData )
{
TheWritableGlobalData->m_showTeamDot = TRUE;
}
return 1;
}
#if defined(_DEBUG) || defined(_INTERNAL)
Int parseSelectAll( char *args[], int num )
{
if( TheWritableGlobalData )
{
TheWritableGlobalData->m_allowUnselectableSelection = TRUE;
}
return 1;
}
Int parseRunAhead( char *args[], Int num )
{
if (num > 2)
{
MIN_RUNAHEAD = atoi(args[1]);
MAX_FRAMES_AHEAD = atoi(args[2]);
FRAME_DATA_LENGTH = (MAX_FRAMES_AHEAD + 1)*2;
}
return 3;
}
#endif
Int parseSeed(char *args[], int num)
{
if (TheWritableGlobalData && num > 1)
{
TheWritableGlobalData->m_fixedSeed = atoi(args[1]);
}
return 2;
}
Int parseIncrAGPBuf(char *args[], int num)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_incrementalAGPBuf = TRUE;
}
return 1;
}
Int parseNetMinPlayers(char *args[], int num)
{
if (TheWritableGlobalData && num > 1)
{
TheWritableGlobalData->m_netMinPlayers = atoi(args[1]);
}
return 2;
}
Int parsePlayStats(char *args[], int num)
{
if (TheWritableGlobalData && num > 1)
{
TheWritableGlobalData->m_playStats = atoi(args[1]);
}
return 2;
}
Int parseDemoLoadScreen(char *args[], int num)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_loadScreenDemo = TRUE;
}
return 1;
}
#if defined(_DEBUG) || defined(_INTERNAL)
Int parseSaveStats(char *args[], int num)
{
if (TheWritableGlobalData && num > 1)
{
TheWritableGlobalData->m_saveStats = TRUE;
TheWritableGlobalData->m_baseStatsDir = args[1];
}
return 2;
}
#endif
#if defined(_DEBUG) || defined(_INTERNAL)
Int parseSaveAllStats(char *args[], int num)
{
if (TheWritableGlobalData && num > 1)
{
TheWritableGlobalData->m_saveStats = TRUE;
TheWritableGlobalData->m_baseStatsDir = args[1];
TheWritableGlobalData->m_saveAllStats = TRUE;
}
return 2;
}
#endif
#if defined(_DEBUG) || defined(_INTERNAL)
Int parseLocalMOTD(char *args[], int num)
{
if (TheWritableGlobalData && num > 1)
{
TheWritableGlobalData->m_useLocalMOTD = TRUE;
TheWritableGlobalData->m_MOTDPath = args[1];
}
return 2;
}
#endif
#if defined(_DEBUG) || defined(_INTERNAL)
Int parseCameraDebug(char *args[], int num)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_debugCamera = TRUE;
}
return 1;
}
#endif
#if defined(_DEBUG) || defined(_INTERNAL)
Int parseBenchmark(char *args[], int num)
{
if (TheWritableGlobalData && num > 1)
{
TheWritableGlobalData->m_benchmarkTimer = atoi(args[1]);
TheWritableGlobalData->m_playStats = atoi(args[1]);
}
return 2;
}
#endif
#if defined(_DEBUG) || defined(_INTERNAL)
#ifdef DUMP_PERF_STATS
Int parseStats(char *args[], int num)
{
if (TheWritableGlobalData && num > 1)
{
TheWritableGlobalData->m_dumpStatsAtInterval = TRUE;
TheWritableGlobalData->m_statsInterval = atoi(args[1]);
}
return 2;
}
#endif
#endif
#if defined(_DEBUG) || defined(_INTERNAL)
Int parseIgnoreAsserts(char *args[], int num)
{
if (TheWritableGlobalData && num > 0)
{
TheWritableGlobalData->m_debugIgnoreAsserts = true;
}
return 1;
}
#endif
#if defined(_DEBUG) || defined(_INTERNAL)
Int parseIgnoreStackTrace(char *args[], int num)
{
if (TheWritableGlobalData && num > 0)
{
TheWritableGlobalData->m_debugIgnoreStackTrace = true;
}
return 1;
}
#endif
Int parseNoFPSLimit(char *args[], int num)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_useFpsLimit = false;
TheWritableGlobalData->m_framesPerSecondLimit = 30000;
}
return 1;
}
Int parseDumpAssetUsage(char *args[], int num)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_dumpAssetUsage = true;
}
return 1;
}
Int parseJumpToFrame(char *args[], int num)
{
if (TheWritableGlobalData && num > 1)
{
parseNoFPSLimit(args, num);
TheWritableGlobalData->m_noDraw = atoi(args[1]);
return 2;
}
return 1;
}
Int parseUpdateImages(char *args[], int num)
{
if (TheWritableGlobalData)
{
TheWritableGlobalData->m_shouldUpdateTGAToDDS = TRUE;
}
return 1;
}
Int parseMod(char *args[], Int num)
{
if (TheWritableGlobalData && num > 1)
{
AsciiString modPath = args[1];
if (strchr(modPath.str(), ':') || modPath.startsWith("/") || modPath.startsWith("\\"))
{
// full path passed in. Don't append base path.
}
else
{
modPath.format("%s%s", TheGlobalData->getPath_UserData().str(), args[1]);
}
DEBUG_LOG(("Looking for mod '%s'\n", modPath.str()));
if (!TheLocalFileSystem->doesFileExist(modPath.str()))
{
DEBUG_LOG(("Mod does not exist.\n"));
return 2; // no such file/dir.
}
// now check for dir-ness
struct _stat statBuf;
if (_stat(modPath.str(), &statBuf) != 0)
{
DEBUG_LOG(("Could not _stat() mod.\n"));
return 2; // could not stat the file/dir.
}
if (statBuf.st_mode & _S_IFDIR)
{
if (!modPath.endsWith("\\") && !modPath.endsWith("/"))
modPath.concat('\\');
DEBUG_LOG(("Mod dir is '%s'.\n", modPath.str()));
TheWritableGlobalData->m_modDir = modPath;
}
else
{
DEBUG_LOG(("Mod file is '%s'.\n", modPath.str()));
TheWritableGlobalData->m_modBIG = modPath;
}
return 2;
}
return 1;
}
static CommandLineParam params[] =
{
{ "-noshellmap", parseNoShellMap },
{ "-win", parseWin },
{ "-xres", parseXRes },
{ "-yres", parseYRes },
{ "-fullscreen", parseNoWin },
{ "-fullVersion", parseFullVersion },
{ "-particleEdit", parseParticleEdit },
{ "-scriptDebug", parseScriptDebug },
{ "-playStats", parsePlayStats },
{ "-mod", parseMod },
{ "-noshaders", parseNoShaders },
{ "-quickstart", parseQuickStart },
#if (defined(_DEBUG) || defined(_INTERNAL))
{ "-noaudio", parseNoAudio },
{ "-map", parseMapName },
{ "-nomusic", parseNoMusic },
{ "-novideo", parseNoVideo },
{ "-noLogOrCrash", parseNoLogOrCrash },
{ "-FPUPreserve", parseFPUPreserve },
{ "-benchmark", parseBenchmark },
#ifdef DUMP_PERF_STATS
{ "-stats", parseStats },
#endif
{ "-saveStats", parseSaveStats },
{ "-localMOTD", parseLocalMOTD },
{ "-UseCSF", parseUseCSF },
{ "-NoInputDisable", parseNoInputDisable },
{ "-DebugCRCFromFrame", parseDebugCRCFromFrame },
{ "-DebugCRCUntilFrame", parseDebugCRCUntilFrame },
{ "-KeepCRCSaves", parseKeepCRCSave },
{ "-CRCLogicModuleData", parseCRCLogicModuleData },
{ "-CRCClientModuleData", parseCRCClientModuleData },
{ "-ClientDeepCRC", parseClientDeepCRC },
{ "-VerifyClientCRC", parseVerifyClientCRC },
{ "-LogObjectCRCs", parseLogObjectCRCs },
{ "-saveAllStats", parseSaveAllStats },
{ "-NetCRCInterval", parseNetCRCInterval },
{ "-ReplayCRCInterval", parseReplayCRCInterval },
{ "-noDraw", parseNoDraw },
{ "-nomilcap", parseNoMilCap },
{ "-nofade", parseNoFade },
{ "-nomovecamera", parseNoMoveCamera },
{ "-nocinematic", parseNoCinematic },
{ "-packetloss", parsePacketLoss },
{ "-latAvg", parseLatencyAverage },
{ "-latAmp", parseLatencyAmplitude },
{ "-latPeriod", parseLatencyPeriod },
{ "-latNoise", parseLatencyNoise },
{ "-noViewLimit", parseNoViewLimit },
{ "-lowDetail", parseLowDetail },
{ "-noDynamicLOD", parseNoDynamicLOD },
{ "-noStaticLOD", parseNoStaticLOD },
{ "-useWaveEditor", parseUseWaveEditor },
{ "-fps", parseFPSLimit },
{ "-wireframe", parseWireframe },
{ "-showCollision", parseShowCollision },
{ "-noShowClientPhysics", parseNoShowClientPhysics },
{ "-showTerrainNormals", parseShowTerrainNormals },
{ "-stateMachineDebug", parseStateMachineDebug },
{ "-jabber", parseJabber },
{ "-munkee", parseMunkee },
{ "-displayDebug", parseDisplayDebug },
{ "-file", parseFile },
// { "-preload", parsePreload },
{ "-preloadEverything", parsePreloadEverything },
{ "-logAssets", parseLogAssets },
{ "-netMinPlayers", parseNetMinPlayers },
{ "-DemoLoadScreen", parseDemoLoadScreen },
{ "-cameraDebug", parseCameraDebug },
{ "-ignoreAsserts", parseIgnoreAsserts },
{ "-ignoreStackTrace", parseIgnoreStackTrace },
{ "-logToCon", parseLogToConsole },
{ "-vTune", parseVTune },
{ "-selectTheUnselectable", parseSelectAll },
{ "-RunAhead", parseRunAhead },
{ "-noshroud", parseNoShroud },
{ "-forceBenchmark", parseForceBenchmark },
{ "-buildmapcache", parseBuildMapCache },
{ "-noshadowvolumes", parseNoShadows },
{ "-nofx", parseNoFX },
{ "-ignoresync", parseSync },
{ "-nologo", parseNoLogo },
{ "-shellmap", parseShellMap },
{ "-noShellAnim", parseNoWindowAnimation },
{ "-winCursors", parseWinCursors },
{ "-constantDebug", parseConstantDebug },
{ "-seed", parseSeed },
{ "-noagpfix", parseIncrAGPBuf },
{ "-noFPSLimit", parseNoFPSLimit },
{ "-dumpAssetUsage", parseDumpAssetUsage },
{ "-jumpToFrame", parseJumpToFrame },
{ "-updateImages", parseUpdateImages },
{ "-showTeamDot", parseShowTeamDot },
{ "-extraLogging", parseExtraLogging },
#endif
//-allAdvice feature
//{ "-allAdvice", parseAllAdvice },
#if defined(_DEBUG) || defined(_INTERNAL) || defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE)
{ "-preload", parsePreload },
#endif
};
// parseCommandLine ===========================================================
/** Parse command-line parameters. */
//=============================================================================
void parseCommandLine(int argc, char *argv[])
{
// To parse command-line parameters, we loop through a table holding arguments
// and functions to handle them. Comparisons can be case-(in)sensitive, and
// can check the entire string (for testing the presence of a flag) or check
// just the start (for a key=val argument). The handling function can also
// look at the next argument(s), to accomodate multi-arg parameters, e.g. "-p 1234".
int arg=1, param;
Bool found;
#ifdef DEBUG_LOGGING
DEBUG_LOG(("Command-line args:"));
int debugFlags = DebugGetFlags();
DebugSetFlags(debugFlags & ~DEBUG_FLAG_PREPEND_TIME); // turn off timestamps
for (arg=1; argloadMods();
}