Advertisement
Zacam

Debug Console SVN Patch

Feb 20th, 2014
32
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 259.10 KB | None | 0 0
  1. Index: code/ai/aicode.cpp
  2. ===================================================================
  3. --- code/ai/aicode.cpp  (revision 10462)
  4. +++ code/ai/aicode.cpp  (working copy)
  5. @@ -18,6 +18,7 @@
  6.  
  7.  
  8.  #include "ai/ai.h"
  9. +#include "debugconsole/console.h"
  10.  #include "globalincs/linklist.h"
  11.  #include "object/object.h"
  12.  #include "physics/physics.h"
  13. @@ -11339,16 +11340,14 @@ float get_wing_largest_radius(object *objp, int formation_object_flag)
  14.  
  15.  float Wing_y_scale = 2.0f;
  16.  float Wing_scale = 1.0f;
  17. -DCF(wing_y_scale, "")
  18. +DCF(wing_y_scale, "Adjusts the wing formation scale along the Y axis (Default is 2.0)")
  19.  {
  20. -   dc_get_arg(ARG_FLOAT);
  21. -   Wing_y_scale = Dc_arg_float;
  22. +   dc_stuff_float(&Wing_y_scale);
  23.  }
  24.  
  25. -DCF(wing_scale, "")
  26. +DCF(wing_scale, "Adjusts the wing formation scale. (Default is 1.0f)")
  27.  {
  28. -   dc_get_arg(ARG_FLOAT);
  29. -   Wing_scale = Dc_arg_float;
  30. +   dc_stuff_float(&Wing_scale);
  31.  }
  32.  
  33.  /**
  34. Index: code/ai/aiturret.cpp
  35. ===================================================================
  36. --- code/ai/aiturret.cpp    (revision 10462)
  37. +++ code/ai/aiturret.cpp    (working copy)
  38. @@ -22,6 +22,7 @@
  39.  #include "iff_defs/iff_defs.h"
  40.  #include "weapon/muzzleflash.h"
  41.  #include "parse/scripting.h"
  42. +#include "debugconsole/console.h"
  43.  
  44.  #include <limits.h>
  45.  
  46. @@ -38,8 +39,7 @@
  47.  float Lethality_range_const = 2.0f;
  48.  DCF(lethality_range, "N for modifying range: 1 / (1+N) at 100")
  49.  {
  50. -   dc_get_arg(ARG_FLOAT);
  51. -   Lethality_range_const = Dc_arg_float;
  52. +   dc_stuff_float(&Lethality_range_const);
  53.  }
  54.  
  55.  float Player_lethality_bump[NUM_SKILL_LEVELS] = {
  56. @@ -1466,10 +1466,16 @@ ship_subsys *aifft_list[MAX_AIFFT_TURRETS];
  57.  float aifft_rank[MAX_AIFFT_TURRETS];
  58.  int aifft_list_size = 0;
  59.  int aifft_max_checks = 5;
  60. -DCF(mf, "")
  61. +DCF(mf, "Adjusts the maximum number of tries an AI may do when trying to pick a subsystem to attack (Default is 5)")
  62.  {
  63. -   dc_get_arg(ARG_INT);
  64. -   aifft_max_checks = Dc_arg_int;
  65. +   dc_stuff_int(&aifft_max_checks);
  66. +
  67. +   if (aifft_max_checks <= 0) {
  68. +       dc_printf("Value must be a non-negative, non-zero integer\n");
  69. +       dc_printf("aifft_max_checks set to default value of 5\n");
  70. +
  71. +       aifft_max_checks = 5;
  72. +   }
  73.  }
  74.  
  75.  
  76. Index: code/asteroid/asteroid.cpp
  77. ===================================================================
  78. --- code/asteroid/asteroid.cpp  (revision 10462)
  79. +++ code/asteroid/asteroid.cpp  (working copy)
  80. @@ -39,6 +39,8 @@
  81.  #include "network/multimsgs.h"
  82.  #include "network/multi.h"
  83.  #include "parse/scripting.h"
  84. +#include "debugconsole/console.h"
  85. +
  86.  #include <algorithm>
  87.  #include "globalincs/compatibility.h"
  88.  
  89. @@ -1404,23 +1406,8 @@ void asteroid_level_close()
  90.     Asteroid_field.num_initial_asteroids=0;
  91.  }
  92.  
  93. -DCF(asteroids,"Turns asteroids on/off")
  94. -{ 
  95. -   if ( Dc_command )   {  
  96. -       dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);       
  97. -       if ( Dc_arg_type & ARG_TRUE )  
  98. -           Asteroids_enabled = 1
  99. -       else if ( Dc_arg_type & ARG_FALSE )
  100. -           Asteroids_enabled = 0
  101. -       else if ( Dc_arg_type & ARG_NONE )
  102. -           Asteroids_enabled ^= 1;
  103. -   }  
  104. -   if ( Dc_help ) 
  105. -       dc_printf( "Usage: asteroids [bool]\nTurns asteroid system on/off.  If nothing passed, then toggles it.\n" );  
  106. -  
  107. -   if ( Dc_status )   
  108. -       dc_printf( "asteroids are %s\n", (Asteroids_enabled?"ON":"OFF") )
  109. -}
  110. +DCF_BOOL2(asteroids, Asteroids_enabled, "enables or disables asteroids", "Usage: asteroids [bool]\nTurns asteroid system on/off.  If nothing passed, then toggles it.\n");
  111. +
  112.  
  113.  void hud_target_asteroid()
  114.  {
  115. Index: code/bmpman/bmpman.cpp
  116. ===================================================================
  117. --- code/bmpman/bmpman.cpp  (revision 10462)
  118. +++ code/bmpman/bmpman.cpp  (working copy)
  119. @@ -37,6 +37,7 @@
  120.  #include "jpgutils/jpgutils.h"
  121.  #include "parse/parselo.h"
  122.  #include "network/multiutil.h"
  123. +#include "debugconsole/console.h"
  124.  
  125.  #define BMPMAN_INTERNAL
  126.  #include "bmpman/bm_internal.h"
  127. @@ -669,46 +670,53 @@ int bm_reload(int bitmap_handle, const char* filename)
  128.  
  129.  DCF(bm_frag,"Shows BmpMan fragmentation")
  130.  {
  131. -   if ( Dc_command )   {
  132. +   if (dc_optional_string_either("help", "--help")) {
  133. +       dc_printf("Displays a graphic showing the BmpMan fragmentation. Color key:\n");
  134. +       dc_printf("\tGray  : NONE\n");
  135. +       dc_printf("\tRed   : PCXn");
  136. +       dc_printf("\tGreen : USER, TGA, PNG, DDS\n");
  137. +       dc_printf("\tBlue  : ANI, EFF\n\n");
  138.  
  139. -       gr_clear();
  140. -
  141. -       int x=0, y=0;
  142. -       int xs=2, ys=2;
  143. -       int w=4, h=4;
  144. -
  145. -       for (int i=0; i<MAX_BITMAPS; i++ )  {
  146. -           switch( bm_bitmaps[i].type )    {
  147. -           case BM_TYPE_NONE:
  148. -               gr_set_color(128,128,128);
  149. -               break;
  150. -           case BM_TYPE_PCX:
  151. -               gr_set_color(255,0,0);
  152. -               break;
  153. -           case BM_TYPE_USER:
  154. -           case BM_TYPE_TGA:
  155. -           case BM_TYPE_PNG:
  156. -           case BM_TYPE_DDS:
  157. -               gr_set_color(0,255,0);
  158. -               break;
  159. -           case BM_TYPE_ANI:
  160. -           case BM_TYPE_EFF:
  161. -               gr_set_color(0,0,255);
  162. -               break;
  163. -           }
  164. +       dc_printf("Once done reviewing the graphic, press any key to return to the console\n");
  165. +       return;
  166. +   }
  167. +  
  168. +   gr_clear();
  169.  
  170. -           gr_rect( x+xs, y+ys, w, h );
  171. -           x += w+xs+xs;
  172. -           if ( x > 639 )  {
  173. -               x = 0;
  174. -               y += h + ys + ys;
  175. -           }
  176. +   int x=0, y=0;
  177. +   int xs=2, ys=2;
  178. +   int w=4, h=4;
  179.  
  180. +   for (int i=0; i<MAX_BITMAPS; i++ )  {
  181. +       switch( bm_bitmaps[i].type )    {
  182. +       case BM_TYPE_NONE:
  183. +           gr_set_color(128,128,128);
  184. +           break;
  185. +       case BM_TYPE_PCX:
  186. +           gr_set_color(255,0,0);
  187. +           break;
  188. +       case BM_TYPE_USER:
  189. +       case BM_TYPE_TGA:
  190. +       case BM_TYPE_PNG:
  191. +       case BM_TYPE_DDS:
  192. +           gr_set_color(0,255,0);
  193. +           break;
  194. +       case BM_TYPE_ANI:
  195. +       case BM_TYPE_EFF:
  196. +           gr_set_color(0,0,255);
  197. +           break;
  198.         }
  199.  
  200. -       gr_flip();
  201. -       key_getch();
  202. +       gr_rect( x+xs, y+ys, w, h );
  203. +       x += w+xs+xs;
  204. +       if ( x > 639 )  {
  205. +           x = 0;
  206. +           y += h + ys + ys;
  207. +       }
  208.     }
  209. +
  210. +   gr_flip();
  211. +   key_getch();
  212.  }
  213.  
  214.  static int find_block_of(int n)
  215. @@ -2068,48 +2076,52 @@ void bm_unload_all()
  216.  
  217.  DCF(bmpman,"Shows/changes bitmap caching parameters and usage")
  218.  {
  219. -   if ( Dc_command )   {
  220. -       dc_get_arg(ARG_STRING);
  221. -       if ( !strcmp( Dc_arg, "flush" ))    {
  222. -           dc_printf( "Total RAM usage before flush: %d bytes\n", bm_texture_ram );
  223. -           int i;
  224. -           for (i = 0; i < MAX_BITMAPS; i++)   {
  225. -               if ( bm_bitmaps[i].type != BM_TYPE_NONE )   {
  226. -                   bm_free_data(i);
  227. -               }
  228. -           }
  229. -           dc_printf( "Total RAM after flush: %d bytes\n", bm_texture_ram );
  230. -       } else if ( !strcmp( Dc_arg, "ram" ))   {
  231. -           dc_get_arg(ARG_INT);
  232. -           Bm_max_ram = Dc_arg_int*1024*1024;
  233. -       } else {
  234. -           // print usage, not stats
  235. -           Dc_help = 1;
  236. -       }
  237. -   }
  238. -
  239. -   if ( Dc_help )  {
  240. -       dc_printf( "Usage: BmpMan keyword\nWhere keyword can be in the following forms:\n" );
  241. -       dc_printf( "BmpMan flush    Unloads all bitmaps.\n" );
  242. -       dc_printf( "BmpMan ram x    Sets max mem usage to x MB. (Set to 0 to have no limit.)\n" );
  243. -       dc_printf( "\nUse '? BmpMan' to see status of Bitmap manager.\n" );
  244. -       Dc_status = 0;  // don't print status if help is printed.  Too messy.
  245. +   if ( dc_optional_string_either("help", "--help"))   {
  246. +       dc_printf( "Usage: BmpMan [arg]\nWhere arg can be any of the following:\n" );
  247. +       dc_printf( "\tflush    Unloads all bitmaps.\n" );
  248. +       dc_printf( "\tram [x]  Sets max mem usage to x MB. (Set to 0 to have no limit.)\n" );
  249. +       dc_printf( "\t?        Displays status of Bitmap manager.\n" );
  250. +       return;
  251.     }
  252.  
  253. -   if ( Dc_status )    {
  254. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  255.         dc_printf( "Total RAM usage: %d bytes\n", bm_texture_ram );
  256.  
  257. -
  258. -       if ( Bm_max_ram > 1024*1024 )
  259. -           dc_printf( "Max RAM allowed: %.1f MB\n", i2fl(Bm_max_ram)/(1024.0f*1024.0f) );
  260. -       else if ( Bm_max_ram > 1024 )
  261. -           dc_printf( "Max RAM allowed: %.1f KB\n", i2fl(Bm_max_ram)/(1024.0f) );
  262. -       else if ( Bm_max_ram > 0 )
  263. -           dc_printf( "Max RAM allowed: %d bytes\n", Bm_max_ram );
  264. -       else
  265. -           dc_printf( "No RAM limit\n" );
  266. +       if (Bm_max_ram > 1024*1024) {
  267. +           dc_printf( "\tMax RAM allowed: %.1f MB\n", i2fl(Bm_max_ram)/(1024.0f*1024.0f) );
  268. +       } else if ( Bm_max_ram > 1024 ) {
  269. +           dc_printf( "\tMax RAM allowed: %.1f KB\n", i2fl(Bm_max_ram)/(1024.0f) );
  270. +       } else if ( Bm_max_ram > 0 ) {
  271. +           dc_printf( "\tMax RAM allowed: %d bytes\n", Bm_max_ram );
  272. +       } else {
  273. +           dc_printf( "\tNo RAM limit\n" );
  274. +       }
  275. +       return;
  276. +   }
  277.  
  278.  
  279. +   if (dc_optional_string("flush")) {
  280. +       dc_printf( "Total RAM usage before flush: %d bytes\n", bm_texture_ram );
  281. +       int i;
  282. +       for (i = 0; i < MAX_BITMAPS; i++)   {
  283. +           if ( bm_bitmaps[i].type != BM_TYPE_NONE )   {
  284. +               bm_free_data(i);
  285. +           }
  286. +       }
  287. +       dc_printf( "Total RAM after flush: %d bytes\n", bm_texture_ram );
  288. +   } else if (dc_optional_string("ram")) {
  289. +       dc_stuff_int(&Bm_max_ram);
  290. +
  291. +       if (Bm_max_ram > 0) {
  292. +           dc_printf("BmpMan limited to %i, MB's\n", Bm_max_ram);
  293. +           Bm_max_ram *= 1024 * 1024;
  294. +       } else if (Bm_max_ram == 0) {
  295. +           dc_printf("!!BmpMan memory is unlimited!!\n");
  296. +       } else {
  297. +           dc_printf("Illegal value. Must be non-negative.");
  298. +       }
  299. +   } else {
  300. +       dc_printf("<BmpMan> No argument given\n");
  301.     }
  302.  }
  303.  
  304. Index: code/controlconfig/controlsconfig.cpp
  305. ===================================================================
  306. --- code/controlconfig/controlsconfig.cpp (revision 10462)
  307. +++ code/controlconfig/controlsconfig.cpp   (working copy)
  308. @@ -28,7 +28,8 @@
  309.  #include "globalincs/alphacolors.h"
  310.  #include "network/multi_pmsg.h"
  311.  #include "network/multiutil.h"
  312.  #include "parse/scripting.h"
  313. +#include "debugconsole/console.h"
  314.  
  315.  
  316.  #ifndef NDEBUG
  317. @@ -347,7 +348,7 @@ int Config_allowed[] = {
  318.  #ifndef NDEBUG
  319.  int Show_controls_info = 0;
  320.  
  321. -DCF_BOOL(show_controls_info, Show_controls_info)
  322. +DCF_BOOL(show_controls_info, Show_controls_info);
  323.  #endif
  324.  
  325.  static int Axes_origin[JOY_NUM_AXES];
  326. Index: code/debugconsole/console.cpp
  327. ===================================================================
  328. --- code/debugconsole/console.cpp   (revision 10462)
  329. +++ code/debugconsole/console.cpp   (working copy)
  330. @@ -8,740 +8,458 @@
  331.  */
  332.  
  333.  
  334. -
  335. -#include <stdlib.h>
  336. -#include <stdio.h>
  337. -#include <stdarg.h>
  338. -#include <setjmp.h>
  339. -#include <string.h>
  340. -
  341. +#include "debugconsole/console.h"
  342. +#include "debugconsole/consoleparse.h"
  343. +#include "globalincs/alphacolors.h"
  344.  #include "globalincs/pstypes.h"
  345. +#include "globalincs/version.h"
  346. +#include "globalincs/vmallocator.h"
  347.  #include "graphics/font.h"
  348.  #include "io/timer.h"
  349.  #include "io/key.h"
  350. -#include "globalincs/alphacolors.h"
  351.  #include "osapi/osapi.h"
  352.  
  353. +#include <cstdarg>
  354.  
  355. -#define MAX_COMMANDS 300
  356. -
  357. -static int Num_debug_commands = 0;
  358. -static debug_command *Debug_command[MAX_COMMANDS];
  359. -
  360. -
  361. -debug_command::debug_command(char *_name, char *_help, void (*_func)() )
  362. -{
  363. -   int i;
  364. -
  365. -   if ( Num_debug_commands >= MAX_COMMANDS ) {
  366. -       Int3();         // Too many debug console commands!! Increase MAX_COMMANDS!!
  367. -       return;
  368. -   }
  369. -
  370. -   for (i=0; i<Num_debug_commands; i++ ) {
  371. -       int ret  = stricmp( Debug_command[i]->name, _name );
  372. -
  373. -       if ( ret == 0) {
  374. -           Int3();     // This debug console command already exists!!!!
  375. -           return;
  376. -       } else if ( ret > 0 ) {
  377. -           break;      // Insert it here
  378. -
  379. -       } else if ( ret < 0 ) {
  380. -           // do nothing
  381. -       }
  382. -   }
  383. -
  384. -   if ( i < Num_debug_commands ) {
  385. -       // Insert it at element i
  386. -       int j;
  387. -       for (j=Num_debug_commands; j>i; j-- ) {
  388. -           Debug_command[j] = Debug_command[j-1];
  389. -       }
  390. -       Debug_command[i] = this;
  391. -       Num_debug_commands++;
  392. -   } else {
  393. -       Debug_command[Num_debug_commands] = this;
  394. -       Num_debug_commands++;
  395. -   }
  396. +// ========================= GLOBALS =========================
  397. +dc_mode Dc_mode;       //!< Debug Console mode, can either process the command, report the command's status, or provide help. (But not all at the same time)
  398.  
  399. -   name = _name;
  400. -   help = _help;
  401. -   func = _func;
  402. -}
  403. +bool Dc_debug_on;      //!< Flag used to print console and command debugging strings
  404.  
  405. -// some global variables
  406. -int Dc_command;            // If this is set, then process the command
  407. -int Dc_help;           // If this is set, then print out the help text in the form, "usage: ... \nLong description\n" );
  408. -int Dc_status;         // If this is set, then print out the current status of the command.
  409. -char *Dc_arg;          // The (lowercased) string value of the argument retrieved from dc_arg
  410. -char *Dc_arg_org;      // Dc_arg before it got converted to lowercase
  411. -uint Dc_arg_type;      // The type of dc_arg.
  412. -char *Dc_command_line; // The rest of the command line, from the end of the last processed arg on.
  413. -int Dc_arg_int;            // If Dc_arg_type & ARG_INT is set, then this is the value
  414. -ubyte Dc_arg_ubyte;        // If Dc_arg_type & ARG_UBYTE is set, then this is the value
  415. -float Dc_arg_float;        // If Dc_arg_type & ARG_FLOAT is set, then this is the value
  416. +// Commands and History
  417. +SCP_string dc_command_str;     //!< The entered command line, arguments and all.
  418. +                               //!< Is progressively culled from the left as commands, arguments are parsed in DCF's
  419.  
  420. -int scroll_times = 0;  // incremented each time display scrolls
  421. +// Misc
  422. +bool debug_inited = FALSE;
  423.  
  424. -int debug_inited = 0;
  425.  
  426. -#define DROWS 25
  427. -#define DCOLS 80
  428. +// ========================= LOCALS =========================
  429. +// Text Buffer
  430. +uint DBROWS = 80;  // # of buffer rows
  431. +uint DBCOLS = 120; // # of buffer columns
  432. +unsigned char DTABS = 4;   //!< Tab size in spaces
  433.  
  434. -int debug_x=0, debug_y=0;
  435. -char debug_text[DROWS][DCOLS];
  436. +SCP_deque<SCP_string> dc_buffer;
  437.  
  438. +// Display Window
  439. +uint DROWS = 25;
  440. +uint DCOLS = 80;
  441. +const uint DROWS_MIN = 25;
  442. +const uint DCOLS_MIN = 80;
  443. +uint dc_scroll_x;  // X scroll position (Leftmost character)
  444. +uint dc_scroll_y;  // Y scroll position (Topmost character)
  445.  
  446. -static char command_line[1024];
  447. -static int command_line_pos = 0;
  448. -#define DEBUG_HISTORY 16
  449. -static char oldcommand_line[DEBUG_HISTORY][1024];
  450. -int last_oldcommand=-1;
  451. -int command_scroll = 0;
  452. +SCP_string dc_title;
  453.  
  454. -///=========================== SCANNER =======================
  455. -typedef enum {
  456. -   LETTER, QUOTE, SPECIAL, EOF_CODE, DIGIT
  457. -} CHAR_CODE;
  458. +// Commands and History
  459. +uint last_oldcommand;      // Index of the last old command. Is reset to 0 at every new command push.
  460. +uint DCMDS = 40;           // Max number of commands to remember
  461. +const uint DCMDS_MIN = 3;
  462.  
  463. -typedef enum {
  464. -   NO_TOKEN, IDENTIFIER, NUMBER, STRING
  465. -} TOKEN_CODE;
  466. +SCP_deque<SCP_string> dc_history;
  467.  
  468. +const char dc_prompt[]= "> ";  // The prompt c_str
  469. +SCP_string dc_command_buf;     // The command line as shown in the console. Essentially an input buffer for dc_command_str
  470.  
  471. -#define MAX_TOKEN_STRING_LENGTH 128
  472. +// Local functions
  473. +void dc_init(void);
  474.  
  475. -char       scanner_ch;
  476. -TOKEN_CODE scanner_token;
  477. +void dc_do_command(SCP_string *cmd_str);
  478.  
  479. -char scanner_token_string[MAX_TOKEN_STRING_LENGTH];
  480. -char scanner_word_string[MAX_TOKEN_STRING_LENGTH];
  481. -char * scanner_bufferp = "";
  482. -char * scanner_tokenp = scanner_token_string;
  483. +void dc_draw(bool show_prompt);
  484. +void dc_draw_cursor( SCP_string &cmd_string, int x, int y );
  485. +void dc_draw_window(bool show_prompt);
  486.  
  487. -CHAR_CODE scanner_char_table[256];
  488. +void dc_putc(char c);
  489.  
  490. -#define scanner_char_code(x) scanner_char_table[x]
  491. -
  492. -void scanner_get_char()
  493. -{
  494. -   if ( *scanner_bufferp == '\0' ) {
  495. -       scanner_ch = 0;
  496. -       return;
  497. -   }
  498. -   scanner_ch = *scanner_bufferp++;
  499. -}
  500. -
  501. -void scanner_init()
  502. -{
  503. -   int ch;
  504. -   for (ch=0; ch<256; ++ch) scanner_char_table[ch] = SPECIAL;
  505. -   for (ch='0'; ch<='9'; ++ch) scanner_char_table[ch] = DIGIT;
  506. -   for (ch='A'; ch<='Z'; ++ch) scanner_char_table[ch] = LETTER;
  507. -   for (ch='a'; ch<='z'; ++ch) scanner_char_table[ch] = LETTER;
  508. -
  509. -   scanner_char_table['.'] = DIGIT;
  510. -   scanner_char_table['-'] = DIGIT;
  511. -   scanner_char_table['+'] = DIGIT;
  512. -
  513. -   scanner_char_table['_'] = LETTER;
  514. -   scanner_char_table[34] = QUOTE;
  515. -   scanner_char_table[0] = EOF_CODE;
  516. -
  517. -   scanner_char_table[':'] = LETTER;
  518. -   scanner_char_table['\\'] = LETTER;
  519. -
  520. -   scanner_ch = 0;
  521. -}
  522. -
  523. -void scanner_skip_blanks()
  524. -{
  525. -   while( (scanner_ch ==' ') || (scanner_ch =='\t') )
  526. -       scanner_get_char();
  527. -}
  528. -
  529. -void scanner_downshift_word()
  530. +// ============================== IMPLEMENTATIONS =============================
  531. +/**
  532. + * @brieft Prints the given char string to the debug console
  533. + * @details See the doc for std::printf() for formating and more details
  534. + */
  535. +void dc_printf(char *format, ...)
  536.  {
  537. -   int offset = 'a' - 'A';
  538. -   char * tp;
  539. +   SCP_string tmp;
  540. +   va_list args;
  541. +   SCP_string::iterator tmp_it;
  542.  
  543. -   strcpy_s( scanner_word_string, scanner_token_string );
  544. -  
  545. -   tp = scanner_word_string;
  546. -   do {
  547. -       *tp = (char)((*tp>='A') && (*tp <='Z') ? *tp + offset : *tp) ;
  548. -       tp++;
  549. -   } while (*tp != '\0' );
  550. -}
  551. +   va_start(args, format);
  552. +   vsprintf(tmp, format, args);
  553. +   va_end(args);
  554.  
  555. -void scanner_get_word()
  556. -{
  557. -   while( (scanner_char_code(scanner_ch)==LETTER) || (scanner_char_code(scanner_ch)==DIGIT) ) {
  558. -       *scanner_tokenp++ = scanner_ch;
  559. -       scanner_get_char();
  560. +   for (tmp_it = tmp.begin(); tmp_it != tmp.end(); ++tmp_it) {
  561. +       dc_putc(*tmp_it);
  562.     }
  563. -   *scanner_tokenp = '\0';
  564. -
  565. -   scanner_token = IDENTIFIER;
  566.  }
  567.  
  568. -void scanner_get_string()
  569. +/**
  570. + * @brief Opens and processes the debug console. (Blocking call)
  571. + * @details TODO: Make this a non-blocking call so that the game can still run while the debug console is open.
  572. + */
  573. +void debug_console(void (*_func)(void))
  574.  {
  575. -   *scanner_tokenp++ = 34;
  576. -   scanner_get_char();
  577. +   int done = 0;
  578.  
  579. -   while(scanner_ch != 34 ) {
  580. -       *scanner_tokenp++ = scanner_ch;
  581. -       scanner_get_char();
  582. +   while( key_inkey() ) {
  583. +       os_poll();
  584.     }
  585. -   scanner_get_char();
  586. -   *scanner_tokenp++ = 34;
  587. -   *scanner_tokenp = '\0';
  588. -   scanner_token = STRING;
  589. -}
  590.  
  591. -void scanner_get_token()
  592. -{
  593. -   scanner_skip_blanks();
  594. -   scanner_tokenp = scanner_token_string;
  595. -   *scanner_tokenp = 0;
  596. -
  597. -   switch( scanner_char_code(scanner_ch) ) {
  598. -   case QUOTE: scanner_get_string(); break;
  599. -   case EOF_CODE: scanner_token = NO_TOKEN; break;
  600. -   case DIGIT:
  601. -   case LETTER: scanner_get_word(); break;
  602. -   default:
  603. -       *scanner_tokenp++ = scanner_ch;
  604. -       *scanner_tokenp = '\0';
  605. -       scanner_get_char();
  606. -       scanner_token = IDENTIFIER;
  607. -       break;
  608. +   if ( !debug_inited ) {
  609. +       dc_init();
  610.     }
  611.  
  612. -   scanner_downshift_word();
  613. -}
  614. -
  615. -void scanner_start_command( char * s )
  616. -{
  617. -   scanner_bufferp = s;
  618. -   scanner_get_char();
  619. -}
  620. -
  621. -int Dc_debug_on = 0;
  622. -jmp_buf dc_bad_arg;
  623. +   dc_draw(TRUE);
  624.  
  625. -void dc_get_arg(uint type)
  626. -{
  627. -   scanner_get_token();
  628. -
  629. -   Dc_command_line = scanner_bufferp;
  630. -   Dc_arg_org = scanner_token_string;
  631. -   Dc_arg = scanner_word_string;
  632. -
  633. -   if (Dc_debug_on) {
  634. -       dc_printf( "next arg is '%s', was originally '%s'\n", Dc_arg, Dc_arg_org );
  635. -       dc_printf( "Rest of the command line is '%s'\n", Dc_command_line );
  636. -   }
  637. -
  638. -   if ( scanner_token == NO_TOKEN ) {
  639. -       Dc_arg_type = ARG_NONE;
  640. -   } else if ( scanner_token == IDENTIFIER ) {
  641. -       Dc_arg_type = ARG_STRING;
  642. -   } else if ( scanner_token == STRING ) {
  643. -       Dc_arg_type = ARG_QUOTE;
  644. -   } else {
  645. -       Dc_arg_type = ARG_STRING;
  646. -   }
  647. +   while (!done) {
  648. +       // poll the os
  649. +       os_poll();
  650.  
  651. -   if ( Dc_arg_type & ARG_STRING ) {
  652. -       int i, num_digits, len;
  653. +       int k = key_inkey();
  654. +       switch( k ) {
  655.  
  656. -       len = strlen(Dc_arg);
  657. -       num_digits = 0;
  658. +       case KEY_SHIFTED+KEY_ENTER:
  659. +       case KEY_ESC:
  660. +           done = TRUE;
  661. +           break;
  662.  
  663. -       for (i=0; i<len; i++) {
  664. -           if ( scanner_char_table[Dc_arg[i]] == DIGIT ) {
  665. -               num_digits++;
  666. +       case KEY_BACKSP:
  667. +           if (!dc_command_buf.empty()) {
  668. +               dc_command_buf.erase(dc_command_str.end() - 1, dc_command_buf.end());
  669.             }
  670. +           break;
  671.  
  672. -           if ( num_digits==len ) {
  673. -               Dc_arg_type |= ARG_FLOAT;
  674. -               Dc_arg_float = (float)atof(Dc_arg);
  675. -               if ( !strchr( Dc_arg, '.' )) {
  676. -                   Dc_arg_type |= ARG_INT;
  677. -                   Dc_arg_int = atoi(Dc_arg);
  678. -                   Dc_arg_type |= ARG_UBYTE;
  679. -                   Dc_arg_ubyte = (ubyte)atoi(Dc_arg);
  680. -               }
  681. -           } else {
  682. -               if ( (Dc_arg[0] == '0') && (Dc_arg[1] == 'x') ) {
  683. -                   char *p;
  684. -                   int n;
  685. -                   n = strtol(Dc_arg,&p,0);
  686. -                   if ( *p == 0 ) {
  687. -                       Dc_arg_type |= ARG_INT|ARG_HEX;
  688. -                       Dc_arg_int = n;
  689. -                   }
  690. -               }
  691. +       case KEY_F3:
  692. +       case KEY_UP:
  693. +           if (dc_history.empty()) {
  694. +               // No saved commands
  695. +               last_oldcommand = 0;
  696. +               break;
  697.             }
  698. -       }
  699. +          
  700. +           CLAMP(last_oldcommand, 0, dc_history.size());
  701.  
  702. -       if (Dc_debug_on) {
  703. -           if ( Dc_arg_type & ARG_FLOAT ) {
  704. -               dc_printf( "Found float number! %f\n", Dc_arg_float );
  705. -           }
  706. +           dc_command_buf = dc_history[last_oldcommand];
  707. +           ++last_oldcommand;
  708. +           break;
  709.  
  710. -           if ( Dc_arg_type & ARG_INT ) {
  711. -               dc_printf( "Found int number! %d\n", Dc_arg_int );
  712. +       case KEY_DOWN:
  713. +           if (dc_history.empty()) {
  714. +               // No saved commands
  715. +               last_oldcommand = 0;
  716. +               break;
  717.             }
  718. +          
  719. +           CLAMP(last_oldcommand, 1, dc_history.size());
  720.  
  721. -           if ( Dc_arg_type & ARG_UBYTE ) {
  722. -               dc_printf( "Found ubyte number! %d\n", Dc_arg_ubyte );
  723. -           }
  724. +           --last_oldcommand;
  725. +           dc_command_buf = dc_history[last_oldcommand];
  726. +           break;
  727.  
  728. -           if ( Dc_arg_type & ARG_HEX ) {
  729. -               dc_printf( "Found hex number! 0x%x\n", Dc_arg_int );
  730. +       case KEY_ENTER:
  731. +           // Clear the command line on the window, but don't print the prompt until the command has processed
  732. +           // Stuff a copy of the command line onto the history
  733. +           // Search for the command
  734. +               // If not found:
  735. +               //   abort,
  736. +               //   dc_printf("Error: Invalid or Missing command %s", cmd), and
  737. +               //   dc_printf(dc_prompt) when ready for input
  738. +           // Call the function for that command, and strip the cmd token from the command line string
  739. +           if (dc_command_buf.empty()) {
  740. +               dc_printf("No command given.\n");
  741. +               break;
  742. +           } // Else, continue to process the cmd_line
  743. +
  744. +           // z64: Thread Note: Maybe lock a mutex here to allow a previous DCF to finish/abort before starting a new one
  745. +           // z64: We'll just assume we won't be here unless a command has finished...
  746. +           dc_history.push_front(dc_command_buf);  // Push the command onto the history queue
  747. +
  748. +           while (dc_history.size() > DCMDS) {
  749. +               dc_history.pop_back();          // Keep the commands less than or equal to DCMDS
  750.             }
  751. -       }
  752.  
  753. -       if ( !stricmp( Dc_arg, "on" ) ) {
  754. -           Dc_arg_type |= ARG_TRUE;
  755. -       }
  756. -       if ( !stricmp( Dc_arg, "true" ) ) {
  757. -           Dc_arg_type |= ARG_TRUE;
  758. -       }
  759. -       if ( !stricmp( Dc_arg, "off" ) ) {
  760. -           Dc_arg_type |= ARG_FALSE;
  761. -       }
  762. -       if ( !stricmp( Dc_arg, "false" ) ) {
  763. -           Dc_arg_type |= ARG_FALSE;
  764. -       }
  765. +           dc_command_str = dc_command_buf;    // Xfer to the command string for processing
  766. +           dc_command_buf.resize(0);           // Nullify the buffer
  767. +           dc_draw(FALSE);                 // Redraw the console without the command line.
  768.  
  769. -       if ( !stricmp( Dc_arg, "+" ) ) {
  770. -           Dc_arg_type |= ARG_PLUS;
  771. -       }
  772. -
  773. -       if ( !stricmp( Dc_arg, "-" ) ) {
  774. -           Dc_arg_type |= ARG_MINUS;
  775. -       }
  776. +           dc_do_command(&dc_command_str); // Try to do the command
  777. +           break;
  778.  
  779. -       if ( !stricmp( Dc_arg, "," ) ) {
  780. -           Dc_arg_type |= ARG_COMMA;
  781. +       default:
  782. +           // Not any of the control key codes, so it's probably a letter or number.
  783. +           ubyte c = (ubyte)key_to_ascii(k);
  784. +           if ((c != 255) && (dc_command_buf.size() < MAX_CLI_LEN)) {
  785. +               dc_command_buf.push_back(c);
  786. +           }
  787.         }
  788. -   }
  789.  
  790. -   if ( Dc_arg_type & ARG_INT) {
  791. -       if ( Dc_arg_int ) {
  792. -           Dc_arg_type |= ARG_TRUE;
  793. -       } else {
  794. -           Dc_arg_type |= ARG_FALSE;
  795. +       // Do the passed function
  796. +       if ( _func ) {
  797. +           _func();
  798.         }
  799. -   }
  800.  
  801. -   if ( Dc_arg_type & ARG_UBYTE) {
  802. -       if ( Dc_arg_ubyte ) {
  803. -           Dc_arg_type |= ARG_TRUE;
  804. -       } else {
  805. -           Dc_arg_type |= ARG_FALSE;
  806. -       }
  807. +       // All done, and ready for new entry
  808. +       dc_draw(TRUE);
  809.     }
  810.  
  811. -   if ( !(Dc_arg_type&type) ) {
  812. -       if ( (Dc_arg_type & ARG_NONE) && !(type & ARG_NONE) ) {
  813. -           dc_printf( "Error: Not enough parameters.\n" );
  814. -       } else {
  815. -           dc_printf( "Error: '%s' invalid type\n", Dc_arg );
  816. -           longjmp(dc_bad_arg,1);
  817. -       }
  818. +   while( key_inkey() ) {
  819. +       os_poll();
  820.     }
  821.  }
  822.  
  823. -void debug_help();
  824. -
  825. -void debug_do_command(char * command)
  826. +/**
  827. + * @brief Initializes the debug console.
  828. + */
  829. +void dc_init(void)
  830.  {
  831. -
  832. -   int i;
  833. -   int mode = 0;
  834. -
  835. -   if ( strlen(command) < 1 ) {
  836. -       return;
  837. -   }
  838. -
  839. -   Dc_debug_on = 0;
  840. -   Dc_command_line = command;
  841. -   scanner_start_command(command);
  842. -
  843. -   if (setjmp(dc_bad_arg) ) {
  844. +   if (debug_inited) {
  845.         return;
  846.     }
  847.  
  848. -   dc_get_arg( ARG_ANY );
  849. -
  850. -   if ( !strcmp( Dc_arg, "debug" ) ) {
  851. -       Dc_debug_on = 1;
  852. -       dc_printf( "Command line: '%s'\n", Dc_command_line );
  853. -       dc_get_arg( ARG_ANY );
  854. -   }
  855. -
  856. -   if ( !stricmp( Dc_arg, "xyzzy" ) ) {
  857. -       dc_printf("Nothing happens.\n");
  858. -       return;
  859. -   }
  860. +   debug_inited = TRUE;
  861.  
  862. -   if ( !strcmp( Dc_arg, "?" ) ) {
  863. -       mode = 1;
  864. -       dc_get_arg( ARG_ANY );
  865. +   dc_scroll_x = 0;
  866. +   dc_scroll_y = 0;
  867.  
  868. -       if ( Dc_arg_type&ARG_NONE ) {
  869. -           debug_help();
  870. -           return;
  871. -       }
  872. +   // Empty the buffers
  873. +   if (!dc_buffer.empty()) {
  874. +       dc_buffer.clear();
  875.     }
  876.  
  877. -   if ( !strcmp( Dc_arg, "help" ) || !strcmp( Dc_arg, "man" ) ) {
  878. -       mode = 2;
  879. -       dc_get_arg( ARG_ANY );
  880. -       if ( Dc_arg_type&ARG_NONE ) {
  881. -           debug_help();
  882. -           return;
  883. -       }
  884. +   if (!dc_command_buf.empty()) {
  885. +       dc_command_buf.clear();
  886.     }
  887.  
  888. -   if ( strstr( Dc_command_line, "?" ) ) {
  889. -       mode = 2;
  890. -   }
  891. +   sprintf(dc_title, "FreeSpace Open v%i.%i.%i", FS_VERSION_MAJOR, FS_VERSION_MINOR, FS_VERSION_BUILD);
  892. +   dc_printf("Debug console started.\n" );
  893. +}
  894.  
  895. -   if ( !(Dc_arg_type&ARG_STRING) ) {
  896. -       dc_printf( "Invalid keyword '%s'\n", Dc_arg );
  897. +/**
  898. + * @brief Process the entered command string
  899. + */
  900. +void dc_do_command(SCP_string *cmd_str)
  901. +{
  902. +   /**
  903. +    * Grab the first word from the cmd_str
  904. +    *  If it is not a literal, ignore it "Invalid keyword: %s"
  905. +    *  Search for the command...
  906. +    *      Compare the word against valid commands
  907. +    *      If command not found, ignore it "Invalid or unknown command: %s"\
  908. +    *  Process the command...
  909. +    *      Call the function to process the command (the rest of the command line is in the parser)
  910. +    *          Function takes care of long_help and status depending on the mode.
  911. +    */
  912. +   SCP_string command;
  913. +   extern SCP_map<SCP_string, debug_command*> dc_commands; // z64: I don't like this extern here, at all. Nope nope nope.
  914. +
  915. +   if (cmd_str->empty()) {
  916.         return;
  917.     }
  918.  
  919. +   dc_parse_init(*cmd_str);
  920.  
  921. -   if (Dc_debug_on) {
  922. -       dc_printf( "Searching for command '%s'\n", Dc_arg );
  923. -   }
  924. +   dc_stuff_string_white(command);     // Grab the first token, presumably this is a command
  925.  
  926. -   for (i=0; i<Num_debug_commands; i++ ) {
  927. -       if ( !stricmp( Debug_command[i]->name, Dc_arg ) ) {
  928. -      
  929. -           if (mode==0) {
  930. -               if (Dc_debug_on) {
  931. -                   dc_printf( "Calling function '%s'\n", Dc_arg );
  932. -               }
  933. -               Dc_command = 1;
  934. -               Dc_help = 0;
  935. -               Dc_status = 1;
  936. -           } else if (mode==1) {
  937. -               if (Dc_debug_on) {
  938. -                   dc_printf( "Checking status for '%s'\n", Dc_arg );
  939. -               }
  940. -               Dc_command = 0;
  941. -               Dc_help = 0;
  942. -               Dc_status = 1;
  943. -           } else {
  944. -               if (Dc_debug_on) {
  945. -                   dc_printf( "Doing help for '%s'\n", Dc_arg );
  946. -               }
  947. -               Dc_command = 0;
  948. -               Dc_help = 1;
  949. -               Dc_status = 0;
  950. -           }
  951. +   SCP_map<SCP_string, debug_command*>::iterator it = dc_commands.find(command);
  952.  
  953. -           (*Debug_command[i]->func)();
  954. +   if (it == dc_commands.end()) {
  955. +       dc_printf("Command not found: '%s'\n", command);
  956. +       return;
  957. +   } // Else, we found our command
  958.  
  959. -           if (mode==0) {
  960. -               dc_get_arg(ARG_ANY);
  961. -               if (!(Dc_arg_type&ARG_NONE)) {
  962. -                   dc_printf( "Ignoring the unused command line tail '%s %s'\n", Dc_arg_org, Dc_command_line );
  963. -               }
  964. -           }
  965. +   (it->second)->func();   // Run the command!
  966.  
  967. -           return;
  968. -       }
  969. +   dc_stuff_string(command);
  970. +   if (command.size() > 0) {
  971. +       dc_printf( "Ignoring the unused command line tail '%s'\n", command );
  972.     }
  973. -
  974. -   dc_printf( "Unknown command '%s'\n", Dc_arg );
  975.  }
  976.  
  977. -void debug_draw()
  978. +/**
  979. + * @brief Draws the in-game console.
  980. + */
  981. +void dc_draw(bool show_prompt = FALSE)
  982.  {
  983. -   int i;
  984. -
  985.     gr_clear();
  986.     gr_set_font(FONT1);
  987.     gr_set_color_fast( &Color_bright );
  988. -   gr_string( 0x8000, 3, "Debug Console" );
  989. +   gr_string( 0x8000, 3, dc_title.c_str() );
  990.  
  991.     gr_set_color_fast( &Color_normal );
  992.  
  993. -   for (i=0; i<DROWS; i++ ) {
  994. -       gr_string( 0, i*16+16, debug_text[i] );
  995. -   }
  996. +   dc_draw_window(show_prompt);
  997.  
  998. -   int t = timer_get_fixed_seconds() / (F1_0/3);
  999. -   if ( t & 1 ) {
  1000. -       int w,h;
  1001. -       char c;
  1002. +   gr_flip();
  1003. +}
  1004.  
  1005. -       c = debug_text[debug_y][command_line_pos+1];
  1006. -       debug_text[debug_y][command_line_pos+1] = 0;
  1007. +/**
  1008. + * Draws the cursor
  1009. + * @param [in] cmd_string  The formatted command string displayed by dc_draw_window
  1010. + * @param [in] x, y            The x and y screen position of the command string
  1011. + */
  1012. +void dc_draw_cursor( SCP_string &cmd_string, int x, int y )
  1013. +{
  1014. +   int t;
  1015. +   int w, h;   // gr_string width and height
  1016.  
  1017. -       gr_get_string_size( &w, &h, debug_text[debug_y] );
  1018. +   t = timer_get_fixed_seconds() / (F1_0/3);
  1019. +   if ( t & 1 ) {
  1020. +       gr_get_string_size( &w, &h, cmd_string.c_str() );
  1021.  
  1022.         //gr_string( w, debug_y*16, "_" );
  1023. -       gr_rect(w+1,debug_y*16+1+16,2,14);
  1024. -
  1025. -       debug_text[debug_y][command_line_pos+1] = c;
  1026. +       gr_rect((x + (w + 1)), (y + (h + 1) + 16), 2, 14);
  1027.     }
  1028. -
  1029. -   gr_flip();
  1030.  }
  1031.  
  1032. -
  1033. -void debug_output( char c )
  1034. +/**
  1035. + * Draws the window text
  1036. + */
  1037. +void dc_draw_window(bool show_prompt)
  1038.  {
  1039. -   if ( c == '\t' ) {
  1040. -       int next_tab = ((debug_x/28)+1)*28;
  1041. -
  1042. -       if ( next_tab >= DCOLS-1 ) {
  1043. -           debug_x=0;
  1044. -           debug_y++;
  1045. -           scroll_times++;
  1046. -           if ( debug_y >= DROWS ) {
  1047. -               int i;
  1048. -               for (i=1; i<DROWS; i++ ) {
  1049. -                   strcpy_s( debug_text[i-1], debug_text[i] );
  1050. -               }
  1051. -               debug_y = DROWS-1;
  1052. -               debug_x = 0;
  1053. -               debug_text[debug_y][debug_x] = 0;
  1054. -           }
  1055. -           debug_text[debug_y][debug_x] = 0;
  1056. -           return;
  1057. -       }
  1058. -  
  1059. -       for ( ; debug_x < next_tab; ) {
  1060. -           debug_text[debug_y][debug_x++] = ' ';
  1061. -       }
  1062. -       debug_text[debug_y][debug_x] = 0;
  1063. -       return;
  1064. +   const int nocmd_lines = 2;      // Number of empty lines at the end when the command line is not shown
  1065. +   uint cmd_lines;                 // Number of lines for the command string
  1066. +   uint buffer_lines;              // Number of lines from the buffer to draw
  1067. +   uint i;                         // The current row we're drawing
  1068. +   uint j;                         // The current row of the command string we're drawing
  1069. +   SCP_string out_str;             // The command string + prompt character
  1070. +   SCP_string::iterator str_it;    // Iterator to out_str
  1071. +
  1072. +   out_str = dc_prompt + dc_command_buf;
  1073. +   cmd_lines = (out_str.size() / DCOLS) + 1;
  1074. +   if (show_prompt) {
  1075. +       buffer_lines = DROWS - cmd_lines;
  1076. +   } else {
  1077. +       buffer_lines = DROWS - nocmd_lines;
  1078.     }
  1079.  
  1080. -   if ( (c == '\n') || (debug_x >= DCOLS-1) ) {
  1081. -       debug_x=0;
  1082. -       debug_y++;
  1083. -       scroll_times++;
  1084. -       if ( debug_y >= DROWS ) {
  1085. -           int i;
  1086. -           for (i=1; i<DROWS; i++ ) {
  1087. -               strcpy_s( debug_text[i-1], debug_text[i] );
  1088. -           }
  1089. -           debug_y = DROWS-1;
  1090. -           debug_x = 0;
  1091. -           debug_text[debug_y][debug_x] = 0;
  1092. -       }
  1093. -       debug_text[debug_y][debug_x] = 0;
  1094. -       if ( c == '\n' ) {
  1095. -           return;
  1096. -       }
  1097. +   // Ensure the buffer has DBROWS number of rows, expanding it with null strings or shrinking it as necassary
  1098. +   if (dc_buffer.size() != DBROWS) {
  1099. +       dc_buffer.resize(DBROWS, "");
  1100.     }
  1101.  
  1102. -   debug_text[debug_y][debug_x++] = c;
  1103. -   debug_text[debug_y][debug_x] = 0;
  1104. -}
  1105. +   // Ensure the window is not bigger than the buffer
  1106. +   CLAMP(DROWS, DROWS_MIN, DBROWS);
  1107. +   CLAMP(DCOLS, DCOLS_MIN, DBCOLS);
  1108.  
  1109. -void dc_printf(char *format, ...)
  1110. -{
  1111. -   char tmp[DCOLS*DROWS];
  1112. -   va_list args;
  1113. -
  1114. -   va_start(args, format);
  1115. -   vsprintf(tmp, format, args);
  1116. -   va_end(args);
  1117. +   // Ensure we don't scroll too far
  1118. +   CLAMP(dc_scroll_x, 0, (DBCOLS - DCOLS));
  1119. +   CLAMP(dc_scroll_y, 0, (dc_buffer.size() - buffer_lines));
  1120.  
  1121. -   char *p = tmp;
  1122. -   while( *p != '\0' ) {
  1123. -       debug_output(*p);
  1124. -       p++;
  1125. +   // Draw the buffer strings
  1126. +   for (i = 0; i < buffer_lines; ++i) {
  1127. +       gr_string(0, ((i * 16) + 16), dc_buffer[i + dc_scroll_y].substr(dc_scroll_x).c_str());  // z64: gr_string's y param may benifit from a font size (in pixels) variable
  1128.     }
  1129. -}
  1130.  
  1131. -void debug_init()
  1132. -{
  1133. -   int i;
  1134. -   if ( debug_inited ) {
  1135. -       return;
  1136. -   }
  1137. -
  1138. -   debug_inited = 1;
  1139. +   // Draw the command string w/ padding only if the prompt is active.
  1140. +   if (show_prompt) {
  1141. +       i += 1;     // 1 line between the output and the input text
  1142.  
  1143. -   debug_x=0;
  1144. -   debug_y=0;
  1145. +       for (str_it = out_str.begin(), j = 0; str_it < out_str.end(); ++str_it, ++j) {
  1146. +           if ((j % (DCOLS - 1)) == 0) {
  1147. +               // Insert a newline char at every place the string needs to return the 'carriage'
  1148. +               out_str.insert(str_it, '\n');
  1149. +               ++j;
  1150. +           }
  1151. +       }
  1152. +       gr_string(0, ((i*16) + 16), out_str.c_str());
  1153.  
  1154. -   for (i=0; i<DROWS; i++ ) {
  1155. -       debug_text[i][0] = 0;
  1156. +       dc_draw_cursor(out_str, 0, ((i*16) + 16));
  1157.     }
  1158. -
  1159. -   dc_printf("Debug console started.\n" );
  1160.  }
  1161.  
  1162. -void debug_console( void (*_func)() )
  1163. +
  1164. +/**
  1165. + * @brief   Stuffs the given character into the output buffer.
  1166. + * @details Also handles tab alignment, newlines, and maintains the target.
  1167. + */
  1168. +void dc_putc(char c)
  1169.  {
  1170. -   int done = 0;
  1171. +   SCP_string* line_str = &dc_buffer.back();
  1172. +   int i;
  1173.  
  1174. -   scanner_init();
  1175. +   if (c == '\t') {
  1176. +       /**
  1177. +        * Calculate how many spaces to put in to align tabs,
  1178. +        * If we run out of room on the line, change c to a '\n' and let subsequent block handle it,
  1179. +        * Else, push the spaces onto the line
  1180. +        */
  1181. +       i = DTABS - (line_str->size() % DTABS);
  1182.  
  1183. -   while( key_inkey() ) {
  1184. -       os_poll();
  1185. +       if ((line_str->size() + i) >= (DBCOLS - 1)) {
  1186. +           c = '\n';
  1187. +       } else {
  1188. +           for (; i > 0; --i) {
  1189. +               line_str->push_back(' ');
  1190. +           }
  1191. +       }
  1192.     }
  1193.  
  1194. -   if ( !debug_inited ) {
  1195. -       debug_init();
  1196. +   if ((c == '\n') || (line_str->size() >= DBCOLS)) {
  1197. +       /**
  1198. +        * Trash whatever char happens to be past (DBCOLS - 1),
  1199. +        * Push a blank line onto the dc_buffer from the bottom,
  1200. +        * Update line_str to point to the new line,
  1201. +        * Trash the topmost line(s) in the buffer, and finally
  1202. +        * Return if the char to push was a \n
  1203. +        */
  1204. +       if (line_str->size() > DBCOLS) {
  1205. +           line_str->resize(DBCOLS);
  1206. +       }
  1207. +       dc_buffer.push_back("");
  1208. +       line_str = &dc_buffer.back();
  1209. +       ++dc_scroll_y;
  1210. +       while (dc_buffer.size() > DBROWS) {
  1211. +           dc_buffer.pop_front();
  1212. +           --dc_scroll_y;
  1213. +       }
  1214. +       if (c == '\n') {
  1215. +           return;
  1216. +       }
  1217.     }
  1218.  
  1219. -   debug_draw();
  1220. +   line_str->push_back(c);
  1221. +}
  1222.  
  1223. -   while (!done) {
  1224. -       // poll the os
  1225. -       os_poll();
  1226. +/**
  1227. + * @brief   Pauses the output of a command and allows user to scroll through the output history.
  1228. + * @details Returns true if user has pressed Esc, returns false otherwise. Use this in your function to (safely?) break
  1229. + *     out of the loop it's presumably in.
  1230. + */
  1231. +bool dc_pause_output(uint &lines)
  1232. +{
  1233. +   dc_printf("More to follow. Press any key to continue. ESC halts output...");
  1234.  
  1235. -       int k = key_inkey();
  1236. -       switch( k ) {
  1237. +   int key;
  1238. +   bool loop;
  1239. +   do {
  1240. +       loop = false;
  1241.  
  1242. -       case KEY_SHIFTED+KEY_ENTER:
  1243. +       key = key_inkey();
  1244. +       switch (key) {
  1245.         case KEY_ESC:
  1246. -           done=1; break;
  1247. -
  1248. -       case KEY_BACKSP:
  1249. -           if ( command_line_pos > 0 ) {
  1250. -               command_line[--command_line_pos] = 0;
  1251. -           }
  1252. +           return true;
  1253.             break;
  1254.  
  1255. -       case KEY_F3:
  1256. -           if ( last_oldcommand > -1 ) {
  1257. -               strcpy_s( command_line, oldcommand_line[last_oldcommand] );
  1258. -               command_line_pos = strlen(command_line);
  1259. -               command_line[command_line_pos] = 0;
  1260. -           }
  1261. +       case KEY_PAGEUP:
  1262. +           // TODO: Scroll Up
  1263. +           loop = true;
  1264.             break;
  1265. -
  1266. -       case KEY_UP:
  1267. -           command_scroll--;
  1268. -           if (command_scroll<0) {
  1269. -               command_scroll = last_oldcommand;
  1270. -           }
  1271. -
  1272. -           if ( command_scroll > -1 ) {
  1273. -               strcpy_s( command_line, oldcommand_line[command_scroll] );
  1274. -               command_line_pos = strlen(command_line);
  1275. -               command_line[command_line_pos] = 0;
  1276. -           }
  1277. +       case KEY_PAGEDOWN:
  1278. +           // TODO: Scroll Down
  1279. +           loop = true;
  1280.             break;
  1281. -
  1282. -       case KEY_DOWN:
  1283. -           command_scroll++;
  1284. -           if (command_scroll>last_oldcommand) {
  1285. -               command_scroll = 0;
  1286. -           }
  1287. -           if (command_scroll>last_oldcommand) {
  1288. -               command_scroll = -1;
  1289. -           }
  1290. -           if ( command_scroll > -1 ) {
  1291. -               strcpy_s( command_line, oldcommand_line[command_scroll] );
  1292. -               command_line_pos = strlen(command_line);
  1293. -               command_line[command_line_pos] = 0;
  1294. -           }
  1295. +       case KEY_LEFT:
  1296. +           // TODO: Scroll Left
  1297. +           loop = true;
  1298.             break;
  1299. -
  1300. -       case KEY_ENTER: {
  1301. -           debug_output( '\n' );
  1302. -           debug_draw();
  1303. -
  1304. -           debug_do_command(command_line);
  1305. -
  1306. -           int i, found = 0;
  1307. -           for (i=0; i<=last_oldcommand; i++ ) {
  1308. -               if (!stricmp( oldcommand_line[i], command_line )) {
  1309. -                   found = 1;
  1310. -               }
  1311. -           }
  1312. -           if ( !found ) {
  1313. -               if ( last_oldcommand < DEBUG_HISTORY-1 ) {
  1314. -                   last_oldcommand++;
  1315. -                   strcpy_s( oldcommand_line[last_oldcommand], command_line);
  1316. -               } else {
  1317. -                   int iLoop;
  1318. -                   for (iLoop=0; iLoop<last_oldcommand; iLoop++ ) {
  1319. -                       strcpy_s( oldcommand_line[iLoop], oldcommand_line[iLoop+1] );
  1320. -                   }
  1321. -                   strcpy_s( oldcommand_line[last_oldcommand], command_line);
  1322. -               }
  1323. -           }
  1324. -
  1325. -           debug_output( '\n' );
  1326. -           command_line_pos = 0;
  1327. -           command_line[command_line_pos] = 0;
  1328. -
  1329. -           command_scroll = 0;
  1330. -
  1331. -           }
  1332. +       case KEY_RIGHT:
  1333. +           // TODO: Scroll Right
  1334. +           loop = true;
  1335.             break;
  1336. -       default: {
  1337. -               ubyte c = (ubyte)key_to_ascii(k);
  1338. -               if ( c != 255 ) {
  1339. -                   command_line[command_line_pos++] = c;
  1340. -                   command_line[command_line_pos] = 0;
  1341. -               }
  1342. -           }
  1343. +       default:
  1344. +           lines = 0;
  1345.         }
  1346. +   } while (loop);
  1347.  
  1348. -       strcpy_s( debug_text[debug_y], ">" );
  1349. -       strcat_s( debug_text[debug_y], command_line );
  1350. -       debug_draw();
  1351. -
  1352. -       if ( _func ) {
  1353. -           _func();
  1354. -       }
  1355. -   }
  1356. -
  1357. -   while( key_inkey() ) {
  1358. -       os_poll();
  1359. -   }
  1360. -}
  1361. -
  1362. -void debug_help()
  1363. -{
  1364. -   int s, i;
  1365. -
  1366. -   dc_printf( "Available functions:\n\n" );
  1367. -
  1368. -   s = scroll_times;
  1369. -   for (i=0; i<Num_debug_commands; i++ ) {
  1370. -       dc_printf( " %s - %s\n", Debug_command[i]->name, Debug_command[i]->help );
  1371. -
  1372. -       if ( scroll_times - s > DROWS - 3 ) {
  1373. -           int k;
  1374. -           dc_printf( "       Press a key...B for back\n" );
  1375. -           debug_draw();
  1376. -           k = key_getch();
  1377. -           s = scroll_times;
  1378. -           if ( k == KEY_B ) {
  1379. -               i -= ((DROWS-3)*2);
  1380. -               if ( i <= 0 ) {
  1381. -                   i = -1;
  1382. -               }
  1383. -           }
  1384. -       }
  1385. -       debug_draw();
  1386. -   }
  1387. -   dc_printf( "\n" );
  1388. -
  1389. -   dc_printf( "Typing '? function_name' will give the current status.\n" );
  1390. -   dc_printf( "Typing 'function_name ?' will give help on the function.\n" );
  1391. -   dc_printf( "Typing ? or help will give you help.\n");
  1392. -   dc_printf( "F3 selects last command line.\n" );
  1393. -}
  1394. +   return false;
  1395. +};
  1396. Index: code/debugconsole/console.h
  1397. ===================================================================
  1398. index 0000000..966cec6
  1399. --- code/debugconsole/console.h (revision 0)
  1400. +++ code/debugconsole/console.h (working copy)
  1401. @@ -0,0 +1,260 @@
  1402. +#ifndef _CONSOLE_H
  1403. +#define _CONSOLE_H
  1404. +/*
  1405. + * z64555's debug console, created for the FreeSpace Source Code project
  1406. + *
  1407. + * Portions of this source code are based on works by Volition, Inc. circa 1999. You may not sell or otherwise
  1408. + * commercially exploit the source or things you created based on the source.
  1409. + */
  1410. +
  1411. +/**
  1412. + * @file console.h
  1413. + * @brief An overhauled/updated debug console to allow monitoring, testing, and general debugging of new features.
  1414. + *
  1415. + * @details
  1416. + * Of key interest is Volition's DCF macro, which adds the function argument to the available command list in the
  1417. + * debug console. These functions may be defined in the .cpp file that they are related to, but it is recommended
  1418. + * that they be in their own .cpp if they have multiple sub-arguments (ex: Git has its sub-arguments delimited by
  1419. + * a pair of -'s, or --)
  1420. + */
  1421. +
  1422. +#include "debugconsole/consoleparse.h"
  1423. +#include "globalincs/pstypes.h"
  1424. +#include "globalincs/vmallocator.h"
  1425. +
  1426. +/**
  1427. + * @def DCF
  1428. + *
  1429. + * @brief The potent DCF macro, used to define new debug commands for the console.
  1430. + *
  1431. + * @param function_name[in] The name of the function, as shown in the debug console
  1432. + * @param help_txt[in] The short-help text, as shown as listed from the 'help' command
  1433. + *
  1434. + * @details Usage example:
  1435. + * DCF(toggle_it,"description")
  1436. + * {
  1437. + *     switch (Dc_mode) {
  1438. + *     case dcm_command:
  1439. + *          This_var = !This_var;
  1440. + *     break;
  1441. + *
  1442. + *     case dcm_help:
  1443. + *         dc_printf( "Usage: sample. Toggles This_var on/off.\n" );
  1444. + *     break;
  1445. + *
  1446. + *     case dcm_status:
  1447. + *         dc_printf( "The status is %d.\n", This_var );
  1448. + *     break;
  1449. + *     default:
  1450. + *         if (Dc_debug_on) {
  1451. + *             dc_printf( "<debug> Unknown command mode %i", Dc_mode);
  1452. + *         }
  1453. + *     }
  1454. + * }
  1455. + *  
  1456. + *  In the console, the command will be listed as 'toggle_it', and help will display it as:
  1457. + *      toggle_it  - Usage: sample. Toggles This_var on/off.
  1458. + *  Note: The only allowed function type is a void fn( void )
  1459. + */
  1460. +#define DCF(function_name, help_text)  \
  1461. +       void dcf_##function_name(); \
  1462. +       debug_command dcmd_##function_name(#function_name, help_text, dcf_##function_name); \
  1463. +       void dcf_##function_name()
  1464. +
  1465. +
  1466. +/**
  1467. + *  @def Shortcut for debug commands that toggle a bool, such as Show_lightning
  1468. + *  
  1469. + *  @param [in] function_name Name of the function, as shown in the debug console
  1470. + *  @param [in] bool_variable Name of the variable to allow toggling.
  1471. + */
  1472. +#define DCF_BOOL(function_name, bool_variable) \
  1473. +   void dcf_##function_name();     \
  1474. +   debug_command dcmd_##function_name(#function_name, "Sets or toggles the boolean: "#bool_variable, dcf_##function_name );    \
  1475. +   void dcf_##function_name() {    \
  1476. +       if (dc_optional_string_either("help", "--help")) {  \
  1477. +               dc_printf( "Usage: %s [bool]\nSets %s to true or false.  If nothing passed, then toggles it.\n", #function_name, #bool_variable );  \
  1478. +               return;     \
  1479. +       }   \
  1480. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  1481. +           dc_printf("%s = %s\n", #function_name, (bool_variable ? "TRUE" : "FALSE"));     \
  1482. +           return;     \
  1483. +       }   \
  1484. +       if (!dc_maybe_stuff_boolean(&bool_variable)) {  \
  1485. +           bool_variable = !bool_variable; \
  1486. +       }   \
  1487. +   }   \
  1488. +
  1489. +
  1490. +/**
  1491. + *  @def Same as DCF_BOOL, but with custom help strings
  1492. + *  
  1493. + *  @param [in] function_name Name of the function, as shown in the debug console
  1494. + *  @param [in] bool_variable Name of the variable to allow toggling.
  1495. + */
  1496. +#define DCF_BOOL2(function_name, bool_variable, short_help, long_help) \
  1497. +   void dcf_##function_name();     \
  1498. +   debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );  \
  1499. +   void dcf_##function_name() {    \
  1500. +       if (dc_optional_string_either("help", "--help")) {  \
  1501. +           dc_printf( #long_help );    \
  1502. +               return;     \
  1503. +       }   \
  1504. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  1505. +           dc_printf("%s = %s\n", #function_name, (bool_variable ? "TRUE" : "FALSE"));     \
  1506. +           return;     \
  1507. +       }   \
  1508. +       if (!dc_maybe_stuff_boolean(&bool_variable)) {  \
  1509. +           bool_variable = !bool_variable; \
  1510. +       }   \
  1511. +   }   \
  1512. +
  1513. + /**
  1514. +  * @def Shortcut for single-variable setters/monitors
  1515. +  *
  1516. +  * @param [in] function_name
  1517. +  * @param [in] float_variable
  1518. +  * @param [in] short_help
  1519. +  */
  1520. + #define DCF_FLOAT(function_name, float_variable, short_help)  \
  1521. +   void dcf_##function_name();     \
  1522. +   debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );  \
  1523. +   void dcf_##function_name() {    \
  1524. +       float value;    \
  1525. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  1526. +           dc_printf("%s = %f\n", #float_variable, float_variable);        \
  1527. +           return;     \
  1528. +       }   \
  1529. +       dc_stuff_float(&value); \
  1530. +       float_variable = value; \
  1531. +       dc_printf("%s set to %f\n", #float_variable, float_variable);   \
  1532. +   }   \
  1533. +
  1534. + /**
  1535. +  * @def Shortcut for single-variable setters/monitors with lower/upper bounds clamping
  1536. +  *
  1537. +  * @param [in] function_name
  1538. +  * @param [in] float_variable
  1539. +  * @param [in] short_help
  1540. +  */
  1541. + #define DCF_FLOAT2(function_name, float_variable, lower_bounds, upper_bounds, short_help) \
  1542. +   void dcf_##function_name();     \
  1543. +   debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );  \
  1544. +   void dcf_##function_name() {    \
  1545. +       float value;    \
  1546. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  1547. +           dc_printf("%s = %f\n", #float_variable, float_variable);        \
  1548. +           return;     \
  1549. +       }   \
  1550. +       dc_stuff_float(&value); \
  1551. +       CLAMP(float_variable, lower_bounds, upper_bounds);  \
  1552. +       float_variable = value; \
  1553. +       dc_printf("%s set to %f\n", #float_variable, float_variable);   \
  1554. +   }   \
  1555. +
  1556. + /**
  1557. +  * @def Shortcut for single-variable setters/monitors
  1558. +  *
  1559. +  * @param [in] function_name
  1560. +  * @param [in] int_variable
  1561. +  * @param [in] short_help
  1562. +  */
  1563. + #define DCF_INT(function_name, int_variable, short_help)  \
  1564. +   void dcf_##function_name();     \
  1565. +   debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );  \
  1566. +   void dcf_##function_name() {    \
  1567. +       float value;    \
  1568. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  1569. +           dc_printf("%s = %f\n", #int_variable, int_variable);        \
  1570. +           return;     \
  1571. +       }   \
  1572. +       dc_stuff_float(&value); \
  1573. +       int_variable = value;   \
  1574. +       dc_printf("%s set to %f\n", #int_variable, int_variable);   \
  1575. +   }   \
  1576. +
  1577. + /**
  1578. +  * @def Shortcut for single-variable setters/monitors with lower/upper bounds clamping
  1579. +  *
  1580. +  * @param [in] function_name
  1581. +  * @param [in] int_variable
  1582. +  * @param [in] short_help
  1583. +  */
  1584. + #define DCF_INT2(function_name, int_variable, lower_bounds, upper_bounds, short_help) \
  1585. +   void dcf_##function_name();     \
  1586. +   debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );  \
  1587. +   void dcf_##function_name() {    \
  1588. +       float value;    \
  1589. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  1590. +           dc_printf("%s = %f\n", #int_variable, int_variable);        \
  1591. +           return;     \
  1592. +       }   \
  1593. +       dc_stuff_float(&value); \
  1594. +       CLAMP(int_variable, lower_bounds, upper_bounds);    \
  1595. +       int_variable = value;   \
  1596. +       dc_printf("%s set to %f\n", #int_variable, int_variable);   \
  1597. +   }   \
  1598. +
  1599. +/**
  1600. + *  @class debug_command
  1601. + *  @brief Class to aggregate a debug command with its name (as shown in the console) and short help.
  1602. + *  
  1603. + *  @details
  1604. + *  Note: Long help, as evoked by '<command> help', should be handled by the function itself. It is recommended
  1605. + *  that arguments that have sub-arguments be in their own function, so as to aide in organization and to keep the
  1606. + *  size of the command function down.
  1607. + */
  1608. +class debug_command {
  1609. +public:
  1610. +   char *name;     //!< The name of the command, as shown in the debug console
  1611. +   char *help;     //!< The short help string, as shown by 'help <command>'
  1612. +   void (*func)(); //!< Pointer to the function that is run when this command is evoked
  1613. +
  1614. +   /**
  1615. +   * @brief Adds a debug command to the debug_commands map, if it isn't in there already.
  1616. +   *
  1617. +   * @details The DCF macro more or less guarantees that a command won't be duplicated on compile time. But no harm in
  1618. +   *   some extra caution.
  1619. +   */
  1620. +   debug_command(char *name, char *help, void (*func)());
  1621. +};
  1622. +
  1623. +/**
  1624. + * Dc_mode tells your function what to do.
  1625. + * Your function _must_ process the command.
  1626. + *
  1627. + * It is recommended that each function have, at minimum, this switch statement:
  1628. + *   switch (Dc_mode) {
  1629. + *   case dcm_command:
  1630. + *     // process command
  1631. + *     break;
  1632. + *  
  1633. + *   case dcm_help:
  1634. + *     // provide detailed help
  1635. + *     break;
  1636. + *  
  1637. + *   case dcm_status:
  1638. + *     // provide status on the command
  1639. + *     break;
  1640. + *  
  1641. + *   default:
  1642. + *     // (optional)
  1643. + *     dc_printf("<command_name> Unknown command mode %i\n", Dc_mode);
  1644. + *   }
  1645. + */
  1646. +enum dc_mode {
  1647. +   dcm_command,    // process the command
  1648. +   dcm_help,       // print out the help text in the form, "usage: ... \nLong description\n" );
  1649. +   dcm_status      // print out the current status of the command.
  1650. +};
  1651. +
  1652. +extern dc_mode Dc_mode;
  1653. +extern bool Dc_debug_on;
  1654. +
  1655. +extern SCP_string dc_command_str;  // The rest of the command line, from the end of the last processed arg on.
  1656. +
  1657. +void debug_console(void (*func)(void) = NULL);     // Starts the debug console, and runs the given function after each time a command is processed
  1658. +void dc_printf( char *format, ... );               // Outputs to the debug console
  1659. +bool dc_pause_output(uint &lines);                 // Pauses execution and waits for user intput. Allows scrolling.
  1660. +
  1661. +#endif // _CONSOLE_H
  1662. \ No newline at end of file
  1663. Index: code/debugconsole/consolecmds.cpp
  1664. ===================================================================
  1665. index 0000000..da30632
  1666. --- code/debugconsole/consolecmds.cpp   (revision 0)
  1667. +++ code/debugconsole/consolecmds.cpp   (working copy)
  1668. @@ -0,0 +1,162 @@
  1669. +/*
  1670. + * z64555's debug console
  1671. + * Created for the FreeSpace Source Code project
  1672. + *
  1673. + * Portions of this source code are based on works by Volition, Inc. circa
  1674. + * 1999. You may not sell or otherwise commercially exploit the source or things you
  1675. + * created based on the source
  1676. + */
  1677. +
  1678. +/**
  1679. + *  @file consolecmds.cpp
  1680. + *  
  1681. + *  @brief This file contains the "built-in" commands for the debug console, and is listed by the 'help' and '?' commands
  1682. + *  
  1683. + *  @details
  1684. + *  All other debug commands should be in their respective files and added to the console with the DCF macro. For
  1685. + *  further documentation, please see console.h
  1686. + */
  1687. +
  1688. +#include "debugconsole/console.h"
  1689. +#include "debugconsole/consoleparse.h"
  1690. +#include "globalincs/pstypes.h"
  1691. +#include "globalincs/vmallocator.h"
  1692. +#include "io/key.h"
  1693. +
  1694. +SCP_map<SCP_string, debug_command*> dc_commands;
  1695. +typedef SCP_map<SCP_string, debug_command*>::iterator dc_commands_it;
  1696. +
  1697. +debug_command::debug_command(char *_name, char *_help, void (*_func)())
  1698. +{
  1699. +   SCP_map<SCP_string, debug_command*>::iterator it = dc_commands.find(_name);
  1700. +  
  1701. +   if (it != dc_commands.end()) {
  1702. +       Int3();     // Command already exists! Somebody didn't use the DCF macro as they should've...
  1703. +   }
  1704. +
  1705. +   dc_commands[_name] = this;
  1706. +
  1707. +   name = _name;
  1708. +   help = _help;
  1709. +   func = _func;
  1710. +}
  1711. +
  1712. +DCF( debug, "Runs a command in debug mode.")
  1713. +{
  1714. +   SCP_string command = "";
  1715. +   Dc_debug_on = true;
  1716. +
  1717. +   dc_stuff_string_white(command);
  1718. +
  1719. +   if (command == "") {
  1720. +       dc_printf("<debug> No command given");
  1721. +       return;
  1722. +   } // Else, command is present.
  1723. +
  1724. +   dc_commands_it it = dc_commands.find(command);
  1725. +
  1726. +   if (it == dc_commands.end()) {
  1727. +       dc_printf("<debug> Command not found: '%s'\n", command);
  1728. +       return;
  1729. +   } // Else, command exists. Run it.
  1730. +
  1731. +   dc_printf("<debug> Executing command: '%s'\n", command);
  1732. +   // try {
  1733. +   (it->second)->func();
  1734. +   // } catch {
  1735. +   // }
  1736. +
  1737. +   Dc_debug_on = false;
  1738. +}
  1739. +
  1740. +DCF( help, "Displays the help list." )
  1741. +{
  1742. +   extern uint DBCOLS;
  1743. +   unsigned int lines;
  1744. +   SCP_string command = "";
  1745. +
  1746. +   dc_stuff_string_white(command);
  1747. +
  1748. +   if (command != "") {
  1749. +       dc_commands_it it = dc_commands.find(command);
  1750. +
  1751. +       if (it == dc_commands.end()) {
  1752. +           dc_printf("Command not found: '%s'\n", command);
  1753. +           return;
  1754. +       }
  1755. +
  1756. +       dc_printf((it->second)->help);
  1757. +       return;
  1758. +   } // Else, command line is empty, print out the help list
  1759. +
  1760. +   dc_printf("FreeSpace Open Debug Console\n");
  1761. +   dc_printf(" These commands are defined internally.\n");
  1762. +   dc_printf(" Typing 'help function_name' will give the short help on the function.\n");
  1763. +   dc_printf(" Some functions may have detailed help, try passing \"help\" or \"--help\" to them.");
  1764. +   dc_printf(" F3 selects last command line. Up and Down arrow keys scroll through the command history\n");
  1765. +   dc_printf("\n");
  1766. +
  1767. +   dc_printf(" Available commands:\n");
  1768. +   lines = 0;
  1769. +   for (dc_commands_it it = dc_commands.begin(); it != dc_commands.end(); ++it) {
  1770. +       if (lines >= (DBCOLS - 1)) {
  1771. +           if (dc_pause_output(lines) == true) {
  1772. +               break;
  1773. +           }
  1774. +       }
  1775. +
  1776. +       dc_printf(" %s\t\t- %s", (it->second)->name, (it->second)->help);
  1777. +       ++lines;
  1778. +   }
  1779. +}
  1780. +
  1781. +debug_command dc_man("man", "Also displays the help list", dcf_help);
  1782. +
  1783. +void dc_shell_font( void );
  1784. +void dc_shell_resize( void );
  1785. +void dc_shell_resize_buf( void );
  1786. +
  1787. +DCF( shell, "Change/set various console-related settings.\n" )
  1788. +{
  1789. +   switch (Dc_mode) {
  1790. +   case dcm_command:
  1791. +       dc_printf("Sorry, This command is not implemented yet...");
  1792. +       break;
  1793. +
  1794. +   case dcm_help:
  1795. +       dc_printf("Shell: Change/set various console-related settings.\n");
  1796. +       dc_printf(" Available arguments:\n");
  1797. +       dc_printf("\t-font       - Change the console font");
  1798. +       dc_printf("\t-resize     - Resize the console window\n");
  1799. +       dc_printf("\t-resize_buf - Resize the console buffer\n");
  1800. +       break;
  1801. +
  1802. +   case dcm_status:
  1803. +       dc_printf("<shell> No status available.\n");
  1804. +       break;
  1805. +
  1806. +   default:
  1807. +       dc_printf("<shell> Unknown command mode %i\n", Dc_mode);
  1808. +   }
  1809. +}
  1810. +
  1811. +DCF( pause, "Pause/Unpause the game. (Singleplayer only)\n")
  1812. +{
  1813. +   switch (Dc_mode) {
  1814. +   case dcm_command:
  1815. +       dc_printf("Sorry, This command is not implemented yet...");
  1816. +       break;
  1817. +
  1818. +   case dcm_help:
  1819. +       dc_printf("Pause: Pause/Unpause the game.\n");
  1820. +       dc_printf(" Only available in singleplayer games.\n");
  1821. +       break;
  1822. +
  1823. +   case dcm_status:
  1824. +       dc_printf("No status available.\n");
  1825. +       break;
  1826. +
  1827. +   default:
  1828. +       dc_printf("<pause> Unknown command mode %i\n", Dc_mode);
  1829. +   }
  1830. +}
  1831. Index: code/debugconsole/consoleparse.cpp
  1832. ===================================================================
  1833. index 0000000..2c9c2ae
  1834. --- code/debugconsole/consoleparse.cpp  (revision 0)
  1835. +++ code/debugconsole/consoleparse.cpp  (working copy)
  1836. @@ -0,0 +1,1452 @@
  1837. +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1838. +// Command-line parsing functions for z64555's debug console, created for the FreeSpace Source Code project
  1839. +//
  1840. +// Portions of this source code are based on works by Volition, Inc. circa 1999. You may not sell or otherwise
  1841. +// commercially exploit the source or things you created based on the source.
  1842. +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1843. +
  1844. +/////////////////
  1845. +// Testing Goals
  1846. +// Breakpoints are set at places that need testing:
  1847. +// * the value of endptr strtol and strtoul needs to investigated, according to cplusplus.com, *endptr = end of the string that was successfully converted
  1848. +// TODO: Make a fast version of the parse_long, parse_ulong, etc. That just checks the first 1-3 characters. The fast version will be used in retail builds while the slow/safe version will be in debug's
  1849. +////////////////
  1850. +#include "debugconsole/consoleparse.h"
  1851. +
  1852. +#include "debugconsole/console.h"
  1853. +#include "globalincs/pstypes.h"
  1854. +#include "parse/parselo.h"
  1855. +
  1856. +#include <cstring>
  1857. +
  1858. +// ========================= LOCALS =========================
  1859. +char Command_string[MAX_CLI_LEN];
  1860. +char *Cp = NULL;
  1861. +
  1862. +enum state_int {
  1863. +   si_start   = 0,
  1864. +   si_end     = 1,
  1865. +   si_invalid,
  1866. +   si_sign,        //!< Sign character, '-' '+'
  1867. +   si_prefix,      //!< prefix character sequence, 0b, 0o, or 0x
  1868. +   si_numeral,     //!< Numeral state, 0 - 9
  1869. +   si_numeral_bin,     //!< Numeral altstate, 0, 1
  1870. +   si_numeral_octal,   //!< Numeral altstate, 0 - 7
  1871. +   si_numeral_hex      //!< Numeral altstate, 0 - 9 and 'a' - 'f'
  1872. +};
  1873. +
  1874. +enum state_float {
  1875. +   sf_start = 0,
  1876. +   sf_end = 1,
  1877. +   sf_invalid,
  1878. +   sf_sign,        //!< Sign character for mantessa
  1879. +   sf_whole,       //!< Whole value numeral
  1880. +   sf_decimal,     //!< Decimal character
  1881. +   sf_fraction,    //!< Fractional value numeral
  1882. +   sf_expprefix,   //!< Exponent prefix, 'e', 'E'
  1883. +   sf_expsign,     //!< Exponent sign
  1884. +   sf_exponent     //!< Exponent value numeral
  1885. +};
  1886. +
  1887. +bool ch_is_sign(char ch);
  1888. +bool ch_is_numeral(char ch);
  1889. +bool ch_is_decimal(char ch);
  1890. +bool ch_is_binary(char ch);
  1891. +bool ch_is_octal(char ch);
  1892. +bool ch_is_hex(char ch);
  1893. +
  1894. +bool ch_is_prefix(char ch);
  1895. +bool ch_is_binary_prefix(char ch);
  1896. +bool ch_is_octal_prefix(char ch);
  1897. +bool ch_is_hex_prefix(char ch);
  1898. +bool ch_is_exp_prefix(char ch);
  1899. +
  1900. +char *dc_get_token(void);
  1901. +char *dc_get_token_no_advance(void);
  1902. +
  1903. +double dc_parse_double(char *ch, dc_token type);
  1904. +long   dc_parse_long(char *ch, dc_token type);
  1905. +ulong  dc_parse_ulong(char *ch, dc_token type);
  1906. +
  1907. +state_int process_state_prefix(char *ch_ptr, SCP_string &buffer_str, int &base);
  1908. +state_int process_state_sign(char *ch_ptr, SCP_string &buffer_str);
  1909. +state_int process_state_numeral(char *ch_ptr, SCP_string &buffer_str);
  1910. +state_int process_state_numeral_bin(char *ch_ptr, SCP_string &buffer_str);
  1911. +state_int process_state_numeral_hex(char *ch_ptr, SCP_string &buffer_str);
  1912. +state_int process_state_numeral_octal(char *ch_ptr, SCP_string &buffer_str);
  1913. +
  1914. +
  1915. +// ============================== IMPLEMENTATIONS =============================
  1916. +// Character identification
  1917. +inline
  1918. +bool ch_is_sign(char ch)
  1919. +{
  1920. +   return ((ch == '-') || (ch == '+'));
  1921. +}
  1922. +
  1923. +inline
  1924. +bool ch_is_numeral(char ch)
  1925. +{
  1926. +   return ((ch >= '0') && (ch <= '9'));
  1927. +}
  1928. +
  1929. +inline
  1930. +bool ch_is_decimal(char ch)
  1931. +{
  1932. +   return (ch == '.');
  1933. +}
  1934. +
  1935. +inline
  1936. +bool ch_is_binary(char ch)
  1937. +{
  1938. +   return ((ch == '0') || (ch == '1'));
  1939. +}
  1940. +
  1941. +inline
  1942. +bool ch_is_octal(char ch)
  1943. +{
  1944. +   return ((ch >= '0') && (ch <= '7'));
  1945. +}
  1946. +
  1947. +inline
  1948. +bool ch_is_hex(char ch)
  1949. +{
  1950. +   return (((ch >= '0') && (ch <= '9')) || ((ch >= 'a') && (ch <= 'f')) || ((ch >= 'A') || (ch <= 'F')));
  1951. +};
  1952. +
  1953. +inline
  1954. +bool ch_is_prefix(char ch)
  1955. +{
  1956. +   return (ch == '0');
  1957. +}
  1958. +
  1959. +inline
  1960. +bool ch_is_binary_prefix(char ch)
  1961. +{
  1962. +   return ((ch == 'b') || (ch == 'B'));
  1963. +}
  1964. +
  1965. +inline
  1966. +bool ch_is_octal_prefix(char ch)
  1967. +{
  1968. +   return ((ch == 'o') || (ch == 'O'));
  1969. +}
  1970. +
  1971. +inline
  1972. +bool ch_is_hex_prefix(char ch)
  1973. +{
  1974. +   return ((ch == 'x') || (ch == 'X'));
  1975. +}
  1976. +
  1977. +inline
  1978. +bool ch_is_exp_prefix(char ch)
  1979. +{
  1980. +   return ((ch == 'e') || (ch == 'E'));
  1981. +}
  1982. +
  1983. +// Getters
  1984. +
  1985. +/**
  1986. + * @brief Returns/Advances past a single token
  1987. + */
  1988. +char * dc_get_token(void) {
  1989. +   char token[MAX_TOKEN_LENGTH];
  1990. +   char *begin_ptr;
  1991. +
  1992. +   dc_ignore_gray_space();
  1993. +
  1994. +   begin_ptr = Cp;
  1995. +
  1996. +   while ((*Cp != '\0') && !is_gray_space(*Cp)) {
  1997. +       Cp++;
  1998. +   }
  1999. +
  2000. +   strncpy(token, begin_ptr, (Cp - begin_ptr));
  2001. +   return token;
  2002. +}
  2003. +
  2004. +/**
  2005. + * @brief Returns a single token, but does not advances Cp
  2006. + */
  2007. +char * dc_get_token_no_advance(void) {
  2008. +   char token[MAX_TOKEN_LENGTH];
  2009. +   char *begin_ptr;
  2010. +   char *ch_ptr = Cp;
  2011. +
  2012. +   while ((*ch_ptr != '\0') && is_gray_space(*ch_ptr)) {
  2013. +       ch_ptr++;
  2014. +   }
  2015. +
  2016. +   begin_ptr = ch_ptr;
  2017. +
  2018. +   while ((*ch_ptr != '\0') && !is_gray_space(*ch_ptr)) {
  2019. +       ch_ptr++;
  2020. +   }
  2021. +
  2022. +   strncpy(token, begin_ptr, (ch_ptr - begin_ptr));
  2023. +   return token;
  2024. +}
  2025. +
  2026. +void dc_ignore_white_space(void) {
  2027. +   while (is_white_space(*Cp) && (*Cp != '\0')) {
  2028. +       Cp++;
  2029. +   }
  2030. +}
  2031. +
  2032. +void dc_ignore_gray_space(void) {
  2033. +   while (is_gray_space(*Cp) && (*Cp != '\0')) {
  2034. +       Cp++;
  2035. +   }
  2036. +}
  2037. +
  2038. +// Required/Optional Strings
  2039. +bool dc_required_string(char *pstr)
  2040. +{
  2041. +   char *str_found = NULL;
  2042. +
  2043. +   dc_ignore_gray_space();
  2044. +
  2045. +   if (strnicmp(pstr, Cp, strlen(pstr))) {
  2046. +       str_found = pstr;
  2047. +   }
  2048. +
  2049. +   if (str_found != NULL) {
  2050. +       // Found a required string
  2051. +       if (Dc_debug_on) {
  2052. +           dc_printf("<debug> Found required string [%s}\n", str_found);
  2053. +       }
  2054. +
  2055. +       Cp += strlen(str_found);
  2056. +   } else {
  2057. +       // Didn't find a required string.
  2058. +       throw errParseString(dc_get_token_no_advance(), pstr);
  2059. +   }
  2060. +   return true;
  2061. +}
  2062. +
  2063. +int dc_required_string_either(char *str1, char *str2)
  2064. +{
  2065. +   char *str_found = NULL;
  2066. +   int i = -1;
  2067. +
  2068. +   dc_ignore_gray_space();
  2069. +
  2070. +   if (strncmp(str1, Cp, strlen(str1) == 0)) {
  2071. +       str_found = str1;
  2072. +       i = 0;
  2073. +   } else if (strncmp(str2, Cp, strlen(str2) == 0)) {
  2074. +       str_found = str2;
  2075. +       i = 1;
  2076. +   }
  2077. +
  2078. +   if (i > -1) {
  2079. +       // Found a required string
  2080. +       if (Dc_debug_on) {
  2081. +           dc_printf("<debug> Found required string [%s}\n", str_found);
  2082. +       }
  2083. +
  2084. +       Cp += strlen(str_found);
  2085. +   } else {
  2086. +       // Didn't find a required string.
  2087. +       throw errParseString(dc_get_token_no_advance(), str1, str2);
  2088. +   }
  2089. +
  2090. +   return i;
  2091. +}
  2092. +
  2093. +int dc_required_string_3(char *str1, char *str2, char *str3)
  2094. +{
  2095. +   char *str_found = NULL;
  2096. +   int i = -1;
  2097. +
  2098. +   dc_ignore_gray_space();
  2099. +
  2100. +   if (strncmp(str1, Cp, strlen(str1) == 0)) {
  2101. +       str_found = str1;
  2102. +       i = 0;
  2103. +   } else if (strncmp(str2, Cp, strlen(str2) == 0)) {
  2104. +       str_found = str2;
  2105. +       i = 1;
  2106. +   } else if (strncmp(str3, Cp, strlen(str3) == 0)) {
  2107. +       str_found = str3;
  2108. +       i = 2;
  2109. +   }
  2110. +
  2111. +   if (i > -1) {
  2112. +       // Found a required string
  2113. +       if (Dc_debug_on) {
  2114. +           dc_printf("<debug> Found required string [%s}\n", str_found);
  2115. +       }
  2116. +
  2117. +       Cp += strlen(str_found);
  2118. +   } else {
  2119. +       // Didn't find a required string.
  2120. +       throw errParseString(dc_get_token_no_advance(), str1, str2, str3);
  2121. +   }
  2122. +
  2123. +   return i;
  2124. +}
  2125. +
  2126. +int dc_required_string_4(char *str1, char *str2, char *str3, char *str4)
  2127. +{
  2128. +   char *str_found = NULL;
  2129. +   int i = -1;
  2130. +
  2131. +   dc_ignore_gray_space();
  2132. +
  2133. +   if (strncmp(str1, Cp, strlen(str1) == 0)) {
  2134. +       str_found = str1;
  2135. +       i = 0;
  2136. +   } else if (strncmp(str2, Cp, strlen(str2) == 0)) {
  2137. +       str_found = str2;
  2138. +       i = 1;
  2139. +   } else if (strncmp(str3, Cp, strlen(str3) == 0)) {
  2140. +       str_found = str3;
  2141. +       i = 2;
  2142. +   } else if (strncmp(str4, Cp, strlen(str4) == 0)) {
  2143. +       str_found = str4;
  2144. +       i = 3;
  2145. +   }
  2146. +
  2147. +   if (i > -1) {
  2148. +       // Found a required string
  2149. +       if (Dc_debug_on) {
  2150. +           dc_printf("<debug> Found required string [%s}\n", str_found);
  2151. +       }
  2152. +
  2153. +       Cp += strlen(str_found);
  2154. +   } else {
  2155. +       // Didn't find a required string.
  2156. +       throw errParseString(dc_get_token_no_advance(), str1, str2, str3, str4);
  2157. +   }
  2158. +
  2159. +   return i;
  2160. +}
  2161. +
  2162. +bool dc_optional_string(char *pstr)
  2163. +{
  2164. +   dc_ignore_gray_space();
  2165. +
  2166. +   if (strncmp(pstr, Cp, strlen(pstr) != 0)) {
  2167. +       return false;
  2168. +   } // Else, optional string was found
  2169. +
  2170. +   if (Dc_debug_on) {
  2171. +       dc_printf("<debug> Found optional string [%s]\n", pstr);
  2172. +   }
  2173. +
  2174. +   Cp += strlen(pstr);
  2175. +   return true;
  2176. +}
  2177. +
  2178. +bool dc_optional_string_either(char *str1, char *str2)
  2179. +{
  2180. +   char * str_found = NULL;
  2181. +
  2182. +   dc_ignore_gray_space();
  2183. +
  2184. +   if (strncmp(str1, Cp, strlen(str1)) == 0) {
  2185. +       str_found = str1;
  2186. +   } else if (strncmp(str2, Cp, strlen(str2)) == 0) {
  2187. +       str_found = str2;
  2188. +   } else {
  2189. +       return false;
  2190. +   }
  2191. +
  2192. +   if (Dc_debug_on) {
  2193. +       dc_printf("<debug> Found optional string [%s]\n",str_found);
  2194. +   }
  2195. +
  2196. +   Cp += strlen(str_found);
  2197. +   return true;;
  2198. +}
  2199. +
  2200. +// Parsers
  2201. +
  2202. +/**
  2203. + * @brief Initializes the DC command line parser
  2204. + */
  2205. +void dc_parse_init(SCP_string &str)
  2206. +{
  2207. +   strcpy(Command_string, str.c_str());
  2208. +   Cp = Command_string;
  2209. +}
  2210. +
  2211. +/**
  2212. + * @brief Parses a double-precision floating point type. Supports, Whole, Fractional, and Mixed numbers, and supports
  2213. + *   scientific notation (exponent prefixed by 'e' or 'E').
  2214. + *
  2215. + * @param[in] ch   Points to the start of the string to parse
  2216. + * @param[in] type The expected type. is thrown along with ch when an unexpected/malformed float is found
  2217. + *
  2218. + * @details
  2219. + *   The returned double may be cast to a single-precision float, but be sure to check it before doing so!
  2220. + */
  2221. +double dc_parse_double(char *ch, dc_token type) {
  2222. +   char *ch_ptr = ch;
  2223. +   char *end_ptr;
  2224. +   double ret;
  2225. +   state_float state = sf_start;
  2226. +   SCP_string buffer_str;
  2227. +
  2228. +   do {
  2229. +       if ((ch_ptr == '\0') || is_white_space(*ch_ptr)) {
  2230. +           state = sf_end;
  2231. +       }
  2232. +
  2233. +       switch (state) {
  2234. +       case sf_start:
  2235. +           if (ch_is_sign(*ch_ptr)) {
  2236. +               state = sf_sign;
  2237. +               if (*ch_ptr == '-') {
  2238. +                   buffer_str.push_back(*ch_ptr);
  2239. +               } // Else, sign is positive, and isn't needed on the buffer
  2240. +               ch_ptr++;
  2241. +
  2242. +           } else if (ch_is_numeral(*ch_ptr)) {
  2243. +               state = sf_whole;
  2244. +               buffer_str.push_back(*ch_ptr);
  2245. +               ch_ptr++;
  2246. +
  2247. +           } else if (ch_is_decimal(*ch_ptr)) {
  2248. +               state = sf_decimal;
  2249. +               buffer_str.push_back(*ch_ptr);
  2250. +               ch_ptr++;
  2251. +
  2252. +           } else {
  2253. +               if (Dc_debug_on) {
  2254. +                   dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_start\n", *ch_ptr);
  2255. +               }
  2256. +               state = sf_invalid;
  2257. +
  2258. +           }
  2259. +           break;
  2260. +       case sf_end:
  2261. +           if ((buffer_str == "") || (buffer_str == "-"))
  2262. +           {
  2263. +               state = sf_invalid;
  2264. +           } // Else, we can convert the token.
  2265. +           // Do nothing, and allow the while loop exit condition to trigger
  2266. +           break;
  2267. +       case sf_sign:
  2268. +           if (ch_is_numeral(*ch_ptr)) {
  2269. +               state = sf_whole;
  2270. +               buffer_str.push_back(*ch_ptr);
  2271. +               ch_ptr++;
  2272. +
  2273. +           } else if (ch_is_decimal(*ch_ptr)) {
  2274. +               state = sf_decimal;
  2275. +               buffer_str.push_back(*ch_ptr);
  2276. +               ch_ptr++;
  2277. +
  2278. +           } else {
  2279. +               if (Dc_debug_on) {
  2280. +                   dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_sign\n", *ch_ptr);
  2281. +               }
  2282. +               state = sf_invalid;
  2283. +
  2284. +           }
  2285. +           break;
  2286. +       case sf_whole:
  2287. +           if (ch_is_numeral(*ch_ptr)) {
  2288. +               buffer_str.push_back(*ch_ptr);
  2289. +               ch_ptr++;
  2290. +
  2291. +           } else if (ch_is_decimal(*ch_ptr)) {
  2292. +               state = sf_decimal;
  2293. +               buffer_str.push_back(*ch_ptr);
  2294. +               ch_ptr++;
  2295. +
  2296. +           } else if (ch_is_exp_prefix(*ch_ptr)) {
  2297. +               state = sf_expprefix;
  2298. +               buffer_str.push_back(*ch_ptr);
  2299. +               ch_ptr++;
  2300. +
  2301. +           } else {
  2302. +               if (Dc_debug_on) {
  2303. +                   dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_whole\n", *ch_ptr);
  2304. +               }
  2305. +               state = sf_invalid;
  2306. +
  2307. +           }
  2308. +           break;
  2309. +       case sf_decimal:
  2310. +           if (ch_is_numeral(*ch_ptr)) {
  2311. +               state = sf_fraction;
  2312. +               buffer_str.push_back(*ch_ptr);
  2313. +               ch_ptr++;
  2314. +
  2315. +           } else if (ch_is_exp_prefix(*ch_ptr)) {
  2316. +               state = sf_expprefix;
  2317. +               buffer_str.push_back(*ch_ptr);
  2318. +               ch_ptr++;
  2319. +
  2320. +           } else {
  2321. +               if (Dc_debug_on) {
  2322. +                   dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_decimal\n", *ch_ptr);
  2323. +               }
  2324. +               state = sf_invalid;
  2325. +
  2326. +           }
  2327. +           break;
  2328. +       case sf_fraction:
  2329. +           if (ch_is_numeral(*ch_ptr)) {
  2330. +               buffer_str.push_back(*ch_ptr);
  2331. +               ch_ptr++;
  2332. +
  2333. +           } else if (ch_is_exp_prefix(*ch_ptr)) {
  2334. +               state = sf_expprefix;
  2335. +               buffer_str.push_back(*ch_ptr);
  2336. +               ch_ptr++;
  2337. +
  2338. +           } else {
  2339. +               if (Dc_debug_on) {
  2340. +                   dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_faction\n", *ch_ptr);
  2341. +               }
  2342. +               state = sf_invalid;
  2343. +
  2344. +           }
  2345. +           break;
  2346. +       case sf_expprefix:
  2347. +           if (ch_is_sign(*ch_ptr)) {
  2348. +               state = sf_expsign;
  2349. +               buffer_str.push_back(*ch_ptr);
  2350. +               ch_ptr++;
  2351. +
  2352. +           } else if (ch_is_numeral(*ch_ptr)) {
  2353. +               state = sf_exponent;
  2354. +               buffer_str.push_back(*ch_ptr);
  2355. +               ch_ptr++;
  2356. +
  2357. +           } else {
  2358. +               if (Dc_debug_on) {
  2359. +                   dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_expprefix\n", *ch_ptr);
  2360. +               }
  2361. +               state = sf_invalid;
  2362. +
  2363. +           }
  2364. +           break;
  2365. +       case sf_expsign:
  2366. +           if (ch_is_numeral(*ch_ptr)) {
  2367. +               state = sf_exponent;
  2368. +               buffer_str.push_back(*ch_ptr);
  2369. +               ch_ptr++;
  2370. +
  2371. +           } else {
  2372. +               if (Dc_debug_on) {
  2373. +                   dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_expsign\n", *ch_ptr);
  2374. +               }
  2375. +               state = sf_invalid;
  2376. +
  2377. +           }
  2378. +           break;
  2379. +       case sf_exponent:
  2380. +           if (ch_is_numeral(*ch_ptr)) {
  2381. +               buffer_str.push_back(*ch_ptr);
  2382. +               ch_ptr++;
  2383. +
  2384. +           } else {
  2385. +               if (Dc_debug_on) {
  2386. +                   dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_exponent\n", *ch_ptr);
  2387. +               }
  2388. +               state = sf_invalid;
  2389. +
  2390. +           }
  2391. +           break;
  2392. +       case sf_invalid:
  2393. +       default:
  2394. +           SCP_string token = dc_get_token_no_advance();
  2395. +           dc_printf("Syntax Error: Expected integer, found '%s'\n", token);
  2396. +           throw errParse(token.c_str(), type);
  2397. +       }
  2398. +   } while (state != sf_end);
  2399. +
  2400. +   ret = strtod(buffer_str.c_str(), &end_ptr);
  2401. +
  2402. +   return ret;
  2403. +}
  2404. +
  2405. +/**
  2406. + * @brief Parses a long integral type. Supports decimal, binary, octal, and hexidecimal strings.
  2407. + *
  2408. + * @param[in] ch    Points to the start of the string to parse.
  2409. + * @param[in] type  The expected type. Is thrown along with ch when an unexpected/malformed integral is found
  2410. + *
  2411. + * @details
  2412. + * ! Non-decimal values must be prefixed by their corresponding sequence. Binary: "0b", Octal: "0o", Hex: "0x"
  2413. + *
  2414. + *   The returned long may be cast to a smaller integral, but be sure to check it before doing so!
  2415. + *
  2416. + *   The only thing left making this function specific to the DC is the expected type. So, if you want to use this
  2417. + *   for parsing something other than the debug CL, you'll have to make a set of errParse classes that take a
  2418. + *   different expected type.
  2419. + */
  2420. +long dc_parse_long(char *ch, dc_token type) {
  2421. +   char *ch_ptr = ch;
  2422. +   char *end_ptr;
  2423. +   int base = 10;
  2424. +   long ret;
  2425. +   state_int state = si_start;
  2426. +   SCP_string buffer_str;
  2427. +
  2428. +   while ((*ch_ptr != '\0') || is_white_space(*ch_ptr)) {
  2429. +       ch_ptr++;
  2430. +   }
  2431. +
  2432. +   if (*ch_ptr == '\0') {
  2433. +       if (Dc_debug_on) {
  2434. +           dc_printf("<debug> [parse_long] no argument found\n");
  2435. +       }
  2436. +       throw errParse("", type);
  2437. +   }
  2438. +
  2439. +   do {
  2440. +       if ((ch_ptr == '\0') || is_white_space(*ch_ptr)) {
  2441. +           state = si_end;
  2442. +       }
  2443. +
  2444. +       switch (state) {
  2445. +       case si_start:
  2446. +           if (ch_is_sign(*ch_ptr)) {
  2447. +               state = si_sign;
  2448. +               if (*ch_ptr == '-') {
  2449. +                   buffer_str.push_back(*ch_ptr);
  2450. +               } // Else, it's positive. Positive sign isn't needed for conversion
  2451. +               ch_ptr++;
  2452. +
  2453. +           } else if (ch_is_prefix(*ch_ptr)) {
  2454. +               // prefixes must be checked before numeral, because they all start with a numeral zero
  2455. +               state = si_prefix;
  2456. +               ch_ptr++;
  2457. +      
  2458. +           } else if (ch_is_numeral(*ch_ptr)) {
  2459. +               state = si_numeral;
  2460. +               buffer_str.push_back(*ch_ptr);
  2461. +               ch_ptr++;
  2462. +      
  2463. +           } else {
  2464. +               if (Dc_debug_on) {
  2465. +                   dc_printf("<debug> [parse_long] Invalid character '%c' found in si_start\n", *ch_ptr);
  2466. +               }
  2467. +               state = si_invalid;
  2468. +
  2469. +           }
  2470. +           break;
  2471. +       case si_end:
  2472. +           if ((buffer_str == "") || (buffer_str == "-"))
  2473. +           {
  2474. +               state = si_invalid;
  2475. +           } // Else, we can convert the token.
  2476. +           // Do nothing, and allow the while loop exit condition to trigger
  2477. +           break;
  2478. +
  2479. +       case si_sign:
  2480. +           state = process_state_sign(ch_ptr, buffer_str);
  2481. +           break;
  2482. +
  2483. +       case si_prefix:
  2484. +           state = process_state_prefix(ch_ptr, buffer_str, base);
  2485. +           break;
  2486. +
  2487. +       case si_numeral_bin:
  2488. +           state = process_state_numeral_bin(ch_ptr, buffer_str);
  2489. +           break;
  2490. +
  2491. +       case si_numeral_octal:
  2492. +           state = process_state_numeral_octal(ch_ptr, buffer_str);
  2493. +           break;
  2494. +
  2495. +       case si_numeral_hex:
  2496. +           state = process_state_numeral_hex(ch_ptr, buffer_str);
  2497. +           break;
  2498. +
  2499. +       case si_numeral:
  2500. +           state = process_state_numeral(ch_ptr, buffer_str);
  2501. +           break;
  2502. +
  2503. +       case si_invalid:
  2504. +       default:
  2505. +           SCP_string token = dc_get_token_no_advance();
  2506. +           dc_printf("Syntax Error: Expected integer, found '%s'\n", token);
  2507. +           throw errParse(token.c_str(), type);
  2508. +       }
  2509. +   } while (state != si_end);
  2510. +
  2511. +   ret = strtol(buffer_str.c_str(), &end_ptr, base);
  2512. +
  2513. +   // This last check can be omitted once I can verify the operation of strtol in this sense
  2514. +   if (end_ptr != ch_ptr) {
  2515. +       dc_printf("Error: Could not convert all of the buffer '%s'.\n", buffer_str.c_str());
  2516. +       if (Dc_debug_on) {
  2517. +           dc_printf("<debug> Buffer value: %s\n", buffer_str.c_str());
  2518. +           dc_printf("<debug> Return value: %i", ret);
  2519. +       }
  2520. +       throw errParse(ch, type);
  2521. +   }
  2522. +
  2523. +   return ret;
  2524. +}
  2525. +
  2526. +/**
  2527. + * @brief Parses an unsigned long integral type. Supports decimal, binary, octal, and hexidecimal strings.
  2528. + *
  2529. + * @param[in] ch    Points to the start of the string to parse.
  2530. + * @param[in] type  The expected type. Is thrown along with ch when an unexpected/malformed integral is found
  2531. + *
  2532. + * @details
  2533. + * ! Non-decimal values must be delimited by their corresponding sequence. Binary: "0b", Octal: "0o", Hex: "0x"
  2534. + *   The returned long may be cast to a smaller integral, but be sure to check it before doing so!
  2535. + *   The only thing left making this function specific to the DC is the expected type. So, if you want to use this
  2536. + *   for parsing something other than the debug CL, you'll have to make a set of errParse classes that take a
  2537. + *   different expected type.
  2538. + */
  2539. +ulong dc_parse_ulong(char *ch, dc_token type) {
  2540. +   char *ch_ptr = ch;
  2541. +   char *end_ptr;
  2542. +   int base = 10;
  2543. +   ulong ret;
  2544. +   state_int state = si_start;
  2545. +   SCP_string buffer_str;
  2546. +
  2547. +   while ((*ch_ptr != '\0') || is_white_space(*ch_ptr)) {
  2548. +       ch_ptr++;
  2549. +   }
  2550. +
  2551. +   if (*ch_ptr == '\0') {
  2552. +       if (Dc_debug_on) {
  2553. +           dc_printf("<debug> [parse_long] no argument found\n");
  2554. +       }
  2555. +       throw errParse("", type);
  2556. +   }
  2557. +
  2558. +   do {
  2559. +       if ((ch_ptr == '\0') || is_white_space(*ch_ptr)) {
  2560. +           state = si_end;
  2561. +       }
  2562. +
  2563. +
  2564. +       switch (state) {
  2565. +       case si_start:
  2566. +           if (ch_is_prefix(*ch_ptr)) {
  2567. +               // prefixes must be checked before numeral, because they all start with a numeral zero
  2568. +               state = si_prefix;
  2569. +               ch_ptr++;
  2570. +      
  2571. +           } else if (ch_is_numeral(*ch_ptr)) {
  2572. +               state = si_numeral;
  2573. +               buffer_str.push_back(*ch_ptr);
  2574. +               ch_ptr++;
  2575. +      
  2576. +           } else {
  2577. +               if (Dc_debug_on) {
  2578. +                   dc_printf("<debug> [parse_long] Invalid character '%s' found in si_start\n", *ch_ptr);
  2579. +               }
  2580. +               state = si_invalid;
  2581. +
  2582. +           }
  2583. +           break;
  2584. +       case si_end:
  2585. +           if (buffer_str == "")
  2586. +           {
  2587. +               state = si_invalid;
  2588. +           } // Else, we can convert the token.
  2589. +           // Do nothing, and allow the while loop exit condition to trigger
  2590. +           break;
  2591. +
  2592. +       case si_sign:
  2593. +           state = process_state_sign(ch_ptr, buffer_str);
  2594. +           break;
  2595. +
  2596. +       case si_prefix:
  2597. +           state = process_state_prefix(ch_ptr, buffer_str, base);
  2598. +           break;
  2599. +
  2600. +       case si_numeral_bin:
  2601. +           state = process_state_numeral_bin(ch_ptr, buffer_str);
  2602. +           break;
  2603. +
  2604. +       case si_numeral_octal:
  2605. +           state = process_state_numeral_octal(ch_ptr, buffer_str);
  2606. +           break;
  2607. +
  2608. +       case si_numeral_hex:
  2609. +           state = process_state_numeral_hex(ch_ptr, buffer_str);
  2610. +           break;
  2611. +
  2612. +       case si_numeral:
  2613. +           state = process_state_numeral(ch_ptr, buffer_str);
  2614. +           break;
  2615. +
  2616. +       case si_invalid:
  2617. +       default:
  2618. +           SCP_string token = dc_get_token();
  2619. +           dc_printf("Syntax Error: Expected unsigned integer, found '%s'\n", token);
  2620. +           throw errParse(token.c_str(), type);
  2621. +       }
  2622. +   } while (state != si_end);
  2623. +
  2624. +   ret = strtoul(buffer_str.c_str(), &end_ptr, base);
  2625. +
  2626. +   // This last check can be omitted once I can verify the operation of strtol in this sense
  2627. +   if (end_ptr != ch_ptr) {
  2628. +       dc_printf("Error: Could not convert all of the buffer '%s'.\n", buffer_str.c_str());
  2629. +       if (Dc_debug_on) {
  2630. +           dc_printf("<debug> Buffer value: %s\n", buffer_str.c_str());
  2631. +           dc_printf("<debug> Return value: %i", ret);
  2632. +       }
  2633. +       throw errParse(ch, type);
  2634. +   }
  2635. +
  2636. +   return ret;
  2637. +}
  2638. +
  2639. +// Stuffs
  2640. +
  2641. +/**
  2642. + * @brief Stuffs a float to the given variable.
  2643. + *
  2644. + * @param[in] f  The float variable to stuff to
  2645. + *
  2646. + * @details Throws an errParse class if an unexpected or otherwise malformed float string is found. Also throws an
  2647. + *   errParse class if nothing was found
  2648. + */
  2649. +void dc_stuff_float(float *f)
  2650. +{
  2651. +   double value_d;
  2652. +
  2653. +   dc_ignore_gray_space();
  2654. +
  2655. +   value_d = dc_parse_double(Cp, DCT_FLOAT);
  2656. +
  2657. +   if ((value_d < FLT_MAX) && (value_d > FLT_MIN)) {
  2658. +       *f = value_d;
  2659. +       dc_get_token();    // Advance Cp
  2660. +
  2661. +   } else {
  2662. +       throw errParse(dc_get_token(), DCT_FLOAT);
  2663. +   }
  2664. +}
  2665. +
  2666. +void dc_stuff_int(int *i)
  2667. +{
  2668. +   long value_l;
  2669. +
  2670. +   dc_ignore_gray_space();
  2671. +
  2672. +   value_l = dc_parse_long(Cp, DCT_INT);
  2673. +
  2674. +   if ((value_l < INT_MAX) && (value_l > INT_MIN)) {
  2675. +       *i = value_l;
  2676. +       dc_get_token();    // Advance Cp
  2677. +
  2678. +   } else {
  2679. +       throw errParse(dc_get_token(), DCT_INT);
  2680. +   }
  2681. +}
  2682. +
  2683. +void dc_stuff_uint(uint *i)
  2684. +{
  2685. +   ulong value_l;
  2686. +
  2687. +   dc_ignore_gray_space();
  2688. +
  2689. +   value_l = dc_parse_long(Cp, DCT_INT);
  2690. +
  2691. +   if (value_l < UINT_MAX) {
  2692. +       *i = value_l;
  2693. +       dc_get_token();    // Advance Cp
  2694. +
  2695. +   } else {
  2696. +       throw errParse(dc_get_token(), DCT_INT);
  2697. +   }
  2698. +}
  2699. +
  2700. +void dc_stuff_ubyte(ubyte *i)
  2701. +{
  2702. +   ulong value_ul;
  2703. +
  2704. +   dc_ignore_gray_space();
  2705. +
  2706. +   value_ul = dc_parse_ulong(Cp, DCT_UBYTE);
  2707. +
  2708. +   // Since some system's chars may be greater than 1 byte, we can't use UCHAR_MAX for a UBYTE
  2709. +   if ((value_ul <= 255) && (value_ul >= 0)) {
  2710. +       *i = value_ul;
  2711. +       dc_get_token();    // Advance Cp
  2712. +
  2713. +   } else {
  2714. +       throw errParse(dc_get_token(), DCT_UBYTE);
  2715. +   }
  2716. +}
  2717. +
  2718. +void dc_stuff_boolean(bool *b)
  2719. +{
  2720. +   SCP_string token;
  2721. +
  2722. +   token = dc_get_token();
  2723. +
  2724. +   if ((token == "yes")
  2725. +       || (token == "true")
  2726. +       || (token == "ja")          // German
  2727. +       || (token == "Oui")         // French
  2728. +       || (token == "si")          // Spanish
  2729. +//     || (token == "ita vero")    // Latin, not supported
  2730. +       || (token == "HIja") || (token == "HISLaH"))    // Klingon
  2731. +   {
  2732. +       *b = true;
  2733. +
  2734. +   } else if ((token == "no")
  2735. +       || (token == "false")
  2736. +       || (token == "nein")    // German
  2737. +       || (token == "Non")     // French
  2738. +//     || (token == "no")      // Spanish, redundant with English "no"
  2739. +//     || (token == "minime")  // Latin, not supported
  2740. +       || (token == "ghobe'"))  // Klingon
  2741. +   {
  2742. +       *b = false;
  2743. +
  2744. +   } else {
  2745. +       throw errParse(token.c_str(), DCT_BOOL);
  2746. +   }
  2747. +}
  2748. +
  2749. +// Stupid hack to get around plain C's lack of a bool type
  2750. +void dc_stuff_boolean(int *i)
  2751. +{
  2752. +   bool value_b;
  2753. +
  2754. +   dc_stuff_boolean(&value_b);
  2755. +
  2756. +   value_b ? *i = 1 : *i = 0;
  2757. +}
  2758. +
  2759. +/**
  2760. + * @brief Stuffs a string to out_str from the Command_string, stopping at the end of the Command_string
  2761. + *
  2762. + * @param[out] out_str  Destination string
  2763. + * @param[in]  maxlen   Maximum length to copy, is less than or equal to sizeof(out_str)
  2764. + *
  2765. + * @details Throws an errParseOverflow when parser cannot stuff the entirety of the found string into out_str
  2766. + */
  2767. +void dc_stuff_string(char *out_str, size_t maxlen)
  2768. +{
  2769. +   size_t count = 0;
  2770. +   char *c_ptr = Cp;
  2771. +
  2772. +   Assert(Cp);
  2773. +   Assert(out_str);
  2774. +
  2775. +   // Advance past grayspace, stopping at null terminator
  2776. +   while (is_gray_space(*c_ptr) && (*c_ptr != '\0')) {
  2777. +       c_ptr++;
  2778. +   }
  2779. +
  2780. +   // Bail if we're at the terminator
  2781. +   if (*c_ptr == '\0') {
  2782. +       throw errParse("Nothing!", DCT_STRING);
  2783. +       return;
  2784. +   }
  2785. +
  2786. +   // Scan the string, stopping at null terminator, or before we overflow
  2787. +   while ((*c_ptr != '\0') && (count < maxlen)) {
  2788. +       count++;
  2789. +   }
  2790. +
  2791. +   // Bail if overflow
  2792. +   if (count == maxlen) {
  2793. +       throw errParse("", DCT_STRING);
  2794. +       return;
  2795. +   }
  2796. +
  2797. +   // Copy string into out_str
  2798. +   strncpy(out_str, Cp, (c_ptr - Cp));
  2799. +  
  2800. +   // Advance the parser pointer past what we copied
  2801. +   Cp = c_ptr;
  2802. +}
  2803. +
  2804. +/**
  2805. + * @brief Stuffs a string to out_str from the Command_string, stopping at the end of the Command_string
  2806. + *
  2807. + * @param[out] out_str  Destination string
  2808. + *
  2809. + * @details
  2810. + */
  2811. +void dc_stuff_string(SCP_string &out_str)
  2812. +{
  2813. +   size_t count = 0;
  2814. +   char *c_ptr = Cp;
  2815. +
  2816. +   Assert(Cp);
  2817. +
  2818. +   // Advance past grayspace, stopping at null terminator
  2819. +   while (is_gray_space(*c_ptr) && (*c_ptr != '\0')) {
  2820. +       c_ptr++;
  2821. +   }
  2822. +
  2823. +   // Bail if we're at the terminator
  2824. +   if (*c_ptr == '\0') {
  2825. +       throw errParse("Nothing!", DCT_STRING);
  2826. +       return;
  2827. +   }
  2828. +
  2829. +   // Scan the string, stopping at null terminator, or before we overflow
  2830. +   while ((*c_ptr != '\0') && (count < out_str.max_size())) {
  2831. +       count++;
  2832. +   }
  2833. +
  2834. +   // Bail if overflow
  2835. +   if (count == out_str.max_size()) {
  2836. +       throw errParse("", DCT_STRING);
  2837. +       return;
  2838. +   }
  2839. +
  2840. +   // Copy string into out_str
  2841. +   out_str.copy(Cp, (c_ptr - Cp));
  2842. +  
  2843. +   // Advance the parser pointer past what we copied
  2844. +   Cp = c_ptr;
  2845. +}
  2846. +
  2847. +/**
  2848. + * @brief Stuffs a string to str from the Command_string, stopping at the first whitespace character
  2849. + * @details Actually stops at the first grayspace character, since there will never be an EOF character in the
  2850. + *     Command_line string.
  2851. + * TODO: Double Quote support
  2852. + */
  2853. +void dc_stuff_string_white(char *out_str, size_t maxlen)
  2854. +{
  2855. +   size_t count = 0;
  2856. +   char *c_ptr = Cp;
  2857. +
  2858. +   Assert(Cp);
  2859. +   Assert(out_str);
  2860. +
  2861. +   // Advance past grayspace, stopping at null terminator
  2862. +   while (is_gray_space(*c_ptr) && (*c_ptr != '\0')) {
  2863. +       c_ptr++;
  2864. +   }
  2865. +
  2866. +   // Bail if we're at the terminator
  2867. +   if (*c_ptr == '\0') {
  2868. +       throw errParse("Nothing!", DCT_STRING);
  2869. +       return;
  2870. +   }
  2871. +
  2872. +   // Scan the string, stopping at grayspace, null terminator, or before we overflow
  2873. +   while (!is_gray_space(*c_ptr) && (*c_ptr != '\0') && (count < maxlen)) {
  2874. +       count++;
  2875. +   }
  2876. +
  2877. +   // Bail if overflow
  2878. +   if (count == maxlen) {
  2879. +       throw errParse("", DCT_STRING);
  2880. +       return;
  2881. +   }
  2882. +
  2883. +   // Copy string into out_str
  2884. +   strncpy(out_str, Cp, (c_ptr - Cp));
  2885. +  
  2886. +   // Advance the parser pointer past what we copied
  2887. +   Cp = c_ptr;
  2888. +}
  2889. +
  2890. +void dc_stuff_string_white(SCP_string &out_str)
  2891. +{
  2892. +   size_t count = 0;
  2893. +   char *c_ptr = Cp;
  2894. +
  2895. +   Assert(Cp);
  2896. +
  2897. +   // Advance past grayspace, stopping at null terminator
  2898. +   while (is_gray_space(*c_ptr) && (*c_ptr != '\0')) {
  2899. +       c_ptr++;
  2900. +   }
  2901. +
  2902. +   // Bail if we're at the terminator
  2903. +   if (*c_ptr == '\0') {
  2904. +       throw errParse("Nothing!", DCT_STRING);
  2905. +       return;
  2906. +   }
  2907. +
  2908. +   // Scan the string, stopping at grayspace, null terminator, or before we overflow
  2909. +   while (!is_gray_space(*c_ptr) && (*c_ptr != '\0') && (count < out_str.max_size())) {
  2910. +       count++;
  2911. +   }
  2912. +
  2913. +   // Bail if overflow
  2914. +   if (count == out_str.max_size()) {
  2915. +       throw errParse("", DCT_STRING);
  2916. +       return;
  2917. +   }
  2918. +
  2919. +   // Copy string into out_str
  2920. +   out_str.copy(Cp, (c_ptr - Cp));
  2921. +  
  2922. +   // Advance the parser pointer past what we copied
  2923. +   Cp = c_ptr;
  2924. +}
  2925. +
  2926. +// Maybe stuffs
  2927. +
  2928. +/**
  2929. + * @brief Tries to stuff a float from the Command_string.
  2930. + *
  2931. + * @param[in] f  The float variable to maybe stuff.
  2932. + *
  2933. + * @details
  2934. + *   If there's nothing on the command line, *f = 0 and false is returned
  2935. + *
  2936. + *   If there's something on the command line, and we're able to convert it, *f = the converted value, true is
  2937. + *     returned, and the parser is advanced past the token
  2938. + *
  2939. + *   If there's something on command line, but we can't convert it, an errParse is thrown
  2940. + */
  2941. +bool dc_maybe_stuff_float(float *f)
  2942. +{
  2943. +   dc_ignore_gray_space();
  2944. +
  2945. +   if (Cp != '\0') {
  2946. +       dc_stuff_float(f);
  2947. +       return true;
  2948. +  
  2949. +   } else {
  2950. +       *f = 0;
  2951. +       return false;
  2952. +   }
  2953. +}
  2954. +
  2955. +/**
  2956. + * @brief Tries to stuff an int from the Command_string.
  2957. + *
  2958. + * @param[in] i  The int variable to maybe stuff.
  2959. + *
  2960. + * @details
  2961. + *   If there's nothing on the command line, *i = 0 and false is returned
  2962. + *
  2963. + *   If there's something on the command line, and we're able to convert it, *i = the converted value, true is
  2964. + *     returned, and the parser is advanced past the token
  2965. + *
  2966. + *   If there's something on command line, but we can't convert it, an errParse is thrown
  2967. + */
  2968. +bool dc_maybe_stuff_int(int *i)
  2969. +{
  2970. +   dc_ignore_gray_space();
  2971. +
  2972. +   if (Cp != '\0') {
  2973. +       dc_stuff_int(i);
  2974. +       return true;
  2975. +   } else {
  2976. +       *i = 0;
  2977. +       return false;
  2978. +   }
  2979. +}
  2980. +
  2981. +/**
  2982. + * @brief Tries to stuff an uint from the Command_string.
  2983. + *
  2984. + * @param[in] i  The uint variable to maybe stuff.
  2985. + *
  2986. + * @details
  2987. + *   If there's nothing on the command line, *i = 0 and false is returned
  2988. + *
  2989. + *   If there's something on the command line, and we're able to convert it, *i = the converted value, true is
  2990. + *     returned, and the parser is advanced past the token
  2991. + *
  2992. + *   If there's something on command line, but we can't convert it, an errParse is thrown
  2993. + */
  2994. +bool dc_maybe_stuff_uint(uint *i)
  2995. +{
  2996. +   dc_ignore_gray_space();
  2997. +
  2998. +   if (Cp != '\0') {
  2999. +       dc_stuff_uint(i);
  3000. +       return true;
  3001. +   } else {
  3002. +       *i = 0;
  3003. +       return false;
  3004. +   }
  3005. +}
  3006. +
  3007. +/**
  3008. + * @brief Tries to stuff an ubyte from the Command_string.
  3009. + *
  3010. + * @param[in] i  The ubyte variable to maybe stuff.
  3011. + *
  3012. + * @details
  3013. + *   If there's nothing on the command line, *i = 0 and false is returned
  3014. + *
  3015. + *   If there's something on the command line, and we're able to convert it, *i = the converted value, true is
  3016. + *     returned, and the parser is advanced past the token
  3017. + *
  3018. + *   If there's something on command line, but we can't convert it, an errParse is thrown
  3019. + */
  3020. +bool dc_maybe_stuff_ubyte(ubyte *i)
  3021. +{
  3022. +   dc_ignore_gray_space();
  3023. +
  3024. +   if (Cp != '\0') {
  3025. +       dc_stuff_ubyte(i);
  3026. +       return true;
  3027. +   } else {
  3028. +       *i = 0;
  3029. +       return false;
  3030. +   }
  3031. +}
  3032. +
  3033. +/**
  3034. + * @brief Tries to stuff a bool from the Command_string.
  3035. + *
  3036. + * @param[in] b  The bool variable to maybe stuff.
  3037. + *
  3038. + * @details
  3039. + *   If there's nothing on the command line, *b = false and false is returned
  3040. + *
  3041. + *   If there's something on the command line, and we're able to convert it, *b = the converted value, true is
  3042. + *     returned, and the parser is advanced past the token
  3043. + *
  3044. + *   If there's something on command line, but we can't convert it, an errParse is thrown
  3045. + */
  3046. +bool dc_maybe_stuff_boolean(bool *b)
  3047. +{
  3048. +   dc_ignore_gray_space();
  3049. +
  3050. +   if (Cp != '\0') {
  3051. +       dc_stuff_boolean(b);
  3052. +       return true;
  3053. +   } else {
  3054. +       *b = false;
  3055. +       return false;
  3056. +   }
  3057. +}
  3058. +
  3059. +/**
  3060. + * @brief Tries to stuff an int with a bool value from the Command_string.
  3061. + *
  3062. + * @param[in] i  The int variable to maybe stuff.
  3063. + *
  3064. + * @details
  3065. + *   If there's nothing on the command line, *i = 0 and false is returned
  3066. + *
  3067. + *   If there's something on the command line, and we're able to convert it, *i = the converted value, true is
  3068. + *     returned, and the parser is advanced past the token
  3069. + *
  3070. + *   If there's something on command line, but we can't convert it, an errParse is thrown
  3071. + */
  3072. +bool dc_maybe_stuff_boolean(int *i)
  3073. +{
  3074. +   dc_ignore_gray_space();
  3075. +
  3076. +   if (Cp != '\0') {
  3077. +       dc_stuff_boolean(i);
  3078. +       return true;
  3079. +   } else {
  3080. +       *i = 0;
  3081. +       return false;
  3082. +   }
  3083. +}
  3084. +
  3085. +/**
  3086. + * @brief Tries to stuff a whitespace delimited string from the Command_string.
  3087. + *
  3088. + * @param[in] str  The string to maybe stuff.
  3089. + *
  3090. + * @details
  3091. + *   If there's nothing on the command line, *str = "" and false is returned
  3092. + *
  3093. + *   If there's something on the command line, *str = the token, true is
  3094. + *     returned, and the parser is advanced past the token
  3095. + *
  3096. + *   If there's a token on the command line, but we can't fit it inside of str (token.size() >= len), then errParse is
  3097. + *     thrown
  3098. + */
  3099. +bool dc_maybe_stuff_string_white(char *str, size_t len)
  3100. +{
  3101. +   dc_ignore_gray_space();
  3102. +
  3103. +   if (Cp != '\0') {
  3104. +       dc_stuff_string_white(str, len);
  3105. +       return true;
  3106. +   } else {
  3107. +       *str = '\0';
  3108. +       return false;
  3109. +   }
  3110. +}
  3111. +
  3112. +/**
  3113. + * @brief Tries to stuff a whitespace delimited string from the Command_string.
  3114. + *
  3115. + * @param[in] str  The string to maybe stuff.
  3116. + *
  3117. + * @details
  3118. + *   If there's nothing on the command line, str = "" and false is returned
  3119. + *
  3120. + *   If there's something on the command line, str = the token, true is
  3121. + *     returned, and the parser is advanced past the token
  3122. + *
  3123. + *   If there's a token on the command line, but we can't fit it inside of str (token.size() >= str.max_size()), then
  3124. + *     errParse is thrown. Very unlikely to happen.
  3125. + */
  3126. +bool dc_maybe_stuff_string_white(SCP_string &str)
  3127. +{
  3128. +   dc_ignore_gray_space();
  3129. +
  3130. +   if (Cp != '\0') {
  3131. +       dc_stuff_string_white(str);
  3132. +       return true;
  3133. +   } else {
  3134. +       str = "";
  3135. +       return false;
  3136. +   }
  3137. +}
  3138. +
  3139. +// State machine processes
  3140. +inline
  3141. +state_int process_state_prefix(char *ch_ptr, SCP_string &buffer_str, int &base) {
  3142. +   state_int state = si_invalid;
  3143. +
  3144. +   if (ch_is_binary_prefix(*ch_ptr)) {
  3145. +       state = si_numeral_bin;
  3146. +       base = 2;
  3147. +       ch_ptr++;
  3148. +  
  3149. +   } else if (ch_is_octal_prefix(*ch_ptr)) {
  3150. +       state = si_numeral_octal;
  3151. +       base = 8;
  3152. +       ch_ptr++;
  3153. +  
  3154. +   } else if (ch_is_hex_prefix(*ch_ptr)) {
  3155. +       state = si_numeral_hex;
  3156. +       base = 16;
  3157. +       ch_ptr++;
  3158. +
  3159. +   } else if (ch_is_numeral(*ch_ptr)) {
  3160. +       // User passed something like 0123
  3161. +       // Just ignore the first 0, if the user passed something like 00001 then state si_numeral can handle it
  3162. +       state = si_numeral;
  3163. +       ch_ptr++;
  3164. +  
  3165. +   } else if ((*ch_ptr == '\0') || is_white_space(*ch_ptr)) {
  3166. +       // Just a 0 was passed.
  3167. +       buffer_str.push_back('0');
  3168. +       state = si_end;
  3169. +
  3170. +   } else {
  3171. +       if (Dc_debug_on) {
  3172. +           dc_printf("<debug> [parse_long] Invalid character '%c' found in si_prefix\n", *ch_ptr);
  3173. +       }
  3174. +       state = si_invalid;
  3175. +
  3176. +   }
  3177. +   return state;
  3178. +}
  3179. +
  3180. +inline
  3181. +state_int process_state_sign(char *ch_ptr, SCP_string &buffer_str) {
  3182. +   state_int state;
  3183. +   if (ch_is_numeral(*ch_ptr)) {
  3184. +       state = si_numeral;
  3185. +       buffer_str.push_back(*ch_ptr);
  3186. +       ch_ptr++;
  3187. +
  3188. +   } else if (ch_is_prefix(*ch_ptr)) {
  3189. +       state = si_prefix;
  3190. +       ch_ptr++;
  3191. +
  3192. +   } else if ((*ch_ptr == '\0') || is_white_space(*ch_ptr)) {
  3193. +       // Error condition, but let si_end handle it (consistant with how the numerals handle it)
  3194. +       state = si_end;
  3195. +
  3196. +   } else {
  3197. +       if (Dc_debug_on) {
  3198. +           dc_printf("<debug> [parse_long] Invalid character '%c' found in si_sign\n", *ch_ptr);
  3199. +       }
  3200. +       state = si_invalid;
  3201. +
  3202. +   }
  3203. +   return state;
  3204. +}
  3205. +
  3206. +inline
  3207. +state_int process_state_numeral(char* ch_ptr, SCP_string &buffer_str) {
  3208. +   state_int state = si_numeral;
  3209. +
  3210. +   if (ch_is_numeral(*ch_ptr)) {
  3211. +       buffer_str.push_back(*ch_ptr);
  3212. +       ch_ptr++;
  3213. +  
  3214. +   } else if ((*ch_ptr == '\0') || is_white_space(*ch_ptr)) {
  3215. +       state = si_end;
  3216. +  
  3217. +   } else {
  3218. +       // Invalid character, throw and bail
  3219. +       if (Dc_debug_on) {
  3220. +           dc_printf("<debug> [parse_long] Invalid character '%c' found in si_numeral\n", *ch_ptr);
  3221. +       }
  3222. +       state = si_invalid;
  3223. +
  3224. +   }
  3225. +   return state;
  3226. +}
  3227. +
  3228. +inline
  3229. +state_int process_state_numeral_bin(char* ch_ptr, SCP_string &buffer_str) {
  3230. +   state_int state = si_numeral_bin;
  3231. +
  3232. +   if (ch_is_binary(*ch_ptr)) {
  3233. +       buffer_str.push_back(*ch_ptr);
  3234. +       ch_ptr++;
  3235. +  
  3236. +   } else if ((*ch_ptr == '\0') || is_white_space(*ch_ptr)) {
  3237. +       state = si_end;
  3238. +  
  3239. +   } else {
  3240. +       if (Dc_debug_on) {
  3241. +           dc_printf("<debug> [parse_long] Invalid character '%c' found in si_numeral_bin\n", *ch_ptr);
  3242. +       }
  3243. +       state = si_invalid;
  3244. +
  3245. +   }
  3246. +   return state;
  3247. +}
  3248. +
  3249. +inline
  3250. +state_int process_state_numeral_hex(char* ch_ptr, SCP_string &buffer_str) {
  3251. +   state_int state = si_numeral_hex;
  3252. +
  3253. +   if (ch_is_hex(*ch_ptr)) {
  3254. +       buffer_str.push_back(*ch_ptr);
  3255. +       ch_ptr++;
  3256. +  
  3257. +   } else if ((*ch_ptr == '\0') || is_white_space(*ch_ptr)) {
  3258. +       state = si_end;
  3259. +  
  3260. +   } else {
  3261. +       if (Dc_debug_on) {
  3262. +           dc_printf("<debug> [parse_long] Invalid character '%c' found in si_numeral_hex\n", *ch_ptr);
  3263. +       }
  3264. +       state = si_invalid;
  3265. +   }
  3266. +   return state;
  3267. +}
  3268. +
  3269. +inline
  3270. +state_int process_state_numeral_octal(char* ch_ptr, SCP_string &buffer_str) {
  3271. +   state_int state = si_numeral_octal;
  3272. +
  3273. +   if (ch_is_octal(*ch_ptr)) {
  3274. +       buffer_str.push_back(*ch_ptr);
  3275. +       ch_ptr++;
  3276. +  
  3277. +   } else if ((*ch_ptr == '\0') || is_white_space(*ch_ptr)) {
  3278. +       state = si_end;
  3279. +  
  3280. +   } else {
  3281. +       // Invalid character, throw and bail
  3282. +       if (Dc_debug_on) {
  3283. +           dc_printf("<debug> [parse_long] Invalid character '%c' found in si_numeral_octal\n", *ch_ptr);
  3284. +       }
  3285. +       state = si_invalid;
  3286. +   }
  3287. +   return state;
  3288. +}
  3289. Index: code/debugconsole/consoleparse.h
  3290. ===================================================================
  3291. index 0000000..9358476
  3292. --- code/debugconsole/consoleparse.h    (revision 0)
  3293. +++ code/debugconsole/consoleparse.h    (working copy)
  3294. @@ -0,0 +1,163 @@
  3295. +#ifndef _CONSOLEPARSE_H
  3296. +#define _CONSOLEPARSE_H
  3297. +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3298. +// Command-line parsing functions for z64555's debug console, created for the FreeSpace Source Code project
  3299. +//
  3300. +// Portions of this source code are based on works by Volition, Inc. circa 1999. You may not sell or otherwise
  3301. +// commercially exploit the source or things you created based on the source.
  3302. +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  3303. +
  3304. +/**
  3305. + * @file consoleparse.h
  3306. + * @brief Parsing functions for the command line. Previously known as the command line scanner
  3307. + *
  3308. + * @details A lot of functions here are blatently copied from parselo.h :D
  3309. +  */
  3310. +
  3311. +#include "globalincs/pstypes.h"
  3312. +
  3313. +#define MAX_CLI_LEN 512
  3314. +#define MAX_TOKEN_LENGTH 255
  3315. +
  3316. +enum dc_token {
  3317. +   DCT_NONE = 0,
  3318. +   DCT_STRING,
  3319. +   DCT_FLOAT,
  3320. +   DCT_INT,
  3321. +   DCT_UINT,
  3322. +   DCT_BYTE,
  3323. +   DCT_UBYTE,
  3324. +   DCT_BOOL
  3325. +};
  3326. +
  3327. +/**
  3328. + * @class errParse
  3329. + *
  3330. + * @brief Class thrown when a required token is not found
  3331. + *
  3332. + *  @details This is a basic parser error, it contains the token (a single word) that was found, and the expected token
  3333. + *      type. Some DCT's, such as the DCT_STRING's, have their own specific requirements for error handling, and as
  3334. + *      such get their own class derived from errParse. The catching routines should be able to catch the derived error
  3335. + *      objects, but if not, they can be caught by a routine looking for the base class and then be casted to their
  3336. + *      proper type.
  3337. + */
  3338. +class errParse {
  3339. +public:
  3340. +   SCP_string found_token;
  3341. +   dc_token expected_type;
  3342. +
  3343. +   /**
  3344. +   *  @brief Invalid/Unexpected token constructor
  3345. +   *  @param [in] found_str The token that was found
  3346. +   *  @param [in] expected_dct The token type that was expected
  3347. +   */
  3348. +   errParse(const char *found_str, dc_token expected_dct)
  3349. +       : found_token(found_str), expected_type(expected_dct)
  3350. +   {
  3351. +   }
  3352. +};
  3353. +
  3354. +/**
  3355. + * @class errParseString
  3356. + *
  3357. + * @brief Class thrown when an expected string was not found. Supports up to 4 required strings.
  3358. + */
  3359. +class errParseString : public errParse
  3360. +{
  3361. +public:
  3362. +   SCP_string expected_token1;
  3363. +   SCP_string expected_token2;
  3364. +   SCP_string expected_token3;
  3365. +   SCP_string expected_token4;
  3366. +   /**
  3367. +    *  @brief Invalid/Unexpected token constructor.
  3368. +    *  
  3369. +    *  @param [in] found_str The string that was found
  3370. +    *  @param [in] str The token that was expected
  3371. +    */
  3372. +   errParseString(char *found_str, char *str)
  3373. +       : errParse(found_str, DCT_STRING), expected_token1(str)
  3374. +   {
  3375. +   }
  3376. +
  3377. +   /**
  3378. +    *  @brief Invalid/Unexpected token constructor.
  3379. +    *  
  3380. +    *  @param [in] found_str The string that was found
  3381. +    *  @param [in] str1 The first token that was expected
  3382. +    *  @param [in] str2 The second token that was expected
  3383. +    */
  3384. +   errParseString(char *found_str, char *str1, char *str2)
  3385. +       : errParse(found_str, DCT_STRING), expected_token1(str1), expected_token2(str2)
  3386. +   {
  3387. +   }
  3388. +
  3389. +   /**
  3390. +    *  @brief Invalid/Unexpected token constructor.
  3391. +    *  
  3392. +    *  @param [in] found_str The string that was found
  3393. +    *  @param [in] str1 The first token that was expected
  3394. +    *  @param [in] str2 The second token that was expected
  3395. +    *  @param [in] str3 The third token that was expected
  3396. +    */
  3397. +   errParseString(char *found_str, char *str1, char *str2, char *str3)
  3398. +       : errParse(found_str, DCT_STRING), expected_token1(str1), expected_token2(str2), expected_token3(str3)
  3399. +   {
  3400. +   }
  3401. +
  3402. +   /**
  3403. +    *  @brief Invalid/Unexpected token constructor.
  3404. +    *  
  3405. +    *  @param [in] found_str The string that was found
  3406. +    *  @param [in] str1 The first token that was expected
  3407. +    *  @param [in] str2 The second token that was expected
  3408. +    *  @param [in] str3 The third token that was expected
  3409. +    *  @param [in] str4 The fourth token that was expected
  3410. +    */
  3411. +   errParseString(char *found_str, char *str1, char *str2, char *str3, char *str4)
  3412. +       : errParse(found_str, DCT_STRING), expected_token1(str1), expected_token2(str2), expected_token3(str3), expected_token4(str4)
  3413. +   {
  3414. +   }
  3415. +};
  3416. +
  3417. +void dc_parse_init(SCP_string &str);
  3418. +
  3419. +void dc_ignore_white_space(void);
  3420. +void dc_ignore_gray_space(void);
  3421. +
  3422. +// Required/Optional Token
  3423. +bool dc_required_string(char *pstr);
  3424. +int dc_required_string_either(char *str1, char *str2);
  3425. +int dc_required_string_3(char *str1, char *str2, char *str3);
  3426. +int dc_required_string_4(char *str1, char *str2, char *str3, char *str4);
  3427. +
  3428. +bool dc_optional_string(char *pstr);
  3429. +bool dc_optional_string_either(char *str1, char *str2);
  3430. +
  3431. +// Stuffs
  3432. +// These provide a limited support of math evaluations.
  3433. +void dc_stuff_float(float *f);
  3434. +void dc_stuff_int(int *i);
  3435. +void dc_stuff_uint(uint *i);
  3436. +void dc_stuff_ubyte(ubyte *i);
  3437. +void dc_stuff_boolean(bool *b);
  3438. +void dc_stuff_boolean(int *i); // Stupid hack to get around plain C's lack of a bool type
  3439. +
  3440. +void dc_stuff_string(char *str);
  3441. +void dc_stuff_string(SCP_string &str);
  3442. +void dc_stuff_string_white(char *str, size_t len);
  3443. +void dc_stuff_string_white(SCP_string &str);
  3444. +
  3445. +// Maybe Stuffs.
  3446. +// These won't throw errors if there is nothing left on the command line. They'll still throw an error if an unexpected type is found
  3447. +// Each returns TRUE if a stuff was actually performed. FALSE if nothing was stuffed.
  3448. +bool dc_maybe_stuff_float(float *f);
  3449. +bool dc_maybe_stuff_int(int *i);
  3450. +bool dc_maybe_stuff_uint(uint *i);
  3451. +bool dc_maybe_stuff_ubyte(ubyte *i);
  3452. +bool dc_maybe_stuff_boolean(bool *b);
  3453. +bool dc_maybe_stuff_boolean(int *i);
  3454. +bool dc_maybe_stuff_string_white(char *str, size_t len);
  3455. +bool dc_maybe_stuff_string_white(SCP_string &str);
  3456. +
  3457. +#endif // _CONSOLEPARSE_H
  3458. \ No newline at end of file
  3459. Index: code/freespace2/freespace.cpp
  3460. ===================================================================
  3461. --- code/freespace2/freespace.cpp   (revision 10462)
  3462. +++ code/freespace2/freespace.cpp   (working copy)
  3463. @@ -33,6 +33,7 @@
  3464.  #include "cutscene/cutscenes.h"
  3465.  #include "cutscene/movie.h"
  3466.  #include "debris/debris.h"
  3467. +#include "debugconsole/console.h"
  3468.  #include "exceptionhandler/exceptionhandler.h"
  3469.  #include "external_dll/trackirpublic.h" // header file for the TrackIR routines (Swifty)
  3470.  #include "fireball/fireballs.h"
  3471. @@ -665,10 +666,9 @@ void big_explosion_flash(float flash)
  3472.  int Sun_drew = 0;
  3473.  
  3474.  float sn_glare_scale = 1.7f;
  3475. -DCF(sn_glare, "")
  3476. +DCF(sn_glare, "Sets the sun glare scale (Default is 1.7)")
  3477.  {
  3478. -   dc_get_arg(ARG_FLOAT);
  3479. -   sn_glare_scale = Dc_arg_float;
  3480. +   dc_stuff_float(&sn_glare_scale);
  3481.  }
  3482.  
  3483.  float Supernova_last_glare = 0.0f;
  3484. @@ -1499,80 +1499,101 @@ DCF_BOOL(i_framerate, Interface_framerate )
  3485.  
  3486.  DCF(warp, "Tests warpin effect")
  3487.  {
  3488. -   if ( Dc_command )   {
  3489. -       bool warpin = true;
  3490. -       int idx = -1;
  3491. +   if (dc_optional_string_either("help", "--help")) {
  3492. +       dc_printf( "Params: bool warpin, string Target = ""\n  Warps in if true, out if false. Player is target unless specific ship is specified\n" );
  3493. +       return;
  3494. +   } // Else, process command
  3495.  
  3496. -       dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);
  3497. -       if( Dc_arg_type & ARG_TRUE) warpin = true;
  3498. -       else if(Dc_arg_type & ARG_FALSE) warpin = false;
  3499. +   // TODO: Provide status flag
  3500.  
  3501. -       if(!(Dc_arg_type & ARG_NONE))
  3502. -       {
  3503. -           dc_get_arg(ARG_STRING|ARG_NONE);
  3504. -           if(Dc_arg_type & ARG_STRING)
  3505. -           {
  3506. -               idx = ship_name_lookup(Dc_arg);
  3507. -               if(idx > -1)
  3508. -               {
  3509. -                   if(warpin)
  3510. -                       shipfx_warpin_start(&Objects[Ships[idx].objnum]);
  3511. -                   else
  3512. -                       shipfx_warpout_start(&Objects[Ships[idx].objnum]);
  3513. -               }
  3514. +   bool warpin;
  3515. +   char target[MAX_NAME_LEN];
  3516. +   int idx = -1;
  3517. +
  3518. +   dc_stuff_boolean(&warpin);
  3519. +   if (dc_maybe_stuff_string_white(target, MAX_NAME_LEN)) {
  3520. +       idx = ship_name_lookup(target);
  3521. +   }   // Else, default target to player
  3522. +  
  3523. +   if (idx < 0) {
  3524. +       // Player is target
  3525. +       if (Player_ai->target_objnum > -1) {
  3526. +           if(warpin) {
  3527. +               shipfx_warpin_start(&Objects[Player_ai->target_objnum]);
  3528. +           } else {
  3529. +               shipfx_warpout_start(&Objects[Player_ai->target_objnum]);
  3530.             }
  3531.         }
  3532. -      
  3533. -       if(idx < 0)
  3534. -       {
  3535. -           if(Player_ai->target_objnum > -1)
  3536. -           {
  3537. -               if(warpin)
  3538. -                   shipfx_warpin_start(&Objects[Player_ai->target_objnum]);
  3539. -               else
  3540. -                   shipfx_warpout_start(&Objects[Player_ai->target_objnum]);
  3541. -           }
  3542. +   } else {
  3543. +       // Non-player is targer
  3544. +       if (warpin) {
  3545. +           shipfx_warpin_start(&Objects[Ships[idx].objnum]);
  3546. +       } else {
  3547. +           shipfx_warpout_start(&Objects[Ships[idx].objnum]);
  3548.         }
  3549. -   }  
  3550. -   if ( Dc_help )  dc_printf( "Usage: Show_mem\nWarps in if true, out if false, player target unless specific ship is specified\n" )
  3551. +   }
  3552. +  
  3553.  }
  3554.  
  3555.  DCF(show_mem,"Toggles showing mem usage")
  3556.  {
  3557. -   if ( Dc_command )   {  
  3558. -       dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);       
  3559. -       if ( Dc_arg_type & ARG_TRUE )   Show_mem = 1;  
  3560. -       else if ( Dc_arg_type & ARG_FALSE ) Show_mem = 0;  
  3561. -       else if ( Dc_arg_type & ARG_NONE ) Show_mem ^= 1;  
  3562. +   bool process = true;
  3563.  
  3564. -       if ( Show_mem ) {
  3565. -           Show_cpu = 0;
  3566. -       }
  3567. -   }  
  3568. -   if ( Dc_help )  dc_printf( "Usage: Show_mem\nSets show_mem to true or false.  If nothing passed, then toggles it.\n" );
  3569. -   if ( Dc_status )    {
  3570. -       dc_printf( "Show_mem is %s\n", (Show_mem?"TRUE":"FALSE") );
  3571. -       dc_printf( "Show_cpu is %s\n", (Show_cpu?"TRUE":"FALSE") );
  3572. +   if (dc_optional_string_either("help", "--help")) {
  3573. +       dc_printf( "Usage: (optional) bool Show_mem\n If true, Show_mem is set and Show_cpu is cleared.  If false, then Show_mem is cleared.  If nothing passed, then toggle.\n" );
  3574. +       process = false;
  3575. +   }
  3576. +  
  3577. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  3578. +       dc_printf("Show_mem is %s\n", (Show_mem ? "TRUE" : "FALSE"));
  3579. +       dc_printf("Show_cpu is %s\n", (Show_cpu ? "TRUE" : "FALSE"));
  3580. +       process = false;
  3581. +   }
  3582. +  
  3583. +   if (!process) {
  3584. +       // Help and/or status was given, so don't process the command
  3585. +       return;
  3586. +   } // Else, process the command
  3587. +
  3588. +   if (!dc_maybe_stuff_boolean(&Show_mem)) {
  3589. +       // Nothing passed, so toggle
  3590. +       Show_mem = !Show_mem;
  3591. +   }   // Else, value was set/cleared by user
  3592. +
  3593. +   // Can't show mem and cpu at same time
  3594. +   if (Show_mem) {
  3595. +       Show_cpu = false;
  3596.     }
  3597.  }
  3598.  
  3599.  DCF(show_cpu,"Toggles showing cpu usage")
  3600.  {
  3601. -   if ( Dc_command )   {  
  3602. -       dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);       
  3603. -       if ( Dc_arg_type & ARG_TRUE )   Show_cpu = 1;  
  3604. -       else if ( Dc_arg_type & ARG_FALSE ) Show_cpu = 0;  
  3605. -       else if ( Dc_arg_type & ARG_NONE ) Show_cpu ^= 1;  
  3606. +   bool process = true;
  3607.  
  3608. -       if ( Show_cpu ) {
  3609. -           Show_mem = 0;
  3610. -       }
  3611. -   }  
  3612. -   if ( Dc_help )  dc_printf( "Usage: Show_cpu\nSets show_cpu to true or false.  If nothing passed, then toggles it.\n" );
  3613. -   if ( Dc_status )    {
  3614. -       dc_printf( "Show_mem is %s\n", (Show_mem?"TRUE":"FALSE") );
  3615. -       dc_printf( "Show_cpu is %s\n", (Show_cpu?"TRUE":"FALSE") );
  3616. +   if (dc_optional_string_either("help", "--help")) {
  3617. +       dc_printf( "Usage: (optional) bool Show_cpu\n If true, Show_cpu is set and Show_mem is cleared.  If false, then Show_cpu is cleared.  If nothing passed, then toggle.\n" );
  3618. +       process = false;
  3619. +   }
  3620. +  
  3621. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  3622. +       dc_printf("Show_cpu is %s\n", (Show_cpu ? "TRUE" : "FALSE"));
  3623. +       dc_printf("Show_mem is %s\n", (Show_mem ? "TRUE" : "FALSE"));
  3624. +       process = false;
  3625. +   }
  3626.  
  3627. +   if (!process) {
  3628. +       // Help and/or status was given, so don't process the command
  3629. +       return;
  3630. +   } // Else, process the command
  3631. +
  3632. +   if (!dc_maybe_stuff_boolean(&Show_cpu)) {
  3633. +       // Nothing passed, so toggle
  3634. +       Show_cpu = !Show_cpu;
  3635. +   }   // Else, value was set/cleared by user
  3636. +
  3637. +   // Can't show mem and cpu at same time
  3638. +   if (Show_cpu) {
  3639. +       Show_mem = false;
  3640.     }
  3641.  }
  3642.  
  3643. @@ -1582,42 +1603,56 @@ DCF(show_cpu,"Toggles showing cpu usage")
  3644.  
  3645.  DCF(use_joy_mouse,"Makes joystick move mouse cursor")
  3646.  {
  3647. -   if ( Dc_command )   {  
  3648. -       dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);       
  3649. -       if ( Dc_arg_type & ARG_TRUE )   Use_joy_mouse = 1
  3650. -       else if ( Dc_arg_type & ARG_FALSE ) Use_joy_mouse = 0
  3651. -       else if ( Dc_arg_type & ARG_NONE ) Use_joy_mouse ^= 1
  3652. -   }  
  3653. -   if ( Dc_help )  dc_printf( "Usage: use_joy_mouse [bool]\nSets use_joy_mouse to true or false.  If nothing passed, then toggles it.\n" );   
  3654. -   if ( Dc_status )    dc_printf( "use_joy_mouse is %s\n", (Use_joy_mouse?"TRUE":"FALSE") );  
  3655. +   bool process = true;
  3656. +
  3657. +   if (dc_optional_string_either("help", "--help")) {
  3658. +       dc_printf("Usage: use_joy_mouse [bool]\nSets use_joy_mouse to true or false.  If nothing passed, then toggles it.\n");
  3659. +       process = false;
  3660. +   }
  3661. +
  3662. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  3663. +       dc_printf("use_joy_mouse is %s\n", (Use_joy_mouse ? "TRUE" : "FALSE"));
  3664. +       process = false;
  3665. +   }
  3666. +
  3667. +   if (!process) {
  3668. +       return;
  3669. +   }
  3670. +
  3671. +   if(!dc_maybe_stuff_boolean(&Use_joy_mouse)) {
  3672. +       // Nothing passed, so toggle
  3673. +       Use_joy_mouse = !Use_joy_mouse;
  3674. +   } // Else, value was set/cleared by user
  3675.  
  3676.     os_config_write_uint( NULL, NOX("JoystickMovesCursor"), Use_joy_mouse );
  3677.  }
  3678.  
  3679. -DCF(palette_flash,"Toggles palette flash effect on/off")
  3680. -{
  3681. -   if ( Dc_command )   {  
  3682. -       dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);       
  3683. -       if ( Dc_arg_type & ARG_TRUE )   Use_palette_flash = 1
  3684. -       else if ( Dc_arg_type & ARG_FALSE ) Use_palette_flash = 0
  3685. -       else if ( Dc_arg_type & ARG_NONE ) Use_palette_flash ^= 1
  3686. -   }  
  3687. -   if ( Dc_help )  dc_printf( "Usage: palette_flash [bool]\nSets palette_flash to true or false.  If nothing passed, then toggles it.\n" );   
  3688. -   if ( Dc_status )    dc_printf( "palette_flash is %s\n", (Use_palette_flash?"TRUE":"FALSE") );  
  3689. -}
  3690. +DCF_BOOL(palette_flash, Use_palette_flash);
  3691.  
  3692.  int Use_low_mem = 0;
  3693.  
  3694.  DCF(low_mem,"Uses low memory settings regardless of RAM")
  3695.  {
  3696. -   if ( Dc_command )   {  
  3697. -       dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);       
  3698. -       if ( Dc_arg_type & ARG_TRUE )   Use_low_mem = 1;   
  3699. -       else if ( Dc_arg_type & ARG_FALSE ) Use_low_mem = 0;   
  3700. -       else if ( Dc_arg_type & ARG_NONE ) Use_low_mem ^= 1;   
  3701. -   }  
  3702. -   if ( Dc_help )  dc_printf( "Usage: low_mem [bool]\nSets low_mem to true or false.  If nothing passed, then toggles it.\n" );   
  3703. -   if ( Dc_status )    dc_printf( "low_mem is %s\n", (Use_low_mem?"TRUE":"FALSE") );  
  3704. +   bool process = true;
  3705. +
  3706. +   if (dc_optional_string_either("help", "--help")) {
  3707. +       dc_printf("Usage: low_mem [bool]\nSets low_mem to true or false.  If nothing passed, then toggles it.\n");
  3708. +       process = false;
  3709. +   }
  3710. +
  3711. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  3712. +       dc_printf("low_mem is %s\n", (Use_low_mem ? "TRUE" : "FALSE"));
  3713. +       process = false;
  3714. +   }
  3715. +
  3716. +   if (!process) {
  3717. +       return;
  3718. +   }
  3719. +
  3720. +   if (!dc_maybe_stuff_boolean(&Use_low_mem)) {
  3721. +       // Nothing passed, so toggle
  3722. +       Use_low_mem = !Use_low_mem;
  3723. +   } // Else, value was set/cleared by user
  3724.  
  3725.     os_config_write_uint( NULL, NOX("LowMem"), Use_low_mem );
  3726.  }
  3727. @@ -1627,14 +1662,26 @@ DCF(low_mem,"Uses low memory settings regardless of RAM")
  3728.  
  3729.  DCF(force_fullscreen, "Forces game to startup in fullscreen mode")
  3730.  {
  3731. -   if ( Dc_command )   {  
  3732. -       dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);       
  3733. -       if ( Dc_arg_type & ARG_TRUE )   Use_fullscreen_at_startup = 1
  3734. -       else if ( Dc_arg_type & ARG_FALSE ) Use_fullscreen_at_startup = 0
  3735. -       else if ( Dc_arg_type & ARG_NONE ) Use_fullscreen_at_startup ^= 1
  3736. -   }  
  3737. -   if ( Dc_help )  dc_printf( "Usage: force_fullscreen [bool]\nSets force_fullscreen to true or false.  If nothing passed, then toggles it.\n" )
  3738. -   if ( Dc_status )    dc_printf( "force_fullscreen is %s\n", (Use_fullscreen_at_startup?"TRUE":"FALSE") );   
  3739. +   bool process = true;
  3740. +   if (dc_optional_string_either("help", "--help")) {
  3741. +       dc_printf("Usage: low_mem [bool]\nSets low_mem to true or false.  If nothing passed, then toggles it.\n");
  3742. +       process = false;
  3743. +   }
  3744. +
  3745. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  3746. +       dc_printf("low_mem is %s\n", (Use_fullscreen_at_startup ? "TRUE" : "FALSE"));
  3747. +       process = false;
  3748. +   }
  3749. +
  3750. +   if (!process) {
  3751. +       return;
  3752. +   }
  3753. +
  3754. +   if (dc_maybe_stuff_boolean(&Use_fullscreen_at_startup)) {
  3755. +       // Nothing passed, so toggle
  3756. +       Use_fullscreen_at_startup = !Use_fullscreen_at_startup;
  3757. +   } // Else, value was set/cleared by user
  3758. +
  3759.     os_config_write_uint( NULL, NOX("ForceFullscreen"), Use_fullscreen_at_startup );
  3760.  }
  3761.  #endif
  3762. @@ -1643,37 +1690,33 @@ int Framerate_delay = 0;
  3763.  
  3764.  float FreeSpace_gamma = 1.0f;
  3765.  
  3766. -DCF(gamma,"Sets Gamma factor")
  3767. +DCF(gamma,"Sets and saves Gamma Factor")
  3768.  {
  3769. -   if ( Dc_command )   {
  3770. -       dc_get_arg(ARG_FLOAT|ARG_NONE);
  3771. -       if ( Dc_arg_type & ARG_FLOAT )  {
  3772. -           FreeSpace_gamma = Dc_arg_float;
  3773. -       } else {
  3774. -           dc_printf( "Gamma reset to 1.0f\n" );
  3775. -           FreeSpace_gamma = 1.0f;
  3776. -       }
  3777. -       if ( FreeSpace_gamma < 0.1f )   {
  3778. -           FreeSpace_gamma = 0.1f;
  3779. -       } else if ( FreeSpace_gamma > 5.0f )    {
  3780. -           FreeSpace_gamma = 5.0f;
  3781. -       }
  3782. -       gr_set_gamma(FreeSpace_gamma);
  3783. -
  3784. -       char tmp_gamma_string[32];
  3785. -       sprintf( tmp_gamma_string, NOX("%.2f"), FreeSpace_gamma );
  3786. -       os_config_write_string( NULL, NOX("Gamma"), tmp_gamma_string );
  3787. -   }
  3788. -
  3789. -   if ( Dc_help )  {
  3790. +   if (dc_optional_string_either("help", "--help")) {
  3791.         dc_printf( "Usage: gamma <float>\n" );
  3792.         dc_printf( "Sets gamma in range 1-3, no argument resets to default 1.2\n" );
  3793. -       Dc_status = 0;  // don't print status if help is printed.  Too messy.
  3794. +       return;
  3795.     }
  3796.  
  3797. -   if ( Dc_status )    {
  3798. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  3799.         dc_printf( "Gamma = %.2f\n", FreeSpace_gamma );
  3800. +       return;
  3801. +   }
  3802. +
  3803. +   if (!dc_maybe_stuff_float(&FreeSpace_gamma)) {
  3804. +       dc_printf( "Gamma reset to 1.0f\n" );
  3805. +       FreeSpace_gamma = 1.0f;
  3806.     }
  3807. +   if ( FreeSpace_gamma < 0.1f )   {
  3808. +       FreeSpace_gamma = 0.1f;
  3809. +   } else if ( FreeSpace_gamma > 5.0f )    {
  3810. +       FreeSpace_gamma = 5.0f;
  3811. +   }
  3812. +   gr_set_gamma(FreeSpace_gamma);
  3813. +
  3814. +   char tmp_gamma_string[32];
  3815. +   sprintf( tmp_gamma_string, NOX("%.2f"), FreeSpace_gamma );
  3816. +   os_config_write_string( NULL, NOX("Gamma"), tmp_gamma_string );
  3817.  }
  3818.  
  3819.  #ifdef APPLE_APP
  3820. @@ -2399,33 +2442,54 @@ void game_show_time_left()
  3821.  
  3822.  DCF(ai_pause,"Pauses ai")
  3823.  {
  3824. -   if ( Dc_command )   {  
  3825. -       dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);       
  3826. -       if ( Dc_arg_type & ARG_TRUE )   ai_paused = 1
  3827. -       else if ( Dc_arg_type & ARG_FALSE ) ai_paused = 0
  3828. -       else if ( Dc_arg_type & ARG_NONE ) ai_paused = !ai_paused; 
  3829. +   bool process = true;
  3830. +  
  3831. +   if (dc_optional_string_either("help", "--help")) {
  3832. +       dc_printf( "Usage: ai_paused [bool]\nSets ai_paused to true or false.  If nothing passed, then toggles it.\n" );
  3833. +       process = false;
  3834. +   }
  3835.  
  3836. -       if (ai_paused)  {  
  3837. -           obj_init_all_ships_physics();
  3838. -       }
  3839. -   }  
  3840. -   if ( Dc_help )  dc_printf( "Usage: ai_paused [bool]\nSets ai_paused to true or false.  If nothing passed, then toggles it.\n" );   
  3841. -   if ( Dc_status )    dc_printf( "ai_paused is %s\n", (ai_paused?"TRUE":"FALSE") );  
  3842. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  3843. +       dc_printf( "ai_paused is %s\n", (ai_paused?"TRUE":"FALSE") );
  3844. +       process = false;
  3845. +   }
  3846. +
  3847. +   if (!process) {
  3848. +       return;
  3849. +   }
  3850. +
  3851. +   if (!dc_maybe_stuff_boolean(&ai_paused)) {
  3852. +       ai_paused = !ai_paused;
  3853. +   }
  3854. +
  3855. +   if (ai_paused) {
  3856. +       obj_init_all_ships_physics();
  3857. +   }
  3858.  }
  3859.  
  3860. -DCF(single_step,"Single steps the game")
  3861. +DCF(single_step,"Enables single step mode.")
  3862.  {
  3863. -   if ( Dc_command )   {  
  3864. -       dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);       
  3865. -       if ( Dc_arg_type & ARG_TRUE )   game_single_step = 1;  
  3866. -       else if ( Dc_arg_type & ARG_FALSE ) game_single_step = 0;  
  3867. -       else if ( Dc_arg_type & ARG_NONE ) game_single_step = !game_single_step;   
  3868. +   bool process = true;
  3869. +  
  3870. +   if (dc_optional_string_either("help", "--help")) {
  3871. +       dc_printf( "Usage: game_single_step [bool]\nEnables or disables single-step mode.  If nothing passed, then toggles it.\nSingle-step mode will freeze the game, and will advance frame by frame with each key press\n");
  3872. +       process = false;
  3873. +   }
  3874.  
  3875. -       last_single_step = 0;   // Make so single step waits a frame before stepping
  3876. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  3877. +       dc_printf( "ai_paused is %s\n", (game_single_step ? "TRUE" : "FALSE") );
  3878. +       process = false;
  3879. +   }
  3880.  
  3881. -   }  
  3882. -   if ( Dc_help )  dc_printf( "Usage: single_step [bool]\nSets single_step to true or false.  If nothing passed, then toggles it.\n" );   
  3883. -   if ( Dc_status )    dc_printf( "single_step is %s\n", (game_single_step?"TRUE":"FALSE") )
  3884. +   if (!process) {
  3885. +       return;
  3886. +   }
  3887. +
  3888. +   if (!dc_maybe_stuff_boolean(&game_single_step)) {
  3889. +       game_single_step = !game_single_step;
  3890. +   }
  3891. +
  3892. +   last_single_step = 0;   // Make so single step waits a frame before stepping
  3893.  }
  3894.  
  3895.  DCF_BOOL(physics_pause, physics_paused)
  3896. @@ -2472,22 +2536,28 @@ int View_percent = 100;
  3897.  
  3898.  DCF(view, "Sets the percent of the 3d view to render.")
  3899.  {
  3900. -   if ( Dc_command ) {
  3901. -       dc_get_arg(ARG_INT);
  3902. -       if ( (Dc_arg_int >= 5 ) || (Dc_arg_int <= 100) ) {
  3903. -           View_percent = Dc_arg_int;
  3904. -       } else {
  3905. -           dc_printf( "Illegal value for view. (Must be from 5-100) \n\n");
  3906. -           Dc_help = 1;
  3907. -       }
  3908. -   }
  3909. +   bool process = true;
  3910. +   int value;
  3911.  
  3912. -   if ( Dc_help ) {
  3913. +   if (dc_optional_string_either("help", "--help")) {
  3914.         dc_printf("Usage: view [n]\nwhere n is percent of view to show (5-100).\n");
  3915. +       process = false;
  3916.     }
  3917. -  
  3918. -   if ( Dc_status ) {
  3919. +
  3920. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  3921.         dc_printf("View is set to %d%%\n", View_percent );
  3922. +       process = false;
  3923. +   }
  3924. +
  3925. +   if (!process) {
  3926. +       return;
  3927. +   }
  3928. +
  3929. +   dc_stuff_int(&value);
  3930. +   if ( (value >= 5 ) && (value <= 100) ) {
  3931. +       View_percent = value;
  3932. +   } else {
  3933. +       dc_printf("Error: Outside legal range [5 - 100]");
  3934.     }
  3935.  }
  3936.  
  3937. @@ -2814,65 +2884,86 @@ void do_timing_test(float frame_time)
  3938.  DCF(dcf_fov, "Change the field of view of the main camera")
  3939.  {
  3940.     camera *cam = Main_camera.getCamera();
  3941. -   if ( Dc_command )
  3942. -   {
  3943. -       if(cam == NULL)
  3944. -           return;
  3945. +   bool process = true;
  3946. +   float value;
  3947.  
  3948. -       dc_get_arg(ARG_FLOAT|ARG_NONE);
  3949. -       if ( Dc_arg_type & ARG_NONE )   {
  3950. -           cam->set_fov(VIEWER_ZOOM_DEFAULT);
  3951. -           dc_printf( "Zoom factor reset\n" );
  3952. -       }
  3953. -       if ( Dc_arg_type & ARG_FLOAT )  {
  3954. -           if (Dc_arg_float < 0.25f) {
  3955. -               cam->set_fov(0.25f);
  3956. -               dc_printf("Zoom factor pinned at 0.25.\n");
  3957. -           } else if (Dc_arg_float > 1.25f) {
  3958. -               cam->set_fov(1.25f);
  3959. -               dc_printf("Zoom factor pinned at 1.25.\n");
  3960. -           } else {
  3961. -               cam->set_fov(Dc_arg_float);
  3962. -           }
  3963. +   if (dc_optional_string_either("help", "--help")) {
  3964. +       dc_printf( "Usage: fov [factor]\nFactor is the zoom factor btwn .25 and 1.25\nNo parameter resets it to default.\n" );
  3965. +       process = false;
  3966. +   }
  3967. +
  3968. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  3969. +       if(cam == NULL) {
  3970. +           dc_printf("Camera unavailable.");
  3971. +       } else {
  3972. +           dc_printf("Zoom factor set to %6.3f (original = 0.5, John = 0.75)\n", cam->get_fov());
  3973.         }
  3974. +
  3975. +       process = false;
  3976.     }
  3977.  
  3978. -   if ( Dc_help ) 
  3979. -       dc_printf( "Usage: fov [factor]\nFactor is the zoom factor btwn .25 and 1.25\nNo parameter resets it to default.\n" );
  3980. +   if ((cam == NULL) || (!process)) {
  3981. +       return;
  3982. +   }
  3983.  
  3984. -   if ( Dc_status )
  3985. -   {
  3986. -       if(cam == NULL)
  3987. -           dc_printf("Camera unavailable.");
  3988. -       else
  3989. -           dc_printf("Zoom factor set to %6.3f (original = 0.5, John = 0.75)", cam->get_fov());
  3990. +   if (!dc_maybe_stuff_float(&value)) {
  3991. +       // No value passed, use default
  3992. +       cam->set_fov(VIEWER_ZOOM_DEFAULT);
  3993. +   } else {
  3994. +       // Value passed, Clamp it to valid values
  3995. +       if (value < 0.25f) {
  3996. +           value = 0.25f;
  3997. +           dc_printf("Zoom factor clamped to 0.25\n");
  3998. +       } else if (value > 1.25f) {
  3999. +           value = 1.25f;
  4000. +           dc_printf("Zoom factor clamped to 1.25\n");
  4001. +       } else {
  4002. +           dc_printf("Zoom factor set to %6.3f\n", value);
  4003. +       }
  4004. +
  4005. +       cam->set_fov(value);
  4006.     }
  4007.  }
  4008.  
  4009.  
  4010.  DCF(framerate_cap, "Sets the framerate cap")
  4011.  {
  4012. -   if ( Dc_command ) {
  4013. -       dc_get_arg(ARG_INT);
  4014. -       if ( (Dc_arg_int >= 1 ) || (Dc_arg_int <= 120) ) {
  4015. -           Framerate_cap = Dc_arg_int;
  4016. -       } else {
  4017. -           dc_printf( "Illegal value for framerate cap. (Must be from 1-120) \n\n");
  4018. -           Dc_help = 1;
  4019. -       }
  4020. -   }
  4021. +   bool process = true;
  4022.  
  4023. -   if ( Dc_help ) {
  4024. +   if (dc_optional_string_either("help", "--help")) {
  4025.         dc_printf("Usage: framerate_cap [n]\nwhere n is the frames per second to cap framerate at.\n");
  4026.         dc_printf("If n is 0 or omitted, then the framerate cap is removed\n");
  4027.         dc_printf("[n] must be from 1 to 120.\n");
  4028. +       process = false;
  4029.     }
  4030. -  
  4031. -   if ( Dc_status ) {
  4032. -       if ( Framerate_cap )
  4033. +
  4034. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  4035. +       if ( Framerate_cap ) {
  4036.             dc_printf("Framerate cap is set to %d fps\n", Framerate_cap );
  4037. -       else
  4038. +       } else {
  4039.             dc_printf("There is no framerate cap currently active.\n");
  4040. +       }
  4041. +
  4042. +       process = false;
  4043. +   }
  4044. +
  4045. +   if (!process) {
  4046. +       return;
  4047. +   }
  4048. +
  4049. +   if (!dc_maybe_stuff_int(&Framerate_cap)) {
  4050. +       Framerate_cap = 0;
  4051. +   }
  4052. +
  4053. +   if ((Framerate_cap < 0) || (Framerate_cap > 120)) {
  4054. +       dc_printf( "Illegal value for framerate cap. (Must be from 1-120) \n");
  4055. +       Framerate_cap = 0;
  4056. +   }
  4057. +
  4058. +   if (Framerate_cap == 0) {
  4059. +       dc_printf("Framerate cap disabled");
  4060. +   } else {
  4061. +       dc_printf("Framerate cap is set to %d fps\n", Framerate_cap );
  4062.     }
  4063.  }
  4064.  
  4065. @@ -3774,87 +3865,71 @@ void john_debug_stuff(vec3d *eye_pos, matrix *eye_orient)
  4066.  #ifndef NDEBUG
  4067.  
  4068.  // function to toggle state of dumping every frame into PCX when playing the game
  4069. -DCF(dump_frames, "Starts/stop frame dumping at 15 hz")
  4070. -{
  4071. -   if ( Dc_command )   {
  4072. -
  4073. -       if ( Debug_dump_frames == 0 )   {
  4074. -           // Turn it on
  4075. -           Debug_dump_frames = 15;
  4076. -           Debug_dump_trigger = 0;
  4077. -           gr_dump_frame_start( Debug_dump_frame_num, DUMP_BUFFER_NUM_FRAMES );
  4078. -           dc_printf( "Frame dumping at 15 hz is now ON\n" );
  4079. -       } else {
  4080. -           // Turn it off
  4081. -           Debug_dump_frames = 0;
  4082. -           Debug_dump_trigger = 0;
  4083. -           gr_dump_frame_stop();
  4084. -           dc_printf( "Frame dumping is now OFF\n" );
  4085. -       }
  4086. -      
  4087. +DCF(dump_frames, "Toggles On/off frame dumping at 15 hz")
  4088. +{
  4089. +   if ( Debug_dump_frames == 0 )   {
  4090. +       // Turn it on
  4091. +       Debug_dump_frames = 15;
  4092. +       Debug_dump_trigger = 0;
  4093. +       gr_dump_frame_start( Debug_dump_frame_num, DUMP_BUFFER_NUM_FRAMES );
  4094. +       dc_printf( "Frame dumping at 15 hz is now ON\n" );
  4095. +   } else {
  4096. +       // Turn it off
  4097. +       Debug_dump_frames = 0;
  4098. +       Debug_dump_trigger = 0;
  4099. +       gr_dump_frame_stop();
  4100. +       dc_printf( "Frame dumping is now OFF\n" );
  4101.     }
  4102.  }
  4103.  
  4104.  DCF(dump_frames_trigger, "Starts/stop frame dumping at 15 hz")
  4105.  {
  4106. -   if ( Dc_command )   {
  4107. -
  4108. -       if ( Debug_dump_frames == 0 )   {
  4109. -           // Turn it on
  4110. -           Debug_dump_frames = 15;
  4111. -           Debug_dump_trigger = 1;
  4112. -           gr_dump_frame_start( Debug_dump_frame_num, DUMP_BUFFER_NUM_FRAMES );
  4113. -           dc_printf( "Frame dumping at 15 hz is now ON\n" );
  4114. -       } else {
  4115. -           // Turn it off
  4116. -           Debug_dump_frames = 0;
  4117. -           Debug_dump_trigger = 0;
  4118. -           gr_dump_frame_stop();
  4119. -           dc_printf( "Frame dumping is now OFF\n" );
  4120. -       }
  4121. -      
  4122. +   if ( Debug_dump_frames == 0 )   {
  4123. +       // Turn it on
  4124. +       Debug_dump_frames = 15;
  4125. +       Debug_dump_trigger = 1;
  4126. +       gr_dump_frame_start( Debug_dump_frame_num, DUMP_BUFFER_NUM_FRAMES );
  4127. +       dc_printf( "Frame dumping at 15 hz is now ON\n" );
  4128. +   } else {
  4129. +       // Turn it off
  4130. +       Debug_dump_frames = 0;
  4131. +       Debug_dump_trigger = 0;
  4132. +       gr_dump_frame_stop();
  4133. +       dc_printf( "Frame dumping is now OFF\n" );
  4134.     }
  4135.  }
  4136.  
  4137.  DCF(dump_frames30, "Starts/stop frame dumping at 30 hz")
  4138.  {
  4139. -   if ( Dc_command )   {
  4140. -
  4141. -       if ( Debug_dump_frames == 0 )   {
  4142. -           // Turn it on
  4143. -           Debug_dump_frames = 30;
  4144. -           Debug_dump_trigger = 0;
  4145. -           gr_dump_frame_start( Debug_dump_frame_num, DUMP_BUFFER_NUM_FRAMES );
  4146. -           dc_printf( "Frame dumping at 30 hz is now ON\n" );
  4147. -       } else {
  4148. -           // Turn it off
  4149. -           Debug_dump_frames = 0;
  4150. -           Debug_dump_trigger = 0;
  4151. -           gr_dump_frame_stop();
  4152. -           dc_printf( "Frame dumping is now OFF\n" );
  4153. -       }
  4154. -      
  4155. +   if ( Debug_dump_frames == 0 )   {
  4156. +       // Turn it on
  4157. +       Debug_dump_frames = 30;
  4158. +       Debug_dump_trigger = 0;
  4159. +       gr_dump_frame_start( Debug_dump_frame_num, DUMP_BUFFER_NUM_FRAMES );
  4160. +       dc_printf( "Frame dumping at 30 hz is now ON\n" );
  4161. +   } else {
  4162. +       // Turn it off
  4163. +       Debug_dump_frames = 0;
  4164. +       Debug_dump_trigger = 0;
  4165. +       gr_dump_frame_stop();
  4166. +       dc_printf( "Frame dumping is now OFF\n" );
  4167.     }
  4168.  }
  4169.  
  4170.  DCF(dump_frames30_trigger, "Starts/stop frame dumping at 30 hz")
  4171.  {
  4172. -   if ( Dc_command )   {
  4173. -
  4174. -       if ( Debug_dump_frames == 0 )   {
  4175. -           // Turn it on
  4176. -           Debug_dump_frames = 30;
  4177. -           Debug_dump_trigger = 1;
  4178. -           gr_dump_frame_start( Debug_dump_frame_num, DUMP_BUFFER_NUM_FRAMES );
  4179. -           dc_printf( "Triggered frame dumping at 30 hz is now ON\n" );
  4180. -       } else {
  4181. -           // Turn it off
  4182. -           Debug_dump_frames = 0;
  4183. -           Debug_dump_trigger = 0;
  4184. -           gr_dump_frame_stop();
  4185. -           dc_printf( "Triggered frame dumping is now OFF\n" );
  4186. -       }
  4187. -      
  4188. +   if ( Debug_dump_frames == 0 )   {
  4189. +       // Turn it on
  4190. +       Debug_dump_frames = 30;
  4191. +       Debug_dump_trigger = 1;
  4192. +       gr_dump_frame_start( Debug_dump_frame_num, DUMP_BUFFER_NUM_FRAMES );
  4193. +       dc_printf( "Triggered frame dumping at 30 hz is now ON\n" );
  4194. +   } else {
  4195. +       // Turn it off
  4196. +       Debug_dump_frames = 0;
  4197. +       Debug_dump_trigger = 0;
  4198. +       gr_dump_frame_stop();
  4199. +       dc_printf( "Triggered frame dumping is now OFF\n" );
  4200.     }
  4201.  }
  4202.  
  4203. @@ -6920,7 +6995,7 @@ void game_spew_pof_info()
  4204.     BAIL();
  4205.  }
  4206.  
  4207. -DCF(pofspew, "")
  4208. +DCF(pofspew, "Spews POF info without shutting down the game")
  4209.  {
  4210.     game_spew_pof_info();
  4211.  }
  4212. Index: code/gamehelp/contexthelp.cpp
  4213. ===================================================================
  4214. --- code/gamehelp/contexthelp.cpp   (revision 10462)
  4215. +++ code/gamehelp/contexthelp.cpp   (working copy)
  4216. @@ -19,6 +19,7 @@
  4217.  #include "localization/localize.h"
  4218.  #include "globalincs/alphacolors.h"
  4219.  #include "globalincs/systemvars.h"
  4220. +#include "debugconsole/console.h"
  4221.  
  4222.  
  4223.  
  4224. @@ -556,20 +557,14 @@ void help_overlay_blit(int overlay_id)
  4225.  // --------------------------------------------------
  4226.  // DEBUGGING STUFF
  4227.  // --------------------------------------------------
  4228. -
  4229. +// z64: These DCF's really need a do-over.
  4230.  DCF(help_reload, "Reloads help overlay data from help.tbl")
  4231.  {
  4232. -   if (Dc_command) {
  4233. -       parse_helptbl();
  4234. -   }
  4235. -
  4236. -   if (Dc_help)    {
  4237. +   if (dc_optional_string_either("help", "--help")) {
  4238.         dc_printf( "Usage: sample\nCrashes your machine.\n" );
  4239.     }
  4240.  
  4241. -   if (Dc_status)  {
  4242. -       dc_printf( "Yes, my master." );
  4243. -   }
  4244. +   parse_helptbl();
  4245.  }
  4246.  
  4247.  int h_textnum=0, h_amt=0, h_vtx = 0;
  4248. @@ -630,150 +625,115 @@ void showplinepos(int plinenum)
  4249.  
  4250.  DCF(help_nudgetext_x, "Use to visually position overlay text.")
  4251.  {
  4252. -   if (Dc_command) {
  4253. -       dc_get_arg(ARG_INT);
  4254. -       if(Dc_arg_type & ARG_INT){
  4255. -            h_textnum = Dc_arg_int;       
  4256. -       }
  4257. -       dc_get_arg(ARG_INT);
  4258. -       if(Dc_arg_type & ARG_INT){
  4259. -            h_amt = Dc_arg_int;       
  4260. -       }
  4261. -       nudgetext_x(h_textnum, h_amt);
  4262. -   }
  4263.  
  4264. -   if (Dc_help)    {
  4265. +   if (dc_optional_string_either("help", "--help")) {
  4266.         dc_printf( "Usage: sample\nCrashes your machine.\n" );
  4267. +       return;
  4268.     }
  4269.  
  4270. -   if (Dc_status)  {
  4271. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  4272.         showtextpos(h_textnum);
  4273. +       return;
  4274.     }
  4275. +
  4276. +   dc_stuff_int(&h_textnum);
  4277. +   dc_stuff_int(&h_amt);
  4278. +
  4279. +   nudgetext_x(h_textnum, h_amt);
  4280.  }
  4281.  
  4282.  DCF(help_nudgetext_y, "Use to visually position overlay text.")
  4283.  {
  4284. -   if (Dc_command) {
  4285. -       dc_get_arg(ARG_INT);
  4286. -       if(Dc_arg_type & ARG_INT){
  4287. -            h_textnum = Dc_arg_int;       
  4288. -       }
  4289. -       dc_get_arg(ARG_INT);
  4290. -       if(Dc_arg_type & ARG_INT){
  4291. -            h_amt = Dc_arg_int;       
  4292. -       }
  4293. -       nudgetext_y(h_textnum, h_amt);
  4294. -   }
  4295. -
  4296. -   if (Dc_help)    {
  4297. +   if (dc_optional_string_either("help", "--help")) {
  4298.         dc_printf( "Usage: sample\nCrashes your machine.\n" );
  4299. +       return;
  4300.     }
  4301.  
  4302. -   if (Dc_status)  {
  4303. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  4304.         showtextpos(h_textnum);
  4305. +       return;
  4306.     }
  4307. +
  4308. +   dc_stuff_int(&h_textnum);
  4309. +   dc_stuff_int(&h_amt);
  4310. +  
  4311. +   nudgetext_y(h_textnum, h_amt);
  4312.  }
  4313.  
  4314.  DCF(help_nudgepline_x, "Use to visually position overlay polylines.")
  4315.  {
  4316. -   if (Dc_command) {
  4317. -       dc_get_arg(ARG_INT);
  4318. -       if(Dc_arg_type & ARG_INT){
  4319. -            h_textnum = Dc_arg_int;       
  4320. -       }
  4321. -       dc_get_arg(ARG_INT);
  4322. -       if(Dc_arg_type & ARG_INT){
  4323. -            h_vtx = Dc_arg_int;       
  4324. -       }
  4325. -       dc_get_arg(ARG_INT);
  4326. -       if(Dc_arg_type & ARG_INT){
  4327. -            h_amt = Dc_arg_int;       
  4328. -       }
  4329. -       nudgepline_x(h_textnum, h_vtx, h_amt);
  4330. -   }
  4331. -
  4332. -   if (Dc_help)    {
  4333. +       if (dc_optional_string_either("help", "--help")) {
  4334.         dc_printf( "Usage: help_nudgepline [pline_number] [vertex_number] [distance]\n" );
  4335. +       return;
  4336.     }
  4337.  
  4338. -   if (Dc_status)  {
  4339. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?"))   {
  4340.         showplinepos(h_textnum);
  4341. +       return;
  4342.     }
  4343. +
  4344. +   dc_stuff_int(&h_textnum);
  4345. +   dc_stuff_int(&h_vtx);
  4346. +   dc_stuff_int(&h_amt);
  4347. +
  4348. +   nudgepline_x(h_textnum, h_vtx, h_amt);
  4349.  }
  4350.  
  4351.  
  4352.  DCF(help_nudgepline_y, "Use to visually position overlay polylines.")
  4353.  {
  4354. -   if (Dc_command) {
  4355. -       dc_get_arg(ARG_INT);
  4356. -       if(Dc_arg_type & ARG_INT){
  4357. -            h_textnum = Dc_arg_int;       
  4358. -       }
  4359. -       dc_get_arg(ARG_INT);
  4360. -       if(Dc_arg_type & ARG_INT){
  4361. -            h_vtx = Dc_arg_int;       
  4362. -       }
  4363. -       dc_get_arg(ARG_INT);
  4364. -       if(Dc_arg_type & ARG_INT){
  4365. -            h_amt = Dc_arg_int;       
  4366. -       }
  4367. -       nudgepline_y(h_textnum, h_vtx, h_amt);
  4368. -   }
  4369. -
  4370. -   if (Dc_help)    {
  4371. +   if (dc_optional_string_either("help", "--help")) {
  4372.         dc_printf( "Usage: help_nudgepline [pline_number] [vertex_number] [distance]\n" );
  4373. +       return;
  4374.     }
  4375.  
  4376. -   if (Dc_status)  {
  4377. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?"))   {
  4378.         showplinepos(h_textnum);
  4379. +       return;
  4380.     }
  4381. +
  4382. +   dc_stuff_int(&h_textnum);
  4383. +   dc_stuff_int(&h_vtx);
  4384. +   dc_stuff_int(&h_amt);
  4385. +
  4386. +   nudgepline_y(h_textnum, h_vtx, h_amt);
  4387.  }
  4388.  
  4389.  
  4390.  DCF(help_nudgerbracket_x, "Use to visually position overlay right bracket.")
  4391.  {
  4392. -   if (Dc_command) {
  4393. -       dc_get_arg(ARG_INT);
  4394. -       if(Dc_arg_type & ARG_INT){
  4395. -            h_textnum = Dc_arg_int;       
  4396. -       }
  4397. -       dc_get_arg(ARG_INT);
  4398. -       if(Dc_arg_type & ARG_INT){
  4399. -            h_amt = Dc_arg_int;       
  4400. -       }
  4401. -       nudgerbracket_x(h_textnum, h_amt);
  4402. -   }
  4403. -
  4404. -   if (Dc_help)    {
  4405. +   if (dc_optional_string_either("help", "--help")) {
  4406.         dc_printf( "Usage: help_nudgerbracket_x [num] [amount]\n" );
  4407. +       return;
  4408.     }
  4409.  
  4410. -   if (Dc_status)  {
  4411. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?"))   {
  4412.         showrbracketpos(h_textnum);
  4413. +       return;
  4414.     }
  4415. +
  4416. +   dc_stuff_int(&h_textnum);
  4417. +   dc_stuff_int(&h_amt);
  4418. +
  4419. +   nudgerbracket_x(h_textnum, h_amt);
  4420.  }
  4421.  
  4422.  DCF(help_nudgerbracket_y, "Use to visually position overlay right bracket.")
  4423.  {
  4424. -   if (Dc_command) {
  4425. -       dc_get_arg(ARG_INT);
  4426. -       if(Dc_arg_type & ARG_INT){
  4427. -            h_textnum = Dc_arg_int;       
  4428. -       }
  4429. -       dc_get_arg(ARG_INT);
  4430. -       if(Dc_arg_type & ARG_INT){
  4431. -            h_amt = Dc_arg_int;       
  4432. -       }
  4433. -       nudgerbracket_y(h_textnum, h_amt);
  4434. -   }
  4435. -
  4436. -   if (Dc_help)    {
  4437. +   if (dc_optional_string_either("help", "--help")) {
  4438.         dc_printf( "Usage: help_nudgerbracket_y [num] [amount]\n" );
  4439. +       return;
  4440.     }
  4441.  
  4442. -   if (Dc_status)  {
  4443. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?"))   {
  4444.         showrbracketpos(h_textnum);
  4445. +       return;
  4446.     }
  4447. +
  4448. +   dc_stuff_int(&h_textnum);
  4449. +   dc_stuff_int(&h_amt);
  4450. +  
  4451. +   nudgerbracket_y(h_textnum, h_amt);
  4452.  }
  4453.  
  4454.  
  4455. @@ -781,46 +741,37 @@ DCF(help_nudgerbracket_y, "Use to visually position overlay right bracket.")
  4456.  
  4457.  DCF(help_nudgelbracket_x, "Use to visually position overlay left bracket.")
  4458.  {
  4459. -   if (Dc_command) {
  4460. -       dc_get_arg(ARG_INT);
  4461. -       if(Dc_arg_type & ARG_INT){
  4462. -            h_textnum = Dc_arg_int;       
  4463. -       }
  4464. -       dc_get_arg(ARG_INT);
  4465. -       if(Dc_arg_type & ARG_INT){
  4466. -            h_amt = Dc_arg_int;       
  4467. -       }
  4468. -       nudgelbracket_x(h_textnum, h_amt);
  4469. -   }
  4470.  
  4471. -   if (Dc_help)    {
  4472. +   if (dc_optional_string_either("help", "--help")) {
  4473.         dc_printf( "Usage: help_nudgelbracket_x [num] [amount]\n" );
  4474. +       return;
  4475.     }
  4476.  
  4477. -   if (Dc_status)  {
  4478. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  4479.         showlbracketpos(h_textnum);
  4480. +       return;
  4481.     }
  4482. +
  4483. +   dc_stuff_int(&h_textnum);
  4484. +   dc_stuff_int(&h_amt);
  4485. +
  4486. +   nudgelbracket_x(h_textnum, h_amt);
  4487.  }
  4488.  
  4489.  DCF(help_nudgelbracket_y, "Use to visually position overlay left bracket.")
  4490.  {
  4491. -   if (Dc_command) {
  4492. -       dc_get_arg(ARG_INT);
  4493. -       if(Dc_arg_type & ARG_INT){
  4494. -            h_textnum = Dc_arg_int;       
  4495. -       }
  4496. -       dc_get_arg(ARG_INT);
  4497. -       if(Dc_arg_type & ARG_INT){
  4498. -            h_amt = Dc_arg_int;       
  4499. -       }
  4500. -       nudgelbracket_y(h_textnum, h_amt);
  4501. -   }
  4502. -
  4503. -   if (Dc_help)    {
  4504. +   if (dc_optional_string_either("help", "--help")) {
  4505.         dc_printf( "Usage: help_nudgelbracket_y [num] [amount]\n" );
  4506. +       return;
  4507.     }
  4508.  
  4509. -   if (Dc_status)  {
  4510. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?"))   {
  4511.         showlbracketpos(h_textnum);
  4512. +       return;
  4513.     }
  4514. +
  4515. +   dc_stuff_int(&h_textnum);
  4516. +   dc_stuff_int(&h_amt);
  4517. +
  4518. +   nudgelbracket_y(h_textnum, h_amt);
  4519.  }
  4520. Index: code/globalincs/pstypes.h
  4521. ===================================================================
  4522. --- code/globalincs/pstypes.h   (revision 10462)
  4523. +++ code/globalincs/pstypes.h   (working copy)
  4524. @@ -319,113 +319,6 @@ extern int Fred_running;  // Is Fred running, or FreeSpace?
  4525.  
  4526.  
  4527.  //======================================================================================
  4528. -//======          D E B U G    C O N S O L E   S T U F F        ========================
  4529. -//======================================================================================
  4530. -
  4531. -// Here is a a sample command to toggle something that would
  4532. -// be called by doing "toggle it" from the debug console command window/
  4533. -
  4534. -/*
  4535. -DCF(toggle_it,"description")
  4536. -{
  4537. -   if (Dc_command) {
  4538. -       This_var = !This_var;
  4539. -   }
  4540. -
  4541. -   if (Dc_help) {
  4542. -       dc_printf( "Usage: sample\nToggles This_var on/off.\n" );
  4543. -   }
  4544. -
  4545. -   if (Dc_status) {
  4546. -       dc_printf( "The status is %d.\n", This_var );
  4547. -   }
  4548. -*/
  4549. -
  4550. -class debug_command {
  4551. -   public:
  4552. -   char *name;
  4553. -   char *help;
  4554. -   void (*func)();
  4555. -   debug_command(char *name,char *help,void (*func)());    // constructor
  4556. -};
  4557. -
  4558. -#define DCF(function_name,help_text)   \
  4559. -       void dcf_##function_name(); \
  4560. -       debug_command dc_##function_name(#function_name,help_text,dcf_##function_name); \
  4561. -       void dcf_##function_name()
  4562. -
  4563. -// Starts the debug console
  4564. -extern void debug_console( void (*func)() = NULL );
  4565. -
  4566. -// The next three variables tell your function what to do.  It should
  4567. -// only change something if the dc_command is set.   A minimal function
  4568. -// needs to process the dc_command.   Usually, these will be called in
  4569. -// these combinations:
  4570. -// dc_command=true, dc_status=true  means process it and show status
  4571. -// dc_help=true means show help only
  4572. -// dc_status=true means show status only
  4573. -// I would recommend doing this in each function:
  4574. -// if (dc_command) { process command }
  4575. -// if (dc_help) { print out help }
  4576. -// if (dc_status) { print out status }
  4577. -// with the last two being optional
  4578. -
  4579. -extern int Dc_command;         // If this is set, then process the command
  4580. -extern int Dc_help;                // If this is set, then print out the help text in the form, "usage: ... \nLong description\n" );
  4581. -extern int Dc_status;          // If this is set, then print out the current status of the command.
  4582. -
  4583. -void dc_get_arg(uint flags);   // Gets the next argument.   If it doesn't match the flags, this function will print an error and not return.
  4584. -extern char *Dc_arg;           // The (lowercased) string value of the argument retrieved from dc_arg
  4585. -extern char *Dc_arg_org;       // Dc_arg before it got converted to lowercase
  4586. -extern uint Dc_arg_type;       // The type of dc_arg.
  4587. -extern char *Dc_command_line;  // The rest of the command line, from the end of the last processed arg on.
  4588. -extern int Dc_arg_int;         // If Dc_arg_type & ARG_INT or ARG_HEX is set, then this is the value
  4589. -extern ubyte Dc_arg_ubyte;     // If Dc_arg_type & ARG_UBYTE is set, then this is the value
  4590. -extern float Dc_arg_float;     // If Dc_arg_type & ARG_FLOAT is set, then this is the value
  4591. -
  4592. -// Outputs text to the console
  4593. -void dc_printf( char *format, ... );
  4594. -
  4595. -// Each dc_arg_type can have one or more of these flags set.
  4596. -// This is because some things can fit into two categories.
  4597. -// Like 1 can be an integer, a float, a string, or a true boolean
  4598. -// value.
  4599. -#define ARG_NONE       (1<<0)      // no argument
  4600. -#define ARG_ANY            0xFFFFFFFF  // Anything.
  4601. -#define ARG_STRING     (1<<1)      // any valid string
  4602. -#define ARG_QUOTE      (1<<2)      // a quoted string
  4603. -#define ARG_INT            (1<<3)      // a valid integer
  4604. -#define ARG_FLOAT      (1<<4)      // a valid floating point number
  4605. -
  4606. -// some specific commonly used predefined types. Can add up to (1<<31)
  4607. -#define ARG_HEX            (1<<5)      // a valid hexadecimal integer. Note that ARG_INT will always be set also in this case.
  4608. -#define ARG_TRUE       (1<<6)      // on, true, non-zero number
  4609. -#define ARG_FALSE      (1<<7)      // off, false, zero
  4610. -#define ARG_PLUS       (1<<8)      // Plus sign
  4611. -#define ARG_MINUS      (1<<9)      // Minus sign
  4612. -#define ARG_COMMA      (1<<10)     // a comma
  4613. -#define ARG_UBYTE      (1<<11)     // a valid ubyte
  4614. -
  4615. -// A shortcut for boolean only variables.
  4616. -// Example:  
  4617. -// DCF_BOOL( lighting, Show_lighting )
  4618. -//
  4619. -#define DCF_BOOL( function_name, bool_variable )   \
  4620. -   void dcf_##function_name(); \
  4621. -   debug_command dc_##function_name(#function_name,"Toggles "#bool_variable,dcf_##function_name ); \
  4622. -   void dcf_##function_name()  {   \
  4623. -   if ( Dc_command )   {   \
  4624. -       dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);        \
  4625. -       if ( Dc_arg_type & ARG_TRUE )   bool_variable = 1;  \
  4626. -       else if ( Dc_arg_type & ARG_FALSE ) bool_variable = 0;  \
  4627. -       else if ( Dc_arg_type & ARG_NONE ) bool_variable ^= 1;  \
  4628. -   }   \
  4629. -   if ( Dc_help )  dc_printf( "Usage: %s [bool]\nSets %s to true or false.  If nothing passed, then toggles it.\n", #function_name, #bool_variable );  \
  4630. -   if ( Dc_status )    dc_printf( "%s is %s\n", #function_name, (bool_variable?"TRUE":"FALSE") );  \
  4631. -}
  4632. -
  4633. -
  4634. -//======================================================================================
  4635.  //======================================================================================
  4636.  //======================================================================================
  4637.  
  4638. Index: code/globalincs/systemvars.cpp
  4639. ===================================================================
  4640. --- code/globalincs/systemvars.cpp  (revision 10462)
  4641. +++ code/globalincs/systemvars.cpp  (working copy)
  4642. @@ -8,7 +8,7 @@
  4643.  */
  4644.  
  4645.  
  4646. -
  4647. +#include "debugconsole/console.h"
  4648.  #include "globalincs/pstypes.h"
  4649.  #include "globalincs/systemvars.h"
  4650.  #include "io/timer.h"
  4651. @@ -248,73 +248,76 @@ int Monitor_inited = 0;
  4652.  char Monitor_filename[128];
  4653.  fix monitor_last_time = -1;
  4654.  
  4655. -DCF(monitor,"Monitors game performace")
  4656. +DCF(monitor,"Monitors game performace by saving to file")
  4657.  {
  4658. -   if ( Dc_command )   {
  4659. -       dc_get_arg(ARG_STRING|ARG_NONE);
  4660. -       if ( Dc_arg_type == ARG_NONE )  {
  4661. -           if ( Monitor_inited )   {
  4662. -               Monitor_inited = 0;
  4663. +   SCP_string filename;
  4664.  
  4665. -/*
  4666. -               FILE *fp = fopen( Monitor_filename, "at" );
  4667. -               if ( fp )   {
  4668. -                   fprintf( fp, "\n\n" );
  4669. -                   fprintf( fp, "Name\tMin\tMax\tAvg\n" );
  4670. -                   for (int i=0; i<Num_monitors; i++ ) {
  4671. -                       if ( Monitor[i]->cnt > 0 )  {
  4672. -                           fprintf( fp, "%s\t%d\t%d\t%d\n", Monitor[i]->name, Monitor[i]->min, Monitor[i]->max, Monitor[i]->sum / Monitor[i]->cnt  );
  4673. -                       } else {
  4674. -                           fprintf( fp, "%s\t%d\t%d\t?\n", Monitor[i]->name, Monitor[i]->min, Monitor[i]->max );
  4675. -                       }
  4676. -                   }
  4677. -                   fclose(fp);
  4678. -               }
  4679. -*/
  4680. +   if (dc_optional_string_either("help", "--help")) {
  4681. +       dc_printf("Usage: monitor [filename]\n");
  4682. +       dc_printf("Outputs monitoring info to [filename]. No filename turns it off\n" );
  4683. +       return;
  4684. +   }
  4685.  
  4686. -               dc_printf( "Monitor to file '%s' turned off\n", Monitor_filename );
  4687. -           } else {
  4688. -               dc_printf( "Monitor isn't on\n" );
  4689. -           }
  4690. -       } else {
  4691. -           if ( Monitor_inited )   {
  4692. +   if (dc_maybe_stuff_string_white(filename)) {
  4693. +       if ( Monitor_inited )   {
  4694.                 dc_printf( "Monitor already on\n" );
  4695. -           } else {
  4696. -               Monitor_inited = 1;
  4697. +       } else {
  4698. +           Monitor_inited = 1;
  4699.  
  4700. -               strcpy_s( Monitor_filename, Dc_arg );
  4701. +           strcpy(Monitor_filename, filename.c_str());
  4702. +
  4703. +           // Reset them all
  4704. +           int i;
  4705. +           for (i=0; i<Num_monitors; i++ ) {
  4706. +               Monitor[i]->value = 0;
  4707. +               Monitor[i]->sum = 0;
  4708. +               Monitor[i]->cnt = 0;
  4709. +               Monitor[i]->min = 0;
  4710. +               Monitor[i]->max = 0;
  4711. +           }
  4712.  
  4713. -               // Reset them all
  4714. -               int i;
  4715. +           FILE *fp = fopen( Monitor_filename, "wt" );
  4716. +           if ( fp )   {
  4717.                 for (i=0; i<Num_monitors; i++ ) {
  4718. -                   Monitor[i]->value = 0;
  4719. -                   Monitor[i]->sum = 0;
  4720. -                   Monitor[i]->cnt = 0;
  4721. -                   Monitor[i]->min = 0;
  4722. -                   Monitor[i]->max = 0;
  4723. +                   if ( i > 0 )    {
  4724. +                       fprintf( fp, "\t" );
  4725. +                   }
  4726. +                   fprintf( fp, "%s", Monitor[i]->name );
  4727. +
  4728.                 }
  4729. +               fprintf( fp, "\n" );
  4730. +               fclose(fp);
  4731. +           }
  4732. +           dc_printf( "Monitor outputting to file '%s'\n", Monitor_filename );
  4733. +           monitor_last_time = -1;
  4734. +       }
  4735. +
  4736. +   } else {
  4737. +       // Turn off monitoring
  4738. +       if ( Monitor_inited )   {
  4739. +           Monitor_inited = 0;
  4740.  
  4741. -               FILE *fp = fopen( Monitor_filename, "wt" );
  4742. -               if ( fp )   {
  4743. -                   for (i=0; i<Num_monitors; i++ ) {
  4744. -                       if ( i > 0 )    {
  4745. -                           fprintf( fp, "\t" );
  4746. -                       }
  4747. -                       fprintf( fp, "%s", Monitor[i]->name );
  4748. -                  
  4749. +/*
  4750. +           FILE *fp = fopen( Monitor_filename, "at" );
  4751. +           if ( fp )   {
  4752. +               fprintf( fp, "\n\n" );
  4753. +               fprintf( fp, "Name\tMin\tMax\tAvg\n" );
  4754. +               for (int i=0; i<Num_monitors; i++ ) {
  4755. +                   if ( Monitor[i]->cnt > 0 )  {
  4756. +                       fprintf( fp, "%s\t%d\t%d\t%d\n", Monitor[i]->name, Monitor[i]->min, Monitor[i]->max, Monitor[i]->sum / Monitor[i]->cnt  );
  4757. +                   } else {
  4758. +                       fprintf( fp, "%s\t%d\t%d\t?\n", Monitor[i]->name, Monitor[i]->min, Monitor[i]->max );
  4759.                     }
  4760. -                   fprintf( fp, "\n" );
  4761. -                   fclose(fp);
  4762.                 }
  4763. -               dc_printf( "Monitor outputting to file '%s'\n", Monitor_filename );
  4764. -               monitor_last_time = -1;
  4765. +               fclose(fp);
  4766.             }
  4767. +*/
  4768. +
  4769. +           dc_printf( "Monitor to file '%s' turned off\n", Monitor_filename );
  4770. +       } else {
  4771. +           dc_printf( "Monitor isn't on\n" );
  4772.         }
  4773.     }
  4774. -   if ( Dc_help )  {
  4775. -       dc_printf( "Usage: monitor filename\nOutputs monitoring info to filename. No filename turns it off\n" );
  4776. -   }
  4777. -  
  4778.  }
  4779.  
  4780.  
  4781. @@ -508,44 +511,41 @@ int current_detail_level()
  4782.  #ifndef NDEBUG
  4783.  DCF(detail_level,"Change the detail level")
  4784.  {
  4785. -   if ( Dc_command )   {
  4786. -       dc_get_arg(ARG_INT|ARG_NONE);
  4787. -       if ( Dc_arg_type & ARG_NONE )   {
  4788. -           Game_detail_level = 0;
  4789. -           dc_printf( "Detail level reset\n" );
  4790. -       }
  4791. -       if ( Dc_arg_type & ARG_INT )    {
  4792. -           Game_detail_level = Dc_arg_int;
  4793. -       }
  4794. +   int value;
  4795. +
  4796. +   if (dc_optional_string_either("help", "--help")) {
  4797. +       dc_printf( "Usage: detail_level [n]\n");
  4798. +       dc_printf("[n]  -- is detail level.\n");
  4799. +           dc_printf("\t0 is 'normal' detail,\n");
  4800. +           dc_printf("\tnegative values are lower, and\n");
  4801. +           dc_printf("\tpositive values are higher.\n\n");
  4802. +      
  4803. +       dc_printf("No parameter resets it to default.\n");
  4804. +       return;
  4805.     }
  4806.  
  4807. -   if ( Dc_help ) 
  4808. -       dc_printf( "Usage: detail_level [n]\nn is detail level. 0 normal, - lower, + higher, -2 to 2 usually\nNo parameter resets it to default.\n" );
  4809. -
  4810. -   if ( Dc_status )               
  4811. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  4812.         dc_printf("Detail level set to %d\n", Game_detail_level);
  4813. +       return;
  4814. +   }
  4815. +
  4816. +   if (dc_maybe_stuff_int(&value)) {
  4817. +       Game_detail_level = value;
  4818. +       dc_printf("Detail level set to %i\n", Game_detail_level);
  4819. +
  4820. +   } else {
  4821. +       Game_detail_level = 0;
  4822. +       dc_printf("Detail level reset\n");
  4823. +   }
  4824.  }
  4825.  
  4826.  DCF(detail, "Turns on/off parts of the game for speed testing" )
  4827.  {
  4828. -   if ( Dc_command )   {
  4829. -       dc_get_arg(ARG_INT|ARG_NONE);
  4830. -       if ( Dc_arg_type & ARG_NONE )   {
  4831. -           if ( Game_detail_flags == DETAIL_DEFAULT )  {
  4832. -               Game_detail_flags = DETAIL_FLAG_CLEAR;
  4833. -               dc_printf( "Detail flags set lowest (except has screen clear)\n" );
  4834. -           } else {
  4835. -               Game_detail_flags = DETAIL_DEFAULT;
  4836. -               dc_printf( "Detail flags set highest\n" );
  4837. -           }
  4838. -       }
  4839. -       if ( Dc_arg_type & ARG_INT )    {
  4840. -           Game_detail_flags ^= Dc_arg_int;
  4841. -       }
  4842. -   }
  4843. +   int value;
  4844.  
  4845. -   if ( Dc_help )  {
  4846. -       dc_printf( "Usage: detail [n]\nn is detail bit to toggle.\n" );
  4847. +   if (dc_optional_string_either("help", "--help")) {
  4848. +       dc_printf( "Usage: detail [n]\n");
  4849. +       dc_printf("[n] is detail bit to toggle:\n" );
  4850.         dc_printf( "   1: draw the stars\n" );
  4851.         dc_printf( "   2: draw the nebulas\n" );
  4852.         dc_printf( "   4: draw the motion debris\n" );
  4853. @@ -555,21 +555,38 @@ DCF(detail, "Turns on/off parts of the game for speed testing" )
  4854.         dc_printf( "  64: clear screen background after each frame\n" );
  4855.         dc_printf( " 128: draw hud stuff\n" );
  4856.         dc_printf( " 256: draw fireballs\n" );
  4857. -       dc_printf( " 512: do collision detection\n" );
  4858. +       dc_printf( " 512: do collision detection\n\n" );
  4859. +
  4860. +       dc_printf("No argument will toggle between highest/lowest detail settings\n");
  4861. +       return;
  4862.     }
  4863.  
  4864. -   if ( Dc_status )    {
  4865. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  4866.         dc_printf("Detail flags set to 0x%08x\n", Game_detail_flags);
  4867. -       dc_printf( "   1: draw the stars: %s\n", (Game_detail_flags&1?"on":"off") );
  4868. -       dc_printf( "   2: draw the nebulas: %s\n", (Game_detail_flags&2?"on":"off") );
  4869. -       dc_printf( "   4: draw the motion debris: %s\n", (Game_detail_flags&4?"on":"off")  );
  4870. -       dc_printf( "   8: draw planets: %s\n", (Game_detail_flags&8?"on":"off")  );
  4871. -       dc_printf( "  16: draw models not as blobs: %s\n", (Game_detail_flags&16?"on":"off")  );
  4872. -       dc_printf( "  32: draw lasers not as pixels: %s\n", (Game_detail_flags&32?"on":"off")  );
  4873. -       dc_printf( "  64: clear screen background after each frame: %s\n", (Game_detail_flags&64?"on":"off")  );
  4874. -       dc_printf( " 128: draw hud stuff: %s\n", (Game_detail_flags&128?"on":"off")  );
  4875. -       dc_printf( " 256: draw fireballs: %s\n", (Game_detail_flags&256?"on":"off")  );
  4876. -       dc_printf( " 512: do collision detection: %s\n", (Game_detail_flags&512?"on":"off")  );
  4877. +       dc_printf( "   1: draw the stars: %s\n", ((Game_detail_flags & 1) ? "on" : "off"));
  4878. +       dc_printf( "   2: draw the nebulas: %s\n", ((Game_detail_flags & 2)?"on" : "off"));
  4879. +       dc_printf( "   4: draw the motion debris: %s\n", ((Game_detail_flags & 4) ? "on" : "off"));
  4880. +       dc_printf( "   8: draw planets: %s\n", ((Game_detail_flags & 8) ? "on" : "off"));
  4881. +       dc_printf( "  16: draw models not as blobs: %s\n", ((Game_detail_flags & 16) ? "on" : "off"));
  4882. +       dc_printf( "  32: draw lasers not as pixels: %s\n", ((Game_detail_flags & 32) ? "on" : "off"));
  4883. +       dc_printf( "  64: clear screen background after each frame: %s\n", ((Game_detail_flags & 64) ? "on" : "off"));
  4884. +       dc_printf( " 128: draw hud stuff: %s\n", ((Game_detail_flags & 128) ? "on" : "off"));
  4885. +       dc_printf( " 256: draw fireballs: %s\n", ((Game_detail_flags & 256) ? "on" : "off"));
  4886. +       dc_printf( " 512: do collision detection: %s\n", ((Game_detail_flags & 512) ? "on" : "off"));
  4887. +       return;
  4888. +   }
  4889. +
  4890. +   if (dc_maybe_stuff_int(&value)) {
  4891. +       Game_detail_flags ^= value;
  4892. +  
  4893. +   } else {
  4894. +       if (Game_detail_flags == DETAIL_DEFAULT) {
  4895. +           Game_detail_flags = DETAIL_FLAG_CLEAR;
  4896. +           dc_printf( "Detail flags set lowest (except has screen clear)\n" );
  4897. +       } else {
  4898. +           Game_detail_flags = DETAIL_DEFAULT;
  4899. +           dc_printf( "Detail flags set highest\n" );
  4900. +       }
  4901.     }
  4902.  }
  4903.  #endif
  4904. Index: code/globalincs/vmallocator.h
  4905. ===================================================================
  4906. --- code/globalincs/vmallocator.h   (revision 10462)
  4907. +++ code/globalincs/vmallocator.h   (working copy)
  4908. @@ -8,6 +8,7 @@
  4909.  #include <map>
  4910.  #include <string>
  4911.  #include <queue>
  4912. +#include <deque>
  4913.  
  4914.  #if defined __GNUC__
  4915.  #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
  4916. @@ -127,6 +128,9 @@ class SCP_multimap : public std::multimap<T, U, std::less<T>, SCP_vm_allocator<s
  4917.  template< typename T >
  4918.  class SCP_queue : public std::queue< T, std::deque< T, SCP_vm_allocator< T > > > { };
  4919.  
  4920. +template< typename T >
  4921. +class SCP_deque : public std::deque< T, SCP_vm_allocator< T > > { };
  4922. +
  4923.  template <class T1, class T2>
  4924.  bool operator==(const SCP_vm_allocator<T1>&, const SCP_vm_allocator<T2>&) throw()
  4925.  {
  4926. Index: code/globalincs/windebug.cpp
  4927. ===================================================================
  4928. --- code/globalincs/windebug.cpp    (revision 10462)
  4929. +++ code/globalincs/windebug.cpp    (working copy)
  4930. @@ -33,6 +33,7 @@
  4931.  #include "cmdline/cmdline.h"
  4932.  #include "parse/lua.h"
  4933.  #include "parse/parselo.h"
  4934. +#include "debugconsole/console.h"
  4935.  
  4936.  #if defined( SHOW_CALL_STACK ) && defined( PDB_DEBUGGING )
  4937.  #  include "globalincs/mspdb_callstack.h"
  4938. @@ -1522,7 +1523,7 @@ void windebug_memwatch_init()
  4939.  #endif
  4940.  
  4941.  int Watch_malloc = 0;
  4942. -DCF_BOOL(watch_malloc, Watch_malloc )
  4943. +DCF_BOOL(watch_malloc, Watch_malloc );
  4944.  
  4945.  // Returns 0 if not enough RAM.
  4946.  int vm_init(int min_heap_size)
  4947. Index: code/graphics/2d.cpp
  4948. ===================================================================
  4949. --- code/graphics/2d.cpp    (revision 10462)
  4950. +++ code/graphics/2d.cpp    (working copy)
  4951. @@ -31,6 +31,7 @@
  4952.  #include "parse/scripting.h"
  4953.  #include "gamesequence/gamesequence.h" //WMC - for scripting hooks in gr_flip()
  4954.  #include "io/keycontrol.h" // m!m
  4955. +#include "debugconsole/console.h"
  4956.  
  4957.  
  4958.  #if defined(SCP_UNIX) && !defined(__APPLE__)
  4959. @@ -266,12 +267,9 @@ DCF(clear_color, "set clear color r, g, b")
  4960.  {
  4961.     ubyte r, g, b;
  4962.  
  4963. -   dc_get_arg(ARG_UBYTE);
  4964. -   r = Dc_arg_ubyte;
  4965. -   dc_get_arg(ARG_UBYTE);
  4966. -   g = Dc_arg_ubyte;
  4967. -   dc_get_arg(ARG_UBYTE);
  4968. -   b = Dc_arg_ubyte;
  4969. +   dc_stuff_ubyte(&r);
  4970. +   dc_stuff_ubyte(&g);
  4971. +   dc_stuff_ubyte(&b);
  4972.  
  4973.     // set the color
  4974.     gr_set_clear_color(r, g, b);
  4975. Index: code/graphics/gropengl.cpp
  4976. ===================================================================
  4977. --- code/graphics/gropengl.cpp  (revision 10462)
  4978. +++ code/graphics/gropengl.cpp  (working copy)
  4979. @@ -22,6 +22,7 @@
  4980.  #include "io/timer.h"
  4981.  #include "ddsutils/ddsutils.h"
  4982.  #include "model/model.h"
  4983. +#include "debugconsole/console.h"
  4984.  #include "debugconsole/timerbar.h"
  4985.  #include "graphics/gropenglbmpman.h"
  4986.  #include "graphics/gropengllight.h"
  4987. @@ -2078,56 +2079,61 @@ bool gr_opengl_init()
  4988.  
  4989.  DCF(ogl_minimize, "Minimizes opengl")
  4990.  {
  4991. +   bool minimize_ogl = false;
  4992. +
  4993.     if ( gr_screen.mode != GR_OPENGL ) {
  4994.         dc_printf("Command only available in OpenGL mode.\n");
  4995.         return;
  4996.     }
  4997.  
  4998. -   if (Dc_command) {
  4999. -       dc_get_arg(ARG_TRUE);
  5000. -
  5001. -       if ( Dc_arg_type & ARG_TRUE ) {
  5002. -           opengl_minimize();
  5003. -       }
  5004. +   if (dc_optional_string_either("help", "--help")) {
  5005. +       dc_printf("[bool] If true is passed, then the OpenGL window will minimize.\n");
  5006. +       return;
  5007.     }
  5008. +   dc_stuff_boolean(&minimize_ogl);
  5009.  
  5010. -   if (Dc_help)
  5011. -       dc_printf("If set to true then the OpenGL window will minimize.\n");
  5012. +   if (minimize_ogl) {
  5013. +       opengl_minimize();
  5014. +   }
  5015.  }
  5016.  
  5017.  DCF(ogl_anisotropy, "toggles anisotropic filtering")
  5018.  {
  5019. +   bool process = true;
  5020. +   int value;
  5021. +
  5022.     if ( gr_screen.mode != GR_OPENGL ) {
  5023.         dc_printf("Can only set anisotropic filter in OpenGL mode.\n");
  5024.         return;
  5025.     }
  5026.  
  5027. -   if ( Dc_command && !Is_Extension_Enabled(OGL_EXT_TEXTURE_FILTER_ANISOTROPIC) ) {
  5028. -       dc_printf("Error: Anisotropic filter is not settable!\n");
  5029. +   if (dc_optional_string_either("help", "--help")) {
  5030. +       dc_printf("Sets OpenGL anisotropic filtering level.\n");
  5031. +       dc_printf("GL_anisotropy [int]  Valid values are 0 to %i. 0 turns off anisotropic filtering.\n", (int)opengl_get_max_anisotropy());
  5032. +       process = false;
  5033. +   }
  5034. +
  5035. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  5036. +       dc_printf("Current anisotropic filter value is %i\n", (int)GL_anisotropy);
  5037. +       process = false;
  5038. +   }
  5039. +
  5040. +   if (!process) {
  5041.         return;
  5042.     }
  5043.  
  5044. -   if ( Dc_command ) {
  5045. -       dc_get_arg(ARG_INT | ARG_NONE);
  5046. +   if ( !Is_Extension_Enabled(OGL_EXT_TEXTURE_FILTER_ANISOTROPIC) ) {
  5047. +       dc_printf("Error: Anisotropic filter is not settable!\n");
  5048. +       return;
  5049. +   }
  5050.  
  5051. -       if ( Dc_arg_type & ARG_NONE ) {
  5052. +   if (!dc_maybe_stuff_int(&value)) {
  5053. +       // No arg passed, set to default
  5054.             GL_anisotropy = 1.0f;
  5055.         //  opengl_set_anisotropy();
  5056.             dc_printf("Anisotropic filter value reset to default level.\n");
  5057. -       }
  5058. -
  5059. -       if ( Dc_arg_type & ARG_INT ) {
  5060. -           GL_anisotropy = (GLfloat)Dc_arg_float;
  5061. +   } else {
  5062. +       GL_anisotropy = (GLfloat)value;
  5063.         //  opengl_set_anisotropy( (float)Dc_arg_float );
  5064. -       }
  5065. -   }
  5066. -
  5067. -   if ( Dc_status ) {
  5068. -       dc_printf("Current anisotropic filter value is %i\n", (int)GL_anisotropy);
  5069. -   }
  5070. -
  5071. -   if (Dc_help) {
  5072. -       dc_printf("Sets OpenGL anisotropic filtering level.\n");
  5073. -       dc_printf("Valid values are 1 to %i, or 0 to turn off.\n", (int)opengl_get_max_anisotropy());
  5074.     }
  5075.  }
  5076. Index: code/hud/hudlock.cpp
  5077. ===================================================================
  5078. --- code/hud/hudlock.cpp    (revision 10462)
  5079. +++ code/hud/hudlock.cpp    (working copy)
  5080. @@ -26,6 +26,7 @@
  5081.  #include "mission/missionparse.h"
  5082.  #include "iff_defs/iff_defs.h"
  5083.  #include "network/multi.h"
  5084. +#include "debugconsole/console.h"
  5085.  
  5086.  
  5087.  vec3d lock_world_pos;
  5088. @@ -333,7 +334,7 @@ int hud_lock_has_homing_point()
  5089.  }
  5090.  
  5091.  int Nebula_sec_range = 0;
  5092. -DCF_BOOL(nebula_sec_range, Nebula_sec_range)
  5093. +DCF_BOOL(nebula_sec_range, Nebula_sec_range);
  5094.  
  5095.  int hud_lock_world_pos_in_range(vec3d *target_world_pos, vec3d *vec_to_target)
  5096.  {
  5097. Index: code/io/joy.cpp
  5098. ===================================================================
  5099. --- code/io/joy.cpp (revision 10462)
  5100. +++ code/io/joy.cpp (working copy)
  5101. @@ -21,6 +21,7 @@
  5102.  #include "io/joy_ff.h"
  5103.  #include "directx/vdinput.h"
  5104.  #include "osapi/osapi.h"
  5105. +#include "debugconsole/console.h"
  5106.  
  5107.  
  5108.  
  5109. @@ -300,45 +301,51 @@ void joy_get_caps(int max)
  5110.  int joy_get_scaled_reading(int raw, int axn);
  5111.  int joy_get_unscaled_reading(int raw, int axn);
  5112.  
  5113. -DCF(joytest, "Test joystick")
  5114. +DCF(joytest, "Test joystick (X, Y)")
  5115.  {
  5116. -   if (Dc_command) {
  5117. -       while (!keyd_pressed[KEY_ESC]) {
  5118. -           int x, y, axis[JOY_NUM_AXES];
  5119. +   if (dc_optional_string_either("help", "--help")) {
  5120. +       dc_printf("Outputs the scaled reading of the joystick to a seperate window.\n");
  5121. +       dc_printf("Press ESC to end the test\n");
  5122. +   }
  5123.  
  5124. -           if (joy_num_sticks < 1)
  5125. -               return;
  5126. +   while (!keyd_pressed[KEY_ESC]) {
  5127. +       int x, y, axis[JOY_NUM_AXES];
  5128.  
  5129. -           joystick_read_raw_axis(JOY_NUM_AXES, axis);
  5130. +       if (joy_num_sticks < 1)
  5131. +           return;
  5132.  
  5133. -           x = joy_get_scaled_reading(axis[0], 0);
  5134. -           y = joy_get_scaled_reading(axis[1], 1);
  5135. +       joystick_read_raw_axis(JOY_NUM_AXES, axis);
  5136.  
  5137. -           mprintf(("X=%5d Y=%5d  Calibrated X=%6d Y=%6d\n", axis[0], axis[1], x, y));
  5138. -           Sleep(100);
  5139. -       }
  5140. +       x = joy_get_scaled_reading(axis[0], 0);
  5141. +       y = joy_get_scaled_reading(axis[1], 1);
  5142. +
  5143. +       mprintf(("X=%5d Y=%5d  Calibrated X=%6d Y=%6d\n", axis[0], axis[1], x, y));
  5144. +       Sleep(100);
  5145.     }
  5146.  }
  5147.  
  5148. -DCF(joytest2, "Test joystick (extended)")
  5149. +DCF(joytest2, "Test joystick (X, Y, Z, Rx, Ry, Rz)")
  5150.  {
  5151. -   if (Dc_command) {
  5152. -       while (!keyd_pressed[KEY_ESC]) {
  5153. -           int x, y, z, r, axis[JOY_NUM_AXES];
  5154. +   if (dc_optional_string_either("help", "--help")) {
  5155. +       dc_printf("Outputs the scaled reading of the joystick to a seperate window.\n");
  5156. +       dc_printf("Press ESC to end the test\n");
  5157. +   }
  5158.  
  5159. -           if (joy_num_sticks < 1)
  5160. -               return;
  5161. +   while (!keyd_pressed[KEY_ESC]) {
  5162. +       int x, y, z, r, axis[JOY_NUM_AXES];
  5163.  
  5164. -           joystick_read_raw_axis(JOY_NUM_AXES, axis);
  5165. +       if (joy_num_sticks < 1)
  5166. +           return;
  5167.  
  5168. -           x = joy_get_scaled_reading(axis[0], 0);
  5169. -           y = joy_get_scaled_reading(axis[1], 1);
  5170. -           z = joy_get_unscaled_reading(axis[2], 2);
  5171. -           r = joy_get_scaled_reading(axis[3], 3);
  5172. +       joystick_read_raw_axis(JOY_NUM_AXES, axis);
  5173.  
  5174. -           mprintf(("X=%5d Y=%5d Z=%5d Rx=%5d Ry=%5d Rz=%5d Cal X=%6d Y=%6d Z=%6d R=%6d\n", axis[0], axis[1], axis[2], axis[3], axis[4], axis[5], x, y, z, r));
  5175. -           Sleep(100);
  5176. -       }
  5177. +       x = joy_get_scaled_reading(axis[0], 0);
  5178. +       y = joy_get_scaled_reading(axis[1], 1);
  5179. +       z = joy_get_unscaled_reading(axis[2], 2);
  5180. +       r = joy_get_scaled_reading(axis[3], 3);
  5181. +
  5182. +       mprintf(("X=%5d Y=%5d Z=%5d Rx=%5d Ry=%5d Rz=%5d Cal X=%6d Y=%6d Z=%6d R=%6d\n", axis[0], axis[1], axis[2], axis[3], axis[4], axis[5], x, y, z, r));
  5183. +       Sleep(100);
  5184.     }
  5185.  }
  5186.  
  5187. Index: code/lighting/lighting.cpp
  5188. ===================================================================
  5189. --- code/lighting/lighting.cpp  (revision 10462)
  5190. +++ code/lighting/lighting.cpp  (working copy)
  5191. @@ -15,6 +15,7 @@
  5192.  #include "globalincs/systemvars.h"
  5193.  #include "graphics/2d.h"
  5194.  #include "cmdline/cmdline.h"
  5195. +#include "debugconsole/console.h"
  5196.  
  5197.  
  5198.  
  5199. @@ -62,52 +63,11 @@ int Lighting_flag = 1;
  5200.  
  5201.  DCF(light,"Changes lighting parameters")
  5202.  {
  5203. -   if ( Dc_command )   {
  5204. -       dc_get_arg(ARG_STRING);
  5205. -       if ( !strcmp( Dc_arg, "ambient" ))  {
  5206. -           dc_get_arg(ARG_FLOAT);
  5207. -           if ( (Dc_arg_float < 0.0f) || (Dc_arg_float > 1.0f) )   {
  5208. -               Dc_help = 1;
  5209. -           } else {
  5210. -               Ambient_light = Dc_arg_float;
  5211. -           }
  5212. -       } else if ( !strcmp( Dc_arg, "reflect" ))   {
  5213. -           dc_get_arg(ARG_FLOAT);
  5214. -           if ( (Dc_arg_float < 0.0f) || (Dc_arg_float > 1.0f) )   {
  5215. -               Dc_help = 1;
  5216. -           } else {
  5217. -               Reflective_light = Dc_arg_float;
  5218. -           }
  5219. -       } else if ( !strcmp( Dc_arg, "default" ))   {
  5220. -           Lighting_mode = LM_BRIGHTEN;
  5221. -           Ambient_light = AMBIENT_LIGHT_DEFAULT;
  5222. -           Reflective_light = REFLECTIVE_LIGHT_DEFAULT;
  5223. -           Lighting_flag = 0;
  5224. -       } else if ( !strcmp( Dc_arg, "mode" ))  {
  5225. -           dc_get_arg(ARG_STRING);
  5226. -           if ( !strcmp(Dc_arg, "light") ) {
  5227. -               Lighting_mode = LM_BRIGHTEN;
  5228. -           } else if ( !strcmp(Dc_arg, "darken"))  {
  5229. -               Lighting_mode = LM_DARKEN;
  5230. -           } else {
  5231. -               Dc_help = 1;
  5232. -           }
  5233. -       } else if ( !strcmp( Dc_arg, "dynamic" ))   {
  5234. -           dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);       
  5235. -           if ( Dc_arg_type & ARG_TRUE )   Lighting_flag = 1
  5236. -           else if ( Dc_arg_type & ARG_FALSE ) Lighting_flag = 0
  5237. -           else if ( Dc_arg_type & ARG_NONE ) Lighting_flag ^= 1
  5238. -       } else if ( !strcmp( Dc_arg, "on" ) )   {
  5239. -           Lighting_off = 0;
  5240. -       } else if ( !strcmp( Dc_arg, "off" ) )  {
  5241. -           Lighting_off = 1;
  5242. -       } else {
  5243. -           // print usage, not stats
  5244. -           Dc_help = 1;
  5245. -       }
  5246. -   }
  5247. +   SCP_string arg_str;
  5248. +   float val_f;
  5249. +   bool  val_b;
  5250.  
  5251. -   if ( Dc_help )  {
  5252. +   if (dc_optional_string_either("help", "--help")) {
  5253.         dc_printf( "Usage: light keyword\nWhere keyword can be in the following forms:\n" );
  5254.         dc_printf( "light on|off          Turns all lighting on/off\n" );
  5255.         dc_printf( "light default         Resets lighting to all default values\n" );
  5256. @@ -117,18 +77,70 @@ DCF(light,"Changes lighting parameters")
  5257.         dc_printf( "light mode [light|darken]   Changes the lighting mode.\n" );
  5258.         dc_printf( "   Where 'light' means the global light adds light.\n");
  5259.         dc_printf( "   and 'darken' means the global light subtracts light.\n");
  5260. -       Dc_status = 0;  // don't print status if help is printed.  Too messy.
  5261. +       return;
  5262.     }
  5263.  
  5264. -   if ( Dc_status )    {
  5265. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  5266.         dc_printf( "Ambient light is set to %.2f\n", Ambient_light );
  5267.         dc_printf( "Reflective light is set to %.2f\n", Reflective_light );
  5268.         dc_printf( "Dynamic lighting is: %s\n", (Lighting_flag?"on":"off") );
  5269. -       switch( Lighting_mode ) {
  5270. -       case LM_BRIGHTEN:   dc_printf( "Lighting mode is: light\n" ); break;
  5271. -       case LM_DARKEN:   dc_printf( "Lighting mode is: darken\n" ); break;
  5272. -       default: dc_printf( "Lighting mode is: UNKNOWN\n" ); break;
  5273. +       switch( Lighting_mode ) {
  5274. +       case LM_BRIGHTEN:
  5275. +           dc_printf( "Lighting mode is: light\n" );
  5276. +           break;
  5277. +       case LM_DARKEN:
  5278. +           dc_printf( "Lighting mode is: darken\n" );
  5279. +           break;
  5280. +       default:
  5281. +           dc_printf( "Lighting mode is: UNKNOWN\n" );
  5282. +       }
  5283. +       return;
  5284. +   }
  5285. +  
  5286. +   if (dc_optional_string("ambient")) {
  5287. +       dc_stuff_float(&val_f);
  5288. +       if ((val_f < 0.0f) || (val_f > 1.0f)) {
  5289. +           dc_printf(" Error: ambient value must be between 0.0 and 1.0\n");
  5290. +       } else {
  5291. +           Ambient_light = val_f;
  5292.         }
  5293. +  
  5294. +   } else if (dc_optional_string("reflect")) {
  5295. +       dc_stuff_float(&val_f);
  5296. +       if ( (val_f < 0.0f) || (val_f > 1.0f))  {
  5297. +           dc_printf(" Error: reflect value mus be between 0.0 and 1.0\n");
  5298. +       } else {
  5299. +           Reflective_light = val_f;
  5300. +       }
  5301. +  
  5302. +   } else if (dc_optional_string("default")) {
  5303. +       Lighting_mode = LM_BRIGHTEN;
  5304. +       Ambient_light = AMBIENT_LIGHT_DEFAULT;
  5305. +       Reflective_light = REFLECTIVE_LIGHT_DEFAULT;
  5306. +       Lighting_flag = 0;
  5307. +  
  5308. +   } else if (dc_optional_string("mode")) {
  5309. +       dc_stuff_string_white(arg_str);
  5310. +       if (arg_str == "light") {
  5311. +           Lighting_mode = LM_BRIGHTEN;
  5312. +  
  5313. +       } else if (arg_str == "darken") {
  5314. +           Lighting_mode = LM_DARKEN;
  5315. +      
  5316. +       } else {
  5317. +           dc_printf(" Error: unknown light mode: '%s'\n", arg_str);
  5318. +       }
  5319. +  
  5320. +   } else if (dc_optional_string("dynamic")) {
  5321. +       dc_stuff_boolean(&val_b);
  5322. +       Lighting_flag = val_b;
  5323. +
  5324. +   } else if(dc_maybe_stuff_boolean(&Lighting_off)) {
  5325. +       Lighting_off = !Lighting_off;
  5326. +
  5327. +   } else {
  5328. +       dc_stuff_string_white(arg_str);
  5329. +       dc_printf("Error: Unknown argument '%s'\n");
  5330.     }
  5331.  }
  5332.  
  5333. Index: code/menuui/playermenu.cpp
  5334. ===================================================================
  5335. --- code/menuui/playermenu.cpp  (revision 10462)
  5336. +++ code/menuui/playermenu.cpp  (working copy)
  5337. @@ -31,6 +31,7 @@
  5338.  #include "parse/parselo.h"
  5339.  #include "cfile/cfile.h"
  5340.  #include "network/multi.h"
  5341. +#include "debugconsole/console.h"
  5342.  
  5343.  
  5344.  // --------------------------------------------------------------------------------------------------------
  5345. @@ -1236,39 +1237,37 @@ void player_select_cancel_create()
  5346.  
  5347.  DCF(bastion,"Sets the player to be on the bastion (or any other main hall)")
  5348.  {
  5349. -   if(gameseq_get_state() != GS_STATE_INITIAL_PLAYER_SELECT) {
  5350. -       dc_printf("This command can only be run in the initial player select screen.\n");
  5351. +   int idx;
  5352. +
  5353. +   if (gameseq_get_state() != GS_STATE_INITIAL_PLAYER_SELECT) {
  5354. +       dc_printf("This command can only be run while the in the initial player select screen. \n");
  5355.         return;
  5356.     }
  5357.  
  5358. -   if (Dc_command) {
  5359. -       dc_get_arg(ARG_INT | ARG_NONE);
  5360. -
  5361. -       if (Dc_arg_type & ARG_INT) {
  5362. -           int idx = Dc_arg_int;
  5363. -
  5364. -           Assert(Main_hall_defines.at(gr_screen.res).size() < INT_MAX);
  5365. -           if (idx < 0 || idx >= (int) Main_hall_defines.at(gr_screen.res).size()) {
  5366. -               dc_printf("Main hall index out of range\n");
  5367. -           } else {
  5368. -               main_hall_get_name(Player_select_force_main_hall, idx);
  5369. -               dc_printf("Player is now on main hall '%d'\n", Player_select_force_main_hall.c_str());
  5370. -           }
  5371. -       } else {
  5372. -           Player_select_force_main_hall = "1";
  5373. -           dc_printf("Player is now on the Bastion... hopefully\n");
  5374. -       }
  5375. -       Dc_status = 0;
  5376. +   if (dc_optional_string_either("help", "--help")) {
  5377. +       dc_printf("Usage: bastion [index]\n");
  5378. +       dc_printf("    [index] -- optional main hall index; if not supplied, defaults to 1\n");
  5379. +       return;
  5380.     }
  5381.  
  5382. -   if (Dc_help) {
  5383. -       dc_printf("Usage: bastion [index]\n");
  5384. -       dc_printf("       [index] -- optional main hall index; if not supplied, defaults to 1\n");
  5385. -       Dc_status = 0;
  5386. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  5387. +       dc_printf("Player is on main hall '%s'\n", Player_select_force_main_hall.c_str());
  5388. +       return;
  5389.     }
  5390.  
  5391. -   if (Dc_status) {
  5392. -       dc_printf("There is no current main hall, as the player has not been selected yet!\n");
  5393. +   if (dc_maybe_stuff_int(&idx)) {
  5394. +       Assert(Main_hall_defines.at(gr_screen.res).size() < INT_MAX);
  5395. +       if (idx < 0 || idx >= (int) Main_hall_defines.at(gr_screen.res).size()) {
  5396. +           dc_printf("Main hall index out of range\n");
  5397. +       } else {
  5398. +           main_hall_get_name(Player_select_force_main_hall, idx);
  5399. +           dc_printf("Player is now on main hall '%d'\n", Player_select_force_main_hall.c_str());
  5400. +       }
  5401. +  
  5402. +   } else {
  5403. +       // No argument passed
  5404. +       Player_select_force_main_hall = "1";
  5405. +       dc_printf("Player is now on the Bastion... hopefully\n");
  5406.     }
  5407.  }
  5408.  
  5409. Index: code/mission/missiongoals.cpp
  5410. ===================================================================
  5411. --- code/mission/missiongoals.cpp   (revision 10462)
  5412. +++ code/mission/missiongoals.cpp   (working copy)
  5413. @@ -13,6 +13,7 @@
  5414.  #include "mission/missiongoals.h"
  5415.  #include "mission/missionlog.h"
  5416.  #include "missionui/missionscreencommon.h"
  5417. +#include "debugconsole/console.h"
  5418.  #include "freespace2/freespace.h"
  5419.  #include "gamesequence/gamesequence.h"
  5420.  #include "hud/hud.h"
  5421. @@ -1262,77 +1263,101 @@ void mission_goal_mark_events_complete()
  5422.  }
  5423.  
  5424.  // some debug console functions to help list and change the status of mission goals
  5425. -DCF(show_mission_goals,"List and change the status of mission goals")
  5426. +DCF(show_mission_goals,"Lists the status of mission goals")
  5427.  {
  5428.     int i, type;
  5429.  
  5430. -   if (Dc_command)
  5431. -       Dc_status = 1;
  5432. -
  5433. -   if (Dc_help) {
  5434. +   if (dc_optional_string_either("help", "--help")) {
  5435.         dc_printf("Usage: show_mission_goals\n\nList all mission goals and their current status.\n");
  5436. -       Dc_status = 0;
  5437. -   }
  5438. -
  5439. -   if (Dc_status) {
  5440. -       for (i=0; i<Num_goals; i++) {
  5441. -           type = Mission_goals[i].type & GOAL_TYPE_MASK;
  5442. -           dc_printf("%2d. %32s(%10s) -- ", i, Mission_goals[i].name, Goal_type_text(type));
  5443. -           if ( Mission_goals[i].satisfied == GOAL_COMPLETE )
  5444. -               dc_printf("satisfied.\n");
  5445. -           else if ( Mission_goals[i].satisfied == GOAL_INCOMPLETE )
  5446. -               dc_printf("not satisfied\n");
  5447. -           else if ( Mission_goals[i].satisfied == GOAL_FAILED )
  5448. -               dc_printf("failed\n");
  5449. -           else
  5450. -               dc_printf("\t[unknown goal status].\n");
  5451. -       }
  5452. +       return;
  5453. +   }
  5454. +
  5455. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  5456. +       // Don't do anything, but advance the parser past the flag
  5457. +   }
  5458. +
  5459. +   for (i=0; i<Num_goals; i++) {
  5460. +       type = Mission_goals[i].type & GOAL_TYPE_MASK;
  5461. +       dc_printf("%2d. %32s(%10s) -- ", i, Mission_goals[i].name, Goal_type_text(type));
  5462. +       if ( Mission_goals[i].satisfied == GOAL_COMPLETE )
  5463. +           dc_printf("satisfied.\n");
  5464. +       else if ( Mission_goals[i].satisfied == GOAL_INCOMPLETE )
  5465. +           dc_printf("unsatisfied\n");
  5466. +       else if ( Mission_goals[i].satisfied == GOAL_FAILED )
  5467. +           dc_printf("failed\n");
  5468. +       else
  5469. +           dc_printf("Warning! Mission goal %i is in an invalid state! (value: %i)", i, Mission_goals[i].satisfied);
  5470.     }
  5471. +  
  5472.  }
  5473.  
  5474.  //XSTR:OFF
  5475. -DCF(change_mission_goal, "Change the mission goal")
  5476. +DCF(change_mission_goal, "Changes the mission goal status")
  5477.  {
  5478.     int num;
  5479. +   bool val_b;
  5480. +   char *string;
  5481.  
  5482. -   if ( Dc_command ) {
  5483. -       dc_get_arg(ARG_INT);
  5484. -       if ( Dc_arg_int >= Num_goals ) {
  5485. -           dc_printf ("First parameter must be a valid goal number.\n");
  5486. -           return;
  5487. -       }
  5488. +   if (dc_optional_string_either("help", "--help")) {
  5489. +       dc_printf("Usage: change_mission_goal <goal_num> [status]\n");
  5490. +       dc_printf("<goal_num> --  Integer number of goal to change.  See show_mission_goals\n");
  5491. +       dc_printf("[status]   --  Goal status to change to.\n\n");
  5492.  
  5493. -       num = Dc_arg_int;
  5494. -       dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_STRING);
  5495. -       if ( Dc_arg_type & ARG_TRUE )
  5496. -           Mission_goals[num].satisfied = GOAL_COMPLETE;
  5497. -       else if ( Dc_arg_type & ARG_FALSE )
  5498. -           Mission_goals[num].satisfied = GOAL_FAILED;
  5499. -       else if ( Dc_arg_type & ARG_NONE )
  5500. -           Mission_goals[num].satisfied = GOAL_INCOMPLETE;
  5501. -       else if ( Dc_arg_type & ARG_STRING) {
  5502. -           if ( !stricmp(Dc_arg, "satisfied") )
  5503. -               Mission_goals[num].satisfied = GOAL_COMPLETE;
  5504. -           else if ( !stricmp( Dc_arg, "failed") )
  5505. -               Mission_goals[num].satisfied = GOAL_FAILED;
  5506. -           else if ( !stricmp( Dc_arg, "unknown") )
  5507. -               Mission_goals[num].satisfied = GOAL_INCOMPLETE;
  5508. -           else
  5509. -               dc_printf("Unknown status %s.  Use 'satisfied', 'failed', or 'unknown'\n", Dc_arg);
  5510. -       }
  5511. +       dc_printf("The optional [status] field may be either a bool type or a string.\n");
  5512. +       dc_printf("\ttrue  -- Goal status set to 'complete'\n");
  5513. +       dc_printf("\tfalse -- Goal status set to 'failed'\n\n");
  5514. +
  5515. +       dc_printf("A string value of 'satisfied', 'failed', or 'unknown' will set the goal status to the respective state.\n");
  5516. +       dc_printf("If [status] is not given, then the goal status will be set to 'unknown'");
  5517. +
  5518. +       dc_printf("Examples:\n");
  5519. +       dc_printf("\t'change_mission_goal 1 true'  makes goal 1 as successful.\n");
  5520. +       dc_printf("\t'change_mission_goal 2'       marks goal 2 as unknown/incomplete\n");
  5521. +       dc_printf("\t'change_mission_goal 0 satisfied'    marks goal 0 as satisfied\n");
  5522. +       return;
  5523.     }
  5524.  
  5525. -   if ( Dc_help ) {
  5526. -       dc_printf("Usage: change_mission_goal <goal_num> <status>\n");
  5527. -       dc_printf("<goal_num> --  Integer number of goal to change.  See show_mission_goals\n");
  5528. -       dc_printf("<status>   --  [bool] where a true value makes the goal satisfied,\n");
  5529. -       dc_printf("               a false value makes the goal failed.\n");
  5530. -       dc_printf("The <status> field may also be one of 'satisfied', 'failed', or 'unknown'\n");
  5531. -       dc_printf("\nExamples:\n\n'change_mission_goal 1 true' makes goal 1 successful.\n");
  5532. -       dc_printf("'change_mission_goal 2' marks goal 2 not complete\n");
  5533. -       dc_printf("'change_mission_goal 0 satisfied' marks goal 0 as satisfied\n");
  5534. -       Dc_status = 0;
  5535. +   dc_stuff_int(&num);
  5536. +   if ( num >= Num_goals ) {
  5537. +       dc_printf (" Error: Invalid value for <goal_num>. Valid values: 0 - %i\n", Num_goals);
  5538. +       return;
  5539. +   }
  5540. +
  5541. +   if (dc_optional_string("satisfied")) {
  5542. +       Mission_goals[num].satisfied = GOAL_COMPLETE;
  5543. +
  5544. +   } else if (dc_optional_string("failed")) {
  5545. +       Mission_goals[num].satisfied = GOAL_FAILED;
  5546. +
  5547. +   } else if (dc_optional_string("unsatisfied")) {
  5548. +       Mission_goals[num].satisfied = GOAL_INCOMPLETE;
  5549. +
  5550. +   } else if (dc_maybe_stuff_boolean(&val_b)) {
  5551. +       val_b ? Mission_goals[num].satisfied = GOAL_COMPLETE : Mission_goals[num].satisfied = GOAL_FAILED;
  5552. +
  5553. +   } else {
  5554. +       // No argument given
  5555. +       Mission_goals[num].satisfied = GOAL_INCOMPLETE;
  5556. +   }
  5557. +
  5558. +   switch(Mission_goals[num].satisfied) {
  5559. +   case GOAL_COMPLETE:
  5560. +       string = "satisfied";
  5561. +       break;
  5562. +
  5563. +   case GOAL_FAILED:
  5564. +       string = "failed";
  5565. +       break;
  5566. +
  5567. +   case GOAL_INCOMPLETE:
  5568. +       string = "unsatisfied";
  5569. +       break;
  5570. +
  5571. +   default:
  5572. +       dc_printf("Warning! Mission goal %i is in an invalid state! (value: %i)", num, Mission_goals[num].satisfied);
  5573. +       return;
  5574.     }
  5575. +   dc_printf("Mission goal %i set to '%s'\n", num, string);
  5576.  }
  5577.  //XSTR:ON
  5578.  
  5579. Index: code/model/modelinterp.cpp
  5580. ===================================================================
  5581. --- code/model/modelinterp.cpp  (revision 10462)
  5582. +++ code/model/modelinterp.cpp  (working copy)
  5583. @@ -33,6 +33,7 @@
  5584.  #include "graphics/gropengllight.h"
  5585.  #include "ship/shipfx.h"
  5586.  #include "gamesequence/gamesequence.h"
  5587. +#include "debugconsole/console.h"
  5588.  
  5589.  #include <limits.h>
  5590.  
  5591. @@ -1942,19 +1943,20 @@ float Interp_depth_scale = 1500.0f;
  5592.  
  5593.  DCF(model_darkening,"Makes models darker with distance")
  5594.  {
  5595. -   if ( Dc_command )   {
  5596. -       dc_get_arg(ARG_FLOAT);
  5597. -       Interp_depth_scale = Dc_arg_float;
  5598. -   }
  5599. -
  5600. -   if ( Dc_help )  {
  5601. -       dc_printf( "Usage: model_darkening float\n" );
  5602. -       Dc_status = 0;  // don't print status if help is printed.  Too messy.
  5603. +   if (dc_optional_string_either("help", "--help")) {
  5604. +       dc_printf( "Usage: model_darkening <float>\n" );
  5605. +       dc_printf("Sets the distance at which to start blacking out models (namely asteroids).\n");
  5606. +       return;
  5607.     }
  5608.  
  5609. -   if ( Dc_status )    {
  5610. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  5611.         dc_printf( "model_darkening = %.1f\n", Interp_depth_scale );
  5612. +       return;
  5613.     }
  5614. +
  5615. +   dc_stuff_float(&Interp_depth_scale);
  5616. +
  5617. +   dc_printf("model_darkening set to %.1f\n", Interp_depth_scale);
  5618.  }
  5619.  
  5620.  void model_render(int model_num, matrix *orient, vec3d * pos, uint flags, int objnum, int lighting_skip, int *replacement_textures)
  5621. @@ -2117,8 +2119,13 @@ float model_find_closest_point( vec3d *outpnt, int model_num, int submodel_num,
  5622.  }
  5623.  
  5624.  int tiling = 1;
  5625. -DCF(tiling, "")
  5626. +DCF(tiling, "Toggles rendering of tiled textures (default is on)")
  5627.  {
  5628. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  5629. +       dc_printf("Tiled textures are %s", tiling ? "ON" : "OFF");
  5630. +       return;
  5631. +   }
  5632. +
  5633.     tiling = !tiling;
  5634.     if(tiling){
  5635.         dc_printf("Tiled textures\n");
  5636. Index: code/nebula/neb.cpp
  5637. ===================================================================
  5638. --- code/nebula/neb.cpp (revision 10462)
  5639. +++ code/nebula/neb.cpp (working copy)
  5640. @@ -24,6 +24,7 @@
  5641.  #include "mission/missionparse.h"
  5642.  #include "ship/ship.h"
  5643.  #include "cmdline/cmdline.h"
  5644. +#include "debugconsole/console.h"
  5645.  
  5646.  
  5647.  // --------------------------------------------------------------------------------------------------------
  5648. @@ -503,7 +504,7 @@ void neb2_page_in()
  5649.  
  5650.  // should we not render this object because its obscured by the nebula?
  5651.  int neb_skip_opt = 1;
  5652. -DCF(neb_skip, "")
  5653. +DCF(neb_skip, "Toggles culling of objects obscured by nebula")
  5654.  {
  5655.     neb_skip_opt = !neb_skip_opt;
  5656.     if (neb_skip_opt) {
  5657. @@ -896,12 +897,14 @@ void neb2_regen()
  5658.     }
  5659.  }
  5660.  
  5661. +/*
  5662. + * TODO: remove this
  5663.  float max_area = 100000000.0f;
  5664.  DCF(max_area, "")
  5665.  {
  5666. -   dc_get_arg(ARG_FLOAT);
  5667. -   max_area = Dc_arg_float;
  5668. +   dc_stuff_float(&max_area);
  5669.  }
  5670. +*/
  5671.  
  5672.  float g3_draw_rotated_bitmap_area(vertex *pnt, float angle, float rad, uint tmap_flags, float area);
  5673.  int neb_mode = 1;
  5674. @@ -1443,7 +1446,7 @@ int neb2_get_bitmap()
  5675.  }
  5676.  
  5677.  // nebula DCF functions ------------------------------------------------------
  5678. -
  5679. +// TODO: With the new debug parser in place, most of these sub-commands can now be handled by neb2. This should clear up the DCF list a bit
  5680.  DCF(neb2, "list nebula console commands")
  5681.  {     
  5682.  // dc_printf("neb2_fog <X> <float> <float>  : set near and far fog planes for ship type X\n");
  5683. @@ -1463,7 +1466,7 @@ DCF(neb2, "list nebula console commands")
  5684.     dc_printf("neb2_cinner      : poof cube inner dimension\n");
  5685.     dc_printf("neb2_couter      : poof cube outer dimension\n");
  5686.     dc_printf("neb2_jitter      : poof jitter\n");
  5687. -   dc_printf("neb2_mode        : switch between no nebula, polygon background, pof background, lame or HTL rendering (0, 1, 2, 3 and 4 respectively)\n\n");   
  5688. +   dc_printf("neb2_mode        : switch between no nebula, polygon background, pof background, lame, or HTL rendering (0, 1, 2, 3 and 4 respectively)\n\n");  
  5689.     dc_printf("neb2_ff          : flash fade/sec\n");
  5690.     dc_printf("neb2_background  : rgb background color\n");
  5691.     dc_printf("neb2_fog_color   : rgb fog color\n");
  5692. @@ -1471,95 +1474,91 @@ DCF(neb2, "list nebula console commands")
  5693.  // dc_printf("neb2_fog_vals    : display all the current settings for all above values\n");   
  5694.  }
  5695.  
  5696. -DCF(neb2_prad, "")
  5697. +DCF(neb2_prad, "set cloud poof radius")
  5698.  {
  5699. -   dc_get_arg(ARG_FLOAT);
  5700. -   Nd->prad = Dc_arg_float;
  5701. +   dc_stuff_float(&Nd->prad);
  5702.  }
  5703. -DCF(neb2_cdim, "")
  5704. +DCF(neb2_cdim, "poof cube dimension")
  5705.  {
  5706. -   dc_get_arg(ARG_FLOAT);
  5707. -   Nd->cube_dim = Dc_arg_float;
  5708. +   dc_stuff_float(&Nd->cube_dim);
  5709.  }
  5710.  
  5711. -DCF(neb2_cinner, "")
  5712. +DCF(neb2_cinner, "poof cube inner dimension")
  5713.  {
  5714. -   dc_get_arg(ARG_FLOAT);
  5715. -   Nd->cube_inner = Dc_arg_float;
  5716. +   dc_stuff_float(&Nd->cube_inner);
  5717.  }
  5718.  
  5719. -DCF(neb2_couter, "")
  5720. +DCF(neb2_couter, "poof cube outer dimension")
  5721.  {
  5722. -   dc_get_arg(ARG_FLOAT);
  5723. -   Nd->cube_outer = Dc_arg_float;
  5724. +   dc_stuff_float(&Nd->cube_outer);
  5725.  }
  5726.  
  5727. -DCF(neb2_jitter, "")
  5728. +DCF(neb2_jitter, "poof jitter")
  5729.  {
  5730. -   dc_get_arg(ARG_FLOAT);
  5731. -   Nd->hj = Nd->dj = Nd->wj = Dc_arg_float;
  5732. +   float value;
  5733. +   dc_stuff_float(&value);
  5734. +   Nd->hj = Nd->dj = Nd->wj = value;
  5735.  }
  5736.  
  5737. -DCF(neb2_max_alpha, "")
  5738. +DCF(neb2_max_alpha, "max alpha value (0.0 to 1.0) for cloud poofs.")
  5739.  {
  5740. -   dc_get_arg(ARG_FLOAT);
  5741. -   Nd->max_alpha_glide = Dc_arg_float;
  5742. +   dc_stuff_float(&Nd->max_alpha_glide);
  5743.  }
  5744.  
  5745. -DCF(neb2_break_alpha, "")
  5746. +DCF(neb2_break_alpha, "alpha value (0.0 to 1.0) at which faded polygons are not drawn.")
  5747.  {
  5748. -   dc_get_arg(ARG_FLOAT);
  5749. -   Nd->break_alpha = Dc_arg_float;
  5750. +   dc_stuff_float(&Nd->break_alpha);
  5751.  }
  5752.  
  5753. -DCF(neb2_break_off, "")
  5754. +DCF(neb2_break_off, "how many pixels offscreen (left, right, top, bottom) when a cloud poof becomes fully transparent.")
  5755.  {
  5756. -   dc_get_arg(ARG_INT);
  5757. -   Nd->break_y = (float)Dc_arg_int;
  5758. -   Nd->break_x = Nd->break_y * 1.3333f;
  5759. +   int value;
  5760. +   dc_stuff_int(&value);
  5761. +   Nd->break_y = (float)value;
  5762. +   Nd->break_x = Nd->break_y * gr_screen.aspect;
  5763.  }
  5764.  
  5765. -DCF(neb2_smooth, "")
  5766. +DCF(neb2_smooth, "magic fog smoothing modes (0 - 3)")
  5767.  {
  5768.     int index;
  5769. -   dc_get_arg(ARG_INT);
  5770. -   index = Dc_arg_int;
  5771. +   dc_stuff_int(&index);
  5772.     if ( (index >= 0) && (index <= 3) ) {
  5773.         wacky_scheme = index;
  5774. +   } else {
  5775. +       dc_printf("Invalid smooth mode %i", index);
  5776.     }
  5777.  }
  5778.  
  5779. -DCF(neb2_select, "")
  5780. +DCF(neb2_select, "Enables/disables a poof bitmap")
  5781.  {
  5782. -   dc_get_arg(ARG_INT);
  5783. -   int bmap = Dc_arg_int;
  5784. +   int bmap;
  5785. +   bool val_b;
  5786. +
  5787. +   dc_stuff_int(&bmap);
  5788. +
  5789.     if ( (bmap >= 0) && (bmap < Neb2_poof_count) ) {
  5790. -       dc_get_arg(ARG_INT);
  5791. -       if (Dc_arg_int) {
  5792. -           Neb2_poof_flags |= (1<<bmap);
  5793. -       } else {
  5794. -           Neb2_poof_flags &= ~(1<<bmap);
  5795. -       }
  5796. +       dc_stuff_boolean(&val_b);
  5797. +
  5798. +       val_b ? (Neb2_poof_flags |= (1<<bmap)) : (Neb2_poof_flags &= ~(1<<bmap));
  5799.     }
  5800.  }
  5801.  
  5802. -DCF(neb2_rot, "")
  5803. +DCF(neb2_rot, "set max rotation speed for poofs")
  5804.  {
  5805. -   dc_get_arg(ARG_FLOAT);
  5806. -   max_rotation = Dc_arg_float;
  5807. +   dc_stuff_float(&max_rotation);
  5808.  }
  5809.  
  5810. -DCF(neb2_ff, "")
  5811. +DCF(neb2_ff, "flash fade/sec")
  5812.  {
  5813. -   dc_get_arg(ARG_FLOAT);
  5814. -   neb2_flash_fade = Dc_arg_float;
  5815. +   dc_stuff_float(&neb2_flash_fade);
  5816.  }
  5817.  
  5818. -DCF(neb2_mode, "")
  5819. +DCF(neb2_mode, "Switches nebula render modes")
  5820.  {
  5821. -   dc_get_arg(ARG_INT);
  5822. +   int mode;
  5823. +   dc_stuff_int(&mode);
  5824.  
  5825. -   switch (Dc_arg_int) {
  5826. +   switch (mode) {
  5827.         case NEB2_RENDER_NONE:
  5828.             Neb2_render_mode = NEB2_RENDER_NONE;
  5829.         break;
  5830. @@ -1586,39 +1585,32 @@ DCF(neb2_mode, "")
  5831.     }
  5832.  }
  5833.  
  5834. -DCF(neb2_slices, "")
  5835. +DCF(neb2_slices, "Sets how many 'slices' are used in the nebula")
  5836.  {
  5837. -   dc_get_arg(ARG_INT);
  5838. -   Neb2_slices = Dc_arg_int;
  5839. +   dc_stuff_int(&Neb2_slices);
  5840.     neb2_eye_changed();
  5841.  }
  5842.  
  5843. -DCF(neb2_background, "")
  5844. +DCF(neb2_background, "Sets the RGB background color (lame rendering)")
  5845.  {
  5846.     int r, g, b;
  5847.  
  5848. -   dc_get_arg(ARG_INT);
  5849. -   r = Dc_arg_int;
  5850. -   dc_get_arg(ARG_INT);
  5851. -   g = Dc_arg_int;
  5852. -   dc_get_arg(ARG_INT);
  5853. -   b = Dc_arg_int;
  5854. +   dc_stuff_int(&r);
  5855. +   dc_stuff_int(&g);
  5856. +   dc_stuff_int(&b);
  5857.  
  5858.     Neb2_background_color[0] = r;
  5859.     Neb2_background_color[1] = g;
  5860.     Neb2_background_color[2] = b;
  5861.  }
  5862.  
  5863. -DCF(neb2_fog_color, "")
  5864. +DCF(neb2_fog_color, "Sets the RGB fog color (HTL)")
  5865.  {
  5866.     ubyte r, g, b;
  5867.  
  5868. -   dc_get_arg(ARG_UBYTE);
  5869. -   r = Dc_arg_ubyte;
  5870. -   dc_get_arg(ARG_UBYTE);
  5871. -   g = Dc_arg_ubyte;
  5872. -   dc_get_arg(ARG_UBYTE);
  5873. -   b = Dc_arg_ubyte;
  5874. +   dc_stuff_ubyte(&r);
  5875. +   dc_stuff_ubyte(&g);
  5876. +   dc_stuff_ubyte(&b);
  5877.  
  5878.     Neb2_fog_color_r = r;
  5879.     Neb2_fog_color_g = g;
  5880. Index: code/nebula/neblightning.cpp
  5881. ===================================================================
  5882. --- code/nebula/neblightning.cpp    (revision 10462)
  5883. +++ code/nebula/neblightning.cpp    (working copy)
  5884. @@ -13,6 +13,7 @@
  5885.  #include "parse/parselo.h"
  5886.  #include "globalincs/linklist.h"
  5887.  #include "io/timer.h"
  5888. +#include "debugconsole/console.h"
  5889.  #include "freespace2/freespace.h"
  5890.  #include "gamesnd/gamesnd.h"
  5891.  #include "render/3d.h"
  5892. @@ -81,52 +82,43 @@ vec3d Nebl_bolt_strike;         // strike point of the bolt being generated
  5893.  storm_type *Storm = NULL;
  5894.  
  5895.  // vars
  5896. -DCF(b_scale, "")
  5897. +DCF(b_scale, "Sets the scale factor for debug nebula bolts")
  5898.  {
  5899. -   dc_get_arg(ARG_FLOAT);
  5900. -   Bolt_types[DEBUG_BOLT].b_scale = Dc_arg_float;
  5901. +   dc_stuff_float(&Bolt_types[DEBUG_BOLT].b_scale);
  5902.  }
  5903. -DCF(b_rand, "")
  5904. +DCF(b_rand, "Sets the randomness factor for debug nebula bolts")
  5905.  {
  5906. -   dc_get_arg(ARG_FLOAT);
  5907. -   Bolt_types[DEBUG_BOLT].b_rand = Dc_arg_float;
  5908. +   dc_stuff_float(&Bolt_types[DEBUG_BOLT].b_rand);
  5909.  }
  5910. -DCF(b_shrink, "")
  5911. +DCF(b_shrink, "Sets the shrink factor for debug nebula bolts")
  5912.  {
  5913. -   dc_get_arg(ARG_FLOAT);
  5914. -   Bolt_types[DEBUG_BOLT].b_shrink = Dc_arg_float;
  5915. +   dc_stuff_float(&Bolt_types[DEBUG_BOLT].b_shrink);
  5916.  }
  5917. -DCF(b_poly_pct, "")
  5918. +DCF(b_poly_pct, "Sets b_poly_pct")
  5919.  {
  5920. -   dc_get_arg(ARG_FLOAT);
  5921. -   Bolt_types[DEBUG_BOLT].b_poly_pct = Dc_arg_float;
  5922. +   dc_stuff_float(&Bolt_types[DEBUG_BOLT].b_poly_pct);
  5923.  }
  5924. -DCF(b_add, "")
  5925. +DCF(b_add, "Sets b_add")
  5926.  {
  5927. -   dc_get_arg(ARG_FLOAT);
  5928. -   Bolt_types[DEBUG_BOLT].b_add = Dc_arg_float;
  5929. +   dc_stuff_float(&Bolt_types[DEBUG_BOLT].b_add);
  5930.  }
  5931. -DCF(b_strikes, "")
  5932. +DCF(b_strikes, "Sets num_strikes")
  5933.  {
  5934. -   dc_get_arg(ARG_INT);
  5935. -   Bolt_types[DEBUG_BOLT].num_strikes = Dc_arg_int;
  5936. +   dc_stuff_int(&Bolt_types[DEBUG_BOLT].num_strikes);
  5937.  }
  5938. -DCF(b_noise, "")
  5939. +DCF(b_noise, "Sets noise factor")
  5940.  {
  5941. -   dc_get_arg(ARG_FLOAT);
  5942. -   Bolt_types[DEBUG_BOLT].noise = Dc_arg_float;
  5943. +   dc_stuff_float(&Bolt_types[DEBUG_BOLT].noise);
  5944.  }
  5945. -DCF(b_bright, "")
  5946. +DCF(b_bright, "Sets brightness factor")
  5947.  {
  5948. -   dc_get_arg(ARG_FLOAT);
  5949. -   Bolt_types[DEBUG_BOLT].b_bright = Dc_arg_float;
  5950. +   dc_stuff_float(&Bolt_types[DEBUG_BOLT].b_bright);
  5951.  }
  5952. -DCF(b_lifetime, "")
  5953. +DCF(b_lifetime, "Sets lifetime duration")
  5954.  {
  5955. -   dc_get_arg(ARG_INT);
  5956. -   Bolt_types[DEBUG_BOLT].lifetime = Dc_arg_int;
  5957. +   dc_stuff_int(&Bolt_types[DEBUG_BOLT].lifetime);
  5958.  }
  5959. -DCF(b_list, "")
  5960. +DCF(b_list, "Displays status of debug lightning commands")
  5961.  {
  5962.     dc_printf("Debug lightning bolt settings :\n");
  5963.  
  5964. @@ -144,12 +136,12 @@ DCF(b_list, "")
  5965.  // nebula lightning intensity (0.0 to 1.0)
  5966.  float Nebl_intensity = 0.6667f;
  5967.  
  5968. -DCF(lightning_intensity, "")
  5969. +DCF(lightning_intensity, "Sets lightning intensity between 0.0 and 1.0 (Default is 0.6667)")
  5970.  {
  5971. -   dc_get_arg(ARG_FLOAT);
  5972. -   float val = Dc_arg_float;
  5973. -    
  5974. -    CLAMP(val, 0.0f, 1.0f);
  5975. +   float val;
  5976. +   dc_stuff_float(&val);
  5977. +
  5978. +   CLAMP(val, 0.0f, 1.0f);
  5979.  
  5980.     Nebl_intensity = 1.0f - val;
  5981.  }
  5982. Index: code/network/multi.cpp
  5983. ===================================================================
  5984. --- code/network/multi.cpp  (revision 10462)
  5985. +++ code/network/multi.cpp  (working copy)
  5986. @@ -48,6 +48,7 @@
  5987.  #include "cfile/cfile.h"
  5988.  #include "fs2netd/fs2netd_client.h"
  5989.  #include "pilotfile/pilotfile.h"
  5990. +#include "debugconsole/console.h"
  5991.  
  5992.  
  5993.  
  5994. @@ -1105,14 +1106,15 @@ void multi_process_incoming()
  5995.  //
  5996.  
  5997.  int eye_tog = 1;
  5998. -DCF(eye_tog, "")
  5999. +DCF(eye_tog, "Toggles setting of the local player eyepoint on every frame (Multiplayer)")
  6000.  {
  6001. -   eye_tog = !eye_tog;
  6002. -   if(eye_tog){
  6003. -       dc_printf("proper eye stuff on\n");
  6004. -   } else {
  6005. -       dc_printf("proper eye stuff off\n");
  6006. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  6007. +       dc_printf("proper eye stuff is %s\n", eye_tog ? "ON" : "OFF");
  6008. +       return;
  6009.     }
  6010. +
  6011. +   eye_tog = !eye_tog;
  6012. +   dc_printf("proper eye stuff is %s\n", eye_tog ? "ON" : "OFF");
  6013.  }
  6014.  
  6015.  void multi_do_frame()
  6016. @@ -1772,13 +1774,14 @@ void multi_reset_timestamps()
  6017.  }
  6018.  
  6019.  // netgame debug flags for debug console stuff
  6020. -DCF(netd, "change/list netgame debug flags")
  6021. +DCF(netd, "change netgame debug flags (Mulitplayer)")
  6022.  {
  6023. -   dc_get_arg(ARG_INT);
  6024. +   int value;
  6025. +   dc_stuff_int(&value);
  6026.    
  6027. -   // if we got an integer, and we're the server, change flags
  6028. -   if((Dc_arg_type & ARG_INT) && (Net_player != NULL) && (Net_player->flags & NETINFO_FLAG_AM_MASTER) && (Dc_arg_int <= 7)){
  6029. -       Netgame.debug_flags ^= (1<<Dc_arg_int);
  6030. +   // if we're the server, change flags
  6031. +   if ((Net_player != NULL) && (Net_player->flags & NETINFO_FLAG_AM_MASTER) && (value <= 7)) {
  6032. +       Netgame.debug_flags ^= (1 << value);
  6033.     }
  6034.  
  6035.     // display network flags
  6036. Index: code/network/multi_kick.cpp
  6037. ===================================================================
  6038. --- code/network/multi_kick.cpp (revision 10462)
  6039. +++ code/network/multi_kick.cpp (working copy)
  6040. @@ -18,6 +18,7 @@
  6041.  #include "freespace2/freespace.h"
  6042.  #include "playerman/player.h"
  6043.  #include "io/timer.h"
  6044. +#include "debugconsole/console.h"
  6045.  
  6046.  
  6047.  // ----------------------------------------------------------------------------------
  6048. @@ -137,18 +138,14 @@ int multi_kick_is_banned(net_addr *addr)
  6049.  void multi_dcf_kick()
  6050.  {
  6051.     int player_num,idx;
  6052. +   SCP_string arg;
  6053.  
  6054.     // get the callsign of the player to kick
  6055. -   dc_get_arg(ARG_STRING);
  6056. -
  6057. -   if(Dc_arg[0] == '\0'){
  6058. -       dc_printf("Invalid player callsign!\n");
  6059. -       return ;
  6060. -   }
  6061. +   dc_stuff_string(arg);
  6062.  
  6063.     player_num = -1;
  6064.     for(idx=0;idx<MAX_PLAYERS;idx++){
  6065. -       if(MULTI_CONNECTED(Net_players[idx]) && (stricmp(Net_players[idx].m_player->callsign,Dc_arg)==0)){
  6066. +       if(MULTI_CONNECTED(Net_players[idx]) && (stricmp(Net_players[idx].m_player->callsign, arg.c_str()) == 0)) {
  6067.             player_num = idx;
  6068.             break;
  6069.         }
  6070. @@ -156,7 +153,7 @@ void multi_dcf_kick()
  6071.  
  6072.     // if we didn't find the player, notify of the results
  6073.     if(player_num == -1){
  6074. -       dc_printf("Could not find player %s to kick!",Dc_arg);
  6075. +       dc_printf("Could not find player %s to kick!", arg);
  6076.     }
  6077.     // if we found the guy, then try and kick him
  6078.     else {
  6079. Index: code/network/multi_obj.cpp
  6080. ===================================================================
  6081. --- code/network/multi_obj.cpp  (revision 10462)
  6082. +++ code/network/multi_obj.cpp  (working copy)
  6083. @@ -26,6 +26,7 @@
  6084.  #include "physics/physics.h"
  6085.  #include "ship/afterburner.h"
  6086.  #include "cfile/cfile.h"
  6087. +#include "debugconsole/console.h"
  6088.  
  6089.  
  6090.  // ---------------------------------------------------------------------------------------------------
  6091. @@ -1569,10 +1570,21 @@ int OO_server_rate_stamp = -1;
  6092.  
  6093.  // bandwidth granularity
  6094.  int OO_gran = 1;
  6095. -DCF(oog, "")
  6096. +DCF(oog, "Sets bandwidth granularity (Multiplayer)")
  6097.  {
  6098. -   dc_get_arg(ARG_INT);
  6099. -   OO_gran = Dc_arg_int;
  6100. +   if (dc_optional_string_either("help", "--help")) {
  6101. +       dc_printf("Usage: oog <OO_gran>\n");
  6102. +       dc_printf("Sets bandwidth granularity\n");
  6103. +       return;
  6104. +   }
  6105. +
  6106. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  6107. +       dc_printf("Current Granularity is '%i' (default is 1)", OO_gran);
  6108. +       return;
  6109. +   }
  6110. +
  6111. +   dc_stuff_int(&OO_gran);
  6112. +   dc_printf("Ganularity set to %i", OO_gran);
  6113.  }
  6114.  
  6115.  // process datarate limiting stuff for the server
  6116. @@ -1939,10 +1951,21 @@ void multi_oo_interp(object *objp)
  6117.  }
  6118.  
  6119.  float oo_error = 0.8f;
  6120. -DCF(oo_error, "")
  6121. +DCF(oo_error, "Sets error factor for flight path prediction physics (Multiplayer)")
  6122.  {
  6123. -   dc_get_arg(ARG_FLOAT);
  6124. -   oo_error = Dc_arg_float;
  6125. +   if (dc_optional_string_either("help", "--help")) {
  6126. +       dc_printf("Usage: oo_error <value>\n");
  6127. +       return;
  6128. +   }
  6129. +
  6130. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  6131. +       dc_printf("oo_error is currently %f", oo_error);
  6132. +       return;
  6133. +   }
  6134. +
  6135. +   dc_stuff_float(&oo_error);
  6136. +  
  6137. +   dc_printf("oo_error set to %f", oo_error);
  6138.  }
  6139.  
  6140.  void multi_oo_calc_interp_splines(int ship_index, vec3d *cur_pos, matrix *cur_orient, physics_info *cur_phys_info, vec3d *new_pos, matrix *new_orient, physics_info *new_phys_info)
  6141. @@ -1994,14 +2017,16 @@ void oo_update_time()
  6142.  }
  6143.  
  6144.  int display_oo_bez = 0;
  6145. -DCF(bez, "")
  6146. +DCF(bez, "Toggles rendering of player ship trajectory interpolation splines (Multiplayer) *disabled*")
  6147.  {
  6148. -   display_oo_bez = !display_oo_bez;
  6149. -   if(display_oo_bez){
  6150. -       dc_printf("Showing interp splines");
  6151. -   } else {
  6152. -       dc_printf("Not showing interp splines");
  6153. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  6154. +       dc_printf("Rendering of interpolation splines is '%s'", display_oo_bez ? "ON" : "OFF");
  6155. +       return;
  6156.     }
  6157. +
  6158. +   display_oo_bez = !display_oo_bez;
  6159. +
  6160. +   dc_printf("%showing interp splines", display_oo_bez ? "S" : "Not s");
  6161.  }
  6162.  
  6163.  void oo_display()
  6164. Index: code/network/multi_pxo.cpp
  6165. ===================================================================
  6166. --- code/network/multi_pxo.cpp  (revision 10462)
  6167. +++ code/network/multi_pxo.cpp  (working copy)
  6168. @@ -42,6 +42,7 @@
  6169.  #include "playerman/player.h"
  6170.  #include "fs2netd/fs2netd_client.h"
  6171.  #include "menuui/mainhallmenu.h"
  6172. +#include "debugconsole/console.h"
  6173.  
  6174.  
  6175.  
  6176. @@ -461,14 +462,15 @@ void multi_pxo_scroll_players_down();
  6177.  // get the absolute index of the displayed items which our currently selected one is
  6178.  int multi_pxo_get_select_index();
  6179.  
  6180. -DCF(players, "")
  6181. +DCF(players, "Adds the specified number of bogus players to the PXO listing (Multiplayer)")
  6182.  {
  6183.     char name[512] = "";
  6184. -
  6185. +   int i;
  6186.     // add a bunch of bogus players
  6187. -   dc_get_arg(ARG_INT);
  6188. -   for(int idx=0; idx<Dc_arg_int; idx++){
  6189. -       sprintf(name, "player %d", idx);
  6190. +   dc_stuff_int(&i);
  6191. +
  6192. +   for(int idx = 0; idx < i; idx++){
  6193. +       sprintf(name, "bogus player %d", idx);
  6194.         multi_pxo_add_player(name);
  6195.     }
  6196.  }
  6197. Index: code/network/multi_voice.cpp
  6198. ===================================================================
  6199. --- code/network/multi_voice.cpp    (revision 10462)
  6200. +++ code/network/multi_voice.cpp    (working copy)
  6201. @@ -22,7 +22,7 @@
  6202.  #include "menuui/optionsmenumulti.h"
  6203.  #include "network/multi.h"
  6204.  #include "playerman/player.h"
  6205. -
  6206. +#include "debugconsole/console.h"
  6207.  
  6208.  
  6209.  // --------------------------------------------------------------------------------------------------
  6210. @@ -483,16 +483,17 @@ void multi_voice_process()
  6211.  // voice settings debug console function
  6212.  void multi_voice_dcf()
  6213.  {
  6214. -   dc_get_arg(ARG_STRING);
  6215. +   SCP_string arg;
  6216. +   int value;
  6217. +
  6218. +   dc_stuff_string_white(arg);
  6219.  
  6220.     // set the quality of sound
  6221. -   if (strcmp(Dc_arg, NOX("qos")) == 0) {
  6222. -       dc_get_arg(ARG_INT);
  6223. -       if(Dc_arg_type & ARG_INT){
  6224. -           if((Dc_arg_int >= 1) && (Dc_arg_int <= 10) && (Net_player->flags & NETINFO_FLAG_AM_MASTER)){
  6225. -               multi_voice_set_vars(Dc_arg_int,-1);
  6226. -               dc_printf("Quality of sound : %d\n",Dc_arg_int);
  6227. -           }
  6228. +   if (arg == NOX("qos")) {
  6229. +       dc_stuff_int(&value);
  6230. +       if((value >= 1) && (value <= 10) && (Net_player->flags & NETINFO_FLAG_AM_MASTER)){
  6231. +           multi_voice_set_vars(value,-1);
  6232. +           dc_printf("Quality of sound : %d\n", value);
  6233.         }
  6234.     }
  6235.  }
  6236. Index: code/network/multilag.cpp
  6237. ===================================================================
  6238. --- code/network/multilag.cpp   (revision 10462)
  6239. +++ code/network/multilag.cpp   (working copy)
  6240. @@ -18,6 +18,7 @@
  6241.  #include "io/timer.h"
  6242.  #include "globalincs/linklist.h"
  6243.  #include "network/psnet2.h"
  6244. +#include "debugconsole/console.h"
  6245.  
  6246.  
  6247.  
  6248. @@ -392,6 +393,7 @@ void multi_lag_put_free(lag_buf *buf)
  6249.     Lag_buf_count--;
  6250.  }
  6251.  
  6252. +// Help and status provider for the lag-loss system
  6253.  void multi_lagloss_dcf()
  6254.  {
  6255.     // if the lag system isn't inited, don't do anything
  6256. @@ -400,183 +402,290 @@ void multi_lagloss_dcf()
  6257.         return;
  6258.     }
  6259.  
  6260. +   // display status of lag system
  6261. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  6262. +       dc_printf("Lag system status:\n");
  6263. +       // display lag settings
  6264. +       dc_printf("Lag : \n");
  6265. +       dc_printf("Base  \t\tMin   \t\tMax   \t\tStreak\n");
  6266. +       dc_printf("%f\t\t%f\t\t%f\t\t%f\n\n", Multi_lag_base, Multi_lag_min, Multi_lag_max, Multi_streak_time);
  6267. +
  6268. +       // display loss settings
  6269. +       dc_printf("Loss : \n");
  6270. +       dc_printf("Base  \t\tMin   \t\tMax\n");
  6271. +       dc_printf("%f\t\t%f\t\t%f\n", Multi_loss_base, Multi_loss_min, Multi_loss_max);
  6272. +       return;
  6273. +   }
  6274. +
  6275.     // display all available commands
  6276. -   dc_printf("Usage :\nlag <ms>  (-1 to disable)\nlag_min <ms>\nlag_max <ms>\nloss <0-100>  (-1 to disable)\nloss_min <0-100>\nloss_max <0-100>\nlag_streak <ms>\nlagloss\n");
  6277. +   dc_printf("Lag system commands\n\n");
  6278. +
  6279. +   dc_printf("Usage :\n");
  6280. +   dc_printf("lag <ms>\n");
  6281. +       dc_printf("\tSets the lag base value if <ms> is within the max and min limits (see lag_min and lag_max)\n");
  6282. +       dc_printf("\tIf <ms> is outside of the max and min limits, then nothing is done\n");
  6283. +       dc_printf("\tIf <ms> is negative, then lag simulation is turned off\n\n");
  6284. +
  6285. +   dc_printf("lag_min <ms>\n");
  6286. +       dc_printf("\tSets the lag min value if <ms> is less than the base value\n");
  6287. +       dc_printf("\tIf <ms> is outside the base or max values, then nothing is done\n");
  6288. +       dc_printf("\tIf <ms> is negative, then the min limit is removed\n\n");
  6289. +
  6290. +   dc_printf("lag_max <ms>\n");
  6291. +       dc_printf("\tSets the lag max value if <ms> is greater than the base value\n");
  6292. +       dc_printf("\tIf <ms> is outside the base or min values, then nothing is done\n");
  6293. +       dc_printf("\tIf <ms> is negative, then the max limit is removed\n\n");
  6294. +
  6295. +   dc_printf("loss    <0-100>  (-1 to disable)\n");
  6296. +       dc_printf("\tSimilar to lag, but applies value to loss base value\n\n");
  6297. +
  6298. +   dc_printf("loss_min <0-100>\n");
  6299. +       dc_printf("\tSimilar to lag_min, but applies value to loss min value\n\n");
  6300. +  
  6301. +   dc_printf("loss_max <0-100>\n");
  6302. +       dc_printf("\tSimilar to lag_max, but applies value to loss max value\n\n");
  6303.  
  6304. -   // display lag settings
  6305. -   dc_printf("Lag : ");       
  6306. -   dc_printf("\n   Base %d\n   Min %d\n   Max %d\n   Streak %d\n", Multi_lag_base, Multi_lag_min, Multi_lag_max, Multi_streak_time);  
  6307.  
  6308. -   // display loss settings
  6309. -   dc_printf("Loss : ");      
  6310. -   dc_printf("\n   Base %f\n   Min %f\n   Max %f\n", Multi_loss_base, Multi_loss_min, Multi_loss_max);
  6311. +   dc_printf("lag_streak <ms>\n");
  6312. +       dc_printf("\tSets the duration of lag streaks where the lag is consistant for <ms>\n");
  6313. +       dc_printf("\tEx: A value of 2000 would result in lag streaks that last 2 seconds each\n\n");
  6314. +
  6315. +   dc_printf("lagloss\n");
  6316. +       dc_printf("\tDisplays this text. Passing --status will display the status of the entire lag system");
  6317.  }
  6318.  
  6319. -DCF(lag, "")
  6320. +DCF(lag, "Sets the lag base value (Muliplayer)")
  6321.  {
  6322. +   int value;
  6323. +
  6324.     // if the lag system isn't inited, don't do anything
  6325.     if(!Multi_lag_inited){
  6326.         dc_printf("Lag System Not Initialized!\n");
  6327.         return;
  6328.     }
  6329.  
  6330. -   dc_get_arg(ARG_INT);       
  6331. +   if (dc_optional_string_either("help", "--help")) {
  6332. +       multi_lagloss_dcf();
  6333. +       return;
  6334. +   }
  6335. +
  6336. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  6337. +       dc_printf("Lag base value is currently %i\n", Multi_lag_base);
  6338. +       return;
  6339. +   }
  6340. +
  6341. +   dc_stuff_int(&value);
  6342.     // parse the argument and change things around accordingly
  6343. -   if(Dc_arg_type & ARG_INT){         
  6344. -       if(Dc_arg_int < 0){
  6345. -           // switch the lag sim off
  6346. -           Multi_lag_base = -1;
  6347. -           Multi_lag_min = -1;
  6348. -           Multi_lag_max = -1;
  6349. -           dc_printf("Turning simulated lag off\n");
  6350. -           multi_lagloss_dcf();
  6351. -       } else if((Multi_lag_max >= 0) && (Dc_arg_int > Multi_lag_max)){
  6352. -           dc_printf("Base value greater than max value, ignoring...");
  6353. -       } else if((Multi_lag_min >= 0) && (Dc_arg_int < Multi_lag_min)){
  6354. -           dc_printf("Base value smaller than min value, ignoring...");
  6355. -       } else {
  6356. -           Multi_lag_base = Dc_arg_int;
  6357. -           multi_lagloss_dcf();
  6358. -       }
  6359. -   }  
  6360. +   if (value < 0) {
  6361. +       // switch the lag sim off
  6362. +       Multi_lag_base = -1;
  6363. +       Multi_lag_min = -1;
  6364. +       Multi_lag_max = -1;
  6365. +       dc_printf("Turning simulated lag off\n");
  6366. +       multi_lagloss_dcf();
  6367. +
  6368. +   } else if ((Multi_lag_max >= 0) && (value > Multi_lag_max)) {
  6369. +       dc_printf("Base value greater than max value, ignoring...");
  6370. +
  6371. +   } else if ((Multi_lag_min >= 0) && (value < Multi_lag_min)) {
  6372. +       dc_printf("Base value smaller than min value, ignoring...");
  6373. +
  6374. +   } else {
  6375. +
  6376. +       Multi_lag_base = value;
  6377. +       multi_lagloss_dcf();
  6378. +       dc_printf("Base value set to %i", value);
  6379. +   }
  6380.  }
  6381.  
  6382. -DCF(lag_min, "")
  6383. +DCF(lag_min, "Sets the lag min value (Multiplayer)")
  6384.  {
  6385. +   int value;
  6386. +
  6387.     // if the lag system isn't inited, don't do anything
  6388.     if(!Multi_lag_inited){
  6389.         dc_printf("Lag System Not Initialized!\n");
  6390.         return;
  6391.     }
  6392.  
  6393. -   dc_get_arg(ARG_INT);       
  6394. +   if (dc_optional_string_either("help", "--help")) {
  6395. +       multi_lagloss_dcf();
  6396. +   }
  6397. +
  6398. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  6399. +       dc_printf("Lag min value is currently %i\n", Multi_lag_min);
  6400. +   }
  6401. +
  6402. +   dc_stuff_int(&value);
  6403.     // parse the argument and change things around accordingly
  6404. -   if(Dc_arg_type & ARG_INT){         
  6405. -       if(Dc_arg_int > Multi_lag_base){
  6406. -           dc_printf("Min value greater than base value, ignoring...");
  6407. -       } else {
  6408. -           if(Dc_arg_int < 0){
  6409. -               Multi_lag_min = -1;
  6410. -           } else {
  6411. -               Multi_lag_min = Dc_arg_int;
  6412. -           }
  6413. -           multi_lagloss_dcf();
  6414. -       }
  6415. -   }          
  6416. +  
  6417. +   if (value > Multi_lag_base) {
  6418. +       dc_printf("Min value greater than base value, ignoring...");
  6419. +       return;
  6420. +
  6421. +   } else if (value < 0) {
  6422. +       Multi_lag_min = -1;
  6423. +
  6424. +   } else {
  6425. +       Multi_lag_min = value;
  6426. +   }
  6427. +   dc_printf("Lag min value set to %i\n", Multi_lag_min);
  6428.  }
  6429.  
  6430. -DCF(lag_max, "")
  6431. +DCF(lag_max, "Sets the lag max value (Multiplayer)")
  6432.  {
  6433. +   int value;
  6434. +
  6435.     // if the lag system isn't inited, don't do anything
  6436. -   if(!Multi_lag_inited){
  6437. +   if (!Multi_lag_inited) {
  6438.         dc_printf("Lag System Not Initialized!\n");
  6439.         return;
  6440.     }
  6441.  
  6442. +   if (dc_optional_string_either("help", "--help")) {
  6443. +       multi_lagloss_dcf();
  6444. +       return;
  6445. +   }
  6446. +
  6447. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  6448. +       dc_printf("Lag max value is currently %i\n", Multi_lag_max);
  6449. +       return;
  6450. +   }
  6451. +
  6452.     // parse the argument and change things around accordingly
  6453. -   dc_get_arg(ARG_INT);
  6454. -   if(Dc_arg_type & ARG_INT){         
  6455. -       if((Dc_arg >=0) && (Dc_arg_int < Multi_lag_base)){
  6456. -           dc_printf("Max value smaller than base value, ignoring...");
  6457. -       } else {
  6458. -           if(Dc_arg_int < 0){
  6459. -               Multi_lag_max = -1;
  6460. -           } else {
  6461. -               Multi_lag_max = Dc_arg_int;
  6462. -           }
  6463. -           multi_lagloss_dcf();
  6464. -       }
  6465. -   }      
  6466. +   dc_stuff_int(&value);
  6467. +  
  6468. +   if ((value >= 0) && (value < Multi_lag_base)) {
  6469. +       dc_printf("Max value smaller than base value, ignoring...");
  6470. +
  6471. +   } else if (value < 0) {
  6472. +       Multi_lag_max = -1;
  6473. +
  6474. +   } else {
  6475. +       Multi_lag_max = value;
  6476. +   }
  6477. +   dc_printf("Lag max value set to %i\n", Multi_lag_max);
  6478.  }
  6479.  
  6480. -DCF(loss, "")
  6481. +DCF(loss, "Sets the loss base value (Multiplayer)")
  6482.  {
  6483. +   int val_i;
  6484. +   float val_f;
  6485. +
  6486.     // if the lag system isn't inited, don't do anything
  6487.     if(!Multi_lag_inited){
  6488.         dc_printf("Lag System Not Initialized!\n");
  6489.         return;
  6490.     }
  6491.  
  6492. +       if (dc_optional_string_either("help", "--help")) {
  6493. +       multi_lagloss_dcf();
  6494. +       return;
  6495. +   }
  6496. +
  6497. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  6498. +       dc_printf("Loss value is currently %i percent", Multi_loss_base);
  6499. +       return;
  6500. +   }
  6501. +
  6502.     // parse the argument and change things around accordingly
  6503. -   dc_get_arg(ARG_INT);
  6504. -   if(Dc_arg_type & ARG_INT){
  6505. -       float val = (float)Dc_arg_int / 100.0f;
  6506. -          
  6507. -       if(Dc_arg_int > 100){
  6508. -           dc_printf("Illegal loss base value, ignoring...");
  6509. -       } else if(Dc_arg_int < 0){
  6510. -           // switch the loss sim off
  6511. -           dc_printf("Turning simulated loss off\n");
  6512. -           Multi_loss_base = -1.0f;
  6513. -           Multi_loss_min = -1.0f;
  6514. -           Multi_loss_max = -1.0f;
  6515. -           multi_lagloss_dcf();
  6516. -       } else if((Multi_loss_max >= 0.0f) && (val > Multi_loss_max)){
  6517. -           dc_printf("Base value greater than max value, ignoring...");
  6518. -       } else if((Multi_loss_min >= 0.0f) && (val < Multi_loss_min)){
  6519. -           dc_printf("Base value smaller than min value, ignoring...");
  6520. -       } else {
  6521. -           Multi_loss_base = val;
  6522. -           multi_lagloss_dcf();
  6523. -       }
  6524. -   }          
  6525. +   dc_stuff_int(&val_i);
  6526. +
  6527. +   val_f = (float)val_i / 100.0f;
  6528. +      
  6529. +   if(val_i > 100){
  6530. +       dc_printf("Illegal loss base value, ignoring...");
  6531. +   } else if (val_i < 0){
  6532. +       // switch the loss sim off
  6533. +       dc_printf("Turning simulated loss off\n");
  6534. +       Multi_loss_base = -1.0f;
  6535. +       Multi_loss_min = -1.0f;
  6536. +       Multi_loss_max = -1.0f;
  6537. +
  6538. +   } else if((Multi_loss_max >= 0.0f) && (val_f > Multi_loss_max)){
  6539. +       dc_printf("Base value greater than max value, ignoring...");
  6540. +
  6541. +   } else if((Multi_loss_min >= 0.0f) && (val_f < Multi_loss_min)){
  6542. +       dc_printf("Base value smaller than min value, ignoring...");
  6543. +
  6544. +   } else {
  6545. +       Multi_loss_base = val_f;
  6546. +   }
  6547.  }
  6548.  
  6549. -DCF(loss_min, "")
  6550. +DCF(loss_min, "Sets the loss min value (Multiplayer)")
  6551.  {
  6552. +   int val_i;
  6553. +   float val_f;
  6554. +
  6555.     // if the lag system isn't inited, don't do anything
  6556.     if(!Multi_lag_inited){
  6557.         dc_printf("Lag System Not Initialized!\n");
  6558.         return;
  6559.     }
  6560.  
  6561. +   if (dc_optional_string_either("help", "--help")) {
  6562. +       multi_lagloss_dcf();
  6563. +       return;
  6564. +   }
  6565. +
  6566. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  6567. +       dc_printf("loss_min value is currently %f percent", Multi_loss_min);
  6568. +   }
  6569. +
  6570.     // parse the argument and change things around accordingly
  6571. -   dc_get_arg(ARG_INT);
  6572. -   if(Dc_arg_type & ARG_INT){         
  6573. -      float val = (float)Dc_arg_int / 100.0f;
  6574. +   dc_stuff_int(&val_i);
  6575. +
  6576. +   val_f = (float)val_i / 100.0f;
  6577.  
  6578. -       if(val > Multi_loss_base){
  6579. -           dc_printf("Min value greater than base value, ignoring...");
  6580. +   if(val_f > Multi_loss_base){
  6581. +       dc_printf("Min value greater than base value, ignoring...");
  6582. +   } else {
  6583. +       // otherwise set the value
  6584. +       if (val_f < 0) {
  6585. +           Multi_loss_min = -1.0f;
  6586.         } else {
  6587. -           // otherwise set the value
  6588. -           if(Dc_arg_int < 0){
  6589. -               Multi_loss_min = -1.0f;
  6590. -           } else {
  6591. -               Multi_loss_min = val;
  6592. -           }
  6593. -           multi_lagloss_dcf();
  6594. +           Multi_loss_min = val_f;
  6595.         }
  6596.     }
  6597.  }
  6598.  
  6599. -DCF(loss_max, "")
  6600. -{ 
  6601. +DCF(loss_max, "Sets the loss max value (Multiplayer)")
  6602. +{
  6603. +   int val_i;
  6604. +   float val_f;
  6605.     // if the lag system isn't inited, don't do anything
  6606.     if(!Multi_lag_inited){
  6607.         dc_printf("Lag System Not Initialized!\n");
  6608.         return;
  6609.     }
  6610.  
  6611. +   if (dc_optional_string_either("help", "--help")) {
  6612. +       multi_lagloss_dcf();
  6613. +       return;
  6614. +   }
  6615. +
  6616. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  6617. +       dc_printf("loss_max value is currently %f percent", Multi_loss_max);
  6618. +   }
  6619. +
  6620.     // parse the argument and change things around accordingly
  6621. -   dc_get_arg(ARG_INT);
  6622. -   if(Dc_arg_type & ARG_INT){         
  6623. -      float val = (float)Dc_arg_int / 100.0f;
  6624. +   dc_stuff_int(&val_i);
  6625. +   val_f = (float)val_i / 100.0f;
  6626.  
  6627. -       if(val < Multi_loss_base){
  6628. -           dc_printf("Max value smaller than base value, ignoring...");
  6629. +   if (val_f < Multi_loss_base) {
  6630. +       dc_printf("Max value smaller than base value, ignoring...");
  6631. +   } else {
  6632. +       // otherwise set the value
  6633. +       if (val_f < 0) {
  6634. +           Multi_loss_max = -1.0f;
  6635.         } else {
  6636. -           // otherwise set the value
  6637. -           if(Dc_arg_int < 0){
  6638. -               Multi_loss_max = -1.0f;
  6639. -           } else {
  6640. -               Multi_loss_min = val;
  6641. -           }
  6642. -           multi_lagloss_dcf();
  6643. +           Multi_loss_max = val_f;
  6644.         }
  6645. -   }          
  6646. +   }
  6647.  }
  6648.  
  6649. -DCF(lagloss, "")
  6650. +DCF(lagloss, "Help provider for the lag system (Multiplayer)")
  6651.  {
  6652.     // if the lag system isn't inited, don't do anything
  6653.     if(!Multi_lag_inited){
  6654. @@ -587,29 +696,46 @@ DCF(lagloss, "")
  6655.     multi_lagloss_dcf();
  6656.  }
  6657.  
  6658. -DCF(lag_streak, "")
  6659. +DCF(lag_streak, "Sets the duration of lag streaks (Multiplayer)")
  6660.  {
  6661. +   int val;
  6662. +
  6663.     // if the lag system isn't inited, don't do anything
  6664. -   if(!Multi_lag_inited){
  6665. +   if (!Multi_lag_inited) {
  6666.         dc_printf("Lag System Not Initialized!\n");
  6667.         return;
  6668.     }
  6669.  
  6670. -   dc_get_arg(ARG_INT);
  6671. -   if(Dc_arg_type & ARG_INT){                     
  6672. -       if(Dc_arg_int >= 0){
  6673. -           Multi_streak_time = Dc_arg_int;
  6674. -       }
  6675. +   if (dc_optional_string_either("help", "--help")) {
  6676. +       multi_lagloss_dcf();
  6677. +       return;
  6678. +   }
  6679. +
  6680. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  6681. +       dc_printf("lag_streak value is currently %i", Multi_streak_time);
  6682. +       return;
  6683. +   }
  6684. +
  6685. +   dc_stuff_int(&val);
  6686. +   if(val >= 0){
  6687. +       Multi_streak_time = val;
  6688. +   } else {
  6689. +       dc_printf("Ignoring invalid value (must be non-negative)\n");
  6690.     }
  6691.  }
  6692.  
  6693. -DCF(lag_bad, "")
  6694. +DCF(lag_bad, "Lag system shortcut - Sets for 'bad' lag simulation (Multiplayer)")
  6695.  {
  6696.     // if the lag system isn't inited, don't do anything
  6697.     if(!Multi_lag_inited){
  6698.         dc_printf("Lag System Not Initialized!\n");
  6699.         return;
  6700.     }
  6701. +  
  6702. +   if (dc_optional_string_either("help", "--help")) {
  6703. +       multi_lagloss_dcf();
  6704. +       return;
  6705. +   }
  6706.  
  6707.     dc_printf("Setting bad lag/loss parameters\n");
  6708.  
  6709. @@ -627,7 +753,7 @@ DCF(lag_bad, "")
  6710.     Multi_current_streak = -1;
  6711.  }
  6712.  
  6713. -DCF(lag_avg, "")
  6714. +DCF(lag_avg, "Lag system shortcut - Sets for 'average' lag simulation (Multiplayer)")
  6715.  {
  6716.     // if the lag system isn't inited, don't do anything
  6717.     if(!Multi_lag_inited){
  6718. @@ -635,6 +761,11 @@ DCF(lag_avg, "")
  6719.         return;
  6720.     }
  6721.  
  6722. +   if (dc_optional_string_either("help", "--help")) {
  6723. +       multi_lagloss_dcf();
  6724. +       return;
  6725. +   }
  6726. +
  6727.     dc_printf("Setting avg lag/loss parameters\n");
  6728.  
  6729.     // set good lagloss parameters
  6730. @@ -651,7 +782,7 @@ DCF(lag_avg, "")
  6731.     Multi_current_streak = -1;
  6732.  }
  6733.  
  6734. -DCF(lag_good, "")
  6735. +DCF(lag_good, "Lag system shortcut - Sets for 'good' lag simulation (Multiplayer)")
  6736.  {
  6737.     // if the lag system isn't inited, don't do anything
  6738.     if(!Multi_lag_inited){
  6739. @@ -659,6 +790,11 @@ DCF(lag_good, "")
  6740.         return;
  6741.     }
  6742.  
  6743. +   if (dc_optional_string_either("help", "--help")) {
  6744. +       multi_lagloss_dcf();
  6745. +       return;
  6746. +   }
  6747. +
  6748.     dc_printf("Setting good lag/loss parameters\n");
  6749.  
  6750.     // set good lagloss parameters
  6751. Index: code/network/multiui.cpp
  6752. ===================================================================
  6753. --- code/network/multiui.cpp    (revision 10462)
  6754. +++ code/network/multiui.cpp    (working copy)
  6755. @@ -64,6 +64,7 @@
  6756.  #include "cfile/cfile.h"
  6757.  #include "fs2netd/fs2netd_client.h"
  6758.  #include "menuui/mainhallmenu.h"
  6759. +#include "debugconsole/console.h"
  6760.  
  6761.  #include <algorithm>
  6762.  
  6763. @@ -754,13 +755,20 @@ int multi_join_maybe_warn();
  6764.  int multi_join_warn_pxo();
  6765.  void multi_join_blit_protocol();
  6766.  
  6767. -DCF(mj_make, "")
  6768. +DCF(mj_make, "Makes a multijoin game? (Multiplayer)")
  6769.  {
  6770.     active_game ag, *newitem;
  6771.     int idx;
  6772. +   int idx_max;
  6773.  
  6774. -   dc_get_arg(ARG_INT);
  6775. -   for(idx=0; idx<Dc_arg_int; idx++){
  6776. +   if (dc_optional_string_either("help", "--help")) {
  6777. +       dc_printf("Usage: mj_make <num_games>\n");
  6778. +       return;
  6779. +   }
  6780. +
  6781. +   dc_stuff_int(&idx_max);
  6782. +
  6783. +   for(idx = 0; idx < idx_max; idx++){
  6784.         // stuff some fake info
  6785.         memset(&ag, 0, sizeof(active_game));
  6786.         sprintf(ag.name, "Game %d", idx);
  6787. @@ -776,7 +784,7 @@ DCF(mj_make, "")
  6788.         if(newitem != NULL){
  6789.             // newitem->heard_from_timer = timestamp((int)frand_range(500.0f, 10000.0f));
  6790.         }
  6791. -   }  
  6792. +   }
  6793.  }
  6794.  
  6795.  void multi_join_notify_new_game()
  6796. Index: code/network/multiutil.cpp
  6797. ===================================================================
  6798. --- code/network/multiutil.cpp  (revision 10462)
  6799. +++ code/network/multiutil.cpp  (working copy)
  6800. @@ -77,6 +77,7 @@
  6801.  #include "network/multi_rate.h"
  6802.  #include "fs2netd/fs2netd_client.h"
  6803.  #include "parse/parselo.h"
  6804. +#include "debugconsole/console.h"
  6805.  
  6806.  extern int ascii_table[];
  6807.  extern int shifted_ascii_table[];
  6808. @@ -3198,65 +3199,73 @@ short multi_get_new_id()
  6809.  // ------------------------------------
  6810.  
  6811.  //XSTR:OFF
  6812. -DCF(multi,"changes multiplayer settings")
  6813. +DCF(multi,"changes multiplayer settings (Multiplayer)")
  6814.  {
  6815. -   if(Dc_command){
  6816. -       dc_get_arg(ARG_STRING);
  6817. -      
  6818. -       if(strcmp(Dc_arg, "kick")==0){              // kick a player
  6819. -           multi_dcf_kick();
  6820. +   if (dc_optional_string("kick")) {
  6821. +       // kick a player
  6822. +       multi_dcf_kick();
  6823. +
  6824.  #ifndef NDEBUG
  6825. -       } else if(strcmp(Dc_arg, "stats")==0) {
  6826. -           // multi_toggle_stats();
  6827. -       } else if(strcmp(Dc_arg, "show_stats")==0) {
  6828. -           // multi_show_basic_stats(0);
  6829. -       } else if(strcmp(Dc_arg, "dump_stats")==0) {
  6830. -           // multi_show_basic_stats(1);
  6831. +   } else if (dc_optional_string("stats")) {
  6832. +       // multi_toggle_stats();
  6833. +
  6834. +   } else if (dc_optional_string("show_stats")) {
  6835. +       // multi_show_basic_stats(0);
  6836. +
  6837. +   } else if (dc_optional_string("dump_stats")) {
  6838. +       // multi_show_basic_stats(1);
  6839.  #endif
  6840. -       } else if(strcmp(Dc_arg, "voice")==0){              // settings for multiplayer voice
  6841. -           multi_voice_dcf();
  6842. -       } else if(strcmp(Dc_arg, "respawn_chump")==0){  // set a really large # of respawns
  6843. -           if((Net_player != NULL) && (Net_player->flags & NETINFO_FLAG_GAME_HOST)){          
  6844. -               Netgame.respawn = 9999;
  6845. -               Netgame.options.respawn = 9999;            
  6846. -
  6847. -               // if i'm the server, send a netgame update
  6848. -               if(Net_player->flags & NETINFO_FLAG_AM_MASTER){
  6849. -                   send_netgame_update_packet();
  6850. -               }
  6851. -           }
  6852. -       } else if(strcmp(Dc_arg, "ss_leaders")==0){     // only host or team captains can modify ships
  6853. -           if((Net_player != NULL) && (Net_player->flags & NETINFO_FLAG_GAME_HOST)){          
  6854. -               Netgame.options.flags |= MSO_FLAG_SS_LEADERS;
  6855. -               multi_options_update_netgame();
  6856. -           }
  6857. -       } else if(strcmp(Dc_arg, "make_players")==0){
  6858. +
  6859. +   } else if (dc_optional_string("voice")) {
  6860. +       // settings for multiplayer voice
  6861. +       multi_voice_dcf();
  6862. +
  6863. +   } else if (dc_optional_string("respawn_chump")){
  6864. +       // set a really large # of respawns
  6865. +       if((Net_player != NULL) && (Net_player->flags & NETINFO_FLAG_GAME_HOST)) {
  6866. +           Netgame.respawn = 9999;
  6867. +           Netgame.options.respawn = 9999;
  6868. +
  6869. +           // if i'm the server, send a netgame update
  6870. +           if(Net_player->flags & NETINFO_FLAG_AM_MASTER){
  6871. +               send_netgame_update_packet();
  6872. +           }
  6873. +       }
  6874. +
  6875. +   } else if (dc_optional_string("ss_leaders")) {
  6876. +       // only host or team captains can modify ships
  6877. +       if((Net_player != NULL) && (Net_player->flags & NETINFO_FLAG_GAME_HOST)) {
  6878. +           Netgame.options.flags |= MSO_FLAG_SS_LEADERS;
  6879. +           multi_options_update_netgame();
  6880. +       }
  6881. +
  6882. +   } else if (dc_optional_string("make_players")) {
  6883.  #ifndef NDEBUG
  6884. -           multi_make_fake_players(MAX_PLAYERS);
  6885. +       multi_make_fake_players(MAX_PLAYERS);
  6886.  #endif
  6887. -       } else if(strcmp(Dc_arg, "givecd")==0){
  6888. -           extern int Multi_has_cd;
  6889. -           Multi_has_cd = 1;
  6890. -       } else if(strcmp(Dc_arg, "oo")==0){                    
  6891. -           int new_flags = -1;
  6892. -
  6893. -           dc_get_arg(ARG_INT);
  6894. -           if(Dc_arg_type & ARG_INT){
  6895. -               new_flags = Dc_arg_int;
  6896. -           }
  6897.  
  6898. -           dc_printf("Interesting flags\nPos : %d\nVelocity : %d\nDesired vel : %d\nOrient : %d\nRotvel : %d\nDesired rotvel %d\n",
  6899. -                        1<<0, 1<<7, 1<<8, 1<<1, 1<<9, 1<<10);                     
  6900. -       } else if(strcmp(Dc_arg, "oo_sort")==0){           
  6901. -           extern int OO_sort;
  6902. +   } else if (dc_optional_string("givecd")) {
  6903. +       extern int Multi_has_cd;
  6904. +       Multi_has_cd = 1;
  6905.  
  6906. -           OO_sort = !OO_sort;
  6907. -           if(OO_sort){
  6908. -               dc_printf("Network object sorting ENABLED\n");
  6909. -           } else {
  6910. -               dc_printf("Network object sorting DISABLED\n");
  6911. -           }
  6912. -       }
  6913. +   } else if (dc_optional_string("oo")) {
  6914. +       int new_flags = -1;
  6915. +
  6916. +       dc_maybe_stuff_int(&new_flags);
  6917. +
  6918. +       dc_printf("Interesting flags\n");
  6919. +       dc_printf("Pos : %d\n", 1 << 0);
  6920. +       dc_printf("Velocity    : %d\n", 1 << 7);
  6921. +       dc_printf("Desired vel : %d\n", 1 << 8);
  6922. +       dc_printf("Orient : %d\n", 1 << 1);
  6923. +       dc_printf("Rotvel : %d\n", 1 << 9);
  6924. +       dc_printf("Desired rotvel : %d\n", 1 << 10);
  6925. +
  6926. +   } else if (dc_optional_string("oo_sort")) {
  6927. +       extern int OO_sort;
  6928. +
  6929. +       OO_sort = !OO_sort;
  6930. +       dc_printf("Network object sorting %s\n", OO_sort ? "ENABLED" : "DISABLED");
  6931.     }
  6932.  }
  6933.  
  6934. @@ -3447,19 +3456,20 @@ Done:
  6935.  }
  6936.  */
  6937.  
  6938. -DCF(pxospew,"spew PXO 32 bit checksums for all visible mission files")
  6939. +DCF(pxospew,"spew PXO 32 bit checksums for all visible mission files (Multiplayer)")
  6940.  {
  6941.     int max_files;
  6942. +   char file_str[MAX_NAME_LEN];
  6943.  
  6944. -   dc_get_arg(ARG_INT);
  6945. -   if(Dc_arg_type & ARG_INT){
  6946. -       max_files = Dc_arg_int;
  6947. -
  6948. -       dc_get_arg(ARG_STRING);
  6949. -       if(Dc_arg_type & ARG_STRING){
  6950. -           multi_spew_pxo_checksums(max_files, Dc_arg);
  6951. -       }
  6952. +   if (dc_optional_string_either("help", "--help")) {
  6953. +       dc_printf("Usage: pxospew <max_files> <filename>\n");
  6954. +       return;
  6955.     }
  6956. +
  6957. +   dc_stuff_int(&max_files);
  6958. +   dc_stuff_string_white(file_str, MAX_NAME_LEN);
  6959. +
  6960. +   multi_spew_pxo_checksums(max_files, file_str);
  6961.  }
  6962.  
  6963.  
  6964. Index: code/object/collideshipship.cpp
  6965. ===================================================================
  6966. --- code/object/collideshipship.cpp (revision 10462)
  6967. +++ code/object/collideshipship.cpp (working copy)
  6968. @@ -27,6 +27,7 @@
  6969.  #include "object/objectdock.h"
  6970.  #include "object/objectshield.h"
  6971.  #include "parse/scripting.h"
  6972. +#include "debugconsole/console.h"
  6973.  
  6974.  
  6975.  #define COLLIDE_DEBUG
  6976. Index: code/object/object.cpp
  6977. ===================================================================
  6978. --- code/object/object.cpp  (revision 10462)
  6979. +++ code/object/object.cpp  (working copy)
  6980. @@ -41,6 +41,7 @@
  6981.  #include "weapon/shockwave.h"
  6982.  #include "weapon/swarm.h"
  6983.  #include "weapon/weapon.h"
  6984. +#include "debugconsole/console.h"
  6985.  
  6986.  
  6987.  
  6988. Index: code/object/objectsnd.cpp
  6989. ===================================================================
  6990. --- code/object/objectsnd.cpp   (revision 10462)
  6991. +++ code/object/objectsnd.cpp   (working copy)
  6992. @@ -22,7 +22,7 @@
  6993.  #include "render/3d.h"
  6994.  #include "io/joy_ff.h"
  6995.  #include "species_defs/species_defs.h"
  6996. -
  6997. +#include "debugconsole/console.h"
  6998.  
  6999.  
  7000.  //  // --mharris port hack--
  7001. @@ -96,62 +96,65 @@ void obj_snd_source_pos(vec3d *sound_pos, obj_snd *osp)
  7002.  //XSTR:OFF
  7003.  DCF(objsnd, "Persistent sound stuff" )
  7004.  {
  7005. -   char        buf1[16], buf2[64];
  7006. -   obj_snd *osp;
  7007. +   char buf1[4];
  7008. +   char buf2[MAX_NAME_LEN];
  7009. +   obj_snd *osp;
  7010. +   SCP_string arg;
  7011. +
  7012. +   if (dc_optional_string_either("help", "--help")) {
  7013. +       dc_printf ("Usage: objsnd [-list]\n");
  7014. +       dc_printf ("[-list] --  displays status of all objects with linked sounds\n");
  7015. +       dc_printf ("with no parameters, object sounds are toggled on/off\n");
  7016. +       return;
  7017. +   }
  7018.  
  7019. -   if ( Dc_command )   {
  7020. -       dc_get_arg(ARG_STRING|ARG_NONE);
  7021. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  7022. +       dc_printf( "Object sounds are: %s\n", (Obj_snd_enabled?"ON":"OFF") );
  7023. +   }
  7024. +  
  7025. +   if (dc_optional_string("-list")) {
  7026. +       for ( osp = GET_FIRST(&obj_snd_list); osp !=END_OF_LIST(&obj_snd_list); osp = GET_NEXT(osp) ) {
  7027. +           vec3d source_pos;
  7028. +           float distance;
  7029.  
  7030. -       if ( Dc_arg_type & ARG_NONE ) {
  7031. -           if ( Obj_snd_enabled == TRUE ) {
  7032. -               obj_snd_stop_all();
  7033. -               Obj_snd_enabled = FALSE;
  7034. +           Assert(osp != NULL);
  7035. +           if ( osp->instance == -1 ) {
  7036. +               continue;
  7037. +               //sprintf(buf1,"OFF");
  7038. +           } else {
  7039. +               sprintf(buf1,"ON");
  7040. +           }
  7041. +
  7042. +           if ( Objects[osp->objnum].type == OBJ_SHIP ) {
  7043. +               strcpy_s(buf2, Ships[Objects[osp->objnum].instance].ship_name);
  7044. +           }
  7045. +           else if ( Objects[osp->objnum].type == OBJ_DEBRIS ) {
  7046. +               sprintf(buf2, "Debris");
  7047.             }
  7048.             else {
  7049. -               Obj_snd_enabled = TRUE;
  7050. +               sprintf(buf2, "Unknown");
  7051.             }
  7052. -       }
  7053. -       if ( !stricmp( Dc_arg, "list" ))    {
  7054. -           for ( osp = GET_FIRST(&obj_snd_list); osp !=END_OF_LIST(&obj_snd_list); osp = GET_NEXT(osp) ) {
  7055. -               Assert(osp != NULL);
  7056. -               if ( osp->instance == -1 ) {
  7057. -                   continue;
  7058. -                   //sprintf(buf1,"OFF");
  7059. -               } else {
  7060. -                   sprintf(buf1,"ON");
  7061. -               }
  7062.  
  7063. -               if ( Objects[osp->objnum].type == OBJ_SHIP ) {
  7064. -                   strcpy_s(buf2, Ships[Objects[osp->objnum].instance].ship_name);
  7065. -               }
  7066. -               else if ( Objects[osp->objnum].type == OBJ_DEBRIS ) {
  7067. -                   sprintf(buf2, "Debris");
  7068. -               }
  7069. -               else {
  7070. -                   sprintf(buf2, "Unknown");
  7071. -               }
  7072. +           obj_snd_source_pos(&source_pos, osp);
  7073. +           distance = vm_vec_dist_quick( &source_pos, &View_position );
  7074.  
  7075. -               vec3d source_pos;
  7076. -               float distance;
  7077. -
  7078. -               obj_snd_source_pos(&source_pos, osp);
  7079. -               distance = vm_vec_dist_quick( &source_pos, &View_position );
  7080. -
  7081. -               dc_printf("Object %d => name: %s vol: %.2f pan: %.2f dist: %.2f status: %s\n", osp->objnum, buf2, osp->vol, osp->pan, distance, buf1);
  7082. -           } // end for
  7083. -               dc_printf("Number object-linked sounds playing: %d\n", Num_obj_sounds_playing);
  7084. -       }
  7085. -   }
  7086. +           dc_printf("Object %d => name: %s vol: %.2f pan: %.2f dist: %.2f status: %s\n", osp->objnum, buf2, osp->vol, osp->pan, distance, buf1);
  7087. +       } // end for
  7088.  
  7089. -   if ( Dc_help ) {
  7090. -       dc_printf ("Usage: objsnd [list]\n");
  7091. -       dc_printf ("[list] --  displays status of all objects with linked sounds\n");
  7092. -       dc_printf ("with no parameters, object sounds are toggled on/off\n");
  7093. -       Dc_status = 0;
  7094. +       dc_printf("Number object-linked sounds playing: %d\n", Num_obj_sounds_playing);
  7095. +       return;
  7096.     }
  7097.  
  7098. -   if ( Dc_status )    {
  7099. -       dc_printf( "Object sounds are: %s\n", (Obj_snd_enabled?"ON":"OFF") );
  7100. +   if (!dc_maybe_stuff_string_white(arg)) {
  7101. +       // No arguments, toggle snd on/off
  7102. +       if ( Obj_snd_enabled == TRUE ) {
  7103. +               obj_snd_stop_all();
  7104. +               Obj_snd_enabled = FALSE;
  7105. +           } else {
  7106. +               Obj_snd_enabled = TRUE;
  7107. +       }
  7108. +   } else {
  7109. +       dc_printf("Unknown argument '%s'\n", arg);
  7110.     }
  7111.  }
  7112.  //XSTR:ON
  7113. Index: code/palman/palman.cpp
  7114. ===================================================================
  7115. --- code/palman/palman.cpp  (revision 10462)
  7116. +++ code/palman/palman.cpp  (working copy)
  7117. @@ -11,6 +11,7 @@
  7118.  
  7119.  #include "palman/palman.h"
  7120.  #include "bmpman/bmpman.h"
  7121. +#include "debugconsole/console.h"
  7122.  #include "pcxutils/pcxutils.h"
  7123.  #include "parse/parselo.h"
  7124.  #include "graphics/grinternal.h"
  7125. @@ -165,17 +166,14 @@ void palette_load_table( const char * filename )
  7126.  
  7127.  DCF(palette,"Loads a new palette")
  7128.  {
  7129. -   if ( Dc_command )   {
  7130. -       dc_get_arg(ARG_STRING|ARG_NONE);
  7131. -       if ( Dc_arg_type == ARG_NONE )  {
  7132. -       } else {
  7133. -           palette_load_table( Dc_arg );
  7134. -       }
  7135. -   }
  7136. -   if ( Dc_help )  {
  7137. -       dc_printf( "Usage: palette filename\nLoads the palette file.\n" );
  7138. +   char palette_file[MAX_FILENAME_LEN];
  7139. +
  7140. +   if (dc_optional_string_either("help", "--help")) {
  7141. +       dc_printf( "Usage: palette <filename>\nLoads the palette file.\n" );
  7142.     }
  7143.  
  7144. +   dc_stuff_string_white(palette_file, MAX_FILENAME_LEN);
  7145. +   palette_load_table(palette_file);
  7146.  }
  7147.  
  7148.  int Palman_allow_any_color = 0;
  7149. Index: code/parse/sexp.cpp
  7150. ===================================================================
  7151. --- code/parse/sexp.cpp (revision 10462)
  7152. +++ code/parse/sexp.cpp (working copy)
  7153. @@ -96,6 +96,7 @@
  7154.  #include "mod_table/mod_table.h"
  7155.  #include "ship/afterburner.h"
  7156.  #include "globalincs/alphacolors.h"
  7157. +#include "debugconsole/console.h"
  7158.  
  7159.  #ifndef NDEBUG
  7160.  #include "hud/hudmessage.h"
  7161. @@ -24451,40 +24452,38 @@ int run_sexp(const char* sexpression)
  7162.     return sexp_val;
  7163.  }
  7164.  
  7165. -DCF(sexpc, "Always runs the given sexp command ")
  7166. +DCF(sexpc, "Always runs the given sexp command (Warning! There is no undo for this!)")
  7167.  {
  7168. -   if ( Dc_command )       {
  7169. -       if (Dc_command_line != NULL) {
  7170. -           char buf[8192];
  7171. -           snprintf(buf, 8191, "( when ( true ) ( %s ) )", Dc_command_line);
  7172. -
  7173. -           int sexp_val = run_sexp( buf );
  7174. -           dc_printf("SEXP '%s' run, sexp_val = %d\n", buf, sexp_val);
  7175. -           do {
  7176. -               dc_get_arg(ARG_ANY);
  7177. -           } while (Dc_arg_type != ARG_NONE);
  7178. -       }
  7179. -   }
  7180. -   if ( Dc_help )  {
  7181. +   SCP_string sexp;
  7182. +   SCP_string sexp_always;
  7183. +  
  7184. +   if (dc_optional_string_either("help", "--help")) {
  7185.         dc_printf( "Usage: sexpc sexpression\n. Always runs the given sexp as '( when ( true ) ( sexp ) )' .\n" );
  7186. +       return;
  7187.     }
  7188. +
  7189. +   dc_stuff_string(sexp);
  7190. +
  7191. +   sprintf(sexp_always, "( when ( true ) ( %s ) )", sexp);
  7192. +
  7193. +   int sexp_val = run_sexp(sexp_always.c_str());
  7194. +   dc_printf("SEXP '%s' run, sexp_val = %d\n", sexp_always, sexp_val);
  7195.  }
  7196.  
  7197.  
  7198.  DCF(sexp,"Runs the given sexp")
  7199.  {
  7200. -   if ( Dc_command )       {
  7201. -       if (Dc_command_line != NULL) {
  7202. -           int sexp_val = run_sexp( Dc_command_line );
  7203. -           dc_printf("SEXP '%s' run, sexp_val = %d\n", Dc_command_line, sexp_val);
  7204. -           do {
  7205. -               dc_get_arg(ARG_ANY);
  7206. -           } while (Dc_arg_type != ARG_NONE);
  7207. -       }
  7208. -   }
  7209. -   if ( Dc_help )  {
  7210. +   SCP_string sexp;
  7211. +
  7212. +   if (dc_optional_string_either("help", "--help")) {
  7213.         dc_printf( "Usage: sexp 'sexpression'\n. Runs the given sexp.\n");
  7214. +       return;
  7215.     }
  7216. +
  7217. +   dc_stuff_string(sexp);
  7218. +
  7219. +   int sexp_val = run_sexp(sexp.c_str());
  7220. +   dc_printf("SEXP '%s' run, sexp_val = %d\n", dc_command_str, sexp_val);
  7221.  }
  7222.  
  7223.  
  7224. Index: code/particle/particle.cpp
  7225. ===================================================================
  7226. --- code/particle/particle.cpp  (revision 10462)
  7227. +++ code/particle/particle.cpp  (working copy)
  7228. @@ -17,6 +17,7 @@
  7229.  #include "object/object.h"
  7230.  #include "cmdline/cmdline.h"
  7231.  #include "graphics/grbatch.h"
  7232. +#include "debugconsole/console.h"
  7233.  
  7234.  #ifndef NDEBUG
  7235.  #include "io/timer.h"
  7236. @@ -90,18 +91,7 @@ void particle_page_in()
  7237.     bm_page_in_texture( Anim_bitmap_id_smoke2 );
  7238.  }
  7239.  
  7240. -DCF(particles,"Turns particles on/off")
  7241. -{
  7242. -   if ( Dc_command )   {  
  7243. -       dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);       
  7244. -       if ( Dc_arg_type & ARG_TRUE )   Particles_enabled = 1
  7245. -       else if ( Dc_arg_type & ARG_FALSE ) Particles_enabled = 0
  7246. -       else if ( Dc_arg_type & ARG_NONE ) Particles_enabled ^= 1
  7247. -   }  
  7248. -   if ( Dc_help )  dc_printf( "Usage: particles [bool]\nTurns particle system on/off.  If nothing passed, then toggles it.\n" );  
  7249. -   if ( Dc_status )    dc_printf( "particles are %s\n", (Particles_enabled?"ON":"OFF") )
  7250. -}
  7251. -
  7252. +DCF_BOOL2(particles, Particles_enabled, "Turns particles on/off", "Usage: particles [bool]\nTurns particle system on/off.  If nothing passed, then toggles it.\n");
  7253.  
  7254.  int Num_particles_hwm = 0;
  7255.  
  7256. Index: code/playerman/playercontrol.cpp
  7257. ===================================================================
  7258. --- code/playerman/playercontrol.cpp    (revision 10462)
  7259. +++ code/playerman/playercontrol.cpp    (working copy)
  7260. @@ -34,6 +34,7 @@
  7261.  #include "network/multiutil.h"
  7262.  #include "network/multi_obj.h"
  7263.  #include "parse/parselo.h"
  7264. +#include "debugconsole/console.h"
  7265.  
  7266.  #ifndef NDEBUG
  7267.  #include "io/key.h"
  7268. @@ -286,10 +287,16 @@ void do_view_chase(float frame_time)
  7269.  
  7270.  float camera_zoom_scale = 1.0f;
  7271.  
  7272. -DCF(camera_speed, "")
  7273. +DCF(camera_speed, "Sets the camera zoom scale")
  7274.  {
  7275. -   dc_get_arg(ARG_FLOAT);
  7276. -   camera_zoom_scale = Dc_arg_float;
  7277. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  7278. +       dc_printf("Camera zoom scale is %f\n", camera_zoom_scale);
  7279. +       return;
  7280. +   }
  7281. +
  7282. +   dc_stuff_float(&camera_zoom_scale);
  7283. +
  7284. +   dc_printf("Camera zoom scale set to %f\n", camera_zoom_scale);
  7285.  }
  7286.  
  7287.  void do_view_external(float frame_time)
  7288. Index: code/radar/radarsetup.cpp
  7289. ===================================================================
  7290. --- code/radar/radarsetup.cpp   (revision 10462)
  7291. +++ code/radar/radarsetup.cpp   (working copy)
  7292. @@ -31,6 +31,7 @@
  7293.  #include "radar/radarsetup.h"
  7294.  #include "iff_defs/iff_defs.h"
  7295.  #include "globalincs/linklist.h"
  7296. +#include "debugconsole/console.h"
  7297.  
  7298.  int Radar_static_looping = -1;
  7299.  
  7300. @@ -84,7 +85,7 @@ extern int radar_iff_color[5][2][4];
  7301.  
  7302.  int See_all = 0;
  7303.  
  7304. -DCF_BOOL(see_all, See_all)
  7305. +DCF_BOOL(see_all, See_all);
  7306.  
  7307.  static const char radar_default_filenames[2][16]=
  7308.  {
  7309. Index: code/render/3dlaser.cpp
  7310. ===================================================================
  7311. --- code/render/3dlaser.cpp (revision 10462)
  7312. +++ code/render/3dlaser.cpp (working copy)
  7313. @@ -14,6 +14,7 @@
  7314.  #include "globalincs/systemvars.h"
  7315.  #include "io/key.h"
  7316.  #include "cmdline/cmdline.h"
  7317. +#include "debugconsole/console.h"
  7318.  
  7319.  
  7320.  
  7321. Index: code/ship/ship.cpp
  7322. ===================================================================
  7323. --- code/ship/ship.cpp  (revision 10462)
  7324. +++ code/ship/ship.cpp  (working copy)
  7325. @@ -80,6 +80,7 @@
  7326.  #include "graphics/gropenglshader.h"
  7327.  #include "model/model.h"
  7328.  #include "mod_table/mod_table.h"
  7329. +#include "debugconsole/console.h"
  7330.  
  7331.  
  7332.  #define NUM_SHIP_SUBSYSTEM_SETS            20      // number of subobject sets to use (because of the fact that it's a linked list,
  7333. @@ -8356,10 +8357,14 @@ int ship_subsys_disrupted(ship *sp, int type)
  7334.  }
  7335.  
  7336.  float Decay_rate = 1.0f / 120.0f;
  7337. -DCF(lethality_decay, "time in sec to return from 100 to 0")
  7338. +DCF(lethality_decay, "Sets ship lethality_decay, or the time in sec to go from 100 to 0 health (default is 1/120)")
  7339.  {
  7340. -   dc_get_arg(ARG_FLOAT);
  7341. -   Decay_rate = Dc_arg_float;
  7342. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  7343. +       dc_printf("Decay rate is currently %f\n", Decay_rate);
  7344. +       return;
  7345. +   }
  7346. +  
  7347. +   dc_stuff_float(&Decay_rate);
  7348.  }
  7349.  
  7350.  float min_lethality = 0.0f;
  7351. @@ -9865,31 +9870,44 @@ float t_len = 10.0f;
  7352.  float t_vel = 0.2f;
  7353.  float t_min = 150.0f;
  7354.  float t_max = 300.0f;
  7355. -DCF(t_rad, "")
  7356. +DCF(t_rad, "Sets weapon tracer radius")
  7357.  {
  7358. -   dc_get_arg(ARG_FLOAT);
  7359. -   t_rad = Dc_arg_float;
  7360. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  7361. +       dc_printf("t_rad : %f\n", t_rad);
  7362. +       return;
  7363. +   }
  7364. +  
  7365. +   dc_stuff_float(&t_rad);
  7366.  }
  7367. -DCF(t_len, "")
  7368. +DCF(t_len, "Sets weapon tracer length")
  7369.  {
  7370. -   dc_get_arg(ARG_FLOAT);
  7371. -   t_len = Dc_arg_float;
  7372. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  7373. +       dc_printf("t_len : %f\n", t_len);
  7374. +       return;
  7375. +   }
  7376. +
  7377. +   dc_stuff_float(&t_len);
  7378.  }
  7379. -DCF(t_vel, "")
  7380. +DCF(t_vel, "Sets weapon tracer velocity")
  7381.  {
  7382. -   dc_get_arg(ARG_FLOAT);
  7383. -   t_vel = Dc_arg_float;
  7384. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  7385. +       dc_printf("t_vel : %f\n", t_vel);
  7386. +       return;
  7387. +   }
  7388. +
  7389. +   dc_stuff_float(&t_vel);
  7390.  }
  7391. +/*
  7392. + TODO: These two DCF's (and variables) are unused
  7393.  DCF(t_min, "")
  7394.  {
  7395. -   dc_get_arg(ARG_FLOAT);
  7396. -   t_min = Dc_arg_float;
  7397. +   dc_stuff_float(&t_min);
  7398.  }
  7399.  DCF(t_max, "")
  7400.  {
  7401. -   dc_get_arg(ARG_FLOAT);
  7402. -   t_max = Dc_arg_float;
  7403. +   dc_stuff_float(&t_max);
  7404.  }
  7405. +*/
  7406.  void ship_fire_tracer(int weapon_objnum)
  7407.  {
  7408.     particle_info pinfo;
  7409. @@ -13610,26 +13628,25 @@ void ship_assign_sound_all()
  7410.   */
  7411.  DCF(set_shield,"Change player ship shield strength")
  7412.  {
  7413. -   if ( Dc_command )   {
  7414. -       dc_get_arg(ARG_FLOAT|ARG_NONE);
  7415. -
  7416. -       if ( Dc_arg_type & ARG_FLOAT ) {
  7417. -            CLAMP(Dc_arg_float, 0.0f, 1.0f);
  7418. -           shield_set_strength(Player_obj, Dc_arg_float * Player_ship->ship_max_shield_strength);
  7419. -           dc_printf("Shields set to %.2f\n", shield_get_strength(Player_obj) );
  7420. -       }
  7421. -   }
  7422. +   float value;
  7423.  
  7424. -   if ( Dc_help ) {
  7425. +   if (dc_optional_string_either("help", "--help")) {
  7426.         dc_printf ("Usage: set_shield [num]\n");
  7427.         dc_printf ("[num] --  shield percentage 0.0 -> 1.0 of max\n");
  7428. -       dc_printf ("with no parameters, displays shield strength\n");
  7429. -       Dc_status = 0;
  7430. +       return;
  7431.     }
  7432.  
  7433. -   if ( Dc_status )    {
  7434. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  7435.         dc_printf( "Shields are currently %.2f", shield_get_strength(Player_obj) );
  7436. +       return;
  7437.     }
  7438. +
  7439. +   dc_stuff_float(&value);
  7440. +
  7441. +   CLAMP(value, 0.0f, 1.0f);
  7442. +
  7443. +   shield_set_strength(Player_obj, value * Player_ship->ship_max_shield_strength);
  7444. +   dc_printf("Shields set to %.2f\n", shield_get_strength(Player_obj) );
  7445.  }
  7446.  
  7447.  /**
  7448. @@ -13637,26 +13654,24 @@ DCF(set_shield,"Change player ship shield strength")
  7449.   */
  7450.  DCF(set_hull, "Change player ship hull strength")
  7451.  {
  7452. -   if ( Dc_command )   {
  7453. -       dc_get_arg(ARG_FLOAT|ARG_NONE);
  7454. -
  7455. -       if ( Dc_arg_type & ARG_FLOAT ) {
  7456. -           CLAMP(Dc_arg_float, 0.0f, 1.0f);
  7457. -           Player_obj->hull_strength = Dc_arg_float * Player_ship->ship_max_hull_strength;
  7458. -           dc_printf("Hull set to %.2f\n", Player_obj->hull_strength );
  7459. -       }
  7460. -   }
  7461. -
  7462. -   if ( Dc_help ) {
  7463. +   float value;
  7464. +  
  7465. +   if (dc_optional_string_either("help", "--help")) {
  7466.         dc_printf ("Usage: set_hull [num]\n");
  7467.         dc_printf ("[num] --  hull percentage 0.0 -> 1.0 of max\n");
  7468. -       dc_printf ("with no parameters, displays hull strength\n");
  7469. -       Dc_status = 0;
  7470. +       return;
  7471.     }
  7472.  
  7473. -   if ( Dc_status )    {
  7474. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  7475.         dc_printf( "Hull is currently %.2f", Player_obj->hull_strength );
  7476. +       return;
  7477.     }
  7478. +
  7479. +   dc_stuff_float(&value);
  7480. +
  7481. +   CLAMP(value, 0.0f, 1.0f);
  7482. +   Player_obj->hull_strength = value * Player_ship->ship_max_hull_strength;
  7483. +   dc_printf("Hull set to %.2f\n", Player_obj->hull_strength );
  7484.  }
  7485.  
  7486.  /**
  7487. @@ -13665,70 +13680,65 @@ DCF(set_hull, "Change player ship hull strength")
  7488.  //XSTR:OFF
  7489.  DCF(set_subsys, "Set the strength of a particular subsystem on player ship" )
  7490.  {
  7491. -   if ( Dc_command )   {
  7492. -       dc_get_arg(ARG_STRING);
  7493. -       if ( !subsystem_stricmp( Dc_arg, "weapons" ))   {
  7494. -           dc_get_arg(ARG_FLOAT);
  7495. -           if ( (Dc_arg_float < 0.0f) || (Dc_arg_float > 1.0f) )   {
  7496. -               Dc_help = 1;
  7497. -           } else {
  7498. -               ship_set_subsystem_strength( Player_ship, SUBSYSTEM_WEAPONS, Dc_arg_float );
  7499. -           }
  7500. -       } else if ( !subsystem_stricmp( Dc_arg, "engine" )) {
  7501. -           dc_get_arg(ARG_FLOAT);
  7502. -           if ( (Dc_arg_float < 0.0f) || (Dc_arg_float > 1.0f) )   {
  7503. -               Dc_help = 1;
  7504. -           } else {
  7505. -               ship_set_subsystem_strength( Player_ship, SUBSYSTEM_ENGINE, Dc_arg_float );
  7506. -               if ( Dc_arg_float < ENGINE_MIN_STR )    {
  7507. -                   Player_ship->flags |= SF_DISABLED;              // add the disabled flag
  7508. -               } else {
  7509. -                   Player_ship->flags &= (~SF_DISABLED);               // add the disabled flag
  7510. -               }
  7511. -           }
  7512. -       } else if ( !subsystem_stricmp( Dc_arg, "sensors" ))    {
  7513. -           dc_get_arg(ARG_FLOAT);
  7514. -           if ( (Dc_arg_float < 0.0f) || (Dc_arg_float > 1.0f) )   {
  7515. -               Dc_help = 1;
  7516. -           } else {
  7517. -               ship_set_subsystem_strength( Player_ship, SUBSYSTEM_SENSORS, Dc_arg_float );
  7518. -           }
  7519. -       } else if ( !subsystem_stricmp( Dc_arg, "communication" ))  {
  7520. -           dc_get_arg(ARG_FLOAT);
  7521. -           if ( (Dc_arg_float < 0.0f) || (Dc_arg_float > 1.0f) )   {
  7522. -               Dc_help = 1;
  7523. -           } else {
  7524. -               ship_set_subsystem_strength( Player_ship, SUBSYSTEM_COMMUNICATION, Dc_arg_float );
  7525. -           }
  7526. -       } else if ( !subsystem_stricmp( Dc_arg, "navigation" )) {
  7527. -           dc_get_arg(ARG_FLOAT);
  7528. -           if ( (Dc_arg_float < 0.0f) || (Dc_arg_float > 1.0f) )   {
  7529. -               Dc_help = 1;
  7530. -           } else {
  7531. -               ship_set_subsystem_strength( Player_ship, SUBSYSTEM_NAVIGATION, Dc_arg_float );
  7532. -           }
  7533. -       } else if ( !subsystem_stricmp( Dc_arg, "radar" ))  {
  7534. -           dc_get_arg(ARG_FLOAT);
  7535. -           if ( (Dc_arg_float < 0.0f) || (Dc_arg_float > 1.0f) )   {
  7536. -               Dc_help = 1;
  7537. -           } else {
  7538. -               ship_set_subsystem_strength( Player_ship, SUBSYSTEM_RADAR, Dc_arg_float );
  7539. -           }
  7540. -       } else {
  7541. -           // print usage
  7542. -           Dc_help = 1;
  7543. -       }
  7544. +   SCP_string arg;
  7545. +   int subsystem = SUBSYSTEM_NONE;
  7546. +   float val_f;
  7547. +  
  7548. +   if (dc_optional_string_either("help", "--help")) {
  7549. +       dc_printf( "Usage: set_subsys <type> [--status] <strength>\n");
  7550. +       dc_printf("<type> is any of the following:\n");
  7551. +       dc_printf("\tweapons\n");
  7552. +       dc_printf("\tengine\n");
  7553. +       dc_printf("\tsensors\n");
  7554. +       dc_printf("\tcommunication\n");
  7555. +       dc_printf("\tnavigation\n");
  7556. +       dc_printf("\tradar\n\n");
  7557. +
  7558. +       dc_printf("[--status] will display status of that subsystem\n\n");
  7559. +      
  7560. +       dc_printf("<strength> is any value between 0 and 1.0\n");
  7561. +       return;
  7562.     }
  7563.  
  7564. -   if ( Dc_help )  {
  7565. -       dc_printf( "Usage: set_subsys type X\nWhere X is value between 0 and 1.0, and type can be:\n" );
  7566. -       dc_printf( "weapons\n" );
  7567. -       dc_printf( "engine\n" );
  7568. -       dc_printf( "sensors\n" );
  7569. -       dc_printf( "communication\n" );
  7570. -       dc_printf( "navigation\n" );
  7571. -       dc_printf( "radar\n" );
  7572. -       Dc_status = 0;  // don't print status if help is printed.  Too messy.
  7573. +   dc_stuff_string_white(arg);
  7574. +
  7575. +   if (arg == "weapons") {
  7576. +       subsystem = SUBSYSTEM_WEAPONS;
  7577. +  
  7578. +   } else if (arg == "engine") {
  7579. +       subsystem = SUBSYSTEM_ENGINE;  
  7580. +  
  7581. +   } else if (arg == "sensors") {
  7582. +       subsystem = SUBSYSTEM_SENSORS;
  7583. +
  7584. +   } else if (arg == "communication") {
  7585. +       subsystem = SUBSYSTEM_COMMUNICATION;
  7586. +
  7587. +   } else if (arg == "navigation") {
  7588. +       subsystem = SUBSYSTEM_NAVIGATION;
  7589. +
  7590. +   } else if (arg == "radar") {
  7591. +       subsystem = SUBSYSTEM_RADAR;
  7592. +
  7593. +   } else {
  7594. +       dc_printf("Erro: Unknown argument '%s'\n", arg);
  7595. +       return;
  7596. +   }
  7597. +
  7598. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  7599. +       dc_printf("Subsystem '%s' is at %f strength\n", arg, ship_get_subsystem_strength(Player_ship, subsystem));
  7600. +
  7601. +   } else {
  7602. +       // Set the subsystem strength
  7603. +       dc_stuff_float(&val_f);
  7604. +
  7605. +       CLAMP(val_f, 0.0, 1.0);
  7606. +       ship_set_subsystem_strength( Player_ship, subsystem, val_f );
  7607. +      
  7608. +       if (subsystem == SUBSYSTEM_ENGINE) {
  7609. +           // If subsystem is an engine, set/clear the disabled flag
  7610. +           (val_f < ENGINE_MIN_STR) ? (Player_ship->flags |= SF_DISABLED) : (Player_ship->flags &= (~SF_DISABLED));
  7611. +       }
  7612.     }
  7613.  }
  7614.  //XSTR:ON
  7615. @@ -16419,11 +16429,11 @@ int ship_get_texture(int bitmap)
  7616.  // update artillery lock info
  7617.  #define CLEAR_ARTILLERY_AND_CONTINUE() { if(aip != NULL){ aip->artillery_objnum = -1; aip->artillery_sig = -1; aip->artillery_lock_time = 0.0f;} continue; }
  7618.  float artillery_dist = 10.0f;
  7619. -DCF(art, "")
  7620. +DCF(art, "Sets artillery disance")
  7621.  {
  7622. -   dc_get_arg(ARG_FLOAT);
  7623. -   artillery_dist = Dc_arg_float;
  7624. +   dc_stuff_float(&artillery_dist);
  7625.  }
  7626. +
  7627.  void ship_update_artillery_lock()
  7628.  {
  7629.     ai_info *aip = NULL;
  7630. Index: code/ship/shipfx.cpp
  7631. ===================================================================
  7632. --- code/ship/shipfx.cpp    (revision 10462)
  7633. +++ code/ship/shipfx.cpp    (working copy)
  7634. @@ -40,6 +40,7 @@
  7635.  #include "bmpman/bmpman.h"
  7636.  #include "model/model.h"
  7637.  #include "cmdline/cmdline.h"
  7638. +#include "debugconsole/console.h"
  7639.  
  7640.  
  7641.  #ifndef NDEBUG
  7642. @@ -1355,42 +1356,58 @@ void shipfx_flash_do_frame(float frametime)
  7643.  }
  7644.  
  7645.  float Particle_width = 1.2f;
  7646. -DCF(particle_width, "Multiplier for angular width of the particle spew")
  7647. +DCF(particle_width, "Sets multiplier for angular width of the particle spew ( 0 - 5)")
  7648.  {
  7649. -   if ( Dc_command ) {
  7650. -       dc_get_arg(ARG_FLOAT);
  7651. -       if ( (Dc_arg_float >= 0 ) && (Dc_arg_float <= 5) ) {
  7652. -           Particle_width = Dc_arg_float;
  7653. -       } else {
  7654. -           dc_printf( "Illegal value for particle width. (Must be from 0-5) \n\n");
  7655. -       }
  7656. +   float value;
  7657. +
  7658. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  7659. +       dc_printf("Particle_width : %f\n", Particle_width);
  7660. +       return;
  7661.     }
  7662. +
  7663. +   dc_stuff_float(&value);
  7664. +
  7665. +   CLAMP(value, 0.0, 5.0);
  7666. +   Particle_width = value;
  7667. +
  7668. +   dc_printf("Particle_width set to %f\n", Particle_width);
  7669.  }
  7670.  
  7671.  float Particle_number = 1.2f;
  7672. -DCF(particle_num, "Multiplier for the number of particles created")
  7673. +DCF(particle_num, "Sets multiplier for the number of particles created")
  7674.  {
  7675. -   if ( Dc_command ) {
  7676. -       dc_get_arg(ARG_FLOAT);
  7677. -       if ( (Dc_arg_float >= 0 ) && (Dc_arg_float <= 5) ) {
  7678. -           Particle_number = Dc_arg_float;
  7679. -       } else {
  7680. -           dc_printf( "Illegal value for particle num. (Must be from 0-5) \n\n");
  7681. -       }
  7682. +  
  7683. +   float value;
  7684. +
  7685. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  7686. +       dc_printf("Particle_number : %f\n", Particle_number);
  7687. +       return;
  7688.     }
  7689. +
  7690. +   dc_stuff_float(&value);
  7691. +
  7692. +   CLAMP(value, 0.0, 5.0);
  7693. +   Particle_number = value;
  7694. +
  7695. +   dc_printf("Particle_number set to %f\n", Particle_number);
  7696.  }
  7697.  
  7698.  float Particle_life = 1.2f;
  7699.  DCF(particle_life, "Multiplier for the lifetime of particles created")
  7700.  {
  7701. -   if ( Dc_command ) {
  7702. -       dc_get_arg(ARG_FLOAT);
  7703. -       if ( (Dc_arg_float >= 0 ) && (Dc_arg_float <= 5) ) {
  7704. -           Particle_life = Dc_arg_float;
  7705. -       } else {
  7706. -           dc_printf( "Illegal value for particle life. (Must be from 0-5) \n\n");
  7707. -       }
  7708. +   float value;
  7709. +
  7710. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  7711. +       dc_printf("Particle_life : %f\n", Particle_life);
  7712. +       return;
  7713.     }
  7714. +
  7715. +   dc_stuff_float(&value);
  7716. +
  7717. +   CLAMP(value, 0.0, 5.0);
  7718. +   Particle_life = value;
  7719. +
  7720. +   dc_printf("Particle_life set to %f\n", Particle_life);
  7721.  }
  7722.  
  7723.  // Make sparks fly off of ship n.
  7724. @@ -1602,16 +1619,20 @@ int Bs_exp_fire_low = 1;
  7725.  float  Bs_exp_fire_time_mult = 1.0f;
  7726.  
  7727.  DCF_BOOL(bs_exp_fire_low, Bs_exp_fire_low)
  7728. -DCF(bs_exp_fire_time_mult, "Multiplier time between fireball in big ship explosion")
  7729. +DCF(bs_exp_fire_time_mult, "Sets multiplier time between fireball in big ship explosion")
  7730.  {
  7731. -   if ( Dc_command ) {
  7732. -       dc_get_arg(ARG_FLOAT);
  7733. -       if ( (Dc_arg_float >= 0.1 ) && (Dc_arg_float <= 5) ) {
  7734. -           Bs_exp_fire_time_mult = Dc_arg_float;
  7735. -       } else {
  7736. -           dc_printf( "Illegal value for bs_exp_fire_time_mult. (Must be from 0.1-5) \n\n");
  7737. -       }
  7738. +   float value;
  7739. +
  7740. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  7741. +       dc_printf("Bs_exp_fire_time_mult : %f\n", Bs_exp_fire_time_mult);
  7742. +       return;
  7743.     }
  7744. +
  7745. +   dc_stuff_float(&value);
  7746. +
  7747. +   CLAMP(value, 0.1f, 5.0f);
  7748. +   Bs_exp_fire_time_mult = value;
  7749. +   dc_printf("Bs_exp_fire_time_mult set to %f\n", Bs_exp_fire_time_mult);
  7750.  }
  7751.  
  7752.  
  7753. Index: code/sound/sound.cpp
  7754. ===================================================================
  7755. --- code/sound/sound.cpp    (revision 10462)
  7756. +++ code/sound/sound.cpp    (working copy)
  7757. @@ -15,6 +15,7 @@
  7758.  #include "cmdline/cmdline.h"
  7759.  #include "osapi/osapi.h"
  7760.  #include "globalincs/vmallocator.h"
  7761. +#include "debugconsole/console.h"
  7762.  
  7763.  #include "gamesnd/gamesnd.h"
  7764.  #include "globalincs/alphacolors.h"
  7765. @@ -200,14 +201,15 @@ void snd_spew_info()
  7766.  }
  7767.  
  7768.  int Sound_spew = 0;
  7769. -DCF(show_sounds, "")
  7770. +DCF(show_sounds, "Toggles display of sound debug info")
  7771.  {
  7772. -   Sound_spew = !Sound_spew;
  7773. -   if(Sound_spew){
  7774. -       dc_printf("Sound debug info ON");
  7775. -   } else {
  7776. -       dc_printf("Sound debug info OFF");
  7777. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  7778. +       dc_printf("Sound debug info is %s", (Sound_spew ? "ON" : "OFF"));
  7779. +       return;
  7780.     }
  7781. +
  7782. +   Sound_spew = !Sound_spew;
  7783. +   dc_printf("Sound debug info is %s", (Sound_spew ? "ON" : "OFF"));
  7784.  }
  7785.  void snd_spew_debug_info()
  7786.  {
  7787. Index: code/starfield/nebula.cpp
  7788. ===================================================================
  7789. --- code/starfield/nebula.cpp   (revision 10462)
  7790. +++ code/starfield/nebula.cpp   (working copy)
  7791. @@ -15,7 +15,7 @@
  7792.  #include "mission/missionparse.h"
  7793.  #include "nebula/neb.h"
  7794.  #include "cfile/cfile.h"
  7795. -
  7796. +#include "debugconsole/console.h"
  7797.  
  7798.  
  7799.  #define MAX_TRIS 200
  7800. @@ -215,17 +215,19 @@ void nebula_render()
  7801.  
  7802.  DCF(nebula,"Loads a different nebula")
  7803.  {
  7804. -   if ( Dc_command )   {
  7805. -       dc_get_arg(ARG_STRING|ARG_NONE);
  7806. -       if ( Dc_arg_type == ARG_NONE )  {
  7807. -           nebula_close();
  7808. -       } else {
  7809. -           nebula_init( Dc_arg );
  7810. -       }
  7811. +   char filename[MAX_NAME_LEN];
  7812. +
  7813. +   if (dc_optional_string_either("help", "--help")) {
  7814. +       dc_printf("Usage: nebula [filename]\n");
  7815. +       dc_printf("Loads the nebula file. No filename takes away nebula\n" );
  7816. +       return;
  7817. +   }
  7818. +
  7819. +   if (dc_maybe_stuff_string_white(filename, MAX_NAME_LEN)) {
  7820. +           nebula_init(filename);
  7821. +   } else {
  7822. +       nebula_close();
  7823.     }
  7824. -   if ( Dc_help )  {
  7825. -       dc_printf( "Usage: nebula filename\nLoads the nebula file. No filename takes away nebula\n" );
  7826. -   }  
  7827.  }
  7828.  
  7829.  
  7830. Index: code/starfield/starfield.cpp
  7831. ===================================================================
  7832. --- code/starfield/starfield.cpp    (revision 10462)
  7833. +++ code/starfield/starfield.cpp    (working copy)
  7834. @@ -25,6 +25,7 @@
  7835.  #include "parse/parselo.h"
  7836.  #include "hud/hud.h"
  7837.  #include "hud/hudtarget.h"
  7838. +#include "debugconsole/console.h"
  7839.  
  7840.  
  7841.  #define MAX_DEBRIS_VCLIPS          4
  7842. @@ -865,75 +866,11 @@ uint Star_flags = STAR_FLAG_DEFAULT;
  7843.  //XSTR:OFF
  7844.  DCF(stars,"Set parameters for starfield")
  7845.  {
  7846. -   if ( Dc_command ) {
  7847. -       dc_get_arg(ARG_STRING);
  7848. -       if ( !strcmp( Dc_arg, "tail" )) {
  7849. -           dc_get_arg(ARG_FLOAT);
  7850. -           if ( (Dc_arg_float < 0.0f) || (Dc_arg_float > 1.0f) ) {
  7851. -               Dc_help = 1;
  7852. -           } else {
  7853. -               Star_amount = Dc_arg_float;
  7854. -           }
  7855. -       } else if ( !strcmp( Dc_arg, "len" )) {
  7856. -           dc_get_arg(ARG_FLOAT);
  7857. -           Star_max_length = Dc_arg_float;
  7858. -       } else if ( !strcmp( Dc_arg, "dim" )) {
  7859. -           dc_get_arg(ARG_FLOAT);
  7860. -           if ( Dc_arg_float < 0.0f ) {
  7861. -               Dc_help = 1;
  7862. -           } else {
  7863. -               Star_dim = Dc_arg_float;
  7864. -           }
  7865. -       } else if ( !strcmp( Dc_arg, "flag" )) {
  7866. -           dc_get_arg(ARG_STRING);
  7867. -           if ( !strcmp( Dc_arg, "tail" )) {
  7868. -               Star_flags ^= STAR_FLAG_TAIL;
  7869. -           } else if ( !strcmp( Dc_arg, "dim" )) {
  7870. -               Star_flags ^= STAR_FLAG_DIM;
  7871. -           } else if ( !strcmp( Dc_arg, "aa" )) {
  7872. -               Star_flags ^= STAR_FLAG_ANTIALIAS;
  7873. -           } else {
  7874. -               Dc_help = 1;
  7875. -           }
  7876. -       } else if ( !strcmp( Dc_arg, "cap" )) {
  7877. -           dc_get_arg(ARG_FLOAT);
  7878. -           if ( (Dc_arg_float < 0.0f) || (Dc_arg_float > 255.0f) ) {
  7879. -               Dc_help = 1;
  7880. -           } else {
  7881. -               Star_cap = Dc_arg_float;
  7882. -           }
  7883. -       } else if ( !strcmp( Dc_arg, "m0" )) {
  7884. -           Star_amount = 0.0f;
  7885. -           Star_dim = 0.0f;
  7886. -           Star_cap = 0.0f;
  7887. -           Star_flags = 0;
  7888. -           Star_max_length = STAR_MAX_LENGTH_DEFAULT;
  7889. -       } else if ( !strcmp( Dc_arg, "m1" ) || !strcmp( Dc_arg, "default" )) {
  7890. -           Star_amount = STAR_AMOUNT_DEFAULT;
  7891. -           Star_dim = STAR_DIM_DEFAULT;
  7892. -           Star_cap = STAR_CAP_DEFAULT;
  7893. -           Star_flags = STAR_FLAG_DEFAULT;
  7894. -           Star_max_length = STAR_MAX_LENGTH_DEFAULT;
  7895. -       } else if ( !strcmp( Dc_arg, "m2" )) {
  7896. -           Star_amount = 0.75f;
  7897. -           Star_dim = 20.0f;
  7898. -           Star_cap = 75.0f;
  7899. -           Star_flags = STAR_FLAG_TAIL|STAR_FLAG_DIM|STAR_FLAG_ANTIALIAS;
  7900. -           Star_max_length = STAR_MAX_LENGTH_DEFAULT;
  7901. -       } else if ( !strcmp( Dc_arg, "num" )) {
  7902. -           dc_get_arg(ARG_INT);
  7903. -           if ( (Dc_arg_int < 0) || (Dc_arg_int > MAX_STARS) ) {
  7904. -               Dc_help = 1;
  7905. -           } else {
  7906. -               Num_stars = Dc_arg_int;
  7907. -           }
  7908. -       } else {
  7909. -           // print usage, not stats
  7910. -           Dc_help = 1;
  7911. -       }
  7912. -   }
  7913. +   SCP_string arg;
  7914. +   float val_f;
  7915. +   int val_i;
  7916.  
  7917. -   if ( Dc_help ) {
  7918. +   if (dc_optional_string_either("help", "--help")) {
  7919.         dc_printf( "Usage: stars keyword\nWhere keyword can be in the following forms:\n" );
  7920.         dc_printf( "stars default   Resets stars to all default values\n" );
  7921.         dc_printf( "stars num X     Sets number of stars to X.  Between 0 and %d.\n", MAX_STARS );
  7922. @@ -948,21 +885,105 @@ DCF(stars,"Set parameters for starfield")
  7923.         dc_printf( "\nHINT: set cap to 0 to get dim rate and tail down, then use\n" );
  7924.         dc_printf( "cap to keep the lines from going away when moving too fast.\n" );
  7925.         dc_printf( "\nUse '? stars' to see current values.\n" );
  7926. -       Dc_status = 0;  // don't print status if help is printed.  Too messy.
  7927. +       return; // don't print status if help is printed.  Too messy.
  7928.     }
  7929.  
  7930. -   if ( Dc_status ) {
  7931. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  7932.         dc_printf( "Num_stars: %d\n", Num_stars );
  7933.         dc_printf( "Tail: %.2f\n", Star_amount );
  7934. -       dc_printf( "Dim: %.2f\n", Star_dim );
  7935. -       dc_printf( "Cap: %.2f\n", Star_cap );
  7936. +       dc_printf( "Dim : %.2f\n", Star_dim );
  7937. +       dc_printf( "Cap : %.2f\n", Star_cap );
  7938.         dc_printf( "Max length: %.2f\n", Star_max_length );
  7939.         dc_printf( "Flags:\n" );
  7940. -       dc_printf( "  Tail: %s\n", (Star_flags&STAR_FLAG_TAIL?"On":"Off") );
  7941. -       dc_printf( "  Dim: %s\n", (Star_flags&STAR_FLAG_DIM?"On":"Off") );
  7942. +       dc_printf( "  Tail : %s\n", (Star_flags&STAR_FLAG_TAIL?"On":"Off") );
  7943. +       dc_printf( "  Dim  : %s\n", (Star_flags&STAR_FLAG_DIM?"On":"Off") );
  7944.         dc_printf( "  Antialias: %s\n", (Star_flags&STAR_FLAG_ANTIALIAS?"On":"Off") );
  7945.         dc_printf( "\nTHESE AREN'T SAVED TO DISK, SO IF YOU TWEAK\n" );
  7946.         dc_printf( "THESE AND LIKE THEM, WRITE THEM DOWN!!\n" );
  7947. +       return;
  7948. +   }
  7949. +
  7950. +   dc_stuff_string_white(arg);
  7951. +   // "stars default" is handled by "stars m1"
  7952. +   if (arg == "num") {
  7953. +       dc_stuff_int(&val_i);
  7954. +
  7955. +       CLAMP(val_i, 0, MAX_STARS);
  7956. +       Num_stars = val_i;
  7957. +
  7958. +       dc_printf("Num_stars set to %i\n", Num_stars);
  7959. +  
  7960. +   } else if (arg == "tail") {
  7961. +       dc_stuff_float(&val_f);
  7962. +       CLAMP(val_f, 0.0, 1.0);
  7963. +       Star_amount = val_f;
  7964. +      
  7965. +       dc_printf("Star_amount set to %f\n", Star_amount);
  7966. +
  7967. +   } else if (arg == "dim") {
  7968. +       dc_stuff_float(&val_f);
  7969. +
  7970. +       if (val_f > 0.0f ) {
  7971. +           Star_dim = val_f;
  7972. +           dc_printf("Star_dim set to %f\n", Star_dim);
  7973. +      
  7974. +       } else {
  7975. +           dc_printf("Error: Star_dim value must be non-negative\n");
  7976. +       }
  7977. +  
  7978. +   } else if (arg == "cap") {
  7979. +       dc_stuff_float(&val_f);
  7980. +       CLAMP(val_f, 0.0, 255);
  7981. +       Star_cap = val_f;
  7982. +      
  7983. +       dc_printf("Star_cap set to %f\n", Star_cap);
  7984. +  
  7985. +   } else if (arg == "len") {
  7986. +       dc_stuff_float(&Star_max_length);
  7987. +
  7988. +       dc_printf("Star_max_length set to %f\n", Star_max_length);
  7989. +
  7990. +   } else if (arg == "m0") {
  7991. +       Star_amount = 0.0f;
  7992. +       Star_dim = 0.0f;
  7993. +       Star_cap = 0.0f;
  7994. +       Star_flags = 0;
  7995. +       Star_max_length = STAR_MAX_LENGTH_DEFAULT;
  7996. +
  7997. +       dc_printf("Starfield set: Old 'pixel type' crappy stars. flags=none\n");
  7998. +  
  7999. +   } else if ((arg == "m1") || (arg == "default")) {
  8000. +       Star_amount = STAR_AMOUNT_DEFAULT;
  8001. +       Star_dim = STAR_DIM_DEFAULT;
  8002. +       Star_cap = STAR_CAP_DEFAULT;
  8003. +       Star_flags = STAR_FLAG_DEFAULT;
  8004. +       Star_max_length = STAR_MAX_LENGTH_DEFAULT;
  8005. +
  8006. +       dc_printf("Starfield set: (default) tail=.75, dim=20.0, cap=75.0, flags=dim,tail\n");
  8007. +
  8008. +   } else if (arg == "m2") {
  8009. +       Star_amount = 0.75f;
  8010. +       Star_dim = 20.0f;
  8011. +       Star_cap = 75.0f;
  8012. +       Star_flags = STAR_FLAG_TAIL|STAR_FLAG_DIM|STAR_FLAG_ANTIALIAS;
  8013. +       Star_max_length = STAR_MAX_LENGTH_DEFAULT;
  8014. +
  8015. +       dc_printf("Starfield set: tail=.75, dim=20.0, cap=75.0, flags=dim,tail,aa\n");
  8016. +
  8017. +   } else if (arg == "flag") {
  8018. +       dc_stuff_string_white(arg);
  8019. +       if (arg == "tail") {
  8020. +           Star_flags ^= STAR_FLAG_TAIL;
  8021. +       } else if (arg == "dim" ) {
  8022. +           Star_flags ^= STAR_FLAG_DIM;
  8023. +       } else if (arg == "aa" ) {
  8024. +           Star_flags ^= STAR_FLAG_ANTIALIAS;
  8025. +       } else {
  8026. +           dc_printf("Error: unknown flag argument '%s'\n", arg);
  8027. +       }
  8028. +
  8029. +   } else {
  8030. +       dc_printf("Error: Unknown argument '%s'", arg);
  8031.     }
  8032.  }
  8033.  //XSTR:ON
  8034. @@ -1283,39 +1304,44 @@ float Subspace_glow_rate = 1.0f;
  8035.  //XSTR:OFF
  8036.  DCF(subspace_set,"Set parameters for subspace effect")
  8037.  {
  8038. -   if ( Dc_command ) {
  8039. -       dc_get_arg(ARG_STRING);
  8040. -       if ( !strcmp( Dc_arg, "u" )) {
  8041. -           dc_get_arg(ARG_FLOAT);
  8042. -           if ( Dc_arg_float < 0.0f ) {
  8043. -               Dc_help = 1;
  8044. -           } else {
  8045. -               subspace_u_speed = Dc_arg_float;
  8046. -           }
  8047. -       } else if ( !strcmp( Dc_arg, "v" )) {
  8048. -           dc_get_arg(ARG_FLOAT);
  8049. -           if ( Dc_arg_float < 0.0f ) {
  8050. -               Dc_help = 1;
  8051. -           } else {
  8052. -               subspace_v_speed = Dc_arg_float;
  8053. -           }
  8054. -       } else {
  8055. -           // print usage, not stats
  8056. -           Dc_help = 1;
  8057. -       }
  8058. -   }
  8059. -
  8060. -   if ( Dc_help ) {
  8061. -       dc_printf( "Usage: subspace keyword\nWhere keyword can be in the following forms:\n" );
  8062. -       dc_printf( "subspace u X    Where X is how fast u moves.\n", MAX_STARS );
  8063. -       dc_printf( "subspace v X    Where X is how fast v moves.\n" );
  8064. -       dc_printf( "\nUse '? subspace' to see current values.\n" );
  8065. -       Dc_status = 0;  // don't print status if help is printed.  Too messy.
  8066. +   SCP_string arg;
  8067. +   float value;
  8068. +
  8069. +   if (dc_optional_string_either("help", "--help")) {
  8070. +       dc_printf( "Usage: subspace [--status] <axis> <speed>\n");
  8071. +       dc_printf("[--status] -- Displays the current speeds for both axes\n");
  8072. +       dc_printf("<axis>  -- May be either 'u' or 'v', and corresponds to the texture axis\n");
  8073. +       dc_printf("<speed> -- is the speed along the axis that the texture is moved\n");
  8074. +       return;
  8075.     }
  8076.  
  8077. -   if ( Dc_status ) {
  8078. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  8079.         dc_printf( "u: %.2f\n", subspace_u_speed );
  8080.         dc_printf( "v: %.2f\n", subspace_v_speed );
  8081. +       return;
  8082. +   }
  8083. +
  8084. +   dc_stuff_string_white(arg);
  8085. +   if (arg == "u") {
  8086. +       dc_stuff_float(&value);
  8087. +
  8088. +       if ( value < 0.0f ) {
  8089. +           dc_printf("Error: speed must be non-negative");
  8090. +           return;
  8091. +       }
  8092. +       subspace_u_speed = value;
  8093. +
  8094. +   } else if (arg == "v") {
  8095. +       dc_stuff_float(&value);
  8096. +
  8097. +       if (value < 0.0f) {
  8098. +           dc_printf("Error: speed must be non-negative");
  8099. +           return;
  8100. +       }
  8101. +       subspace_v_speed = value;
  8102. +
  8103. +   } else {
  8104. +       dc_printf("Error: Unknown axis '%s'", arg);
  8105.     }
  8106.  }
  8107.  //XSTR:ON
  8108. Index: code/starfield/supernova.cpp
  8109. ===================================================================
  8110. --- code/starfield/supernova.cpp    (revision 10462)
  8111. +++ code/starfield/supernova.cpp    (working copy)
  8112. @@ -21,6 +21,7 @@
  8113.  #include "gamesequence/gamesequence.h"
  8114.  #include "gamesnd/gamesnd.h"
  8115.  #include "cmdline/cmdline.h"
  8116. +#include "debugconsole/console.h"
  8117.  
  8118.  // --------------------------------------------------------------------------------------------------------------------------
  8119.  // SUPERNOVA DEFINES/VARS
  8120. @@ -116,11 +117,8 @@ void supernova_stop()
  8121.  
  8122.  
  8123.  int sn_particles = 100;
  8124. -DCF(sn_part, "")
  8125. -{
  8126. -   dc_get_arg(ARG_INT);
  8127. -   sn_particles = Dc_arg_int;
  8128. -}
  8129. +DCF_INT2(sn_part, sn_particles, 0, INT_MAX, "Sets number of supernova particles (default is 100)");
  8130. +
  8131.  void supernova_do_particles()
  8132.  {
  8133.     int idx;
  8134. @@ -181,11 +179,7 @@ void supernova_do_particles()
  8135.  
  8136.  // call once per frame
  8137.  float sn_shudder = 0.45f;
  8138. -DCF(sn_shud, "")
  8139. -{
  8140. -   dc_get_arg(ARG_FLOAT);
  8141. -   sn_shudder = Dc_arg_float;
  8142. -}
  8143. +DCF_FLOAT2(sn_shud, sn_shudder, 0.0, FLT_MAX, "Sets camera shudder rate for being in supernova shockwave (default is 0.45)");
  8144.  
  8145.  void supernova_process()
  8146.  {
  8147. @@ -318,17 +312,10 @@ int supernova_camera_cut()
  8148.  // get view params from supernova
  8149.  float sn_distance = 300.0f;                // shockwave moving at 1000/ms ?
  8150.  float sn_cam_distance = 25.0f;
  8151. -DCF(sn_dist, "")
  8152. -{
  8153. -   dc_get_arg(ARG_FLOAT);
  8154. -   sn_distance = Dc_arg_float;
  8155. -}
  8156. +DCF_FLOAT2(sn_dist, sn_distance, 0.0, FLT_MAX, "Sets supernova shockwave distance (default is 300.0f)");
  8157.  
  8158. -DCF(sn_cam_dist, "")
  8159. -{
  8160. -   dc_get_arg(ARG_FLOAT);
  8161. -   sn_cam_distance = Dc_arg_float;
  8162. -}
  8163. +
  8164. +DCF_FLOAT2(sn_cam_dist, sn_cam_distance, 0.0, FLT_MAX, "Sets supernova camera distance (default is 25.0f)");
  8165.  
  8166.  void supernova_get_eye(vec3d *eye_pos, matrix *eye_orient)
  8167.  {
  8168. Index: code/stats/medals.cpp
  8169. ===================================================================
  8170. --- code/stats/medals.cpp   (revision 10462)
  8171. +++ code/stats/medals.cpp   (working copy)
  8172. @@ -21,6 +21,7 @@
  8173.  #include "globalincs/alphacolors.h"
  8174.  #include "localization/localize.h"
  8175.  #include "parse/parselo.h"
  8176. +#include "debugconsole/console.h"
  8177.  
  8178.  #ifndef NDEBUG
  8179.  #include "cmdline/cmdline.h"
  8180. @@ -437,78 +438,17 @@ void parse_medal_tbl()
  8181.  DCF(medals, "Grant or revoke medals")
  8182.  {
  8183.     int i;
  8184. +   int idx;
  8185.  
  8186. -   if (Dc_command)
  8187. -   {
  8188. -       dc_get_arg(ARG_STRING | ARG_INT | ARG_NONE);
  8189. -
  8190. -       if (Dc_arg_type & ARG_INT)
  8191. -       {
  8192. -           int idx = Dc_arg_int;
  8193. -
  8194. -           if (idx < 0 || idx >= Num_medals)
  8195. -           {
  8196. -               dc_printf("Medal index %d is out of range\n", idx);
  8197. -               return;
  8198. -           }
  8199. -
  8200. -           dc_printf("Granted %s\n", Medals[idx].name);
  8201. -           Player->stats.medal_counts[idx]++;
  8202. -       }
  8203. -       else if (Dc_arg_type & ARG_STRING)
  8204. -       {
  8205. -           if (!strcmp(Dc_arg, "all"))
  8206. -           {
  8207. -               for (i = 0; i < Num_medals; i++)
  8208. -                   Player->stats.medal_counts[i]++;
  8209. -
  8210. -               dc_printf("Granted all medals\n");
  8211. -           }
  8212. -           else if (!strcmp(Dc_arg, "clear"))
  8213. -           {
  8214. -               for (i = 0; i < Num_medals; i++)
  8215. -                   Player->stats.medal_counts[i] = 0;
  8216. -
  8217. -               dc_printf("Cleared all medals\n");
  8218. -           }
  8219. -           else if (!strcmp(Dc_arg, "demote"))
  8220. -           {
  8221. -               if (Player->stats.rank > 0)
  8222. -                   Player->stats.rank--;
  8223. -
  8224. -               dc_printf("Demoted to %s\n", Ranks[Player->stats.rank].name);
  8225. -           }
  8226. -           else if (!strcmp(Dc_arg, "promote"))
  8227. -           {
  8228. -               if (Player->stats.rank < MAX_FREESPACE2_RANK)
  8229. -                   Player->stats.rank++;
  8230. -
  8231. -               dc_printf("Promoted to %s\n", Ranks[Player->stats.rank].name);
  8232. -           }
  8233. -           else
  8234. -           {
  8235. -               Dc_help = 1;
  8236. -           }
  8237. -       }
  8238. -       else
  8239. -       {
  8240. -           dc_printf("The following medals are available:\n");
  8241. -           for (i = 0; i < Num_medals; i++)
  8242. -               dc_printf("%d: %s\n", i, Medals[i].name);
  8243. -       }
  8244. -
  8245. -       Dc_status = 0;
  8246. -   }
  8247. -
  8248. -   if (Dc_help)
  8249. +   if (dc_optional_string_either("help", "--help"))
  8250.     {
  8251. -       dc_printf ("Usage: gimmemedals all | clear | promote | demote | [index]\n");
  8252. +       dc_printf ("Usage: medals all | clear | promote | demote | [index]\n");
  8253.         dc_printf ("       [index] --  index of medal to grant\n");
  8254.         dc_printf ("       with no parameters, displays the available medals\n");
  8255. -       Dc_status = 0;
  8256. +       return;
  8257.     }
  8258.  
  8259. -   if (Dc_status)
  8260. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?"))
  8261.     {
  8262.         dc_printf("You have the following medals:\n");
  8263.  
  8264. @@ -518,6 +458,53 @@ DCF(medals, "Grant or revoke medals")
  8265.                 dc_printf("%d %s\n", Player->stats.medal_counts[i], Medals[i].name);
  8266.         }
  8267.         dc_printf("%s\n", Ranks[Player->stats.rank].name);
  8268. +       return;
  8269. +   }
  8270. +
  8271. +   if (dc_optional_string("all")) {
  8272. +       for (i = 0; i < Num_medals; i++) {
  8273. +           Player->stats.medal_counts[i]++;
  8274. +       }
  8275. +       dc_printf("Granted all medals\n");
  8276. +       return;
  8277. +
  8278. +   } else if (dc_optional_string("clear")) {
  8279. +       for (i = 0; i < Num_medals; i++) {
  8280. +           Player->stats.medal_counts[i] = 0;
  8281. +       }
  8282. +       dc_printf("Cleared all medals\n");
  8283. +       return;
  8284. +
  8285. +   } else if (dc_optional_string("promote")) {
  8286. +       if (Player->stats.rank < MAX_FREESPACE2_RANK) {
  8287. +           Player->stats.rank++;
  8288. +       }
  8289. +       dc_printf("Promoted to %s\n", Ranks[Player->stats.rank].name);
  8290. +       return;
  8291. +
  8292. +   } else if (dc_optional_string("demote")) {
  8293. +       if (Player->stats.rank > 0) {
  8294. +           Player->stats.rank--;
  8295. +       }
  8296. +       dc_printf("Demoted to %s\n", Ranks[Player->stats.rank].name);
  8297. +       return;
  8298. +   }
  8299. +
  8300. +   if (dc_maybe_stuff_int(&idx)) {
  8301. +       if (idx < 0 || idx >= Num_medals)
  8302. +       {
  8303. +           dc_printf("Medal index %d is out of range\n", idx);
  8304. +           return;
  8305. +       }
  8306. +
  8307. +       dc_printf("Granted %s\n", Medals[idx].name);
  8308. +       Player->stats.medal_counts[idx]++;
  8309. +       return;
  8310. +   }
  8311. +
  8312. +   dc_printf("The following medals are available:\n");
  8313. +   for (i = 0; i < Num_medals; i++) {
  8314. +       dc_printf("%d: %s\n", i, Medals[i].name);
  8315.     }
  8316.  }
  8317.  
  8318. Index: code/stats/scoring.cpp
  8319. ===================================================================
  8320. --- code/stats/scoring.cpp  (revision 10462)
  8321. +++ code/stats/scoring.cpp  (working copy)
  8322. @@ -31,6 +31,7 @@
  8323.  #include "network/multi_pmsg.h"
  8324.  #include "ai/ai_profiles.h"
  8325.  #include "pilotfile/pilotfile.h"
  8326. +#include "debugconsole/console.h"
  8327.  
  8328.  /*
  8329.  // uncomment to get extra debug messages when a player scores
  8330. @@ -1509,20 +1510,42 @@ void scoring_bash_rank(player *pl,int rank)
  8331.     pl->stats.rank = rank;
  8332.  }
  8333.  
  8334. -DCF(rank, "changes scoring vars")
  8335. +DCF(rank, "changes player rank")
  8336.  {
  8337. -   if(Dc_command){    
  8338. -       dc_get_arg(ARG_INT);       
  8339. -      
  8340. -       // parse the argument and change things around accordingly     
  8341. -       if((Dc_arg_type & ARG_INT) && (Player != NULL)){                           
  8342. -           scoring_bash_rank(Player,Dc_arg_int);
  8343. -       }      
  8344. +   int rank;
  8345. +
  8346. +   if (dc_optional_string_either("help", "--help")) {
  8347. +       dc_printf("Usage: rank <index>\n");
  8348. +       dc_printf(" <index> The rank index you wish to have. For retail ranks, these correspond to:\n");
  8349. +       dc_printf("\t0 : Ensign\n");
  8350. +       dc_printf("\t1 : Lieutenant Junior Grade\n");
  8351. +       dc_printf("\t2 : Lietenant\n");
  8352. +       dc_printf("\t3 : Lieutenant Commander\n");
  8353. +       dc_printf("\t4 : Commander\n");
  8354. +       dc_printf("\t5 : Captain\n");
  8355. +       dc_printf("\t6 : Commodore\n");
  8356. +       dc_printf("\t7 : Rear Admiral\n");
  8357. +       dc_printf("\t8 : Vice Admiral\n");
  8358. +       dc_printf("\t9 : Admiral\n\n");
  8359. +       return;
  8360. +   }
  8361. +
  8362. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  8363. +       if (Player != NULL) {
  8364. +           dc_printf("Current rank is %i\n", Player->stats.rank);
  8365. +       } else {
  8366. +           dc_printf("Error! Current Player not active or loaded\n");
  8367. +       }
  8368. +   }
  8369. +
  8370. +   dc_stuff_int(&rank);
  8371. +  
  8372. +   // parse the argument and change things around accordingly
  8373. +   if (Player != NULL) {
  8374. +           scoring_bash_rank(Player, rank);
  8375. +   } else {
  8376. +       dc_printf("Error! Current Player not active or loaded\n");
  8377.     }
  8378. -   dc_printf("Usage\n0 : Ensign\n1 : Lieutenant Junior Grade\n");
  8379. -   dc_printf("2 : Lietenant\n3 : Lieutenant Commander\n");
  8380. -   dc_printf("4 : Commander\n5 : Captain\n6 : Commodore\n");
  8381. -   dc_printf("7 : Rear Admiral\n8 : Vice Admiral\n9 : Admiral");
  8382.  }
  8383.  
  8384.  void scoreing_close()
  8385. Index: code/weapon/beam.cpp
  8386. ===================================================================
  8387. --- code/weapon/beam.cpp    (revision 10462)
  8388. +++ code/weapon/beam.cpp    (working copy)
  8389. @@ -35,6 +35,7 @@
  8390.  #include "iff_defs/iff_defs.h"
  8391.  #include "globalincs/globals.h"
  8392.  #include "cmdline/cmdline.h"
  8393.  #include "parse/scripting.h"
  8394. +#include "debugconsole/console.h"
  8395.  
  8396.  extern int Cmdline_nohtl;
  8397. @@ -119,20 +120,22 @@ float b_whack_small = 2000.0f;    // used to be 500.0f with the retail whack bug
  8398.  float b_whack_big = 10000.0f;  // used to be 1500.0f with the retail whack bug
  8399.  float b_whack_damage = 150.0f;
  8400.  
  8401. -DCF(b_whack_small, "")
  8402. +DCF(b_whack_small, "Sets the whack factor for small whacks (Default is 2000f)")
  8403.  {
  8404. -   dc_get_arg(ARG_FLOAT);
  8405. -   b_whack_small = Dc_arg_float;
  8406. +   dc_stuff_float(&b_whack_small);
  8407.  }
  8408. -DCF(b_whack_big, "")
  8409. +DCF(b_whack_big, "Sets the whack factor for big whacks (Default is 10000f)")
  8410.  {
  8411. -   dc_get_arg(ARG_FLOAT);
  8412. -   b_whack_big = Dc_arg_float;
  8413. +   dc_stuff_float(&b_whack_big);
  8414.  }
  8415. -DCF(b_whack_damage, "")
  8416. +DCF(b_whack_damage, "Sets the whack damage threshold (Default is 150f)")
  8417.  {
  8418. -   dc_get_arg(ARG_FLOAT);
  8419. -   b_whack_damage = Dc_arg_float;
  8420. +   if (dc_optional_string_either("help", "--help")) {
  8421. +       dc_printf("Sets the threshold to determine whether a big whack or a small whack should be applied. Values equal or greater than this threshold will trigger a big whack, while smaller values will trigger a small whack\n");
  8422. +       return;
  8423. +   }
  8424. +
  8425. +   dc_stuff_float(&b_whack_damage);
  8426.  }
  8427.  
  8428.  
  8429. @@ -1254,10 +1257,9 @@ void beam_render(beam *b, float u_offset)
  8430.  
  8431.  // generate particles for the muzzle glow
  8432.  int hack_time = 100;
  8433. -DCF(h_time, "")
  8434. +DCF(h_time, "Sets the hack time for beam muzzle glow (Default is 100)")
  8435.  {
  8436. -   dc_get_arg(ARG_INT);
  8437. -   hack_time = Dc_arg_int;
  8438. +   dc_stuff_int(&hack_time);
  8439.  }
  8440.  
  8441.  void beam_generate_muzzle_particles(beam *b)
  8442. @@ -1479,10 +1481,9 @@ void beam_calc_facing_pts( vec3d *top, vec3d *bot, vec3d *fvec, vec3d *pos, floa
  8443.  
  8444.  // light scale factor
  8445.  float blight = 25.5f;
  8446. -DCF(blight, "")
  8447. +DCF(blight, "Sets the beam light scale factor (Default is 25.5f)")
  8448.  {
  8449. -   dc_get_arg(ARG_FLOAT);
  8450. -   blight = Dc_arg_float;
  8451. +   dc_stuff_float(&blight);
  8452.  }
  8453.  
  8454.  // call to add a light source to a small object
  8455. @@ -3355,12 +3356,11 @@ int beam_will_tool_target(beam *b, object *objp)
  8456.  }
  8457.  
  8458.  float beam_accuracy = 1.0f;
  8459. -DCF(b_aim, "")
  8460. +DCF(b_aim, "Adjusts the beam accuracy factor (Default is 1.0f)")
  8461.  {
  8462. -   dc_get_arg(ARG_FLOAT);
  8463. -   beam_accuracy = Dc_arg_float;
  8464. +   dc_stuff_float(&beam_accuracy);
  8465.  }
  8466. -DCF(beam_list, "")
  8467. +DCF(beam_list, "Lists all beams")
  8468.  {
  8469.     int idx;
  8470.     int b_count = 0;
  8471. Index: code/weapon/corkscrew.cpp
  8472. ===================================================================
  8473. --- code/weapon/corkscrew.cpp   (revision 10462)
  8474. +++ code/weapon/corkscrew.cpp   (working copy)
  8475. @@ -15,6 +15,7 @@
  8476.  #include "io/timer.h"
  8477.  #include "freespace2/freespace.h"  // for Missiontime
  8478.  #include "object/object.h"
  8479. +#include "debugconsole/console.h"
  8480.  
  8481.  
  8482.  
  8483. @@ -293,41 +294,25 @@ DCF(cscrew, "Listing of corkscrew missile debug console functions")
  8484.  
  8485.  DCF(cscrew_delay, "Change the delay between corkscrew firing")
  8486.  { 
  8487. -   dc_get_arg(ARG_INT);
  8488. -   if(Dc_arg_type & ARG_INT){
  8489. -       Corkscrew_missile_delay = Dc_arg_int;      
  8490. -   }
  8491. -
  8492. +   dc_stuff_int(&Corkscrew_missile_delay);
  8493.     cscrew_display_dcf();
  8494.  }
  8495.  
  8496.  DCF(cscrew_count, "Change the # of corkscrew missiles fired")
  8497.  { 
  8498. -   dc_get_arg(ARG_INT);
  8499. -   if(Dc_arg_type & ARG_INT){
  8500. -       Corkscrew_num_missiles_fired = Dc_arg_int;     
  8501. -   }
  8502. -
  8503. +   dc_stuff_int(&Corkscrew_num_missiles_fired);
  8504.     cscrew_display_dcf();
  8505.  }
  8506.  
  8507.  DCF(cscrew_radius, "Change the radius of corkscrew missiles")
  8508.  { 
  8509. -   dc_get_arg(ARG_FLOAT);
  8510. -   if(Dc_arg_type & ARG_FLOAT){
  8511. -       Corkscrew_radius = Dc_arg_float;
  8512. -   }
  8513. -
  8514. +   dc_stuff_float(&Corkscrew_radius);
  8515.     cscrew_display_dcf();
  8516.  }
  8517.  
  8518.  DCF(cscrew_twist, "Change the rate of the corkscrew twist")
  8519.  {
  8520. -   dc_get_arg(ARG_FLOAT);
  8521. -   if(Dc_arg_type & ARG_FLOAT){
  8522. -       Corkscrew_twist = Dc_arg_float;
  8523. -   }
  8524. -
  8525. +   dc_stuff_float(&Corkscrew_twist);
  8526.     cscrew_display_dcf();
  8527.  }
  8528.  
  8529. @@ -354,11 +339,7 @@ DCF(cscrew_shrink, "Shrink the radius of every other missile")
  8530.  
  8531.  DCF(cscrew_shrinkval, "Change the rate at which the radii shrink")
  8532.  {
  8533. -   dc_get_arg(ARG_FLOAT);
  8534. -   if(Dc_arg_type & ARG_FLOAT){
  8535. -       Corkscrew_shrink_val = Dc_arg_float;
  8536. -   }
  8537. -
  8538. +   dc_stuff_float(&Corkscrew_shrink_val);
  8539.     cscrew_display_dcf();
  8540.  }
  8541.  
  8542. Index: code/weapon/emp.cpp
  8543. ===================================================================
  8544. --- code/weapon/emp.cpp (revision 10462)
  8545. +++ code/weapon/emp.cpp (working copy)
  8546. @@ -26,6 +26,7 @@
  8547.  #include "iff_defs/iff_defs.h"
  8548.  #include "network/multimsgs.h"
  8549.  #include "network/multi.h"
  8550. +#include "debugconsole/console.h"
  8551.  
  8552.  
  8553.  
  8554. @@ -637,13 +638,12 @@ float emp_current_intensity()
  8555.  DCF(zap, "zap a ship with an EMP effect")
  8556.  {
  8557.     int shipnum;
  8558. +   char ship_str[NAME_LENGTH];
  8559.  
  8560. -   dc_get_arg(ARG_STRING);
  8561. -   if(Dc_arg_type & ARG_STRING){
  8562. -        shipnum = ship_name_lookup(Dc_arg, 1);
  8563. +   dc_stuff_string_white(ship_str, NAME_LENGTH);
  8564. +   shipnum = ship_name_lookup(ship_str, 1);
  8565.  
  8566. -        if(shipnum >= 0){
  8567. -           emp_start_ship(&Objects[Ships[shipnum].objnum], 500.0f, 10.0f);
  8568. -        }
  8569. +   if(shipnum >= 0){
  8570. +       emp_start_ship(&Objects[Ships[shipnum].objnum], 500.0f, 10.0f);
  8571.     }
  8572.  }
  8573. Index: code/weapon/weapons.cpp
  8574. ===================================================================
  8575. --- code/weapon/weapons.cpp (revision 10462)
  8576. +++ code/weapon/weapons.cpp (working copy)
  8577. @@ -47,6 +47,7 @@
  8578.  #include "parse/scripting.h"
  8579.  #include "stats/scoring.h"
  8580.  #include "mod_table/mod_table.h"
  8581. +#include "debugconsole/console.h"
  8582.  
  8583.  
  8584.  #ifndef NDEBUG
  8585. @@ -6470,75 +6471,137 @@ void weapon_maybe_spew_particle(object *obj)
  8586.  /**
  8587.   * Debug console functionality
  8588.   */
  8589. -void pspew_display_dcf()
  8590. +void dcf_pspew();
  8591. +DCF(pspew_count, "Number of particles spewed at a time")
  8592.  {
  8593. -   dc_printf("Particle spew settings\n\n");
  8594. -   dc_printf("Particle spew count (pspew_count) : %d\n", Weapon_particle_spew_count);
  8595. -   dc_printf("Particle spew time (pspew_time) : %d\n", Weapon_particle_spew_time);
  8596. -   dc_printf("Particle spew velocity (pspew_vel) : %f\n", Weapon_particle_spew_vel);
  8597. -   dc_printf("Particle spew size (pspew_size) : %f\n", Weapon_particle_spew_radius);
  8598. -   dc_printf("Particle spew lifetime (pspew_life) : %f\n", Weapon_particle_spew_lifetime);
  8599. -   dc_printf("Particle spew scale (psnew_scale) : %f\n", Weapon_particle_spew_scale);
  8600. -}
  8601. +   if (dc_optional_string_either("help", "--help")) {
  8602. +       dcf_pspew();
  8603. +       return;
  8604. +   }
  8605.  
  8606. -DCF(pspew_count, "Number of particles spewed at a time")
  8607. -{ 
  8608. -   dc_get_arg(ARG_INT);
  8609. -   if(Dc_arg_type & ARG_INT){
  8610. -       Weapon_particle_spew_count = Dc_arg_int;
  8611. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  8612. +           dc_printf("Partical count is %i\n", Weapon_particle_spew_count);
  8613. +           return;
  8614.     }
  8615.  
  8616. -   pspew_display_dcf();
  8617. +   dc_stuff_int(&Weapon_particle_spew_count);
  8618. +  
  8619. +   dc_printf("Partical count set to %i\n", Weapon_particle_spew_count);
  8620.  }
  8621.  
  8622.  DCF(pspew_time, "Time between particle spews")
  8623. -{ 
  8624. -   dc_get_arg(ARG_INT);
  8625. -   if(Dc_arg_type & ARG_INT){
  8626. -       Weapon_particle_spew_time = Dc_arg_int;
  8627. +{
  8628. +   if (dc_optional_string_either("help", "--help")) {
  8629. +       dcf_pspew();
  8630. +       return;
  8631. +   }
  8632. +
  8633. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  8634. +       dc_printf("Particle spawn period is %i\n", Weapon_particle_spew_time);
  8635. +       return;
  8636.     }
  8637.  
  8638. -   pspew_display_dcf();
  8639. +   dc_stuff_int(&Weapon_particle_spew_time);
  8640. +
  8641. +   dc_printf("Particle spawn period set to %i\n", Weapon_particle_spew_time);
  8642.  }
  8643.  
  8644.  DCF(pspew_vel, "Relative velocity of particles (0.0 - 1.0)")
  8645. -{ 
  8646. -   dc_get_arg(ARG_FLOAT);
  8647. -   if(Dc_arg_type & ARG_FLOAT){
  8648. -       Weapon_particle_spew_vel = Dc_arg_float;
  8649. +{
  8650. +   if (dc_optional_string_either("help", "--help")) {
  8651. +       dcf_pspew();
  8652. +       return;
  8653.     }
  8654.  
  8655. -   pspew_display_dcf();
  8656. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  8657. +       dc_printf("Particle relative velocity is %f\n", Weapon_particle_spew_vel);
  8658. +       return;
  8659. +   }
  8660. +
  8661. +   dc_stuff_float(&Weapon_particle_spew_vel);
  8662. +
  8663. +   dc_printf("Particle relative velocity set to %f\n", Weapon_particle_spew_vel);
  8664.  }
  8665.  
  8666.  DCF(pspew_size, "Size of spewed particles")
  8667. -{ 
  8668. -   dc_get_arg(ARG_FLOAT);
  8669. -   if(Dc_arg_type & ARG_FLOAT){
  8670. -       Weapon_particle_spew_radius = Dc_arg_float;
  8671. +{
  8672. +   if (dc_optional_string_either("help", "--help")) {
  8673. +       dcf_pspew();
  8674. +       return;
  8675. +   }
  8676. +
  8677. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  8678. +       dc_printf("Particle size is %f\n", Weapon_particle_spew_radius);
  8679. +       return;
  8680.     }
  8681.  
  8682. -   pspew_display_dcf();
  8683. +   dc_stuff_float(&Weapon_particle_spew_radius);
  8684. +
  8685. +   dc_printf("Particle size set to %f\n", Weapon_particle_spew_radius);
  8686.  }
  8687.  
  8688.  DCF(pspew_life, "Lifetime of spewed particles")
  8689. -{ 
  8690. -   dc_get_arg(ARG_FLOAT);
  8691. -   if(Dc_arg_type & ARG_FLOAT){
  8692. -       Weapon_particle_spew_lifetime = Dc_arg_float;
  8693. +{
  8694. +   if (dc_optional_string_either("help", "--help")) {
  8695. +       dcf_pspew();
  8696. +       return;
  8697.     }
  8698.  
  8699. -   pspew_display_dcf();
  8700. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  8701. +       dc_printf("Particle lifetime is %f\n", Weapon_particle_spew_lifetime);
  8702. +       return;
  8703. +   }
  8704. +
  8705. +   dc_stuff_float(&Weapon_particle_spew_lifetime);
  8706. +
  8707. +   dc_printf("Particle lifetime set to %f\n", Weapon_particle_spew_lifetime);
  8708.  }
  8709.  
  8710.  DCF(pspew_scale, "How far away particles are from the weapon path")
  8711. -{ 
  8712. -   dc_get_arg(ARG_FLOAT);
  8713. -   if(Dc_arg_type & ARG_FLOAT){
  8714. -       Weapon_particle_spew_scale = Dc_arg_float;
  8715. +{
  8716. +   if (dc_optional_string_either("help", "--help")) {
  8717. +       dcf_pspew();
  8718. +       return;
  8719.     }
  8720.  
  8721. -   pspew_display_dcf();
  8722. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  8723. +       dc_printf("Particle scale is %f\n", Weapon_particle_spew_scale);
  8724. +   }
  8725. +
  8726. +   dc_stuff_float(&Weapon_particle_spew_scale);
  8727. +
  8728. +   dc_printf("Particle scale set to %f\n", Weapon_particle_spew_scale);
  8729. +}
  8730. +
  8731. +// Help and Status provider
  8732. +DCF(pspew, "Particle spew help and status provider")
  8733. +{
  8734. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  8735. +       dc_printf("Particle spew settings\n\n");
  8736. +
  8737. +       dc_printf(" Count   (pspew_count) : %d\n", Weapon_particle_spew_count);
  8738. +       dc_printf(" Time     (pspew_time) : %d\n", Weapon_particle_spew_time);
  8739. +       dc_printf(" Velocity  (pspew_vel) : %f\n", Weapon_particle_spew_vel);
  8740. +       dc_printf(" Size     (pspew_size) : %f\n", Weapon_particle_spew_radius);
  8741. +       dc_printf(" Lifetime (pspew_life) : %f\n", Weapon_particle_spew_lifetime);
  8742. +       dc_printf(" Scale   (psnew_scale) : %f\n", Weapon_particle_spew_scale);
  8743. +       return;
  8744. +   }
  8745. +
  8746. +   dc_printf("Available particlar spew commands:\n");
  8747. +   dc_printf("pspew_count : %s\n", dcmd_pspew_count.help);
  8748. +   dc_printf("pspew_time  : %s\n", dcmd_pspew_time.help);
  8749. +   dc_printf("pspew_vel   : %s\n", dcmd_pspew_vel.help);
  8750. +   dc_printf("pspew_size  : %s\n", dcmd_pspew_size.help);
  8751. +   dc_printf("pspew_life  : %s\n", dcmd_pspew_life.help);
  8752. +   dc_printf("pspew_scale : %s\n\n", dcmd_pspew_scale.help);
  8753. +
  8754. +   dc_printf("To view status of all pspew settings, type in 'pspew --status'.\n");
  8755. +   dc_printf("Passing '--status' as an argument to any of the individual spew commands will show the status of that variable only.\n\n");
  8756. +
  8757. +   dc_printf("These commands adjust the various properties of the particle spew system, which is used by weapons when they are fired, are in-flight, and die (either by impact or by end of life time.\n");
  8758. +   dc_printf("Generally, a large particle count with small size and scale will result in a nice dense particle spew.\n");
  8759. +   dc_printf("Be advised, this effect is applied to _ALL_ weapons, and as such may drastically reduce framerates on lower powered platforms.\n");
  8760.  }
  8761.  
  8762.  /**
  8763. Index: projects/MSVC_2011/Freespace2.sln
  8764. ===================================================================
  8765. --- projects/MSVC_2011/Freespace2.sln   (revision 10462)
  8766. +++ projects/MSVC_2011/Freespace2.sln   (working copy)
  8767. @@ -1,6 +1,6 @@
  8768.  ?
  8769.  Microsoft Visual Studio Solution File, Format Version 12.00
  8770. -# Visual Studio 2012
  8771. +# Visual Studio Express 2012 for Windows Desktop
  8772.  Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Freespace2", "Freespace2.vcxproj", "{A8030FA3-CEAB-4297-99E3-CD2CFB89830B}"
  8773.  EndProject
  8774.  Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libjpeg", "libjpeg.vcxproj", "{42A241F2-7996-4AAF-8491-FB885E2DC37D}"
  8775. @@ -143,7 +143,6 @@ Global
  8776.         {92C8C611-75AA-4BD7-9B73-584822AAAEB5}.Debug SSE2|Win32.ActiveCfg = Debug SSE2|Win32
  8777.         {92C8C611-75AA-4BD7-9B73-584822AAAEB5}.Debug SSE2|Win32.Build.0 = Debug SSE2|Win32
  8778.         {92C8C611-75AA-4BD7-9B73-584822AAAEB5}.Debug|Win32.ActiveCfg = Debug|Win32
  8779. -       {92C8C611-75AA-4BD7-9B73-584822AAAEB5}.Debug|Win32.Build.0 = Debug|Win32
  8780.         {92C8C611-75AA-4BD7-9B73-584822AAAEB5}.Release AVX|Win32.ActiveCfg = Release AVX|Win32
  8781.         {92C8C611-75AA-4BD7-9B73-584822AAAEB5}.Release AVX|Win32.Build.0 = Release AVX|Win32
  8782.         {92C8C611-75AA-4BD7-9B73-584822AAAEB5}.Release SSE|Win32.ActiveCfg = Release SSE|Win32
  8783. Index: projects/MSVC_2011/code.vcxproj
  8784. ===================================================================
  8785. --- projects/MSVC_2011/code.vcxproj (revision 10462)
  8786. +++ projects/MSVC_2011/code.vcxproj (working copy)
  8787. @@ -529,6 +529,9 @@
  8788.      <ClCompile Include="..\..\code\cutscene\oggplayer.cpp" />
  8789.      <ClCompile Include="..\..\code\Debris\debris.cpp" />
  8790.      <ClCompile Include="..\..\code\DebugConsole\console.cpp" />
  8791. +    <ClCompile Include="..\..\code\debugconsole\consolecmds.cpp" />
  8792. +    <ClCompile Include="..\..\code\debugconsole\consoleparse.cpp" />
  8793. +    <ClCompile Include="..\..\code\debugconsole\timerbar.cpp" />
  8794.      <ClCompile Include="..\..\code\fireball\fireballs.cpp" />
  8795.      <ClCompile Include="..\..\code\fireball\warpineffect.cpp" />
  8796.      <ClCompile Include="..\..\code\gamehelp\contexthelp.cpp" />
  8797. @@ -808,6 +811,9 @@
  8798.      <ClInclude Include="..\..\code\cutscene\mvelib.h" />
  8799.      <ClInclude Include="..\..\code\cutscene\oggplayer.h" />
  8800.      <ClInclude Include="..\..\code\Debris\debris.h" />
  8801. +    <ClInclude Include="..\..\code\debugconsole\console.h" />
  8802. +    <ClInclude Include="..\..\code\debugconsole\consoleparse.h" />
  8803. +    <ClInclude Include="..\..\code\debugconsole\timerbar.h" />
  8804.      <ClInclude Include="..\..\code\DirectX\vasync.h" />
  8805.      <ClInclude Include="..\..\code\DirectX\vdinput.h" />
  8806.      <ClInclude Include="..\..\code\DirectX\vdplay.h" />
  8807. Index: projects/MSVC_2011/code.vcxproj.filters
  8808. ===================================================================
  8809. --- projects/MSVC_2011/code.vcxproj.filters (revision 10462)
  8810. +++ projects/MSVC_2011/code.vcxproj.filters (working copy)
  8811. @@ -1056,6 +1056,15 @@
  8812.      <ClCompile Include="..\..\code\globalincs\profiling.cpp">
  8813.        <Filter>GlobalIncs</Filter>
  8814.      </ClCompile>
  8815. +    <ClCompile Include="..\..\code\debugconsole\consolecmds.cpp">
  8816. +      <Filter>DebugConsole</Filter>
  8817. +    </ClCompile>
  8818. +    <ClCompile Include="..\..\code\debugconsole\consoleparse.cpp">
  8819. +      <Filter>DebugConsole</Filter>
  8820. +    </ClCompile>
  8821. +    <ClCompile Include="..\..\code\debugconsole\timerbar.cpp">
  8822. +      <Filter>DebugConsole</Filter>
  8823. +    </ClCompile>
  8824.    </ItemGroup>
  8825.    <ItemGroup>
  8826.      <ClInclude Include="..\..\code\ai\ai.h">
  8827. @@ -1856,6 +1865,15 @@
  8828.      <ClInclude Include="..\..\code\PilotFile\pilotfile.h">
  8829.        <Filter>PilotFile</Filter>
  8830.      </ClInclude>
  8831. +    <ClInclude Include="..\..\code\debugconsole\console.h">
  8832. +      <Filter>DebugConsole</Filter>
  8833. +    </ClInclude>
  8834. +    <ClInclude Include="..\..\code\debugconsole\consoleparse.h">
  8835. +      <Filter>DebugConsole</Filter>
  8836. +    </ClInclude>
  8837. +    <ClInclude Include="..\..\code\debugconsole\timerbar.h">
  8838. +      <Filter>DebugConsole</Filter>
  8839. +    </ClInclude>
  8840.    </ItemGroup>
  8841.    <ItemGroup>
  8842.      <Library Include="..\..\code\directx\dxguid.lib">
  8843.  
  8844.  
  8845. /* EOF - IGNORE *\
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement