shithub: choc

Download patch

ref: 0d3b41b4a00e11b09583069b8f7f72a11400d737
parent: fd1d07746f16e03cb7f07c0b57a8b373d0e144e9
author: Simon Howard <[email protected]>
date: Sun Dec 24 18:53:15 EST 2006

Javadoc-style self-documenting system for command line options.

Subversion-branch: /trunk/chocolate-doom
Subversion-revision: 806

--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -1,5 +1,5 @@
 
-MANPAGE_GEN_FILES=chocolate-doom-options.in head foot Makefile doom-options.in
+MANPAGE_GEN_FILES=header footer 
 
 man_MANS=chocolate-doom.6
 
@@ -6,9 +6,5 @@
 EXTRA_DIST = $(man_MANS) $(MANPAGE_GEN_FILES)
 
 chocolate-doom.6: $(MANPAGE_GEN_FILES)
-	cp head $@
-	echo .SH DOOM OPTIONS >> $@
-	awk -F"\t" '{print ".TP\n\\fB"$$1"\\fR"; $$1=""; print }' < doom-options.in >>$@
-	echo .SH CHOCOLATE DOOM OPTIONS >> $@
-	awk -F"\t" '{print ".TP\n\\fB"$$1"\\fR"; $$1=""; print }' < chocolate-doom-options.in >>$@
-	sed "s/AUTHORS/`cat ../AUTHORS`/" < foot >> $@
+	./docgen > $@
+
--- a/man/chocolate-doom-options.in
+++ /dev/null
@@ -1,14 +1,0 @@
--1	Sets screenmultiply to 1
--2	Sets screenmultiply to 2, doubling up the screen by 2x.
--extraconfig <file>	Specifies a configuration file to use for Chocolate Doom-specific settings. The default is 'chocolate-doom.cfg'
--fullscreen	Runs the game fullscreen. 
--nofullscreen	Runs the game in a window
--window	runs the game in a window
--gameversion <ver>	Emulates a specific release of Doom 1.9.  Valid values are "1.9", "ultimate" and "final".
--grabmouse	Grabs the mouse during play
--nograbmouse	Does not grab the mouse during play
--iwad <file>	Specifies an IWAD file to use. If unspecified, chocolate doom will look for doom2.wad, doom.wad, tnt.wad, plutonia.wad, in /usr/share/games/doom, and the current directory.
--longtics	When recording demos, records in the the modified "Doom v1.91" format to avoid losing turning resolution.
--merge <file>	Loads a PWAD but simulates merging it into the main IWAD
--novert	Turns on novert
--nonovert	Turns off novert
--- /dev/null
+++ b/man/docgen
@@ -1,0 +1,154 @@
+#!/usr/bin/env python
+
+import re
+import glob
+
+class Category:
+    def __init__(self, description):
+        self.description = description
+        self.params = []
+
+    def add_param(self, param):
+        self.params.append(param)
+
+    def format(self):
+        result = ".SH " + self.description.upper() + "\n"
+
+        for p in self.params:
+            result += ".TP\n"
+            result += p.format()
+
+        return result
+
+categories = {
+    None:      Category("General options"),
+    "video":   Category("Display options"),
+    "demo":    Category("Demo options"),
+    "net":     Category("Networking options"),
+    "mod":     Category("Dehacked and WAD merging"),
+    "compat":  Category("Compatibility"),
+}
+
+class Parameter:
+    def __init__(self):
+        self.text = ""
+        self.name = ""
+        self.args = None
+        self.platform = None
+        self.category = None
+
+    def add_text(self, text):
+        if len(text) <= 0:
+            pass
+        elif text[0] == "@":
+            match = re.match('@(\S+)\s+(.*)', text)
+
+            if not match:
+                raise "Malformed option line: %s" % text
+
+            option_type = match.group(1)
+            data = match.group(2)
+            
+            if option_type == "arg":
+                self.args = data
+            elif option_type == "platform":
+                self.platform = data
+            elif option_type == "category":
+                self.category = data
+            else:
+                raise "Unknown option type '%s'" % option_type
+
+        else:
+            self.text += text + " "
+
+    def format(self):
+        result = self.name
+
+        if self.args:
+            result += " " + self.args
+
+        result = '\\fB' + result + '\\fR'
+
+        result += "\n"
+
+        if self.platform:
+            result += "[%s only] " % self.platform
+
+        result += self.text + "\n"
+
+        return result
+
+def process_file(file):
+    f = open(file)
+
+    try:
+        param = None
+        waiting_for_checkparm = False
+
+        for line in f:
+            line = line.rstrip()
+
+            # Currently reading a doc comment?
+
+            if param:
+                # End of doc comment
+
+                if not re.match('\s*//', line):
+                    waiting_for_checkparm = True
+
+                # Waiting for the M_CheckParm call that contains the
+                # name of the parameter we are documenting?
+
+                if waiting_for_checkparm:
+                    match = re.search('M_CheckParm\s*\(\s*"(.*?)"\s*\)', line)
+
+                    if match:
+                        # Found the name!  Finished documenting this 
+                        # parameter.
+
+                        param.name = match.group(1)
+                        categories[param.category].add_param(param)
+                        param = None
+
+                else:
+                    # More documentation text
+
+                    munged_line = re.sub('\s*\/\/\s*', '', line, 1)
+                    munged_line = re.sub('\s*$', '', munged_line)
+                    param.add_text(munged_line)
+
+            # Check for start of a doc comment
+
+            if re.search("//!", line):
+                param = Parameter()
+                waiting_for_checkparm = False
+    finally:
+        f.close()
+
+def print_file_contents(file):
+    f = open(file)
+
+    try:
+        for line in f:
+            print line.rstrip()
+
+    finally:
+        f.close()
+
+# Process all C source files.
+
+files = glob.glob("../src/*.c")
+
+for file in files:
+    process_file(file)
+
+print_file_contents("header")
+
+print categories[None].format()
+
+for c in categories:
+    if c != None:
+        print categories[c].format()
+
+print_file_contents("footer")
+
--- a/man/doom-options.in
+++ /dev/null
@@ -1,30 +1,0 @@
--deathmatch	start a deathmatch game
--altdeath	start a deathmatch game (alternative mode)
--timer x	exit a deathmatch level after x minutes
--avg	austin virtual gaming (same as -timer 20)
--cdrom	use C:\\DOOMDATA for configuration data
--config x	use x as the configuration file
--devparm	developer mode: F1 saves a PCX screenshot in the current working directory
--dup	put two network commands in each network packet
--episode e	start playing on episode e (from 1-4)
--extratic	send two packets per tic for network redundancy
--fast	monsters move faster
--file f...	add the PWADs f...
--loadgame s	load the save in slot s
--maxdemo x	set the maximum byte size of the recorded demo
--nodes	define the number of players in a network game
-# <not implemented yet> -nodraw	no drawing of the screen is performed
--nomonsters	disable all monsters
--respawn	monsters respawn after being killed
--nomusic	disable music
--nosfx	disable sound effects
--nosound	equivalent to -nomusic -nosfx
--playdemo x	play demo from file x.lmp
--record	record a demo to file x.lmp
--recordfrom x y	start recording y.lmp from save slot x
--skill x 	set the game skill (0-5; 5 being hardest)
--statcopy x	register a stats driver at memory location x
--timedemo x	play x.lmp at double speed and display the redraw count
--warp [x y|zz]	start the game at level ExMy or MAPyy
--wart x y	load PWAD ExMy.WAD and warp to level ExMy
--turbo x	multiple player speed by x%. If unspecified, x defaults to 200. Values are rounded up to 10 and down to 400.
--- a/man/foot
+++ /dev/null
@@ -1,7 +1,0 @@
-.\" this section from foot
-.SH AUTHOR
-Chocolate Doom is written and maintained by
-AUTHORS.
-The manpage was written by Jon Dowland <[email protected]>.
-.SH COPYRIGHT
-Copyright \(co 2006 Simon Howard.
--- /dev/null
+++ b/man/footer
@@ -1,0 +1,7 @@
+.\" this section from foot
+.SH AUTHOR
+Chocolate Doom is written and maintained by
+Simon Howard.
+.SH COPYRIGHT
+Copyright \(co 2006 Simon Howard.
+
--- a/man/head
+++ /dev/null
@@ -1,18 +1,0 @@
-.\" this section from head
-.TH chocolate\-doom 6
-.SH NAME
-chocolate\-doom \- historically compatible doom engine
-.SH SYNOPSIS
-.B chocolate\-doom
-[\fIDOOM OPTIONS\fR]
-[\fICHOCOLATE\-DOOM OPTIONS\fR]
-.SH DESCRIPTION
-.PP
-Chocolate Doom is a modern doom engine designed to behave
-as similar to the original doom game as is possible.
-.br
-Command-line arguments are divided up into \fBDOOM
-OPTIONS\fR, a subset of the original doom's command line
-arguments, and \fBCHOCOLATE\-DOOM OPTIONS\fR which are
-specific to this engine.
-.\" this section generated from vanilla-doom-options.in
--- /dev/null
+++ b/man/header
@@ -1,0 +1,12 @@
+.\" this section from head
+.TH chocolate\-doom 6
+.SH NAME
+chocolate\-doom \- historically compatible doom engine
+.SH SYNOPSIS
+.B chocolate\-doom
+[\fIOPTIONS\fR]
+.SH DESCRIPTION
+.PP
+Chocolate Doom is a modern doom engine designed to behave
+as similar to the original doom game as is possible.
+.br
--- a/src/d_iwad.c
+++ b/src/d_iwad.c
@@ -465,6 +465,12 @@
 
     // Check for the -iwad parameter
 
+    //!
+    // Specify an IWAD file to use.
+    //
+    // @arg <file>
+    //
+
     iwadparm = M_CheckParm("-iwad");
 
     if (iwadparm)
--- a/src/d_main.c
+++ b/src/d_main.c
@@ -833,6 +833,14 @@
     int p;
     int i;
 
+    //! 
+    // @arg <version>
+    // @category compat
+    //
+    // Emulate a specific version of Doom.  Valid values are "1.9",
+    // "ultimate" and "final".
+    //
+
     p = M_CheckParm("-gameversion");
 
     if (p > 0)
@@ -929,6 +937,9 @@
 
     FindResponseFile ();
 
+    // Undocumented "search for IWADs" parameter used by the setup
+    // tool.
+
     if (M_CheckParm("-findiwads") > 0)
     {
         D_FindInstalledIWADs();
@@ -941,6 +952,13 @@
     printf (DEH_String("Z_Init: Init zone memory allocation daemon. \n"));
     Z_Init ();
 
+    //!
+    // @category net
+    //
+    // Start a dedicated server, routing packets but not participating
+    // in the game itself.
+    //
+
     if (M_CheckParm("-dedicated") > 0)
     {
         printf("Dedicated server mode.\n");
@@ -949,7 +967,13 @@
         // Never returns
     }
 
-    // Query network servers?
+    //!
+    // @arg <address>
+    // @category net
+    //
+    // Query the status of the server running on the given IP
+    // address.
+    //
 
     p = M_CheckParm("-query");
 
@@ -958,6 +982,12 @@
         NET_QueryAddress(myargv[p+1]);
     }
 
+    //!
+    // @category net
+    //
+    // Search the local LAN for running servers.
+    //
+
     if (M_CheckParm("-search"))
         NET_LANQuery();
             
@@ -978,15 +1008,50 @@
 	
     setbuf (stdout, NULL);
     modifiedgame = false;
+
+    //!
+    // Disable monsters.
+    //
 	
     nomonsters = M_CheckParm ("-nomonsters");
+
+    //!
+    // Monsters respawn after being killed.
+    //
+
     respawnparm = M_CheckParm ("-respawn");
+
+    //!
+    // Monsters move faster.
+    //
+
     fastparm = M_CheckParm ("-fast");
+
+    //! 
+    // Developer mode.  F1 saves a screenshot in the current working
+    // directory.
+    //
+
     devparm = M_CheckParm ("-devparm");
+
+    //!
+    // @category net
+    //
+    // Start a deathmatch game.
+    //
+
+    if (M_CheckParm ("-deathmatch"))
+	deathmatch = 1;
+
+    //!
+    // @category net
+    //
+    // Start a deathmatch 2.0 game.  Weapons do not stay in place and
+    // all items respawn after 30 seconds.
+    //
+
     if (M_CheckParm ("-altdeath"))
 	deathmatch = 2;
-    else if (M_CheckParm ("-deathmatch"))
-	deathmatch = 1;
 
     if (devparm)
 	printf(DEH_String(D_DEVSTR));
@@ -995,7 +1060,13 @@
 
     M_SetConfigDir();
     
-    // turbo option
+    //!
+    // @arg <x>
+    //
+    // Turbo mode.  The player's speed is multiplied by x%.  If unspecified,
+    // x defaults to 200.  Values are rounded up to 10 and down to 400.
+    //
+
     if ( (p=M_CheckParm ("-turbo")) )
     {
 	int     scale = 200;
@@ -1030,6 +1101,14 @@
     // Merged PWADs are loaded first, because they are supposed to be 
     // modified IWADs.
 
+    //!
+    // @arg <files>
+    // @category mod
+    //
+    // Simulates the behavior of deutex's -merge option, merging a PWAD
+    // into the main IWAD.  Multiple files may be specified.
+    //
+
     p = M_CheckParm("-merge");
 
     if (p > 0)
@@ -1045,6 +1124,13 @@
 
     // NWT's -merge option:
 
+    //!
+    // @arg <files>
+    // @category mod
+    //
+    // Simulates the behavior of NWT's -merge option.  Multiple files
+    // may be specified.
+
     p = M_CheckParm("-nwtmerge");
 
     if (p > 0)
@@ -1058,6 +1144,14 @@
     
     // Add flats
 
+    //!
+    // @arg <files>
+    // @category mod
+    //
+    // Simulates the behavior of NWT's -af option, merging flats into
+    // the main IWAD directory.  Multiple files may be specified.
+    //
+
     p = M_CheckParm("-af");
 
     if (p > 0)
@@ -1069,7 +1163,13 @@
         }
     }
 
-    // Add sprites
+    //!
+    // @arg <files>
+    // @category mod
+    //
+    // Simulates the behavior of NWT's -as option, merging sprites
+    // into the main IWAD directory.  Multiple files may be specified.
+    //
 
     p = M_CheckParm("-as");
 
@@ -1082,7 +1182,12 @@
         }
     }
 
