CommandLine.cpp 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. #include "PreRTS.h" // This must go first in EVERY cpp file in the GameEngine
  24. #include "Common/ArchiveFileSystem.h"
  25. #include "Common/CommandLine.h"
  26. #include "Common/CRCDebug.h"
  27. #include "Common/LocalFileSystem.h"
  28. #include "Common/Version.h"
  29. #include "GameClient/TerrainVisual.h" // for TERRAIN_LOD_MIN definition
  30. #include "GameClient/GameText.h"
  31. Bool TheDebugIgnoreSyncErrors = FALSE;
  32. extern Int DX8Wrapper_PreserveFPU;
  33. #ifdef DEBUG_CRC
  34. Int TheCRCFirstFrameToLog = -1;
  35. UnsignedInt TheCRCLastFrameToLog = 0xffffffff;
  36. Bool g_keepCRCSaves = FALSE;
  37. Bool g_crcModuleDataFromLogic = FALSE;
  38. Bool g_crcModuleDataFromClient = FALSE;
  39. Bool g_verifyClientCRC = FALSE; // verify that GameLogic CRC doesn't change from client
  40. Bool g_clientDeepCRC = FALSE;
  41. Bool g_logObjectCRCs = FALSE;
  42. #endif
  43. #if defined(_DEBUG) || defined(_INTERNAL)
  44. extern Bool g_useStringFile;
  45. #endif
  46. // Retval is number of cmd-line args eaten
  47. typedef Int (*FuncPtr)( char *args[], int num );
  48. static const UnsignedByte F_NOCASE = 1; // Case-insensitive
  49. struct CommandLineParam
  50. {
  51. const char *name;
  52. FuncPtr func;
  53. };
  54. static void ConvertShortMapPathToLongMapPath(AsciiString &mapName)
  55. {
  56. AsciiString path = mapName;
  57. AsciiString token;
  58. AsciiString actualpath;
  59. if ((path.find('\\') == NULL) && (path.find('/') == NULL))
  60. {
  61. DEBUG_CRASH(("Invalid map name %s", mapName.str()));
  62. return;
  63. }
  64. path.nextToken(&token, "\\/");
  65. while (!token.endsWithNoCase(".map") && (token.getLength() > 0))
  66. {
  67. actualpath.concat(token);
  68. actualpath.concat('\\');
  69. path.nextToken(&token, "\\/");
  70. }
  71. if (!token.endsWithNoCase(".map"))
  72. {
  73. DEBUG_CRASH(("Invalid map name %s", mapName.str()));
  74. }
  75. // remove the .map from the end.
  76. token.removeLastChar();
  77. token.removeLastChar();
  78. token.removeLastChar();
  79. token.removeLastChar();
  80. actualpath.concat(token);
  81. actualpath.concat('\\');
  82. actualpath.concat(token);
  83. actualpath.concat(".map");
  84. mapName = actualpath;
  85. }
  86. //=============================================================================
  87. //=============================================================================
  88. Int parseNoLogOrCrash(char *args[], int)
  89. {
  90. #ifdef ALLOW_DEBUG_UTILS
  91. DEBUG_CRASH(("-NoLogOrCrash not supported in this build\n"));
  92. #endif
  93. return 1;
  94. }
  95. //=============================================================================
  96. //=============================================================================
  97. Int parseWin(char *args[], int)
  98. {
  99. if (TheWritableGlobalData)
  100. {
  101. TheWritableGlobalData->m_windowed = true;
  102. }
  103. return 1;
  104. }
  105. //=============================================================================
  106. //=============================================================================
  107. Int parseNoMusic(char *args[], int)
  108. {
  109. if (TheWritableGlobalData)
  110. {
  111. TheWritableGlobalData->m_musicOn = false;
  112. }
  113. return 1;
  114. }
  115. //=============================================================================
  116. //=============================================================================
  117. Int parseNoVideo(char *args[], int)
  118. {
  119. if (TheWritableGlobalData)
  120. {
  121. TheWritableGlobalData->m_videoOn = false;
  122. }
  123. return 1;
  124. }
  125. //=============================================================================
  126. //=============================================================================
  127. Int parseFPUPreserve(char *args[], int argc)
  128. {
  129. if (argc > 1)
  130. {
  131. DX8Wrapper_PreserveFPU = atoi(args[1]);
  132. }
  133. return 2;
  134. }
  135. #if defined(_DEBUG) || defined(_INTERNAL)
  136. //=============================================================================
  137. //=============================================================================
  138. Int parseUseCSF(char *args[], int)
  139. {
  140. g_useStringFile = FALSE;
  141. return 1;
  142. }
  143. //=============================================================================
  144. //=============================================================================
  145. Int parseNoInputDisable(char *args[], int)
  146. {
  147. if (TheWritableGlobalData)
  148. {
  149. TheWritableGlobalData->m_disableScriptedInputDisabling = true;
  150. }
  151. return 1;
  152. }
  153. //=============================================================================
  154. //=============================================================================
  155. Int parseNoFade(char *args[], int)
  156. {
  157. if (TheWritableGlobalData)
  158. {
  159. TheWritableGlobalData->m_disableCameraFade = true;
  160. }
  161. return 1;
  162. }
  163. //=============================================================================
  164. //=============================================================================
  165. Int parseNoMilCap(char *args[], int)
  166. {
  167. if (TheWritableGlobalData)
  168. {
  169. TheWritableGlobalData->m_disableMilitaryCaption = true;
  170. }
  171. return 1;
  172. }
  173. //=============================================================================
  174. //=============================================================================
  175. Int parseDebugCRCFromFrame(char *args[], int argc)
  176. {
  177. #ifdef DEBUG_CRC
  178. if (argc > 1)
  179. {
  180. TheCRCFirstFrameToLog = atoi(args[1]);
  181. }
  182. #endif
  183. return 2;
  184. }
  185. //=============================================================================
  186. //=============================================================================
  187. Int parseDebugCRCUntilFrame(char *args[], int argc)
  188. {
  189. #ifdef DEBUG_CRC
  190. if (argc > 1)
  191. {
  192. TheCRCLastFrameToLog = atoi(args[1]);
  193. }
  194. #endif
  195. return 2;
  196. }
  197. //=============================================================================
  198. //=============================================================================
  199. Int parseKeepCRCSave(char *args[], int argc)
  200. {
  201. #ifdef DEBUG_CRC
  202. g_keepCRCSaves = TRUE;
  203. #endif
  204. return 1;
  205. }
  206. //=============================================================================
  207. //=============================================================================
  208. Int parseCRCLogicModuleData(char *args[], int argc)
  209. {
  210. #ifdef DEBUG_CRC
  211. g_crcModuleDataFromLogic = TRUE;
  212. #endif
  213. return 1;
  214. }
  215. //=============================================================================
  216. //=============================================================================
  217. Int parseCRCClientModuleData(char *args[], int argc)
  218. {
  219. #ifdef DEBUG_CRC
  220. g_crcModuleDataFromClient = TRUE;
  221. #endif
  222. return 1;
  223. }
  224. //=============================================================================
  225. //=============================================================================
  226. Int parseClientDeepCRC(char *args[], int argc)
  227. {
  228. #ifdef DEBUG_CRC
  229. g_clientDeepCRC = TRUE;
  230. #endif
  231. return 1;
  232. }
  233. //=============================================================================
  234. //=============================================================================
  235. Int parseVerifyClientCRC(char *args[], int argc)
  236. {
  237. #ifdef DEBUG_CRC
  238. g_verifyClientCRC = TRUE;
  239. #endif
  240. return 1;
  241. }
  242. //=============================================================================
  243. //=============================================================================
  244. Int parseLogObjectCRCs(char *args[], int argc)
  245. {
  246. #ifdef DEBUG_CRC
  247. g_logObjectCRCs = TRUE;
  248. #endif
  249. return 1;
  250. }
  251. //=============================================================================
  252. //=============================================================================
  253. Int parseNetCRCInterval(char *args[], int argc)
  254. {
  255. #ifdef DEBUG_CRC
  256. if (argc > 1)
  257. {
  258. NET_CRC_INTERVAL = atoi(args[1]);
  259. }
  260. #endif
  261. return 2;
  262. }
  263. //=============================================================================
  264. //=============================================================================
  265. Int parseReplayCRCInterval(char *args[], int argc)
  266. {
  267. #ifdef DEBUG_CRC
  268. if (argc > 1)
  269. {
  270. REPLAY_CRC_INTERVAL = atoi(args[1]);
  271. }
  272. #endif
  273. return 2;
  274. }
  275. //=============================================================================
  276. //=============================================================================
  277. Int parseNoDraw(char *args[], int argc)
  278. {
  279. #ifdef DEBUG_CRC
  280. if (TheWritableGlobalData)
  281. {
  282. TheWritableGlobalData->m_noDraw = TRUE;
  283. }
  284. #endif
  285. return 1;
  286. }
  287. //=============================================================================
  288. //=============================================================================
  289. Int parseLogToConsole(char *args[], int)
  290. {
  291. DebugSetFlags(DebugGetFlags() | DEBUG_FLAG_LOG_TO_CONSOLE);
  292. return 1;
  293. }
  294. #endif // _DEBUG || _INTERNAL
  295. //=============================================================================
  296. //=============================================================================
  297. Int parseNoAudio(char *args[], int)
  298. {
  299. if (TheWritableGlobalData)
  300. {
  301. TheWritableGlobalData->m_audioOn = false;
  302. TheWritableGlobalData->m_speechOn = false;
  303. TheWritableGlobalData->m_soundsOn = false;
  304. TheWritableGlobalData->m_musicOn = false;
  305. }
  306. return 1;
  307. }
  308. //=============================================================================
  309. //=============================================================================
  310. Int parseNoWin(char *args[], int)
  311. {
  312. if (TheWritableGlobalData)
  313. {
  314. TheWritableGlobalData->m_windowed = false;
  315. }
  316. return 1;
  317. }
  318. Int parseFullVersion(char *args[], int num)
  319. {
  320. if (TheVersion && num > 1)
  321. {
  322. TheVersion->setShowFullVersion(atoi(args[1]) != 0);
  323. }
  324. return 1;
  325. }
  326. Int parseNoShadows(char *args[], int)
  327. {
  328. if (TheWritableGlobalData)
  329. {
  330. TheWritableGlobalData->m_useShadowVolumes = false;
  331. TheWritableGlobalData->m_useShadowDecals = false;
  332. }
  333. return 1;
  334. }
  335. Int parseMapName(char *args[], int num)
  336. {
  337. if (TheWritableGlobalData && num == 2)
  338. {
  339. TheWritableGlobalData->m_mapName.set( args[ 1 ] );
  340. ConvertShortMapPathToLongMapPath(TheWritableGlobalData->m_mapName);
  341. }
  342. return 1;
  343. }
  344. Int parseXRes(char *args[], int num)
  345. {
  346. if (TheWritableGlobalData && num > 1)
  347. {
  348. TheWritableGlobalData->m_xResolution = atoi(args[1]);
  349. return 2;
  350. }
  351. return 1;
  352. }
  353. Int parseYRes(char *args[], int num)
  354. {
  355. if (TheWritableGlobalData && num > 1)
  356. {
  357. TheWritableGlobalData->m_yResolution = atoi(args[1]);
  358. return 2;
  359. }
  360. return 1;
  361. }
  362. #if defined(_DEBUG) || defined(_INTERNAL)
  363. //=============================================================================
  364. //=============================================================================
  365. Int parseLatencyAverage(char *args[], int num)
  366. {
  367. if (TheWritableGlobalData && num > 1)
  368. {
  369. TheWritableGlobalData->m_latencyAverage = atoi(args[1]);
  370. }
  371. return 2;
  372. }
  373. //=============================================================================
  374. //=============================================================================
  375. Int parseLatencyAmplitude(char *args[], int num)
  376. {
  377. if (TheWritableGlobalData && num > 1)
  378. {
  379. TheWritableGlobalData->m_latencyAmplitude = atoi(args[1]);
  380. }
  381. return 2;
  382. }
  383. //=============================================================================
  384. //=============================================================================
  385. Int parseLatencyPeriod(char *args[], int num)
  386. {
  387. if (TheWritableGlobalData && num > 1)
  388. {
  389. TheWritableGlobalData->m_latencyPeriod = atoi(args[1]);
  390. }
  391. return 2;
  392. }
  393. //=============================================================================
  394. //=============================================================================
  395. Int parseLatencyNoise(char *args[], int num)
  396. {
  397. if (TheWritableGlobalData && num > 1)
  398. {
  399. TheWritableGlobalData->m_latencyNoise = atoi(args[1]);
  400. }
  401. return 2;
  402. }
  403. //=============================================================================
  404. //=============================================================================
  405. Int parsePacketLoss(char *args[], int num)
  406. {
  407. if (TheWritableGlobalData && num > 1)
  408. {
  409. TheWritableGlobalData->m_packetLoss = atoi(args[1]);
  410. }
  411. return 2;
  412. }
  413. //=============================================================================
  414. //=============================================================================
  415. Int parseLowDetail(char *args[], int num)
  416. {
  417. if (TheWritableGlobalData)
  418. {
  419. TheWritableGlobalData->m_terrainLOD = TERRAIN_LOD_MIN;
  420. }
  421. return 1;
  422. }
  423. //=============================================================================
  424. //=============================================================================
  425. Int parseNoDynamicLOD(char *args[], int num)
  426. {
  427. if (TheWritableGlobalData)
  428. {
  429. TheWritableGlobalData->m_enableDynamicLOD = FALSE;
  430. }
  431. return 1;
  432. }
  433. //=============================================================================
  434. //=============================================================================
  435. Int parseNoStaticLOD(char *args[], int num)
  436. {
  437. if (TheWritableGlobalData)
  438. {
  439. TheWritableGlobalData->m_enableStaticLOD = FALSE;
  440. }
  441. return 1;
  442. }
  443. //=============================================================================
  444. //=============================================================================
  445. Int parseUseWaveEditor(char *args[], int num)
  446. {
  447. if (TheWritableGlobalData)
  448. {
  449. TheWritableGlobalData->m_usingWaterTrackEditor = TRUE;
  450. }
  451. return 1;
  452. }
  453. //=============================================================================
  454. //=============================================================================
  455. Int parseFPSLimit(char *args[], int num)
  456. {
  457. if (TheWritableGlobalData && num > 1)
  458. {
  459. TheWritableGlobalData->m_framesPerSecondLimit = atoi(args[1]);
  460. }
  461. return 2;
  462. }
  463. //=============================================================================
  464. Int parseNoViewLimit(char *args[], int)
  465. {
  466. if (TheWritableGlobalData)
  467. {
  468. TheWritableGlobalData->m_useCameraConstraints = FALSE;
  469. }
  470. return 1;
  471. }
  472. Int parseWireframe(char *args[], int)
  473. {
  474. if (TheWritableGlobalData)
  475. {
  476. TheWritableGlobalData->m_wireframe = TRUE;
  477. }
  478. return 1;
  479. }
  480. Int parseShowCollision(char *args[], int)
  481. {
  482. if (TheWritableGlobalData)
  483. {
  484. TheWritableGlobalData->m_showCollisionExtents = TRUE;
  485. }
  486. return 1;
  487. }
  488. Int parseNoShowClientPhysics(char *args[], int)
  489. {
  490. if (TheWritableGlobalData)
  491. {
  492. TheWritableGlobalData->m_showClientPhysics = FALSE;
  493. }
  494. return 1;
  495. }
  496. Int parseShowTerrainNormals(char *args[], int)
  497. {
  498. if (TheWritableGlobalData)
  499. {
  500. TheWritableGlobalData->m_showTerrainNormals = TRUE;
  501. }
  502. return 1;
  503. }
  504. Int parseStateMachineDebug(char *args[], int)
  505. {
  506. if (TheWritableGlobalData)
  507. {
  508. TheWritableGlobalData->m_stateMachineDebug = TRUE;
  509. }
  510. return 1;
  511. }
  512. Int parseJabber(char *args[], int)
  513. {
  514. if (TheWritableGlobalData)
  515. {
  516. TheWritableGlobalData->m_jabberOn = TRUE;
  517. }
  518. return 1;
  519. }
  520. Int parseMunkee(char *args[], int)
  521. {
  522. if (TheWritableGlobalData)
  523. {
  524. TheWritableGlobalData->m_munkeeOn = TRUE;
  525. }
  526. return 1;
  527. }
  528. #endif // defined(_DEBUG) || defined(_INTERNAL)
  529. Int parseScriptDebug(char *args[], int)
  530. {
  531. if (TheWritableGlobalData)
  532. {
  533. TheWritableGlobalData->m_scriptDebug = TRUE;
  534. TheWritableGlobalData->m_winCursors = TRUE;
  535. }
  536. return 1;
  537. }
  538. Int parseParticleEdit(char *args[], int)
  539. {
  540. if (TheWritableGlobalData)
  541. {
  542. TheWritableGlobalData->m_particleEdit = TRUE;
  543. TheWritableGlobalData->m_winCursors = TRUE;
  544. TheWritableGlobalData->m_windowed = TRUE;
  545. }
  546. return 1;
  547. }
  548. Int parseBuildMapCache(char *args[], int)
  549. {
  550. if (TheWritableGlobalData)
  551. {
  552. TheWritableGlobalData->m_buildMapCache = true;
  553. }
  554. return 1;
  555. }
  556. #if defined(_DEBUG) || defined(_INTERNAL)
  557. Int parseDisplayDebug(char *args[], int)
  558. {
  559. if (TheWritableGlobalData)
  560. {
  561. TheWritableGlobalData->m_displayDebug = TRUE;
  562. }
  563. return 1;
  564. }
  565. Int parseFile(char *args[], int num)
  566. {
  567. if (TheWritableGlobalData && num > 1)
  568. {
  569. TheWritableGlobalData->m_initialFile = args[1];
  570. ConvertShortMapPathToLongMapPath(TheWritableGlobalData->m_initialFile);
  571. }
  572. return 2;
  573. }
  574. Int parsePreload( char *args[], int num )
  575. {
  576. if( TheWritableGlobalData )
  577. TheWritableGlobalData->m_preloadAssets = TRUE;
  578. return 1;
  579. }
  580. Int parsePreloadEverything( char *args[], int num )
  581. {
  582. if( TheWritableGlobalData )
  583. {
  584. TheWritableGlobalData->m_preloadAssets = TRUE;
  585. TheWritableGlobalData->m_preloadEverything = TRUE;
  586. }
  587. return 1;
  588. }
  589. Int parseLogAssets( char *args[], int num )
  590. {
  591. if( TheWritableGlobalData )
  592. {
  593. FILE *logfile=fopen("PreloadedAssets.txt","w");
  594. if (logfile) //clear the file
  595. fclose(logfile);
  596. TheWritableGlobalData->m_preloadReport = TRUE;
  597. }
  598. return 1;
  599. }
  600. /// begin stuff for VTUNE
  601. Int parseVTune ( char *args[], int num )
  602. {
  603. if( TheWritableGlobalData )
  604. TheWritableGlobalData->m_vTune = TRUE;
  605. return 1;
  606. }
  607. /// end stuff for VTUNE
  608. #endif // defined(_DEBUG) || defined(_INTERNAL)
  609. //=============================================================================
  610. //=============================================================================
  611. Int parseNoFX(char *args[], int)
  612. {
  613. if (TheWritableGlobalData)
  614. {
  615. TheWritableGlobalData->m_useFX = FALSE;
  616. }
  617. return 1;
  618. }
  619. #if defined(_DEBUG) || defined(_INTERNAL)
  620. Int parseNoShroud(char *args[], int)
  621. {
  622. if (TheWritableGlobalData)
  623. {
  624. TheWritableGlobalData->m_shroudOn = FALSE;
  625. }
  626. return 1;
  627. }
  628. #endif
  629. Int parseForceBenchmark(char *args[], int)
  630. {
  631. if (TheWritableGlobalData)
  632. {
  633. TheWritableGlobalData->m_forceBenchmark = TRUE;
  634. }
  635. return 1;
  636. }
  637. Int parseNoMoveCamera(char *args[], int)
  638. {
  639. if (TheWritableGlobalData)
  640. {
  641. TheWritableGlobalData->m_disableCameraMovement = true;
  642. }
  643. return 1;
  644. }
  645. #if defined(_DEBUG) || defined(_INTERNAL)
  646. Int parseNoCinematic(char *args[], int)
  647. {
  648. if (TheWritableGlobalData)
  649. {
  650. TheWritableGlobalData->m_disableCameraMovement = true;
  651. TheWritableGlobalData->m_disableMilitaryCaption = true;
  652. TheWritableGlobalData->m_disableCameraFade = true;
  653. TheWritableGlobalData->m_disableScriptedInputDisabling = true;
  654. }
  655. return 1;
  656. }
  657. #endif
  658. Int parseSync(char *args[], int)
  659. {
  660. if (TheWritableGlobalData)
  661. {
  662. TheDebugIgnoreSyncErrors = true;
  663. }
  664. return 1;
  665. }
  666. Int parseNoShellMap(char *args[], int)
  667. {
  668. if (TheWritableGlobalData)
  669. {
  670. TheWritableGlobalData->m_shellMapOn = FALSE;
  671. }
  672. return 1;
  673. }
  674. #if !defined(_PLAYTEST) || (defined(_DEBUG) || defined(_INTERNAL))
  675. Int parseNoLogo(char *args[], int)
  676. {
  677. if (TheWritableGlobalData)
  678. {
  679. TheWritableGlobalData->m_playIntro = FALSE;
  680. TheWritableGlobalData->m_afterIntro = TRUE;
  681. }
  682. return 1;
  683. }
  684. #endif
  685. Int parseShellMap(char *args[], int num)
  686. {
  687. if (TheWritableGlobalData && num > 1)
  688. {
  689. TheWritableGlobalData->m_shellMapName = args[1];
  690. }
  691. return 2;
  692. }
  693. Int parseNoWindowAnimation(char *args[], int num)
  694. {
  695. if (TheWritableGlobalData)
  696. {
  697. TheWritableGlobalData->m_animateWindows = FALSE;
  698. }
  699. return 1;
  700. }
  701. Int parseWinCursors(char *args[], int num)
  702. {
  703. if (TheWritableGlobalData)
  704. {
  705. TheWritableGlobalData->m_winCursors = TRUE;
  706. }
  707. return 1;
  708. }
  709. Int parseQuickStart( char *args[], int num )
  710. {
  711. parseNoLogo( args, num );
  712. parseNoShellMap( args, num );
  713. parseNoWindowAnimation( args, num );
  714. return 1;
  715. }
  716. Int parseConstantDebug( char *args[], int num )
  717. {
  718. if (TheWritableGlobalData)
  719. {
  720. TheWritableGlobalData->m_constantDebugUpdate = TRUE;
  721. }
  722. return 1;
  723. }
  724. Int parseShowTeamDot( char *args[], int num )
  725. {
  726. if( TheWritableGlobalData )
  727. {
  728. TheWritableGlobalData->m_showTeamDot = TRUE;
  729. }
  730. return 1;
  731. }
  732. #if defined(_DEBUG) || defined(_INTERNAL)
  733. Int parseSelectAll( char *args[], int num )
  734. {
  735. if( TheWritableGlobalData )
  736. {
  737. TheWritableGlobalData->m_allowUnselectableSelection = TRUE;
  738. }
  739. return 1;
  740. }
  741. Int parseRunAhead( char *args[], Int num )
  742. {
  743. if (num > 2)
  744. {
  745. MIN_RUNAHEAD = atoi(args[1]);
  746. MAX_FRAMES_AHEAD = atoi(args[2]);
  747. FRAME_DATA_LENGTH = (MAX_FRAMES_AHEAD + 1)*2;
  748. }
  749. return 3;
  750. }
  751. #endif
  752. Int parseSeed(char *args[], int num)
  753. {
  754. if (TheWritableGlobalData && num > 1)
  755. {
  756. TheWritableGlobalData->m_fixedSeed = atoi(args[1]);
  757. }
  758. return 2;
  759. }
  760. Int parseIncrAGPBuf(char *args[], int num)
  761. {
  762. if (TheWritableGlobalData)
  763. {
  764. TheWritableGlobalData->m_incrementalAGPBuf = TRUE;
  765. }
  766. return 1;
  767. }
  768. Int parseNetMinPlayers(char *args[], int num)
  769. {
  770. if (TheWritableGlobalData && num > 1)
  771. {
  772. TheWritableGlobalData->m_netMinPlayers = atoi(args[1]);
  773. }
  774. return 2;
  775. }
  776. Int parsePlayStats(char *args[], int num)
  777. {
  778. if (TheWritableGlobalData && num > 1)
  779. {
  780. TheWritableGlobalData->m_playStats = atoi(args[1]);
  781. }
  782. return 2;
  783. }
  784. Int parseDemoLoadScreen(char *args[], int num)
  785. {
  786. if (TheWritableGlobalData)
  787. {
  788. TheWritableGlobalData->m_loadScreenDemo = TRUE;
  789. }
  790. return 1;
  791. }
  792. #if defined(_DEBUG) || defined(_INTERNAL)
  793. Int parseSaveStats(char *args[], int num)
  794. {
  795. if (TheWritableGlobalData && num > 1)
  796. {
  797. TheWritableGlobalData->m_saveStats = TRUE;
  798. TheWritableGlobalData->m_baseStatsDir = args[1];
  799. }
  800. return 2;
  801. }
  802. #endif
  803. #if defined(_DEBUG) || defined(_INTERNAL)
  804. Int parseSaveAllStats(char *args[], int num)
  805. {
  806. if (TheWritableGlobalData && num > 1)
  807. {
  808. TheWritableGlobalData->m_saveStats = TRUE;
  809. TheWritableGlobalData->m_baseStatsDir = args[1];
  810. TheWritableGlobalData->m_saveAllStats = TRUE;
  811. }
  812. return 2;
  813. }
  814. #endif
  815. #if defined(_DEBUG) || defined(_INTERNAL)
  816. Int parseLocalMOTD(char *args[], int num)
  817. {
  818. if (TheWritableGlobalData && num > 1)
  819. {
  820. TheWritableGlobalData->m_useLocalMOTD = TRUE;
  821. TheWritableGlobalData->m_MOTDPath = args[1];
  822. }
  823. return 2;
  824. }
  825. #endif
  826. #if defined(_DEBUG) || defined(_INTERNAL)
  827. Int parseCameraDebug(char *args[], int num)
  828. {
  829. if (TheWritableGlobalData)
  830. {
  831. TheWritableGlobalData->m_debugCamera = TRUE;
  832. }
  833. return 1;
  834. }
  835. #endif
  836. #if defined(_DEBUG) || defined(_INTERNAL)
  837. Int parseBenchmark(char *args[], int num)
  838. {
  839. if (TheWritableGlobalData && num > 1)
  840. {
  841. TheWritableGlobalData->m_benchmarkTimer = atoi(args[1]);
  842. TheWritableGlobalData->m_playStats = atoi(args[1]);
  843. }
  844. return 2;
  845. }
  846. #endif
  847. #if defined(_DEBUG) || defined(_INTERNAL)
  848. Int parseIgnoreAsserts(char *args[], int num)
  849. {
  850. if (TheWritableGlobalData && num > 0)
  851. {
  852. TheWritableGlobalData->m_debugIgnoreAsserts = true;
  853. }
  854. return 1;
  855. }
  856. #endif
  857. #if defined(_DEBUG) || defined(_INTERNAL)
  858. Int parseIgnoreStackTrace(char *args[], int num)
  859. {
  860. if (TheWritableGlobalData && num > 0)
  861. {
  862. TheWritableGlobalData->m_debugIgnoreStackTrace = true;
  863. }
  864. return 1;
  865. }
  866. #endif
  867. Int parseNoFPSLimit(char *args[], int num)
  868. {
  869. if (TheWritableGlobalData)
  870. {
  871. TheWritableGlobalData->m_useFpsLimit = false;
  872. TheWritableGlobalData->m_framesPerSecondLimit = 30000;
  873. }
  874. return 1;
  875. }
  876. Int parseDumpAssetUsage(char *args[], int num)
  877. {
  878. if (TheWritableGlobalData)
  879. {
  880. TheWritableGlobalData->m_dumpAssetUsage = true;
  881. }
  882. return 1;
  883. }
  884. Int parseJumpToFrame(char *args[], int num)
  885. {
  886. if (TheWritableGlobalData && num > 1)
  887. {
  888. parseNoFPSLimit(args, num);
  889. TheWritableGlobalData->m_noDraw = atoi(args[1]);
  890. return 2;
  891. }
  892. return 1;
  893. }
  894. Int parseUpdateImages(char *args[], int num)
  895. {
  896. if (TheWritableGlobalData)
  897. {
  898. TheWritableGlobalData->m_shouldUpdateTGAToDDS = TRUE;
  899. }
  900. return 1;
  901. }
  902. Int parseMod(char *args[], Int num)
  903. {
  904. if (TheWritableGlobalData && num > 1)
  905. {
  906. AsciiString modPath = args[1];
  907. if (strchr(modPath.str(), ':') || modPath.startsWith("/") || modPath.startsWith("\\"))
  908. {
  909. // full path passed in. Don't append base path.
  910. }
  911. else
  912. {
  913. modPath.format("%s%s", TheGlobalData->getPath_UserData().str(), args[1]);
  914. }
  915. DEBUG_LOG(("Looking for mod '%s'\n", modPath.str()));
  916. if (!TheLocalFileSystem->doesFileExist(modPath.str()))
  917. {
  918. DEBUG_LOG(("Mod does not exist.\n"));
  919. return 2; // no such file/dir.
  920. }
  921. // now check for dir-ness
  922. struct stat statBuf;
  923. if (stat(modPath.str(), &statBuf) != 0)
  924. {
  925. DEBUG_LOG(("Could not _stat() mod.\n"));
  926. return 2; // could not stat the file/dir.
  927. }
  928. if (statBuf.st_mode & S_IFDIR)
  929. {
  930. if (!modPath.endsWith("\\") && !modPath.endsWith("/"))
  931. modPath.concat('\\');
  932. DEBUG_LOG(("Mod dir is '%s'.\n", modPath.str()));
  933. TheWritableGlobalData->m_modDir = modPath;
  934. }
  935. else
  936. {
  937. DEBUG_LOG(("Mod file is '%s'.\n", modPath.str()));
  938. TheWritableGlobalData->m_modBIG = modPath;
  939. }
  940. return 2;
  941. }
  942. return 1;
  943. }
  944. #if defined(_DEBUG) || defined(_INTERNAL)
  945. Int parseSetDebugLevel(char *args[], int num)
  946. {
  947. if (num > 1)
  948. {
  949. AsciiString val = args[1];
  950. for (Int i=0; i<DEBUG_LEVEL_MAX; ++i)
  951. {
  952. if (val == TheDebugLevels[i])
  953. {
  954. DebugLevelMask |= 1<<i;
  955. break;
  956. }
  957. }
  958. }
  959. return 2;
  960. }
  961. Int parseClearDebugLevel(char *args[], int num)
  962. {
  963. if (num > 1)
  964. {
  965. AsciiString val = args[1];
  966. for (Int i=0; i<DEBUG_LEVEL_MAX; ++i)
  967. {
  968. if (val == TheDebugLevels[i])
  969. {
  970. DebugLevelMask &= ~(1<<i);
  971. break;
  972. }
  973. }
  974. }
  975. return 2;
  976. }
  977. #endif
  978. static CommandLineParam params[] =
  979. {
  980. { "-noshellmap", parseNoShellMap },
  981. { "-win", parseWin },
  982. { "-xres", parseXRes },
  983. { "-yres", parseYRes },
  984. { "-fullscreen", parseNoWin },
  985. { "-fullVersion", parseFullVersion },
  986. { "-particleEdit", parseParticleEdit },
  987. { "-scriptDebug", parseScriptDebug },
  988. { "-playStats", parsePlayStats },
  989. { "-mod", parseMod },
  990. #if !defined(_PLAYTEST) || (defined(_DEBUG) || defined(_INTERNAL))
  991. { "-noaudio", parseNoAudio },
  992. { "-map", parseMapName },
  993. { "-nomusic", parseNoMusic },
  994. { "-novideo", parseNoVideo },
  995. { "-noLogOrCrash", parseNoLogOrCrash },
  996. { "-FPUPreserve", parseFPUPreserve },
  997. #if defined(_DEBUG) || defined(_INTERNAL)
  998. { "-benchmark", parseBenchmark },
  999. { "-saveStats", parseSaveStats },
  1000. { "-localMOTD", parseLocalMOTD },
  1001. { "-UseCSF", parseUseCSF },
  1002. { "-NoInputDisable", parseNoInputDisable },
  1003. { "-DebugCRCFromFrame", parseDebugCRCFromFrame },
  1004. { "-DebugCRCUntilFrame", parseDebugCRCUntilFrame },
  1005. { "-KeepCRCSaves", parseKeepCRCSave },
  1006. { "-CRCLogicModuleData", parseCRCLogicModuleData },
  1007. { "-CRCClientModuleData", parseCRCClientModuleData },
  1008. { "-ClientDeepCRC", parseClientDeepCRC },
  1009. { "-VerifyClientCRC", parseVerifyClientCRC },
  1010. { "-LogObjectCRCs", parseLogObjectCRCs },
  1011. { "-saveAllStats", parseSaveAllStats },
  1012. { "-NetCRCInterval", parseNetCRCInterval },
  1013. { "-ReplayCRCInterval", parseReplayCRCInterval },
  1014. { "-noDraw", parseNoDraw },
  1015. { "-nomilcap", parseNoMilCap },
  1016. { "-nofade", parseNoFade },
  1017. { "-nomovecamera", parseNoMoveCamera },
  1018. { "-nocinematic", parseNoCinematic },
  1019. { "-packetloss", parsePacketLoss },
  1020. { "-latAvg", parseLatencyAverage },
  1021. { "-latAmp", parseLatencyAmplitude },
  1022. { "-latPeriod", parseLatencyPeriod },
  1023. { "-latNoise", parseLatencyNoise },
  1024. { "-noViewLimit", parseNoViewLimit },
  1025. { "-lowDetail", parseLowDetail },
  1026. { "-noDynamicLOD", parseNoDynamicLOD },
  1027. { "-noStaticLOD", parseNoStaticLOD },
  1028. { "-useWaveEditor", parseUseWaveEditor },
  1029. { "-fps", parseFPSLimit },
  1030. { "-wireframe", parseWireframe },
  1031. { "-showCollision", parseShowCollision },
  1032. { "-noShowClientPhysics", parseNoShowClientPhysics },
  1033. { "-showTerrainNormals", parseShowTerrainNormals },
  1034. { "-stateMachineDebug", parseStateMachineDebug },
  1035. { "-jabber", parseJabber },
  1036. { "-munkee", parseMunkee },
  1037. { "-displayDebug", parseDisplayDebug },
  1038. { "-file", parseFile },
  1039. { "-preload", parsePreload },
  1040. { "-preloadEverything", parsePreloadEverything },
  1041. { "-logAssets", parseLogAssets },
  1042. { "-netMinPlayers", parseNetMinPlayers },
  1043. { "-DemoLoadScreen", parseDemoLoadScreen },
  1044. { "-cameraDebug", parseCameraDebug },
  1045. { "-ignoreAsserts", parseIgnoreAsserts },
  1046. { "-ignoreStackTrace", parseIgnoreStackTrace },
  1047. { "-logToCon", parseLogToConsole },
  1048. { "-vTune", parseVTune },
  1049. { "-selectTheUnselectable", parseSelectAll },
  1050. { "-RunAhead", parseRunAhead },
  1051. { "-noshroud", parseNoShroud },
  1052. { "-setDebugLevel", parseSetDebugLevel },
  1053. { "-clearDebugLevel", parseClearDebugLevel },
  1054. #endif
  1055. { "-forceBenchmark", parseForceBenchmark },
  1056. { "-buildmapcache", parseBuildMapCache },
  1057. { "-noshadowvolumes", parseNoShadows },
  1058. { "-nofx", parseNoFX },
  1059. { "-ignoresync", parseSync },
  1060. { "-nologo", parseNoLogo },
  1061. { "-shellmap", parseShellMap },
  1062. { "-noShellAnim", parseNoWindowAnimation },
  1063. { "-winCursors", parseWinCursors },
  1064. { "-constantDebug", parseConstantDebug },
  1065. { "-quickstart", parseQuickStart },
  1066. { "-seed", parseSeed },
  1067. { "-noagpfix", parseIncrAGPBuf },
  1068. { "-noFPSLimit", parseNoFPSLimit },
  1069. { "-dumpAssetUsage", parseDumpAssetUsage },
  1070. { "-jumpToFrame", parseJumpToFrame },
  1071. { "-updateImages", parseUpdateImages },
  1072. { "-showTeamDot", parseShowTeamDot },
  1073. #endif
  1074. };
  1075. // parseCommandLine ===========================================================
  1076. /** Parse command-line parameters. */
  1077. //=============================================================================
  1078. void parseCommandLine(int argc, char *argv[])
  1079. {
  1080. // To parse command-line parameters, we loop through a table holding arguments
  1081. // and functions to handle them. Comparisons can be case-(in)sensitive, and
  1082. // can check the entire string (for testing the presence of a flag) or check
  1083. // just the start (for a key=val argument). The handling function can also
  1084. // look at the next argument(s), to accomodate multi-arg parameters, e.g. "-p 1234".
  1085. int arg=1, param;
  1086. Bool found;
  1087. #ifdef DEBUG_LOGGING
  1088. DEBUG_LOG(("Command-line args:"));
  1089. int debugFlags = DebugGetFlags();
  1090. DebugSetFlags(debugFlags & ~DEBUG_FLAG_PREPEND_TIME); // turn off timestamps
  1091. for (arg=1; arg<argc; arg++)
  1092. {
  1093. DEBUG_LOG((" %s", argv[arg]));
  1094. }
  1095. DEBUG_LOG(("\n"));
  1096. DebugSetFlags(debugFlags); // turn timestamps back on iff they were on before
  1097. arg = 1;
  1098. #endif // DEBUG_LOGGING
  1099. while (arg<argc)
  1100. {
  1101. // Look at arg #i
  1102. found = false;
  1103. for (param=0; !found && param<sizeof(params)/sizeof(params[0]); ++param)
  1104. {
  1105. int len = strlen(params[param].name);
  1106. int len2 = strlen(argv[arg]);
  1107. if (len2 != len)
  1108. continue;
  1109. if (!strnicmp(argv[arg], params[param].name, len))
  1110. {
  1111. arg += params[param].func(argv+arg, argc-arg);
  1112. found = true;
  1113. }
  1114. } // for
  1115. if (!found)
  1116. {
  1117. arg++;
  1118. }
  1119. }
  1120. TheArchiveFileSystem->loadMods();
  1121. }