From 308fe041d4388511a7cd00af296801a979fe5423 Mon Sep 17 00:00:00 2001 From: RT Date: Sat, 25 Jul 2026 08:54:10 -0500 Subject: [PATCH] Make -help a complete command line reference MW4.exe accepts 76 command line switches. Only 27 of them appeared in the old -help output, that output went to the debug log rather than to the user, and it did not stop the game from launching afterwards -- so in practice the switches were undocumented. -help now writes a full, categorised reference to mw4-help.txt next to the executable, opens it in Notepad, and returns from WinMain without starting the game. If Notepad cannot be launched, a message box reports where the file was written. The check runs immediately after the command line is lower-cased at the top of WinMain, before any subsystem is initialised. A file plus a viewer was chosen over a message box because MW4 is a GUI-subsystem application with no console, and 76 switches with real descriptions do not fit legibly in a dialog. The reference documents every switch actually parsed, grouped as: display and video, audio and plasma display, pod hardware and arcade (CTCL), zoom and field of view, multiplayer and network, logging and diagnostics, development and test builds, and other. Each entry records the accepted value range where the parser enforces one -- for example -tbaud 9600-921600, -armorlevel 0-4, -tmfds 0-4, -zmfovb 0.01-0.5, and the -zmtime special case where 0 means instant. Two switches are listed under "recognised but inactive" so their behaviour is not misrepresented: -join, whose consuming line is commented out, and -noabzug, which is only parsed inside a disabled code path. The LAB-only switches are marked as accepted and ignored in Release builds. The old partial SPEWALWAYS list in GetGameOSEnvironment was removed so there is a single maintained reference rather than two that can drift apart. A comment there points at the new one. Also adds an explicit #include ; this translation unit previously had no direct stdio use and relied on transitive inclusion. Co-authored-by: Claude Opus 5 (Anthropic) Co-authored-by: GitHub Copilot --- .../Code/MW4Application/MW4Application.cpp | 273 +++++++++++++++--- 1 file changed, 230 insertions(+), 43 deletions(-) diff --git a/Gameleap/code/mw4/Code/MW4Application/MW4Application.cpp b/Gameleap/code/mw4/Code/MW4Application/MW4Application.cpp index 01dc4d62..5cf46209 100644 --- a/Gameleap/code/mw4/Code/MW4Application/MW4Application.cpp +++ b/Gameleap/code/mw4/Code/MW4Application/MW4Application.cpp @@ -16,6 +16,7 @@ #include "MW4AppHeaders.hpp" #include "MW4Application.hpp" #include +#include // [help] FILE/fopen/fprintf used by MW4_ShowCommandLineHelp #include #include #include @@ -819,6 +820,223 @@ GetEnvironmentVariableA( LPSTR lpBuffer, DWORD nSize ); +// [help] --------------------------------------------------------------------- +// Complete command-line reference, shown by "MW4.exe -help". +// +// MW4 is a GUI-subsystem application, so there is no console to print to when it +// is launched normally. -help therefore writes the full reference to +// mw4-help.txt next to the executable, opens it in Notepad, and exits without +// starting the game. If Notepad cannot be launched, a message box reports where +// the file was written. +// +// KEEP THIS IN SYNC when adding or changing a command-line switch. +static const char* const g_apszCommandLineHelp[] = +{ +"BattleTech: FireStorm - MW4.exe command line reference", +"======================================================", +"", +"Usage: MW4.exe [options]", +"", +"Options may appear in any order and are case-insensitive. An option that takes", +"a value must be followed by a single space and then the value, for example:", +"", +" MW4.exe -tmfds 4 -tmon 1,2,3,4 -tbaud 115200", +"", +"Values outside the documented range are ignored and the default is kept.", +"", +"", +"DISPLAY AND VIDEO", +"-----------------", +" -window Run in a window instead of fullscreen.", +" -fullscreen Force fullscreen. Overrides -window.", +" -tmfds <0-4> MFD output mode:", +" 0 = no MFDs", +" 1 = original 1280x480 span (5 channels + radar)", +" 2 = black and white (3 channels + 1 dual)", +" 3 = colour (3 channels + 2 dual)", +" 4 = split dual 640x480 - drives two independent", +" MFD monitors, so no span hardware is needed", +" -tmon ,,, Hard-assign display devices in the order", +" main, radar, MFD1, MFD2. Values are 1-based; a", +" value of 0 leaves that slot auto-detected.", +" Separators may be ',' '/' or ':'.", +" MFD1 and MFD2 only apply with -tmfds 4.", +" Example: -tmon 1,2,4,3 swaps the two MFD panels.", +" -mechview <1|2> Show the rotating mech view. 1 = on the radar", +" -mv <1|2> screen, 2 = on the main screen. Default: off.", +" -3dt Draw the MFD target as a live 3D model instead of", +" the pre-rendered 2D bitmaps.", +" -capdev <0-7> Select which device screen captures come from:", +" 0 main, 1 radar, 2 mission review, 3 hudchat,", +" 4 nav, 5 weapon, 6 target, 7 armor", +"", +"", +"AUDIO AND PLASMA DISPLAY", +"------------------------", +" -nosound Disable all sound output.", +" -noplasma Disable the COM2 plasma score display.", +" -pctime Plasma display clear time. Minimum 3.", +"", +"", +"POD HARDWARE AND ARCADE (CTCL)", +"------------------------------", +" -ctcltype <1-3> CTCL role for this machine:", +" -ctcl <1-3> 1 = console, 2 = game pod, 3 = cameraship.", +" Default when absent: console.", +" -dragon Disable CTCL entirely and run standalone.", +" -coop Co-operative arcade mode. Implies 1 coin per game", +" and the game-pod role.", +" -#coop Co-op with an explicit coin count. A negative", +" value selects the cameraship role instead.", +" -trio <0|1> RIO cockpit board protocol. 0 = original board,", +" 1 = newer protocol (different framing and acks).", +" -tbaud <9600-921600> Force the COM1 baud rate for the RIO board. Use", +" for replica boards with a high-speed UART. The", +" wire protocol is unchanged; only the rate differs.", +" -useorgjoy Use the original joystick axis mapping.", +" -ojoy Same as -useorgjoy.", +" -usetockeys Enable TOC keys. They are disabled by default.", +" -tocadt TOC auto-detect timeout. Minimum 5.", +" -auxadt AUX auto-detect timeout. Minimum 3.", +" -usecam Force camera mode. Implied by the cameraship role.", +" -suicide Allow self-destruct at any time.", +" -jpd Enable JPD input handling.", +"", +"", +"ZOOM AND FIELD OF VIEW", +"----------------------", +" -zmfova <0.01-0.5> Zoom field-of-view, stage A.", +" -zmfovb <0.01-0.5> Zoom field-of-view, stage B. A and B are swapped", +" automatically so that A is the wider of the two.", +" -zmmrgn <0.01-0.49> Zoom left/right margin, as a fraction of width.", +" -zmtime <0, or 0.05-3.0> Zoom transition time in seconds. 0 = instant.", +"", +"", +"MULTIPLAYER AND NETWORK", +"-----------------------", +" -serve Automatically host a server game on startup.", +" -lobby Indicates the game was started from a lobby.", +" -game Load the named game/mission file.", +" -gamename Name advertised for the hosted game.", +" -playername Player name to use.", +" -password Password for the hosted or joined game.", +" -advertiseport Port used to advertise the server.", +" -ipx Use IPX in the server browser.", +" -nodplay Disable DirectPlay networking.", +" -directplayprotocol Force use of the DirectPlay protocol.", +" -secure Enable secure networking for the game session.", +" -set_internet Configure network settings for internet play.", +" -set_lan Configure network settings for LAN play.", +" -win32dedicated Run as a Win32 dedicated server. Disables sound", +" and rendering and uses the dedicated server UI.", +" -allowmultiple Allow more than one instance of the game to run.", +" -oldmpui Use the older multiplayer user interface.", +"", +"", +"LOGGING AND DIAGNOSTICS", +"-----------------------", +" -zlogstyle ZLog output style.", +" -zlogflush ZLog flush behaviour.", +" -zlogbuffer ZLog buffer size.", +" -zlogname ZLog output file name.", +" -olog Write the legacy .log match report instead of the", +" newer .rpt format.", +" -gamestats Save game statistics.", +" -help Show this reference and exit without starting.", +"", +"", +"DEVELOPMENT AND TEST BUILDS", +"---------------------------", +"The following are only active in LAB (Debug, Armor and Profile) builds. In a", +"Release build they are accepted and ignored.", +"", +" -build Rebuild the resource packages at startup.", +" -norun Do not run the game after building.", +" -demo Demo mode.", +" -rekey Re-key resources.", +" -bloat Enable bloat diagnostics.", +" -reportnotresourced Report assets that are not in a resource package.", +" -armorlevel <0-4> Assertion/armor checking level.", +" -leak Memory trace level.", +" -diskfirst Prefer loose files on disk over packaged data.", +" -testclasses Run internal class self-tests.", +" -aistats Enable AI statistics collection.", +" -bspmap Save BSP map differences.", +" -showscripterrors Display script errors as they occur.", +" -mrtest Mission review test mode.", +" -prtest Print report test mode.", +" -nowrc Disable weapon range checking.", +" -regs Debug builds only: enable script regions.", +" -spew Debug builds only: enable script spews.", +"", +"", +"OTHER", +"-----", +" -nocd Skip the CD check. (The CD check is already", +" disabled unconditionally in this build.)", +" -noeula Skip the end user licence agreement screen.", +" -noautoconfig Skip automatic video and sound configuration.", +"", +"", +"RECOGNISED BUT INACTIVE", +"-----------------------", +" -join Parsed for compatibility but has no effect; the", +" code that consumed it is commented out.", +" -noabzug Parsed only in a disabled code path.", +"", +"", +"RELATED CONFIGURATION", +"---------------------", +"Most persistent settings live in options.ini next to MW4.exe rather than on the", +"command line. See OPTIONS-INI.md in the source repository for a full reference.", +"Arcade pod assignments live in c:\\ctcl.ini.", +NULL +}; + +static void MW4_ShowCommandLineHelp() +{ + char szDir[MAX_PATH]; + char szPath[MAX_PATH]; + + // Write next to the executable rather than the working directory, so the file + // is easy to find no matter how the game was launched. + szDir[0] = '\0'; + GetModuleFileNameA(NULL, szDir, sizeof(szDir)); + char* pSlash = strrchr(szDir, '\\'); + if (pSlash) + *(pSlash + 1) = '\0'; + else + szDir[0] = '\0'; + sprintf(szPath, "%smw4-help.txt", szDir); + + FILE* f = fopen(szPath, "wt"); + if (!f) + { + MessageBoxA(NULL, + "Could not write mw4-help.txt next to MW4.exe.\n" + "Check that the folder is writable.", + "MW4 command line help", MB_OK | MB_ICONWARNING); + return; + } + + for (int i = 0; g_apszCommandLineHelp[i] != NULL; i++) + fprintf(f, "%s\n", g_apszCommandLineHelp[i]); + fclose(f); + + // Open it for the user. WinExec is used rather than ShellExecute to avoid a + // dependency on shellapi.h in this translation unit. + char szCmd[MAX_PATH + 32]; + sprintf(szCmd, "notepad.exe \"%s\"", szPath); + if (WinExec(szCmd, SW_SHOWNORMAL) < 32) + { + char szMsg[MAX_PATH + 128]; + sprintf(szMsg, + "The MW4.exe command line reference was written to:\n\n%s", + szPath); + MessageBoxA(NULL, szMsg, "MW4 command line help", MB_OK | MB_ICONINFORMATION); + } +} + void __stdcall GetGameOSEnvironment(char* CommandLine) { #ifdef _DEBUG @@ -1179,49 +1397,10 @@ DWORD __stdcall gos_EnableSetting( gosSetting Setting, DWORD Value ); #endif } - if (strstr(all_lower, "-help")) - { - SPEWALWAYS((NULL, "Command line options:\n")); - SPEWALWAYS((NULL, "-allowmultiple")); - SPEWALWAYS((NULL, "-lobby")); - SPEWALWAYS((NULL, "-game ")); - SPEWALWAYS((NULL, "-gamename ")); - SPEWALWAYS((NULL, "-playername ")); - SPEWALWAYS((NULL, "-serve")); - SPEWALWAYS((NULL, "-join")); - SPEWALWAYS((NULL, "-nosound")); - SPEWALWAYS((NULL, "-window")); - - SPEWALWAYS((NULL, "-zlogstyle ")); - SPEWALWAYS((NULL, "-zlogflush ")); - SPEWALWAYS((NULL, "-zlogbuffer ")); - SPEWALWAYS((NULL, "-zlogname ")); - - SPEWALWAYS((NULL, "-secure")); - - SPEWALWAYS((NULL, "-ipx")); - - - #ifdef LAB_ONLY - SPEWALWAYS((NULL, "-nodplay")); - SPEWALWAYS((NULL, "-dontuseipx")); - SPEWALWAYS((NULL, "-dontusetcp")); - SPEWALWAYS((NULL, "-dontusegamespy")); - SPEWALWAYS((NULL, "-dontusegun")); - SPEWALWAYS((NULL, "-aistats")); - SPEWALWAYS((NULL, "-oldmpui")); - SPEWALWAYS((NULL, "-testclasses")); - SPEWALWAYS((NULL, "-build")); - SPEWALWAYS((NULL, "-norun")); - SPEWALWAYS((NULL, "-demo")); - SPEWALWAYS((NULL, "-rekey")); - SPEWALWAYS((NULL, "-bloat")); - SPEWALWAYS((NULL, "-reportnotresourced")); - SPEWALWAYS((NULL, "-armorlevel ")); - SPEWALWAYS((NULL, "-leak ")); - SPEWALWAYS((NULL, "-diskfirst")); - #endif - } + // [help] -help is handled at the top of WinMain (see MW4_ShowCommandLineHelp), + // which runs before this and exits the process. The old partial list that used + // to live here was incomplete and only reached the debug log, so it was removed + // in favour of a single maintained reference. if (MWApplication::AutoLaunchServerGame || MWApplication::Win32DedicatedServer) @@ -1297,6 +1476,14 @@ int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int n for (p=all_lower; i>0; ++p,--i) *p=(char)tolower(*p); + // [help] Handle -help before anything is initialised: write the full command + // line reference next to the exe, open it, and exit without starting the game. + if (strstr(all_lower, "-help")) + { + MW4_ShowCommandLineHelp(); + return 0; + } + char *token; // jcem - begin token = strstr(all_lower, "-ctcltype ");