-    // Add sprites AND flats
+    //!
+    // @arg <files>
+    // @category mod
+    //
+    // Equivalent to "-af <files> -as <files>".
+    //
 
     p = M_CheckParm("-aa");
 
@@ -1097,7 +1202,11 @@
 
 #endif
 
-    // Load normal PWADs
+    //!
+    // @arg <files>
+    //
+    // Load the specified PWAD files.
+    //
 
     p = M_CheckParm ("-file");
     if (p)
@@ -1145,12 +1254,29 @@
 	}
 	D_AddFile (file);
     }
-	
+
+    //!
+    // @arg <demo>
+    // @category demo
+    //
+    // Play back the demo named demo.lmp.
+    //
+
     p = M_CheckParm ("-playdemo");
 
     if (!p)
+    {
+        //!
+        // @arg <demo>
+        // @category demo
+        //
+        // Play back the demo named demo.lmp, determining the framerate
+        // of the screen.
+        //
 	p = M_CheckParm ("-timedemo");
 
+    }
+
     if (p && p < myargc-1)
     {
         if (!strcasecmp(myargv[p+1] + strlen(myargv[p+1]) - 4, ".lmp"))
@@ -1221,8 +1347,15 @@
     startmap = 1;
     autostart = false;
 
-		
+    //!
+    // @arg <skill>
+    //
+    // Set the game skill, 1-5 (1: easiest, 5: hardest).  A skill of
+    // 0 disables all monsters.
+    //
+
     p = M_CheckParm ("-skill");
+
     if (p && p < myargc-1)
     {
 	startskill = myargv[p+1][0]-'1';
@@ -1229,7 +1362,14 @@
 	autostart = true;
     }
 
+    //!
+    // @arg <n>
+    //
+    // Start playing on episode n (1-4)
+    //
+
     p = M_CheckParm ("-episode");
+
     if (p && p < myargc-1)
     {
 	startepisode = myargv[p+1][0]-'0';
@@ -1239,7 +1379,15 @@
 	
     timelimit = 0;
 
+    //! 
+    // @arg <n>
+    // @category net
+    //
+    // For multiplayer games: exit each level after n minutes.
+    //
+
     p = M_CheckParm ("-timer");
+
     if (p && p < myargc-1 && deathmatch)
     {
 	timelimit = atoi(myargv[p+1]);
@@ -1246,7 +1394,14 @@
 	printf("timer: %i\n", timelimit);
     }
 
+    //!
+    // @category net
+    //
+    // Austin Virtual Gaming: end levels after 20 minutes.
+    //
+
     p = M_CheckParm ("-avg");
+
     if (p && p < myargc-1 && deathmatch)
     {
 	printf(DEH_String("Austin Virtual Gaming: Levels will end "
@@ -1254,7 +1409,15 @@
 	timelimit = 20;
     }
 
+    //!
+    // @arg [<x> <y> | <xy>]
+    //
+    // Start a game immediately, warping to ExMy (Doom 1) or MAPxy
+    // (Doom 2)
+    //
+
     p = M_CheckParm ("-warp");
+
     if (p && p < myargc-1)
     {
         if (gamemode == commercial)
@@ -1275,6 +1438,7 @@
         autostart = true;
     }
 
+    // Undocumented:
     // Invoked by setup to test the controls.
 
     p = M_CheckParm("-testcontrols");
@@ -1291,6 +1455,12 @@
     // We do this here and save the slot number, so that the network code
     // can override it or send the load slot to other players.
 
+    //!
+    // @arg <s>
+    //
+    // Load the game in slot s.
+    //
+
     p = M_CheckParm ("-loadgame");
     
     if (p && p < myargc-1)
@@ -1303,9 +1473,22 @@
         startloadgame = -1;
     }
 
+    //!
+    // @category video
+    //
+    // Disable vertical mouse movement.
+    //
+
     if (M_CheckParm("-novert"))
         novert = true;
-    else if (M_CheckParm("-nonovert"))
+
+    //!
+    // @category video
+    //
+    // Enable vertical mouse movement.
+    //
+
+    if (M_CheckParm("-nonovert"))
         novert = false;
 
     if (W_CheckNumForName("SS_START") >= 0
@@ -1372,7 +1555,13 @@
     if (gamemode == commercial && W_CheckNumForName("map01") < 0)
         storedemo = true;
 
-    // start the apropriate game based on parms
+    //!
+    // @arg <x>
+    // @category demo
+    //
+    // Record a demo named x.lmp.
+    //
+
     p = M_CheckParm ("-record");
 
     if (p && p < myargc-1)
@@ -1380,7 +1569,7 @@
 	G_RecordDemo (myargv[p+1]);
 	autostart = true;
     }
-	
+
     p = M_CheckParm ("-playdemo");
     if (p && p < myargc-1)
     {
--- a/src/d_net.c
+++ b/src/d_net.c
@@ -248,6 +248,12 @@
     {
         net_addr_t *addr = NULL;
 
+        //!
+        // @category net
+        //
+        // Start a multiplayer server, listening for connections.
+        //
+
         if (M_CheckParm("-server") > 0)
         {
             NET_SV_Init();
@@ -259,6 +265,13 @@
         }
         else
         {
+            //! 
+            // @category net
+            //
+            // Automatically search the local LAN for a multiplayer
+            // server and join it.
+            //
+
             i = M_CheckParm("-autojoin");
 
             if (i > 0)
@@ -270,6 +283,14 @@
                     I_Error("No server found on local LAN");
                 }
             }
+
+            //!
+            // @arg <address>
+            // @category net
+            //
+            // Connect to a multiplayer server running on the given 
+            // address.
+            //
             
             i = M_CheckParm("-connect");
 
@@ -292,11 +313,23 @@
                 drone = true;
             }
 
+            //!
+            // @category net
+            //
+            // Run as the left screen in three screen mode.
+            //
+
             if (M_CheckParm("-left") > 0)
             {
                 viewangleoffset = ANG90;
                 drone = true;
             }
+
+            //! 
+            // @category net
+            //
+            // Run as the right screen in three screen mode.
+            //
 
             if (M_CheckParm("-right") > 0)
             {
--- a/src/deh_main.c
+++ b/src/deh_main.c
@@ -339,6 +339,13 @@
 
     InitialiseSections();
 
+    //!
+    // @arg <files>
+    // @category mod
+    //
+    // Load the given dehacked patch(es)
+    //
+
     p = M_CheckParm("-deh");
 
     if (p > 0)
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -1800,6 +1800,14 @@
     strcpy (demoname, name); 
     strcat (demoname, ".lmp"); 
     maxsize = 0x20000;
+
+    //!
+    // @arg <size>
+    // @category demo
+    //
+    // Specify the demo buffer size (KiB)
+    //
+
     i = M_CheckParm ("-maxdemo");
     if (i && i<myargc-1)
 	maxsize = atoi(myargv[i+1])*1024;
@@ -1814,8 +1822,12 @@
 { 
     int             i; 
 
-    // Check for the longtics parameter, to record hires angle
-    // turns in demos
+    //!
+    // @category demo
+    //
+    // Record a high resolution "Doom 1.91" demo.
+    //
+
     longtics = M_CheckParm("-longtics") != 0;
 
     // If not recording a longtics demo, record in low res
@@ -1921,8 +1933,17 @@
 // G_TimeDemo 
 //
 void G_TimeDemo (char* name) 
-{ 	 
+{
+    //!
+    // Disable rendering the screen entirely.
+    //
+
     nodrawers = M_CheckParm ("-nodraw"); 
+
+    //!
+    // Disable blitting the screen.
+    //
+
     noblit = M_CheckParm ("-noblit"); 
     timingdemo = true; 
     singletics = true; 
--- a/src/i_sound.c
+++ b/src/i_sound.c
@@ -453,12 +453,37 @@
         channels_playing[i] = sfx_None;
     }
 
-    nomusicparm = M_CheckParm("-nomusic") > 0
-               || M_CheckParm("-nosound") > 0
-               || snd_musicdevice < SNDDEVICE_ADLIB;
-    nosfxparm = M_CheckParm("-nosfx") > 0
-             || M_CheckParm("-nosound") > 0
-             || snd_sfxdevice < SNDDEVICE_SB;
+    //! 
+    // Disable music playback.
+    //
+
+    nomusicparm = M_CheckParm("-nomusic") > 0;
+
+    if (snd_musicdevice < SNDDEVICE_ADLIB)
+    {
+        nomusicparm = true;
+    }
+
+    //!
+    // Disable sound effects.
+    //
+
+    nosfxparm = M_CheckParm("-nosfx") > 0;
+
+    if (snd_sfxdevice < SNDDEVICE_SB)
+    {
+        nosfxparm = true;
+    }
+
+    //!
+    // Disable sound effects and music.
+    //
+
+    if (M_CheckParm("-nosound") > 0)
+    {
+        nosfxparm = true;
+        nomusicparm = true;
+    }
 
     // If music or sound is going to play, we need to at least
     // initialise SDL
--- a/src/i_system.c
+++ b/src/i_system.c
@@ -75,6 +75,12 @@
 {
     int p;
 
+    //!
+    // @arg <mb>
+    //
+    // Specify the heap size, in MiB (default 16).
+    //
+
     p = M_CheckParm("-mb");
     
     if (p > 0)
--- a/src/i_video.c
+++ b/src/i_video.c
@@ -866,13 +866,24 @@
 
 static void CheckCommandLine(void)
 {
-    // mouse grabbing
+    //!
+    // @category video 
+    //
+    // Grab the mouse when running in windowed mode.
+    //
 
     if (M_CheckParm("-grabmouse"))
     {
         grabmouse = true;
     }
-    else if (M_CheckParm("-nograbmouse"))
+
+    //!
+    // @category video 
+    //
+    // Don't grab the mouse when running in windowed mode.
+    //
+
+    if (M_CheckParm("-nograbmouse"))
     {
         grabmouse = false;
     }
@@ -880,32 +891,78 @@
     // default to fullscreen mode, allow override with command line
     // nofullscreen because we love prboom
 
+    //!
+    // @category video 
+    //
+    // Run in a window.
+    //
+
     if (M_CheckParm("-window") || M_CheckParm("-nofullscreen"))
     {
         fullscreen = FULLSCREEN_OFF;
     }
-    else if (M_CheckParm("-fullscreen"))
+
+    //!
+    // @category video 
+    //
+    // Run in fullscreen mode.
+    //
+
+    if (M_CheckParm("-fullscreen"))
     {
         fullscreen = FULLSCREEN_ON;
     }
 
+    //!
+    // @category video 
+    //
+    // Disable the mouse.
+    //
+
     nomouse = M_CheckParm("-nomouse") > 0;
 
-    // scale-by-2 mode
+    // 2x, 3x, 4x scale mode
  
+    //!
+    // @category video 
+    //
+    // Don't scale up the screen.
+    //
+
     if (M_CheckParm("-1"))
     {
         screenmultiply = 1;
     }
-    else if (M_CheckParm("-2"))
+
+    //!
+    // @category video 
+    //
+    // Double up the screen to 2x its size.
+    //
+
+    if (M_CheckParm("-2"))
     {
         screenmultiply = 2;
     }
-    else if (M_CheckParm("-3"))
+
+    //!
+    // @category video 
+    //
+    // Double up the screen to 3x its size.
+    //
+
+    if (M_CheckParm("-3"))
     {
         screenmultiply = 3;
     }
-    else if (M_CheckParm("-4"))
+
+    //!
+    // @category video 
+    //
+    // Double up the screen to 4x its size.
+    //
+
+    if (M_CheckParm("-4"))
     {
         screenmultiply = 4;
     }
@@ -1061,6 +1118,13 @@
 #ifdef _WIN32
 
     // Allow -gdi as a shortcut for using the windib driver.
+
+    //!
+    // @category video 
+    // @platform windows
+    //
+    // Use the Windows GDI driver instead of DirectX.
+    //
 
     if (M_CheckParm("-gdi") > 0)
     {
--- a/src/m_misc.c
+++ b/src/m_misc.c
@@ -616,6 +616,14 @@
     int i;
  
     // check for a custom default file
+
+    //!
+    // @arg <file>
+    //
+    // Load configuration from the specified file, instead of
+    // default.cfg.
+    //
+
     i = M_CheckParm ("-config");
 
     if (i && i<myargc-1)
@@ -631,6 +639,11 @@
 
     printf("saving config in %s\n", doom_defaults.filename);
 
+    //!
+    // Load extra configuration from the specified file, instead 
+    // of chocolate-doom.cfg.
+    //
+
     i = M_CheckParm("-extraconfig");
 
     if (i && i<myargc-1)
@@ -681,8 +694,12 @@
     else
     {
 #ifdef _WIN32
-        // when given the -cdrom option, save config+savegames in 
-        // c:\doomdata.  This only applies under Windows.
+        //!
+        // @platform windows
+        //
+        // Save configuration data and savegames in c:\doomdata,
+        // allowing play from CD.
+        //
 
         if (M_CheckParm("-cdrom") > 0)
         {
--- a/src/net_client.c
+++ b/src/net_client.c
@@ -390,11 +390,25 @@
     settings.nomonsters = nomonsters;
     settings.timelimit = timelimit;
 
+    //!
+    // @category net
+    //
+    // Use original game sync code.
+    //
+
     if (M_CheckParm("-oldsync") > 0)
 	settings.new_sync = 0;
     else
 	settings.new_sync = 1;
     
+    //!
+    // @category net
+    // @arg <n>
+    //
+    // Send n extra tics in every packet as insurance against dropped
+    // packets.
+    //
+
     i = M_CheckParm("-extratics");
 
     if (i > 0)
@@ -401,6 +415,14 @@
         settings.extratics = atoi(myargv[i+1]);
     else
         settings.extratics = 1;
+
+    //!
+    // @category net
+    // @arg <n>
+    //
+    // Reduce the resolution of the game by a factor of n, reducing
+    // the amount of network bandwidth needed.
+    //
 
     i = M_CheckParm("-dup");
 
--- a/src/net_sdl.c
+++ b/src/net_sdl.c
@@ -161,6 +161,14 @@
 {
     int p;
 
+    //!
+    // @category net
+    // @arg <n>
+    //
+    // Use the specified UDP port for communications, instead of 
+    // the default (2342).
+    //
+
     p = M_CheckParm("-port");
     if (p > 0)
         port = atoi(myargv[p+1]);
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -1379,6 +1379,13 @@
         // what base address we are going to use.
         // Allow a spechit value to be specified on the command line.
 
+        //!
+        // @category compat
+        // @arg <n>
+        //
+        // Use the specified magic value when emulating spechit overruns.
+        //
+
         p = M_CheckParm("-spechit");
         
         if (p > 0)