Advertisement
Guest User

Untitled

a guest
Mar 10th, 2014
247
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Index: Makefile.am
  2. ===================================================================
  3. --- Makefile.am (Revision 10462)
  4. +++ Makefile.am (Arbeitskopie)
  5. @@ -262,7 +262,9 @@
  6.     ddsutils/ddsutils.h \
  7.     debris/debris.cpp   \
  8.     debris/debris.h \
  9. +   debugconsole/consolecmds.cpp \
  10.     debugconsole/console.cpp    \
  11. +   debugconsole/consoleparse.cpp \
  12.     debugconsole/dbugfile.h \
  13.     debugconsole/timerbar.cpp   \
  14.     debugconsole/timerbar.h \
  15. Index: ai/aicode.cpp
  16. ===================================================================
  17. --- ai/aicode.cpp   (Revision 10462)
  18. +++ ai/aicode.cpp   (Arbeitskopie)
  19. @@ -18,6 +18,7 @@
  20.  
  21.  
  22.  #include "ai/ai.h"
  23. +#include "debugconsole/console.h"
  24.  #include "globalincs/linklist.h"
  25.  #include "object/object.h"
  26.  #include "physics/physics.h"
  27. @@ -11367,16 +11368,14 @@
  28.  
  29.  float Wing_y_scale = 2.0f;
  30.  float Wing_scale = 1.0f;
  31. -DCF(wing_y_scale, "")
  32. +DCF(wing_y_scale, "Adjusts the wing formation scale along the Y axis (Default is 2.0)")
  33.  {
  34. -   dc_get_arg(ARG_FLOAT);
  35. -   Wing_y_scale = Dc_arg_float;
  36. +   dc_stuff_float(&Wing_y_scale);
  37.  }
  38.  
  39. -DCF(wing_scale, "")
  40. +DCF(wing_scale, "Adjusts the wing formation scale. (Default is 1.0f)")
  41.  {
  42. -   dc_get_arg(ARG_FLOAT);
  43. -   Wing_scale = Dc_arg_float;
  44. +   dc_stuff_float(&Wing_scale);
  45.  }
  46.  
  47.  /**
  48. Index: ai/aiturret.cpp
  49. ===================================================================
  50. --- ai/aiturret.cpp (Revision 10462)
  51. +++ ai/aiturret.cpp (Arbeitskopie)
  52. @@ -22,6 +22,7 @@
  53.  #include "iff_defs/iff_defs.h"
  54.  #include "weapon/muzzleflash.h"
  55.  #include "parse/scripting.h"
  56. +#include "debugconsole/console.h"
  57.  
  58.  #include <limits.h>
  59.  
  60. @@ -38,8 +39,7 @@
  61.  float Lethality_range_const = 2.0f;
  62.  DCF(lethality_range, "N for modifying range: 1 / (1+N) at 100")
  63.  {
  64. -   dc_get_arg(ARG_FLOAT);
  65. -   Lethality_range_const = Dc_arg_float;
  66. +   dc_stuff_float(&Lethality_range_const);
  67.  }
  68.  
  69.  float Player_lethality_bump[NUM_SKILL_LEVELS] = {
  70. @@ -1466,10 +1466,16 @@
  71.  float aifft_rank[MAX_AIFFT_TURRETS];
  72.  int aifft_list_size = 0;
  73.  int aifft_max_checks = 5;
  74. -DCF(mf, "")
  75. +DCF(mf, "Adjusts the maximum number of tries an AI may do when trying to pick a subsystem to attack (Default is 5)")
  76.  {
  77. -   dc_get_arg(ARG_INT);
  78. -   aifft_max_checks = Dc_arg_int;
  79. +   dc_stuff_int(&aifft_max_checks);
  80. +
  81. +   if (aifft_max_checks <= 0) {
  82. +       dc_printf("Value must be a non-negative, non-zero integer\n");
  83. +       dc_printf("aifft_max_checks set to default value of 5\n");
  84. +
  85. +       aifft_max_checks = 5;
  86. +   }
  87.  }
  88.  
  89.  
  90. Index: asteroid/asteroid.cpp
  91. ===================================================================
  92. --- asteroid/asteroid.cpp   (Revision 10462)
  93. +++ asteroid/asteroid.cpp   (Arbeitskopie)
  94. @@ -39,6 +39,8 @@
  95.  #include "network/multimsgs.h"
  96.  #include "network/multi.h"
  97.  #include "parse/scripting.h"
  98. +#include "debugconsole/console.h"
  99. +
  100.  #include <algorithm>
  101.  #include "globalincs/compatibility.h"
  102.  
  103. @@ -1404,24 +1406,9 @@
  104.     Asteroid_field.num_initial_asteroids=0;
  105.  }
  106.  
  107. -DCF(asteroids,"Turns asteroids on/off")
  108. -{ 
  109. -   if ( Dc_command )   {  
  110. -       dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);       
  111. -       if ( Dc_arg_type & ARG_TRUE )  
  112. -           Asteroids_enabled = 1
  113. -       else if ( Dc_arg_type & ARG_FALSE )
  114. -           Asteroids_enabled = 0
  115. -       else if ( Dc_arg_type & ARG_NONE )
  116. -           Asteroids_enabled ^= 1;
  117. -   }  
  118. -   if ( Dc_help ) 
  119. -       dc_printf( "Usage: asteroids [bool]\nTurns asteroid system on/off.  If nothing passed, then toggles it.\n" );  
  120. -  
  121. -   if ( Dc_status )   
  122. -       dc_printf( "asteroids are %s\n", (Asteroids_enabled?"ON":"OFF") )
  123. -}
  124. +DCF_BOOL2(asteroids, Asteroids_enabled, "enables or disables asteroids", "Usage: asteroids [bool]\nTurns asteroid system on/off.  If nothing passed, then toggles it.\n");
  125.  
  126. +
  127.  void hud_target_asteroid()
  128.  {
  129.     int i;
  130. Index: bmpman/bmpman.cpp
  131. ===================================================================
  132. --- bmpman/bmpman.cpp   (Revision 10462)
  133. +++ bmpman/bmpman.cpp   (Arbeitskopie)
  134. @@ -37,6 +37,7 @@
  135.  #include "jpgutils/jpgutils.h"
  136.  #include "parse/parselo.h"
  137.  #include "network/multiutil.h"
  138. +#include "debugconsole/console.h"
  139.  
  140.  #define BMPMAN_INTERNAL
  141.  #include "bmpman/bm_internal.h"
  142. @@ -669,46 +670,53 @@
  143.  
  144.  DCF(bm_frag,"Shows BmpMan fragmentation")
  145.  {
  146. -   if ( Dc_command )   {
  147. +   if (dc_optional_string_either("help", "--help")) {
  148. +       dc_printf("Displays a graphic showing the BmpMan fragmentation. Color key:\n");
  149. +       dc_printf("\tGray  : NONE\n");
  150. +       dc_printf("\tRed   : PCXn");
  151. +       dc_printf("\tGreen : USER, TGA, PNG, DDS\n");
  152. +       dc_printf("\tBlue  : ANI, EFF\n\n");
  153.  
  154. -       gr_clear();
  155. +       dc_printf("Once done reviewing the graphic, press any key to return to the console\n");
  156. +       return;
  157. +   }
  158. +  
  159. +   gr_clear();
  160.  
  161. -       int x=0, y=0;
  162. -       int xs=2, ys=2;
  163. -       int w=4, h=4;
  164. +   int x=0, y=0;
  165. +   int xs=2, ys=2;
  166. +   int w=4, h=4;
  167.  
  168. -       for (int i=0; i<MAX_BITMAPS; i++ )  {
  169. -           switch( bm_bitmaps[i].type )    {
  170. -           case BM_TYPE_NONE:
  171. -               gr_set_color(128,128,128);
  172. -               break;
  173. -           case BM_TYPE_PCX:
  174. -               gr_set_color(255,0,0);
  175. -               break;
  176. -           case BM_TYPE_USER:
  177. -           case BM_TYPE_TGA:
  178. -           case BM_TYPE_PNG:
  179. -           case BM_TYPE_DDS:
  180. -               gr_set_color(0,255,0);
  181. -               break;
  182. -           case BM_TYPE_ANI:
  183. -           case BM_TYPE_EFF:
  184. -               gr_set_color(0,0,255);
  185. -               break;
  186. -           }
  187. +   for (int i=0; i<MAX_BITMAPS; i++ )  {
  188. +       switch( bm_bitmaps[i].type )    {
  189. +       case BM_TYPE_NONE:
  190. +           gr_set_color(128,128,128);
  191. +           break;
  192. +       case BM_TYPE_PCX:
  193. +           gr_set_color(255,0,0);
  194. +           break;
  195. +       case BM_TYPE_USER:
  196. +       case BM_TYPE_TGA:
  197. +       case BM_TYPE_PNG:
  198. +       case BM_TYPE_DDS:
  199. +           gr_set_color(0,255,0);
  200. +           break;
  201. +       case BM_TYPE_ANI:
  202. +       case BM_TYPE_EFF:
  203. +           gr_set_color(0,0,255);
  204. +           break;
  205. +       }
  206.  
  207. -           gr_rect( x+xs, y+ys, w, h );
  208. -           x += w+xs+xs;
  209. -           if ( x > 639 )  {
  210. -               x = 0;
  211. -               y += h + ys + ys;
  212. -           }
  213. -
  214. +       gr_rect( x+xs, y+ys, w, h );
  215. +       x += w+xs+xs;
  216. +       if ( x > 639 )  {
  217. +           x = 0;
  218. +           y += h + ys + ys;
  219.         }
  220. +   }
  221.  
  222. -       gr_flip();
  223. -       key_getch();
  224. -   }
  225. +   gr_flip();
  226. +   key_getch();
  227.  }
  228.  
  229.  static int find_block_of(int n)
  230. @@ -2068,48 +2076,52 @@
  231.  
  232.  DCF(bmpman,"Shows/changes bitmap caching parameters and usage")
  233.  {
  234. -   if ( Dc_command )   {
  235. -       dc_get_arg(ARG_STRING);
  236. -       if ( !strcmp( Dc_arg, "flush" ))    {
  237. -           dc_printf( "Total RAM usage before flush: %d bytes\n", bm_texture_ram );
  238. -           int i;
  239. -           for (i = 0; i < MAX_BITMAPS; i++)   {
  240. -               if ( bm_bitmaps[i].type != BM_TYPE_NONE )   {
  241. -                   bm_free_data(i);
  242. -               }
  243. -           }
  244. -           dc_printf( "Total RAM after flush: %d bytes\n", bm_texture_ram );
  245. -       } else if ( !strcmp( Dc_arg, "ram" ))   {
  246. -           dc_get_arg(ARG_INT);
  247. -           Bm_max_ram = Dc_arg_int*1024*1024;
  248. -       } else {
  249. -           // print usage, not stats
  250. -           Dc_help = 1;
  251. -       }
  252. +   if ( dc_optional_string_either("help", "--help"))   {
  253. +       dc_printf( "Usage: BmpMan [arg]\nWhere arg can be any of the following:\n" );
  254. +       dc_printf( "\tflush    Unloads all bitmaps.\n" );
  255. +       dc_printf( "\tram [x]  Sets max mem usage to x MB. (Set to 0 to have no limit.)\n" );
  256. +       dc_printf( "\t?        Displays status of Bitmap manager.\n" );
  257. +       return;
  258.     }
  259.  
  260. -   if ( Dc_help )  {
  261. -       dc_printf( "Usage: BmpMan keyword\nWhere keyword can be in the following forms:\n" );
  262. -       dc_printf( "BmpMan flush    Unloads all bitmaps.\n" );
  263. -       dc_printf( "BmpMan ram x    Sets max mem usage to x MB. (Set to 0 to have no limit.)\n" );
  264. -       dc_printf( "\nUse '? BmpMan' to see status of Bitmap manager.\n" );
  265. -       Dc_status = 0;  // don't print status if help is printed.  Too messy.
  266. -   }
  267. -
  268. -   if ( Dc_status )    {
  269. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  270.         dc_printf( "Total RAM usage: %d bytes\n", bm_texture_ram );
  271.  
  272. +       if (Bm_max_ram > 1024*1024) {
  273. +           dc_printf( "\tMax RAM allowed: %.1f MB\n", i2fl(Bm_max_ram)/(1024.0f*1024.0f) );
  274. +       } else if ( Bm_max_ram > 1024 ) {
  275. +           dc_printf( "\tMax RAM allowed: %.1f KB\n", i2fl(Bm_max_ram)/(1024.0f) );
  276. +       } else if ( Bm_max_ram > 0 ) {
  277. +           dc_printf( "\tMax RAM allowed: %d bytes\n", Bm_max_ram );
  278. +       } else {
  279. +           dc_printf( "\tNo RAM limit\n" );
  280. +       }
  281. +       return;
  282. +   }
  283.  
  284. -       if ( Bm_max_ram > 1024*1024 )
  285. -           dc_printf( "Max RAM allowed: %.1f MB\n", i2fl(Bm_max_ram)/(1024.0f*1024.0f) );
  286. -       else if ( Bm_max_ram > 1024 )
  287. -           dc_printf( "Max RAM allowed: %.1f KB\n", i2fl(Bm_max_ram)/(1024.0f) );
  288. -       else if ( Bm_max_ram > 0 )
  289. -           dc_printf( "Max RAM allowed: %d bytes\n", Bm_max_ram );
  290. -       else
  291. -           dc_printf( "No RAM limit\n" );
  292.  
  293. +   if (dc_optional_string("flush")) {
  294. +       dc_printf( "Total RAM usage before flush: %d bytes\n", bm_texture_ram );
  295. +       int i;
  296. +       for (i = 0; i < MAX_BITMAPS; i++)   {
  297. +           if ( bm_bitmaps[i].type != BM_TYPE_NONE )   {
  298. +               bm_free_data(i);
  299. +           }
  300. +       }
  301. +       dc_printf( "Total RAM after flush: %d bytes\n", bm_texture_ram );
  302. +   } else if (dc_optional_string("ram")) {
  303. +       dc_stuff_int(&Bm_max_ram);
  304.  
  305. +       if (Bm_max_ram > 0) {
  306. +           dc_printf("BmpMan limited to %i, MB's\n", Bm_max_ram);
  307. +           Bm_max_ram *= 1024 * 1024;
  308. +       } else if (Bm_max_ram == 0) {
  309. +           dc_printf("!!BmpMan memory is unlimited!!\n");
  310. +       } else {
  311. +           dc_printf("Illegal value. Must be non-negative.");
  312. +       }
  313. +   } else {
  314. +       dc_printf("<BmpMan> No argument given\n");
  315.     }
  316.  }
  317.  
  318. Index: controlconfig/controlsconfig.cpp
  319. ===================================================================
  320. --- controlconfig/controlsconfig.cpp    (Revision 10462)
  321. +++ controlconfig/controlsconfig.cpp    (Arbeitskopie)
  322. @@ -29,6 +29,7 @@
  323.  #include "network/multi_pmsg.h"
  324.  #include "network/multiutil.h"
  325.  #include "parse/scripting.h"
  326. +#include "debugconsole/console.h"
  327.  
  328.  
  329.  #ifndef NDEBUG
  330. @@ -348,7 +349,7 @@
  331.  #ifndef NDEBUG
  332.  int Show_controls_info = 0;
  333.  
  334. -DCF_BOOL(show_controls_info, Show_controls_info)
  335. +DCF_BOOL(show_controls_info, Show_controls_info);
  336.  #endif
  337.  
  338.  static int Axes_origin[JOY_NUM_AXES];
  339. Index: debugconsole/console.cpp
  340. ===================================================================
  341. --- debugconsole/console.cpp    (Revision 10462)
  342. +++ debugconsole/console.cpp    (Arbeitskopie)
  343. @@ -8,740 +8,458 @@
  344.  */
  345.  
  346.  
  347. -
  348. -#include <stdlib.h>
  349. -#include <stdio.h>
  350. -#include <stdarg.h>
  351. -#include <setjmp.h>
  352. -#include <string.h>
  353. -
  354. +#include "debugconsole/console.h"
  355. +#include "debugconsole/consoleparse.h"
  356. +#include "globalincs/alphacolors.h"
  357.  #include "globalincs/pstypes.h"
  358. +#include "globalincs/version.h"
  359. +#include "globalincs/vmallocator.h"
  360.  #include "graphics/font.h"
  361.  #include "io/timer.h"
  362.  #include "io/key.h"
  363. -#include "globalincs/alphacolors.h"
  364.  #include "osapi/osapi.h"
  365.  
  366. +#include <cstdarg>
  367.  
  368. -#define MAX_COMMANDS 300
  369. +// ========================= GLOBALS =========================
  370. +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)
  371.  
  372. -static int Num_debug_commands = 0;
  373. -static debug_command *Debug_command[MAX_COMMANDS];
  374. +bool Dc_debug_on;      //!< Flag used to print console and command debugging strings
  375.  
  376. +// Commands and History
  377. +SCP_string dc_command_str;     //!< The entered command line, arguments and all.
  378. +                               //!< Is progressively culled from the left as commands, arguments are parsed in DCF's
  379.  
  380. -debug_command::debug_command(char *_name, char *_help, void (*_func)() )
  381. -{
  382. -   int i;
  383. +// Misc
  384. +bool debug_inited = FALSE;
  385.  
  386. -   if ( Num_debug_commands >= MAX_COMMANDS ) {
  387. -       Int3();         // Too many debug console commands!! Increase MAX_COMMANDS!!
  388. -       return;
  389. -   }
  390.  
  391. -   for (i=0; i<Num_debug_commands; i++ ) {
  392. -       int ret  = stricmp( Debug_command[i]->name, _name );
  393. +// ========================= LOCALS =========================
  394. +// Text Buffer
  395. +uint DBROWS = 80;  // # of buffer rows
  396. +uint DBCOLS = 120; // # of buffer columns
  397. +unsigned char DTABS = 4;   //!< Tab size in spaces
  398.  
  399. -       if ( ret == 0) {
  400. -           Int3();     // This debug console command already exists!!!!
  401. -           return;
  402. -       } else if ( ret > 0 ) {
  403. -           break;      // Insert it here
  404. +SCP_deque<SCP_string> dc_buffer;
  405.  
  406. -       } else if ( ret < 0 ) {
  407. -           // do nothing
  408. -       }
  409. -   }
  410. +// Display Window
  411. +uint DROWS = 25;
  412. +uint DCOLS = 80;
  413. +const uint DROWS_MIN = 25;
  414. +const uint DCOLS_MIN = 80;
  415. +uint dc_scroll_x;  // X scroll position (Leftmost character)
  416. +uint dc_scroll_y;  // Y scroll position (Topmost character)
  417.  
  418. -   if ( i < Num_debug_commands ) {
  419. -       // Insert it at element i
  420. -       int j;
  421. -       for (j=Num_debug_commands; j>i; j-- ) {
  422. -           Debug_command[j] = Debug_command[j-1];
  423. -       }
  424. -       Debug_command[i] = this;
  425. -       Num_debug_commands++;
  426. -   } else {
  427. -       Debug_command[Num_debug_commands] = this;
  428. -       Num_debug_commands++;
  429. -   }
  430. +SCP_string dc_title;
  431.  
  432. -   name = _name;
  433. -   help = _help;
  434. -   func = _func;
  435. -}
  436. +// Commands and History
  437. +uint last_oldcommand;      // Index of the last old command. Is reset to 0 at every new command push.
  438. +uint DCMDS = 40;           // Max number of commands to remember
  439. +const uint DCMDS_MIN = 3;
  440.  
  441. -// some global variables
  442. -int Dc_command;            // If this is set, then process the command
  443. -int Dc_help;           // If this is set, then print out the help text in the form, "usage: ... \nLong description\n" );
  444. -int Dc_status;         // If this is set, then print out the current status of the command.
  445. -char *Dc_arg;          // The (lowercased) string value of the argument retrieved from dc_arg
  446. -char *Dc_arg_org;      // Dc_arg before it got converted to lowercase
  447. -uint Dc_arg_type;      // The type of dc_arg.
  448. -char *Dc_command_line; // The rest of the command line, from the end of the last processed arg on.
  449. -int Dc_arg_int;            // If Dc_arg_type & ARG_INT is set, then this is the value
  450. -ubyte Dc_arg_ubyte;        // If Dc_arg_type & ARG_UBYTE is set, then this is the value
  451. -float Dc_arg_float;        // If Dc_arg_type & ARG_FLOAT is set, then this is the value
  452. +SCP_deque<SCP_string> dc_history;
  453.  
  454. -int scroll_times = 0;  // incremented each time display scrolls
  455. +const char dc_prompt[]= "> ";  // The prompt c_str
  456. +SCP_string dc_command_buf;     // The command line as shown in the console. Essentially an input buffer for dc_command_str
  457.  
  458. -int debug_inited = 0;
  459. +// Local functions
  460. +void dc_init(void);
  461.  
  462. -#define DROWS 25
  463. -#define DCOLS 80
  464. +void dc_do_command(SCP_string *cmd_str);
  465.  
  466. -int debug_x=0, debug_y=0;
  467. -char debug_text[DROWS][DCOLS];
  468. +void dc_draw(bool show_prompt);
  469. +void dc_draw_cursor( SCP_string &cmd_string, int x, int y );
  470. +void dc_draw_window(bool show_prompt);
  471.  
  472. +void dc_putc(char c);
  473.  
  474. -static char command_line[1024];
  475. -static int command_line_pos = 0;
  476. -#define DEBUG_HISTORY 16
  477. -static char oldcommand_line[DEBUG_HISTORY][1024];
  478. -int last_oldcommand=-1;
  479. -int command_scroll = 0;
  480. -
  481. -///=========================== SCANNER =======================
  482. -typedef enum {
  483. -   LETTER, QUOTE, SPECIAL, EOF_CODE, DIGIT
  484. -} CHAR_CODE;
  485. -
  486. -typedef enum {
  487. -   NO_TOKEN, IDENTIFIER, NUMBER, STRING
  488. -} TOKEN_CODE;
  489. -
  490. -
  491. -#define MAX_TOKEN_STRING_LENGTH 128
  492. -
  493. -char       scanner_ch;
  494. -TOKEN_CODE scanner_token;
  495. -
  496. -char scanner_token_string[MAX_TOKEN_STRING_LENGTH];
  497. -char scanner_word_string[MAX_TOKEN_STRING_LENGTH];
  498. -char * scanner_bufferp = "";
  499. -char * scanner_tokenp = scanner_token_string;
  500. -
  501. -CHAR_CODE scanner_char_table[256];
  502. -
  503. -#define scanner_char_code(x) scanner_char_table[x]
  504. -
  505. -void scanner_get_char()
  506. +// ============================== IMPLEMENTATIONS =============================
  507. +/**
  508. + * @brieft Prints the given char string to the debug console
  509. + * @details See the doc for std::printf() for formating and more details
  510. + */
  511. +void dc_printf(char *format, ...)
  512.  {
  513. -   if ( *scanner_bufferp == '\0' ) {
  514. -       scanner_ch = 0;
  515. -       return;
  516. -   }
  517. -   scanner_ch = *scanner_bufferp++;
  518. -}
  519. +   SCP_string tmp;
  520. +   va_list args;
  521. +   SCP_string::iterator tmp_it;
  522.  
  523. -void scanner_init()
  524. -{
  525. -   int ch;
  526. -   for (ch=0; ch<256; ++ch) scanner_char_table[ch] = SPECIAL;
  527. -   for (ch='0'; ch<='9'; ++ch) scanner_char_table[ch] = DIGIT;
  528. -   for (ch='A'; ch<='Z'; ++ch) scanner_char_table[ch] = LETTER;
  529. -   for (ch='a'; ch<='z'; ++ch) scanner_char_table[ch] = LETTER;
  530. +   va_start(args, format);
  531. +   vsprintf(tmp, format, args);
  532. +   va_end(args);
  533.  
  534. -   scanner_char_table['.'] = DIGIT;
  535. -   scanner_char_table['-'] = DIGIT;
  536. -   scanner_char_table['+'] = DIGIT;
  537. -
  538. -   scanner_char_table['_'] = LETTER;
  539. -   scanner_char_table[34] = QUOTE;
  540. -   scanner_char_table[0] = EOF_CODE;
  541. -
  542. -   scanner_char_table[':'] = LETTER;
  543. -   scanner_char_table['\\'] = LETTER;
  544. -
  545. -   scanner_ch = 0;
  546. -}
  547. -
  548. -void scanner_skip_blanks()
  549. -{
  550. -   while( (scanner_ch ==' ') || (scanner_ch =='\t') )
  551. -       scanner_get_char();
  552. -}
  553. -
  554. -void scanner_downshift_word()
  555. -{
  556. -   int offset = 'a' - 'A';
  557. -   char * tp;
  558. -
  559. -   strcpy_s( scanner_word_string, scanner_token_string );
  560. -  
  561. -   tp = scanner_word_string;
  562. -   do {
  563. -       *tp = (char)((*tp>='A') && (*tp <='Z') ? *tp + offset : *tp) ;
  564. -       tp++;
  565. -   } while (*tp != '\0' );
  566. -}
  567. -
  568. -void scanner_get_word()
  569. -{
  570. -   while( (scanner_char_code(scanner_ch)==LETTER) || (scanner_char_code(scanner_ch)==DIGIT) ) {
  571. -       *scanner_tokenp++ = scanner_ch;
  572. -       scanner_get_char();
  573. +   for (tmp_it = tmp.begin(); tmp_it != tmp.end(); ++tmp_it) {
  574. +       dc_putc(*tmp_it);
  575.     }
  576. -   *scanner_tokenp = '\0';
  577. -
  578. -   scanner_token = IDENTIFIER;
  579.  }
  580.  
  581. -void scanner_get_string()
  582. +/**
  583. + * @brief Opens and processes the debug console. (Blocking call)
  584. + * @details TODO: Make this a non-blocking call so that the game can still run while the debug console is open.
  585. + */
  586. +void debug_console(void (*_func)(void))
  587.  {
  588. -   *scanner_tokenp++ = 34;
  589. -   scanner_get_char();
  590. +   int done = 0;
  591.  
  592. -   while(scanner_ch != 34 ) {
  593. -       *scanner_tokenp++ = scanner_ch;
  594. -       scanner_get_char();
  595. +   while( key_inkey() ) {
  596. +       os_poll();
  597.     }
  598. -   scanner_get_char();
  599. -   *scanner_tokenp++ = 34;
  600. -   *scanner_tokenp = '\0';
  601. -   scanner_token = STRING;
  602. -}
  603.  
  604. -void scanner_get_token()
  605. -{
  606. -   scanner_skip_blanks();
  607. -   scanner_tokenp = scanner_token_string;
  608. -   *scanner_tokenp = 0;
  609. -
  610. -   switch( scanner_char_code(scanner_ch) ) {
  611. -   case QUOTE: scanner_get_string(); break;
  612. -   case EOF_CODE: scanner_token = NO_TOKEN; break;
  613. -   case DIGIT:
  614. -   case LETTER: scanner_get_word(); break;
  615. -   default:
  616. -       *scanner_tokenp++ = scanner_ch;
  617. -       *scanner_tokenp = '\0';
  618. -       scanner_get_char();
  619. -       scanner_token = IDENTIFIER;
  620. -       break;
  621. +   if ( !debug_inited ) {
  622. +       dc_init();
  623.     }
  624.  
  625. -   scanner_downshift_word();
  626. -}
  627. +   dc_draw(TRUE);
  628.  
  629. -void scanner_start_command( char * s )
  630. -{
  631. -   scanner_bufferp = s;
  632. -   scanner_get_char();
  633. -}
  634. +   while (!done) {
  635. +       // poll the os
  636. +       os_poll();
  637.  
  638. -int Dc_debug_on = 0;
  639. -jmp_buf dc_bad_arg;
  640. +       int k = key_inkey();
  641. +       switch( k ) {
  642.  
  643. -void dc_get_arg(uint type)
  644. -{
  645. -   scanner_get_token();
  646. +       case KEY_SHIFTED+KEY_ENTER:
  647. +       case KEY_ESC:
  648. +           done = TRUE;
  649. +           break;
  650.  
  651. -   Dc_command_line = scanner_bufferp;
  652. -   Dc_arg_org = scanner_token_string;
  653. -   Dc_arg = scanner_word_string;
  654. +       case KEY_BACKSP:
  655. +           if (!dc_command_buf.empty()) {
  656. +               dc_command_buf.erase(dc_command_str.end() - 1, dc_command_buf.end());
  657. +           }
  658. +           break;
  659.  
  660. -   if (Dc_debug_on) {
  661. -       dc_printf( "next arg is '%s', was originally '%s'\n", Dc_arg, Dc_arg_org );
  662. -       dc_printf( "Rest of the command line is '%s'\n", Dc_command_line );
  663. -   }
  664. +       case KEY_F3:
  665. +       case KEY_UP:
  666. +           if (dc_history.empty()) {
  667. +               // No saved commands
  668. +               last_oldcommand = 0;
  669. +               break;
  670. +           }
  671. +          
  672. +           CLAMP(last_oldcommand, 0, dc_history.size());
  673.  
  674. -   if ( scanner_token == NO_TOKEN ) {
  675. -       Dc_arg_type = ARG_NONE;
  676. -   } else if ( scanner_token == IDENTIFIER ) {
  677. -       Dc_arg_type = ARG_STRING;
  678. -   } else if ( scanner_token == STRING ) {
  679. -       Dc_arg_type = ARG_QUOTE;
  680. -   } else {
  681. -       Dc_arg_type = ARG_STRING;
  682. -   }
  683. +           dc_command_buf = dc_history[last_oldcommand];
  684. +           ++last_oldcommand;
  685. +           break;
  686.  
  687. -   if ( Dc_arg_type & ARG_STRING ) {
  688. -       int i, num_digits, len;
  689. +       case KEY_DOWN:
  690. +           if (dc_history.empty()) {
  691. +               // No saved commands
  692. +               last_oldcommand = 0;
  693. +               break;
  694. +           }
  695. +          
  696. +           CLAMP(last_oldcommand, 1, dc_history.size());
  697.  
  698. -       len = strlen(Dc_arg);
  699. -       num_digits = 0;
  700. +           --last_oldcommand;
  701. +           dc_command_buf = dc_history[last_oldcommand];
  702. +           break;
  703.  
  704. -       for (i=0; i<len; i++) {
  705. -           if ( scanner_char_table[Dc_arg[i]] == DIGIT ) {
  706. -               num_digits++;
  707. -           }
  708. +       case KEY_ENTER:
  709. +           // Clear the command line on the window, but don't print the prompt until the command has processed
  710. +           // Stuff a copy of the command line onto the history
  711. +           // Search for the command
  712. +               // If not found:
  713. +               //   abort,
  714. +               //   dc_printf("Error: Invalid or Missing command %s", cmd), and
  715. +               //   dc_printf(dc_prompt) when ready for input
  716. +           // Call the function for that command, and strip the cmd token from the command line string
  717. +           if (dc_command_buf.empty()) {
  718. +               dc_printf("No command given.\n");
  719. +               break;
  720. +           } // Else, continue to process the cmd_line
  721.  
  722. -           if ( num_digits==len ) {
  723. -               Dc_arg_type |= ARG_FLOAT;
  724. -               Dc_arg_float = (float)atof(Dc_arg);
  725. -               if ( !strchr( Dc_arg, '.' )) {
  726. -                   Dc_arg_type |= ARG_INT;
  727. -                   Dc_arg_int = atoi(Dc_arg);
  728. -                   Dc_arg_type |= ARG_UBYTE;
  729. -                   Dc_arg_ubyte = (ubyte)atoi(Dc_arg);
  730. -               }
  731. -           } else {
  732. -               if ( (Dc_arg[0] == '0') && (Dc_arg[1] == 'x') ) {
  733. -                   char *p;
  734. -                   int n;
  735. -                   n = strtol(Dc_arg,&p,0);
  736. -                   if ( *p == 0 ) {
  737. -                       Dc_arg_type |= ARG_INT|ARG_HEX;
  738. -                       Dc_arg_int = n;
  739. -                   }
  740. -               }
  741. -           }
  742. -       }
  743. +           // z64: Thread Note: Maybe lock a mutex here to allow a previous DCF to finish/abort before starting a new one
  744. +           // z64: We'll just assume we won't be here unless a command has finished...
  745. +           dc_history.push_front(dc_command_buf);  // Push the command onto the history queue
  746.  
  747. -       if (Dc_debug_on) {
  748. -           if ( Dc_arg_type & ARG_FLOAT ) {
  749. -               dc_printf( "Found float number! %f\n", Dc_arg_float );
  750. +           while (dc_history.size() > DCMDS) {
  751. +               dc_history.pop_back();          // Keep the commands less than or equal to DCMDS
  752.             }
  753.  
  754. -           if ( Dc_arg_type & ARG_INT ) {
  755. -               dc_printf( "Found int number! %d\n", Dc_arg_int );
  756. -           }
  757. +           dc_command_str = dc_command_buf;    // Xfer to the command string for processing
  758. +           dc_command_buf.resize(0);           // Nullify the buffer
  759. +           dc_draw(FALSE);                 // Redraw the console without the command line.
  760.  
  761. -           if ( Dc_arg_type & ARG_UBYTE ) {
  762. -               dc_printf( "Found ubyte number! %d\n", Dc_arg_ubyte );
  763. -           }
  764. +           dc_do_command(&dc_command_str); // Try to do the command
  765. +           break;
  766.  
  767. -           if ( Dc_arg_type & ARG_HEX ) {
  768. -               dc_printf( "Found hex number! 0x%x\n", Dc_arg_int );
  769. +       default:
  770. +           // Not any of the control key codes, so it's probably a letter or number.
  771. +           ubyte c = (ubyte)key_to_ascii(k);
  772. +           if ((c != 255) && (dc_command_buf.size() < MAX_CLI_LEN)) {
  773. +               dc_command_buf.push_back(c);
  774.             }
  775.         }
  776.  
  777. -       if ( !stricmp( Dc_arg, "on" ) ) {
  778. -           Dc_arg_type |= ARG_TRUE;
  779. +       // Do the passed function
  780. +       if ( _func ) {
  781. +           _func();
  782.         }
  783. -       if ( !stricmp( Dc_arg, "true" ) ) {
  784. -           Dc_arg_type |= ARG_TRUE;
  785. -       }
  786. -       if ( !stricmp( Dc_arg, "off" ) ) {
  787. -           Dc_arg_type |= ARG_FALSE;
  788. -       }
  789. -       if ( !stricmp( Dc_arg, "false" ) ) {
  790. -           Dc_arg_type |= ARG_FALSE;
  791. -       }
  792.  
  793. -       if ( !stricmp( Dc_arg, "+" ) ) {
  794. -           Dc_arg_type |= ARG_PLUS;
  795. -       }
  796. -
  797. -       if ( !stricmp( Dc_arg, "-" ) ) {
  798. -           Dc_arg_type |= ARG_MINUS;
  799. -       }
  800. -
  801. -       if ( !stricmp( Dc_arg, "," ) ) {
  802. -           Dc_arg_type |= ARG_COMMA;
  803. -       }
  804. +       // All done, and ready for new entry
  805. +       dc_draw(TRUE);
  806.     }
  807.  
  808. -   if ( Dc_arg_type & ARG_INT) {
  809. -       if ( Dc_arg_int ) {
  810. -           Dc_arg_type |= ARG_TRUE;
  811. -       } else {
  812. -           Dc_arg_type |= ARG_FALSE;
  813. -       }
  814. +   while( key_inkey() ) {
  815. +       os_poll();
  816.     }
  817. -
  818. -   if ( Dc_arg_type & ARG_UBYTE) {
  819. -       if ( Dc_arg_ubyte ) {
  820. -           Dc_arg_type |= ARG_TRUE;
  821. -       } else {
  822. -           Dc_arg_type |= ARG_FALSE;
  823. -       }
  824. -   }
  825. -
  826. -   if ( !(Dc_arg_type&type) ) {
  827. -       if ( (Dc_arg_type & ARG_NONE) && !(type & ARG_NONE) ) {
  828. -           dc_printf( "Error: Not enough parameters.\n" );
  829. -       } else {
  830. -           dc_printf( "Error: '%s' invalid type\n", Dc_arg );
  831. -           longjmp(dc_bad_arg,1);
  832. -       }
  833. -   }
  834.  }
  835.  
  836. -void debug_help();
  837. -
  838. -void debug_do_command(char * command)
  839. +/**
  840. + * @brief Initializes the debug console.
  841. + */
  842. +void dc_init(void)
  843.  {
  844. -
  845. -   int i;
  846. -   int mode = 0;
  847. -
  848. -   if ( strlen(command) < 1 ) {
  849. +   if (debug_inited) {
  850.         return;
  851.     }
  852.  
  853. -   Dc_debug_on = 0;
  854. -   Dc_command_line = command;
  855. -   scanner_start_command(command);
  856. +   debug_inited = TRUE;
  857.  
  858. -   if (setjmp(dc_bad_arg) ) {
  859. -       return;
  860. -   }
  861. +   dc_scroll_x = 0;
  862. +   dc_scroll_y = 0;
  863.  
  864. -   dc_get_arg( ARG_ANY );
  865. -
  866. -   if ( !strcmp( Dc_arg, "debug" ) ) {
  867. -       Dc_debug_on = 1;
  868. -       dc_printf( "Command line: '%s'\n", Dc_command_line );
  869. -       dc_get_arg( ARG_ANY );
  870. +   // Empty the buffers
  871. +   if (!dc_buffer.empty()) {
  872. +       dc_buffer.clear();
  873.     }
  874.  
  875. -   if ( !stricmp( Dc_arg, "xyzzy" ) ) {
  876. -       dc_printf("Nothing happens.\n");
  877. -       return;
  878. +   if (!dc_command_buf.empty()) {
  879. +       dc_command_buf.clear();
  880.     }
  881.  
  882. -   if ( !strcmp( Dc_arg, "?" ) ) {
  883. -       mode = 1;
  884. -       dc_get_arg( ARG_ANY );
  885. +   sprintf(dc_title, "FreeSpace Open v%i.%i.%i", FS_VERSION_MAJOR, FS_VERSION_MINOR, FS_VERSION_BUILD);
  886. +   dc_printf("Debug console started.\n" );
  887. +}
  888.  
  889. -       if ( Dc_arg_type&ARG_NONE ) {
  890. -           debug_help();
  891. -           return;
  892. -       }
  893. -   }
  894. +/**
  895. + * @brief Process the entered command string
  896. + */
  897. +void dc_do_command(SCP_string *cmd_str)
  898. +{
  899. +   /**
  900. +    * Grab the first word from the cmd_str
  901. +    *  If it is not a literal, ignore it "Invalid keyword: %s"
  902. +    *  Search for the command...
  903. +    *      Compare the word against valid commands
  904. +    *      If command not found, ignore it "Invalid or unknown command: %s"\
  905. +    *  Process the command...
  906. +    *      Call the function to process the command (the rest of the command line is in the parser)
  907. +    *          Function takes care of long_help and status depending on the mode.
  908. +    */
  909. +   SCP_string command;
  910. +   extern SCP_map<SCP_string, debug_command*> dc_commands; // z64: I don't like this extern here, at all. Nope nope nope.
  911.  
  912. -   if ( !strcmp( Dc_arg, "help" ) || !strcmp( Dc_arg, "man" ) ) {
  913. -       mode = 2;
  914. -       dc_get_arg( ARG_ANY );
  915. -       if ( Dc_arg_type&ARG_NONE ) {
  916. -           debug_help();
  917. -           return;
  918. -       }
  919. -   }
  920. -
  921. -   if ( strstr( Dc_command_line, "?" ) ) {
  922. -       mode = 2;
  923. -   }
  924. -
  925. -   if ( !(Dc_arg_type&ARG_STRING) ) {
  926. -       dc_printf( "Invalid keyword '%s'\n", Dc_arg );
  927. +   if (cmd_str->empty()) {
  928.         return;
  929.     }
  930.  
  931. +   dc_parse_init(*cmd_str);
  932.  
  933. -   if (Dc_debug_on) {
  934. -       dc_printf( "Searching for command '%s'\n", Dc_arg );
  935. -   }
  936. +   dc_stuff_string_white(command);     // Grab the first token, presumably this is a command
  937.  
  938. -   for (i=0; i<Num_debug_commands; i++ ) {
  939. -       if ( !stricmp( Debug_command[i]->name, Dc_arg ) ) {
  940. -      
  941. -           if (mode==0) {
  942. -               if (Dc_debug_on) {
  943. -                   dc_printf( "Calling function '%s'\n", Dc_arg );
  944. -               }
  945. -               Dc_command = 1;
  946. -               Dc_help = 0;
  947. -               Dc_status = 1;
  948. -           } else if (mode==1) {
  949. -               if (Dc_debug_on) {
  950. -                   dc_printf( "Checking status for '%s'\n", Dc_arg );
  951. -               }
  952. -               Dc_command = 0;
  953. -               Dc_help = 0;
  954. -               Dc_status = 1;
  955. -           } else {
  956. -               if (Dc_debug_on) {
  957. -                   dc_printf( "Doing help for '%s'\n", Dc_arg );
  958. -               }
  959. -               Dc_command = 0;
  960. -               Dc_help = 1;
  961. -               Dc_status = 0;
  962. -           }
  963. +   SCP_map<SCP_string, debug_command*>::iterator it = dc_commands.find(command);
  964.  
  965. -           (*Debug_command[i]->func)();
  966. +   if (it == dc_commands.end()) {
  967. +       dc_printf("Command not found: '%s'\n", command.c_str());
  968. +       return;
  969. +   } // Else, we found our command
  970.  
  971. -           if (mode==0) {
  972. -               dc_get_arg(ARG_ANY);
  973. -               if (!(Dc_arg_type&ARG_NONE)) {
  974. -                   dc_printf( "Ignoring the unused command line tail '%s %s'\n", Dc_arg_org, Dc_command_line );
  975. -               }
  976. -           }
  977. +   (it->second)->func();   // Run the command!
  978.  
  979. -           return;
  980. -       }
  981. +   dc_stuff_string(command);
  982. +   if (command.size() > 0) {
  983. +       dc_printf( "Ignoring the unused command line tail '%s'\n", command.c_str() );
  984.     }
  985. -
  986. -   dc_printf( "Unknown command '%s'\n", Dc_arg );
  987.  }
  988.  
  989. -void debug_draw()
  990. +/**
  991. + * @brief Draws the in-game console.
  992. + */
  993. +void dc_draw(bool show_prompt = FALSE)
  994.  {
  995. -   int i;
  996. -
  997.     gr_clear();
  998.     gr_set_font(FONT1);
  999.     gr_set_color_fast( &Color_bright );
  1000. -   gr_string( 0x8000, 3, "Debug Console" );
  1001. +   gr_string( 0x8000, 3, dc_title.c_str() );
  1002.  
  1003.     gr_set_color_fast( &Color_normal );
  1004.  
  1005. -   for (i=0; i<DROWS; i++ ) {
  1006. -       gr_string( 0, i*16+16, debug_text[i] );
  1007. -   }
  1008. +   dc_draw_window(show_prompt);
  1009.  
  1010. -   int t = timer_get_fixed_seconds() / (F1_0/3);
  1011. -   if ( t & 1 ) {
  1012. -       int w,h;
  1013. -       char c;
  1014. +   gr_flip();
  1015. +}
  1016.  
  1017. -       c = debug_text[debug_y][command_line_pos+1];
  1018. -       debug_text[debug_y][command_line_pos+1] = 0;
  1019. +/**
  1020. + * Draws the cursor
  1021. + * @param [in] cmd_string  The formatted command string displayed by dc_draw_window
  1022. + * @param [in] x, y            The x and y screen position of the command string
  1023. + */
  1024. +void dc_draw_cursor( SCP_string &cmd_string, int x, int y )
  1025. +{
  1026. +   int t;
  1027. +   int w, h;   // gr_string width and height
  1028.  
  1029. -       gr_get_string_size( &w, &h, debug_text[debug_y] );
  1030. +   t = timer_get_fixed_seconds() / (F1_0/3);
  1031. +   if ( t & 1 ) {
  1032. +       gr_get_string_size( &w, &h, cmd_string.c_str() );
  1033.  
  1034.         //gr_string( w, debug_y*16, "_" );
  1035. -       gr_rect(w+1,debug_y*16+1+16,2,14);
  1036. -
  1037. -       debug_text[debug_y][command_line_pos+1] = c;
  1038. +       gr_rect((x + (w + 1)), (y + (h + 1) + 16), 2, 14);
  1039.     }
  1040. -
  1041. -   gr_flip();
  1042.  }
  1043.  
  1044. -
  1045. -void debug_output( char c )
  1046. +/**
  1047. + * Draws the window text
  1048. + */
  1049. +void dc_draw_window(bool show_prompt)
  1050.  {
  1051. -   if ( c == '\t' ) {
  1052. -       int next_tab = ((debug_x/28)+1)*28;
  1053. +   const int nocmd_lines = 2;      // Number of empty lines at the end when the command line is not shown
  1054. +   uint cmd_lines;                 // Number of lines for the command string
  1055. +   uint buffer_lines;              // Number of lines from the buffer to draw
  1056. +   uint i;                         // The current row we're drawing
  1057. +   uint j;                         // The current row of the command string we're drawing
  1058. +   SCP_string out_str;             // The command string + prompt character
  1059. +   SCP_string::iterator str_it;    // Iterator to out_str
  1060.  
  1061. -       if ( next_tab >= DCOLS-1 ) {
  1062. -           debug_x=0;
  1063. -           debug_y++;
  1064. -           scroll_times++;
  1065. -           if ( debug_y >= DROWS ) {
  1066. -               int i;
  1067. -               for (i=1; i<DROWS; i++ ) {
  1068. -                   strcpy_s( debug_text[i-1], debug_text[i] );
  1069. -               }
  1070. -               debug_y = DROWS-1;
  1071. -               debug_x = 0;
  1072. -               debug_text[debug_y][debug_x] = 0;
  1073. -           }
  1074. -           debug_text[debug_y][debug_x] = 0;
  1075. -           return;
  1076. -       }
  1077. -  
  1078. -       for ( ; debug_x < next_tab; ) {
  1079. -           debug_text[debug_y][debug_x++] = ' ';
  1080. -       }
  1081. -       debug_text[debug_y][debug_x] = 0;
  1082. -       return;
  1083. +   out_str = dc_prompt + dc_command_buf;
  1084. +   cmd_lines = (out_str.size() / DCOLS) + 1;
  1085. +   if (show_prompt) {
  1086. +       buffer_lines = DROWS - cmd_lines;
  1087. +   } else {
  1088. +       buffer_lines = DROWS - nocmd_lines;
  1089.     }
  1090.  
  1091. -   if ( (c == '\n') || (debug_x >= DCOLS-1) ) {
  1092. -       debug_x=0;
  1093. -       debug_y++;
  1094. -       scroll_times++;
  1095. -       if ( debug_y >= DROWS ) {
  1096. -           int i;
  1097. -           for (i=1; i<DROWS; i++ ) {
  1098. -               strcpy_s( debug_text[i-1], debug_text[i] );
  1099. -           }
  1100. -           debug_y = DROWS-1;
  1101. -           debug_x = 0;
  1102. -           debug_text[debug_y][debug_x] = 0;
  1103. -       }
  1104. -       debug_text[debug_y][debug_x] = 0;
  1105. -       if ( c == '\n' ) {
  1106. -           return;
  1107. -       }
  1108. +   // Ensure the buffer has DBROWS number of rows, expanding it with null strings or shrinking it as necassary
  1109. +   if (dc_buffer.size() != DBROWS) {
  1110. +       dc_buffer.resize(DBROWS, "");
  1111.     }
  1112.  
  1113. -   debug_text[debug_y][debug_x++] = c;
  1114. -   debug_text[debug_y][debug_x] = 0;
  1115. -}
  1116. +   // Ensure the window is not bigger than the buffer
  1117. +   CLAMP(DROWS, DROWS_MIN, DBROWS);
  1118. +   CLAMP(DCOLS, DCOLS_MIN, DBCOLS);
  1119.  
  1120. -void dc_printf(char *format, ...)
  1121. -{
  1122. -   char tmp[DCOLS*DROWS];
  1123. -   va_list args;
  1124. +   // Ensure we don't scroll too far
  1125. +   CLAMP(dc_scroll_x, 0, (DBCOLS - DCOLS));
  1126. +   CLAMP(dc_scroll_y, 0, (dc_buffer.size() - buffer_lines));
  1127.  
  1128. -   va_start(args, format);
  1129. -   vsprintf(tmp, format, args);
  1130. -   va_end(args);
  1131. -
  1132. -   char *p = tmp;
  1133. -   while( *p != '\0' ) {
  1134. -       debug_output(*p);
  1135. -       p++;
  1136. +   // Draw the buffer strings
  1137. +   for (i = 0; i < buffer_lines; ++i) {
  1138. +       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
  1139.     }
  1140. -}
  1141.  
  1142. -void debug_init()
  1143. -{
  1144. -   int i;
  1145. -   if ( debug_inited ) {
  1146. -       return;
  1147. -   }
  1148. +   // Draw the command string w/ padding only if the prompt is active.
  1149. +   if (show_prompt) {
  1150. +       i += 1;     // 1 line between the output and the input text
  1151.  
  1152. -   debug_inited = 1;
  1153. +       for (str_it = out_str.begin(), j = 0; str_it < out_str.end(); ++str_it, ++j) {
  1154. +           if ((j % (DCOLS - 1)) == 0) {
  1155. +               // Insert a newline char at every place the string needs to return the 'carriage'
  1156. +               out_str.insert(str_it, '\n');
  1157. +               ++j;
  1158. +           }
  1159. +       }
  1160. +       gr_string(0, ((i*16) + 16), out_str.c_str());
  1161.  
  1162. -   debug_x=0;
  1163. -   debug_y=0;
  1164. -
  1165. -   for (i=0; i<DROWS; i++ ) {
  1166. -       debug_text[i][0] = 0;
  1167. +       dc_draw_cursor(out_str, 0, ((i*16) + 16));
  1168.     }
  1169. -
  1170. -   dc_printf("Debug console started.\n" );
  1171.  }
  1172.  
  1173. -void debug_console( void (*_func)() )
  1174. +
  1175. +/**
  1176. + * @brief   Stuffs the given character into the output buffer.
  1177. + * @details Also handles tab alignment, newlines, and maintains the target.
  1178. + */
  1179. +void dc_putc(char c)
  1180.  {
  1181. -   int done = 0;
  1182. +   SCP_string* line_str = &dc_buffer.back();
  1183. +   int i;
  1184.  
  1185. -   scanner_init();
  1186. +   if (c == '\t') {
  1187. +       /**
  1188. +        * Calculate how many spaces to put in to align tabs,
  1189. +        * If we run out of room on the line, change c to a '\n' and let subsequent block handle it,
  1190. +        * Else, push the spaces onto the line
  1191. +        */
  1192. +       i = DTABS - (line_str->size() % DTABS);
  1193.  
  1194. -   while( key_inkey() ) {
  1195. -       os_poll();
  1196. +       if ((line_str->size() + i) >= (DBCOLS - 1)) {
  1197. +           c = '\n';
  1198. +       } else {
  1199. +           for (; i > 0; --i) {
  1200. +               line_str->push_back(' ');
  1201. +           }
  1202. +       }
  1203.     }
  1204.  
  1205. -   if ( !debug_inited ) {
  1206. -       debug_init();
  1207. +   if ((c == '\n') || (line_str->size() >= DBCOLS)) {
  1208. +       /**
  1209. +        * Trash whatever char happens to be past (DBCOLS - 1),
  1210. +        * Push a blank line onto the dc_buffer from the bottom,
  1211. +        * Update line_str to point to the new line,
  1212. +        * Trash the topmost line(s) in the buffer, and finally
  1213. +        * Return if the char to push was a \n
  1214. +        */
  1215. +       if (line_str->size() > DBCOLS) {
  1216. +           line_str->resize(DBCOLS);
  1217. +       }
  1218. +       dc_buffer.push_back("");
  1219. +       line_str = &dc_buffer.back();
  1220. +       ++dc_scroll_y;
  1221. +       while (dc_buffer.size() > DBROWS) {
  1222. +           dc_buffer.pop_front();
  1223. +           --dc_scroll_y;
  1224. +       }
  1225. +       if (c == '\n') {
  1226. +           return;
  1227. +       }
  1228.     }
  1229.  
  1230. -   debug_draw();
  1231. +   line_str->push_back(c);
  1232. +}
  1233.  
  1234. -   while (!done) {
  1235. -       // poll the os
  1236. -       os_poll();
  1237. +/**
  1238. + * @brief   Pauses the output of a command and allows user to scroll through the output history.
  1239. + * @details Returns true if user has pressed Esc, returns false otherwise. Use this in your function to (safely?) break
  1240. + *     out of the loop it's presumably in.
  1241. + */
  1242. +bool dc_pause_output(uint &lines)
  1243. +{
  1244. +   dc_printf("More to follow. Press any key to continue. ESC halts output...");
  1245.  
  1246. -       int k = key_inkey();
  1247. -       switch( k ) {
  1248. +   int key;
  1249. +   bool loop;
  1250. +   do {
  1251. +       loop = false;
  1252.  
  1253. -       case KEY_SHIFTED+KEY_ENTER:
  1254. +       key = key_inkey();
  1255. +       switch (key) {
  1256.         case KEY_ESC:
  1257. -           done=1; break;
  1258. -
  1259. -       case KEY_BACKSP:
  1260. -           if ( command_line_pos > 0 ) {
  1261. -               command_line[--command_line_pos] = 0;
  1262. -           }
  1263. +           return true;
  1264.             break;
  1265.  
  1266. -       case KEY_F3:
  1267. -           if ( last_oldcommand > -1 ) {
  1268. -               strcpy_s( command_line, oldcommand_line[last_oldcommand] );
  1269. -               command_line_pos = strlen(command_line);
  1270. -               command_line[command_line_pos] = 0;
  1271. -           }
  1272. +       case KEY_PAGEUP:
  1273. +           // TODO: Scroll Up
  1274. +           loop = true;
  1275.             break;
  1276. -
  1277. -       case KEY_UP:
  1278. -           command_scroll--;
  1279. -           if (command_scroll<0) {
  1280. -               command_scroll = last_oldcommand;
  1281. -           }
  1282. -
  1283. -           if ( command_scroll > -1 ) {
  1284. -               strcpy_s( command_line, oldcommand_line[command_scroll] );
  1285. -               command_line_pos = strlen(command_line);
  1286. -               command_line[command_line_pos] = 0;
  1287. -           }
  1288. +       case KEY_PAGEDOWN:
  1289. +           // TODO: Scroll Down
  1290. +           loop = true;
  1291.             break;
  1292. -
  1293. -       case KEY_DOWN:
  1294. -           command_scroll++;
  1295. -           if (command_scroll>last_oldcommand) {
  1296. -               command_scroll = 0;
  1297. -           }
  1298. -           if (command_scroll>last_oldcommand) {
  1299. -               command_scroll = -1;
  1300. -           }
  1301. -           if ( command_scroll > -1 ) {
  1302. -               strcpy_s( command_line, oldcommand_line[command_scroll] );
  1303. -               command_line_pos = strlen(command_line);
  1304. -               command_line[command_line_pos] = 0;
  1305. -           }
  1306. +       case KEY_LEFT:
  1307. +           // TODO: Scroll Left
  1308. +           loop = true;
  1309.             break;
  1310. -
  1311. -       case KEY_ENTER: {
  1312. -           debug_output( '\n' );
  1313. -           debug_draw();
  1314. -
  1315. -           debug_do_command(command_line);
  1316. -
  1317. -           int i, found = 0;
  1318. -           for (i=0; i<=last_oldcommand; i++ ) {
  1319. -               if (!stricmp( oldcommand_line[i], command_line )) {
  1320. -                   found = 1;
  1321. -               }
  1322. -           }
  1323. -           if ( !found ) {
  1324. -               if ( last_oldcommand < DEBUG_HISTORY-1 ) {
  1325. -                   last_oldcommand++;
  1326. -                   strcpy_s( oldcommand_line[last_oldcommand], command_line);
  1327. -               } else {
  1328. -                   int iLoop;
  1329. -                   for (iLoop=0; iLoop<last_oldcommand; iLoop++ ) {
  1330. -                       strcpy_s( oldcommand_line[iLoop], oldcommand_line[iLoop+1] );
  1331. -                   }
  1332. -                   strcpy_s( oldcommand_line[last_oldcommand], command_line);
  1333. -               }
  1334. -           }
  1335. -
  1336. -           debug_output( '\n' );
  1337. -           command_line_pos = 0;
  1338. -           command_line[command_line_pos] = 0;
  1339. -
  1340. -           command_scroll = 0;
  1341. -
  1342. -           }
  1343. +       case KEY_RIGHT:
  1344. +           // TODO: Scroll Right
  1345. +           loop = true;
  1346.             break;
  1347. -       default: {
  1348. -               ubyte c = (ubyte)key_to_ascii(k);
  1349. -               if ( c != 255 ) {
  1350. -                   command_line[command_line_pos++] = c;
  1351. -                   command_line[command_line_pos] = 0;
  1352. -               }
  1353. -           }
  1354. +       default:
  1355. +           lines = 0;
  1356.         }
  1357. +   } while (loop);
  1358.  
  1359. -       strcpy_s( debug_text[debug_y], ">" );
  1360. -       strcat_s( debug_text[debug_y], command_line );
  1361. -       debug_draw();
  1362. -
  1363. -       if ( _func ) {
  1364. -           _func();
  1365. -       }
  1366. -   }
  1367. -
  1368. -   while( key_inkey() ) {
  1369. -       os_poll();
  1370. -   }
  1371. -}
  1372. -
  1373. -void debug_help()
  1374. -{
  1375. -   int s, i;
  1376. -
  1377. -   dc_printf( "Available functions:\n\n" );
  1378. -
  1379. -   s = scroll_times;
  1380. -   for (i=0; i<Num_debug_commands; i++ ) {
  1381. -       dc_printf( " %s - %s\n", Debug_command[i]->name, Debug_command[i]->help );
  1382. -
  1383. -       if ( scroll_times - s > DROWS - 3 ) {
  1384. -           int k;
  1385. -           dc_printf( "       Press a key...B for back\n" );
  1386. -           debug_draw();
  1387. -           k = key_getch();
  1388. -           s = scroll_times;
  1389. -           if ( k == KEY_B ) {
  1390. -               i -= ((DROWS-3)*2);
  1391. -               if ( i <= 0 ) {
  1392. -                   i = -1;
  1393. -               }
  1394. -           }
  1395. -       }
  1396. -       debug_draw();
  1397. -   }
  1398. -   dc_printf( "\n" );
  1399. -
  1400. -   dc_printf( "Typing '? function_name' will give the current status.\n" );
  1401. -   dc_printf( "Typing 'function_name ?' will give help on the function.\n" );
  1402. -   dc_printf( "Typing ? or help will give you help.\n");
  1403. -   dc_printf( "F3 selects last command line.\n" );
  1404. -}
  1405. +   return false;
  1406. +};
  1407. Index: debugconsole/console.h
  1408. ===================================================================
  1409. --- debugconsole/console.h  (Revision 0)
  1410. +++ debugconsole/console.h  (Arbeitskopie)
  1411. @@ -0,0 +1,1040 @@
  1412. +#ifndef _CONSOLE_H
  1413. +#define _CONSOLE_H
  1414. +/*
  1415. + * z64555's debug console, created for the FreeSpace Source Code project
  1416. + *
  1417. + * Portions of this source code are based on works by Volition, Inc. circa 1999. You may not sell or otherwise
  1418. + * commercially exploit the source or things you created based on the source.
  1419. + */
  1420. +
  1421. +/**
  1422. + * @file console.h
  1423. + * @brief An overhauled/updated debug console to allow monitoring, testing, and general debugging of new features.
  1424. + *
  1425. + * @details
  1426. + * Of key interest is Volition's DCF macro, which adds the function argument to the available command list in the
  1427. + * debug console. These functions may be defined in the .cpp file that they are related to, but it is recommended
  1428. + * that they be in their own .cpp if they have multiple sub-arguments (ex: Git has its sub-arguments delimited by
  1429. + * a pair of -'s, or --)
  1430. + */
  1431. +
  1432. +#include "debugconsole/consoleparse.h"
  1433. +#include "globalincs/pstypes.h"
  1434. +#include "globalincs/vmallocator.h"
  1435. +
  1436. +/**
  1437. + * @def DCF
  1438. + *
  1439. + * @brief The potent DCF macro, used to define new debug commands for the console.
  1440. + *
  1441. + * @param function_name[in] The name of the function, as shown in the debug console
  1442. + * @param help_txt[in] The short-help text, as shown as listed from the 'help' command
  1443. + *
  1444. + * @details Usage example:
  1445. + * DCF(toggle_it,"description")
  1446. + * {
  1447. + *     switch (Dc_mode) {
  1448. + *     case dcm_command:
  1449. + *          This_var = !This_var;
  1450. + *     break;
  1451. + *
  1452. + *     case dcm_help:
  1453. + *         dc_printf( "Usage: sample. Toggles This_var on/off.\n" );
  1454. + *     break;
  1455. + *
  1456. + *     case dcm_status:
  1457. + *         dc_printf( "The status is %d.\n", This_var );
  1458. + *     break;
  1459. + *     default:
  1460. + *         if (Dc_debug_on) {
  1461. + *             dc_printf( "<debug> Unknown command mode %i", Dc_mode);
  1462. + *         }
  1463. + *     }
  1464. + * }
  1465. + *  
  1466. + *  In the console, the command will be listed as 'toggle_it', and help will display it as:
  1467. + *      toggle_it  - Usage: sample. Toggles This_var on/off.
  1468. + *  Note: The only allowed function type is a void fn( void )
  1469. + */
  1470. +#define DCF(function_name, help_text)  \
  1471. +       void dcf_##function_name(); \
  1472. +       debug_command dcmd_##function_name(#function_name, help_text, dcf_##function_name); \
  1473. +       void dcf_##function_name()
  1474. +
  1475. +
  1476. +/**
  1477. + *  @def Shortcut for debug commands that toggle a bool, such as Show_lightning
  1478. + *  
  1479. + *  @param [in] function_name Name of the function, as shown in the debug console
  1480. + *  @param [in] bool_variable Name of the variable to allow toggling.
  1481. + */
  1482. +#define DCF_BOOL(function_name, bool_variable) \
  1483. +   void dcf_##function_name();     \
  1484. +   debug_command dcmd_##function_name(#function_name, "Sets or toggles the boolean: "#bool_variable, dcf_##function_name );    \
  1485. +   void dcf_##function_name() {    \
  1486. +       if (dc_optional_string_either("help", "--help")) {  \
  1487. +               dc_printf( "Usage: %s [bool]\nSets %s to true or false.  If nothing passed, then toggles it.\n", #function_name, #bool_variable );  \
  1488. +               return;     \
  1489. +       }   \
  1490. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  1491. +           dc_printf("%s = %s\n", #function_name, (bool_variable ? "TRUE" : "FALSE"));     \
  1492. +           return;     \
  1493. +       }   \
  1494. +       if (!dc_maybe_stuff_boolean(&bool_variable)) {  \
  1495. +           bool_variable = !bool_variable; \
  1496. +       }   \
  1497. +   }   \
  1498. +
  1499. +
  1500. +/**
  1501. + *  @def Same as DCF_BOOL, but with custom help strings
  1502. + *  
  1503. + *  @param [in] function_name Name of the function, as shown in the debug console
  1504. + *  @param [in] bool_variable Name of the variable to allow toggling.
  1505. + */
  1506. +#define DCF_BOOL2(function_name, bool_variable, short_help, long_help) \
  1507. +   void dcf_##function_name();     \
  1508. +   debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );  \
  1509. +   void dcf_##function_name() {    \
  1510. +       if (dc_optional_string_either("help", "--help")) {  \
  1511. +           dc_printf( #long_help );    \
  1512. +               return;     \
  1513. +       }   \
  1514. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  1515. +           dc_printf("%s = %s\n", #function_name, (bool_variable ? "TRUE" : "FALSE"));     \
  1516. +           return;     \
  1517. +       }   \
  1518. +       if (!dc_maybe_stuff_boolean(&bool_variable)) {  \
  1519. +           bool_variable = !bool_variable; \
  1520. +       }   \
  1521. +   }   \
  1522. +
  1523. + /**
  1524. +  * @def Shortcut for single-variable setters/monitors
  1525. +  *
  1526. +  * @param [in] function_name
  1527. +  * @param [in] float_variable
  1528. +  * @param [in] short_help
  1529. +  */
  1530. + #define DCF_FLOAT(function_name, float_variable, short_help)  \
  1531. +   void dcf_##function_name();     \
  1532. +   debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );  \
  1533. +   void dcf_##function_name() {    \
  1534. +       float value;    \
  1535. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  1536. +           dc_printf("%s = %f\n", #float_variable, float_variable);        \
  1537. +           return;     \
  1538. +       }   \
  1539. +       dc_stuff_float(&value); \
  1540. +       float_variable = value; \
  1541. +       dc_printf("%s set to %f\n", #float_variable, float_variable);   \
  1542. +   }   \
  1543. +
  1544. + /**
  1545. +  * @def Shortcut for single-variable setters/monitors with lower/upper bounds clamping
  1546. +  *
  1547. +  * @param [in] function_name
  1548. +  * @param [in] float_variable
  1549. +  * @param [in] short_help
  1550. +  */
  1551. + #define DCF_FLOAT2(function_name, float_variable, lower_bounds, upper_bounds, short_help) \
  1552. +   void dcf_##function_name();     \
  1553. +   debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );  \
  1554. +   void dcf_##function_name() {    \
  1555. +       float value;    \
  1556. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  1557. +           dc_printf("%s = %f\n", #float_variable, float_variable);        \
  1558. +           return;     \
  1559. +       }   \
  1560. +       dc_stuff_float(&value); \
  1561. +       CLAMP(float_variable, lower_bounds, upper_bounds);  \
  1562. +       float_variable = value; \
  1563. +       dc_printf("%s set to %f\n", #float_variable, float_variable);   \
  1564. +   }   \
  1565. +
  1566. + /**
  1567. +  * @def Shortcut for single-variable setters/monitors
  1568. +  *
  1569. +  * @param [in] function_name
  1570. +  * @param [in] int_variable
  1571. +  * @param [in] short_help
  1572. +  */
  1573. + #define DCF_INT(function_name, int_variable, short_help)  \
  1574. +   void dcf_##function_name();     \
  1575. +   debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );  \
  1576. +   void dcf_##function_name() {    \
  1577. +       float value;    \
  1578. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  1579. +           dc_printf("%s = %f\n", #int_variable, int_variable);        \
  1580. +           return;     \
  1581. +       }   \
  1582. +       dc_stuff_float(&value); \
  1583. +       int_variable = value;   \
  1584. +       dc_printf("%s set to %f\n", #int_variable, int_variable);   \
  1585. +   }   \
  1586. +
  1587. + /**
  1588. +  * @def Shortcut for single-variable setters/monitors with lower/upper bounds clamping
  1589. +  *
  1590. +  * @param [in] function_name
  1591. +  * @param [in] int_variable
  1592. +  * @param [in] short_help
  1593. +  */
  1594. + #define DCF_INT2(function_name, int_variable, lower_bounds, upper_bounds, short_help) \
  1595. +   void dcf_##function_name();     \
  1596. +   debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );  \
  1597. +   void dcf_##function_name() {    \
  1598. +       float value;    \
  1599. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  1600. +           dc_printf("%s = %f\n", #int_variable, int_variable);        \
  1601. +           return;     \
  1602. +       }   \
  1603. +       dc_stuff_float(&value); \
  1604. +       CLAMP(int_variable, lower_bounds, upper_bounds);    \
  1605. +       int_variable = value;   \
  1606. +       dc_printf("%s set to %f\n", #int_variable, int_variable);   \
  1607. +   }   \
  1608. +
  1609. +/**
  1610. + *  @class debug_command
  1611. + *  @brief Class to aggregate a debug command with its name (as shown in the console) and short help.
  1612. + *  
  1613. + *  @details
  1614. + *  Note: Long help, as evoked by '<command> help', should be handled by the function itself. It is recommended
  1615. + *  that arguments that have sub-arguments be in their own function, so as to aide in organization and to keep the
  1616. + *  size of the command function down.
  1617. + */
  1618. +class debug_command {
  1619. +public:
  1620. +   char *name;     //!< The name of the command, as shown in the debug console
  1621. +   char *help;     //!< The short help string, as shown by 'help <command>'
  1622. +   void (*func)(); //!< Pointer to the function that is run when this command is evoked
  1623. +
  1624. +   /**
  1625. +   * @brief Adds a debug command to the debug_commands map, if it isn't in there already.
  1626. +   *
  1627. +   * @details The DCF macro more or less guarantees that a command won't be duplicated on compile time. But no harm in
  1628. +   *   some extra caution.
  1629. +   */
  1630. +   debug_command(char *name, char *help, void (*func)());
  1631. +};
  1632. +
  1633. +/**
  1634. + * Dc_mode tells your function what to do.
  1635. + * Your function _must_ process the command.
  1636. + *
  1637. + * It is recommended that each function have, at minimum, this switch statement:
  1638. + *   switch (Dc_mode) {
  1639. + *   case dcm_command:
  1640. + *     // process command
  1641. + *     break;
  1642. + *  
  1643. + *   case dcm_help:
  1644. + *     // provide detailed help
  1645. + *     break;
  1646. + *  
  1647. + *   case dcm_status:
  1648. + *     // provide status on the command
  1649. + *     break;
  1650. + *  
  1651. + *   default:
  1652. + *     // (optional)
  1653. + *     dc_printf("<command_name> Unknown command mode %i\n", Dc_mode);
  1654. + *   }
  1655. + */
  1656. +enum dc_mode {
  1657. +   dcm_command,    // process the command
  1658. +   dcm_help,       // print out the help text in the form, "usage: ... \nLong description\n" );
  1659. +   dcm_status      // print out the current status of the command.
  1660. +};
  1661. +
  1662. +extern dc_mode Dc_mode;
  1663. +extern bool Dc_debug_on;
  1664. +
  1665. +extern SCP_string dc_command_str;  // The rest of the command line, from the end of the last processed arg on.
  1666. +
  1667. +void debug_console(void (*func)(void) = NULL);     // Starts the debug console, and runs the given function after each time a command is processed
  1668. +void dc_printf( char *format, ... );               // Outputs to the debug console
  1669. +bool dc_pause_output(uint &lines);                 // Pauses execution and waits for user intput. Allows scrolling.
  1670. +
  1671. +#endif // _CONSOLE_H
  1672. +#ifndef _CONSOLE_H
  1673. +#define _CONSOLE_H
  1674. +/*
  1675. + * z64555's debug console, created for the FreeSpace Source Code project
  1676. + *
  1677. + * Portions of this source code are based on works by Volition, Inc. circa 1999. You may not sell or otherwise
  1678. + * commercially exploit the source or things you created based on the source.
  1679. + */
  1680. +
  1681. +/**
  1682. + * @file console.h
  1683. + * @brief An overhauled/updated debug console to allow monitoring, testing, and general debugging of new features.
  1684. + *
  1685. + * @details
  1686. + * Of key interest is Volition's DCF macro, which adds the function argument to the available command list in the
  1687. + * debug console. These functions may be defined in the .cpp file that they are related to, but it is recommended
  1688. + * that they be in their own .cpp if they have multiple sub-arguments (ex: Git has its sub-arguments delimited by
  1689. + * a pair of -'s, or --)
  1690. + */
  1691. +
  1692. +#include "debugconsole/consoleparse.h"
  1693. +#include "globalincs/pstypes.h"
  1694. +#include "globalincs/vmallocator.h"
  1695. +
  1696. +/**
  1697. + * @def DCF
  1698. + *
  1699. + * @brief The potent DCF macro, used to define new debug commands for the console.
  1700. + *
  1701. + * @param function_name[in] The name of the function, as shown in the debug console
  1702. + * @param help_txt[in] The short-help text, as shown as listed from the 'help' command
  1703. + *
  1704. + * @details Usage example:
  1705. + * DCF(toggle_it,"description")
  1706. + * {
  1707. + *     switch (Dc_mode) {
  1708. + *     case dcm_command:
  1709. + *          This_var = !This_var;
  1710. + *     break;
  1711. + *
  1712. + *     case dcm_help:
  1713. + *         dc_printf( "Usage: sample. Toggles This_var on/off.\n" );
  1714. + *     break;
  1715. + *
  1716. + *     case dcm_status:
  1717. + *         dc_printf( "The status is %d.\n", This_var );
  1718. + *     break;
  1719. + *     default:
  1720. + *         if (Dc_debug_on) {
  1721. + *             dc_printf( "<debug> Unknown command mode %i", Dc_mode);
  1722. + *         }
  1723. + *     }
  1724. + * }
  1725. + *  
  1726. + *  In the console, the command will be listed as 'toggle_it', and help will display it as:
  1727. + *      toggle_it  - Usage: sample. Toggles This_var on/off.
  1728. + *  Note: The only allowed function type is a void fn( void )
  1729. + */
  1730. +#define DCF(function_name, help_text)  \
  1731. +       void dcf_##function_name(); \
  1732. +       debug_command dcmd_##function_name(#function_name, help_text, dcf_##function_name); \
  1733. +       void dcf_##function_name()
  1734. +
  1735. +
  1736. +/**
  1737. + *  @def Shortcut for debug commands that toggle a bool, such as Show_lightning
  1738. + *  
  1739. + *  @param [in] function_name Name of the function, as shown in the debug console
  1740. + *  @param [in] bool_variable Name of the variable to allow toggling.
  1741. + */
  1742. +#define DCF_BOOL(function_name, bool_variable) \
  1743. +   void dcf_##function_name();     \
  1744. +   debug_command dcmd_##function_name(#function_name, "Sets or toggles the boolean: "#bool_variable, dcf_##function_name );    \
  1745. +   void dcf_##function_name() {    \
  1746. +       if (dc_optional_string_either("help", "--help")) {  \
  1747. +               dc_printf( "Usage: %s [bool]\nSets %s to true or false.  If nothing passed, then toggles it.\n", #function_name, #bool_variable );  \
  1748. +               return;     \
  1749. +       }   \
  1750. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  1751. +           dc_printf("%s = %s\n", #function_name, (bool_variable ? "TRUE" : "FALSE"));     \
  1752. +           return;     \
  1753. +       }   \
  1754. +       if (!dc_maybe_stuff_boolean(&bool_variable)) {  \
  1755. +           bool_variable = !bool_variable; \
  1756. +       }   \
  1757. +   }   \
  1758. +
  1759. +
  1760. +/**
  1761. + *  @def Same as DCF_BOOL, but with custom help strings
  1762. + *  
  1763. + *  @param [in] function_name Name of the function, as shown in the debug console
  1764. + *  @param [in] bool_variable Name of the variable to allow toggling.
  1765. + */
  1766. +#define DCF_BOOL2(function_name, bool_variable, short_help, long_help) \
  1767. +   void dcf_##function_name();     \
  1768. +   debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );  \
  1769. +   void dcf_##function_name() {    \
  1770. +       if (dc_optional_string_either("help", "--help")) {  \
  1771. +           dc_printf( #long_help );    \
  1772. +               return;     \
  1773. +       }   \
  1774. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  1775. +           dc_printf("%s = %s\n", #function_name, (bool_variable ? "TRUE" : "FALSE"));     \
  1776. +           return;     \
  1777. +       }   \
  1778. +       if (!dc_maybe_stuff_boolean(&bool_variable)) {  \
  1779. +           bool_variable = !bool_variable; \
  1780. +       }   \
  1781. +   }   \
  1782. +
  1783. + /**
  1784. +  * @def Shortcut for single-variable setters/monitors
  1785. +  *
  1786. +  * @param [in] function_name
  1787. +  * @param [in] float_variable
  1788. +  * @param [in] short_help
  1789. +  */
  1790. + #define DCF_FLOAT(function_name, float_variable, short_help)  \
  1791. +   void dcf_##function_name();     \
  1792. +   debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );  \
  1793. +   void dcf_##function_name() {    \
  1794. +       float value;    \
  1795. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  1796. +           dc_printf("%s = %f\n", #float_variable, float_variable);        \
  1797. +           return;     \
  1798. +       }   \
  1799. +       dc_stuff_float(&value); \
  1800. +       float_variable = value; \
  1801. +       dc_printf("%s set to %f\n", #float_variable, float_variable);   \
  1802. +   }   \
  1803. +
  1804. + /**
  1805. +  * @def Shortcut for single-variable setters/monitors with lower/upper bounds clamping
  1806. +  *
  1807. +  * @param [in] function_name
  1808. +  * @param [in] float_variable
  1809. +  * @param [in] short_help
  1810. +  */
  1811. + #define DCF_FLOAT2(function_name, float_variable, lower_bounds, upper_bounds, short_help) \
  1812. +   void dcf_##function_name();     \
  1813. +   debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );  \
  1814. +   void dcf_##function_name() {    \
  1815. +       float value;    \
  1816. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  1817. +           dc_printf("%s = %f\n", #float_variable, float_variable);        \
  1818. +           return;     \
  1819. +       }   \
  1820. +       dc_stuff_float(&value); \
  1821. +       CLAMP(float_variable, lower_bounds, upper_bounds);  \
  1822. +       float_variable = value; \
  1823. +       dc_printf("%s set to %f\n", #float_variable, float_variable);   \
  1824. +   }   \
  1825. +
  1826. + /**
  1827. +  * @def Shortcut for single-variable setters/monitors
  1828. +  *
  1829. +  * @param [in] function_name
  1830. +  * @param [in] int_variable
  1831. +  * @param [in] short_help
  1832. +  */
  1833. + #define DCF_INT(function_name, int_variable, short_help)  \
  1834. +   void dcf_##function_name();     \
  1835. +   debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );  \
  1836. +   void dcf_##function_name() {    \
  1837. +       float value;    \
  1838. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  1839. +           dc_printf("%s = %f\n", #int_variable, int_variable);        \
  1840. +           return;     \
  1841. +       }   \
  1842. +       dc_stuff_float(&value); \
  1843. +       int_variable = value;   \
  1844. +       dc_printf("%s set to %f\n", #int_variable, int_variable);   \
  1845. +   }   \
  1846. +
  1847. + /**
  1848. +  * @def Shortcut for single-variable setters/monitors with lower/upper bounds clamping
  1849. +  *
  1850. +  * @param [in] function_name
  1851. +  * @param [in] int_variable
  1852. +  * @param [in] short_help
  1853. +  */
  1854. + #define DCF_INT2(function_name, int_variable, lower_bounds, upper_bounds, short_help) \
  1855. +   void dcf_##function_name();     \
  1856. +   debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );  \
  1857. +   void dcf_##function_name() {    \
  1858. +       float value;    \
  1859. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  1860. +           dc_printf("%s = %f\n", #int_variable, int_variable);        \
  1861. +           return;     \
  1862. +       }   \
  1863. +       dc_stuff_float(&value); \
  1864. +       CLAMP(int_variable, lower_bounds, upper_bounds);    \
  1865. +       int_variable = value;   \
  1866. +       dc_printf("%s set to %f\n", #int_variable, int_variable);   \
  1867. +   }   \
  1868. +
  1869. +/**
  1870. + *  @class debug_command
  1871. + *  @brief Class to aggregate a debug command with its name (as shown in the console) and short help.
  1872. + *  
  1873. + *  @details
  1874. + *  Note: Long help, as evoked by '<command> help', should be handled by the function itself. It is recommended
  1875. + *  that arguments that have sub-arguments be in their own function, so as to aide in organization and to keep the
  1876. + *  size of the command function down.
  1877. + */
  1878. +class debug_command {
  1879. +public:
  1880. +   char *name;     //!< The name of the command, as shown in the debug console
  1881. +   char *help;     //!< The short help string, as shown by 'help <command>'
  1882. +   void (*func)(); //!< Pointer to the function that is run when this command is evoked
  1883. +
  1884. +   /**
  1885. +   * @brief Adds a debug command to the debug_commands map, if it isn't in there already.
  1886. +   *
  1887. +   * @details The DCF macro more or less guarantees that a command won't be duplicated on compile time. But no harm in
  1888. +   *   some extra caution.
  1889. +   */
  1890. +   debug_command(char *name, char *help, void (*func)());
  1891. +};
  1892. +
  1893. +/**
  1894. + * Dc_mode tells your function what to do.
  1895. + * Your function _must_ process the command.
  1896. + *
  1897. + * It is recommended that each function have, at minimum, this switch statement:
  1898. + *   switch (Dc_mode) {
  1899. + *   case dcm_command:
  1900. + *     // process command
  1901. + *     break;
  1902. + *  
  1903. + *   case dcm_help:
  1904. + *     // provide detailed help
  1905. + *     break;
  1906. + *  
  1907. + *   case dcm_status:
  1908. + *     // provide status on the command
  1909. + *     break;
  1910. + *  
  1911. + *   default:
  1912. + *     // (optional)
  1913. + *     dc_printf("<command_name> Unknown command mode %i\n", Dc_mode);
  1914. + *   }
  1915. + */
  1916. +enum dc_mode {
  1917. +   dcm_command,    // process the command
  1918. +   dcm_help,       // print out the help text in the form, "usage: ... \nLong description\n" );
  1919. +   dcm_status      // print out the current status of the command.
  1920. +};
  1921. +
  1922. +extern dc_mode Dc_mode;
  1923. +extern bool Dc_debug_on;
  1924. +
  1925. +extern SCP_string dc_command_str;  // The rest of the command line, from the end of the last processed arg on.
  1926. +
  1927. +void debug_console(void (*func)(void) = NULL);     // Starts the debug console, and runs the given function after each time a command is processed
  1928. +void dc_printf( char *format, ... );               // Outputs to the debug console
  1929. +bool dc_pause_output(uint &lines);                 // Pauses execution and waits for user intput. Allows scrolling.
  1930. +
  1931. +#endif // _CONSOLE_H
  1932. +#ifndef _CONSOLE_H
  1933. +#define _CONSOLE_H
  1934. +/*
  1935. + * z64555's debug console, created for the FreeSpace Source Code project
  1936. + *
  1937. + * Portions of this source code are based on works by Volition, Inc. circa 1999. You may not sell or otherwise
  1938. + * commercially exploit the source or things you created based on the source.
  1939. + */
  1940. +
  1941. +/**
  1942. + * @file console.h
  1943. + * @brief An overhauled/updated debug console to allow monitoring, testing, and general debugging of new features.
  1944. + *
  1945. + * @details
  1946. + * Of key interest is Volition's DCF macro, which adds the function argument to the available command list in the
  1947. + * debug console. These functions may be defined in the .cpp file that they are related to, but it is recommended
  1948. + * that they be in their own .cpp if they have multiple sub-arguments (ex: Git has its sub-arguments delimited by
  1949. + * a pair of -'s, or --)
  1950. + */
  1951. +
  1952. +#include "debugconsole/consoleparse.h"
  1953. +#include "globalincs/pstypes.h"
  1954. +#include "globalincs/vmallocator.h"
  1955. +
  1956. +/**
  1957. + * @def DCF
  1958. + *
  1959. + * @brief The potent DCF macro, used to define new debug commands for the console.
  1960. + *
  1961. + * @param function_name[in] The name of the function, as shown in the debug console
  1962. + * @param help_txt[in] The short-help text, as shown as listed from the 'help' command
  1963. + *
  1964. + * @details Usage example:
  1965. + * DCF(toggle_it,"description")
  1966. + * {
  1967. + *     switch (Dc_mode) {
  1968. + *     case dcm_command:
  1969. + *          This_var = !This_var;
  1970. + *     break;
  1971. + *
  1972. + *     case dcm_help:
  1973. + *         dc_printf( "Usage: sample. Toggles This_var on/off.\n" );
  1974. + *     break;
  1975. + *
  1976. + *     case dcm_status:
  1977. + *         dc_printf( "The status is %d.\n", This_var );
  1978. + *     break;
  1979. + *     default:
  1980. + *         if (Dc_debug_on) {
  1981. + *             dc_printf( "<debug> Unknown command mode %i", Dc_mode);
  1982. + *         }
  1983. + *     }
  1984. + * }
  1985. + *  
  1986. + *  In the console, the command will be listed as 'toggle_it', and help will display it as:
  1987. + *      toggle_it  - Usage: sample. Toggles This_var on/off.
  1988. + *  Note: The only allowed function type is a void fn( void )
  1989. + */
  1990. +#define DCF(function_name, help_text)  \
  1991. +       void dcf_##function_name(); \
  1992. +       debug_command dcmd_##function_name(#function_name, help_text, dcf_##function_name); \
  1993. +       void dcf_##function_name()
  1994. +
  1995. +
  1996. +/**
  1997. + *  @def Shortcut for debug commands that toggle a bool, such as Show_lightning
  1998. + *  
  1999. + *  @param [in] function_name Name of the function, as shown in the debug console
  2000. + *  @param [in] bool_variable Name of the variable to allow toggling.
  2001. + */
  2002. +#define DCF_BOOL(function_name, bool_variable) \
  2003. +   void dcf_##function_name();     \
  2004. +   debug_command dcmd_##function_name(#function_name, "Sets or toggles the boolean: "#bool_variable, dcf_##function_name );    \
  2005. +   void dcf_##function_name() {    \
  2006. +       if (dc_optional_string_either("help", "--help")) {  \
  2007. +               dc_printf( "Usage: %s [bool]\nSets %s to true or false.  If nothing passed, then toggles it.\n", #function_name, #bool_variable );  \
  2008. +               return;     \
  2009. +       }   \
  2010. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  2011. +           dc_printf("%s = %s\n", #function_name, (bool_variable ? "TRUE" : "FALSE"));     \
  2012. +           return;     \
  2013. +       }   \
  2014. +       if (!dc_maybe_stuff_boolean(&bool_variable)) {  \
  2015. +           bool_variable = !bool_variable; \
  2016. +       }   \
  2017. +   }   \
  2018. +
  2019. +
  2020. +/**
  2021. + *  @def Same as DCF_BOOL, but with custom help strings
  2022. + *  
  2023. + *  @param [in] function_name Name of the function, as shown in the debug console
  2024. + *  @param [in] bool_variable Name of the variable to allow toggling.
  2025. + */
  2026. +#define DCF_BOOL2(function_name, bool_variable, short_help, long_help) \
  2027. +   void dcf_##function_name();     \
  2028. +   debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );  \
  2029. +   void dcf_##function_name() {    \
  2030. +       if (dc_optional_string_either("help", "--help")) {  \
  2031. +           dc_printf( #long_help );    \
  2032. +               return;     \
  2033. +       }   \
  2034. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  2035. +           dc_printf("%s = %s\n", #function_name, (bool_variable ? "TRUE" : "FALSE"));     \
  2036. +           return;     \
  2037. +       }   \
  2038. +       if (!dc_maybe_stuff_boolean(&bool_variable)) {  \
  2039. +           bool_variable = !bool_variable; \
  2040. +       }   \
  2041. +   }   \
  2042. +
  2043. + /**
  2044. +  * @def Shortcut for single-variable setters/monitors
  2045. +  *
  2046. +  * @param [in] function_name
  2047. +  * @param [in] float_variable
  2048. +  * @param [in] short_help
  2049. +  */
  2050. + #define DCF_FLOAT(function_name, float_variable, short_help)  \
  2051. +   void dcf_##function_name();     \
  2052. +   debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );  \
  2053. +   void dcf_##function_name() {    \
  2054. +       float value;    \
  2055. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  2056. +           dc_printf("%s = %f\n", #float_variable, float_variable);        \
  2057. +           return;     \
  2058. +       }   \
  2059. +       dc_stuff_float(&value); \
  2060. +       float_variable = value; \
  2061. +       dc_printf("%s set to %f\n", #float_variable, float_variable);   \
  2062. +   }   \
  2063. +
  2064. + /**
  2065. +  * @def Shortcut for single-variable setters/monitors with lower/upper bounds clamping
  2066. +  *
  2067. +  * @param [in] function_name
  2068. +  * @param [in] float_variable
  2069. +  * @param [in] short_help
  2070. +  */
  2071. + #define DCF_FLOAT2(function_name, float_variable, lower_bounds, upper_bounds, short_help) \
  2072. +   void dcf_##function_name();     \
  2073. +   debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );  \
  2074. +   void dcf_##function_name() {    \
  2075. +       float value;    \
  2076. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  2077. +           dc_printf("%s = %f\n", #float_variable, float_variable);        \
  2078. +           return;     \
  2079. +       }   \
  2080. +       dc_stuff_float(&value); \
  2081. +       CLAMP(float_variable, lower_bounds, upper_bounds);  \
  2082. +       float_variable = value; \
  2083. +       dc_printf("%s set to %f\n", #float_variable, float_variable);   \
  2084. +   }   \
  2085. +
  2086. + /**
  2087. +  * @def Shortcut for single-variable setters/monitors
  2088. +  *
  2089. +  * @param [in] function_name
  2090. +  * @param [in] int_variable
  2091. +  * @param [in] short_help
  2092. +  */
  2093. + #define DCF_INT(function_name, int_variable, short_help)  \
  2094. +   void dcf_##function_name();     \
  2095. +   debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );  \
  2096. +   void dcf_##function_name() {    \
  2097. +       float value;    \
  2098. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  2099. +           dc_printf("%s = %f\n", #int_variable, int_variable);        \
  2100. +           return;     \
  2101. +       }   \
  2102. +       dc_stuff_float(&value); \
  2103. +       int_variable = value;   \
  2104. +       dc_printf("%s set to %f\n", #int_variable, int_variable);   \
  2105. +   }   \
  2106. +
  2107. + /**
  2108. +  * @def Shortcut for single-variable setters/monitors with lower/upper bounds clamping
  2109. +  *
  2110. +  * @param [in] function_name
  2111. +  * @param [in] int_variable
  2112. +  * @param [in] short_help
  2113. +  */
  2114. + #define DCF_INT2(function_name, int_variable, lower_bounds, upper_bounds, short_help) \
  2115. +   void dcf_##function_name();     \
  2116. +   debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );  \
  2117. +   void dcf_##function_name() {    \
  2118. +       float value;    \
  2119. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  2120. +           dc_printf("%s = %f\n", #int_variable, int_variable);        \
  2121. +           return;     \
  2122. +       }   \
  2123. +       dc_stuff_float(&value); \
  2124. +       CLAMP(int_variable, lower_bounds, upper_bounds);    \
  2125. +       int_variable = value;   \
  2126. +       dc_printf("%s set to %f\n", #int_variable, int_variable);   \
  2127. +   }   \
  2128. +
  2129. +/**
  2130. + *  @class debug_command
  2131. + *  @brief Class to aggregate a debug command with its name (as shown in the console) and short help.
  2132. + *  
  2133. + *  @details
  2134. + *  Note: Long help, as evoked by '<command> help', should be handled by the function itself. It is recommended
  2135. + *  that arguments that have sub-arguments be in their own function, so as to aide in organization and to keep the
  2136. + *  size of the command function down.
  2137. + */
  2138. +class debug_command {
  2139. +public:
  2140. +   char *name;     //!< The name of the command, as shown in the debug console
  2141. +   char *help;     //!< The short help string, as shown by 'help <command>'
  2142. +   void (*func)(); //!< Pointer to the function that is run when this command is evoked
  2143. +
  2144. +   /**
  2145. +   * @brief Adds a debug command to the debug_commands map, if it isn't in there already.
  2146. +   *
  2147. +   * @details The DCF macro more or less guarantees that a command won't be duplicated on compile time. But no harm in
  2148. +   *   some extra caution.
  2149. +   */
  2150. +   debug_command(char *name, char *help, void (*func)());
  2151. +};
  2152. +
  2153. +/**
  2154. + * Dc_mode tells your function what to do.
  2155. + * Your function _must_ process the command.
  2156. + *
  2157. + * It is recommended that each function have, at minimum, this switch statement:
  2158. + *   switch (Dc_mode) {
  2159. + *   case dcm_command:
  2160. + *     // process command
  2161. + *     break;
  2162. + *  
  2163. + *   case dcm_help:
  2164. + *     // provide detailed help
  2165. + *     break;
  2166. + *  
  2167. + *   case dcm_status:
  2168. + *     // provide status on the command
  2169. + *     break;
  2170. + *  
  2171. + *   default:
  2172. + *     // (optional)
  2173. + *     dc_printf("<command_name> Unknown command mode %i\n", Dc_mode);
  2174. + *   }
  2175. + */
  2176. +enum dc_mode {
  2177. +   dcm_command,    // process the command
  2178. +   dcm_help,       // print out the help text in the form, "usage: ... \nLong description\n" );
  2179. +   dcm_status      // print out the current status of the command.
  2180. +};
  2181. +
  2182. +extern dc_mode Dc_mode;
  2183. +extern bool Dc_debug_on;
  2184. +
  2185. +extern SCP_string dc_command_str;  // The rest of the command line, from the end of the last processed arg on.
  2186. +
  2187. +void debug_console(void (*func)(void) = NULL);     // Starts the debug console, and runs the given function after each time a command is processed
  2188. +void dc_printf( char *format, ... );               // Outputs to the debug console
  2189. +bool dc_pause_output(uint &lines);                 // Pauses execution and waits for user intput. Allows scrolling.
  2190. +
  2191. +#endif // _CONSOLE_H
  2192. +#ifndef _CONSOLE_H
  2193. +#define _CONSOLE_H
  2194. +/*
  2195. + * z64555's debug console, created for the FreeSpace Source Code project
  2196. + *
  2197. + * Portions of this source code are based on works by Volition, Inc. circa 1999. You may not sell or otherwise
  2198. + * commercially exploit the source or things you created based on the source.
  2199. + */
  2200. +
  2201. +/**
  2202. + * @file console.h
  2203. + * @brief An overhauled/updated debug console to allow monitoring, testing, and general debugging of new features.
  2204. + *
  2205. + * @details
  2206. + * Of key interest is Volition's DCF macro, which adds the function argument to the available command list in the
  2207. + * debug console. These functions may be defined in the .cpp file that they are related to, but it is recommended
  2208. + * that they be in their own .cpp if they have multiple sub-arguments (ex: Git has its sub-arguments delimited by
  2209. + * a pair of -'s, or --)
  2210. + */
  2211. +
  2212. +#include "debugconsole/consoleparse.h"
  2213. +#include "globalincs/pstypes.h"
  2214. +#include "globalincs/vmallocator.h"
  2215. +
  2216. +/**
  2217. + * @def DCF
  2218. + *
  2219. + * @brief The potent DCF macro, used to define new debug commands for the console.
  2220. + *
  2221. + * @param function_name[in] The name of the function, as shown in the debug console
  2222. + * @param help_txt[in] The short-help text, as shown as listed from the 'help' command
  2223. + *
  2224. + * @details Usage example:
  2225. + * DCF(toggle_it,"description")
  2226. + * {
  2227. + *     switch (Dc_mode) {
  2228. + *     case dcm_command:
  2229. + *          This_var = !This_var;
  2230. + *     break;
  2231. + *
  2232. + *     case dcm_help:
  2233. + *         dc_printf( "Usage: sample. Toggles This_var on/off.\n" );
  2234. + *     break;
  2235. + *
  2236. + *     case dcm_status:
  2237. + *         dc_printf( "The status is %d.\n", This_var );
  2238. + *     break;
  2239. + *     default:
  2240. + *         if (Dc_debug_on) {
  2241. + *             dc_printf( "<debug> Unknown command mode %i", Dc_mode);
  2242. + *         }
  2243. + *     }
  2244. + * }
  2245. + *  
  2246. + *  In the console, the command will be listed as 'toggle_it', and help will display it as:
  2247. + *      toggle_it  - Usage: sample. Toggles This_var on/off.
  2248. + *  Note: The only allowed function type is a void fn( void )
  2249. + */
  2250. +#define DCF(function_name, help_text)  \
  2251. +       void dcf_##function_name(); \
  2252. +       debug_command dcmd_##function_name(#function_name, help_text, dcf_##function_name); \
  2253. +       void dcf_##function_name()
  2254. +
  2255. +
  2256. +/**
  2257. + *  @def Shortcut for debug commands that toggle a bool, such as Show_lightning
  2258. + *  
  2259. + *  @param [in] function_name Name of the function, as shown in the debug console
  2260. + *  @param [in] bool_variable Name of the variable to allow toggling.
  2261. + */
  2262. +#define DCF_BOOL(function_name, bool_variable) \
  2263. +   void dcf_##function_name();     \
  2264. +   debug_command dcmd_##function_name(#function_name, "Sets or toggles the boolean: "#bool_variable, dcf_##function_name );    \
  2265. +   void dcf_##function_name() {    \
  2266. +       if (dc_optional_string_either("help", "--help")) {  \
  2267. +               dc_printf( "Usage: %s [bool]\nSets %s to true or false.  If nothing passed, then toggles it.\n", #function_name, #bool_variable );  \
  2268. +               return;     \
  2269. +       }   \
  2270. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  2271. +           dc_printf("%s = %s\n", #function_name, (bool_variable ? "TRUE" : "FALSE"));     \
  2272. +           return;     \
  2273. +       }   \
  2274. +       if (!dc_maybe_stuff_boolean(&bool_variable)) {  \
  2275. +           bool_variable = !bool_variable; \
  2276. +       }   \
  2277. +   }   \
  2278. +
  2279. +
  2280. +/**
  2281. + *  @def Same as DCF_BOOL, but with custom help strings
  2282. + *  
  2283. + *  @param [in] function_name Name of the function, as shown in the debug console
  2284. + *  @param [in] bool_variable Name of the variable to allow toggling.
  2285. + */
  2286. +#define DCF_BOOL2(function_name, bool_variable, short_help, long_help) \
  2287. +   void dcf_##function_name();     \
  2288. +   debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );  \
  2289. +   void dcf_##function_name() {    \
  2290. +       if (dc_optional_string_either("help", "--help")) {  \
  2291. +           dc_printf( #long_help );    \
  2292. +               return;     \
  2293. +       }   \
  2294. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  2295. +           dc_printf("%s = %s\n", #function_name, (bool_variable ? "TRUE" : "FALSE"));     \
  2296. +           return;     \
  2297. +       }   \
  2298. +       if (!dc_maybe_stuff_boolean(&bool_variable)) {  \
  2299. +           bool_variable = !bool_variable; \
  2300. +       }   \
  2301. +   }   \
  2302. +
  2303. + /**
  2304. +  * @def Shortcut for single-variable setters/monitors
  2305. +  *
  2306. +  * @param [in] function_name
  2307. +  * @param [in] float_variable
  2308. +  * @param [in] short_help
  2309. +  */
  2310. + #define DCF_FLOAT(function_name, float_variable, short_help)  \
  2311. +   void dcf_##function_name();     \
  2312. +   debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );  \
  2313. +   void dcf_##function_name() {    \
  2314. +       float value;    \
  2315. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  2316. +           dc_printf("%s = %f\n", #float_variable, float_variable);        \
  2317. +           return;     \
  2318. +       }   \
  2319. +       dc_stuff_float(&value); \
  2320. +       float_variable = value; \
  2321. +       dc_printf("%s set to %f\n", #float_variable, float_variable);   \
  2322. +   }   \
  2323. +
  2324. + /**
  2325. +  * @def Shortcut for single-variable setters/monitors with lower/upper bounds clamping
  2326. +  *
  2327. +  * @param [in] function_name
  2328. +  * @param [in] float_variable
  2329. +  * @param [in] short_help
  2330. +  */
  2331. + #define DCF_FLOAT2(function_name, float_variable, lower_bounds, upper_bounds, short_help) \
  2332. +   void dcf_##function_name();     \
  2333. +   debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );  \
  2334. +   void dcf_##function_name() {    \
  2335. +       float value;    \
  2336. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  2337. +           dc_printf("%s = %f\n", #float_variable, float_variable);        \
  2338. +           return;     \
  2339. +       }   \
  2340. +       dc_stuff_float(&value); \
  2341. +       CLAMP(float_variable, lower_bounds, upper_bounds);  \
  2342. +       float_variable = value; \
  2343. +       dc_printf("%s set to %f\n", #float_variable, float_variable);   \
  2344. +   }   \
  2345. +
  2346. + /**
  2347. +  * @def Shortcut for single-variable setters/monitors
  2348. +  *
  2349. +  * @param [in] function_name
  2350. +  * @param [in] int_variable
  2351. +  * @param [in] short_help
  2352. +  */
  2353. + #define DCF_INT(function_name, int_variable, short_help)  \
  2354. +   void dcf_##function_name();     \
  2355. +   debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );  \
  2356. +   void dcf_##function_name() {    \
  2357. +       float value;    \
  2358. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  2359. +           dc_printf("%s = %f\n", #int_variable, int_variable);        \
  2360. +           return;     \
  2361. +       }   \
  2362. +       dc_stuff_float(&value); \
  2363. +       int_variable = value;   \
  2364. +       dc_printf("%s set to %f\n", #int_variable, int_variable);   \
  2365. +   }   \
  2366. +
  2367. + /**
  2368. +  * @def Shortcut for single-variable setters/monitors with lower/upper bounds clamping
  2369. +  *
  2370. +  * @param [in] function_name
  2371. +  * @param [in] int_variable
  2372. +  * @param [in] short_help
  2373. +  */
  2374. + #define DCF_INT2(function_name, int_variable, lower_bounds, upper_bounds, short_help) \
  2375. +   void dcf_##function_name();     \
  2376. +   debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );  \
  2377. +   void dcf_##function_name() {    \
  2378. +       float value;    \
  2379. +       if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) { \
  2380. +           dc_printf("%s = %f\n", #int_variable, int_variable);        \
  2381. +           return;     \
  2382. +       }   \
  2383. +       dc_stuff_float(&value); \
  2384. +       CLAMP(int_variable, lower_bounds, upper_bounds);    \
  2385. +       int_variable = value;   \
  2386. +       dc_printf("%s set to %f\n", #int_variable, int_variable);   \
  2387. +   }   \
  2388. +
  2389. +/**
  2390. + *  @class debug_command
  2391. + *  @brief Class to aggregate a debug command with its name (as shown in the console) and short help.
  2392. + *  
  2393. + *  @details
  2394. + *  Note: Long help, as evoked by '<command> help', should be handled by the function itself. It is recommended
  2395. + *  that arguments that have sub-arguments be in their own function, so as to aide in organization and to keep the
  2396. + *  size of the command function down.
  2397. + */
  2398. +class debug_command {
  2399. +public:
  2400. +   char *name;     //!< The name of the command, as shown in the debug console
  2401. +   char *help;     //!< The short help string, as shown by 'help <command>'
  2402. +   void (*func)(); //!< Pointer to the function that is run when this command is evoked
  2403. +
  2404. +   /**
  2405. +   * @brief Adds a debug command to the debug_commands map, if it isn't in there already.
  2406. +   *
  2407. +   * @details The DCF macro more or less guarantees that a command won't be duplicated on compile time. But no harm in
  2408. +   *   some extra caution.
  2409. +   */
  2410. +   debug_command(char *name, char *help, void (*func)());
  2411. +};
  2412. +
  2413. +/**
  2414. + * Dc_mode tells your function what to do.
  2415. + * Your function _must_ process the command.
  2416. + *
  2417. + * It is recommended that each function have, at minimum, this switch statement:
  2418. + *   switch (Dc_mode) {
  2419. + *   case dcm_command:
  2420. + *     // process command
  2421. + *     break;
  2422. + *  
  2423. + *   case dcm_help:
  2424. + *     // provide detailed help
  2425. + *     break;
  2426. + *  
  2427. + *   case dcm_status:
  2428. + *     // provide status on the command
  2429. + *     break;
  2430. + *  
  2431. + *   default:
  2432. + *     // (optional)
  2433. + *     dc_printf("<command_name> Unknown command mode %i\n", Dc_mode);
  2434. + *   }
  2435. + */
  2436. +enum dc_mode {
  2437. +   dcm_command,    // process the command
  2438. +   dcm_help,       // print out the help text in the form, "usage: ... \nLong description\n" );
  2439. +   dcm_status      // print out the current status of the command.
  2440. +};
  2441. +
  2442. +extern dc_mode Dc_mode;
  2443. +extern bool Dc_debug_on;
  2444. +
  2445. +extern SCP_string dc_command_str;  // The rest of the command line, from the end of the last processed arg on.
  2446. +
  2447. +void debug_console(void (*func)(void) = NULL);     // Starts the debug console, and runs the given function after each time a command is processed
  2448. +void dc_printf( char *format, ... );               // Outputs to the debug console
  2449. +bool dc_pause_output(uint &lines);                 // Pauses execution and waits for user intput. Allows scrolling.
  2450. +
  2451. +#endif // _CONSOLE_H
  2452. \ No newline at end of file
  2453. Index: debugconsole/consolecmds.cpp
  2454. ===================================================================
  2455. --- debugconsole/consolecmds.cpp    (Revision 0)
  2456. +++ debugconsole/consolecmds.cpp    (Arbeitskopie)
  2457. @@ -0,0 +1,162 @@
  2458. +/*
  2459. + * z64555's debug console
  2460. + * Created for the FreeSpace Source Code project
  2461. + *
  2462. + * Portions of this source code are based on works by Volition, Inc. circa
  2463. + * 1999. You may not sell or otherwise commercially exploit the source or things you
  2464. + * created based on the source
  2465. + */
  2466. +
  2467. +/**
  2468. + *  @file consolecmds.cpp
  2469. + *  
  2470. + *  @brief This file contains the "built-in" commands for the debug console, and is listed by the 'help' and '?' commands
  2471. + *  
  2472. + *  @details
  2473. + *  All other debug commands should be in their respective files and added to the console with the DCF macro. For
  2474. + *  further documentation, please see console.h
  2475. + */
  2476. +
  2477. +#include "debugconsole/console.h"
  2478. +#include "debugconsole/consoleparse.h"
  2479. +#include "globalincs/pstypes.h"
  2480. +#include "globalincs/vmallocator.h"
  2481. +#include "io/key.h"
  2482. +
  2483. +SCP_map<SCP_string, debug_command*> dc_commands;
  2484. +typedef SCP_map<SCP_string, debug_command*>::iterator dc_commands_it;
  2485. +
  2486. +debug_command::debug_command(char *_name, char *_help, void (*_func)())
  2487. +{
  2488. +       SCP_map<SCP_string, debug_command*>::iterator it = dc_commands.find(_name);
  2489. +      
  2490. +       if (it != dc_commands.end()) {
  2491. +               Int3();         // Command already exists! Somebody didn't use the DCF macro as they should've...
  2492. +       }
  2493. +
  2494. +       dc_commands[_name] = this;
  2495. +
  2496. +       name = _name;
  2497. +       help = _help;
  2498. +       func = _func;
  2499. +}
  2500. +
  2501. +DCF( debug, "Runs a command in debug mode.")
  2502. +{
  2503. +       SCP_string command = "";
  2504. +       Dc_debug_on = true;
  2505. +
  2506. +       dc_stuff_string_white(command);
  2507. +
  2508. +       if (command == "") {
  2509. +               dc_printf("<debug> No command given");
  2510. +               return;
  2511. +       } // Else, command is present.
  2512. +
  2513. +       dc_commands_it it = dc_commands.find(command);
  2514. +
  2515. +       if (it == dc_commands.end()) {
  2516. +               dc_printf("<debug> Command not found: '%s'\n", command.c_str());
  2517. +               return;
  2518. +       } // Else, command exists. Run it.
  2519. +
  2520. +       dc_printf("<debug> Executing command: '%s'\n", command.c_str());
  2521. +       // try {
  2522. +       (it->second)->func();
  2523. +       // } catch {
  2524. +       // }
  2525. +
  2526. +       Dc_debug_on = false;
  2527. +}
  2528. +
  2529. +DCF( help, "Displays the help list." )
  2530. +{
  2531. +       extern uint DBCOLS;
  2532. +       unsigned int lines;
  2533. +       SCP_string command = "";
  2534. +
  2535. +       dc_stuff_string_white(command);
  2536. +
  2537. +       if (command != "") {
  2538. +               dc_commands_it it = dc_commands.find(command);
  2539. +
  2540. +               if (it == dc_commands.end()) {
  2541. +                       dc_printf("Command not found: '%s'\n", command.c_str());
  2542. +                       return;
  2543. +               }
  2544. +
  2545. +               dc_printf((it->second)->help);
  2546. +               return;
  2547. +       } // Else, command line is empty, print out the help list
  2548. +
  2549. +       dc_printf("FreeSpace Open Debug Console\n");
  2550. +       dc_printf(" These commands are defined internally.\n");
  2551. +       dc_printf(" Typing 'help function_name' will give the short help on the function.\n");
  2552. +       dc_printf(" Some functions may have detailed help, try passing \"help\" or \"--help\" to them.");
  2553. +       dc_printf(" F3 selects last command line. Up and Down arrow keys scroll through the command history\n");
  2554. +       dc_printf("\n");
  2555. +
  2556. +       dc_printf(" Available commands:\n");
  2557. +       lines = 0;
  2558. +       for (dc_commands_it it = dc_commands.begin(); it != dc_commands.end(); ++it) {
  2559. +               if (lines >= (DBCOLS - 1)) {
  2560. +                       if (dc_pause_output(lines) == true) {
  2561. +                               break;
  2562. +                       }
  2563. +               }
  2564. +
  2565. +               dc_printf(" %s\t\t- %s", (it->second)->name, (it->second)->help);
  2566. +               ++lines;
  2567. +       }
  2568. +}
  2569. +
  2570. +debug_command dc_man("man", "Also displays the help list", dcf_help);
  2571. +
  2572. +void dc_shell_font( void );
  2573. +void dc_shell_resize( void );
  2574. +void dc_shell_resize_buf( void );
  2575. +
  2576. +DCF( shell, "Change/set various console-related settings.\n" )
  2577. +{
  2578. +       switch (Dc_mode) {
  2579. +       case dcm_command:
  2580. +               dc_printf("Sorry, This command is not implemented yet...");
  2581. +               break;
  2582. +
  2583. +       case dcm_help:
  2584. +               dc_printf("Shell: Change/set various console-related settings.\n");
  2585. +               dc_printf(" Available arguments:\n");
  2586. +               dc_printf("\t-font       - Change the console font");
  2587. +               dc_printf("\t-resize     - Resize the console window\n");
  2588. +               dc_printf("\t-resize_buf - Resize the console buffer\n");
  2589. +               break;
  2590. +
  2591. +       case dcm_status:
  2592. +               dc_printf("<shell> No status available.\n");
  2593. +               break;
  2594. +
  2595. +       default:
  2596. +               dc_printf("<shell> Unknown command mode %i\n", Dc_mode);
  2597. +       }
  2598. +}
  2599. +
  2600. +DCF( pause, "Pause/Unpause the game. (Singleplayer only)\n")
  2601. +{
  2602. +       switch (Dc_mode) {
  2603. +       case dcm_command:
  2604. +               dc_printf("Sorry, This command is not implemented yet...");
  2605. +               break;
  2606. +
  2607. +       case dcm_help:
  2608. +               dc_printf("Pause: Pause/Unpause the game.\n");
  2609. +               dc_printf(" Only available in singleplayer games.\n");
  2610. +               break;
  2611. +
  2612. +       case dcm_status:
  2613. +               dc_printf("No status available.\n");
  2614. +               break;
  2615. +
  2616. +       default:
  2617. +               dc_printf("<pause> Unknown command mode %i\n", Dc_mode);
  2618. +       }
  2619. +}
  2620. Index: debugconsole/consoleparse.cpp
  2621. ===================================================================
  2622. --- debugconsole/consoleparse.cpp   (Revision 0)
  2623. +++ debugconsole/consoleparse.cpp   (Arbeitskopie)
  2624. @@ -0,0 +1,1453 @@
  2625. +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2626. +// Command-line parsing functions for z64555's debug console, created for the FreeSpace Source Code project
  2627. +//
  2628. +// Portions of this source code are based on works by Volition, Inc. circa 1999. You may not sell or otherwise
  2629. +// commercially exploit the source or things you created based on the source.
  2630. +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2631. +
  2632. +/////////////////
  2633. +// Testing Goals
  2634. +// Breakpoints are set at places that need testing:
  2635. +// * the value of endptr strtol and strtoul needs to investigated, according to cplusplus.com, *endptr = end of the string that was successfully converted
  2636. +// 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
  2637. +////////////////
  2638. +#include "debugconsole/consoleparse.h"
  2639. +
  2640. +#include "debugconsole/console.h"
  2641. +#include "globalincs/pstypes.h"
  2642. +#include "parse/parselo.h"
  2643. +
  2644. +#include <cstring>
  2645. +#include <limits.h>
  2646. +
  2647. +// ========================= LOCALS =========================
  2648. +char Command_string[MAX_CLI_LEN];
  2649. +char *Cp = NULL;
  2650. +
  2651. +enum state_int {
  2652. +       si_start   = 0,
  2653. +       si_end     = 1,
  2654. +       si_invalid,
  2655. +       si_sign,        //!< Sign character, '-' '+'
  2656. +       si_prefix,      //!< prefix character sequence, 0b, 0o, or 0x
  2657. +       si_numeral,     //!< Numeral state, 0 - 9
  2658. +       si_numeral_bin,     //!< Numeral altstate, 0, 1
  2659. +       si_numeral_octal,   //!< Numeral altstate, 0 - 7
  2660. +       si_numeral_hex      //!< Numeral altstate, 0 - 9 and 'a' - 'f'
  2661. +};
  2662. +
  2663. +enum state_float {
  2664. +       sf_start = 0,
  2665. +       sf_end = 1,
  2666. +       sf_invalid,
  2667. +       sf_sign,                //!< Sign character for mantessa
  2668. +       sf_whole,               //!< Whole value numeral
  2669. +       sf_decimal,             //!< Decimal character
  2670. +       sf_fraction,    //!< Fractional value numeral
  2671. +       sf_expprefix,   //!< Exponent prefix, 'e', 'E'
  2672. +       sf_expsign,             //!< Exponent sign
  2673. +       sf_exponent             //!< Exponent value numeral
  2674. +};
  2675. +
  2676. +bool ch_is_sign(char ch);
  2677. +bool ch_is_numeral(char ch);
  2678. +bool ch_is_decimal(char ch);
  2679. +bool ch_is_binary(char ch);
  2680. +bool ch_is_octal(char ch);
  2681. +bool ch_is_hex(char ch);
  2682. +
  2683. +bool ch_is_prefix(char ch);
  2684. +bool ch_is_binary_prefix(char ch);
  2685. +bool ch_is_octal_prefix(char ch);
  2686. +bool ch_is_hex_prefix(char ch);
  2687. +bool ch_is_exp_prefix(char ch);
  2688. +
  2689. +char *dc_get_token(void);
  2690. +char *dc_get_token_no_advance(void);
  2691. +
  2692. +double dc_parse_double(char *ch, dc_token type);
  2693. +long   dc_parse_long(char *ch, dc_token type);
  2694. +ulong  dc_parse_ulong(char *ch, dc_token type);
  2695. +
  2696. +state_int process_state_prefix(char *ch_ptr, SCP_string &buffer_str, int &base);
  2697. +state_int process_state_sign(char *ch_ptr, SCP_string &buffer_str);
  2698. +state_int process_state_numeral(char *ch_ptr, SCP_string &buffer_str);
  2699. +state_int process_state_numeral_bin(char *ch_ptr, SCP_string &buffer_str);
  2700. +state_int process_state_numeral_hex(char *ch_ptr, SCP_string &buffer_str);
  2701. +state_int process_state_numeral_octal(char *ch_ptr, SCP_string &buffer_str);
  2702. +
  2703. +
  2704. +// ============================== IMPLEMENTATIONS =============================
  2705. +// Character identification
  2706. +inline
  2707. +bool ch_is_sign(char ch)
  2708. +{
  2709. +       return ((ch == '-') || (ch == '+'));
  2710. +}
  2711. +
  2712. +inline
  2713. +bool ch_is_numeral(char ch)
  2714. +{
  2715. +       return ((ch >= '0') && (ch <= '9'));
  2716. +}
  2717. +
  2718. +inline
  2719. +bool ch_is_decimal(char ch)
  2720. +{
  2721. +       return (ch == '.');
  2722. +}
  2723. +
  2724. +inline
  2725. +bool ch_is_binary(char ch)
  2726. +{
  2727. +       return ((ch == '0') || (ch == '1'));
  2728. +}
  2729. +
  2730. +inline
  2731. +bool ch_is_octal(char ch)
  2732. +{
  2733. +       return ((ch >= '0') && (ch <= '7'));
  2734. +}
  2735. +
  2736. +inline
  2737. +bool ch_is_hex(char ch)
  2738. +{
  2739. +       return (((ch >= '0') && (ch <= '9')) || ((ch >= 'a') && (ch <= 'f')) || ((ch >= 'A') || (ch <= 'F')));
  2740. +};
  2741. +
  2742. +inline
  2743. +bool ch_is_prefix(char ch)
  2744. +{
  2745. +       return (ch == '0');
  2746. +}
  2747. +
  2748. +inline
  2749. +bool ch_is_binary_prefix(char ch)
  2750. +{
  2751. +       return ((ch == 'b') || (ch == 'B'));
  2752. +}
  2753. +
  2754. +inline
  2755. +bool ch_is_octal_prefix(char ch)
  2756. +{
  2757. +       return ((ch == 'o') || (ch == 'O'));
  2758. +}
  2759. +
  2760. +inline
  2761. +bool ch_is_hex_prefix(char ch)
  2762. +{
  2763. +       return ((ch == 'x') || (ch == 'X'));
  2764. +}
  2765. +
  2766. +inline
  2767. +bool ch_is_exp_prefix(char ch)
  2768. +{
  2769. +       return ((ch == 'e') || (ch == 'E'));
  2770. +}
  2771. +
  2772. +// Getters
  2773. +
  2774. +/**
  2775. + * @brief Returns/Advances past a single token
  2776. + */
  2777. +char * dc_get_token(void) {
  2778. +       char token[MAX_TOKEN_LENGTH];
  2779. +       char *begin_ptr;
  2780. +
  2781. +       dc_ignore_gray_space();
  2782. +
  2783. +       begin_ptr = Cp;
  2784. +
  2785. +       while ((*Cp != '\0') && !is_gray_space(*Cp)) {
  2786. +               Cp++;
  2787. +       }
  2788. +
  2789. +       strncpy(token, begin_ptr, (Cp - begin_ptr));
  2790. +       return token;
  2791. +}
  2792. +
  2793. +/**
  2794. + * @brief Returns a single token, but does not advances Cp
  2795. + */
  2796. +char * dc_get_token_no_advance(void) {
  2797. +       char token[MAX_TOKEN_LENGTH];
  2798. +       char *begin_ptr;
  2799. +       char *ch_ptr = Cp;
  2800. +
  2801. +       while ((*ch_ptr != '\0') && is_gray_space(*ch_ptr)) {
  2802. +               ch_ptr++;
  2803. +       }
  2804. +
  2805. +       begin_ptr = ch_ptr;
  2806. +
  2807. +       while ((*ch_ptr != '\0') && !is_gray_space(*ch_ptr)) {
  2808. +               ch_ptr++;
  2809. +       }
  2810. +
  2811. +       strncpy(token, begin_ptr, (ch_ptr - begin_ptr));
  2812. +       return token;
  2813. +}
  2814. +
  2815. +void dc_ignore_white_space(void) {
  2816. +       while (is_white_space(*Cp) && (*Cp != '\0')) {
  2817. +               Cp++;
  2818. +       }
  2819. +}
  2820. +
  2821. +void dc_ignore_gray_space(void) {
  2822. +       while (is_gray_space(*Cp) && (*Cp != '\0')) {
  2823. +               Cp++;
  2824. +       }
  2825. +}
  2826. +
  2827. +// Required/Optional Strings
  2828. +bool dc_required_string(char *pstr)
  2829. +{
  2830. +       char *str_found = NULL;
  2831. +
  2832. +       dc_ignore_gray_space();
  2833. +
  2834. +       if (strnicmp(pstr, Cp, strlen(pstr))) {
  2835. +               str_found = pstr;
  2836. +       }
  2837. +
  2838. +       if (str_found != NULL) {
  2839. +               // Found a required string
  2840. +               if (Dc_debug_on) {
  2841. +                       dc_printf("<debug> Found required string [%s}\n", str_found);
  2842. +               }
  2843. +
  2844. +               Cp += strlen(str_found);
  2845. +       } else {
  2846. +               // Didn't find a required string.
  2847. +               throw errParseString(dc_get_token_no_advance(), pstr);
  2848. +       }
  2849. +       return true;
  2850. +}
  2851. +
  2852. +int dc_required_string_either(char *str1, char *str2)
  2853. +{
  2854. +       char *str_found = NULL;
  2855. +       int i = -1;
  2856. +
  2857. +       dc_ignore_gray_space();
  2858. +
  2859. +       if (strncmp(str1, Cp, strlen(str1) == 0)) {
  2860. +               str_found = str1;
  2861. +               i = 0;
  2862. +       } else if (strncmp(str2, Cp, strlen(str2) == 0)) {
  2863. +               str_found = str2;
  2864. +               i = 1;
  2865. +       }
  2866. +
  2867. +       if (i > -1) {
  2868. +               // Found a required string
  2869. +               if (Dc_debug_on) {
  2870. +                       dc_printf("<debug> Found required string [%s}\n", str_found);
  2871. +               }
  2872. +
  2873. +               Cp += strlen(str_found);
  2874. +       } else {
  2875. +               // Didn't find a required string.
  2876. +               throw errParseString(dc_get_token_no_advance(), str1, str2);
  2877. +       }
  2878. +
  2879. +       return i;
  2880. +}
  2881. +
  2882. +int dc_required_string_3(char *str1, char *str2, char *str3)
  2883. +{
  2884. +       char *str_found = NULL;
  2885. +       int i = -1;
  2886. +
  2887. +       dc_ignore_gray_space();
  2888. +
  2889. +       if (strncmp(str1, Cp, strlen(str1) == 0)) {
  2890. +               str_found = str1;
  2891. +               i = 0;
  2892. +       } else if (strncmp(str2, Cp, strlen(str2) == 0)) {
  2893. +               str_found = str2;
  2894. +               i = 1;
  2895. +       } else if (strncmp(str3, Cp, strlen(str3) == 0)) {
  2896. +               str_found = str3;
  2897. +               i = 2;
  2898. +       }
  2899. +
  2900. +       if (i > -1) {
  2901. +               // Found a required string
  2902. +               if (Dc_debug_on) {
  2903. +                       dc_printf("<debug> Found required string [%s}\n", str_found);
  2904. +               }
  2905. +
  2906. +               Cp += strlen(str_found);
  2907. +       } else {
  2908. +               // Didn't find a required string.
  2909. +               throw errParseString(dc_get_token_no_advance(), str1, str2, str3);
  2910. +       }
  2911. +
  2912. +       return i;
  2913. +}
  2914. +
  2915. +int dc_required_string_4(char *str1, char *str2, char *str3, char *str4)
  2916. +{
  2917. +       char *str_found = NULL;
  2918. +       int i = -1;
  2919. +
  2920. +       dc_ignore_gray_space();
  2921. +
  2922. +       if (strncmp(str1, Cp, strlen(str1) == 0)) {
  2923. +               str_found = str1;
  2924. +               i = 0;
  2925. +       } else if (strncmp(str2, Cp, strlen(str2) == 0)) {
  2926. +               str_found = str2;
  2927. +               i = 1;
  2928. +       } else if (strncmp(str3, Cp, strlen(str3) == 0)) {
  2929. +               str_found = str3;
  2930. +               i = 2;
  2931. +       } else if (strncmp(str4, Cp, strlen(str4) == 0)) {
  2932. +               str_found = str4;
  2933. +               i = 3;
  2934. +       }
  2935. +
  2936. +       if (i > -1) {
  2937. +               // Found a required string
  2938. +               if (Dc_debug_on) {
  2939. +                       dc_printf("<debug> Found required string [%s}\n", str_found);
  2940. +               }
  2941. +
  2942. +               Cp += strlen(str_found);
  2943. +       } else {
  2944. +               // Didn't find a required string.
  2945. +               throw errParseString(dc_get_token_no_advance(), str1, str2, str3, str4);
  2946. +       }
  2947. +
  2948. +       return i;
  2949. +}
  2950. +
  2951. +bool dc_optional_string(char *pstr)
  2952. +{
  2953. +       dc_ignore_gray_space();
  2954. +
  2955. +       if (strncmp(pstr, Cp, strlen(pstr) != 0)) {
  2956. +               return false;
  2957. +       } // Else, optional string was found
  2958. +
  2959. +       if (Dc_debug_on) {
  2960. +               dc_printf("<debug> Found optional string [%s]\n", pstr);
  2961. +       }
  2962. +
  2963. +       Cp += strlen(pstr);
  2964. +       return true;
  2965. +}
  2966. +
  2967. +bool dc_optional_string_either(char *str1, char *str2)
  2968. +{
  2969. +       char * str_found = NULL;
  2970. +
  2971. +       dc_ignore_gray_space();
  2972. +
  2973. +       if (strncmp(str1, Cp, strlen(str1)) == 0) {
  2974. +               str_found = str1;
  2975. +       } else if (strncmp(str2, Cp, strlen(str2)) == 0) {
  2976. +               str_found = str2;
  2977. +       } else {
  2978. +               return false;
  2979. +       }
  2980. +
  2981. +       if (Dc_debug_on) {
  2982. +               dc_printf("<debug> Found optional string [%s]\n",str_found);
  2983. +       }
  2984. +
  2985. +       Cp += strlen(str_found);
  2986. +       return true;;
  2987. +}
  2988. +
  2989. +// Parsers
  2990. +
  2991. +/**
  2992. + * @brief Initializes the DC command line parser
  2993. + */
  2994. +void dc_parse_init(SCP_string &str)
  2995. +{
  2996. +       strcpy(Command_string, str.c_str());
  2997. +       Cp = Command_string;
  2998. +}
  2999. +
  3000. +/**
  3001. + * @brief Parses a double-precision floating point type. Supports, Whole, Fractional, and Mixed numbers, and supports
  3002. + *   scientific notation (exponent prefixed by 'e' or 'E').
  3003. + *
  3004. + * @param[in] ch   Points to the start of the string to parse
  3005. + * @param[in] type The expected type. is thrown along with ch when an unexpected/malformed float is found
  3006. + *
  3007. + * @details
  3008. + *   The returned double may be cast to a single-precision float, but be sure to check it before doing so!
  3009. + */
  3010. +double dc_parse_double(char *ch, dc_token type) {
  3011. +       char *ch_ptr = ch;
  3012. +       char *end_ptr;
  3013. +       double ret;
  3014. +       state_float state = sf_start;
  3015. +       SCP_string buffer_str;
  3016. +
  3017. +       do {
  3018. +               if ((ch_ptr == '\0') || is_white_space(*ch_ptr)) {
  3019. +                       state = sf_end;
  3020. +               }
  3021. +
  3022. +               switch (state) {
  3023. +               case sf_start:
  3024. +                       if (ch_is_sign(*ch_ptr)) {
  3025. +                               state = sf_sign;
  3026. +                               if (*ch_ptr == '-') {
  3027. +                                       buffer_str.push_back(*ch_ptr);
  3028. +                               } // Else, sign is positive, and isn't needed on the buffer
  3029. +                               ch_ptr++;
  3030. +
  3031. +                       } else if (ch_is_numeral(*ch_ptr)) {
  3032. +                               state = sf_whole;
  3033. +                               buffer_str.push_back(*ch_ptr);
  3034. +                               ch_ptr++;
  3035. +
  3036. +                       } else if (ch_is_decimal(*ch_ptr)) {
  3037. +                               state = sf_decimal;
  3038. +                               buffer_str.push_back(*ch_ptr);
  3039. +                               ch_ptr++;
  3040. +
  3041. +                       } else {
  3042. +                               if (Dc_debug_on) {
  3043. +                                       dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_start\n", *ch_ptr);
  3044. +                               }
  3045. +                               state = sf_invalid;
  3046. +
  3047. +                       }
  3048. +                       break;
  3049. +               case sf_end:
  3050. +                       if ((buffer_str == "") || (buffer_str == "-"))
  3051. +                       {
  3052. +                               state = sf_invalid;
  3053. +                       } // Else, we can convert the token.
  3054. +                       // Do nothing, and allow the while loop exit condition to trigger
  3055. +                       break;
  3056. +               case sf_sign:
  3057. +                       if (ch_is_numeral(*ch_ptr)) {
  3058. +                               state = sf_whole;
  3059. +                               buffer_str.push_back(*ch_ptr);
  3060. +                               ch_ptr++;
  3061. +
  3062. +                       } else if (ch_is_decimal(*ch_ptr)) {
  3063. +                               state = sf_decimal;
  3064. +                               buffer_str.push_back(*ch_ptr);
  3065. +                               ch_ptr++;
  3066. +
  3067. +                       } else {
  3068. +                               if (Dc_debug_on) {
  3069. +                                       dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_sign\n", *ch_ptr);
  3070. +                               }
  3071. +                               state = sf_invalid;
  3072. +
  3073. +                       }
  3074. +                       break;
  3075. +               case sf_whole:
  3076. +                       if (ch_is_numeral(*ch_ptr)) {
  3077. +                               buffer_str.push_back(*ch_ptr);
  3078. +                               ch_ptr++;
  3079. +
  3080. +                       } else if (ch_is_decimal(*ch_ptr)) {
  3081. +                               state = sf_decimal;
  3082. +                               buffer_str.push_back(*ch_ptr);
  3083. +                               ch_ptr++;
  3084. +
  3085. +                       } else if (ch_is_exp_prefix(*ch_ptr)) {
  3086. +                               state = sf_expprefix;
  3087. +                               buffer_str.push_back(*ch_ptr);
  3088. +                               ch_ptr++;
  3089. +
  3090. +                       } else {
  3091. +                               if (Dc_debug_on) {
  3092. +                                       dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_whole\n", *ch_ptr);
  3093. +                               }
  3094. +                               state = sf_invalid;
  3095. +
  3096. +                       }
  3097. +                       break;
  3098. +               case sf_decimal:
  3099. +                       if (ch_is_numeral(*ch_ptr)) {
  3100. +                               state = sf_fraction;
  3101. +                               buffer_str.push_back(*ch_ptr);
  3102. +                               ch_ptr++;
  3103. +
  3104. +                       } else if (ch_is_exp_prefix(*ch_ptr)) {
  3105. +                               state = sf_expprefix;
  3106. +                               buffer_str.push_back(*ch_ptr);
  3107. +                               ch_ptr++;
  3108. +
  3109. +                       } else {
  3110. +                               if (Dc_debug_on) {
  3111. +                                       dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_decimal\n", *ch_ptr);
  3112. +                               }
  3113. +                               state = sf_invalid;
  3114. +
  3115. +                       }
  3116. +                       break;
  3117. +               case sf_fraction:
  3118. +                       if (ch_is_numeral(*ch_ptr)) {
  3119. +                               buffer_str.push_back(*ch_ptr);
  3120. +                               ch_ptr++;
  3121. +
  3122. +                       } else if (ch_is_exp_prefix(*ch_ptr)) {
  3123. +                               state = sf_expprefix;
  3124. +                               buffer_str.push_back(*ch_ptr);
  3125. +                               ch_ptr++;
  3126. +
  3127. +                       } else {
  3128. +                               if (Dc_debug_on) {
  3129. +                                       dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_faction\n", *ch_ptr);
  3130. +                               }
  3131. +                               state = sf_invalid;
  3132. +
  3133. +                       }
  3134. +                       break;
  3135. +               case sf_expprefix:
  3136. +                       if (ch_is_sign(*ch_ptr)) {
  3137. +                               state = sf_expsign;
  3138. +                               buffer_str.push_back(*ch_ptr);
  3139. +                               ch_ptr++;
  3140. +
  3141. +                       } else if (ch_is_numeral(*ch_ptr)) {
  3142. +                               state = sf_exponent;
  3143. +                               buffer_str.push_back(*ch_ptr);
  3144. +                               ch_ptr++;
  3145. +
  3146. +                       } else {
  3147. +                               if (Dc_debug_on) {
  3148. +                                       dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_expprefix\n", *ch_ptr);
  3149. +                               }
  3150. +                               state = sf_invalid;
  3151. +
  3152. +                       }
  3153. +                       break;
  3154. +               case sf_expsign:
  3155. +                       if (ch_is_numeral(*ch_ptr)) {
  3156. +                               state = sf_exponent;
  3157. +                               buffer_str.push_back(*ch_ptr);
  3158. +                               ch_ptr++;
  3159. +
  3160. +                       } else {
  3161. +                               if (Dc_debug_on) {
  3162. +                                       dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_expsign\n", *ch_ptr);
  3163. +                               }
  3164. +                               state = sf_invalid;
  3165. +
  3166. +                       }
  3167. +                       break;
  3168. +               case sf_exponent:
  3169. +                       if (ch_is_numeral(*ch_ptr)) {
  3170. +                               buffer_str.push_back(*ch_ptr);
  3171. +                               ch_ptr++;
  3172. +
  3173. +                       } else {
  3174. +                               if (Dc_debug_on) {
  3175. +                                       dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_exponent\n", *ch_ptr);
  3176. +                               }
  3177. +                               state = sf_invalid;
  3178. +
  3179. +                       }
  3180. +                       break;
  3181. +               case sf_invalid:
  3182. +               default:
  3183. +                       SCP_string token = dc_get_token_no_advance();
  3184. +                       dc_printf("Syntax Error: Expected integer, found '%s'\n", token.c_str());
  3185. +                       throw errParse(token.c_str(), type);
  3186. +               }
  3187. +       } while (state != sf_end);
  3188. +
  3189. +       ret = strtod(buffer_str.c_str(), &end_ptr);
  3190. +
  3191. +       return ret;
  3192. +}
  3193. +
  3194. +/**
  3195. + * @brief Parses a long integral type. Supports decimal, binary, octal, and hexidecimal strings.
  3196. + *
  3197. + * @param[in] ch    Points to the start of the string to parse.
  3198. + * @param[in] type  The expected type. Is thrown along with ch when an unexpected/malformed integral is found
  3199. + *
  3200. + * @details
  3201. + * ! Non-decimal values must be prefixed by their corresponding sequence. Binary: "0b", Octal: "0o", Hex: "0x"
  3202. + *
  3203. + *   The returned long may be cast to a smaller integral, but be sure to check it before doing so!
  3204. + *
  3205. + *   The only thing left making this function specific to the DC is the expected type. So, if you want to use this
  3206. + *   for parsing something other than the debug CL, you'll have to make a set of errParse classes that take a
  3207. + *   different expected type.
  3208. + */
  3209. +long dc_parse_long(char *ch, dc_token type) {
  3210. +       char *ch_ptr = ch;
  3211. +       char *end_ptr;
  3212. +       int base = 10;
  3213. +       long ret;
  3214. +       state_int state = si_start;
  3215. +       SCP_string buffer_str;
  3216. +
  3217. +       while ((*ch_ptr != '\0') || is_white_space(*ch_ptr)) {
  3218. +               ch_ptr++;
  3219. +       }
  3220. +
  3221. +       if (*ch_ptr == '\0') {
  3222. +               if (Dc_debug_on) {
  3223. +                       dc_printf("<debug> [parse_long] no argument found\n");
  3224. +               }
  3225. +               throw errParse("", type);
  3226. +       }
  3227. +
  3228. +       do {
  3229. +               if ((ch_ptr == '\0') || is_white_space(*ch_ptr)) {
  3230. +                       state = si_end;
  3231. +               }
  3232. +
  3233. +               switch (state) {
  3234. +               case si_start:
  3235. +                       if (ch_is_sign(*ch_ptr)) {
  3236. +                               state = si_sign;
  3237. +                               if (*ch_ptr == '-') {
  3238. +                                       buffer_str.push_back(*ch_ptr);
  3239. +                               } // Else, it's positive. Positive sign isn't needed for conversion
  3240. +                               ch_ptr++;
  3241. +
  3242. +                       } else if (ch_is_prefix(*ch_ptr)) {
  3243. +                               // prefixes must be checked before numeral, because they all start with a numeral zero
  3244. +                               state = si_prefix;
  3245. +                               ch_ptr++;
  3246. +              
  3247. +                       } else if (ch_is_numeral(*ch_ptr)) {
  3248. +                               state = si_numeral;
  3249. +                               buffer_str.push_back(*ch_ptr);
  3250. +                               ch_ptr++;
  3251. +              
  3252. +                       } else {
  3253. +                               if (Dc_debug_on) {
  3254. +                                       dc_printf("<debug> [parse_long] Invalid character '%c' found in si_start\n", *ch_ptr);
  3255. +                               }
  3256. +                               state = si_invalid;
  3257. +
  3258. +                       }
  3259. +                       break;
  3260. +               case si_end:
  3261. +                       if ((buffer_str == "") || (buffer_str == "-"))
  3262. +                       {
  3263. +                               state = si_invalid;
  3264. +                       } // Else, we can convert the token.
  3265. +                       // Do nothing, and allow the while loop exit condition to trigger
  3266. +                       break;
  3267. +
  3268. +               case si_sign:
  3269. +                       state = process_state_sign(ch_ptr, buffer_str);
  3270. +                       break;
  3271. +
  3272. +               case si_prefix:
  3273. +                       state = process_state_prefix(ch_ptr, buffer_str, base);
  3274. +                       break;
  3275. +
  3276. +               case si_numeral_bin:
  3277. +                       state = process_state_numeral_bin(ch_ptr, buffer_str);
  3278. +                       break;
  3279. +
  3280. +               case si_numeral_octal:
  3281. +                       state = process_state_numeral_octal(ch_ptr, buffer_str);
  3282. +                       break;
  3283. +
  3284. +               case si_numeral_hex:
  3285. +                       state = process_state_numeral_hex(ch_ptr, buffer_str);
  3286. +                       break;
  3287. +
  3288. +               case si_numeral:
  3289. +                       state = process_state_numeral(ch_ptr, buffer_str);
  3290. +                       break;
  3291. +
  3292. +               case si_invalid:
  3293. +               default:
  3294. +                       SCP_string token = dc_get_token_no_advance();
  3295. +                       dc_printf("Syntax Error: Expected integer, found '%s'\n", token.c_str());
  3296. +                       throw errParse(token.c_str(), type);
  3297. +               }
  3298. +       } while (state != si_end);
  3299. +
  3300. +       ret = strtol(buffer_str.c_str(), &end_ptr, base);
  3301. +
  3302. +       // This last check can be omitted once I can verify the operation of strtol in this sense
  3303. +       if (end_ptr != ch_ptr) {
  3304. +               dc_printf("Error: Could not convert all of the buffer '%s'.\n", buffer_str.c_str());
  3305. +               if (Dc_debug_on) {
  3306. +                       dc_printf("<debug> Buffer value: %s\n", buffer_str.c_str());
  3307. +                       dc_printf("<debug> Return value: %i", ret);
  3308. +               }
  3309. +               throw errParse(ch, type);
  3310. +       }
  3311. +
  3312. +       return ret;
  3313. +}
  3314. +
  3315. +/**
  3316. + * @brief Parses an unsigned long integral type. Supports decimal, binary, octal, and hexidecimal strings.
  3317. + *
  3318. + * @param[in] ch    Points to the start of the string to parse.
  3319. + * @param[in] type  The expected type. Is thrown along with ch when an unexpected/malformed integral is found
  3320. + *
  3321. + * @details
  3322. + * ! Non-decimal values must be delimited by their corresponding sequence. Binary: "0b", Octal: "0o", Hex: "0x"
  3323. + *   The returned long may be cast to a smaller integral, but be sure to check it before doing so!
  3324. + *   The only thing left making this function specific to the DC is the expected type. So, if you want to use this
  3325. + *   for parsing something other than the debug CL, you'll have to make a set of errParse classes that take a
  3326. + *   different expected type.
  3327. + */
  3328. +ulong dc_parse_ulong(char *ch, dc_token type) {
  3329. +       char *ch_ptr = ch;
  3330. +       char *end_ptr;
  3331. +       int base = 10;
  3332. +       ulong ret;
  3333. +       state_int state = si_start;
  3334. +       SCP_string buffer_str;
  3335. +
  3336. +       while ((*ch_ptr != '\0') || is_white_space(*ch_ptr)) {
  3337. +               ch_ptr++;
  3338. +       }
  3339. +
  3340. +       if (*ch_ptr == '\0') {
  3341. +               if (Dc_debug_on) {
  3342. +                       dc_printf("<debug> [parse_long] no argument found\n");
  3343. +               }
  3344. +               throw errParse("", type);
  3345. +       }
  3346. +
  3347. +       do {
  3348. +               if ((ch_ptr == '\0') || is_white_space(*ch_ptr)) {
  3349. +                       state = si_end;
  3350. +               }
  3351. +
  3352. +
  3353. +               switch (state) {
  3354. +               case si_start:
  3355. +                       if (ch_is_prefix(*ch_ptr)) {
  3356. +                               // prefixes must be checked before numeral, because they all start with a numeral zero
  3357. +                               state = si_prefix;
  3358. +                               ch_ptr++;
  3359. +              
  3360. +                       } else if (ch_is_numeral(*ch_ptr)) {
  3361. +                               state = si_numeral;
  3362. +                               buffer_str.push_back(*ch_ptr);
  3363. +                               ch_ptr++;
  3364. +              
  3365. +                       } else {
  3366. +                               if (Dc_debug_on) {
  3367. +                                       dc_printf("<debug> [parse_long] Invalid character '%s' found in si_start\n", *ch_ptr);
  3368. +                               }
  3369. +                               state = si_invalid;
  3370. +
  3371. +                       }
  3372. +                       break;
  3373. +               case si_end:
  3374. +                       if (buffer_str == "")
  3375. +                       {
  3376. +                               state = si_invalid;
  3377. +                       } // Else, we can convert the token.
  3378. +                       // Do nothing, and allow the while loop exit condition to trigger
  3379. +                       break;
  3380. +
  3381. +               case si_sign:
  3382. +                       state = process_state_sign(ch_ptr, buffer_str);
  3383. +                       break;
  3384. +
  3385. +               case si_prefix:
  3386. +                       state = process_state_prefix(ch_ptr, buffer_str, base);
  3387. +                       break;
  3388. +
  3389. +               case si_numeral_bin:
  3390. +                       state = process_state_numeral_bin(ch_ptr, buffer_str);
  3391. +                       break;
  3392. +
  3393. +               case si_numeral_octal:
  3394. +                       state = process_state_numeral_octal(ch_ptr, buffer_str);
  3395. +                       break;
  3396. +
  3397. +               case si_numeral_hex:
  3398. +                       state = process_state_numeral_hex(ch_ptr, buffer_str);
  3399. +                       break;
  3400. +
  3401. +               case si_numeral:
  3402. +                       state = process_state_numeral(ch_ptr, buffer_str);
  3403. +                       break;
  3404. +
  3405. +               case si_invalid:
  3406. +               default:
  3407. +                       SCP_string token = dc_get_token();
  3408. +                       dc_printf("Syntax Error: Expected unsigned integer, found '%s'\n", token.c_str());
  3409. +                       throw errParse(token.c_str(), type);
  3410. +               }
  3411. +       } while (state != si_end);
  3412. +
  3413. +       ret = strtoul(buffer_str.c_str(), &end_ptr, base);
  3414. +
  3415. +       // This last check can be omitted once I can verify the operation of strtol in this sense
  3416. +       if (end_ptr != ch_ptr) {
  3417. +               dc_printf("Error: Could not convert all of the buffer '%s'.\n", buffer_str.c_str());
  3418. +               if (Dc_debug_on) {
  3419. +                       dc_printf("<debug> Buffer value: %s\n", buffer_str.c_str());
  3420. +                       dc_printf("<debug> Return value: %i", ret);
  3421. +               }
  3422. +               throw errParse(ch, type);
  3423. +       }
  3424. +
  3425. +       return ret;
  3426. +}
  3427. +
  3428. +// Stuffs
  3429. +
  3430. +/**
  3431. + * @brief Stuffs a float to the given variable.
  3432. + *
  3433. + * @param[in] f  The float variable to stuff to
  3434. + *
  3435. + * @details Throws an errParse class if an unexpected or otherwise malformed float string is found. Also throws an
  3436. + *   errParse class if nothing was found
  3437. + */
  3438. +void dc_stuff_float(float *f)
  3439. +{
  3440. +       double value_d;
  3441. +
  3442. +       dc_ignore_gray_space();
  3443. +
  3444. +       value_d = dc_parse_double(Cp, DCT_FLOAT);
  3445. +
  3446. +       if ((value_d < FLT_MAX) && (value_d > FLT_MIN)) {
  3447. +               *f = value_d;
  3448. +               dc_get_token();    // Advance Cp
  3449. +
  3450. +       } else {
  3451. +               throw errParse(dc_get_token(), DCT_FLOAT);
  3452. +       }
  3453. +}
  3454. +
  3455. +void dc_stuff_int(int *i)
  3456. +{
  3457. +       long value_l;
  3458. +
  3459. +       dc_ignore_gray_space();
  3460. +
  3461. +       value_l = dc_parse_long(Cp, DCT_INT);
  3462. +
  3463. +       if ((value_l < INT_MAX) && (value_l > INT_MIN)) {
  3464. +               *i = value_l;
  3465. +               dc_get_token();    // Advance Cp
  3466. +
  3467. +       } else {
  3468. +               throw errParse(dc_get_token(), DCT_INT);
  3469. +       }
  3470. +}
  3471. +
  3472. +void dc_stuff_uint(uint *i)
  3473. +{
  3474. +       ulong value_l;
  3475. +
  3476. +       dc_ignore_gray_space();
  3477. +
  3478. +       value_l = dc_parse_long(Cp, DCT_INT);
  3479. +
  3480. +       if (value_l < UINT_MAX) {
  3481. +               *i = value_l;
  3482. +               dc_get_token();    // Advance Cp
  3483. +
  3484. +       } else {
  3485. +               throw errParse(dc_get_token(), DCT_INT);
  3486. +       }
  3487. +}
  3488. +
  3489. +void dc_stuff_ubyte(ubyte *i)
  3490. +{
  3491. +       ulong value_ul;
  3492. +
  3493. +       dc_ignore_gray_space();
  3494. +
  3495. +       value_ul = dc_parse_ulong(Cp, DCT_UBYTE);
  3496. +
  3497. +       // Since some system's chars may be greater than 1 byte, we can't use UCHAR_MAX for a UBYTE
  3498. +       if ((value_ul <= 255) && (value_ul >= 0)) {
  3499. +               *i = value_ul;
  3500. +               dc_get_token();    // Advance Cp
  3501. +
  3502. +       } else {
  3503. +               throw errParse(dc_get_token(), DCT_UBYTE);
  3504. +       }
  3505. +}
  3506. +
  3507. +void dc_stuff_boolean(bool *b)
  3508. +{
  3509. +       SCP_string token;
  3510. +
  3511. +       token = dc_get_token();
  3512. +
  3513. +       if ((token == "yes")
  3514. +               || (token == "true")
  3515. +               || (token == "ja")          // German
  3516. +               || (token == "Oui")         // French
  3517. +               || (token == "si")          // Spanish
  3518. +//             || (token == "ita vero")    // Latin, not supported
  3519. +               || (token == "HIja") || (token == "HISLaH"))    // Klingon
  3520. +       {
  3521. +               *b = true;
  3522. +
  3523. +       } else if ((token == "no")
  3524. +               || (token == "false")
  3525. +               || (token == "nein")    // German
  3526. +               || (token == "Non")     // French
  3527. +//             || (token == "no")      // Spanish, redundant with English "no"
  3528. +//             || (token == "minime")  // Latin, not supported
  3529. +               || (token == "ghobe'"))  // Klingon
  3530. +       {
  3531. +               *b = false;
  3532. +
  3533. +       } else {
  3534. +               throw errParse(token.c_str(), DCT_BOOL);
  3535. +       }
  3536. +}
  3537. +
  3538. +// Stupid hack to get around plain C's lack of a bool type
  3539. +void dc_stuff_boolean(int *i)
  3540. +{
  3541. +       bool value_b;
  3542. +
  3543. +       dc_stuff_boolean(&value_b);
  3544. +
  3545. +       value_b ? *i = 1 : *i = 0;
  3546. +}
  3547. +
  3548. +/**
  3549. + * @brief Stuffs a string to out_str from the Command_string, stopping at the end of the Command_string
  3550. + *
  3551. + * @param[out] out_str  Destination string
  3552. + * @param[in]  maxlen   Maximum length to copy, is less than or equal to sizeof(out_str)
  3553. + *
  3554. + * @details Throws an errParseOverflow when parser cannot stuff the entirety of the found string into out_str
  3555. + */
  3556. +void dc_stuff_string(char *out_str, size_t maxlen)
  3557. +{
  3558. +       size_t count = 0;
  3559. +       char *c_ptr = Cp;
  3560. +
  3561. +       Assert(Cp);
  3562. +       Assert(out_str);
  3563. +
  3564. +       // Advance past grayspace, stopping at null terminator
  3565. +       while (is_gray_space(*c_ptr) && (*c_ptr != '\0')) {
  3566. +               c_ptr++;
  3567. +       }
  3568. +
  3569. +       // Bail if we're at the terminator
  3570. +       if (*c_ptr == '\0') {
  3571. +               throw errParse("Nothing!", DCT_STRING);
  3572. +               return;
  3573. +       }
  3574. +
  3575. +       // Scan the string, stopping at null terminator, or before we overflow
  3576. +       while ((*c_ptr != '\0') && (count < maxlen)) {
  3577. +               count++;
  3578. +       }
  3579. +
  3580. +       // Bail if overflow
  3581. +       if (count == maxlen) {
  3582. +               throw errParse("", DCT_STRING);
  3583. +               return;
  3584. +       }
  3585. +
  3586. +       // Copy string into out_str
  3587. +       strncpy(out_str, Cp, (c_ptr - Cp));
  3588. +      
  3589. +       // Advance the parser pointer past what we copied
  3590. +       Cp = c_ptr;
  3591. +}
  3592. +
  3593. +/**
  3594. + * @brief Stuffs a string to out_str from the Command_string, stopping at the end of the Command_string
  3595. + *
  3596. + * @param[out] out_str  Destination string
  3597. + *
  3598. + * @details
  3599. + */
  3600. +void dc_stuff_string(SCP_string &out_str)
  3601. +{
  3602. +       size_t count = 0;
  3603. +       char *c_ptr = Cp;
  3604. +
  3605. +       Assert(Cp);
  3606. +
  3607. +       // Advance past grayspace, stopping at null terminator
  3608. +       while (is_gray_space(*c_ptr) && (*c_ptr != '\0')) {
  3609. +               c_ptr++;
  3610. +       }
  3611. +
  3612. +       // Bail if we're at the terminator
  3613. +       if (*c_ptr == '\0') {
  3614. +               throw errParse("Nothing!", DCT_STRING);
  3615. +               return;
  3616. +       }
  3617. +
  3618. +       // Scan the string, stopping at null terminator, or before we overflow
  3619. +       while ((*c_ptr != '\0') && (count < out_str.max_size())) {
  3620. +               count++;
  3621. +       }
  3622. +
  3623. +       // Bail if overflow
  3624. +       if (count == out_str.max_size()) {
  3625. +               throw errParse("", DCT_STRING);
  3626. +               return;
  3627. +       }
  3628. +
  3629. +       // Copy string into out_str
  3630. +       out_str.copy(Cp, (c_ptr - Cp));
  3631. +      
  3632. +       // Advance the parser pointer past what we copied
  3633. +       Cp = c_ptr;
  3634. +}
  3635. +
  3636. +/**
  3637. + * @brief Stuffs a string to str from the Command_string, stopping at the first whitespace character
  3638. + * @details Actually stops at the first grayspace character, since there will never be an EOF character in the
  3639. + *     Command_line string.
  3640. + * TODO: Double Quote support
  3641. + */
  3642. +void dc_stuff_string_white(char *out_str, size_t maxlen)
  3643. +{
  3644. +       size_t count = 0;
  3645. +       char *c_ptr = Cp;
  3646. +
  3647. +       Assert(Cp);
  3648. +       Assert(out_str);
  3649. +
  3650. +       // Advance past grayspace, stopping at null terminator
  3651. +       while (is_gray_space(*c_ptr) && (*c_ptr != '\0')) {
  3652. +               c_ptr++;
  3653. +       }
  3654. +
  3655. +       // Bail if we're at the terminator
  3656. +       if (*c_ptr == '\0') {
  3657. +               throw errParse("Nothing!", DCT_STRING);
  3658. +               return;
  3659. +       }
  3660. +
  3661. +       // Scan the string, stopping at grayspace, null terminator, or before we overflow
  3662. +       while (!is_gray_space(*c_ptr) && (*c_ptr != '\0') && (count < maxlen)) {
  3663. +               count++;
  3664. +       }
  3665. +
  3666. +       // Bail if overflow
  3667. +       if (count == maxlen) {
  3668. +               throw errParse("", DCT_STRING);
  3669. +               return;
  3670. +       }
  3671. +
  3672. +       // Copy string into out_str
  3673. +       strncpy(out_str, Cp, (c_ptr - Cp));
  3674. +      
  3675. +       // Advance the parser pointer past what we copied
  3676. +       Cp = c_ptr;
  3677. +}
  3678. +
  3679. +void dc_stuff_string_white(SCP_string &out_str)
  3680. +{
  3681. +       size_t count = 0;
  3682. +       char *c_ptr = Cp;
  3683. +
  3684. +       Assert(Cp);
  3685. +
  3686. +       // Advance past grayspace, stopping at null terminator
  3687. +       while (is_gray_space(*c_ptr) && (*c_ptr != '\0')) {
  3688. +               c_ptr++;
  3689. +       }
  3690. +
  3691. +       // Bail if we're at the terminator
  3692. +       if (*c_ptr == '\0') {
  3693. +               throw errParse("Nothing!", DCT_STRING);
  3694. +               return;
  3695. +       }
  3696. +
  3697. +       // Scan the string, stopping at grayspace, null terminator, or before we overflow
  3698. +       while (!is_gray_space(*c_ptr) && (*c_ptr != '\0') && (count < out_str.max_size())) {
  3699. +               count++;
  3700. +       }
  3701. +
  3702. +       // Bail if overflow
  3703. +       if (count == out_str.max_size()) {
  3704. +               throw errParse("", DCT_STRING);
  3705. +               return;
  3706. +       }
  3707. +
  3708. +       // Copy string into out_str
  3709. +       out_str.copy(Cp, (c_ptr - Cp));
  3710. +      
  3711. +       // Advance the parser pointer past what we copied
  3712. +       Cp = c_ptr;
  3713. +}
  3714. +
  3715. +// Maybe stuffs
  3716. +
  3717. +/**
  3718. + * @brief Tries to stuff a float from the Command_string.
  3719. + *
  3720. + * @param[in] f  The float variable to maybe stuff.
  3721. + *
  3722. + * @details
  3723. + *   If there's nothing on the command line, *f = 0 and false is returned
  3724. + *
  3725. + *   If there's something on the command line, and we're able to convert it, *f = the converted value, true is
  3726. + *     returned, and the parser is advanced past the token
  3727. + *
  3728. + *   If there's something on command line, but we can't convert it, an errParse is thrown
  3729. + */
  3730. +bool dc_maybe_stuff_float(float *f)
  3731. +{
  3732. +       dc_ignore_gray_space();
  3733. +
  3734. +       if (Cp != '\0') {
  3735. +               dc_stuff_float(f);
  3736. +               return true;
  3737. +      
  3738. +       } else {
  3739. +               *f = 0;
  3740. +               return false;
  3741. +       }
  3742. +}
  3743. +
  3744. +/**
  3745. + * @brief Tries to stuff an int from the Command_string.
  3746. + *
  3747. + * @param[in] i  The int variable to maybe stuff.
  3748. + *
  3749. + * @details
  3750. + *   If there's nothing on the command line, *i = 0 and false is returned
  3751. + *
  3752. + *   If there's something on the command line, and we're able to convert it, *i = the converted value, true is
  3753. + *     returned, and the parser is advanced past the token
  3754. + *
  3755. + *   If there's something on command line, but we can't convert it, an errParse is thrown
  3756. + */
  3757. +bool dc_maybe_stuff_int(int *i)
  3758. +{
  3759. +       dc_ignore_gray_space();
  3760. +
  3761. +       if (Cp != '\0') {
  3762. +               dc_stuff_int(i);
  3763. +               return true;
  3764. +       } else {
  3765. +               *i = 0;
  3766. +               return false;
  3767. +       }
  3768. +}
  3769. +
  3770. +/**
  3771. + * @brief Tries to stuff an uint from the Command_string.
  3772. + *
  3773. + * @param[in] i  The uint variable to maybe stuff.
  3774. + *
  3775. + * @details
  3776. + *   If there's nothing on the command line, *i = 0 and false is returned
  3777. + *
  3778. + *   If there's something on the command line, and we're able to convert it, *i = the converted value, true is
  3779. + *     returned, and the parser is advanced past the token
  3780. + *
  3781. + *   If there's something on command line, but we can't convert it, an errParse is thrown
  3782. + */
  3783. +bool dc_maybe_stuff_uint(uint *i)
  3784. +{
  3785. +       dc_ignore_gray_space();
  3786. +
  3787. +       if (Cp != '\0') {
  3788. +               dc_stuff_uint(i);
  3789. +               return true;
  3790. +       } else {
  3791. +               *i = 0;
  3792. +               return false;
  3793. +       }
  3794. +}
  3795. +
  3796. +/**
  3797. + * @brief Tries to stuff an ubyte from the Command_string.
  3798. + *
  3799. + * @param[in] i  The ubyte variable to maybe stuff.
  3800. + *
  3801. + * @details
  3802. + *   If there's nothing on the command line, *i = 0 and false is returned
  3803. + *
  3804. + *   If there's something on the command line, and we're able to convert it, *i = the converted value, true is
  3805. + *     returned, and the parser is advanced past the token
  3806. + *
  3807. + *   If there's something on command line, but we can't convert it, an errParse is thrown
  3808. + */
  3809. +bool dc_maybe_stuff_ubyte(ubyte *i)
  3810. +{
  3811. +       dc_ignore_gray_space();
  3812. +
  3813. +       if (Cp != '\0') {
  3814. +               dc_stuff_ubyte(i);
  3815. +               return true;
  3816. +       } else {
  3817. +               *i = 0;
  3818. +               return false;
  3819. +       }
  3820. +}
  3821. +
  3822. +/**
  3823. + * @brief Tries to stuff a bool from the Command_string.
  3824. + *
  3825. + * @param[in] b  The bool variable to maybe stuff.
  3826. + *
  3827. + * @details
  3828. + *   If there's nothing on the command line, *b = false and false is returned
  3829. + *
  3830. + *   If there's something on the command line, and we're able to convert it, *b = the converted value, true is
  3831. + *     returned, and the parser is advanced past the token
  3832. + *
  3833. + *   If there's something on command line, but we can't convert it, an errParse is thrown
  3834. + */
  3835. +bool dc_maybe_stuff_boolean(bool *b)
  3836. +{
  3837. +       dc_ignore_gray_space();
  3838. +
  3839. +       if (Cp != '\0') {
  3840. +               dc_stuff_boolean(b);
  3841. +               return true;
  3842. +       } else {
  3843. +               *b = false;
  3844. +               return false;
  3845. +       }
  3846. +}
  3847. +
  3848. +/**
  3849. + * @brief Tries to stuff an int with a bool value from the Command_string.
  3850. + *
  3851. + * @param[in] i  The int variable to maybe stuff.
  3852. + *
  3853. + * @details
  3854. + *   If there's nothing on the command line, *i = 0 and false is returned
  3855. + *
  3856. + *   If there's something on the command line, and we're able to convert it, *i = the converted value, true is
  3857. + *     returned, and the parser is advanced past the token
  3858. + *
  3859. + *   If there's something on command line, but we can't convert it, an errParse is thrown
  3860. + */
  3861. +bool dc_maybe_stuff_boolean(int *i)
  3862. +{
  3863. +       dc_ignore_gray_space();
  3864. +
  3865. +       if (Cp != '\0') {
  3866. +               dc_stuff_boolean(i);
  3867. +               return true;
  3868. +       } else {
  3869. +               *i = 0;
  3870. +               return false;
  3871. +       }
  3872. +}
  3873. +
  3874. +/**
  3875. + * @brief Tries to stuff a whitespace delimited string from the Command_string.
  3876. + *
  3877. + * @param[in] str  The string to maybe stuff.
  3878. + *
  3879. + * @details
  3880. + *   If there's nothing on the command line, *str = "" and false is returned
  3881. + *
  3882. + *   If there's something on the command line, *str = the token, true is
  3883. + *     returned, and the parser is advanced past the token
  3884. + *
  3885. + *   If there's a token on the command line, but we can't fit it inside of str (token.size() >= len), then errParse is
  3886. + *     thrown
  3887. + */
  3888. +bool dc_maybe_stuff_string_white(char *str, size_t len)
  3889. +{
  3890. +       dc_ignore_gray_space();
  3891. +
  3892. +       if (Cp != '\0') {
  3893. +               dc_stuff_string_white(str, len);
  3894. +               return true;
  3895. +       } else {
  3896. +               *str = '\0';
  3897. +               return false;
  3898. +       }
  3899. +}
  3900. +
  3901. +/**
  3902. + * @brief Tries to stuff a whitespace delimited string from the Command_string.
  3903. + *
  3904. + * @param[in] str  The string to maybe stuff.
  3905. + *
  3906. + * @details
  3907. + *   If there's nothing on the command line, str = "" and false is returned
  3908. + *
  3909. + *   If there's something on the command line, str = the token, true is
  3910. + *     returned, and the parser is advanced past the token
  3911. + *
  3912. + *   If there's a token on the command line, but we can't fit it inside of str (token.size() >= str.max_size()), then
  3913. + *     errParse is thrown. Very unlikely to happen.
  3914. + */
  3915. +bool dc_maybe_stuff_string_white(SCP_string &str)
  3916. +{
  3917. +       dc_ignore_gray_space();
  3918. +
  3919. +       if (Cp != '\0') {
  3920. +               dc_stuff_string_white(str);
  3921. +               return true;
  3922. +       } else {
  3923. +               str = "";
  3924. +               return false;
  3925. +       }
  3926. +}
  3927. +
  3928. +// State machine processes
  3929. +inline
  3930. +state_int process_state_prefix(char *ch_ptr, SCP_string &buffer_str, int &base) {
  3931. +       state_int state = si_invalid;
  3932. +
  3933. +       if (ch_is_binary_prefix(*ch_ptr)) {
  3934. +               state = si_numeral_bin;
  3935. +               base = 2;
  3936. +               ch_ptr++;
  3937. +      
  3938. +       } else if (ch_is_octal_prefix(*ch_ptr)) {
  3939. +               state = si_numeral_octal;
  3940. +               base = 8;
  3941. +               ch_ptr++;
  3942. +      
  3943. +       } else if (ch_is_hex_prefix(*ch_ptr)) {
  3944. +               state = si_numeral_hex;
  3945. +               base = 16;
  3946. +               ch_ptr++;
  3947. +
  3948. +       } else if (ch_is_numeral(*ch_ptr)) {
  3949. +               // User passed something like 0123
  3950. +               // Just ignore the first 0, if the user passed something like 00001 then state si_numeral can handle it
  3951. +               state = si_numeral;
  3952. +               ch_ptr++;
  3953. +      
  3954. +       } else if ((*ch_ptr == '\0') || is_white_space(*ch_ptr)) {
  3955. +               // Just a 0 was passed.
  3956. +               buffer_str.push_back('0');
  3957. +               state = si_end;
  3958. +
  3959. +       } else {
  3960. +               if (Dc_debug_on) {
  3961. +                       dc_printf("<debug> [parse_long] Invalid character '%c' found in si_prefix\n", *ch_ptr);
  3962. +               }
  3963. +               state = si_invalid;
  3964. +
  3965. +       }
  3966. +       return state;
  3967. +}
  3968. +
  3969. +inline
  3970. +state_int process_state_sign(char *ch_ptr, SCP_string &buffer_str) {
  3971. +       state_int state;
  3972. +       if (ch_is_numeral(*ch_ptr)) {
  3973. +               state = si_numeral;
  3974. +               buffer_str.push_back(*ch_ptr);
  3975. +               ch_ptr++;
  3976. +
  3977. +       } else if (ch_is_prefix(*ch_ptr)) {
  3978. +               state = si_prefix;
  3979. +               ch_ptr++;
  3980. +
  3981. +       } else if ((*ch_ptr == '\0') || is_white_space(*ch_ptr)) {
  3982. +               // Error condition, but let si_end handle it (consistant with how the numerals handle it)
  3983. +               state = si_end;
  3984. +
  3985. +       } else {
  3986. +               if (Dc_debug_on) {
  3987. +                       dc_printf("<debug> [parse_long] Invalid character '%c' found in si_sign\n", *ch_ptr);
  3988. +               }
  3989. +               state = si_invalid;
  3990. +
  3991. +       }
  3992. +       return state;
  3993. +}
  3994. +
  3995. +inline
  3996. +state_int process_state_numeral(char* ch_ptr, SCP_string &buffer_str) {
  3997. +       state_int state = si_numeral;
  3998. +
  3999. +       if (ch_is_numeral(*ch_ptr)) {
  4000. +               buffer_str.push_back(*ch_ptr);
  4001. +               ch_ptr++;
  4002. +      
  4003. +       } else if ((*ch_ptr == '\0') || is_white_space(*ch_ptr)) {
  4004. +               state = si_end;
  4005. +      
  4006. +       } else {
  4007. +               // Invalid character, throw and bail
  4008. +               if (Dc_debug_on) {
  4009. +                       dc_printf("<debug> [parse_long] Invalid character '%c' found in si_numeral\n", *ch_ptr);
  4010. +               }
  4011. +               state = si_invalid;
  4012. +
  4013. +       }
  4014. +       return state;
  4015. +}
  4016. +
  4017. +inline
  4018. +state_int process_state_numeral_bin(char* ch_ptr, SCP_string &buffer_str) {
  4019. +       state_int state = si_numeral_bin;
  4020. +
  4021. +       if (ch_is_binary(*ch_ptr)) {
  4022. +               buffer_str.push_back(*ch_ptr);
  4023. +               ch_ptr++;
  4024. +      
  4025. +       } else if ((*ch_ptr == '\0') || is_white_space(*ch_ptr)) {
  4026. +               state = si_end;
  4027. +      
  4028. +       } else {
  4029. +               if (Dc_debug_on) {
  4030. +                       dc_printf("<debug> [parse_long] Invalid character '%c' found in si_numeral_bin\n", *ch_ptr);
  4031. +               }
  4032. +               state = si_invalid;
  4033. +
  4034. +       }
  4035. +       return state;
  4036. +}
  4037. +
  4038. +inline
  4039. +state_int process_state_numeral_hex(char* ch_ptr, SCP_string &buffer_str) {
  4040. +       state_int state = si_numeral_hex;
  4041. +
  4042. +       if (ch_is_hex(*ch_ptr)) {
  4043. +               buffer_str.push_back(*ch_ptr);
  4044. +               ch_ptr++;
  4045. +      
  4046. +       } else if ((*ch_ptr == '\0') || is_white_space(*ch_ptr)) {
  4047. +               state = si_end;
  4048. +      
  4049. +       } else {
  4050. +               if (Dc_debug_on) {
  4051. +                       dc_printf("<debug> [parse_long] Invalid character '%c' found in si_numeral_hex\n", *ch_ptr);
  4052. +               }
  4053. +               state = si_invalid;
  4054. +       }
  4055. +       return state;
  4056. +}
  4057. +
  4058. +inline
  4059. +state_int process_state_numeral_octal(char* ch_ptr, SCP_string &buffer_str) {
  4060. +       state_int state = si_numeral_octal;
  4061. +
  4062. +       if (ch_is_octal(*ch_ptr)) {
  4063. +               buffer_str.push_back(*ch_ptr);
  4064. +               ch_ptr++;
  4065. +      
  4066. +       } else if ((*ch_ptr == '\0') || is_white_space(*ch_ptr)) {
  4067. +               state = si_end;
  4068. +      
  4069. +       } else {
  4070. +               // Invalid character, throw and bail
  4071. +               if (Dc_debug_on) {
  4072. +                       dc_printf("<debug> [parse_long] Invalid character '%c' found in si_numeral_octal\n", *ch_ptr);
  4073. +               }
  4074. +               state = si_invalid;
  4075. +       }
  4076. +       return state;
  4077. +}
  4078. Index: debugconsole/consoleparse.h
  4079. ===================================================================
  4080. --- debugconsole/consoleparse.h (Revision 0)
  4081. +++ debugconsole/consoleparse.h (Arbeitskopie)
  4082. @@ -0,0 +1,163 @@
  4083. +#ifndef _CONSOLEPARSE_H
  4084. +#define _CONSOLEPARSE_H
  4085. +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4086. +// Command-line parsing functions for z64555's debug console, created for the FreeSpace Source Code project
  4087. +//
  4088. +// Portions of this source code are based on works by Volition, Inc. circa 1999. You may not sell or otherwise
  4089. +// commercially exploit the source or things you created based on the source.
  4090. +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4091. +
  4092. +/**
  4093. + * @file consoleparse.h
  4094. + * @brief Parsing functions for the command line. Previously known as the command line scanner
  4095. + *
  4096. + * @details A lot of functions here are blatently copied from parselo.h :D
  4097. +  */
  4098. +
  4099. +#include "globalincs/pstypes.h"
  4100. +
  4101. +#define MAX_CLI_LEN 512
  4102. +#define MAX_TOKEN_LENGTH 255
  4103. +
  4104. +enum dc_token {
  4105. +       DCT_NONE = 0,
  4106. +       DCT_STRING,
  4107. +       DCT_FLOAT,
  4108. +       DCT_INT,
  4109. +       DCT_UINT,
  4110. +       DCT_BYTE,
  4111. +       DCT_UBYTE,
  4112. +       DCT_BOOL
  4113. +};
  4114. +
  4115. +/**
  4116. + * @class errParse
  4117. + *
  4118. + * @brief Class thrown when a required token is not found
  4119. + *
  4120. + *  @details This is a basic parser error, it contains the token (a single word) that was found, and the expected token
  4121. + *      type. Some DCT's, such as the DCT_STRING's, have their own specific requirements for error handling, and as
  4122. + *      such get their own class derived from errParse. The catching routines should be able to catch the derived error
  4123. + *      objects, but if not, they can be caught by a routine looking for the base class and then be casted to their
  4124. + *      proper type.
  4125. + */
  4126. +class errParse {
  4127. +public:
  4128. +       SCP_string found_token;
  4129. +       dc_token expected_type;
  4130. +
  4131. +       /**
  4132. +       *  @brief Invalid/Unexpected token constructor
  4133. +       *  @param [in] found_str The token that was found
  4134. +       *  @param [in] expected_dct The token type that was expected
  4135. +       */
  4136. +       errParse(const char *found_str, dc_token expected_dct)
  4137. +               : found_token(found_str), expected_type(expected_dct)
  4138. +       {
  4139. +       }
  4140. +};
  4141. +
  4142. +/**
  4143. + * @class errParseString
  4144. + *
  4145. + * @brief Class thrown when an expected string was not found. Supports up to 4 required strings.
  4146. + */
  4147. +class errParseString : public errParse
  4148. +{
  4149. +public:
  4150. +       SCP_string expected_token1;
  4151. +       SCP_string expected_token2;
  4152. +       SCP_string expected_token3;
  4153. +       SCP_string expected_token4;
  4154. +       /**
  4155. +        *  @brief Invalid/Unexpected token constructor.
  4156. +        *  
  4157. +        *  @param [in] found_str The string that was found
  4158. +        *  @param [in] str The token that was expected
  4159. +        */
  4160. +       errParseString(char *found_str, char *str)
  4161. +           : errParse(found_str, DCT_STRING), expected_token1(str)
  4162. +       {
  4163. +       }
  4164. +
  4165. +       /**
  4166. +        *  @brief Invalid/Unexpected token constructor.
  4167. +        *  
  4168. +        *  @param [in] found_str The string that was found
  4169. +        *  @param [in] str1 The first token that was expected
  4170. +        *  @param [in] str2 The second token that was expected
  4171. +        */
  4172. +       errParseString(char *found_str, char *str1, char *str2)
  4173. +           : errParse(found_str, DCT_STRING), expected_token1(str1), expected_token2(str2)
  4174. +       {
  4175. +       }
  4176. +
  4177. +       /**
  4178. +        *  @brief Invalid/Unexpected token constructor.
  4179. +        *  
  4180. +        *  @param [in] found_str The string that was found
  4181. +        *  @param [in] str1 The first token that was expected
  4182. +        *  @param [in] str2 The second token that was expected
  4183. +        *  @param [in] str3 The third token that was expected
  4184. +        */
  4185. +       errParseString(char *found_str, char *str1, char *str2, char *str3)
  4186. +           : errParse(found_str, DCT_STRING), expected_token1(str1), expected_token2(str2), expected_token3(str3)
  4187. +       {
  4188. +       }
  4189. +
  4190. +       /**
  4191. +        *  @brief Invalid/Unexpected token constructor.
  4192. +        *  
  4193. +        *  @param [in] found_str The string that was found
  4194. +        *  @param [in] str1 The first token that was expected
  4195. +        *  @param [in] str2 The second token that was expected
  4196. +        *  @param [in] str3 The third token that was expected
  4197. +        *  @param [in] str4 The fourth token that was expected
  4198. +        */
  4199. +       errParseString(char *found_str, char *str1, char *str2, char *str3, char *str4)
  4200. +           : errParse(found_str, DCT_STRING), expected_token1(str1), expected_token2(str2), expected_token3(str3), expected_token4(str4)
  4201. +       {
  4202. +       }
  4203. +};
  4204. +
  4205. +void dc_parse_init(SCP_string &str);
  4206. +
  4207. +void dc_ignore_white_space(void);
  4208. +void dc_ignore_gray_space(void);
  4209. +
  4210. +// Required/Optional Token
  4211. +bool dc_required_string(char *pstr);
  4212. +int dc_required_string_either(char *str1, char *str2);
  4213. +int dc_required_string_3(char *str1, char *str2, char *str3);
  4214. +int dc_required_string_4(char *str1, char *str2, char *str3, char *str4);
  4215. +
  4216. +bool dc_optional_string(char *pstr);
  4217. +bool dc_optional_string_either(char *str1, char *str2);
  4218. +
  4219. +// Stuffs
  4220. +// These provide a limited support of math evaluations.
  4221. +void dc_stuff_float(float *f);
  4222. +void dc_stuff_int(int *i);
  4223. +void dc_stuff_uint(uint *i);
  4224. +void dc_stuff_ubyte(ubyte *i);
  4225. +void dc_stuff_boolean(bool *b);
  4226. +void dc_stuff_boolean(int *i); // Stupid hack to get around plain C's lack of a bool type
  4227. +
  4228. +void dc_stuff_string(char *str);
  4229. +void dc_stuff_string(SCP_string &str);
  4230. +void dc_stuff_string_white(char *str, size_t len);
  4231. +void dc_stuff_string_white(SCP_string &str);
  4232. +
  4233. +// Maybe Stuffs.
  4234. +// 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
  4235. +// Each returns TRUE if a stuff was actually performed. FALSE if nothing was stuffed.
  4236. +bool dc_maybe_stuff_float(float *f);
  4237. +bool dc_maybe_stuff_int(int *i);
  4238. +bool dc_maybe_stuff_uint(uint *i);
  4239. +bool dc_maybe_stuff_ubyte(ubyte *i);
  4240. +bool dc_maybe_stuff_boolean(bool *b);
  4241. +bool dc_maybe_stuff_boolean(int *i);
  4242. +bool dc_maybe_stuff_string_white(char *str, size_t len);
  4243. +bool dc_maybe_stuff_string_white(SCP_string &str);
  4244. +
  4245. +#endif // _CONSOLEPARSE_H
  4246. Index: freespace2/freespace.cpp
  4247. ===================================================================
  4248. --- freespace2/freespace.cpp    (Revision 10462)
  4249. +++ freespace2/freespace.cpp    (Arbeitskopie)
  4250. @@ -33,6 +33,7 @@
  4251.  #include "cutscene/cutscenes.h"
  4252.  #include "cutscene/movie.h"
  4253.  #include "debris/debris.h"
  4254. +#include "debugconsole/console.h"
  4255.  #include "exceptionhandler/exceptionhandler.h"
  4256.  #include "external_dll/trackirpublic.h" // header file for the TrackIR routines (Swifty)
  4257.  #include "fireball/fireballs.h"
  4258. @@ -665,10 +666,9 @@
  4259.  int Sun_drew = 0;
  4260.  
  4261.  float sn_glare_scale = 1.7f;
  4262. -DCF(sn_glare, "")
  4263. +DCF(sn_glare, "Sets the sun glare scale (Default is 1.7)")
  4264.  {
  4265. -   dc_get_arg(ARG_FLOAT);
  4266. -   sn_glare_scale = Dc_arg_float;
  4267. +   dc_stuff_float(&sn_glare_scale);
  4268.  }
  4269.  
  4270.  float Supernova_last_glare = 0.0f;
  4271. @@ -1499,80 +1499,101 @@
  4272.  
  4273.  DCF(warp, "Tests warpin effect")
  4274.  {
  4275. -   if ( Dc_command )   {
  4276. -       bool warpin = true;
  4277. -       int idx = -1;
  4278. +   if (dc_optional_string_either("help", "--help")) {
  4279. +       dc_printf( "Params: bool warpin, string Target = ""\n  Warps in if true, out if false. Player is target unless specific ship is specified\n" );
  4280. +       return;
  4281. +   } // Else, process command
  4282.  
  4283. -       dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);
  4284. -       if( Dc_arg_type & ARG_TRUE) warpin = true;
  4285. -       else if(Dc_arg_type & ARG_FALSE) warpin = false;
  4286. +   // TODO: Provide status flag
  4287.  
  4288. -       if(!(Dc_arg_type & ARG_NONE))
  4289. -       {
  4290. -           dc_get_arg(ARG_STRING|ARG_NONE);
  4291. -           if(Dc_arg_type & ARG_STRING)
  4292. -           {
  4293. -               idx = ship_name_lookup(Dc_arg);
  4294. -               if(idx > -1)
  4295. -               {
  4296. -                   if(warpin)
  4297. -                       shipfx_warpin_start(&Objects[Ships[idx].objnum]);
  4298. -                   else
  4299. -                       shipfx_warpout_start(&Objects[Ships[idx].objnum]);
  4300. -               }
  4301. +   bool warpin;
  4302. +   char target[MAX_NAME_LEN];
  4303. +   int idx = -1;
  4304. +
  4305. +   dc_stuff_boolean(&warpin);
  4306. +   if (dc_maybe_stuff_string_white(target, MAX_NAME_LEN)) {
  4307. +       idx = ship_name_lookup(target);
  4308. +   }   // Else, default target to player
  4309. +  
  4310. +   if (idx < 0) {
  4311. +       // Player is target
  4312. +       if (Player_ai->target_objnum > -1) {
  4313. +           if(warpin) {
  4314. +               shipfx_warpin_start(&Objects[Player_ai->target_objnum]);
  4315. +           } else {
  4316. +               shipfx_warpout_start(&Objects[Player_ai->target_objnum]);
  4317.             }
  4318.         }
  4319. -      
  4320. -       if(idx < 0)
  4321. -       {
  4322. -           if(Player_ai->target_objnum > -1)
  4323. -           {
  4324. -               if(warpin)
  4325. -                   shipfx_warpin_start(&Objects[Player_ai->target_objnum]);
  4326. -               else
  4327. -                   shipfx_warpout_start(&Objects[Player_ai->target_objnum]);
  4328. -           }
  4329. +   } else {
  4330. +       // Non-player is targer
  4331. +       if (warpin) {
  4332. +           shipfx_warpin_start(&Objects[Ships[idx].objnum]);
  4333. +       } else {
  4334. +           shipfx_warpout_start(&Objects[Ships[idx].objnum]);
  4335.         }
  4336. -   }  
  4337. -   if ( Dc_help )  dc_printf( "Usage: Show_mem\nWarps in if true, out if false, player target unless specific ship is specified\n" )
  4338. +   }
  4339. +  
  4340.  }
  4341.  
  4342.  DCF(show_mem,"Toggles showing mem usage")
  4343.  {
  4344. -   if ( Dc_command )   {  
  4345. -       dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);       
  4346. -       if ( Dc_arg_type & ARG_TRUE )   Show_mem = 1;  
  4347. -       else if ( Dc_arg_type & ARG_FALSE ) Show_mem = 0;  
  4348. -       else if ( Dc_arg_type & ARG_NONE ) Show_mem ^= 1;  
  4349. +   bool process = true;
  4350.  
  4351. -       if ( Show_mem ) {
  4352. -           Show_cpu = 0;
  4353. -       }
  4354. -   }  
  4355. -   if ( Dc_help )  dc_printf( "Usage: Show_mem\nSets show_mem to true or false.  If nothing passed, then toggles it.\n" );
  4356. -   if ( Dc_status )    {
  4357. -       dc_printf( "Show_mem is %s\n", (Show_mem?"TRUE":"FALSE") );
  4358. -       dc_printf( "Show_cpu is %s\n", (Show_cpu?"TRUE":"FALSE") );
  4359. +   if (dc_optional_string_either("help", "--help")) {
  4360. +       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" );
  4361. +       process = false;
  4362.     }
  4363. +  
  4364. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  4365. +       dc_printf("Show_mem is %s\n", (Show_mem ? "TRUE" : "FALSE"));
  4366. +       dc_printf("Show_cpu is %s\n", (Show_cpu ? "TRUE" : "FALSE"));
  4367. +       process = false;
  4368. +   }
  4369. +  
  4370. +   if (!process) {
  4371. +       // Help and/or status was given, so don't process the command
  4372. +       return;
  4373. +   } // Else, process the command
  4374. +
  4375. +   if (!dc_maybe_stuff_boolean(&Show_mem)) {
  4376. +       // Nothing passed, so toggle
  4377. +       Show_mem = !Show_mem;
  4378. +   }   // Else, value was set/cleared by user
  4379. +
  4380. +   // Can't show mem and cpu at same time
  4381. +   if (Show_mem) {
  4382. +       Show_cpu = false;
  4383. +   }
  4384.  }
  4385.  
  4386.  DCF(show_cpu,"Toggles showing cpu usage")
  4387.  {
  4388. -   if ( Dc_command )   {  
  4389. -       dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);       
  4390. -       if ( Dc_arg_type & ARG_TRUE )   Show_cpu = 1;  
  4391. -       else if ( Dc_arg_type & ARG_FALSE ) Show_cpu = 0;  
  4392. -       else if ( Dc_arg_type & ARG_NONE ) Show_cpu ^= 1;  
  4393. +   bool process = true;
  4394.  
  4395. -       if ( Show_cpu ) {
  4396. -           Show_mem = 0;
  4397. -       }
  4398. -   }  
  4399. -   if ( Dc_help )  dc_printf( "Usage: Show_cpu\nSets show_cpu to true or false.  If nothing passed, then toggles it.\n" );
  4400. -   if ( Dc_status )    {
  4401. -       dc_printf( "Show_mem is %s\n", (Show_mem?"TRUE":"FALSE") );
  4402. -       dc_printf( "Show_cpu is %s\n", (Show_cpu?"TRUE":"FALSE") );
  4403. +   if (dc_optional_string_either("help", "--help")) {
  4404. +       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" );
  4405. +       process = false;
  4406. +   }
  4407. +  
  4408. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  4409. +       dc_printf("Show_cpu is %s\n", (Show_cpu ? "TRUE" : "FALSE"));
  4410. +       dc_printf("Show_mem is %s\n", (Show_mem ? "TRUE" : "FALSE"));
  4411. +       process = false;
  4412. +   }
  4413.  
  4414. +   if (!process) {
  4415. +       // Help and/or status was given, so don't process the command
  4416. +       return;
  4417. +   } // Else, process the command
  4418. +
  4419. +   if (!dc_maybe_stuff_boolean(&Show_cpu)) {
  4420. +       // Nothing passed, so toggle
  4421. +       Show_cpu = !Show_cpu;
  4422. +   }   // Else, value was set/cleared by user
  4423. +
  4424. +   // Can't show mem and cpu at same time
  4425. +   if (Show_cpu) {
  4426. +       Show_mem = false;
  4427.     }
  4428.  }
  4429.  
  4430. @@ -1582,43 +1603,57 @@
  4431.  
  4432.  DCF(use_joy_mouse,"Makes joystick move mouse cursor")
  4433.  {
  4434. -   if ( Dc_command )   {  
  4435. -       dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);       
  4436. -       if ( Dc_arg_type & ARG_TRUE )   Use_joy_mouse = 1
  4437. -       else if ( Dc_arg_type & ARG_FALSE ) Use_joy_mouse = 0
  4438. -       else if ( Dc_arg_type & ARG_NONE ) Use_joy_mouse ^= 1
  4439. -   }  
  4440. -   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" );   
  4441. -   if ( Dc_status )    dc_printf( "use_joy_mouse is %s\n", (Use_joy_mouse?"TRUE":"FALSE") );  
  4442. +   bool process = true;
  4443.  
  4444. +   if (dc_optional_string_either("help", "--help")) {
  4445. +       dc_printf("Usage: use_joy_mouse [bool]\nSets use_joy_mouse to true or false.  If nothing passed, then toggles it.\n");
  4446. +       process = false;
  4447. +   }
  4448. +
  4449. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  4450. +       dc_printf("use_joy_mouse is %s\n", (Use_joy_mouse ? "TRUE" : "FALSE"));
  4451. +       process = false;
  4452. +   }
  4453. +
  4454. +   if (!process) {
  4455. +       return;
  4456. +   }
  4457. +
  4458. +   if(!dc_maybe_stuff_boolean(&Use_joy_mouse)) {
  4459. +       // Nothing passed, so toggle
  4460. +       Use_joy_mouse = !Use_joy_mouse;
  4461. +   } // Else, value was set/cleared by user
  4462. +
  4463.     os_config_write_uint( NULL, NOX("JoystickMovesCursor"), Use_joy_mouse );
  4464.  }
  4465.  
  4466. -DCF(palette_flash,"Toggles palette flash effect on/off")
  4467. -{
  4468. -   if ( Dc_command )   {  
  4469. -       dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);       
  4470. -       if ( Dc_arg_type & ARG_TRUE )   Use_palette_flash = 1
  4471. -       else if ( Dc_arg_type & ARG_FALSE ) Use_palette_flash = 0
  4472. -       else if ( Dc_arg_type & ARG_NONE ) Use_palette_flash ^= 1
  4473. -   }  
  4474. -   if ( Dc_help )  dc_printf( "Usage: palette_flash [bool]\nSets palette_flash to true or false.  If nothing passed, then toggles it.\n" );   
  4475. -   if ( Dc_status )    dc_printf( "palette_flash is %s\n", (Use_palette_flash?"TRUE":"FALSE") );  
  4476. -}
  4477. +DCF_BOOL(palette_flash, Use_palette_flash);
  4478.  
  4479.  int Use_low_mem = 0;
  4480.  
  4481.  DCF(low_mem,"Uses low memory settings regardless of RAM")
  4482.  {
  4483. -   if ( Dc_command )   {  
  4484. -       dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);       
  4485. -       if ( Dc_arg_type & ARG_TRUE )   Use_low_mem = 1;   
  4486. -       else if ( Dc_arg_type & ARG_FALSE ) Use_low_mem = 0;   
  4487. -       else if ( Dc_arg_type & ARG_NONE ) Use_low_mem ^= 1;   
  4488. -   }  
  4489. -   if ( Dc_help )  dc_printf( "Usage: low_mem [bool]\nSets low_mem to true or false.  If nothing passed, then toggles it.\n" );   
  4490. -   if ( Dc_status )    dc_printf( "low_mem is %s\n", (Use_low_mem?"TRUE":"FALSE") );  
  4491. +   bool process = true;
  4492.  
  4493. +   if (dc_optional_string_either("help", "--help")) {
  4494. +       dc_printf("Usage: low_mem [bool]\nSets low_mem to true or false.  If nothing passed, then toggles it.\n");
  4495. +       process = false;
  4496. +   }
  4497. +
  4498. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  4499. +       dc_printf("low_mem is %s\n", (Use_low_mem ? "TRUE" : "FALSE"));
  4500. +       process = false;
  4501. +   }
  4502. +
  4503. +   if (!process) {
  4504. +       return;
  4505. +   }
  4506. +
  4507. +   if (!dc_maybe_stuff_boolean(&Use_low_mem)) {
  4508. +       // Nothing passed, so toggle
  4509. +       Use_low_mem = !Use_low_mem;
  4510. +   } // Else, value was set/cleared by user
  4511. +
  4512.     os_config_write_uint( NULL, NOX("LowMem"), Use_low_mem );
  4513.  }
  4514.  
  4515. @@ -1627,14 +1662,26 @@
  4516.  
  4517.  DCF(force_fullscreen, "Forces game to startup in fullscreen mode")
  4518.  {
  4519. -   if ( Dc_command )   {  
  4520. -       dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);       
  4521. -       if ( Dc_arg_type & ARG_TRUE )   Use_fullscreen_at_startup = 1
  4522. -       else if ( Dc_arg_type & ARG_FALSE ) Use_fullscreen_at_startup = 0
  4523. -       else if ( Dc_arg_type & ARG_NONE ) Use_fullscreen_at_startup ^= 1
  4524. -   }  
  4525. -   if ( Dc_help )  dc_printf( "Usage: force_fullscreen [bool]\nSets force_fullscreen to true or false.  If nothing passed, then toggles it.\n" )
  4526. -   if ( Dc_status )    dc_printf( "force_fullscreen is %s\n", (Use_fullscreen_at_startup?"TRUE":"FALSE") );   
  4527. +   bool process = true;
  4528. +   if (dc_optional_string_either("help", "--help")) {
  4529. +       dc_printf("Usage: low_mem [bool]\nSets low_mem to true or false.  If nothing passed, then toggles it.\n");
  4530. +       process = false;
  4531. +   }
  4532. +
  4533. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  4534. +       dc_printf("low_mem is %s\n", (Use_fullscreen_at_startup ? "TRUE" : "FALSE"));
  4535. +       process = false;
  4536. +   }
  4537. +
  4538. +   if (!process) {
  4539. +       return;
  4540. +   }
  4541. +
  4542. +   if (dc_maybe_stuff_boolean(&Use_fullscreen_at_startup)) {
  4543. +       // Nothing passed, so toggle
  4544. +       Use_fullscreen_at_startup = !Use_fullscreen_at_startup;
  4545. +   } // Else, value was set/cleared by user
  4546. +
  4547.     os_config_write_uint( NULL, NOX("ForceFullscreen"), Use_fullscreen_at_startup );
  4548.  }
  4549.  #endif
  4550. @@ -1643,37 +1690,33 @@
  4551.  
  4552.  float FreeSpace_gamma = 1.0f;
  4553.  
  4554. -DCF(gamma,"Sets Gamma factor")
  4555. +DCF(gamma,"Sets and saves Gamma Factor")
  4556.  {
  4557. -   if ( Dc_command )   {
  4558. -       dc_get_arg(ARG_FLOAT|ARG_NONE);
  4559. -       if ( Dc_arg_type & ARG_FLOAT )  {
  4560. -           FreeSpace_gamma = Dc_arg_float;
  4561. -       } else {
  4562. -           dc_printf( "Gamma reset to 1.0f\n" );
  4563. -           FreeSpace_gamma = 1.0f;
  4564. -       }
  4565. -       if ( FreeSpace_gamma < 0.1f )   {
  4566. -           FreeSpace_gamma = 0.1f;
  4567. -       } else if ( FreeSpace_gamma > 5.0f )    {
  4568. -           FreeSpace_gamma = 5.0f;
  4569. -       }
  4570. -       gr_set_gamma(FreeSpace_gamma);
  4571. -
  4572. -       char tmp_gamma_string[32];
  4573. -       sprintf( tmp_gamma_string, NOX("%.2f"), FreeSpace_gamma );
  4574. -       os_config_write_string( NULL, NOX("Gamma"), tmp_gamma_string );
  4575. -   }
  4576. -
  4577. -   if ( Dc_help )  {
  4578. +   if (dc_optional_string_either("help", "--help")) {
  4579.         dc_printf( "Usage: gamma <float>\n" );
  4580.         dc_printf( "Sets gamma in range 1-3, no argument resets to default 1.2\n" );
  4581. -       Dc_status = 0;  // don't print status if help is printed.  Too messy.
  4582. +       return;
  4583.     }
  4584.  
  4585. -   if ( Dc_status )    {
  4586. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  4587.         dc_printf( "Gamma = %.2f\n", FreeSpace_gamma );
  4588. +       return;
  4589.     }
  4590. +
  4591. +   if (!dc_maybe_stuff_float(&FreeSpace_gamma)) {
  4592. +       dc_printf( "Gamma reset to 1.0f\n" );
  4593. +       FreeSpace_gamma = 1.0f;
  4594. +   }
  4595. +   if ( FreeSpace_gamma < 0.1f )   {
  4596. +       FreeSpace_gamma = 0.1f;
  4597. +   } else if ( FreeSpace_gamma > 5.0f )    {
  4598. +       FreeSpace_gamma = 5.0f;
  4599. +   }
  4600. +   gr_set_gamma(FreeSpace_gamma);
  4601. +
  4602. +   char tmp_gamma_string[32];
  4603. +   sprintf( tmp_gamma_string, NOX("%.2f"), FreeSpace_gamma );
  4604. +   os_config_write_string( NULL, NOX("Gamma"), tmp_gamma_string );
  4605.  }
  4606.  
  4607.  #ifdef APPLE_APP
  4608. @@ -2399,33 +2442,54 @@
  4609.  
  4610.  DCF(ai_pause,"Pauses ai")
  4611.  {
  4612. -   if ( Dc_command )   {  
  4613. -       dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);       
  4614. -       if ( Dc_arg_type & ARG_TRUE )   ai_paused = 1
  4615. -       else if ( Dc_arg_type & ARG_FALSE ) ai_paused = 0
  4616. -       else if ( Dc_arg_type & ARG_NONE ) ai_paused = !ai_paused; 
  4617. +   bool process = true;
  4618. +  
  4619. +   if (dc_optional_string_either("help", "--help")) {
  4620. +       dc_printf( "Usage: ai_paused [bool]\nSets ai_paused to true or false.  If nothing passed, then toggles it.\n" );
  4621. +       process = false;
  4622. +   }
  4623.  
  4624. -       if (ai_paused)  {  
  4625. -           obj_init_all_ships_physics();
  4626. -       }
  4627. -   }  
  4628. -   if ( Dc_help )  dc_printf( "Usage: ai_paused [bool]\nSets ai_paused to true or false.  If nothing passed, then toggles it.\n" );   
  4629. -   if ( Dc_status )    dc_printf( "ai_paused is %s\n", (ai_paused?"TRUE":"FALSE") );  
  4630. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  4631. +       dc_printf( "ai_paused is %s\n", (ai_paused?"TRUE":"FALSE") );
  4632. +       process = false;
  4633. +   }
  4634. +
  4635. +   if (!process) {
  4636. +       return;
  4637. +   }
  4638. +
  4639. +   if (!dc_maybe_stuff_boolean(&ai_paused)) {
  4640. +       ai_paused = !ai_paused;
  4641. +   }
  4642. +
  4643. +   if (ai_paused) {
  4644. +       obj_init_all_ships_physics();
  4645. +   }
  4646.  }
  4647.  
  4648. -DCF(single_step,"Single steps the game")
  4649. +DCF(single_step,"Enables single step mode.")
  4650.  {
  4651. -   if ( Dc_command )   {  
  4652. -       dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);       
  4653. -       if ( Dc_arg_type & ARG_TRUE )   game_single_step = 1;  
  4654. -       else if ( Dc_arg_type & ARG_FALSE ) game_single_step = 0;  
  4655. -       else if ( Dc_arg_type & ARG_NONE ) game_single_step = !game_single_step;   
  4656. +   bool process = true;
  4657. +  
  4658. +   if (dc_optional_string_either("help", "--help")) {
  4659. +       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");
  4660. +       process = false;
  4661. +   }
  4662.  
  4663. -       last_single_step = 0;   // Make so single step waits a frame before stepping
  4664. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  4665. +       dc_printf( "ai_paused is %s\n", (game_single_step ? "TRUE" : "FALSE") );
  4666. +       process = false;
  4667. +   }
  4668.  
  4669. -   }  
  4670. -   if ( Dc_help )  dc_printf( "Usage: single_step [bool]\nSets single_step to true or false.  If nothing passed, then toggles it.\n" );   
  4671. -   if ( Dc_status )    dc_printf( "single_step is %s\n", (game_single_step?"TRUE":"FALSE") )
  4672. +   if (!process) {
  4673. +       return;
  4674. +   }
  4675. +
  4676. +   if (!dc_maybe_stuff_boolean(&game_single_step)) {
  4677. +       game_single_step = !game_single_step;
  4678. +   }
  4679. +
  4680. +   last_single_step = 0;   // Make so single step waits a frame before stepping
  4681.  }
  4682.  
  4683.  DCF_BOOL(physics_pause, physics_paused)
  4684. @@ -2472,23 +2536,29 @@
  4685.  
  4686.  DCF(view, "Sets the percent of the 3d view to render.")
  4687.  {
  4688. -   if ( Dc_command ) {
  4689. -       dc_get_arg(ARG_INT);
  4690. -       if ( (Dc_arg_int >= 5 ) || (Dc_arg_int <= 100) ) {
  4691. -           View_percent = Dc_arg_int;
  4692. -       } else {
  4693. -           dc_printf( "Illegal value for view. (Must be from 5-100) \n\n");
  4694. -           Dc_help = 1;
  4695. -       }
  4696. -   }
  4697. +   bool process = true;
  4698. +   int value;
  4699.  
  4700. -   if ( Dc_help ) {
  4701. +   if (dc_optional_string_either("help", "--help")) {
  4702.         dc_printf("Usage: view [n]\nwhere n is percent of view to show (5-100).\n");
  4703. +       process = false;
  4704.     }
  4705. -  
  4706. -   if ( Dc_status ) {
  4707. +
  4708. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  4709.         dc_printf("View is set to %d%%\n", View_percent );
  4710. +       process = false;
  4711.     }
  4712. +
  4713. +   if (!process) {
  4714. +       return;
  4715. +   }
  4716. +
  4717. +   dc_stuff_int(&value);
  4718. +   if ( (value >= 5 ) && (value <= 100) ) {
  4719. +       View_percent = value;
  4720. +   } else {
  4721. +       dc_printf("Error: Outside legal range [5 - 100]");
  4722. +   }
  4723.  }
  4724.  
  4725.  
  4726. @@ -2814,38 +2884,44 @@
  4727.  DCF(dcf_fov, "Change the field of view of the main camera")
  4728.  {
  4729.     camera *cam = Main_camera.getCamera();
  4730. -   if ( Dc_command )
  4731. -   {
  4732. -       if(cam == NULL)
  4733. -           return;
  4734. +   bool process = true;
  4735. +   float value;
  4736.  
  4737. -       dc_get_arg(ARG_FLOAT|ARG_NONE);
  4738. -       if ( Dc_arg_type & ARG_NONE )   {
  4739. -           cam->set_fov(VIEWER_ZOOM_DEFAULT);
  4740. -           dc_printf( "Zoom factor reset\n" );
  4741. +   if (dc_optional_string_either("help", "--help")) {
  4742. +       dc_printf( "Usage: fov [factor]\nFactor is the zoom factor btwn .25 and 1.25\nNo parameter resets it to default.\n" );
  4743. +       process = false;
  4744. +   }
  4745. +
  4746. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  4747. +       if(cam == NULL) {
  4748. +           dc_printf("Camera unavailable.");
  4749. +       } else {
  4750. +           dc_printf("Zoom factor set to %6.3f (original = 0.5, John = 0.75)\n", cam->get_fov());
  4751.         }
  4752. -       if ( Dc_arg_type & ARG_FLOAT )  {
  4753. -           if (Dc_arg_float < 0.25f) {
  4754. -               cam->set_fov(0.25f);
  4755. -               dc_printf("Zoom factor pinned at 0.25.\n");
  4756. -           } else if (Dc_arg_float > 1.25f) {
  4757. -               cam->set_fov(1.25f);
  4758. -               dc_printf("Zoom factor pinned at 1.25.\n");
  4759. -           } else {
  4760. -               cam->set_fov(Dc_arg_float);
  4761. -           }
  4762. -       }
  4763. +
  4764. +       process = false;
  4765.     }
  4766.  
  4767. -   if ( Dc_help ) 
  4768. -       dc_printf( "Usage: fov [factor]\nFactor is the zoom factor btwn .25 and 1.25\nNo parameter resets it to default.\n" );
  4769. +   if ((cam == NULL) || (!process)) {
  4770. +       return;
  4771. +   }
  4772.  
  4773. -   if ( Dc_status )
  4774. -   {
  4775. -       if(cam == NULL)
  4776. -           dc_printf("Camera unavailable.");
  4777. -       else
  4778. -           dc_printf("Zoom factor set to %6.3f (original = 0.5, John = 0.75)", cam->get_fov());
  4779. +   if (!dc_maybe_stuff_float(&value)) {
  4780. +       // No value passed, use default
  4781. +       cam->set_fov(VIEWER_ZOOM_DEFAULT);
  4782. +   } else {
  4783. +       // Value passed, Clamp it to valid values
  4784. +       if (value < 0.25f) {
  4785. +           value = 0.25f;
  4786. +           dc_printf("Zoom factor clamped to 0.25\n");
  4787. +       } else if (value > 1.25f) {
  4788. +           value = 1.25f;
  4789. +           dc_printf("Zoom factor clamped to 1.25\n");
  4790. +       } else {
  4791. +           dc_printf("Zoom factor set to %6.3f\n", value);
  4792. +       }
  4793. +
  4794. +       cam->set_fov(value);
  4795.     }
  4796.  }
  4797.  
  4798. @@ -2852,28 +2928,43 @@
  4799.  
  4800.  DCF(framerate_cap, "Sets the framerate cap")
  4801.  {
  4802. -   if ( Dc_command ) {
  4803. -       dc_get_arg(ARG_INT);
  4804. -       if ( (Dc_arg_int >= 1 ) || (Dc_arg_int <= 120) ) {
  4805. -           Framerate_cap = Dc_arg_int;
  4806. -       } else {
  4807. -           dc_printf( "Illegal value for framerate cap. (Must be from 1-120) \n\n");
  4808. -           Dc_help = 1;
  4809. -       }
  4810. -   }
  4811. +   bool process = true;
  4812.  
  4813. -   if ( Dc_help ) {
  4814. +   if (dc_optional_string_either("help", "--help")) {
  4815.         dc_printf("Usage: framerate_cap [n]\nwhere n is the frames per second to cap framerate at.\n");
  4816.         dc_printf("If n is 0 or omitted, then the framerate cap is removed\n");
  4817.         dc_printf("[n] must be from 1 to 120.\n");
  4818. +       process = false;
  4819.     }
  4820. -  
  4821. -   if ( Dc_status ) {
  4822. -       if ( Framerate_cap )
  4823. +
  4824. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  4825. +       if ( Framerate_cap ) {
  4826.             dc_printf("Framerate cap is set to %d fps\n", Framerate_cap );
  4827. -       else
  4828. +       } else {
  4829.             dc_printf("There is no framerate cap currently active.\n");
  4830. +       }
  4831. +
  4832. +       process = false;
  4833.     }
  4834. +
  4835. +   if (!process) {
  4836. +       return;
  4837. +   }
  4838. +
  4839. +   if (!dc_maybe_stuff_int(&Framerate_cap)) {
  4840. +       Framerate_cap = 0;
  4841. +   }
  4842. +
  4843. +   if ((Framerate_cap < 0) || (Framerate_cap > 120)) {
  4844. +       dc_printf( "Illegal value for framerate cap. (Must be from 1-120) \n");
  4845. +       Framerate_cap = 0;
  4846. +   }
  4847. +
  4848. +   if (Framerate_cap == 0) {
  4849. +       dc_printf("Framerate cap disabled");
  4850. +   } else {
  4851. +       dc_printf("Framerate cap is set to %d fps\n", Framerate_cap );
  4852. +   }
  4853.  }
  4854.  
  4855.  #define    MIN_DIST_TO_DEAD_CAMERA     50.0f
  4856. @@ -3774,87 +3865,71 @@
  4857.  #ifndef NDEBUG
  4858.  
  4859.  // function to toggle state of dumping every frame into PCX when playing the game
  4860. -DCF(dump_frames, "Starts/stop frame dumping at 15 hz")
  4861. +DCF(dump_frames, "Toggles On/off frame dumping at 15 hz")
  4862.  {
  4863. -   if ( Dc_command )   {
  4864. -
  4865. -       if ( Debug_dump_frames == 0 )   {
  4866. -           // Turn it on
  4867. -           Debug_dump_frames = 15;
  4868. -           Debug_dump_trigger = 0;
  4869. -           gr_dump_frame_start( Debug_dump_frame_num, DUMP_BUFFER_NUM_FRAMES );
  4870. -           dc_printf( "Frame dumping at 15 hz is now ON\n" );
  4871. -       } else {
  4872. -           // Turn it off
  4873. -           Debug_dump_frames = 0;
  4874. -           Debug_dump_trigger = 0;
  4875. -           gr_dump_frame_stop();
  4876. -           dc_printf( "Frame dumping is now OFF\n" );
  4877. -       }
  4878. -      
  4879. +   if ( Debug_dump_frames == 0 )   {
  4880. +       // Turn it on
  4881. +       Debug_dump_frames = 15;
  4882. +       Debug_dump_trigger = 0;
  4883. +       gr_dump_frame_start( Debug_dump_frame_num, DUMP_BUFFER_NUM_FRAMES );
  4884. +       dc_printf( "Frame dumping at 15 hz is now ON\n" );
  4885. +   } else {
  4886. +       // Turn it off
  4887. +       Debug_dump_frames = 0;
  4888. +       Debug_dump_trigger = 0;
  4889. +       gr_dump_frame_stop();
  4890. +       dc_printf( "Frame dumping is now OFF\n" );
  4891.     }
  4892.  }
  4893.  
  4894.  DCF(dump_frames_trigger, "Starts/stop frame dumping at 15 hz")
  4895.  {
  4896. -   if ( Dc_command )   {
  4897. -
  4898. -       if ( Debug_dump_frames == 0 )   {
  4899. -           // Turn it on
  4900. -           Debug_dump_frames = 15;
  4901. -           Debug_dump_trigger = 1;
  4902. -           gr_dump_frame_start( Debug_dump_frame_num, DUMP_BUFFER_NUM_FRAMES );
  4903. -           dc_printf( "Frame dumping at 15 hz is now ON\n" );
  4904. -       } else {
  4905. -           // Turn it off
  4906. -           Debug_dump_frames = 0;
  4907. -           Debug_dump_trigger = 0;
  4908. -           gr_dump_frame_stop();
  4909. -           dc_printf( "Frame dumping is now OFF\n" );
  4910. -       }
  4911. -      
  4912. +   if ( Debug_dump_frames == 0 )   {
  4913. +       // Turn it on
  4914. +       Debug_dump_frames = 15;
  4915. +       Debug_dump_trigger = 1;
  4916. +       gr_dump_frame_start( Debug_dump_frame_num, DUMP_BUFFER_NUM_FRAMES );
  4917. +       dc_printf( "Frame dumping at 15 hz is now ON\n" );
  4918. +   } else {
  4919. +       // Turn it off
  4920. +       Debug_dump_frames = 0;
  4921. +       Debug_dump_trigger = 0;
  4922. +       gr_dump_frame_stop();
  4923. +       dc_printf( "Frame dumping is now OFF\n" );
  4924.     }
  4925.  }
  4926.  
  4927.  DCF(dump_frames30, "Starts/stop frame dumping at 30 hz")
  4928.  {
  4929. -   if ( Dc_command )   {
  4930. -
  4931. -       if ( Debug_dump_frames == 0 )   {
  4932. -           // Turn it on
  4933. -           Debug_dump_frames = 30;
  4934. -           Debug_dump_trigger = 0;
  4935. -           gr_dump_frame_start( Debug_dump_frame_num, DUMP_BUFFER_NUM_FRAMES );
  4936. -           dc_printf( "Frame dumping at 30 hz is now ON\n" );
  4937. -       } else {
  4938. -           // Turn it off
  4939. -           Debug_dump_frames = 0;
  4940. -           Debug_dump_trigger = 0;
  4941. -           gr_dump_frame_stop();
  4942. -           dc_printf( "Frame dumping is now OFF\n" );
  4943. -       }
  4944. -      
  4945. +   if ( Debug_dump_frames == 0 )   {
  4946. +       // Turn it on
  4947. +       Debug_dump_frames = 30;
  4948. +       Debug_dump_trigger = 0;
  4949. +       gr_dump_frame_start( Debug_dump_frame_num, DUMP_BUFFER_NUM_FRAMES );
  4950. +       dc_printf( "Frame dumping at 30 hz is now ON\n" );
  4951. +   } else {
  4952. +       // Turn it off
  4953. +       Debug_dump_frames = 0;
  4954. +       Debug_dump_trigger = 0;
  4955. +       gr_dump_frame_stop();
  4956. +       dc_printf( "Frame dumping is now OFF\n" );
  4957.     }
  4958.  }
  4959.  
  4960.  DCF(dump_frames30_trigger, "Starts/stop frame dumping at 30 hz")
  4961.  {
  4962. -   if ( Dc_command )   {
  4963. -
  4964. -       if ( Debug_dump_frames == 0 )   {
  4965. -           // Turn it on
  4966. -           Debug_dump_frames = 30;
  4967. -           Debug_dump_trigger = 1;
  4968. -           gr_dump_frame_start( Debug_dump_frame_num, DUMP_BUFFER_NUM_FRAMES );
  4969. -           dc_printf( "Triggered frame dumping at 30 hz is now ON\n" );
  4970. -       } else {
  4971. -           // Turn it off
  4972. -           Debug_dump_frames = 0;
  4973. -           Debug_dump_trigger = 0;
  4974. -           gr_dump_frame_stop();
  4975. -           dc_printf( "Triggered frame dumping is now OFF\n" );
  4976. -       }
  4977. -      
  4978. +   if ( Debug_dump_frames == 0 )   {
  4979. +       // Turn it on
  4980. +       Debug_dump_frames = 30;
  4981. +       Debug_dump_trigger = 1;
  4982. +       gr_dump_frame_start( Debug_dump_frame_num, DUMP_BUFFER_NUM_FRAMES );
  4983. +       dc_printf( "Triggered frame dumping at 30 hz is now ON\n" );
  4984. +   } else {
  4985. +       // Turn it off
  4986. +       Debug_dump_frames = 0;
  4987. +       Debug_dump_trigger = 0;
  4988. +       gr_dump_frame_stop();
  4989. +       dc_printf( "Triggered frame dumping is now OFF\n" );
  4990.     }
  4991.  }
  4992.  
  4993. @@ -6921,7 +6996,7 @@
  4994.     BAIL();
  4995.  }
  4996.  
  4997. -DCF(pofspew, "")
  4998. +DCF(pofspew, "Spews POF info without shutting down the game")
  4999.  {
  5000.     game_spew_pof_info();
  5001.  }
  5002. Index: gamehelp/contexthelp.cpp
  5003. ===================================================================
  5004. --- gamehelp/contexthelp.cpp    (Revision 10462)
  5005. +++ gamehelp/contexthelp.cpp    (Arbeitskopie)
  5006. @@ -19,6 +19,7 @@
  5007.  #include "localization/localize.h"
  5008.  #include "globalincs/alphacolors.h"
  5009.  #include "globalincs/systemvars.h"
  5010. +#include "debugconsole/console.h"
  5011.  
  5012.  
  5013.  
  5014. @@ -556,20 +557,14 @@
  5015.  // --------------------------------------------------
  5016.  // DEBUGGING STUFF
  5017.  // --------------------------------------------------
  5018. -
  5019. +// z64: These DCF's really need a do-over.
  5020.  DCF(help_reload, "Reloads help overlay data from help.tbl")
  5021.  {
  5022. -   if (Dc_command) {
  5023. -       parse_helptbl();
  5024. -   }
  5025. -
  5026. -   if (Dc_help)    {
  5027. +   if (dc_optional_string_either("help", "--help")) {
  5028.         dc_printf( "Usage: sample\nCrashes your machine.\n" );
  5029.     }
  5030.  
  5031. -   if (Dc_status)  {
  5032. -       dc_printf( "Yes, my master." );
  5033. -   }
  5034. +   parse_helptbl();
  5035.  }
  5036.  
  5037.  int h_textnum=0, h_amt=0, h_vtx = 0;
  5038. @@ -630,150 +625,115 @@
  5039.  
  5040.  DCF(help_nudgetext_x, "Use to visually position overlay text.")
  5041.  {
  5042. -   if (Dc_command) {
  5043. -       dc_get_arg(ARG_INT);
  5044. -       if(Dc_arg_type & ARG_INT){
  5045. -            h_textnum = Dc_arg_int;       
  5046. -       }
  5047. -       dc_get_arg(ARG_INT);
  5048. -       if(Dc_arg_type & ARG_INT){
  5049. -            h_amt = Dc_arg_int;       
  5050. -       }
  5051. -       nudgetext_x(h_textnum, h_amt);
  5052. -   }
  5053.  
  5054. -   if (Dc_help)    {
  5055. +   if (dc_optional_string_either("help", "--help")) {
  5056.         dc_printf( "Usage: sample\nCrashes your machine.\n" );
  5057. +       return;
  5058.     }
  5059.  
  5060. -   if (Dc_status)  {
  5061. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  5062.         showtextpos(h_textnum);
  5063. +       return;
  5064.     }
  5065. +
  5066. +   dc_stuff_int(&h_textnum);
  5067. +   dc_stuff_int(&h_amt);
  5068. +
  5069. +   nudgetext_x(h_textnum, h_amt);
  5070.  }
  5071.  
  5072.  DCF(help_nudgetext_y, "Use to visually position overlay text.")
  5073.  {
  5074. -   if (Dc_command) {
  5075. -       dc_get_arg(ARG_INT);
  5076. -       if(Dc_arg_type & ARG_INT){
  5077. -            h_textnum = Dc_arg_int;       
  5078. -       }
  5079. -       dc_get_arg(ARG_INT);
  5080. -       if(Dc_arg_type & ARG_INT){
  5081. -            h_amt = Dc_arg_int;       
  5082. -       }
  5083. -       nudgetext_y(h_textnum, h_amt);
  5084. -   }
  5085. -
  5086. -   if (Dc_help)    {
  5087. +   if (dc_optional_string_either("help", "--help")) {
  5088.         dc_printf( "Usage: sample\nCrashes your machine.\n" );
  5089. +       return;
  5090.     }
  5091.  
  5092. -   if (Dc_status)  {
  5093. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  5094.         showtextpos(h_textnum);
  5095. +       return;
  5096.     }
  5097. +
  5098. +   dc_stuff_int(&h_textnum);
  5099. +   dc_stuff_int(&h_amt);
  5100. +  
  5101. +   nudgetext_y(h_textnum, h_amt);
  5102.  }
  5103.  
  5104.  DCF(help_nudgepline_x, "Use to visually position overlay polylines.")
  5105.  {
  5106. -   if (Dc_command) {
  5107. -       dc_get_arg(ARG_INT);
  5108. -       if(Dc_arg_type & ARG_INT){
  5109. -            h_textnum = Dc_arg_int;       
  5110. -       }
  5111. -       dc_get_arg(ARG_INT);
  5112. -       if(Dc_arg_type & ARG_INT){
  5113. -            h_vtx = Dc_arg_int;       
  5114. -       }
  5115. -       dc_get_arg(ARG_INT);
  5116. -       if(Dc_arg_type & ARG_INT){
  5117. -            h_amt = Dc_arg_int;       
  5118. -       }
  5119. -       nudgepline_x(h_textnum, h_vtx, h_amt);
  5120. -   }
  5121. -
  5122. -   if (Dc_help)    {
  5123. +       if (dc_optional_string_either("help", "--help")) {
  5124.         dc_printf( "Usage: help_nudgepline [pline_number] [vertex_number] [distance]\n" );
  5125. +       return;
  5126.     }
  5127.  
  5128. -   if (Dc_status)  {
  5129. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?"))   {
  5130.         showplinepos(h_textnum);
  5131. +       return;
  5132.     }
  5133. +
  5134. +   dc_stuff_int(&h_textnum);
  5135. +   dc_stuff_int(&h_vtx);
  5136. +   dc_stuff_int(&h_amt);
  5137. +
  5138. +   nudgepline_x(h_textnum, h_vtx, h_amt);
  5139.  }
  5140.  
  5141.  
  5142.  DCF(help_nudgepline_y, "Use to visually position overlay polylines.")
  5143.  {
  5144. -   if (Dc_command) {
  5145. -       dc_get_arg(ARG_INT);
  5146. -       if(Dc_arg_type & ARG_INT){
  5147. -            h_textnum = Dc_arg_int;       
  5148. -       }
  5149. -       dc_get_arg(ARG_INT);
  5150. -       if(Dc_arg_type & ARG_INT){
  5151. -            h_vtx = Dc_arg_int;       
  5152. -       }
  5153. -       dc_get_arg(ARG_INT);
  5154. -       if(Dc_arg_type & ARG_INT){
  5155. -            h_amt = Dc_arg_int;       
  5156. -       }
  5157. -       nudgepline_y(h_textnum, h_vtx, h_amt);
  5158. -   }
  5159. -
  5160. -   if (Dc_help)    {
  5161. +   if (dc_optional_string_either("help", "--help")) {
  5162.         dc_printf( "Usage: help_nudgepline [pline_number] [vertex_number] [distance]\n" );
  5163. +       return;
  5164.     }
  5165.  
  5166. -   if (Dc_status)  {
  5167. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?"))   {
  5168.         showplinepos(h_textnum);
  5169. +       return;
  5170.     }
  5171. +
  5172. +   dc_stuff_int(&h_textnum);
  5173. +   dc_stuff_int(&h_vtx);
  5174. +   dc_stuff_int(&h_amt);
  5175. +
  5176. +   nudgepline_y(h_textnum, h_vtx, h_amt);
  5177.  }
  5178.  
  5179.  
  5180.  DCF(help_nudgerbracket_x, "Use to visually position overlay right bracket.")
  5181.  {
  5182. -   if (Dc_command) {
  5183. -       dc_get_arg(ARG_INT);
  5184. -       if(Dc_arg_type & ARG_INT){
  5185. -            h_textnum = Dc_arg_int;       
  5186. -       }
  5187. -       dc_get_arg(ARG_INT);
  5188. -       if(Dc_arg_type & ARG_INT){
  5189. -            h_amt = Dc_arg_int;       
  5190. -       }
  5191. -       nudgerbracket_x(h_textnum, h_amt);
  5192. -   }
  5193. -
  5194. -   if (Dc_help)    {
  5195. +   if (dc_optional_string_either("help", "--help")) {
  5196.         dc_printf( "Usage: help_nudgerbracket_x [num] [amount]\n" );
  5197. +       return;
  5198.     }
  5199.  
  5200. -   if (Dc_status)  {
  5201. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?"))   {
  5202.         showrbracketpos(h_textnum);
  5203. +       return;
  5204.     }
  5205. +
  5206. +   dc_stuff_int(&h_textnum);
  5207. +   dc_stuff_int(&h_amt);
  5208. +
  5209. +   nudgerbracket_x(h_textnum, h_amt);
  5210.  }
  5211.  
  5212.  DCF(help_nudgerbracket_y, "Use to visually position overlay right bracket.")
  5213.  {
  5214. -   if (Dc_command) {
  5215. -       dc_get_arg(ARG_INT);
  5216. -       if(Dc_arg_type & ARG_INT){
  5217. -            h_textnum = Dc_arg_int;       
  5218. -       }
  5219. -       dc_get_arg(ARG_INT);
  5220. -       if(Dc_arg_type & ARG_INT){
  5221. -            h_amt = Dc_arg_int;       
  5222. -       }
  5223. -       nudgerbracket_y(h_textnum, h_amt);
  5224. -   }
  5225. -
  5226. -   if (Dc_help)    {
  5227. +   if (dc_optional_string_either("help", "--help")) {
  5228.         dc_printf( "Usage: help_nudgerbracket_y [num] [amount]\n" );
  5229. +       return;
  5230.     }
  5231.  
  5232. -   if (Dc_status)  {
  5233. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?"))   {
  5234.         showrbracketpos(h_textnum);
  5235. +       return;
  5236.     }
  5237. +
  5238. +   dc_stuff_int(&h_textnum);
  5239. +   dc_stuff_int(&h_amt);
  5240. +  
  5241. +   nudgerbracket_y(h_textnum, h_amt);
  5242.  }
  5243.  
  5244.  
  5245. @@ -781,46 +741,37 @@
  5246.  
  5247.  DCF(help_nudgelbracket_x, "Use to visually position overlay left bracket.")
  5248.  {
  5249. -   if (Dc_command) {
  5250. -       dc_get_arg(ARG_INT);
  5251. -       if(Dc_arg_type & ARG_INT){
  5252. -            h_textnum = Dc_arg_int;       
  5253. -       }
  5254. -       dc_get_arg(ARG_INT);
  5255. -       if(Dc_arg_type & ARG_INT){
  5256. -            h_amt = Dc_arg_int;       
  5257. -       }
  5258. -       nudgelbracket_x(h_textnum, h_amt);
  5259. -   }
  5260.  
  5261. -   if (Dc_help)    {
  5262. +   if (dc_optional_string_either("help", "--help")) {
  5263.         dc_printf( "Usage: help_nudgelbracket_x [num] [amount]\n" );
  5264. +       return;
  5265.     }
  5266.  
  5267. -   if (Dc_status)  {
  5268. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  5269.         showlbracketpos(h_textnum);
  5270. +       return;
  5271.     }
  5272. +
  5273. +   dc_stuff_int(&h_textnum);
  5274. +   dc_stuff_int(&h_amt);
  5275. +
  5276. +   nudgelbracket_x(h_textnum, h_amt);
  5277.  }
  5278.  
  5279.  DCF(help_nudgelbracket_y, "Use to visually position overlay left bracket.")
  5280.  {
  5281. -   if (Dc_command) {
  5282. -       dc_get_arg(ARG_INT);
  5283. -       if(Dc_arg_type & ARG_INT){
  5284. -            h_textnum = Dc_arg_int;       
  5285. -       }
  5286. -       dc_get_arg(ARG_INT);
  5287. -       if(Dc_arg_type & ARG_INT){
  5288. -            h_amt = Dc_arg_int;       
  5289. -       }
  5290. -       nudgelbracket_y(h_textnum, h_amt);
  5291. -   }
  5292. -
  5293. -   if (Dc_help)    {
  5294. +   if (dc_optional_string_either("help", "--help")) {
  5295.         dc_printf( "Usage: help_nudgelbracket_y [num] [amount]\n" );
  5296. +       return;
  5297.     }
  5298.  
  5299. -   if (Dc_status)  {
  5300. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?"))   {
  5301.         showlbracketpos(h_textnum);
  5302. +       return;
  5303.     }
  5304. +
  5305. +   dc_stuff_int(&h_textnum);
  5306. +   dc_stuff_int(&h_amt);
  5307. +
  5308. +   nudgelbracket_y(h_textnum, h_amt);
  5309.  }
  5310. Index: globalincs/pstypes.h
  5311. ===================================================================
  5312. --- globalincs/pstypes.h    (Revision 10462)
  5313. +++ globalincs/pstypes.h    (Arbeitskopie)
  5314. @@ -319,115 +319,8 @@
  5315.  
  5316.  
  5317.  //======================================================================================
  5318. -//======          D E B U G    C O N S O L E   S T U F F        ========================
  5319.  //======================================================================================
  5320. -
  5321. -// Here is a a sample command to toggle something that would
  5322. -// be called by doing "toggle it" from the debug console command window/
  5323. -
  5324. -/*
  5325. -DCF(toggle_it,"description")
  5326. -{
  5327. -   if (Dc_command) {
  5328. -       This_var = !This_var;
  5329. -   }
  5330. -
  5331. -   if (Dc_help) {
  5332. -       dc_printf( "Usage: sample\nToggles This_var on/off.\n" );
  5333. -   }
  5334. -
  5335. -   if (Dc_status) {
  5336. -       dc_printf( "The status is %d.\n", This_var );
  5337. -   }
  5338. -*/
  5339. -
  5340. -class debug_command {
  5341. -   public:
  5342. -   char *name;
  5343. -   char *help;
  5344. -   void (*func)();
  5345. -   debug_command(char *name,char *help,void (*func)());    // constructor
  5346. -};
  5347. -
  5348. -#define DCF(function_name,help_text)   \
  5349. -       void dcf_##function_name(); \
  5350. -       debug_command dc_##function_name(#function_name,help_text,dcf_##function_name); \
  5351. -       void dcf_##function_name()
  5352. -
  5353. -// Starts the debug console
  5354. -extern void debug_console( void (*func)() = NULL );
  5355. -
  5356. -// The next three variables tell your function what to do.  It should
  5357. -// only change something if the dc_command is set.   A minimal function
  5358. -// needs to process the dc_command.   Usually, these will be called in
  5359. -// these combinations:
  5360. -// dc_command=true, dc_status=true  means process it and show status
  5361. -// dc_help=true means show help only
  5362. -// dc_status=true means show status only
  5363. -// I would recommend doing this in each function:
  5364. -// if (dc_command) { process command }
  5365. -// if (dc_help) { print out help }
  5366. -// if (dc_status) { print out status }
  5367. -// with the last two being optional
  5368. -
  5369. -extern int Dc_command;         // If this is set, then process the command
  5370. -extern int Dc_help;                // If this is set, then print out the help text in the form, "usage: ... \nLong description\n" );
  5371. -extern int Dc_status;          // If this is set, then print out the current status of the command.
  5372. -
  5373. -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.
  5374. -extern char *Dc_arg;           // The (lowercased) string value of the argument retrieved from dc_arg
  5375. -extern char *Dc_arg_org;       // Dc_arg before it got converted to lowercase
  5376. -extern uint Dc_arg_type;       // The type of dc_arg.
  5377. -extern char *Dc_command_line;  // The rest of the command line, from the end of the last processed arg on.
  5378. -extern int Dc_arg_int;         // If Dc_arg_type & ARG_INT or ARG_HEX is set, then this is the value
  5379. -extern ubyte Dc_arg_ubyte;     // If Dc_arg_type & ARG_UBYTE is set, then this is the value
  5380. -extern float Dc_arg_float;     // If Dc_arg_type & ARG_FLOAT is set, then this is the value
  5381. -
  5382. -// Outputs text to the console
  5383. -void dc_printf( char *format, ... );
  5384. -
  5385. -// Each dc_arg_type can have one or more of these flags set.
  5386. -// This is because some things can fit into two categories.
  5387. -// Like 1 can be an integer, a float, a string, or a true boolean
  5388. -// value.
  5389. -#define ARG_NONE       (1<<0)      // no argument
  5390. -#define ARG_ANY            0xFFFFFFFF  // Anything.
  5391. -#define ARG_STRING     (1<<1)      // any valid string
  5392. -#define ARG_QUOTE      (1<<2)      // a quoted string
  5393. -#define ARG_INT            (1<<3)      // a valid integer
  5394. -#define ARG_FLOAT      (1<<4)      // a valid floating point number
  5395. -
  5396. -// some specific commonly used predefined types. Can add up to (1<<31)
  5397. -#define ARG_HEX            (1<<5)      // a valid hexadecimal integer. Note that ARG_INT will always be set also in this case.
  5398. -#define ARG_TRUE       (1<<6)      // on, true, non-zero number
  5399. -#define ARG_FALSE      (1<<7)      // off, false, zero
  5400. -#define ARG_PLUS       (1<<8)      // Plus sign
  5401. -#define ARG_MINUS      (1<<9)      // Minus sign
  5402. -#define ARG_COMMA      (1<<10)     // a comma
  5403. -#define ARG_UBYTE      (1<<11)     // a valid ubyte
  5404. -
  5405. -// A shortcut for boolean only variables.
  5406. -// Example:  
  5407. -// DCF_BOOL( lighting, Show_lighting )
  5408. -//
  5409. -#define DCF_BOOL( function_name, bool_variable )   \
  5410. -   void dcf_##function_name(); \
  5411. -   debug_command dc_##function_name(#function_name,"Toggles "#bool_variable,dcf_##function_name ); \
  5412. -   void dcf_##function_name()  {   \
  5413. -   if ( Dc_command )   {   \
  5414. -       dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);        \
  5415. -       if ( Dc_arg_type & ARG_TRUE )   bool_variable = 1;  \
  5416. -       else if ( Dc_arg_type & ARG_FALSE ) bool_variable = 0;  \
  5417. -       else if ( Dc_arg_type & ARG_NONE ) bool_variable ^= 1;  \
  5418. -   }   \
  5419. -   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 );  \
  5420. -   if ( Dc_status )    dc_printf( "%s is %s\n", #function_name, (bool_variable?"TRUE":"FALSE") );  \
  5421. -}
  5422. -
  5423. -
  5424.  //======================================================================================
  5425. -//======================================================================================
  5426. -//======================================================================================
  5427.  
  5428.  
  5429.  #include "math/fix.h"
  5430. Index: globalincs/systemvars.cpp
  5431. ===================================================================
  5432. --- globalincs/systemvars.cpp   (Revision 10462)
  5433. +++ globalincs/systemvars.cpp   (Arbeitskopie)
  5434. @@ -8,7 +8,7 @@
  5435.  */
  5436.  
  5437.  
  5438. -
  5439. +#include "debugconsole/console.h"
  5440.  #include "globalincs/pstypes.h"
  5441.  #include "globalincs/systemvars.h"
  5442.  #include "io/timer.h"
  5443. @@ -248,73 +248,76 @@
  5444.  char Monitor_filename[128];
  5445.  fix monitor_last_time = -1;
  5446.  
  5447. -DCF(monitor,"Monitors game performace")
  5448. +DCF(monitor,"Monitors game performace by saving to file")
  5449.  {
  5450. -   if ( Dc_command )   {
  5451. -       dc_get_arg(ARG_STRING|ARG_NONE);
  5452. -       if ( Dc_arg_type == ARG_NONE )  {
  5453. -           if ( Monitor_inited )   {
  5454. -               Monitor_inited = 0;
  5455. +   SCP_string filename;
  5456.  
  5457. -/*
  5458. -               FILE *fp = fopen( Monitor_filename, "at" );
  5459. -               if ( fp )   {
  5460. -                   fprintf( fp, "\n\n" );
  5461. -                   fprintf( fp, "Name\tMin\tMax\tAvg\n" );
  5462. -                   for (int i=0; i<Num_monitors; i++ ) {
  5463. -                       if ( Monitor[i]->cnt > 0 )  {
  5464. -                           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  );
  5465. -                       } else {
  5466. -                           fprintf( fp, "%s\t%d\t%d\t?\n", Monitor[i]->name, Monitor[i]->min, Monitor[i]->max );
  5467. -                       }
  5468. -                   }
  5469. -                   fclose(fp);
  5470. -               }
  5471. -*/
  5472. +   if (dc_optional_string_either("help", "--help")) {
  5473. +       dc_printf("Usage: monitor [filename]\n");
  5474. +       dc_printf("Outputs monitoring info to [filename]. No filename turns it off\n" );
  5475. +       return;
  5476. +   }
  5477.  
  5478. -               dc_printf( "Monitor to file '%s' turned off\n", Monitor_filename );
  5479. -           } else {
  5480. -               dc_printf( "Monitor isn't on\n" );
  5481. -           }
  5482. +   if (dc_maybe_stuff_string_white(filename)) {
  5483. +       if ( Monitor_inited )   {
  5484. +               dc_printf( "Monitor already on\n" );
  5485.         } else {
  5486. -           if ( Monitor_inited )   {
  5487. -               dc_printf( "Monitor already on\n" );
  5488. -           } else {
  5489. -               Monitor_inited = 1;
  5490. +           Monitor_inited = 1;
  5491.  
  5492. -               strcpy_s( Monitor_filename, Dc_arg );
  5493. +           strcpy(Monitor_filename, filename.c_str());
  5494.  
  5495. -               // Reset them all
  5496. -               int i;
  5497. +           // Reset them all
  5498. +           int i;
  5499. +           for (i=0; i<Num_monitors; i++ ) {
  5500. +               Monitor[i]->value = 0;
  5501. +               Monitor[i]->sum = 0;
  5502. +               Monitor[i]->cnt = 0;
  5503. +               Monitor[i]->min = 0;
  5504. +               Monitor[i]->max = 0;
  5505. +           }
  5506. +
  5507. +           FILE *fp = fopen( Monitor_filename, "wt" );
  5508. +           if ( fp )   {
  5509.                 for (i=0; i<Num_monitors; i++ ) {
  5510. -                   Monitor[i]->value = 0;
  5511. -                   Monitor[i]->sum = 0;
  5512. -                   Monitor[i]->cnt = 0;
  5513. -                   Monitor[i]->min = 0;
  5514. -                   Monitor[i]->max = 0;
  5515. +                   if ( i > 0 )    {
  5516. +                       fprintf( fp, "\t" );
  5517. +                   }
  5518. +                   fprintf( fp, "%s", Monitor[i]->name );
  5519. +
  5520.                 }
  5521. +               fprintf( fp, "\n" );
  5522. +               fclose(fp);
  5523. +           }
  5524. +           dc_printf( "Monitor outputting to file '%s'\n", Monitor_filename );
  5525. +           monitor_last_time = -1;
  5526. +       }
  5527.  
  5528. -               FILE *fp = fopen( Monitor_filename, "wt" );
  5529. -               if ( fp )   {
  5530. -                   for (i=0; i<Num_monitors; i++ ) {
  5531. -                       if ( i > 0 )    {
  5532. -                           fprintf( fp, "\t" );
  5533. -                       }
  5534. -                       fprintf( fp, "%s", Monitor[i]->name );
  5535. -                  
  5536. +   } else {
  5537. +       // Turn off monitoring
  5538. +       if ( Monitor_inited )   {
  5539. +           Monitor_inited = 0;
  5540. +
  5541. +/*
  5542. +           FILE *fp = fopen( Monitor_filename, "at" );
  5543. +           if ( fp )   {
  5544. +               fprintf( fp, "\n\n" );
  5545. +               fprintf( fp, "Name\tMin\tMax\tAvg\n" );
  5546. +               for (int i=0; i<Num_monitors; i++ ) {
  5547. +                   if ( Monitor[i]->cnt > 0 )  {
  5548. +                       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  );
  5549. +                   } else {
  5550. +                       fprintf( fp, "%s\t%d\t%d\t?\n", Monitor[i]->name, Monitor[i]->min, Monitor[i]->max );
  5551.                     }
  5552. -                   fprintf( fp, "\n" );
  5553. -                   fclose(fp);
  5554.                 }
  5555. -               dc_printf( "Monitor outputting to file '%s'\n", Monitor_filename );
  5556. -               monitor_last_time = -1;
  5557. +               fclose(fp);
  5558.             }
  5559. +*/
  5560. +
  5561. +           dc_printf( "Monitor to file '%s' turned off\n", Monitor_filename );
  5562. +       } else {
  5563. +           dc_printf( "Monitor isn't on\n" );
  5564.         }
  5565.     }
  5566. -   if ( Dc_help )  {
  5567. -       dc_printf( "Usage: monitor filename\nOutputs monitoring info to filename. No filename turns it off\n" );
  5568. -   }
  5569. -  
  5570.  }
  5571.  
  5572.  
  5573. @@ -508,44 +511,41 @@
  5574.  #ifndef NDEBUG
  5575.  DCF(detail_level,"Change the detail level")
  5576.  {
  5577. -   if ( Dc_command )   {
  5578. -       dc_get_arg(ARG_INT|ARG_NONE);
  5579. -       if ( Dc_arg_type & ARG_NONE )   {
  5580. -           Game_detail_level = 0;
  5581. -           dc_printf( "Detail level reset\n" );
  5582. -       }
  5583. -       if ( Dc_arg_type & ARG_INT )    {
  5584. -           Game_detail_level = Dc_arg_int;
  5585. -       }
  5586. +   int value;
  5587. +
  5588. +   if (dc_optional_string_either("help", "--help")) {
  5589. +       dc_printf( "Usage: detail_level [n]\n");
  5590. +       dc_printf("[n]  -- is detail level.\n");
  5591. +           dc_printf("\t0 is 'normal' detail,\n");
  5592. +           dc_printf("\tnegative values are lower, and\n");
  5593. +           dc_printf("\tpositive values are higher.\n\n");
  5594. +      
  5595. +       dc_printf("No parameter resets it to default.\n");
  5596. +       return;
  5597.     }
  5598.  
  5599. -   if ( Dc_help ) 
  5600. -       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" );
  5601. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  5602. +       dc_printf("Detail level set to %d\n", Game_detail_level);
  5603. +       return;
  5604. +   }
  5605.  
  5606. -   if ( Dc_status )               
  5607. -       dc_printf("Detail level set to %d\n", Game_detail_level);
  5608. +   if (dc_maybe_stuff_int(&value)) {
  5609. +       Game_detail_level = value;
  5610. +       dc_printf("Detail level set to %i\n", Game_detail_level);
  5611. +
  5612. +   } else {
  5613. +       Game_detail_level = 0;
  5614. +       dc_printf("Detail level reset\n");
  5615. +   }
  5616.  }
  5617.  
  5618.  DCF(detail, "Turns on/off parts of the game for speed testing" )
  5619.  {
  5620. -   if ( Dc_command )   {
  5621. -       dc_get_arg(ARG_INT|ARG_NONE);
  5622. -       if ( Dc_arg_type & ARG_NONE )   {
  5623. -           if ( Game_detail_flags == DETAIL_DEFAULT )  {
  5624. -               Game_detail_flags = DETAIL_FLAG_CLEAR;
  5625. -               dc_printf( "Detail flags set lowest (except has screen clear)\n" );
  5626. -           } else {
  5627. -               Game_detail_flags = DETAIL_DEFAULT;
  5628. -               dc_printf( "Detail flags set highest\n" );
  5629. -           }
  5630. -       }
  5631. -       if ( Dc_arg_type & ARG_INT )    {
  5632. -           Game_detail_flags ^= Dc_arg_int;
  5633. -       }
  5634. -   }
  5635. +   int value;
  5636.  
  5637. -   if ( Dc_help )  {
  5638. -       dc_printf( "Usage: detail [n]\nn is detail bit to toggle.\n" );
  5639. +   if (dc_optional_string_either("help", "--help")) {
  5640. +       dc_printf( "Usage: detail [n]\n");
  5641. +       dc_printf("[n] is detail bit to toggle:\n" );
  5642.         dc_printf( "   1: draw the stars\n" );
  5643.         dc_printf( "   2: draw the nebulas\n" );
  5644.         dc_printf( "   4: draw the motion debris\n" );
  5645. @@ -555,22 +555,39 @@
  5646.         dc_printf( "  64: clear screen background after each frame\n" );
  5647.         dc_printf( " 128: draw hud stuff\n" );
  5648.         dc_printf( " 256: draw fireballs\n" );
  5649. -       dc_printf( " 512: do collision detection\n" );
  5650. +       dc_printf( " 512: do collision detection\n\n" );
  5651. +
  5652. +       dc_printf("No argument will toggle between highest/lowest detail settings\n");
  5653. +       return;
  5654.     }
  5655.  
  5656. -   if ( Dc_status )    {
  5657. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  5658.         dc_printf("Detail flags set to 0x%08x\n", Game_detail_flags);
  5659. -       dc_printf( "   1: draw the stars: %s\n", (Game_detail_flags&1?"on":"off") );
  5660. -       dc_printf( "   2: draw the nebulas: %s\n", (Game_detail_flags&2?"on":"off") );
  5661. -       dc_printf( "   4: draw the motion debris: %s\n", (Game_detail_flags&4?"on":"off")  );
  5662. -       dc_printf( "   8: draw planets: %s\n", (Game_detail_flags&8?"on":"off")  );
  5663. -       dc_printf( "  16: draw models not as blobs: %s\n", (Game_detail_flags&16?"on":"off")  );
  5664. -       dc_printf( "  32: draw lasers not as pixels: %s\n", (Game_detail_flags&32?"on":"off")  );
  5665. -       dc_printf( "  64: clear screen background after each frame: %s\n", (Game_detail_flags&64?"on":"off")  );
  5666. -       dc_printf( " 128: draw hud stuff: %s\n", (Game_detail_flags&128?"on":"off")  );
  5667. -       dc_printf( " 256: draw fireballs: %s\n", (Game_detail_flags&256?"on":"off")  );
  5668. -       dc_printf( " 512: do collision detection: %s\n", (Game_detail_flags&512?"on":"off")  );
  5669. +       dc_printf( "   1: draw the stars: %s\n", ((Game_detail_flags & 1) ? "on" : "off"));
  5670. +       dc_printf( "   2: draw the nebulas: %s\n", ((Game_detail_flags & 2)?"on" : "off"));
  5671. +       dc_printf( "   4: draw the motion debris: %s\n", ((Game_detail_flags & 4) ? "on" : "off"));
  5672. +       dc_printf( "   8: draw planets: %s\n", ((Game_detail_flags & 8) ? "on" : "off"));
  5673. +       dc_printf( "  16: draw models not as blobs: %s\n", ((Game_detail_flags & 16) ? "on" : "off"));
  5674. +       dc_printf( "  32: draw lasers not as pixels: %s\n", ((Game_detail_flags & 32) ? "on" : "off"));
  5675. +       dc_printf( "  64: clear screen background after each frame: %s\n", ((Game_detail_flags & 64) ? "on" : "off"));
  5676. +       dc_printf( " 128: draw hud stuff: %s\n", ((Game_detail_flags & 128) ? "on" : "off"));
  5677. +       dc_printf( " 256: draw fireballs: %s\n", ((Game_detail_flags & 256) ? "on" : "off"));
  5678. +       dc_printf( " 512: do collision detection: %s\n", ((Game_detail_flags & 512) ? "on" : "off"));
  5679. +       return;
  5680.     }
  5681. +
  5682. +   if (dc_maybe_stuff_int(&value)) {
  5683. +       Game_detail_flags ^= value;
  5684. +  
  5685. +   } else {
  5686. +       if (Game_detail_flags == DETAIL_DEFAULT) {
  5687. +           Game_detail_flags = DETAIL_FLAG_CLEAR;
  5688. +           dc_printf( "Detail flags set lowest (except has screen clear)\n" );
  5689. +       } else {
  5690. +           Game_detail_flags = DETAIL_DEFAULT;
  5691. +           dc_printf( "Detail flags set highest\n" );
  5692. +       }
  5693. +   }
  5694.  }
  5695.  #endif
  5696.  
  5697. Index: globalincs/vmallocator.h
  5698. ===================================================================
  5699. --- globalincs/vmallocator.h    (Revision 10462)
  5700. +++ globalincs/vmallocator.h    (Arbeitskopie)
  5701. @@ -8,6 +8,7 @@
  5702.  #include <map>
  5703.  #include <string>
  5704.  #include <queue>
  5705. +#include <deque>
  5706.  
  5707.  #if defined __GNUC__
  5708.  #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
  5709. @@ -127,6 +128,9 @@
  5710.  template< typename T >
  5711.  class SCP_queue : public std::queue< T, std::deque< T, SCP_vm_allocator< T > > > { };
  5712.  
  5713. +template< typename T >
  5714. +class SCP_deque : public std::deque< T, SCP_vm_allocator< T > > { };
  5715. +
  5716.  template <class T1, class T2>
  5717.  bool operator==(const SCP_vm_allocator<T1>&, const SCP_vm_allocator<T2>&) throw()
  5718.  {
  5719. Index: globalincs/windebug.cpp
  5720. ===================================================================
  5721. --- globalincs/windebug.cpp (Revision 10462)
  5722. +++ globalincs/windebug.cpp (Arbeitskopie)
  5723. @@ -33,6 +33,7 @@
  5724.  #include "cmdline/cmdline.h"
  5725.  #include "parse/lua.h"
  5726.  #include "parse/parselo.h"
  5727. +#include "debugconsole/console.h"
  5728.  
  5729.  #if defined( SHOW_CALL_STACK ) && defined( PDB_DEBUGGING )
  5730.  #  include "globalincs/mspdb_callstack.h"
  5731. @@ -1522,7 +1523,7 @@
  5732.  #endif
  5733.  
  5734.  int Watch_malloc = 0;
  5735. -DCF_BOOL(watch_malloc, Watch_malloc )
  5736. +DCF_BOOL(watch_malloc, Watch_malloc );
  5737.  
  5738.  // Returns 0 if not enough RAM.
  5739.  int vm_init(int min_heap_size)
  5740. Index: graphics/2d.cpp
  5741. ===================================================================
  5742. --- graphics/2d.cpp (Revision 10462)
  5743. +++ graphics/2d.cpp (Arbeitskopie)
  5744. @@ -31,6 +31,7 @@
  5745.  #include "parse/scripting.h"
  5746.  #include "gamesequence/gamesequence.h" //WMC - for scripting hooks in gr_flip()
  5747.  #include "io/keycontrol.h" // m!m
  5748. +#include "debugconsole/console.h"
  5749.  
  5750.  
  5751.  #if defined(SCP_UNIX) && !defined(__APPLE__)
  5752. @@ -266,12 +267,9 @@
  5753.  {
  5754.     ubyte r, g, b;
  5755.  
  5756. -   dc_get_arg(ARG_UBYTE);
  5757. -   r = Dc_arg_ubyte;
  5758. -   dc_get_arg(ARG_UBYTE);
  5759. -   g = Dc_arg_ubyte;
  5760. -   dc_get_arg(ARG_UBYTE);
  5761. -   b = Dc_arg_ubyte;
  5762. +   dc_stuff_ubyte(&r);
  5763. +   dc_stuff_ubyte(&g);
  5764. +   dc_stuff_ubyte(&b);
  5765.  
  5766.     // set the color
  5767.     gr_set_clear_color(r, g, b);
  5768. Index: graphics/gropengl.cpp
  5769. ===================================================================
  5770. --- graphics/gropengl.cpp   (Revision 10462)
  5771. +++ graphics/gropengl.cpp   (Arbeitskopie)
  5772. @@ -22,6 +22,7 @@
  5773.  #include "io/timer.h"
  5774.  #include "ddsutils/ddsutils.h"
  5775.  #include "model/model.h"
  5776. +#include "debugconsole/console.h"
  5777.  #include "debugconsole/timerbar.h"
  5778.  #include "graphics/gropenglbmpman.h"
  5779.  #include "graphics/gropengllight.h"
  5780. @@ -2078,56 +2079,61 @@
  5781.  
  5782.  DCF(ogl_minimize, "Minimizes opengl")
  5783.  {
  5784. +   bool minimize_ogl = false;
  5785. +
  5786.     if ( gr_screen.mode != GR_OPENGL ) {
  5787.         dc_printf("Command only available in OpenGL mode.\n");
  5788.         return;
  5789.     }
  5790.  
  5791. -   if (Dc_command) {
  5792. -       dc_get_arg(ARG_TRUE);
  5793. +   if (dc_optional_string_either("help", "--help")) {
  5794. +       dc_printf("[bool] If true is passed, then the OpenGL window will minimize.\n");
  5795. +       return;
  5796. +   }
  5797. +   dc_stuff_boolean(&minimize_ogl);
  5798.  
  5799. -       if ( Dc_arg_type & ARG_TRUE ) {
  5800. -           opengl_minimize();
  5801. -       }
  5802. +   if (minimize_ogl) {
  5803. +       opengl_minimize();
  5804.     }
  5805. -
  5806. -   if (Dc_help)
  5807. -       dc_printf("If set to true then the OpenGL window will minimize.\n");
  5808.  }
  5809.  
  5810.  DCF(ogl_anisotropy, "toggles anisotropic filtering")
  5811.  {
  5812. +   bool process = true;
  5813. +   int value;
  5814. +
  5815.     if ( gr_screen.mode != GR_OPENGL ) {
  5816.         dc_printf("Can only set anisotropic filter in OpenGL mode.\n");
  5817.         return;
  5818.     }
  5819.  
  5820. -   if ( Dc_command && !Is_Extension_Enabled(OGL_EXT_TEXTURE_FILTER_ANISOTROPIC) ) {
  5821. +   if (dc_optional_string_either("help", "--help")) {
  5822. +       dc_printf("Sets OpenGL anisotropic filtering level.\n");
  5823. +       dc_printf("GL_anisotropy [int]  Valid values are 0 to %i. 0 turns off anisotropic filtering.\n", (int)opengl_get_max_anisotropy());
  5824. +       process = false;
  5825. +   }
  5826. +
  5827. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  5828. +       dc_printf("Current anisotropic filter value is %i\n", (int)GL_anisotropy);
  5829. +       process = false;
  5830. +   }
  5831. +
  5832. +   if (!process) {
  5833. +       return;
  5834. +   }
  5835. +
  5836. +   if ( !Is_Extension_Enabled(OGL_EXT_TEXTURE_FILTER_ANISOTROPIC) ) {
  5837.         dc_printf("Error: Anisotropic filter is not settable!\n");
  5838.         return;
  5839.     }
  5840.  
  5841. -   if ( Dc_command ) {
  5842. -       dc_get_arg(ARG_INT | ARG_NONE);
  5843. -
  5844. -       if ( Dc_arg_type & ARG_NONE ) {
  5845. +   if (!dc_maybe_stuff_int(&value)) {
  5846. +       // No arg passed, set to default
  5847.             GL_anisotropy = 1.0f;
  5848.         //  opengl_set_anisotropy();
  5849.             dc_printf("Anisotropic filter value reset to default level.\n");
  5850. -       }
  5851. -
  5852. -       if ( Dc_arg_type & ARG_INT ) {
  5853. -           GL_anisotropy = (GLfloat)Dc_arg_float;
  5854. +   } else {
  5855. +       GL_anisotropy = (GLfloat)value;
  5856.         //  opengl_set_anisotropy( (float)Dc_arg_float );
  5857. -       }
  5858.     }
  5859. -
  5860. -   if ( Dc_status ) {
  5861. -       dc_printf("Current anisotropic filter value is %i\n", (int)GL_anisotropy);
  5862. -   }
  5863. -
  5864. -   if (Dc_help) {
  5865. -       dc_printf("Sets OpenGL anisotropic filtering level.\n");
  5866. -       dc_printf("Valid values are 1 to %i, or 0 to turn off.\n", (int)opengl_get_max_anisotropy());
  5867. -   }
  5868.  }
  5869. Index: hud/hudlock.cpp
  5870. ===================================================================
  5871. --- hud/hudlock.cpp (Revision 10462)
  5872. +++ hud/hudlock.cpp (Arbeitskopie)
  5873. @@ -26,6 +26,7 @@
  5874.  #include "mission/missionparse.h"
  5875.  #include "iff_defs/iff_defs.h"
  5876.  #include "network/multi.h"
  5877. +#include "debugconsole/console.h"
  5878.  
  5879.  
  5880.  vec3d lock_world_pos;
  5881. @@ -333,7 +334,7 @@
  5882.  }
  5883.  
  5884.  int Nebula_sec_range = 0;
  5885. -DCF_BOOL(nebula_sec_range, Nebula_sec_range)
  5886. +DCF_BOOL(nebula_sec_range, Nebula_sec_range);
  5887.  
  5888.  int hud_lock_world_pos_in_range(vec3d *target_world_pos, vec3d *vec_to_target)
  5889.  {
  5890. Index: io/joy.cpp
  5891. ===================================================================
  5892. --- io/joy.cpp  (Revision 10462)
  5893. +++ io/joy.cpp  (Arbeitskopie)
  5894. @@ -21,6 +21,7 @@
  5895.  #include "io/joy_ff.h"
  5896.  #include "directx/vdinput.h"
  5897.  #include "osapi/osapi.h"
  5898. +#include "debugconsole/console.h"
  5899.  
  5900.  
  5901.  
  5902. @@ -300,45 +301,51 @@
  5903.  int joy_get_scaled_reading(int raw, int axn);
  5904.  int joy_get_unscaled_reading(int raw, int axn);
  5905.  
  5906. -DCF(joytest, "Test joystick")
  5907. +DCF(joytest, "Test joystick (X, Y)")
  5908.  {
  5909. -   if (Dc_command) {
  5910. -       while (!keyd_pressed[KEY_ESC]) {
  5911. -           int x, y, axis[JOY_NUM_AXES];
  5912. +   if (dc_optional_string_either("help", "--help")) {
  5913. +       dc_printf("Outputs the scaled reading of the joystick to a seperate window.\n");
  5914. +       dc_printf("Press ESC to end the test\n");
  5915. +   }
  5916.  
  5917. -           if (joy_num_sticks < 1)
  5918. -               return;
  5919. +   while (!keyd_pressed[KEY_ESC]) {
  5920. +       int x, y, axis[JOY_NUM_AXES];
  5921.  
  5922. -           joystick_read_raw_axis(JOY_NUM_AXES, axis);
  5923. +       if (joy_num_sticks < 1)
  5924. +           return;
  5925.  
  5926. -           x = joy_get_scaled_reading(axis[0], 0);
  5927. -           y = joy_get_scaled_reading(axis[1], 1);
  5928. +       joystick_read_raw_axis(JOY_NUM_AXES, axis);
  5929.  
  5930. -           mprintf(("X=%5d Y=%5d  Calibrated X=%6d Y=%6d\n", axis[0], axis[1], x, y));
  5931. -           Sleep(100);
  5932. -       }
  5933. +       x = joy_get_scaled_reading(axis[0], 0);
  5934. +       y = joy_get_scaled_reading(axis[1], 1);
  5935. +
  5936. +       mprintf(("X=%5d Y=%5d  Calibrated X=%6d Y=%6d\n", axis[0], axis[1], x, y));
  5937. +       Sleep(100);
  5938.     }
  5939.  }
  5940.  
  5941. -DCF(joytest2, "Test joystick (extended)")
  5942. +DCF(joytest2, "Test joystick (X, Y, Z, Rx, Ry, Rz)")
  5943.  {
  5944. -   if (Dc_command) {
  5945. -       while (!keyd_pressed[KEY_ESC]) {
  5946. -           int x, y, z, r, axis[JOY_NUM_AXES];
  5947. +   if (dc_optional_string_either("help", "--help")) {
  5948. +       dc_printf("Outputs the scaled reading of the joystick to a seperate window.\n");
  5949. +       dc_printf("Press ESC to end the test\n");
  5950. +   }
  5951.  
  5952. -           if (joy_num_sticks < 1)
  5953. -               return;
  5954. +   while (!keyd_pressed[KEY_ESC]) {
  5955. +       int x, y, z, r, axis[JOY_NUM_AXES];
  5956.  
  5957. -           joystick_read_raw_axis(JOY_NUM_AXES, axis);
  5958. +       if (joy_num_sticks < 1)
  5959. +           return;
  5960.  
  5961. -           x = joy_get_scaled_reading(axis[0], 0);
  5962. -           y = joy_get_scaled_reading(axis[1], 1);
  5963. -           z = joy_get_unscaled_reading(axis[2], 2);
  5964. -           r = joy_get_scaled_reading(axis[3], 3);
  5965. +       joystick_read_raw_axis(JOY_NUM_AXES, axis);
  5966.  
  5967. -           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));
  5968. -           Sleep(100);
  5969. -       }
  5970. +       x = joy_get_scaled_reading(axis[0], 0);
  5971. +       y = joy_get_scaled_reading(axis[1], 1);
  5972. +       z = joy_get_unscaled_reading(axis[2], 2);
  5973. +       r = joy_get_scaled_reading(axis[3], 3);
  5974. +
  5975. +       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));
  5976. +       Sleep(100);
  5977.     }
  5978.  }
  5979.  
  5980. Index: lighting/lighting.cpp
  5981. ===================================================================
  5982. --- lighting/lighting.cpp   (Revision 10462)
  5983. +++ lighting/lighting.cpp   (Arbeitskopie)
  5984. @@ -15,6 +15,7 @@
  5985.  #include "globalincs/systemvars.h"
  5986.  #include "graphics/2d.h"
  5987.  #include "cmdline/cmdline.h"
  5988. +#include "debugconsole/console.h"
  5989.  
  5990.  
  5991.  
  5992. @@ -62,52 +63,11 @@
  5993.  
  5994.  DCF(light,"Changes lighting parameters")
  5995.  {
  5996. -   if ( Dc_command )   {
  5997. -       dc_get_arg(ARG_STRING);
  5998. -       if ( !strcmp( Dc_arg, "ambient" ))  {
  5999. -           dc_get_arg(ARG_FLOAT);
  6000. -           if ( (Dc_arg_float < 0.0f) || (Dc_arg_float > 1.0f) )   {
  6001. -               Dc_help = 1;
  6002. -           } else {
  6003. -               Ambient_light = Dc_arg_float;
  6004. -           }
  6005. -       } else if ( !strcmp( Dc_arg, "reflect" ))   {
  6006. -           dc_get_arg(ARG_FLOAT);
  6007. -           if ( (Dc_arg_float < 0.0f) || (Dc_arg_float > 1.0f) )   {
  6008. -               Dc_help = 1;
  6009. -           } else {
  6010. -               Reflective_light = Dc_arg_float;
  6011. -           }
  6012. -       } else if ( !strcmp( Dc_arg, "default" ))   {
  6013. -           Lighting_mode = LM_BRIGHTEN;
  6014. -           Ambient_light = AMBIENT_LIGHT_DEFAULT;
  6015. -           Reflective_light = REFLECTIVE_LIGHT_DEFAULT;
  6016. -           Lighting_flag = 0;
  6017. -       } else if ( !strcmp( Dc_arg, "mode" ))  {
  6018. -           dc_get_arg(ARG_STRING);
  6019. -           if ( !strcmp(Dc_arg, "light") ) {
  6020. -               Lighting_mode = LM_BRIGHTEN;
  6021. -           } else if ( !strcmp(Dc_arg, "darken"))  {
  6022. -               Lighting_mode = LM_DARKEN;
  6023. -           } else {
  6024. -               Dc_help = 1;
  6025. -           }
  6026. -       } else if ( !strcmp( Dc_arg, "dynamic" ))   {
  6027. -           dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);       
  6028. -           if ( Dc_arg_type & ARG_TRUE )   Lighting_flag = 1
  6029. -           else if ( Dc_arg_type & ARG_FALSE ) Lighting_flag = 0
  6030. -           else if ( Dc_arg_type & ARG_NONE ) Lighting_flag ^= 1
  6031. -       } else if ( !strcmp( Dc_arg, "on" ) )   {
  6032. -           Lighting_off = 0;
  6033. -       } else if ( !strcmp( Dc_arg, "off" ) )  {
  6034. -           Lighting_off = 1;
  6035. -       } else {
  6036. -           // print usage, not stats
  6037. -           Dc_help = 1;
  6038. -       }
  6039. -   }
  6040. +   SCP_string arg_str;
  6041. +   float val_f;
  6042. +   bool  val_b;
  6043.  
  6044. -   if ( Dc_help )  {
  6045. +   if (dc_optional_string_either("help", "--help")) {
  6046.         dc_printf( "Usage: light keyword\nWhere keyword can be in the following forms:\n" );
  6047.         dc_printf( "light on|off          Turns all lighting on/off\n" );
  6048.         dc_printf( "light default         Resets lighting to all default values\n" );
  6049. @@ -117,19 +77,71 @@
  6050.         dc_printf( "light mode [light|darken]   Changes the lighting mode.\n" );
  6051.         dc_printf( "   Where 'light' means the global light adds light.\n");
  6052.         dc_printf( "   and 'darken' means the global light subtracts light.\n");
  6053. -       Dc_status = 0;  // don't print status if help is printed.  Too messy.
  6054. +       return;
  6055.     }
  6056.  
  6057. -   if ( Dc_status )    {
  6058. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  6059.         dc_printf( "Ambient light is set to %.2f\n", Ambient_light );
  6060.         dc_printf( "Reflective light is set to %.2f\n", Reflective_light );
  6061.         dc_printf( "Dynamic lighting is: %s\n", (Lighting_flag?"on":"off") );
  6062. -       switch( Lighting_mode ) {
  6063. -       case LM_BRIGHTEN:   dc_printf( "Lighting mode is: light\n" ); break;
  6064. -       case LM_DARKEN:   dc_printf( "Lighting mode is: darken\n" ); break;
  6065. -       default: dc_printf( "Lighting mode is: UNKNOWN\n" ); break;
  6066. +       switch( Lighting_mode ) {
  6067. +       case LM_BRIGHTEN:
  6068. +           dc_printf( "Lighting mode is: light\n" );
  6069. +           break;
  6070. +       case LM_DARKEN:
  6071. +           dc_printf( "Lighting mode is: darken\n" );
  6072. +           break;
  6073. +       default:
  6074. +           dc_printf( "Lighting mode is: UNKNOWN\n" );
  6075.         }
  6076. +       return;
  6077.     }
  6078. +  
  6079. +   if (dc_optional_string("ambient")) {
  6080. +       dc_stuff_float(&val_f);
  6081. +       if ((val_f < 0.0f) || (val_f > 1.0f)) {
  6082. +           dc_printf(" Error: ambient value must be between 0.0 and 1.0\n");
  6083. +       } else {
  6084. +           Ambient_light = val_f;
  6085. +       }
  6086. +  
  6087. +   } else if (dc_optional_string("reflect")) {
  6088. +       dc_stuff_float(&val_f);
  6089. +       if ( (val_f < 0.0f) || (val_f > 1.0f))  {
  6090. +           dc_printf(" Error: reflect value mus be between 0.0 and 1.0\n");
  6091. +       } else {
  6092. +           Reflective_light = val_f;
  6093. +       }
  6094. +  
  6095. +   } else if (dc_optional_string("default")) {
  6096. +       Lighting_mode = LM_BRIGHTEN;
  6097. +       Ambient_light = AMBIENT_LIGHT_DEFAULT;
  6098. +       Reflective_light = REFLECTIVE_LIGHT_DEFAULT;
  6099. +       Lighting_flag = 0;
  6100. +  
  6101. +   } else if (dc_optional_string("mode")) {
  6102. +       dc_stuff_string_white(arg_str);
  6103. +       if (arg_str == "light") {
  6104. +           Lighting_mode = LM_BRIGHTEN;
  6105. +  
  6106. +       } else if (arg_str == "darken") {
  6107. +           Lighting_mode = LM_DARKEN;
  6108. +      
  6109. +       } else {
  6110. +           dc_printf(" Error: unknown light mode: '%s'\n", arg_str.c_str());
  6111. +       }
  6112. +  
  6113. +   } else if (dc_optional_string("dynamic")) {
  6114. +       dc_stuff_boolean(&val_b);
  6115. +       Lighting_flag = val_b;
  6116. +
  6117. +   } else if(dc_maybe_stuff_boolean(&Lighting_off)) {
  6118. +       Lighting_off = !Lighting_off;
  6119. +
  6120. +   } else {
  6121. +       dc_stuff_string_white(arg_str);
  6122. +       dc_printf("Error: Unknown argument '%s'\n");
  6123. +   }
  6124.  }
  6125.  
  6126.  void light_reset()
  6127. Index: menuui/playermenu.cpp
  6128. ===================================================================
  6129. --- menuui/playermenu.cpp   (Revision 10462)
  6130. +++ menuui/playermenu.cpp   (Arbeitskopie)
  6131. @@ -31,6 +31,7 @@
  6132.  #include "parse/parselo.h"
  6133.  #include "cfile/cfile.h"
  6134.  #include "network/multi.h"
  6135. +#include "debugconsole/console.h"
  6136.  
  6137.  
  6138.  // --------------------------------------------------------------------------------------------------------
  6139. @@ -1236,40 +1237,38 @@
  6140.  
  6141.  DCF(bastion,"Sets the player to be on the bastion (or any other main hall)")
  6142.  {
  6143. -   if(gameseq_get_state() != GS_STATE_INITIAL_PLAYER_SELECT) {
  6144. -       dc_printf("This command can only be run in the initial player select screen.\n");
  6145. +   int idx;
  6146. +
  6147. +   if (gameseq_get_state() != GS_STATE_INITIAL_PLAYER_SELECT) {
  6148. +       dc_printf("This command can only be run while the in the initial player select screen. \n");
  6149.         return;
  6150.     }
  6151.  
  6152. -   if (Dc_command) {
  6153. -       dc_get_arg(ARG_INT | ARG_NONE);
  6154. +   if (dc_optional_string_either("help", "--help")) {
  6155. +       dc_printf("Usage: bastion [index]\n");
  6156. +       dc_printf("    [index] -- optional main hall index; if not supplied, defaults to 1\n");
  6157. +       return;
  6158. +   }
  6159.  
  6160. -       if (Dc_arg_type & ARG_INT) {
  6161. -           int idx = Dc_arg_int;
  6162. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  6163. +       dc_printf("Player is on main hall '%s'\n", Player_select_force_main_hall.c_str());
  6164. +       return;
  6165. +   }
  6166.  
  6167. -           Assert(Main_hall_defines.at(gr_screen.res).size() < INT_MAX);
  6168. -           if (idx < 0 || idx >= (int) Main_hall_defines.at(gr_screen.res).size()) {
  6169. -               dc_printf("Main hall index out of range\n");
  6170. -           } else {
  6171. -               main_hall_get_name(Player_select_force_main_hall, idx);
  6172. -               dc_printf("Player is now on main hall '%d'\n", Player_select_force_main_hall.c_str());
  6173. -           }
  6174. +   if (dc_maybe_stuff_int(&idx)) {
  6175. +       Assert(Main_hall_defines.at(gr_screen.res).size() < INT_MAX);
  6176. +       if (idx < 0 || idx >= (int) Main_hall_defines.at(gr_screen.res).size()) {
  6177. +           dc_printf("Main hall index out of range\n");
  6178.         } else {
  6179. -           Player_select_force_main_hall = "1";
  6180. -           dc_printf("Player is now on the Bastion... hopefully\n");
  6181. +           main_hall_get_name(Player_select_force_main_hall, idx);
  6182. +           dc_printf("Player is now on main hall '%d'\n", Player_select_force_main_hall.c_str());
  6183.         }
  6184. -       Dc_status = 0;
  6185. +  
  6186. +   } else {
  6187. +       // No argument passed
  6188. +       Player_select_force_main_hall = "1";
  6189. +       dc_printf("Player is now on the Bastion... hopefully\n");
  6190.     }
  6191. -
  6192. -   if (Dc_help) {
  6193. -       dc_printf("Usage: bastion [index]\n");
  6194. -       dc_printf("       [index] -- optional main hall index; if not supplied, defaults to 1\n");
  6195. -       Dc_status = 0;
  6196. -   }
  6197. -
  6198. -   if (Dc_status) {
  6199. -       dc_printf("There is no current main hall, as the player has not been selected yet!\n");
  6200. -   }
  6201.  }
  6202.  
  6203.  #define MAX_PLAYER_TIPS            40
  6204. Index: mission/missiongoals.cpp
  6205. ===================================================================
  6206. --- mission/missiongoals.cpp    (Revision 10462)
  6207. +++ mission/missiongoals.cpp    (Arbeitskopie)
  6208. @@ -13,6 +13,7 @@
  6209.  #include "mission/missiongoals.h"
  6210.  #include "mission/missionlog.h"
  6211.  #include "missionui/missionscreencommon.h"
  6212. +#include "debugconsole/console.h"
  6213.  #include "freespace2/freespace.h"
  6214.  #include "gamesequence/gamesequence.h"
  6215.  #include "hud/hud.h"
  6216. @@ -1262,77 +1263,101 @@
  6217.  }
  6218.  
  6219.  // some debug console functions to help list and change the status of mission goals
  6220. -DCF(show_mission_goals,"List and change the status of mission goals")
  6221. +DCF(show_mission_goals,"Lists the status of mission goals")
  6222.  {
  6223.     int i, type;
  6224.  
  6225. -   if (Dc_command)
  6226. -       Dc_status = 1;
  6227. -
  6228. -   if (Dc_help) {
  6229. +   if (dc_optional_string_either("help", "--help")) {
  6230.         dc_printf("Usage: show_mission_goals\n\nList all mission goals and their current status.\n");
  6231. -       Dc_status = 0;
  6232. +       return;
  6233.     }
  6234.  
  6235. -   if (Dc_status) {
  6236. -       for (i=0; i<Num_goals; i++) {
  6237. -           type = Mission_goals[i].type & GOAL_TYPE_MASK;
  6238. -           dc_printf("%2d. %32s(%10s) -- ", i, Mission_goals[i].name, Goal_type_text(type));
  6239. -           if ( Mission_goals[i].satisfied == GOAL_COMPLETE )
  6240. -               dc_printf("satisfied.\n");
  6241. -           else if ( Mission_goals[i].satisfied == GOAL_INCOMPLETE )
  6242. -               dc_printf("not satisfied\n");
  6243. -           else if ( Mission_goals[i].satisfied == GOAL_FAILED )
  6244. -               dc_printf("failed\n");
  6245. -           else
  6246. -               dc_printf("\t[unknown goal status].\n");
  6247. -       }
  6248. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  6249. +       // Don't do anything, but advance the parser past the flag
  6250.     }
  6251. +
  6252. +   for (i=0; i<Num_goals; i++) {
  6253. +       type = Mission_goals[i].type & GOAL_TYPE_MASK;
  6254. +       dc_printf("%2d. %32s(%10s) -- ", i, Mission_goals[i].name, Goal_type_text(type));
  6255. +       if ( Mission_goals[i].satisfied == GOAL_COMPLETE )
  6256. +           dc_printf("satisfied.\n");
  6257. +       else if ( Mission_goals[i].satisfied == GOAL_INCOMPLETE )
  6258. +           dc_printf("unsatisfied\n");
  6259. +       else if ( Mission_goals[i].satisfied == GOAL_FAILED )
  6260. +           dc_printf("failed\n");
  6261. +       else
  6262. +           dc_printf("Warning! Mission goal %i is in an invalid state! (value: %i)", i, Mission_goals[i].satisfied);
  6263. +   }
  6264. +  
  6265.  }
  6266.  
  6267.  //XSTR:OFF
  6268. -DCF(change_mission_goal, "Change the mission goal")
  6269. +DCF(change_mission_goal, "Changes the mission goal status")
  6270.  {
  6271.     int num;
  6272. +   bool val_b;
  6273. +   char *string;
  6274.  
  6275. -   if ( Dc_command ) {
  6276. -       dc_get_arg(ARG_INT);
  6277. -       if ( Dc_arg_int >= Num_goals ) {
  6278. -           dc_printf ("First parameter must be a valid goal number.\n");
  6279. -           return;
  6280. -       }
  6281. +   if (dc_optional_string_either("help", "--help")) {
  6282. +       dc_printf("Usage: change_mission_goal <goal_num> [status]\n");
  6283. +       dc_printf("<goal_num> --  Integer number of goal to change.  See show_mission_goals\n");
  6284. +       dc_printf("[status]   --  Goal status to change to.\n\n");
  6285.  
  6286. -       num = Dc_arg_int;
  6287. -       dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_STRING);
  6288. -       if ( Dc_arg_type & ARG_TRUE )
  6289. -           Mission_goals[num].satisfied = GOAL_COMPLETE;
  6290. -       else if ( Dc_arg_type & ARG_FALSE )
  6291. -           Mission_goals[num].satisfied = GOAL_FAILED;
  6292. -       else if ( Dc_arg_type & ARG_NONE )
  6293. -           Mission_goals[num].satisfied = GOAL_INCOMPLETE;
  6294. -       else if ( Dc_arg_type & ARG_STRING) {
  6295. -           if ( !stricmp(Dc_arg, "satisfied") )
  6296. -               Mission_goals[num].satisfied = GOAL_COMPLETE;
  6297. -           else if ( !stricmp( Dc_arg, "failed") )
  6298. -               Mission_goals[num].satisfied = GOAL_FAILED;
  6299. -           else if ( !stricmp( Dc_arg, "unknown") )
  6300. -               Mission_goals[num].satisfied = GOAL_INCOMPLETE;
  6301. -           else
  6302. -               dc_printf("Unknown status %s.  Use 'satisfied', 'failed', or 'unknown'\n", Dc_arg);
  6303. -       }
  6304. +       dc_printf("The optional [status] field may be either a bool type or a string.\n");
  6305. +       dc_printf("\ttrue  -- Goal status set to 'complete'\n");
  6306. +       dc_printf("\tfalse -- Goal status set to 'failed'\n\n");
  6307. +
  6308. +       dc_printf("A string value of 'satisfied', 'failed', or 'unknown' will set the goal status to the respective state.\n");
  6309. +       dc_printf("If [status] is not given, then the goal status will be set to 'unknown'");
  6310. +
  6311. +       dc_printf("Examples:\n");
  6312. +       dc_printf("\t'change_mission_goal 1 true'  makes goal 1 as successful.\n");
  6313. +       dc_printf("\t'change_mission_goal 2'       marks goal 2 as unknown/incomplete\n");
  6314. +       dc_printf("\t'change_mission_goal 0 satisfied'    marks goal 0 as satisfied\n");
  6315. +       return;
  6316.     }
  6317.  
  6318. -   if ( Dc_help ) {
  6319. -       dc_printf("Usage: change_mission_goal <goal_num> <status>\n");
  6320. -       dc_printf("<goal_num> --  Integer number of goal to change.  See show_mission_goals\n");
  6321. -       dc_printf("<status>   --  [bool] where a true value makes the goal satisfied,\n");
  6322. -       dc_printf("               a false value makes the goal failed.\n");
  6323. -       dc_printf("The <status> field may also be one of 'satisfied', 'failed', or 'unknown'\n");
  6324. -       dc_printf("\nExamples:\n\n'change_mission_goal 1 true' makes goal 1 successful.\n");
  6325. -       dc_printf("'change_mission_goal 2' marks goal 2 not complete\n");
  6326. -       dc_printf("'change_mission_goal 0 satisfied' marks goal 0 as satisfied\n");
  6327. -       Dc_status = 0;
  6328. +   dc_stuff_int(&num);
  6329. +   if ( num >= Num_goals ) {
  6330. +       dc_printf (" Error: Invalid value for <goal_num>. Valid values: 0 - %i\n", Num_goals);
  6331. +       return;
  6332.     }
  6333. +
  6334. +   if (dc_optional_string("satisfied")) {
  6335. +       Mission_goals[num].satisfied = GOAL_COMPLETE;
  6336. +
  6337. +   } else if (dc_optional_string("failed")) {
  6338. +       Mission_goals[num].satisfied = GOAL_FAILED;
  6339. +
  6340. +   } else if (dc_optional_string("unsatisfied")) {
  6341. +       Mission_goals[num].satisfied = GOAL_INCOMPLETE;
  6342. +
  6343. +   } else if (dc_maybe_stuff_boolean(&val_b)) {
  6344. +       val_b ? Mission_goals[num].satisfied = GOAL_COMPLETE : Mission_goals[num].satisfied = GOAL_FAILED;
  6345. +
  6346. +   } else {
  6347. +       // No argument given
  6348. +       Mission_goals[num].satisfied = GOAL_INCOMPLETE;
  6349. +   }
  6350. +
  6351. +   switch(Mission_goals[num].satisfied) {
  6352. +   case GOAL_COMPLETE:
  6353. +       string = "satisfied";
  6354. +       break;
  6355. +
  6356. +   case GOAL_FAILED:
  6357. +       string = "failed";
  6358. +       break;
  6359. +
  6360. +   case GOAL_INCOMPLETE:
  6361. +       string = "unsatisfied";
  6362. +       break;
  6363. +
  6364. +   default:
  6365. +       dc_printf("Warning! Mission goal %i is in an invalid state! (value: %i)", num, Mission_goals[num].satisfied);
  6366. +       return;
  6367. +   }
  6368. +   dc_printf("Mission goal %i set to '%s'\n", num, string);
  6369.  }
  6370.  //XSTR:ON
  6371.  
  6372. Index: model/modelinterp.cpp
  6373. ===================================================================
  6374. --- model/modelinterp.cpp   (Revision 10462)
  6375. +++ model/modelinterp.cpp   (Arbeitskopie)
  6376. @@ -33,6 +33,7 @@
  6377.  #include "graphics/gropengllight.h"
  6378.  #include "ship/shipfx.h"
  6379.  #include "gamesequence/gamesequence.h"
  6380. +#include "debugconsole/console.h"
  6381.  
  6382.  #include <limits.h>
  6383.  
  6384. @@ -1941,19 +1942,20 @@
  6385.  
  6386.  DCF(model_darkening,"Makes models darker with distance")
  6387.  {
  6388. -   if ( Dc_command )   {
  6389. -       dc_get_arg(ARG_FLOAT);
  6390. -       Interp_depth_scale = Dc_arg_float;
  6391. +   if (dc_optional_string_either("help", "--help")) {
  6392. +       dc_printf( "Usage: model_darkening <float>\n" );
  6393. +       dc_printf("Sets the distance at which to start blacking out models (namely asteroids).\n");
  6394. +       return;
  6395.     }
  6396.  
  6397. -   if ( Dc_help )  {
  6398. -       dc_printf( "Usage: model_darkening float\n" );
  6399. -       Dc_status = 0;  // don't print status if help is printed.  Too messy.
  6400. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  6401. +       dc_printf( "model_darkening = %.1f\n", Interp_depth_scale );
  6402. +       return;
  6403.     }
  6404.  
  6405. -   if ( Dc_status )    {
  6406. -       dc_printf( "model_darkening = %.1f\n", Interp_depth_scale );
  6407. -   }
  6408. +   dc_stuff_float(&Interp_depth_scale);
  6409. +
  6410. +   dc_printf("model_darkening set to %.1f\n", Interp_depth_scale);
  6411.  }
  6412.  
  6413.  void model_render(int model_num, matrix *orient, vec3d * pos, uint flags, int objnum, int lighting_skip, int *replacement_textures)
  6414. @@ -2116,8 +2118,13 @@
  6415.  }
  6416.  
  6417.  int tiling = 1;
  6418. -DCF(tiling, "")
  6419. +DCF(tiling, "Toggles rendering of tiled textures (default is on)")
  6420.  {
  6421. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  6422. +       dc_printf("Tiled textures are %s", tiling ? "ON" : "OFF");
  6423. +       return;
  6424. +   }
  6425. +
  6426.     tiling = !tiling;
  6427.     if(tiling){
  6428.         dc_printf("Tiled textures\n");
  6429. Index: nebula/neb.cpp
  6430. ===================================================================
  6431. --- nebula/neb.cpp  (Revision 10462)
  6432. +++ nebula/neb.cpp  (Arbeitskopie)
  6433. @@ -24,6 +24,7 @@
  6434.  #include "mission/missionparse.h"
  6435.  #include "ship/ship.h"
  6436.  #include "cmdline/cmdline.h"
  6437. +#include "debugconsole/console.h"
  6438.  
  6439.  
  6440.  // --------------------------------------------------------------------------------------------------------
  6441. @@ -503,7 +504,7 @@
  6442.  
  6443.  // should we not render this object because its obscured by the nebula?
  6444.  int neb_skip_opt = 1;
  6445. -DCF(neb_skip, "")
  6446. +DCF(neb_skip, "Toggles culling of objects obscured by nebula")
  6447.  {
  6448.     neb_skip_opt = !neb_skip_opt;
  6449.     if (neb_skip_opt) {
  6450. @@ -896,12 +897,14 @@
  6451.     }
  6452.  }
  6453.  
  6454. +/*
  6455. + * TODO: remove this
  6456.  float max_area = 100000000.0f;
  6457.  DCF(max_area, "")
  6458.  {
  6459. -   dc_get_arg(ARG_FLOAT);
  6460. -   max_area = Dc_arg_float;
  6461. +   dc_stuff_float(&max_area);
  6462.  }
  6463. +*/
  6464.  
  6465.  float g3_draw_rotated_bitmap_area(vertex *pnt, float angle, float rad, uint tmap_flags, float area);
  6466.  int neb_mode = 1;
  6467. @@ -1443,7 +1446,7 @@
  6468.  }
  6469.  
  6470.  // nebula DCF functions ------------------------------------------------------
  6471. -
  6472. +// 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
  6473.  DCF(neb2, "list nebula console commands")
  6474.  {     
  6475.  // dc_printf("neb2_fog <X> <float> <float>  : set near and far fog planes for ship type X\n");
  6476. @@ -1463,7 +1466,7 @@
  6477.     dc_printf("neb2_cinner      : poof cube inner dimension\n");
  6478.     dc_printf("neb2_couter      : poof cube outer dimension\n");
  6479.     dc_printf("neb2_jitter      : poof jitter\n");
  6480. -   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");   
  6481. +   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");  
  6482.     dc_printf("neb2_ff          : flash fade/sec\n");
  6483.     dc_printf("neb2_background  : rgb background color\n");
  6484.     dc_printf("neb2_fog_color   : rgb fog color\n");
  6485. @@ -1471,95 +1474,91 @@
  6486.  // dc_printf("neb2_fog_vals    : display all the current settings for all above values\n");   
  6487.  }
  6488.  
  6489. -DCF(neb2_prad, "")
  6490. +DCF(neb2_prad, "set cloud poof radius")
  6491.  {
  6492. -   dc_get_arg(ARG_FLOAT);
  6493. -   Nd->prad = Dc_arg_float;
  6494. +   dc_stuff_float(&Nd->prad);
  6495.  }
  6496. -DCF(neb2_cdim, "")
  6497. +DCF(neb2_cdim, "poof cube dimension")
  6498.  {
  6499. -   dc_get_arg(ARG_FLOAT);
  6500. -   Nd->cube_dim = Dc_arg_float;
  6501. +   dc_stuff_float(&Nd->cube_dim);
  6502.  }
  6503.  
  6504. -DCF(neb2_cinner, "")
  6505. +DCF(neb2_cinner, "poof cube inner dimension")
  6506.  {
  6507. -   dc_get_arg(ARG_FLOAT);
  6508. -   Nd->cube_inner = Dc_arg_float;
  6509. +   dc_stuff_float(&Nd->cube_inner);
  6510.  }
  6511.  
  6512. -DCF(neb2_couter, "")
  6513. +DCF(neb2_couter, "poof cube outer dimension")
  6514.  {
  6515. -   dc_get_arg(ARG_FLOAT);
  6516. -   Nd->cube_outer = Dc_arg_float;
  6517. +   dc_stuff_float(&Nd->cube_outer);
  6518.  }
  6519.  
  6520. -DCF(neb2_jitter, "")
  6521. +DCF(neb2_jitter, "poof jitter")
  6522.  {
  6523. -   dc_get_arg(ARG_FLOAT);
  6524. -   Nd->hj = Nd->dj = Nd->wj = Dc_arg_float;
  6525. +   float value;
  6526. +   dc_stuff_float(&value);
  6527. +   Nd->hj = Nd->dj = Nd->wj = value;
  6528.  }
  6529.  
  6530. -DCF(neb2_max_alpha, "")
  6531. +DCF(neb2_max_alpha, "max alpha value (0.0 to 1.0) for cloud poofs.")
  6532.  {
  6533. -   dc_get_arg(ARG_FLOAT);
  6534. -   Nd->max_alpha_glide = Dc_arg_float;
  6535. +   dc_stuff_float(&Nd->max_alpha_glide);
  6536.  }
  6537.  
  6538. -DCF(neb2_break_alpha, "")
  6539. +DCF(neb2_break_alpha, "alpha value (0.0 to 1.0) at which faded polygons are not drawn.")
  6540.  {
  6541. -   dc_get_arg(ARG_FLOAT);
  6542. -   Nd->break_alpha = Dc_arg_float;
  6543. +   dc_stuff_float(&Nd->break_alpha);
  6544.  }
  6545.  
  6546. -DCF(neb2_break_off, "")
  6547. +DCF(neb2_break_off, "how many pixels offscreen (left, right, top, bottom) when a cloud poof becomes fully transparent.")
  6548.  {
  6549. -   dc_get_arg(ARG_INT);
  6550. -   Nd->break_y = (float)Dc_arg_int;
  6551. -   Nd->break_x = Nd->break_y * 1.3333f;
  6552. +   int value;
  6553. +   dc_stuff_int(&value);
  6554. +   Nd->break_y = (float)value;
  6555. +   Nd->break_x = Nd->break_y * gr_screen.aspect;
  6556.  }
  6557.  
  6558. -DCF(neb2_smooth, "")
  6559. +DCF(neb2_smooth, "magic fog smoothing modes (0 - 3)")
  6560.  {
  6561.     int index;
  6562. -   dc_get_arg(ARG_INT);
  6563. -   index = Dc_arg_int;
  6564. +   dc_stuff_int(&index);
  6565.     if ( (index >= 0) && (index <= 3) ) {
  6566.         wacky_scheme = index;
  6567. +   } else {
  6568. +       dc_printf("Invalid smooth mode %i", index);
  6569.     }
  6570.  }
  6571.  
  6572. -DCF(neb2_select, "")
  6573. +DCF(neb2_select, "Enables/disables a poof bitmap")
  6574.  {
  6575. -   dc_get_arg(ARG_INT);
  6576. -   int bmap = Dc_arg_int;
  6577. +   int bmap;
  6578. +   bool val_b;
  6579. +
  6580. +   dc_stuff_int(&bmap);
  6581. +
  6582.     if ( (bmap >= 0) && (bmap < Neb2_poof_count) ) {
  6583. -       dc_get_arg(ARG_INT);
  6584. -       if (Dc_arg_int) {
  6585. -           Neb2_poof_flags |= (1<<bmap);
  6586. -       } else {
  6587. -           Neb2_poof_flags &= ~(1<<bmap);
  6588. -       }
  6589. +       dc_stuff_boolean(&val_b);
  6590. +
  6591. +       val_b ? (Neb2_poof_flags |= (1<<bmap)) : (Neb2_poof_flags &= ~(1<<bmap));
  6592.     }
  6593.  }
  6594.  
  6595. -DCF(neb2_rot, "")
  6596. +DCF(neb2_rot, "set max rotation speed for poofs")
  6597.  {
  6598. -   dc_get_arg(ARG_FLOAT);
  6599. -   max_rotation = Dc_arg_float;
  6600. +   dc_stuff_float(&max_rotation);
  6601.  }
  6602.  
  6603. -DCF(neb2_ff, "")
  6604. +DCF(neb2_ff, "flash fade/sec")
  6605.  {
  6606. -   dc_get_arg(ARG_FLOAT);
  6607. -   neb2_flash_fade = Dc_arg_float;
  6608. +   dc_stuff_float(&neb2_flash_fade);
  6609.  }
  6610.  
  6611. -DCF(neb2_mode, "")
  6612. +DCF(neb2_mode, "Switches nebula render modes")
  6613.  {
  6614. -   dc_get_arg(ARG_INT);
  6615. +   int mode;
  6616. +   dc_stuff_int(&mode);
  6617.  
  6618. -   switch (Dc_arg_int) {
  6619. +   switch (mode) {
  6620.         case NEB2_RENDER_NONE:
  6621.             Neb2_render_mode = NEB2_RENDER_NONE;
  6622.         break;
  6623. @@ -1586,23 +1585,19 @@
  6624.     }
  6625.  }
  6626.  
  6627. -DCF(neb2_slices, "")
  6628. +DCF(neb2_slices, "Sets how many 'slices' are used in the nebula")
  6629.  {
  6630. -   dc_get_arg(ARG_INT);
  6631. -   Neb2_slices = Dc_arg_int;
  6632. +   dc_stuff_int(&Neb2_slices);
  6633.     neb2_eye_changed();
  6634.  }
  6635.  
  6636. -DCF(neb2_background, "")
  6637. +DCF(neb2_background, "Sets the RGB background color (lame rendering)")
  6638.  {
  6639.     int r, g, b;
  6640.  
  6641. -   dc_get_arg(ARG_INT);
  6642. -   r = Dc_arg_int;
  6643. -   dc_get_arg(ARG_INT);
  6644. -   g = Dc_arg_int;
  6645. -   dc_get_arg(ARG_INT);
  6646. -   b = Dc_arg_int;
  6647. +   dc_stuff_int(&r);
  6648. +   dc_stuff_int(&g);
  6649. +   dc_stuff_int(&b);
  6650.  
  6651.     Neb2_background_color[0] = r;
  6652.     Neb2_background_color[1] = g;
  6653. @@ -1609,16 +1604,13 @@
  6654.     Neb2_background_color[2] = b;
  6655.  }
  6656.  
  6657. -DCF(neb2_fog_color, "")
  6658. +DCF(neb2_fog_color, "Sets the RGB fog color (HTL)")
  6659.  {
  6660.     ubyte r, g, b;
  6661.  
  6662. -   dc_get_arg(ARG_UBYTE);
  6663. -   r = Dc_arg_ubyte;
  6664. -   dc_get_arg(ARG_UBYTE);
  6665. -   g = Dc_arg_ubyte;
  6666. -   dc_get_arg(ARG_UBYTE);
  6667. -   b = Dc_arg_ubyte;
  6668. +   dc_stuff_ubyte(&r);
  6669. +   dc_stuff_ubyte(&g);
  6670. +   dc_stuff_ubyte(&b);
  6671.  
  6672.     Neb2_fog_color_r = r;
  6673.     Neb2_fog_color_g = g;
  6674. Index: nebula/neblightning.cpp
  6675. ===================================================================
  6676. --- nebula/neblightning.cpp (Revision 10462)
  6677. +++ nebula/neblightning.cpp (Arbeitskopie)
  6678. @@ -13,6 +13,7 @@
  6679.  #include "parse/parselo.h"
  6680.  #include "globalincs/linklist.h"
  6681.  #include "io/timer.h"
  6682. +#include "debugconsole/console.h"
  6683.  #include "freespace2/freespace.h"
  6684.  #include "gamesnd/gamesnd.h"
  6685.  #include "render/3d.h"
  6686. @@ -81,52 +82,43 @@
  6687.  storm_type *Storm = NULL;
  6688.  
  6689.  // vars
  6690. -DCF(b_scale, "")
  6691. +DCF(b_scale, "Sets the scale factor for debug nebula bolts")
  6692.  {
  6693. -   dc_get_arg(ARG_FLOAT);
  6694. -   Bolt_types[DEBUG_BOLT].b_scale = Dc_arg_float;
  6695. +   dc_stuff_float(&Bolt_types[DEBUG_BOLT].b_scale);
  6696.  }
  6697. -DCF(b_rand, "")
  6698. +DCF(b_rand, "Sets the randomness factor for debug nebula bolts")
  6699.  {
  6700. -   dc_get_arg(ARG_FLOAT);
  6701. -   Bolt_types[DEBUG_BOLT].b_rand = Dc_arg_float;
  6702. +   dc_stuff_float(&Bolt_types[DEBUG_BOLT].b_rand);
  6703.  }
  6704. -DCF(b_shrink, "")
  6705. +DCF(b_shrink, "Sets the shrink factor for debug nebula bolts")
  6706.  {
  6707. -   dc_get_arg(ARG_FLOAT);
  6708. -   Bolt_types[DEBUG_BOLT].b_shrink = Dc_arg_float;
  6709. +   dc_stuff_float(&Bolt_types[DEBUG_BOLT].b_shrink);
  6710.  }
  6711. -DCF(b_poly_pct, "")
  6712. +DCF(b_poly_pct, "Sets b_poly_pct")
  6713.  {
  6714. -   dc_get_arg(ARG_FLOAT);
  6715. -   Bolt_types[DEBUG_BOLT].b_poly_pct = Dc_arg_float;
  6716. +   dc_stuff_float(&Bolt_types[DEBUG_BOLT].b_poly_pct);
  6717.  }
  6718. -DCF(b_add, "")
  6719. +DCF(b_add, "Sets b_add")
  6720.  {
  6721. -   dc_get_arg(ARG_FLOAT);
  6722. -   Bolt_types[DEBUG_BOLT].b_add = Dc_arg_float;
  6723. +   dc_stuff_float(&Bolt_types[DEBUG_BOLT].b_add);
  6724.  }
  6725. -DCF(b_strikes, "")
  6726. +DCF(b_strikes, "Sets num_strikes")
  6727.  {
  6728. -   dc_get_arg(ARG_INT);
  6729. -   Bolt_types[DEBUG_BOLT].num_strikes = Dc_arg_int;
  6730. +   dc_stuff_int(&Bolt_types[DEBUG_BOLT].num_strikes);
  6731.  }
  6732. -DCF(b_noise, "")
  6733. +DCF(b_noise, "Sets noise factor")
  6734.  {
  6735. -   dc_get_arg(ARG_FLOAT);
  6736. -   Bolt_types[DEBUG_BOLT].noise = Dc_arg_float;
  6737. +   dc_stuff_float(&Bolt_types[DEBUG_BOLT].noise);
  6738.  }
  6739. -DCF(b_bright, "")
  6740. +DCF(b_bright, "Sets brightness factor")
  6741.  {
  6742. -   dc_get_arg(ARG_FLOAT);
  6743. -   Bolt_types[DEBUG_BOLT].b_bright = Dc_arg_float;
  6744. +   dc_stuff_float(&Bolt_types[DEBUG_BOLT].b_bright);
  6745.  }
  6746. -DCF(b_lifetime, "")
  6747. +DCF(b_lifetime, "Sets lifetime duration")
  6748.  {
  6749. -   dc_get_arg(ARG_INT);
  6750. -   Bolt_types[DEBUG_BOLT].lifetime = Dc_arg_int;
  6751. +   dc_stuff_int(&Bolt_types[DEBUG_BOLT].lifetime);
  6752.  }
  6753. -DCF(b_list, "")
  6754. +DCF(b_list, "Displays status of debug lightning commands")
  6755.  {
  6756.     dc_printf("Debug lightning bolt settings :\n");
  6757.  
  6758. @@ -144,13 +136,13 @@
  6759.  // nebula lightning intensity (0.0 to 1.0)
  6760.  float Nebl_intensity = 0.6667f;
  6761.  
  6762. -DCF(lightning_intensity, "")
  6763. +DCF(lightning_intensity, "Sets lightning intensity between 0.0 and 1.0 (Default is 0.6667)")
  6764.  {
  6765. -   dc_get_arg(ARG_FLOAT);
  6766. -   float val = Dc_arg_float;
  6767. -    
  6768. -    CLAMP(val, 0.0f, 1.0f);
  6769. +   float val;
  6770. +   dc_stuff_float(&val);
  6771.  
  6772. +   CLAMP(val, 0.0f, 1.0f);
  6773. +
  6774.     Nebl_intensity = 1.0f - val;
  6775.  }
  6776.  
  6777. Index: network/multi.cpp
  6778. ===================================================================
  6779. --- network/multi.cpp   (Revision 10462)
  6780. +++ network/multi.cpp   (Arbeitskopie)
  6781. @@ -48,6 +48,7 @@
  6782.  #include "cfile/cfile.h"
  6783.  #include "fs2netd/fs2netd_client.h"
  6784.  #include "pilotfile/pilotfile.h"
  6785. +#include "debugconsole/console.h"
  6786.  
  6787.  
  6788.  
  6789. @@ -1105,14 +1106,15 @@
  6790.  //
  6791.  
  6792.  int eye_tog = 1;
  6793. -DCF(eye_tog, "")
  6794. +DCF(eye_tog, "Toggles setting of the local player eyepoint on every frame (Multiplayer)")
  6795.  {
  6796. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  6797. +       dc_printf("proper eye stuff is %s\n", eye_tog ? "ON" : "OFF");
  6798. +       return;
  6799. +   }
  6800. +
  6801.     eye_tog = !eye_tog;
  6802. -   if(eye_tog){
  6803. -       dc_printf("proper eye stuff on\n");
  6804. -   } else {
  6805. -       dc_printf("proper eye stuff off\n");
  6806. -   }
  6807. +   dc_printf("proper eye stuff is %s\n", eye_tog ? "ON" : "OFF");
  6808.  }
  6809.  
  6810.  void multi_do_frame()
  6811. @@ -1772,13 +1774,14 @@
  6812.  }
  6813.  
  6814.  // netgame debug flags for debug console stuff
  6815. -DCF(netd, "change/list netgame debug flags")
  6816. +DCF(netd, "change netgame debug flags (Mulitplayer)")
  6817.  {
  6818. -   dc_get_arg(ARG_INT);
  6819. +   int value;
  6820. +   dc_stuff_int(&value);
  6821.    
  6822. -   // if we got an integer, and we're the server, change flags
  6823. -   if((Dc_arg_type & ARG_INT) && (Net_player != NULL) && (Net_player->flags & NETINFO_FLAG_AM_MASTER) && (Dc_arg_int <= 7)){
  6824. -       Netgame.debug_flags ^= (1<<Dc_arg_int);
  6825. +   // if we're the server, change flags
  6826. +   if ((Net_player != NULL) && (Net_player->flags & NETINFO_FLAG_AM_MASTER) && (value <= 7)) {
  6827. +       Netgame.debug_flags ^= (1 << value);
  6828.     }
  6829.  
  6830.     // display network flags
  6831. Index: network/multi_kick.cpp
  6832. ===================================================================
  6833. --- network/multi_kick.cpp  (Revision 10462)
  6834. +++ network/multi_kick.cpp  (Arbeitskopie)
  6835. @@ -18,6 +18,7 @@
  6836.  #include "freespace2/freespace.h"
  6837.  #include "playerman/player.h"
  6838.  #include "io/timer.h"
  6839. +#include "debugconsole/console.h"
  6840.  
  6841.  
  6842.  // ----------------------------------------------------------------------------------
  6843. @@ -137,18 +138,14 @@
  6844.  void multi_dcf_kick()
  6845.  {
  6846.     int player_num,idx;
  6847. +   SCP_string arg;
  6848.  
  6849.     // get the callsign of the player to kick
  6850. -   dc_get_arg(ARG_STRING);
  6851. +   dc_stuff_string(arg);
  6852.  
  6853. -   if(Dc_arg[0] == '\0'){
  6854. -       dc_printf("Invalid player callsign!\n");
  6855. -       return ;
  6856. -   }
  6857. -
  6858.     player_num = -1;
  6859.     for(idx=0;idx<MAX_PLAYERS;idx++){
  6860. -       if(MULTI_CONNECTED(Net_players[idx]) && (stricmp(Net_players[idx].m_player->callsign,Dc_arg)==0)){
  6861. +       if(MULTI_CONNECTED(Net_players[idx]) && (stricmp(Net_players[idx].m_player->callsign, arg.c_str()) == 0)) {
  6862.             player_num = idx;
  6863.             break;
  6864.         }
  6865. @@ -156,7 +153,7 @@
  6866.  
  6867.     // if we didn't find the player, notify of the results
  6868.     if(player_num == -1){
  6869. -       dc_printf("Could not find player %s to kick!",Dc_arg);
  6870. +       dc_printf("Could not find player %s to kick!", arg.c_str());
  6871.     }
  6872.     // if we found the guy, then try and kick him
  6873.     else {
  6874. Index: network/multi_obj.cpp
  6875. ===================================================================
  6876. --- network/multi_obj.cpp   (Revision 10462)
  6877. +++ network/multi_obj.cpp   (Arbeitskopie)
  6878. @@ -26,6 +26,7 @@
  6879.  #include "physics/physics.h"
  6880.  #include "ship/afterburner.h"
  6881.  #include "cfile/cfile.h"
  6882. +#include "debugconsole/console.h"
  6883.  
  6884.  
  6885.  // ---------------------------------------------------------------------------------------------------
  6886. @@ -1569,10 +1570,21 @@
  6887.  
  6888.  // bandwidth granularity
  6889.  int OO_gran = 1;
  6890. -DCF(oog, "")
  6891. +DCF(oog, "Sets bandwidth granularity (Multiplayer)")
  6892.  {
  6893. -   dc_get_arg(ARG_INT);
  6894. -   OO_gran = Dc_arg_int;
  6895. +   if (dc_optional_string_either("help", "--help")) {
  6896. +       dc_printf("Usage: oog <OO_gran>\n");
  6897. +       dc_printf("Sets bandwidth granularity\n");
  6898. +       return;
  6899. +   }
  6900. +
  6901. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  6902. +       dc_printf("Current Granularity is '%i' (default is 1)", OO_gran);
  6903. +       return;
  6904. +   }
  6905. +
  6906. +   dc_stuff_int(&OO_gran);
  6907. +   dc_printf("Ganularity set to %i", OO_gran);
  6908.  }
  6909.  
  6910.  // process datarate limiting stuff for the server
  6911. @@ -1939,10 +1951,21 @@
  6912.  }
  6913.  
  6914.  float oo_error = 0.8f;
  6915. -DCF(oo_error, "")
  6916. +DCF(oo_error, "Sets error factor for flight path prediction physics (Multiplayer)")
  6917.  {
  6918. -   dc_get_arg(ARG_FLOAT);
  6919. -   oo_error = Dc_arg_float;
  6920. +   if (dc_optional_string_either("help", "--help")) {
  6921. +       dc_printf("Usage: oo_error <value>\n");
  6922. +       return;
  6923. +   }
  6924. +
  6925. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  6926. +       dc_printf("oo_error is currently %f", oo_error);
  6927. +       return;
  6928. +   }
  6929. +
  6930. +   dc_stuff_float(&oo_error);
  6931. +  
  6932. +   dc_printf("oo_error set to %f", oo_error);
  6933.  }
  6934.  
  6935.  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)
  6936. @@ -1994,14 +2017,16 @@
  6937.  }
  6938.  
  6939.  int display_oo_bez = 0;
  6940. -DCF(bez, "")
  6941. +DCF(bez, "Toggles rendering of player ship trajectory interpolation splines (Multiplayer) *disabled*")
  6942.  {
  6943. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  6944. +       dc_printf("Rendering of interpolation splines is '%s'", display_oo_bez ? "ON" : "OFF");
  6945. +       return;
  6946. +   }
  6947. +
  6948.     display_oo_bez = !display_oo_bez;
  6949. -   if(display_oo_bez){
  6950. -       dc_printf("Showing interp splines");
  6951. -   } else {
  6952. -       dc_printf("Not showing interp splines");
  6953. -   }
  6954. +
  6955. +   dc_printf("%showing interp splines", display_oo_bez ? "S" : "Not s");
  6956.  }
  6957.  
  6958.  void oo_display()
  6959. Index: network/multi_pxo.cpp
  6960. ===================================================================
  6961. --- network/multi_pxo.cpp   (Revision 10462)
  6962. +++ network/multi_pxo.cpp   (Arbeitskopie)
  6963. @@ -42,6 +42,7 @@
  6964.  #include "playerman/player.h"
  6965.  #include "fs2netd/fs2netd_client.h"
  6966.  #include "menuui/mainhallmenu.h"
  6967. +#include "debugconsole/console.h"
  6968.  
  6969.  
  6970.  
  6971. @@ -461,14 +462,15 @@
  6972.  // get the absolute index of the displayed items which our currently selected one is
  6973.  int multi_pxo_get_select_index();
  6974.  
  6975. -DCF(players, "")
  6976. +DCF(players, "Adds the specified number of bogus players to the PXO listing (Multiplayer)")
  6977.  {
  6978.     char name[512] = "";
  6979. +   int i;
  6980. +   // add a bunch of bogus players
  6981. +   dc_stuff_int(&i);
  6982.  
  6983. -   // add a bunch of bogus players
  6984. -   dc_get_arg(ARG_INT);
  6985. -   for(int idx=0; idx<Dc_arg_int; idx++){
  6986. -       sprintf(name, "player %d", idx);
  6987. +   for(int idx = 0; idx < i; idx++){
  6988. +       sprintf(name, "bogus player %d", idx);
  6989.         multi_pxo_add_player(name);
  6990.     }
  6991.  }
  6992. Index: network/multi_voice.cpp
  6993. ===================================================================
  6994. --- network/multi_voice.cpp (Revision 10462)
  6995. +++ network/multi_voice.cpp (Arbeitskopie)
  6996. @@ -22,9 +22,9 @@
  6997.  #include "menuui/optionsmenumulti.h"
  6998.  #include "network/multi.h"
  6999.  #include "playerman/player.h"
  7000. +#include "debugconsole/console.h"
  7001.  
  7002.  
  7003. -
  7004.  // --------------------------------------------------------------------------------------------------
  7005.  // MULTI VOICE DEFINES/VARS
  7006.  //
  7007. @@ -483,16 +483,17 @@
  7008.  // voice settings debug console function
  7009.  void multi_voice_dcf()
  7010.  {
  7011. -   dc_get_arg(ARG_STRING);
  7012. +   SCP_string arg;
  7013. +   int value;
  7014.  
  7015. +   dc_stuff_string_white(arg);
  7016. +
  7017.     // set the quality of sound
  7018. -   if (strcmp(Dc_arg, NOX("qos")) == 0) {
  7019. -       dc_get_arg(ARG_INT);
  7020. -       if(Dc_arg_type & ARG_INT){
  7021. -           if((Dc_arg_int >= 1) && (Dc_arg_int <= 10) && (Net_player->flags & NETINFO_FLAG_AM_MASTER)){
  7022. -               multi_voice_set_vars(Dc_arg_int,-1);
  7023. -               dc_printf("Quality of sound : %d\n",Dc_arg_int);
  7024. -           }
  7025. +   if (arg == NOX("qos")) {
  7026. +       dc_stuff_int(&value);
  7027. +       if((value >= 1) && (value <= 10) && (Net_player->flags & NETINFO_FLAG_AM_MASTER)){
  7028. +           multi_voice_set_vars(value,-1);
  7029. +           dc_printf("Quality of sound : %d\n", value);
  7030.         }
  7031.     }
  7032.  }
  7033. Index: network/multilag.cpp
  7034. ===================================================================
  7035. --- network/multilag.cpp    (Revision 10462)
  7036. +++ network/multilag.cpp    (Arbeitskopie)
  7037. @@ -18,6 +18,7 @@
  7038.  #include "io/timer.h"
  7039.  #include "globalincs/linklist.h"
  7040.  #include "network/psnet2.h"
  7041. +#include "debugconsole/console.h"
  7042.  
  7043.  
  7044.  
  7045. @@ -392,6 +393,7 @@
  7046.     Lag_buf_count--;
  7047.  }
  7048.  
  7049. +// Help and status provider for the lag-loss system
  7050.  void multi_lagloss_dcf()
  7051.  {
  7052.     // if the lag system isn't inited, don't do anything
  7053. @@ -400,20 +402,62 @@
  7054.         return;
  7055.     }
  7056.  
  7057. +   // display status of lag system
  7058. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  7059. +       dc_printf("Lag system status:\n");
  7060. +       // display lag settings
  7061. +       dc_printf("Lag : \n");
  7062. +       dc_printf("Base  \t\tMin   \t\tMax   \t\tStreak\n");
  7063. +       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);
  7064. +
  7065. +       // display loss settings
  7066. +       dc_printf("Loss : \n");
  7067. +       dc_printf("Base  \t\tMin   \t\tMax\n");
  7068. +       dc_printf("%f\t\t%f\t\t%f\n", Multi_loss_base, Multi_loss_min, Multi_loss_max);
  7069. +       return;
  7070. +   }
  7071. +
  7072.     // display all available commands
  7073. -   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");
  7074. +   dc_printf("Lag system commands\n\n");
  7075.  
  7076. -   // display lag settings
  7077. -   dc_printf("Lag : ");       
  7078. -   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);  
  7079. +   dc_printf("Usage :\n");
  7080. +   dc_printf("lag <ms>\n");
  7081. +       dc_printf("\tSets the lag base value if <ms> is within the max and min limits (see lag_min and lag_max)\n");
  7082. +       dc_printf("\tIf <ms> is outside of the max and min limits, then nothing is done\n");
  7083. +       dc_printf("\tIf <ms> is negative, then lag simulation is turned off\n\n");
  7084.  
  7085. -   // display loss settings
  7086. -   dc_printf("Loss : ");      
  7087. -   dc_printf("\n   Base %f\n   Min %f\n   Max %f\n", Multi_loss_base, Multi_loss_min, Multi_loss_max);
  7088. +   dc_printf("lag_min <ms>\n");
  7089. +       dc_printf("\tSets the lag min value if <ms> is less than the base value\n");
  7090. +       dc_printf("\tIf <ms> is outside the base or max values, then nothing is done\n");
  7091. +       dc_printf("\tIf <ms> is negative, then the min limit is removed\n\n");
  7092. +
  7093. +   dc_printf("lag_max <ms>\n");
  7094. +       dc_printf("\tSets the lag max value if <ms> is greater than the base value\n");
  7095. +       dc_printf("\tIf <ms> is outside the base or min values, then nothing is done\n");
  7096. +       dc_printf("\tIf <ms> is negative, then the max limit is removed\n\n");
  7097. +
  7098. +   dc_printf("loss    <0-100>  (-1 to disable)\n");
  7099. +       dc_printf("\tSimilar to lag, but applies value to loss base value\n\n");
  7100. +
  7101. +   dc_printf("loss_min <0-100>\n");
  7102. +       dc_printf("\tSimilar to lag_min, but applies value to loss min value\n\n");
  7103. +  
  7104. +   dc_printf("loss_max <0-100>\n");
  7105. +       dc_printf("\tSimilar to lag_max, but applies value to loss max value\n\n");
  7106. +
  7107. +
  7108. +   dc_printf("lag_streak <ms>\n");
  7109. +       dc_printf("\tSets the duration of lag streaks where the lag is consistant for <ms>\n");
  7110. +       dc_printf("\tEx: A value of 2000 would result in lag streaks that last 2 seconds each\n\n");
  7111. +
  7112. +   dc_printf("lagloss\n");
  7113. +       dc_printf("\tDisplays this text. Passing --status will display the status of the entire lag system");
  7114.  }
  7115.  
  7116. -DCF(lag, "")
  7117. +DCF(lag, "Sets the lag base value (Muliplayer)")
  7118.  {
  7119. +   int value;
  7120. +
  7121.     // if the lag system isn't inited, don't do anything
  7122.     if(!Multi_lag_inited){
  7123.         dc_printf("Lag System Not Initialized!\n");
  7124. @@ -420,29 +464,44 @@
  7125.         return;
  7126.     }
  7127.  
  7128. -   dc_get_arg(ARG_INT);       
  7129. +   if (dc_optional_string_either("help", "--help")) {
  7130. +       multi_lagloss_dcf();
  7131. +       return;
  7132. +   }
  7133. +
  7134. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  7135. +       dc_printf("Lag base value is currently %i\n", Multi_lag_base);
  7136. +       return;
  7137. +   }
  7138. +
  7139. +   dc_stuff_int(&value);
  7140.     // parse the argument and change things around accordingly
  7141. -   if(Dc_arg_type & ARG_INT){         
  7142. -       if(Dc_arg_int < 0){
  7143. -           // switch the lag sim off
  7144. -           Multi_lag_base = -1;
  7145. -           Multi_lag_min = -1;
  7146. -           Multi_lag_max = -1;
  7147. -           dc_printf("Turning simulated lag off\n");
  7148. -           multi_lagloss_dcf();
  7149. -       } else if((Multi_lag_max >= 0) && (Dc_arg_int > Multi_lag_max)){
  7150. -           dc_printf("Base value greater than max value, ignoring...");
  7151. -       } else if((Multi_lag_min >= 0) && (Dc_arg_int < Multi_lag_min)){
  7152. -           dc_printf("Base value smaller than min value, ignoring...");
  7153. -       } else {
  7154. -           Multi_lag_base = Dc_arg_int;
  7155. -           multi_lagloss_dcf();
  7156. -       }
  7157. -   }  
  7158. +   if (value < 0) {
  7159. +       // switch the lag sim off
  7160. +       Multi_lag_base = -1;
  7161. +       Multi_lag_min = -1;
  7162. +       Multi_lag_max = -1;
  7163. +       dc_printf("Turning simulated lag off\n");
  7164. +       multi_lagloss_dcf();
  7165. +
  7166. +   } else if ((Multi_lag_max >= 0) && (value > Multi_lag_max)) {
  7167. +       dc_printf("Base value greater than max value, ignoring...");
  7168. +
  7169. +   } else if ((Multi_lag_min >= 0) && (value < Multi_lag_min)) {
  7170. +       dc_printf("Base value smaller than min value, ignoring...");
  7171. +
  7172. +   } else {
  7173. +
  7174. +       Multi_lag_base = value;
  7175. +       multi_lagloss_dcf();
  7176. +       dc_printf("Base value set to %i", value);
  7177. +   }
  7178.  }
  7179.  
  7180. -DCF(lag_min, "")
  7181. +DCF(lag_min, "Sets the lag min value (Multiplayer)")
  7182.  {
  7183. +   int value;
  7184. +
  7185.     // if the lag system isn't inited, don't do anything
  7186.     if(!Multi_lag_inited){
  7187.         dc_printf("Lag System Not Initialized!\n");
  7188. @@ -449,48 +508,70 @@
  7189.         return;
  7190.     }
  7191.  
  7192. -   dc_get_arg(ARG_INT);       
  7193. +   if (dc_optional_string_either("help", "--help")) {
  7194. +       multi_lagloss_dcf();
  7195. +   }
  7196. +
  7197. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  7198. +       dc_printf("Lag min value is currently %i\n", Multi_lag_min);
  7199. +   }
  7200. +
  7201. +   dc_stuff_int(&value);
  7202.     // parse the argument and change things around accordingly
  7203. -   if(Dc_arg_type & ARG_INT){         
  7204. -       if(Dc_arg_int > Multi_lag_base){
  7205. -           dc_printf("Min value greater than base value, ignoring...");
  7206. -       } else {
  7207. -           if(Dc_arg_int < 0){
  7208. -               Multi_lag_min = -1;
  7209. -           } else {
  7210. -               Multi_lag_min = Dc_arg_int;
  7211. -           }
  7212. -           multi_lagloss_dcf();
  7213. -       }
  7214. -   }          
  7215. +  
  7216. +   if (value > Multi_lag_base) {
  7217. +       dc_printf("Min value greater than base value, ignoring...");
  7218. +       return;
  7219. +
  7220. +   } else if (value < 0) {
  7221. +       Multi_lag_min = -1;
  7222. +
  7223. +   } else {
  7224. +       Multi_lag_min = value;
  7225. +   }
  7226. +   dc_printf("Lag min value set to %i\n", Multi_lag_min);
  7227.  }
  7228.  
  7229. -DCF(lag_max, "")
  7230. +DCF(lag_max, "Sets the lag max value (Multiplayer)")
  7231.  {
  7232. +   int value;
  7233. +
  7234.     // if the lag system isn't inited, don't do anything
  7235. -   if(!Multi_lag_inited){
  7236. +   if (!Multi_lag_inited) {
  7237.         dc_printf("Lag System Not Initialized!\n");
  7238.         return;
  7239.     }
  7240.  
  7241. +   if (dc_optional_string_either("help", "--help")) {
  7242. +       multi_lagloss_dcf();
  7243. +       return;
  7244. +   }
  7245. +
  7246. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  7247. +       dc_printf("Lag max value is currently %i\n", Multi_lag_max);
  7248. +       return;
  7249. +   }
  7250. +
  7251.     // parse the argument and change things around accordingly
  7252. -   dc_get_arg(ARG_INT);
  7253. -   if(Dc_arg_type & ARG_INT){         
  7254. -       if((Dc_arg >=0) && (Dc_arg_int < Multi_lag_base)){
  7255. -           dc_printf("Max value smaller than base value, ignoring...");
  7256. -       } else {
  7257. -           if(Dc_arg_int < 0){
  7258. -               Multi_lag_max = -1;
  7259. -           } else {
  7260. -               Multi_lag_max = Dc_arg_int;
  7261. -           }
  7262. -           multi_lagloss_dcf();
  7263. -       }
  7264. -   }      
  7265. +   dc_stuff_int(&value);
  7266. +  
  7267. +   if ((value >= 0) && (value < Multi_lag_base)) {
  7268. +       dc_printf("Max value smaller than base value, ignoring...");
  7269. +
  7270. +   } else if (value < 0) {
  7271. +       Multi_lag_max = -1;
  7272. +
  7273. +   } else {
  7274. +       Multi_lag_max = value;
  7275. +   }
  7276. +   dc_printf("Lag max value set to %i\n", Multi_lag_max);
  7277.  }
  7278.  
  7279. -DCF(loss, "")
  7280. +DCF(loss, "Sets the loss base value (Multiplayer)")
  7281.  {
  7282. +   int val_i;
  7283. +   float val_f;
  7284. +
  7285.     // if the lag system isn't inited, don't do anything
  7286.     if(!Multi_lag_inited){
  7287.         dc_printf("Lag System Not Initialized!\n");
  7288. @@ -497,33 +578,46 @@
  7289.         return;
  7290.     }
  7291.  
  7292. +       if (dc_optional_string_either("help", "--help")) {
  7293. +       multi_lagloss_dcf();
  7294. +       return;
  7295. +   }
  7296. +
  7297. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  7298. +       dc_printf("Loss value is currently %i percent", Multi_loss_base);
  7299. +       return;
  7300. +   }
  7301. +
  7302.     // parse the argument and change things around accordingly
  7303. -   dc_get_arg(ARG_INT);
  7304. -   if(Dc_arg_type & ARG_INT){
  7305. -       float val = (float)Dc_arg_int / 100.0f;
  7306. -          
  7307. -       if(Dc_arg_int > 100){
  7308. -           dc_printf("Illegal loss base value, ignoring...");
  7309. -       } else if(Dc_arg_int < 0){
  7310. -           // switch the loss sim off
  7311. -           dc_printf("Turning simulated loss off\n");
  7312. -           Multi_loss_base = -1.0f;
  7313. -           Multi_loss_min = -1.0f;
  7314. -           Multi_loss_max = -1.0f;
  7315. -           multi_lagloss_dcf();
  7316. -       } else if((Multi_loss_max >= 0.0f) && (val > Multi_loss_max)){
  7317. -           dc_printf("Base value greater than max value, ignoring...");
  7318. -       } else if((Multi_loss_min >= 0.0f) && (val < Multi_loss_min)){
  7319. -           dc_printf("Base value smaller than min value, ignoring...");
  7320. -       } else {
  7321. -           Multi_loss_base = val;
  7322. -           multi_lagloss_dcf();
  7323. -       }
  7324. -   }          
  7325. +   dc_stuff_int(&val_i);
  7326. +
  7327. +   val_f = (float)val_i / 100.0f;
  7328. +      
  7329. +   if(val_i > 100){
  7330. +       dc_printf("Illegal loss base value, ignoring...");
  7331. +   } else if (val_i < 0){
  7332. +       // switch the loss sim off
  7333. +       dc_printf("Turning simulated loss off\n");
  7334. +       Multi_loss_base = -1.0f;
  7335. +       Multi_loss_min = -1.0f;
  7336. +       Multi_loss_max = -1.0f;
  7337. +
  7338. +   } else if((Multi_loss_max >= 0.0f) && (val_f > Multi_loss_max)){
  7339. +       dc_printf("Base value greater than max value, ignoring...");
  7340. +
  7341. +   } else if((Multi_loss_min >= 0.0f) && (val_f < Multi_loss_min)){
  7342. +       dc_printf("Base value smaller than min value, ignoring...");
  7343. +
  7344. +   } else {
  7345. +       Multi_loss_base = val_f;
  7346. +   }
  7347.  }
  7348.  
  7349. -DCF(loss_min, "")
  7350. +DCF(loss_min, "Sets the loss min value (Multiplayer)")
  7351.  {
  7352. +   int val_i;
  7353. +   float val_f;
  7354. +
  7355.     // if the lag system isn't inited, don't do anything
  7356.     if(!Multi_lag_inited){
  7357.         dc_printf("Lag System Not Initialized!\n");
  7358. @@ -530,27 +624,36 @@
  7359.         return;
  7360.     }
  7361.  
  7362. +   if (dc_optional_string_either("help", "--help")) {
  7363. +       multi_lagloss_dcf();
  7364. +       return;
  7365. +   }
  7366. +
  7367. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  7368. +       dc_printf("loss_min value is currently %f percent", Multi_loss_min);
  7369. +   }
  7370. +
  7371.     // parse the argument and change things around accordingly
  7372. -   dc_get_arg(ARG_INT);
  7373. -   if(Dc_arg_type & ARG_INT){         
  7374. -      float val = (float)Dc_arg_int / 100.0f;
  7375. +   dc_stuff_int(&val_i);
  7376.  
  7377. -       if(val > Multi_loss_base){
  7378. -           dc_printf("Min value greater than base value, ignoring...");
  7379. +   val_f = (float)val_i / 100.0f;
  7380. +
  7381. +   if(val_f > Multi_loss_base){
  7382. +       dc_printf("Min value greater than base value, ignoring...");
  7383. +   } else {
  7384. +       // otherwise set the value
  7385. +       if (val_f < 0) {
  7386. +           Multi_loss_min = -1.0f;
  7387.         } else {
  7388. -           // otherwise set the value
  7389. -           if(Dc_arg_int < 0){
  7390. -               Multi_loss_min = -1.0f;
  7391. -           } else {
  7392. -               Multi_loss_min = val;
  7393. -           }
  7394. -           multi_lagloss_dcf();
  7395. +           Multi_loss_min = val_f;
  7396.         }
  7397.     }
  7398.  }
  7399.  
  7400. -DCF(loss_max, "")
  7401. -{ 
  7402. +DCF(loss_max, "Sets the loss max value (Multiplayer)")
  7403. +{
  7404. +   int val_i;
  7405. +   float val_f;
  7406.     // if the lag system isn't inited, don't do anything
  7407.     if(!Multi_lag_inited){
  7408.         dc_printf("Lag System Not Initialized!\n");
  7409. @@ -557,26 +660,32 @@
  7410.         return;
  7411.     }
  7412.  
  7413. +   if (dc_optional_string_either("help", "--help")) {
  7414. +       multi_lagloss_dcf();
  7415. +       return;
  7416. +   }
  7417. +
  7418. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  7419. +       dc_printf("loss_max value is currently %f percent", Multi_loss_max);
  7420. +   }
  7421. +
  7422.     // parse the argument and change things around accordingly
  7423. -   dc_get_arg(ARG_INT);
  7424. -   if(Dc_arg_type & ARG_INT){         
  7425. -      float val = (float)Dc_arg_int / 100.0f;
  7426. +   dc_stuff_int(&val_i);
  7427. +   val_f = (float)val_i / 100.0f;
  7428.  
  7429. -       if(val < Multi_loss_base){
  7430. -           dc_printf("Max value smaller than base value, ignoring...");
  7431. +   if (val_f < Multi_loss_base) {
  7432. +       dc_printf("Max value smaller than base value, ignoring...");
  7433. +   } else {
  7434. +       // otherwise set the value
  7435. +       if (val_f < 0) {
  7436. +           Multi_loss_max = -1.0f;
  7437.         } else {
  7438. -           // otherwise set the value
  7439. -           if(Dc_arg_int < 0){
  7440. -               Multi_loss_max = -1.0f;
  7441. -           } else {
  7442. -               Multi_loss_min = val;
  7443. -           }
  7444. -           multi_lagloss_dcf();
  7445. +           Multi_loss_max = val_f;
  7446.         }
  7447. -   }          
  7448. +   }
  7449.  }
  7450.  
  7451. -DCF(lagloss, "")
  7452. +DCF(lagloss, "Help provider for the lag system (Multiplayer)")
  7453.  {
  7454.     // if the lag system isn't inited, don't do anything
  7455.     if(!Multi_lag_inited){
  7456. @@ -587,23 +696,35 @@
  7457.     multi_lagloss_dcf();
  7458.  }
  7459.  
  7460. -DCF(lag_streak, "")
  7461. +DCF(lag_streak, "Sets the duration of lag streaks (Multiplayer)")
  7462.  {
  7463. +   int val;
  7464. +
  7465.     // if the lag system isn't inited, don't do anything
  7466. -   if(!Multi_lag_inited){
  7467. +   if (!Multi_lag_inited) {
  7468.         dc_printf("Lag System Not Initialized!\n");
  7469.         return;
  7470.     }
  7471.  
  7472. -   dc_get_arg(ARG_INT);
  7473. -   if(Dc_arg_type & ARG_INT){                     
  7474. -       if(Dc_arg_int >= 0){
  7475. -           Multi_streak_time = Dc_arg_int;
  7476. -       }
  7477. +   if (dc_optional_string_either("help", "--help")) {
  7478. +       multi_lagloss_dcf();
  7479. +       return;
  7480.     }
  7481. +
  7482. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  7483. +       dc_printf("lag_streak value is currently %i", Multi_streak_time);
  7484. +       return;
  7485. +   }
  7486. +
  7487. +   dc_stuff_int(&val);
  7488. +   if(val >= 0){
  7489. +       Multi_streak_time = val;
  7490. +   } else {
  7491. +       dc_printf("Ignoring invalid value (must be non-negative)\n");
  7492. +   }
  7493.  }
  7494.  
  7495. -DCF(lag_bad, "")
  7496. +DCF(lag_bad, "Lag system shortcut - Sets for 'bad' lag simulation (Multiplayer)")
  7497.  {
  7498.     // if the lag system isn't inited, don't do anything
  7499.     if(!Multi_lag_inited){
  7500. @@ -610,6 +731,11 @@
  7501.         dc_printf("Lag System Not Initialized!\n");
  7502.         return;
  7503.     }
  7504. +  
  7505. +   if (dc_optional_string_either("help", "--help")) {
  7506. +       multi_lagloss_dcf();
  7507. +       return;
  7508. +   }
  7509.  
  7510.     dc_printf("Setting bad lag/loss parameters\n");
  7511.  
  7512. @@ -627,7 +753,7 @@
  7513.     Multi_current_streak = -1;
  7514.  }
  7515.  
  7516. -DCF(lag_avg, "")
  7517. +DCF(lag_avg, "Lag system shortcut - Sets for 'average' lag simulation (Multiplayer)")
  7518.  {
  7519.     // if the lag system isn't inited, don't do anything
  7520.     if(!Multi_lag_inited){
  7521. @@ -635,6 +761,11 @@
  7522.         return;
  7523.     }
  7524.  
  7525. +   if (dc_optional_string_either("help", "--help")) {
  7526. +       multi_lagloss_dcf();
  7527. +       return;
  7528. +   }
  7529. +
  7530.     dc_printf("Setting avg lag/loss parameters\n");
  7531.  
  7532.     // set good lagloss parameters
  7533. @@ -651,7 +782,7 @@
  7534.     Multi_current_streak = -1;
  7535.  }
  7536.  
  7537. -DCF(lag_good, "")
  7538. +DCF(lag_good, "Lag system shortcut - Sets for 'good' lag simulation (Multiplayer)")
  7539.  {
  7540.     // if the lag system isn't inited, don't do anything
  7541.     if(!Multi_lag_inited){
  7542. @@ -659,6 +790,11 @@
  7543.         return;
  7544.     }
  7545.  
  7546. +   if (dc_optional_string_either("help", "--help")) {
  7547. +       multi_lagloss_dcf();
  7548. +       return;
  7549. +   }
  7550. +
  7551.     dc_printf("Setting good lag/loss parameters\n");
  7552.  
  7553.     // set good lagloss parameters
  7554. Index: network/multiui.cpp
  7555. ===================================================================
  7556. --- network/multiui.cpp (Revision 10462)
  7557. +++ network/multiui.cpp (Arbeitskopie)
  7558. @@ -64,6 +64,7 @@
  7559.  #include "cfile/cfile.h"
  7560.  #include "fs2netd/fs2netd_client.h"
  7561.  #include "menuui/mainhallmenu.h"
  7562. +#include "debugconsole/console.h"
  7563.  
  7564.  #include <algorithm>
  7565.  
  7566. @@ -754,13 +755,20 @@
  7567.  int multi_join_warn_pxo();
  7568.  void multi_join_blit_protocol();
  7569.  
  7570. -DCF(mj_make, "")
  7571. +DCF(mj_make, "Makes a multijoin game? (Multiplayer)")
  7572.  {
  7573.     active_game ag, *newitem;
  7574.     int idx;
  7575. +   int idx_max;
  7576.  
  7577. -   dc_get_arg(ARG_INT);
  7578. -   for(idx=0; idx<Dc_arg_int; idx++){
  7579. +   if (dc_optional_string_either("help", "--help")) {
  7580. +       dc_printf("Usage: mj_make <num_games>\n");
  7581. +       return;
  7582. +   }
  7583. +
  7584. +   dc_stuff_int(&idx_max);
  7585. +
  7586. +   for(idx = 0; idx < idx_max; idx++){
  7587.         // stuff some fake info
  7588.         memset(&ag, 0, sizeof(active_game));
  7589.         sprintf(ag.name, "Game %d", idx);
  7590. @@ -776,7 +784,7 @@
  7591.         if(newitem != NULL){
  7592.             // newitem->heard_from_timer = timestamp((int)frand_range(500.0f, 10000.0f));
  7593.         }
  7594. -   }  
  7595. +   }
  7596.  }
  7597.  
  7598.  void multi_join_notify_new_game()
  7599. Index: network/multiutil.cpp
  7600. ===================================================================
  7601. --- network/multiutil.cpp   (Revision 10462)
  7602. +++ network/multiutil.cpp   (Arbeitskopie)
  7603. @@ -77,6 +77,7 @@
  7604.  #include "network/multi_rate.h"
  7605.  #include "fs2netd/fs2netd_client.h"
  7606.  #include "parse/parselo.h"
  7607. +#include "debugconsole/console.h"
  7608.  
  7609.  extern int ascii_table[];
  7610.  extern int shifted_ascii_table[];
  7611. @@ -3198,65 +3199,73 @@
  7612.  // ------------------------------------
  7613.  
  7614.  //XSTR:OFF
  7615. -DCF(multi,"changes multiplayer settings")
  7616. +DCF(multi,"changes multiplayer settings (Multiplayer)")
  7617.  {
  7618. -   if(Dc_command){
  7619. -       dc_get_arg(ARG_STRING);
  7620. -      
  7621. -       if(strcmp(Dc_arg, "kick")==0){              // kick a player
  7622. -           multi_dcf_kick();
  7623. +   if (dc_optional_string("kick")) {
  7624. +       // kick a player
  7625. +       multi_dcf_kick();
  7626. +
  7627.  #ifndef NDEBUG
  7628. -       } else if(strcmp(Dc_arg, "stats")==0) {
  7629. -           // multi_toggle_stats();
  7630. -       } else if(strcmp(Dc_arg, "show_stats")==0) {
  7631. -           // multi_show_basic_stats(0);
  7632. -       } else if(strcmp(Dc_arg, "dump_stats")==0) {
  7633. -           // multi_show_basic_stats(1);
  7634. +   } else if (dc_optional_string("stats")) {
  7635. +       // multi_toggle_stats();
  7636. +
  7637. +   } else if (dc_optional_string("show_stats")) {
  7638. +       // multi_show_basic_stats(0);
  7639. +
  7640. +   } else if (dc_optional_string("dump_stats")) {
  7641. +       // multi_show_basic_stats(1);
  7642.  #endif
  7643. -       } else if(strcmp(Dc_arg, "voice")==0){              // settings for multiplayer voice
  7644. -           multi_voice_dcf();
  7645. -       } else if(strcmp(Dc_arg, "respawn_chump")==0){  // set a really large # of respawns
  7646. -           if((Net_player != NULL) && (Net_player->flags & NETINFO_FLAG_GAME_HOST)){          
  7647. -               Netgame.respawn = 9999;
  7648. -               Netgame.options.respawn = 9999;            
  7649.  
  7650. -               // if i'm the server, send a netgame update
  7651. -               if(Net_player->flags & NETINFO_FLAG_AM_MASTER){
  7652. -                   send_netgame_update_packet();
  7653. -               }
  7654. -           }
  7655. -       } else if(strcmp(Dc_arg, "ss_leaders")==0){     // only host or team captains can modify ships
  7656. -           if((Net_player != NULL) && (Net_player->flags & NETINFO_FLAG_GAME_HOST)){          
  7657. -               Netgame.options.flags |= MSO_FLAG_SS_LEADERS;
  7658. -               multi_options_update_netgame();
  7659. -           }
  7660. -       } else if(strcmp(Dc_arg, "make_players")==0){
  7661. +   } else if (dc_optional_string("voice")) {
  7662. +       // settings for multiplayer voice
  7663. +       multi_voice_dcf();
  7664. +
  7665. +   } else if (dc_optional_string("respawn_chump")){
  7666. +       // set a really large # of respawns
  7667. +       if((Net_player != NULL) && (Net_player->flags & NETINFO_FLAG_GAME_HOST)) {
  7668. +           Netgame.respawn = 9999;
  7669. +           Netgame.options.respawn = 9999;
  7670. +
  7671. +           // if i'm the server, send a netgame update
  7672. +           if(Net_player->flags & NETINFO_FLAG_AM_MASTER){
  7673. +               send_netgame_update_packet();
  7674. +           }
  7675. +       }
  7676. +
  7677. +   } else if (dc_optional_string("ss_leaders")) {
  7678. +       // only host or team captains can modify ships
  7679. +       if((Net_player != NULL) && (Net_player->flags & NETINFO_FLAG_GAME_HOST)) {
  7680. +           Netgame.options.flags |= MSO_FLAG_SS_LEADERS;
  7681. +           multi_options_update_netgame();
  7682. +       }
  7683. +
  7684. +   } else if (dc_optional_string("make_players")) {
  7685.  #ifndef NDEBUG
  7686. -           multi_make_fake_players(MAX_PLAYERS);
  7687. +       multi_make_fake_players(MAX_PLAYERS);
  7688.  #endif
  7689. -       } else if(strcmp(Dc_arg, "givecd")==0){
  7690. -           extern int Multi_has_cd;
  7691. -           Multi_has_cd = 1;
  7692. -       } else if(strcmp(Dc_arg, "oo")==0){                    
  7693. -           int new_flags = -1;
  7694.  
  7695. -           dc_get_arg(ARG_INT);
  7696. -           if(Dc_arg_type & ARG_INT){
  7697. -               new_flags = Dc_arg_int;
  7698. -           }
  7699. +   } else if (dc_optional_string("givecd")) {
  7700. +       extern int Multi_has_cd;
  7701. +       Multi_has_cd = 1;
  7702.  
  7703. -           dc_printf("Interesting flags\nPos : %d\nVelocity : %d\nDesired vel : %d\nOrient : %d\nRotvel : %d\nDesired rotvel %d\n",
  7704. -                        1<<0, 1<<7, 1<<8, 1<<1, 1<<9, 1<<10);                     
  7705. -       } else if(strcmp(Dc_arg, "oo_sort")==0){           
  7706. -           extern int OO_sort;
  7707. +   } else if (dc_optional_string("oo")) {
  7708. +       int new_flags = -1;
  7709.  
  7710. -           OO_sort = !OO_sort;
  7711. -           if(OO_sort){
  7712. -               dc_printf("Network object sorting ENABLED\n");
  7713. -           } else {
  7714. -               dc_printf("Network object sorting DISABLED\n");
  7715. -           }
  7716. -       }
  7717. +       dc_maybe_stuff_int(&new_flags);
  7718. +
  7719. +       dc_printf("Interesting flags\n");
  7720. +       dc_printf("Pos : %d\n", 1 << 0);
  7721. +       dc_printf("Velocity    : %d\n", 1 << 7);
  7722. +       dc_printf("Desired vel : %d\n", 1 << 8);
  7723. +       dc_printf("Orient : %d\n", 1 << 1);
  7724. +       dc_printf("Rotvel : %d\n", 1 << 9);
  7725. +       dc_printf("Desired rotvel : %d\n", 1 << 10);
  7726. +
  7727. +   } else if (dc_optional_string("oo_sort")) {
  7728. +       extern int OO_sort;
  7729. +
  7730. +       OO_sort = !OO_sort;
  7731. +       dc_printf("Network object sorting %s\n", OO_sort ? "ENABLED" : "DISABLED");
  7732.     }
  7733.  }
  7734.  
  7735. @@ -3447,19 +3456,20 @@
  7736.  }
  7737.  */
  7738.  
  7739. -DCF(pxospew,"spew PXO 32 bit checksums for all visible mission files")
  7740. +DCF(pxospew,"spew PXO 32 bit checksums for all visible mission files (Multiplayer)")
  7741.  {
  7742.     int max_files;
  7743. +   char file_str[MAX_NAME_LEN];
  7744.  
  7745. -   dc_get_arg(ARG_INT);
  7746. -   if(Dc_arg_type & ARG_INT){
  7747. -       max_files = Dc_arg_int;
  7748. +   if (dc_optional_string_either("help", "--help")) {
  7749. +       dc_printf("Usage: pxospew <max_files> <filename>\n");
  7750. +       return;
  7751. +   }
  7752.  
  7753. -       dc_get_arg(ARG_STRING);
  7754. -       if(Dc_arg_type & ARG_STRING){
  7755. -           multi_spew_pxo_checksums(max_files, Dc_arg);
  7756. -       }
  7757. -   }
  7758. +   dc_stuff_int(&max_files);
  7759. +   dc_stuff_string_white(file_str, MAX_NAME_LEN);
  7760. +
  7761. +   multi_spew_pxo_checksums(max_files, file_str);
  7762.  }
  7763.  
  7764.  
  7765. Index: object/collideshipship.cpp
  7766. ===================================================================
  7767. --- object/collideshipship.cpp  (Revision 10462)
  7768. +++ object/collideshipship.cpp  (Arbeitskopie)
  7769. @@ -27,6 +27,7 @@
  7770.  #include "object/objectdock.h"
  7771.  #include "object/objectshield.h"
  7772.  #include "parse/scripting.h"
  7773. +#include "debugconsole/console.h"
  7774.  
  7775.  
  7776.  #define COLLIDE_DEBUG
  7777. Index: object/object.cpp
  7778. ===================================================================
  7779. --- object/object.cpp   (Revision 10462)
  7780. +++ object/object.cpp   (Arbeitskopie)
  7781. @@ -41,6 +41,7 @@
  7782.  #include "weapon/shockwave.h"
  7783.  #include "weapon/swarm.h"
  7784.  #include "weapon/weapon.h"
  7785. +#include "debugconsole/console.h"
  7786.  
  7787.  
  7788.  
  7789. Index: object/objectsnd.cpp
  7790. ===================================================================
  7791. --- object/objectsnd.cpp    (Revision 10462)
  7792. +++ object/objectsnd.cpp    (Arbeitskopie)
  7793. @@ -22,9 +22,9 @@
  7794.  #include "render/3d.h"
  7795.  #include "io/joy_ff.h"
  7796.  #include "species_defs/species_defs.h"
  7797. +#include "debugconsole/console.h"
  7798.  
  7799.  
  7800. -
  7801.  //  // --mharris port hack--
  7802.  //  int ds_using_ds3d();
  7803.  //  int ds_get_channel(int);
  7804. @@ -96,63 +96,66 @@
  7805.  //XSTR:OFF
  7806.  DCF(objsnd, "Persistent sound stuff" )
  7807.  {
  7808. -   char        buf1[16], buf2[64];
  7809. -   obj_snd *osp;
  7810. +   char buf1[4];
  7811. +   char buf2[MAX_NAME_LEN];
  7812. +   obj_snd *osp;
  7813. +   SCP_string arg;
  7814.  
  7815. -   if ( Dc_command )   {
  7816. -       dc_get_arg(ARG_STRING|ARG_NONE);
  7817. +   if (dc_optional_string_either("help", "--help")) {
  7818. +       dc_printf ("Usage: objsnd [-list]\n");
  7819. +       dc_printf ("[-list] --  displays status of all objects with linked sounds\n");
  7820. +       dc_printf ("with no parameters, object sounds are toggled on/off\n");
  7821. +       return;
  7822. +   }
  7823.  
  7824. -       if ( Dc_arg_type & ARG_NONE ) {
  7825. -           if ( Obj_snd_enabled == TRUE ) {
  7826. -               obj_snd_stop_all();
  7827. -               Obj_snd_enabled = FALSE;
  7828. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  7829. +       dc_printf( "Object sounds are: %s\n", (Obj_snd_enabled?"ON":"OFF") );
  7830. +   }
  7831. +  
  7832. +   if (dc_optional_string("-list")) {
  7833. +       for ( osp = GET_FIRST(&obj_snd_list); osp !=END_OF_LIST(&obj_snd_list); osp = GET_NEXT(osp) ) {
  7834. +           vec3d source_pos;
  7835. +           float distance;
  7836. +
  7837. +           Assert(osp != NULL);
  7838. +           if ( osp->instance == -1 ) {
  7839. +               continue;
  7840. +               //sprintf(buf1,"OFF");
  7841. +           } else {
  7842. +               sprintf(buf1,"ON");
  7843.             }
  7844. +
  7845. +           if ( Objects[osp->objnum].type == OBJ_SHIP ) {
  7846. +               strcpy_s(buf2, Ships[Objects[osp->objnum].instance].ship_name);
  7847. +           }
  7848. +           else if ( Objects[osp->objnum].type == OBJ_DEBRIS ) {
  7849. +               sprintf(buf2, "Debris");
  7850. +           }
  7851.             else {
  7852. -               Obj_snd_enabled = TRUE;
  7853. +               sprintf(buf2, "Unknown");
  7854.             }
  7855. -       }
  7856. -       if ( !stricmp( Dc_arg, "list" ))    {
  7857. -           for ( osp = GET_FIRST(&obj_snd_list); osp !=END_OF_LIST(&obj_snd_list); osp = GET_NEXT(osp) ) {
  7858. -               Assert(osp != NULL);
  7859. -               if ( osp->instance == -1 ) {
  7860. -                   continue;
  7861. -                   //sprintf(buf1,"OFF");
  7862. -               } else {
  7863. -                   sprintf(buf1,"ON");
  7864. -               }
  7865.  
  7866. -               if ( Objects[osp->objnum].type == OBJ_SHIP ) {
  7867. -                   strcpy_s(buf2, Ships[Objects[osp->objnum].instance].ship_name);
  7868. -               }
  7869. -               else if ( Objects[osp->objnum].type == OBJ_DEBRIS ) {
  7870. -                   sprintf(buf2, "Debris");
  7871. -               }
  7872. -               else {
  7873. -                   sprintf(buf2, "Unknown");
  7874. -               }
  7875. +           obj_snd_source_pos(&source_pos, osp);
  7876. +           distance = vm_vec_dist_quick( &source_pos, &View_position );
  7877.  
  7878. -               vec3d source_pos;
  7879. -               float distance;
  7880. +           dc_printf("Object %d => name: %s vol: %.2f pan: %.2f dist: %.2f status: %s\n", osp->objnum, buf2, osp->vol, osp->pan, distance, buf1);
  7881. +       } // end for
  7882.  
  7883. -               obj_snd_source_pos(&source_pos, osp);
  7884. -               distance = vm_vec_dist_quick( &source_pos, &View_position );
  7885. +       dc_printf("Number object-linked sounds playing: %d\n", Num_obj_sounds_playing);
  7886. +       return;
  7887. +   }
  7888.  
  7889. -               dc_printf("Object %d => name: %s vol: %.2f pan: %.2f dist: %.2f status: %s\n", osp->objnum, buf2, osp->vol, osp->pan, distance, buf1);
  7890. -           } // end for
  7891. -               dc_printf("Number object-linked sounds playing: %d\n", Num_obj_sounds_playing);
  7892. +   if (!dc_maybe_stuff_string_white(arg)) {
  7893. +       // No arguments, toggle snd on/off
  7894. +       if ( Obj_snd_enabled == TRUE ) {
  7895. +               obj_snd_stop_all();
  7896. +               Obj_snd_enabled = FALSE;
  7897. +           } else {
  7898. +               Obj_snd_enabled = TRUE;
  7899.         }
  7900. +   } else {
  7901. +       dc_printf("Unknown argument '%s'\n", arg.c_str());
  7902.     }
  7903. -
  7904. -   if ( Dc_help ) {
  7905. -       dc_printf ("Usage: objsnd [list]\n");
  7906. -       dc_printf ("[list] --  displays status of all objects with linked sounds\n");
  7907. -       dc_printf ("with no parameters, object sounds are toggled on/off\n");
  7908. -       Dc_status = 0;
  7909. -   }
  7910. -
  7911. -   if ( Dc_status )    {
  7912. -       dc_printf( "Object sounds are: %s\n", (Obj_snd_enabled?"ON":"OFF") );
  7913. -   }
  7914.  }
  7915.  //XSTR:ON
  7916.  
  7917. Index: palman/palman.cpp
  7918. ===================================================================
  7919. --- palman/palman.cpp   (Revision 10462)
  7920. +++ palman/palman.cpp   (Arbeitskopie)
  7921. @@ -11,6 +11,7 @@
  7922.  
  7923.  #include "palman/palman.h"
  7924.  #include "bmpman/bmpman.h"
  7925. +#include "debugconsole/console.h"
  7926.  #include "pcxutils/pcxutils.h"
  7927.  #include "parse/parselo.h"
  7928.  #include "graphics/grinternal.h"
  7929. @@ -165,17 +166,14 @@
  7930.  
  7931.  DCF(palette,"Loads a new palette")
  7932.  {
  7933. -   if ( Dc_command )   {
  7934. -       dc_get_arg(ARG_STRING|ARG_NONE);
  7935. -       if ( Dc_arg_type == ARG_NONE )  {
  7936. -       } else {
  7937. -           palette_load_table( Dc_arg );
  7938. -       }
  7939. +   char palette_file[MAX_FILENAME_LEN];
  7940. +
  7941. +   if (dc_optional_string_either("help", "--help")) {
  7942. +       dc_printf( "Usage: palette <filename>\nLoads the palette file.\n" );
  7943.     }
  7944. -   if ( Dc_help )  {
  7945. -       dc_printf( "Usage: palette filename\nLoads the palette file.\n" );
  7946. -   }
  7947.  
  7948. +   dc_stuff_string_white(palette_file, MAX_FILENAME_LEN);
  7949. +   palette_load_table(palette_file);
  7950.  }
  7951.  
  7952.  int Palman_allow_any_color = 0;
  7953. Index: parse/sexp.cpp
  7954. ===================================================================
  7955. --- parse/sexp.cpp  (Revision 10462)
  7956. +++ parse/sexp.cpp  (Arbeitskopie)
  7957. @@ -96,6 +96,7 @@
  7958.  #include "mod_table/mod_table.h"
  7959.  #include "ship/afterburner.h"
  7960.  #include "globalincs/alphacolors.h"
  7961. +#include "debugconsole/console.h"
  7962.  
  7963.  #ifndef NDEBUG
  7964.  #include "hud/hudmessage.h"
  7965. @@ -24487,40 +24488,38 @@
  7966.     return sexp_val;
  7967.  }
  7968.  
  7969. -DCF(sexpc, "Always runs the given sexp command ")
  7970. +DCF(sexpc, "Always runs the given sexp command (Warning! There is no undo for this!)")
  7971.  {
  7972. -   if ( Dc_command )       {
  7973. -       if (Dc_command_line != NULL) {
  7974. -           char buf[8192];
  7975. -           snprintf(buf, 8191, "( when ( true ) ( %s ) )", Dc_command_line);
  7976. -
  7977. -           int sexp_val = run_sexp( buf );
  7978. -           dc_printf("SEXP '%s' run, sexp_val = %d\n", buf, sexp_val);
  7979. -           do {
  7980. -               dc_get_arg(ARG_ANY);
  7981. -           } while (Dc_arg_type != ARG_NONE);
  7982. -       }
  7983. -   }
  7984. -   if ( Dc_help )  {
  7985. +   SCP_string sexp;
  7986. +   SCP_string sexp_always;
  7987. +  
  7988. +   if (dc_optional_string_either("help", "--help")) {
  7989.         dc_printf( "Usage: sexpc sexpression\n. Always runs the given sexp as '( when ( true ) ( sexp ) )' .\n" );
  7990. +       return;
  7991.     }
  7992. +
  7993. +   dc_stuff_string(sexp);
  7994. +
  7995. +   sprintf(sexp_always, "( when ( true ) ( %s ) )", sexp.c_str());
  7996. +
  7997. +   int sexp_val = run_sexp(sexp_always.c_str());
  7998. +   dc_printf("SEXP '%s' run, sexp_val = %d\n", sexp_always.c_str(), sexp_val);
  7999.  }
  8000.  
  8001.  
  8002.  DCF(sexp,"Runs the given sexp")
  8003.  {
  8004. -   if ( Dc_command )       {
  8005. -       if (Dc_command_line != NULL) {
  8006. -           int sexp_val = run_sexp( Dc_command_line );
  8007. -           dc_printf("SEXP '%s' run, sexp_val = %d\n", Dc_command_line, sexp_val);
  8008. -           do {
  8009. -               dc_get_arg(ARG_ANY);
  8010. -           } while (Dc_arg_type != ARG_NONE);
  8011. -       }
  8012. -   }
  8013. -   if ( Dc_help )  {
  8014. +   SCP_string sexp;
  8015. +
  8016. +   if (dc_optional_string_either("help", "--help")) {
  8017.         dc_printf( "Usage: sexp 'sexpression'\n. Runs the given sexp.\n");
  8018. +       return;
  8019.     }
  8020. +
  8021. +   dc_stuff_string(sexp);
  8022. +
  8023. +   int sexp_val = run_sexp(sexp.c_str());
  8024. +   dc_printf("SEXP '%s' run, sexp_val = %d\n", dc_command_str.c_str(), sexp_val);
  8025.  }
  8026.  
  8027.  
  8028. Index: particle/particle.cpp
  8029. ===================================================================
  8030. --- particle/particle.cpp   (Revision 10462)
  8031. +++ particle/particle.cpp   (Arbeitskopie)
  8032. @@ -17,6 +17,7 @@
  8033.  #include "object/object.h"
  8034.  #include "cmdline/cmdline.h"
  8035.  #include "graphics/grbatch.h"
  8036. +#include "debugconsole/console.h"
  8037.  
  8038.  #ifndef NDEBUG
  8039.  #include "io/timer.h"
  8040. @@ -90,19 +91,8 @@
  8041.     bm_page_in_texture( Anim_bitmap_id_smoke2 );
  8042.  }
  8043.  
  8044. -DCF(particles,"Turns particles on/off")
  8045. -{
  8046. -   if ( Dc_command )   {  
  8047. -       dc_get_arg(ARG_TRUE|ARG_FALSE|ARG_NONE);       
  8048. -       if ( Dc_arg_type & ARG_TRUE )   Particles_enabled = 1
  8049. -       else if ( Dc_arg_type & ARG_FALSE ) Particles_enabled = 0
  8050. -       else if ( Dc_arg_type & ARG_NONE ) Particles_enabled ^= 1
  8051. -   }  
  8052. -   if ( Dc_help )  dc_printf( "Usage: particles [bool]\nTurns particle system on/off.  If nothing passed, then toggles it.\n" );  
  8053. -   if ( Dc_status )    dc_printf( "particles are %s\n", (Particles_enabled?"ON":"OFF") )
  8054. -}
  8055. +DCF_BOOL2(particles, Particles_enabled, "Turns particles on/off", "Usage: particles [bool]\nTurns particle system on/off.  If nothing passed, then toggles it.\n");
  8056.  
  8057. -
  8058.  int Num_particles_hwm = 0;
  8059.  
  8060.  // Creates a single particle. See the PARTICLE_?? defines for types.
  8061. Index: playerman/playercontrol.cpp
  8062. ===================================================================
  8063. --- playerman/playercontrol.cpp (Revision 10462)
  8064. +++ playerman/playercontrol.cpp (Arbeitskopie)
  8065. @@ -34,6 +34,7 @@
  8066.  #include "network/multiutil.h"
  8067.  #include "network/multi_obj.h"
  8068.  #include "parse/parselo.h"
  8069. +#include "debugconsole/console.h"
  8070.  
  8071.  #ifndef NDEBUG
  8072.  #include "io/key.h"
  8073. @@ -286,10 +287,16 @@
  8074.  
  8075.  float camera_zoom_scale = 1.0f;
  8076.  
  8077. -DCF(camera_speed, "")
  8078. +DCF(camera_speed, "Sets the camera zoom scale")
  8079.  {
  8080. -   dc_get_arg(ARG_FLOAT);
  8081. -   camera_zoom_scale = Dc_arg_float;
  8082. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  8083. +       dc_printf("Camera zoom scale is %f\n", camera_zoom_scale);
  8084. +       return;
  8085. +   }
  8086. +
  8087. +   dc_stuff_float(&camera_zoom_scale);
  8088. +
  8089. +   dc_printf("Camera zoom scale set to %f\n", camera_zoom_scale);
  8090.  }
  8091.  
  8092.  void do_view_external(float frame_time)
  8093. Index: radar/radarsetup.cpp
  8094. ===================================================================
  8095. --- radar/radarsetup.cpp    (Revision 10462)
  8096. +++ radar/radarsetup.cpp    (Arbeitskopie)
  8097. @@ -31,6 +31,7 @@
  8098.  #include "radar/radarsetup.h"
  8099.  #include "iff_defs/iff_defs.h"
  8100.  #include "globalincs/linklist.h"
  8101. +#include "debugconsole/console.h"
  8102.  
  8103.  int Radar_static_looping = -1;
  8104.  
  8105. @@ -84,7 +85,7 @@
  8106.  
  8107.  int See_all = 0;
  8108.  
  8109. -DCF_BOOL(see_all, See_all)
  8110. +DCF_BOOL(see_all, See_all);
  8111.  
  8112.  static const char radar_default_filenames[2][16]=
  8113.  {
  8114. Index: render/3dlaser.cpp
  8115. ===================================================================
  8116. --- render/3dlaser.cpp  (Revision 10462)
  8117. +++ render/3dlaser.cpp  (Arbeitskopie)
  8118. @@ -14,6 +14,7 @@
  8119.  #include "globalincs/systemvars.h"
  8120.  #include "io/key.h"
  8121.  #include "cmdline/cmdline.h"
  8122. +#include "debugconsole/console.h"
  8123.  
  8124.  
  8125.  
  8126. Index: ship/ship.cpp
  8127. ===================================================================
  8128. --- ship/ship.cpp   (Revision 10462)
  8129. +++ ship/ship.cpp   (Arbeitskopie)
  8130. @@ -80,6 +80,7 @@
  8131.  #include "graphics/gropenglshader.h"
  8132.  #include "model/model.h"
  8133.  #include "mod_table/mod_table.h"
  8134. +#include "debugconsole/console.h"
  8135.  
  8136.  
  8137.  #define NUM_SHIP_SUBSYSTEM_SETS            20      // number of subobject sets to use (because of the fact that it's a linked list,
  8138. @@ -8356,10 +8357,14 @@
  8139.  }
  8140.  
  8141.  float Decay_rate = 1.0f / 120.0f;
  8142. -DCF(lethality_decay, "time in sec to return from 100 to 0")
  8143. +DCF(lethality_decay, "Sets ship lethality_decay, or the time in sec to go from 100 to 0 health (default is 1/120)")
  8144.  {
  8145. -   dc_get_arg(ARG_FLOAT);
  8146. -   Decay_rate = Dc_arg_float;
  8147. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  8148. +       dc_printf("Decay rate is currently %f\n", Decay_rate);
  8149. +       return;
  8150. +   }
  8151. +  
  8152. +   dc_stuff_float(&Decay_rate);
  8153.  }
  8154.  
  8155.  float min_lethality = 0.0f;
  8156. @@ -9865,31 +9870,44 @@
  8157.  float t_vel = 0.2f;
  8158.  float t_min = 150.0f;
  8159.  float t_max = 300.0f;
  8160. -DCF(t_rad, "")
  8161. +DCF(t_rad, "Sets weapon tracer radius")
  8162.  {
  8163. -   dc_get_arg(ARG_FLOAT);
  8164. -   t_rad = Dc_arg_float;
  8165. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  8166. +       dc_printf("t_rad : %f\n", t_rad);
  8167. +       return;
  8168. +   }
  8169. +  
  8170. +   dc_stuff_float(&t_rad);
  8171.  }
  8172. -DCF(t_len, "")
  8173. +DCF(t_len, "Sets weapon tracer length")
  8174.  {
  8175. -   dc_get_arg(ARG_FLOAT);
  8176. -   t_len = Dc_arg_float;
  8177. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  8178. +       dc_printf("t_len : %f\n", t_len);
  8179. +       return;
  8180. +   }
  8181. +
  8182. +   dc_stuff_float(&t_len);
  8183.  }
  8184. -DCF(t_vel, "")
  8185. +DCF(t_vel, "Sets weapon tracer velocity")
  8186.  {
  8187. -   dc_get_arg(ARG_FLOAT);
  8188. -   t_vel = Dc_arg_float;
  8189. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  8190. +       dc_printf("t_vel : %f\n", t_vel);
  8191. +       return;
  8192. +   }
  8193. +
  8194. +   dc_stuff_float(&t_vel);
  8195.  }
  8196. +/*
  8197. + TODO: These two DCF's (and variables) are unused
  8198.  DCF(t_min, "")
  8199.  {
  8200. -   dc_get_arg(ARG_FLOAT);
  8201. -   t_min = Dc_arg_float;
  8202. +   dc_stuff_float(&t_min);
  8203.  }
  8204.  DCF(t_max, "")
  8205.  {
  8206. -   dc_get_arg(ARG_FLOAT);
  8207. -   t_max = Dc_arg_float;
  8208. +   dc_stuff_float(&t_max);
  8209.  }
  8210. +*/
  8211.  void ship_fire_tracer(int weapon_objnum)
  8212.  {
  8213.     particle_info pinfo;
  8214. @@ -13611,26 +13629,25 @@
  8215.   */
  8216.  DCF(set_shield,"Change player ship shield strength")
  8217.  {
  8218. -   if ( Dc_command )   {
  8219. -       dc_get_arg(ARG_FLOAT|ARG_NONE);
  8220. +   float value;
  8221.  
  8222. -       if ( Dc_arg_type & ARG_FLOAT ) {
  8223. -            CLAMP(Dc_arg_float, 0.0f, 1.0f);
  8224. -           shield_set_strength(Player_obj, Dc_arg_float * Player_ship->ship_max_shield_strength);
  8225. -           dc_printf("Shields set to %.2f\n", shield_get_strength(Player_obj) );
  8226. -       }
  8227. -   }
  8228. -
  8229. -   if ( Dc_help ) {
  8230. +   if (dc_optional_string_either("help", "--help")) {
  8231.         dc_printf ("Usage: set_shield [num]\n");
  8232.         dc_printf ("[num] --  shield percentage 0.0 -> 1.0 of max\n");
  8233. -       dc_printf ("with no parameters, displays shield strength\n");
  8234. -       Dc_status = 0;
  8235. +       return;
  8236.     }
  8237.  
  8238. -   if ( Dc_status )    {
  8239. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  8240.         dc_printf( "Shields are currently %.2f", shield_get_strength(Player_obj) );
  8241. +       return;
  8242.     }
  8243. +
  8244. +   dc_stuff_float(&value);
  8245. +
  8246. +   CLAMP(value, 0.0f, 1.0f);
  8247. +
  8248. +   shield_set_strength(Player_obj, value * Player_ship->ship_max_shield_strength);
  8249. +   dc_printf("Shields set to %.2f\n", shield_get_strength(Player_obj) );
  8250.  }
  8251.  
  8252.  /**
  8253. @@ -13638,26 +13655,24 @@
  8254.   */
  8255.  DCF(set_hull, "Change player ship hull strength")
  8256.  {
  8257. -   if ( Dc_command )   {
  8258. -       dc_get_arg(ARG_FLOAT|ARG_NONE);
  8259. -
  8260. -       if ( Dc_arg_type & ARG_FLOAT ) {
  8261. -           CLAMP(Dc_arg_float, 0.0f, 1.0f);
  8262. -           Player_obj->hull_strength = Dc_arg_float * Player_ship->ship_max_hull_strength;
  8263. -           dc_printf("Hull set to %.2f\n", Player_obj->hull_strength );
  8264. -       }
  8265. -   }
  8266. -
  8267. -   if ( Dc_help ) {
  8268. +   float value;
  8269. +  
  8270. +   if (dc_optional_string_either("help", "--help")) {
  8271.         dc_printf ("Usage: set_hull [num]\n");
  8272.         dc_printf ("[num] --  hull percentage 0.0 -> 1.0 of max\n");
  8273. -       dc_printf ("with no parameters, displays hull strength\n");
  8274. -       Dc_status = 0;
  8275. +       return;
  8276.     }
  8277.  
  8278. -   if ( Dc_status )    {
  8279. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  8280.         dc_printf( "Hull is currently %.2f", Player_obj->hull_strength );
  8281. +       return;
  8282.     }
  8283. +
  8284. +   dc_stuff_float(&value);
  8285. +
  8286. +   CLAMP(value, 0.0f, 1.0f);
  8287. +   Player_obj->hull_strength = value * Player_ship->ship_max_hull_strength;
  8288. +   dc_printf("Hull set to %.2f\n", Player_obj->hull_strength );
  8289.  }
  8290.  
  8291.  /**
  8292. @@ -13666,71 +13681,66 @@
  8293.  //XSTR:OFF
  8294.  DCF(set_subsys, "Set the strength of a particular subsystem on player ship" )
  8295.  {
  8296. -   if ( Dc_command )   {
  8297. -       dc_get_arg(ARG_STRING);
  8298. -       if ( !subsystem_stricmp( Dc_arg, "weapons" ))   {
  8299. -           dc_get_arg(ARG_FLOAT);
  8300. -           if ( (Dc_arg_float < 0.0f) || (Dc_arg_float > 1.0f) )   {
  8301. -               Dc_help = 1;
  8302. -           } else {
  8303. -               ship_set_subsystem_strength( Player_ship, SUBSYSTEM_WEAPONS, Dc_arg_float );
  8304. -           }
  8305. -       } else if ( !subsystem_stricmp( Dc_arg, "engine" )) {
  8306. -           dc_get_arg(ARG_FLOAT);
  8307. -           if ( (Dc_arg_float < 0.0f) || (Dc_arg_float > 1.0f) )   {
  8308. -               Dc_help = 1;
  8309. -           } else {
  8310. -               ship_set_subsystem_strength( Player_ship, SUBSYSTEM_ENGINE, Dc_arg_float );
  8311. -               if ( Dc_arg_float < ENGINE_MIN_STR )    {
  8312. -                   Player_ship->flags |= SF_DISABLED;              // add the disabled flag
  8313. -               } else {
  8314. -                   Player_ship->flags &= (~SF_DISABLED);               // add the disabled flag
  8315. -               }
  8316. -           }
  8317. -       } else if ( !subsystem_stricmp( Dc_arg, "sensors" ))    {
  8318. -           dc_get_arg(ARG_FLOAT);
  8319. -           if ( (Dc_arg_float < 0.0f) || (Dc_arg_float > 1.0f) )   {
  8320. -               Dc_help = 1;
  8321. -           } else {
  8322. -               ship_set_subsystem_strength( Player_ship, SUBSYSTEM_SENSORS, Dc_arg_float );
  8323. -           }
  8324. -       } else if ( !subsystem_stricmp( Dc_arg, "communication" ))  {
  8325. -           dc_get_arg(ARG_FLOAT);
  8326. -           if ( (Dc_arg_float < 0.0f) || (Dc_arg_float > 1.0f) )   {
  8327. -               Dc_help = 1;
  8328. -           } else {
  8329. -               ship_set_subsystem_strength( Player_ship, SUBSYSTEM_COMMUNICATION, Dc_arg_float );
  8330. -           }
  8331. -       } else if ( !subsystem_stricmp( Dc_arg, "navigation" )) {
  8332. -           dc_get_arg(ARG_FLOAT);
  8333. -           if ( (Dc_arg_float < 0.0f) || (Dc_arg_float > 1.0f) )   {
  8334. -               Dc_help = 1;
  8335. -           } else {
  8336. -               ship_set_subsystem_strength( Player_ship, SUBSYSTEM_NAVIGATION, Dc_arg_float );
  8337. -           }
  8338. -       } else if ( !subsystem_stricmp( Dc_arg, "radar" ))  {
  8339. -           dc_get_arg(ARG_FLOAT);
  8340. -           if ( (Dc_arg_float < 0.0f) || (Dc_arg_float > 1.0f) )   {
  8341. -               Dc_help = 1;
  8342. -           } else {
  8343. -               ship_set_subsystem_strength( Player_ship, SUBSYSTEM_RADAR, Dc_arg_float );
  8344. -           }
  8345. -       } else {
  8346. -           // print usage
  8347. -           Dc_help = 1;
  8348. -       }
  8349. +   SCP_string arg;
  8350. +   int subsystem = SUBSYSTEM_NONE;
  8351. +   float val_f;
  8352. +  
  8353. +   if (dc_optional_string_either("help", "--help")) {
  8354. +       dc_printf( "Usage: set_subsys <type> [--status] <strength>\n");
  8355. +       dc_printf("<type> is any of the following:\n");
  8356. +       dc_printf("\tweapons\n");
  8357. +       dc_printf("\tengine\n");
  8358. +       dc_printf("\tsensors\n");
  8359. +       dc_printf("\tcommunication\n");
  8360. +       dc_printf("\tnavigation\n");
  8361. +       dc_printf("\tradar\n\n");
  8362. +
  8363. +       dc_printf("[--status] will display status of that subsystem\n\n");
  8364. +      
  8365. +       dc_printf("<strength> is any value between 0 and 1.0\n");
  8366. +       return;
  8367.     }
  8368.  
  8369. -   if ( Dc_help )  {
  8370. -       dc_printf( "Usage: set_subsys type X\nWhere X is value between 0 and 1.0, and type can be:\n" );
  8371. -       dc_printf( "weapons\n" );
  8372. -       dc_printf( "engine\n" );
  8373. -       dc_printf( "sensors\n" );
  8374. -       dc_printf( "communication\n" );
  8375. -       dc_printf( "navigation\n" );
  8376. -       dc_printf( "radar\n" );
  8377. -       Dc_status = 0;  // don't print status if help is printed.  Too messy.
  8378. +   dc_stuff_string_white(arg);
  8379. +
  8380. +   if (arg == "weapons") {
  8381. +       subsystem = SUBSYSTEM_WEAPONS;
  8382. +  
  8383. +   } else if (arg == "engine") {
  8384. +       subsystem = SUBSYSTEM_ENGINE;  
  8385. +  
  8386. +   } else if (arg == "sensors") {
  8387. +       subsystem = SUBSYSTEM_SENSORS;
  8388. +
  8389. +   } else if (arg == "communication") {
  8390. +       subsystem = SUBSYSTEM_COMMUNICATION;
  8391. +
  8392. +   } else if (arg == "navigation") {
  8393. +       subsystem = SUBSYSTEM_NAVIGATION;
  8394. +
  8395. +   } else if (arg == "radar") {
  8396. +       subsystem = SUBSYSTEM_RADAR;
  8397. +
  8398. +   } else {
  8399. +       dc_printf("Erro: Unknown argument '%s'\n", arg.c_str());
  8400. +       return;
  8401.     }
  8402. +
  8403. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  8404. +       dc_printf("Subsystem '%s' is at %f strength\n", arg.c_str(), ship_get_subsystem_strength(Player_ship, subsystem));
  8405. +
  8406. +   } else {
  8407. +       // Set the subsystem strength
  8408. +       dc_stuff_float(&val_f);
  8409. +
  8410. +       CLAMP(val_f, 0.0, 1.0);
  8411. +       ship_set_subsystem_strength( Player_ship, subsystem, val_f );
  8412. +      
  8413. +       if (subsystem == SUBSYSTEM_ENGINE) {
  8414. +           // If subsystem is an engine, set/clear the disabled flag
  8415. +           (val_f < ENGINE_MIN_STR) ? (Player_ship->flags |= SF_DISABLED) : (Player_ship->flags &= (~SF_DISABLED));
  8416. +       }
  8417. +   }
  8418.  }
  8419.  //XSTR:ON
  8420.  
  8421. @@ -16420,11 +16430,11 @@
  8422.  // update artillery lock info
  8423.  #define CLEAR_ARTILLERY_AND_CONTINUE() { if(aip != NULL){ aip->artillery_objnum = -1; aip->artillery_sig = -1; aip->artillery_lock_time = 0.0f;} continue; }
  8424.  float artillery_dist = 10.0f;
  8425. -DCF(art, "")
  8426. +DCF(art, "Sets artillery disance")
  8427.  {
  8428. -   dc_get_arg(ARG_FLOAT);
  8429. -   artillery_dist = Dc_arg_float;
  8430. +   dc_stuff_float(&artillery_dist);
  8431.  }
  8432. +
  8433.  void ship_update_artillery_lock()
  8434.  {
  8435.     ai_info *aip = NULL;
  8436. Index: ship/shipfx.cpp
  8437. ===================================================================
  8438. --- ship/shipfx.cpp (Revision 10462)
  8439. +++ ship/shipfx.cpp (Arbeitskopie)
  8440. @@ -40,6 +40,7 @@
  8441.  #include "bmpman/bmpman.h"
  8442.  #include "model/model.h"
  8443.  #include "cmdline/cmdline.h"
  8444. +#include "debugconsole/console.h"
  8445.  
  8446.  
  8447.  #ifndef NDEBUG
  8448. @@ -1355,42 +1356,58 @@
  8449.  }
  8450.  
  8451.  float Particle_width = 1.2f;
  8452. -DCF(particle_width, "Multiplier for angular width of the particle spew")
  8453. +DCF(particle_width, "Sets multiplier for angular width of the particle spew ( 0 - 5)")
  8454.  {
  8455. -   if ( Dc_command ) {
  8456. -       dc_get_arg(ARG_FLOAT);
  8457. -       if ( (Dc_arg_float >= 0 ) && (Dc_arg_float <= 5) ) {
  8458. -           Particle_width = Dc_arg_float;
  8459. -       } else {
  8460. -           dc_printf( "Illegal value for particle width. (Must be from 0-5) \n\n");
  8461. -       }
  8462. +   float value;
  8463. +
  8464. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  8465. +       dc_printf("Particle_width : %f\n", Particle_width);
  8466. +       return;
  8467.     }
  8468. +
  8469. +   dc_stuff_float(&value);
  8470. +
  8471. +   CLAMP(value, 0.0, 5.0);
  8472. +   Particle_width = value;
  8473. +
  8474. +   dc_printf("Particle_width set to %f\n", Particle_width);
  8475.  }
  8476.  
  8477.  float Particle_number = 1.2f;
  8478. -DCF(particle_num, "Multiplier for the number of particles created")
  8479. +DCF(particle_num, "Sets multiplier for the number of particles created")
  8480.  {
  8481. -   if ( Dc_command ) {
  8482. -       dc_get_arg(ARG_FLOAT);
  8483. -       if ( (Dc_arg_float >= 0 ) && (Dc_arg_float <= 5) ) {
  8484. -           Particle_number = Dc_arg_float;
  8485. -       } else {
  8486. -           dc_printf( "Illegal value for particle num. (Must be from 0-5) \n\n");
  8487. -       }
  8488. +  
  8489. +   float value;
  8490. +
  8491. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  8492. +       dc_printf("Particle_number : %f\n", Particle_number);
  8493. +       return;
  8494.     }
  8495. +
  8496. +   dc_stuff_float(&value);
  8497. +
  8498. +   CLAMP(value, 0.0, 5.0);
  8499. +   Particle_number = value;
  8500. +
  8501. +   dc_printf("Particle_number set to %f\n", Particle_number);
  8502.  }
  8503.  
  8504.  float Particle_life = 1.2f;
  8505.  DCF(particle_life, "Multiplier for the lifetime of particles created")
  8506.  {
  8507. -   if ( Dc_command ) {
  8508. -       dc_get_arg(ARG_FLOAT);
  8509. -       if ( (Dc_arg_float >= 0 ) && (Dc_arg_float <= 5) ) {
  8510. -           Particle_life = Dc_arg_float;
  8511. -       } else {
  8512. -           dc_printf( "Illegal value for particle life. (Must be from 0-5) \n\n");
  8513. -       }
  8514. +   float value;
  8515. +
  8516. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  8517. +       dc_printf("Particle_life : %f\n", Particle_life);
  8518. +       return;
  8519.     }
  8520. +
  8521. +   dc_stuff_float(&value);
  8522. +
  8523. +   CLAMP(value, 0.0, 5.0);
  8524. +   Particle_life = value;
  8525. +
  8526. +   dc_printf("Particle_life set to %f\n", Particle_life);
  8527.  }
  8528.  
  8529.  // Make sparks fly off of ship n.
  8530. @@ -1602,16 +1619,20 @@
  8531.  float  Bs_exp_fire_time_mult = 1.0f;
  8532.  
  8533.  DCF_BOOL(bs_exp_fire_low, Bs_exp_fire_low)
  8534. -DCF(bs_exp_fire_time_mult, "Multiplier time between fireball in big ship explosion")
  8535. +DCF(bs_exp_fire_time_mult, "Sets multiplier time between fireball in big ship explosion")
  8536.  {
  8537. -   if ( Dc_command ) {
  8538. -       dc_get_arg(ARG_FLOAT);
  8539. -       if ( (Dc_arg_float >= 0.1 ) && (Dc_arg_float <= 5) ) {
  8540. -           Bs_exp_fire_time_mult = Dc_arg_float;
  8541. -       } else {
  8542. -           dc_printf( "Illegal value for bs_exp_fire_time_mult. (Must be from 0.1-5) \n\n");
  8543. -       }
  8544. +   float value;
  8545. +
  8546. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  8547. +       dc_printf("Bs_exp_fire_time_mult : %f\n", Bs_exp_fire_time_mult);
  8548. +       return;
  8549.     }
  8550. +
  8551. +   dc_stuff_float(&value);
  8552. +
  8553. +   CLAMP(value, 0.1f, 5.0f);
  8554. +   Bs_exp_fire_time_mult = value;
  8555. +   dc_printf("Bs_exp_fire_time_mult set to %f\n", Bs_exp_fire_time_mult);
  8556.  }
  8557.  
  8558.  
  8559. Index: sound/sound.cpp
  8560. ===================================================================
  8561. --- sound/sound.cpp (Revision 10462)
  8562. +++ sound/sound.cpp (Arbeitskopie)
  8563. @@ -15,6 +15,7 @@
  8564.  #include "cmdline/cmdline.h"
  8565.  #include "osapi/osapi.h"
  8566.  #include "globalincs/vmallocator.h"
  8567. +#include "debugconsole/console.h"
  8568.  
  8569.  #include "gamesnd/gamesnd.h"
  8570.  #include "globalincs/alphacolors.h"
  8571. @@ -200,14 +201,15 @@
  8572.  }
  8573.  
  8574.  int Sound_spew = 0;
  8575. -DCF(show_sounds, "")
  8576. +DCF(show_sounds, "Toggles display of sound debug info")
  8577.  {
  8578. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  8579. +       dc_printf("Sound debug info is %s", (Sound_spew ? "ON" : "OFF"));
  8580. +       return;
  8581. +   }
  8582. +
  8583.     Sound_spew = !Sound_spew;
  8584. -   if(Sound_spew){
  8585. -       dc_printf("Sound debug info ON");
  8586. -   } else {
  8587. -       dc_printf("Sound debug info OFF");
  8588. -   }
  8589. +   dc_printf("Sound debug info is %s", (Sound_spew ? "ON" : "OFF"));
  8590.  }
  8591.  void snd_spew_debug_info()
  8592.  {
  8593. Index: starfield/nebula.cpp
  8594. ===================================================================
  8595. --- starfield/nebula.cpp    (Revision 10462)
  8596. +++ starfield/nebula.cpp    (Arbeitskopie)
  8597. @@ -15,9 +15,9 @@
  8598.  #include "mission/missionparse.h"
  8599.  #include "nebula/neb.h"
  8600.  #include "cfile/cfile.h"
  8601. +#include "debugconsole/console.h"
  8602.  
  8603.  
  8604. -
  8605.  #define MAX_TRIS 200
  8606.  #define MAX_POINTS 300
  8607.  
  8608. @@ -215,17 +215,19 @@
  8609.  
  8610.  DCF(nebula,"Loads a different nebula")
  8611.  {
  8612. -   if ( Dc_command )   {
  8613. -       dc_get_arg(ARG_STRING|ARG_NONE);
  8614. -       if ( Dc_arg_type == ARG_NONE )  {
  8615. -           nebula_close();
  8616. -       } else {
  8617. -           nebula_init( Dc_arg );
  8618. -       }
  8619. +   char filename[MAX_NAME_LEN];
  8620. +
  8621. +   if (dc_optional_string_either("help", "--help")) {
  8622. +       dc_printf("Usage: nebula [filename]\n");
  8623. +       dc_printf("Loads the nebula file. No filename takes away nebula\n" );
  8624. +       return;
  8625.     }
  8626. -   if ( Dc_help )  {
  8627. -       dc_printf( "Usage: nebula filename\nLoads the nebula file. No filename takes away nebula\n" );
  8628. -   }  
  8629. +
  8630. +   if (dc_maybe_stuff_string_white(filename, MAX_NAME_LEN)) {
  8631. +           nebula_init(filename);
  8632. +   } else {
  8633. +       nebula_close();
  8634. +   }
  8635.  }
  8636.  
  8637.  
  8638. Index: starfield/starfield.cpp
  8639. ===================================================================
  8640. --- starfield/starfield.cpp (Revision 10462)
  8641. +++ starfield/starfield.cpp (Arbeitskopie)
  8642. @@ -25,6 +25,7 @@
  8643.  #include "parse/parselo.h"
  8644.  #include "hud/hud.h"
  8645.  #include "hud/hudtarget.h"
  8646. +#include "debugconsole/console.h"
  8647.  
  8648.  
  8649.  #define MAX_DEBRIS_VCLIPS          4
  8650. @@ -866,75 +867,11 @@
  8651.  //XSTR:OFF
  8652.  DCF(stars,"Set parameters for starfield")
  8653.  {
  8654. -   if ( Dc_command ) {
  8655. -       dc_get_arg(ARG_STRING);
  8656. -       if ( !strcmp( Dc_arg, "tail" )) {
  8657. -           dc_get_arg(ARG_FLOAT);
  8658. -           if ( (Dc_arg_float < 0.0f) || (Dc_arg_float > 1.0f) ) {
  8659. -               Dc_help = 1;
  8660. -           } else {
  8661. -               Star_amount = Dc_arg_float;
  8662. -           }
  8663. -       } else if ( !strcmp( Dc_arg, "len" )) {
  8664. -           dc_get_arg(ARG_FLOAT);
  8665. -           Star_max_length = Dc_arg_float;
  8666. -       } else if ( !strcmp( Dc_arg, "dim" )) {
  8667. -           dc_get_arg(ARG_FLOAT);
  8668. -           if ( Dc_arg_float < 0.0f ) {
  8669. -               Dc_help = 1;
  8670. -           } else {
  8671. -               Star_dim = Dc_arg_float;
  8672. -           }
  8673. -       } else if ( !strcmp( Dc_arg, "flag" )) {
  8674. -           dc_get_arg(ARG_STRING);
  8675. -           if ( !strcmp( Dc_arg, "tail" )) {
  8676. -               Star_flags ^= STAR_FLAG_TAIL;
  8677. -           } else if ( !strcmp( Dc_arg, "dim" )) {
  8678. -               Star_flags ^= STAR_FLAG_DIM;
  8679. -           } else if ( !strcmp( Dc_arg, "aa" )) {
  8680. -               Star_flags ^= STAR_FLAG_ANTIALIAS;
  8681. -           } else {
  8682. -               Dc_help = 1;
  8683. -           }
  8684. -       } else if ( !strcmp( Dc_arg, "cap" )) {
  8685. -           dc_get_arg(ARG_FLOAT);
  8686. -           if ( (Dc_arg_float < 0.0f) || (Dc_arg_float > 255.0f) ) {
  8687. -               Dc_help = 1;
  8688. -           } else {
  8689. -               Star_cap = Dc_arg_float;
  8690. -           }
  8691. -       } else if ( !strcmp( Dc_arg, "m0" )) {
  8692. -           Star_amount = 0.0f;
  8693. -           Star_dim = 0.0f;
  8694. -           Star_cap = 0.0f;
  8695. -           Star_flags = 0;
  8696. -           Star_max_length = STAR_MAX_LENGTH_DEFAULT;
  8697. -       } else if ( !strcmp( Dc_arg, "m1" ) || !strcmp( Dc_arg, "default" )) {
  8698. -           Star_amount = STAR_AMOUNT_DEFAULT;
  8699. -           Star_dim = STAR_DIM_DEFAULT;
  8700. -           Star_cap = STAR_CAP_DEFAULT;
  8701. -           Star_flags = STAR_FLAG_DEFAULT;
  8702. -           Star_max_length = STAR_MAX_LENGTH_DEFAULT;
  8703. -       } else if ( !strcmp( Dc_arg, "m2" )) {
  8704. -           Star_amount = 0.75f;
  8705. -           Star_dim = 20.0f;
  8706. -           Star_cap = 75.0f;
  8707. -           Star_flags = STAR_FLAG_TAIL|STAR_FLAG_DIM|STAR_FLAG_ANTIALIAS;
  8708. -           Star_max_length = STAR_MAX_LENGTH_DEFAULT;
  8709. -       } else if ( !strcmp( Dc_arg, "num" )) {
  8710. -           dc_get_arg(ARG_INT);
  8711. -           if ( (Dc_arg_int < 0) || (Dc_arg_int > MAX_STARS) ) {
  8712. -               Dc_help = 1;
  8713. -           } else {
  8714. -               Num_stars = Dc_arg_int;
  8715. -           }
  8716. -       } else {
  8717. -           // print usage, not stats
  8718. -           Dc_help = 1;
  8719. -       }
  8720. -   }
  8721. +   SCP_string arg;
  8722. +   float val_f;
  8723. +   int val_i;
  8724.  
  8725. -   if ( Dc_help ) {
  8726. +   if (dc_optional_string_either("help", "--help")) {
  8727.         dc_printf( "Usage: stars keyword\nWhere keyword can be in the following forms:\n" );
  8728.         dc_printf( "stars default   Resets stars to all default values\n" );
  8729.         dc_printf( "stars num X     Sets number of stars to X.  Between 0 and %d.\n", MAX_STARS );
  8730. @@ -949,22 +886,106 @@
  8731.         dc_printf( "\nHINT: set cap to 0 to get dim rate and tail down, then use\n" );
  8732.         dc_printf( "cap to keep the lines from going away when moving too fast.\n" );
  8733.         dc_printf( "\nUse '? stars' to see current values.\n" );
  8734. -       Dc_status = 0;  // don't print status if help is printed.  Too messy.
  8735. +       return; // don't print status if help is printed.  Too messy.
  8736.     }
  8737.  
  8738. -   if ( Dc_status ) {
  8739. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  8740.         dc_printf( "Num_stars: %d\n", Num_stars );
  8741.         dc_printf( "Tail: %.2f\n", Star_amount );
  8742. -       dc_printf( "Dim: %.2f\n", Star_dim );
  8743. -       dc_printf( "Cap: %.2f\n", Star_cap );
  8744. +       dc_printf( "Dim : %.2f\n", Star_dim );
  8745. +       dc_printf( "Cap : %.2f\n", Star_cap );
  8746.         dc_printf( "Max length: %.2f\n", Star_max_length );
  8747.         dc_printf( "Flags:\n" );
  8748. -       dc_printf( "  Tail: %s\n", (Star_flags&STAR_FLAG_TAIL?"On":"Off") );
  8749. -       dc_printf( "  Dim: %s\n", (Star_flags&STAR_FLAG_DIM?"On":"Off") );
  8750. +       dc_printf( "  Tail : %s\n", (Star_flags&STAR_FLAG_TAIL?"On":"Off") );
  8751. +       dc_printf( "  Dim  : %s\n", (Star_flags&STAR_FLAG_DIM?"On":"Off") );
  8752.         dc_printf( "  Antialias: %s\n", (Star_flags&STAR_FLAG_ANTIALIAS?"On":"Off") );
  8753.         dc_printf( "\nTHESE AREN'T SAVED TO DISK, SO IF YOU TWEAK\n" );
  8754.         dc_printf( "THESE AND LIKE THEM, WRITE THEM DOWN!!\n" );
  8755. +       return;
  8756.     }
  8757. +
  8758. +   dc_stuff_string_white(arg);
  8759. +   // "stars default" is handled by "stars m1"
  8760. +   if (arg == "num") {
  8761. +       dc_stuff_int(&val_i);
  8762. +
  8763. +       CLAMP(val_i, 0, MAX_STARS);
  8764. +       Num_stars = val_i;
  8765. +
  8766. +       dc_printf("Num_stars set to %i\n", Num_stars);
  8767. +  
  8768. +   } else if (arg == "tail") {
  8769. +       dc_stuff_float(&val_f);
  8770. +       CLAMP(val_f, 0.0, 1.0);
  8771. +       Star_amount = val_f;
  8772. +      
  8773. +       dc_printf("Star_amount set to %f\n", Star_amount);
  8774. +
  8775. +   } else if (arg == "dim") {
  8776. +       dc_stuff_float(&val_f);
  8777. +
  8778. +       if (val_f > 0.0f ) {
  8779. +           Star_dim = val_f;
  8780. +           dc_printf("Star_dim set to %f\n", Star_dim);
  8781. +      
  8782. +       } else {
  8783. +           dc_printf("Error: Star_dim value must be non-negative\n");
  8784. +       }
  8785. +  
  8786. +   } else if (arg == "cap") {
  8787. +       dc_stuff_float(&val_f);
  8788. +       CLAMP(val_f, 0.0, 255);
  8789. +       Star_cap = val_f;
  8790. +      
  8791. +       dc_printf("Star_cap set to %f\n", Star_cap);
  8792. +  
  8793. +   } else if (arg == "len") {
  8794. +       dc_stuff_float(&Star_max_length);
  8795. +
  8796. +       dc_printf("Star_max_length set to %f\n", Star_max_length);
  8797. +
  8798. +   } else if (arg == "m0") {
  8799. +       Star_amount = 0.0f;
  8800. +       Star_dim = 0.0f;
  8801. +       Star_cap = 0.0f;
  8802. +       Star_flags = 0;
  8803. +       Star_max_length = STAR_MAX_LENGTH_DEFAULT;
  8804. +
  8805. +       dc_printf("Starfield set: Old 'pixel type' crappy stars. flags=none\n");
  8806. +  
  8807. +   } else if ((arg == "m1") || (arg == "default")) {
  8808. +       Star_amount = STAR_AMOUNT_DEFAULT;
  8809. +       Star_dim = STAR_DIM_DEFAULT;
  8810. +       Star_cap = STAR_CAP_DEFAULT;
  8811. +       Star_flags = STAR_FLAG_DEFAULT;
  8812. +       Star_max_length = STAR_MAX_LENGTH_DEFAULT;
  8813. +
  8814. +       dc_printf("Starfield set: (default) tail=.75, dim=20.0, cap=75.0, flags=dim,tail\n");
  8815. +
  8816. +   } else if (arg == "m2") {
  8817. +       Star_amount = 0.75f;
  8818. +       Star_dim = 20.0f;
  8819. +       Star_cap = 75.0f;
  8820. +       Star_flags = STAR_FLAG_TAIL|STAR_FLAG_DIM|STAR_FLAG_ANTIALIAS;
  8821. +       Star_max_length = STAR_MAX_LENGTH_DEFAULT;
  8822. +
  8823. +       dc_printf("Starfield set: tail=.75, dim=20.0, cap=75.0, flags=dim,tail,aa\n");
  8824. +
  8825. +   } else if (arg == "flag") {
  8826. +       dc_stuff_string_white(arg);
  8827. +       if (arg == "tail") {
  8828. +           Star_flags ^= STAR_FLAG_TAIL;
  8829. +       } else if (arg == "dim" ) {
  8830. +           Star_flags ^= STAR_FLAG_DIM;
  8831. +       } else if (arg == "aa" ) {
  8832. +           Star_flags ^= STAR_FLAG_ANTIALIAS;
  8833. +       } else {
  8834. +           dc_printf("Error: unknown flag argument '%s'\n", arg.c_str());
  8835. +       }
  8836. +
  8837. +   } else {
  8838. +       dc_printf("Error: Unknown argument '%s'", arg.c_str());
  8839. +   }
  8840.  }
  8841.  //XSTR:ON
  8842.  
  8843. @@ -1284,40 +1305,45 @@
  8844.  //XSTR:OFF
  8845.  DCF(subspace_set,"Set parameters for subspace effect")
  8846.  {
  8847. -   if ( Dc_command ) {
  8848. -       dc_get_arg(ARG_STRING);
  8849. -       if ( !strcmp( Dc_arg, "u" )) {
  8850. -           dc_get_arg(ARG_FLOAT);
  8851. -           if ( Dc_arg_float < 0.0f ) {
  8852. -               Dc_help = 1;
  8853. -           } else {
  8854. -               subspace_u_speed = Dc_arg_float;
  8855. -           }
  8856. -       } else if ( !strcmp( Dc_arg, "v" )) {
  8857. -           dc_get_arg(ARG_FLOAT);
  8858. -           if ( Dc_arg_float < 0.0f ) {
  8859. -               Dc_help = 1;
  8860. -           } else {
  8861. -               subspace_v_speed = Dc_arg_float;
  8862. -           }
  8863. -       } else {
  8864. -           // print usage, not stats
  8865. -           Dc_help = 1;
  8866. -       }
  8867. -   }
  8868. +   SCP_string arg;
  8869. +   float value;
  8870.  
  8871. -   if ( Dc_help ) {
  8872. -       dc_printf( "Usage: subspace keyword\nWhere keyword can be in the following forms:\n" );
  8873. -       dc_printf( "subspace u X    Where X is how fast u moves.\n", MAX_STARS );
  8874. -       dc_printf( "subspace v X    Where X is how fast v moves.\n" );
  8875. -       dc_printf( "\nUse '? subspace' to see current values.\n" );
  8876. -       Dc_status = 0;  // don't print status if help is printed.  Too messy.
  8877. +   if (dc_optional_string_either("help", "--help")) {
  8878. +       dc_printf( "Usage: subspace [--status] <axis> <speed>\n");
  8879. +       dc_printf("[--status] -- Displays the current speeds for both axes\n");
  8880. +       dc_printf("<axis>  -- May be either 'u' or 'v', and corresponds to the texture axis\n");
  8881. +       dc_printf("<speed> -- is the speed along the axis that the texture is moved\n");
  8882. +       return;
  8883.     }
  8884.  
  8885. -   if ( Dc_status ) {
  8886. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  8887.         dc_printf( "u: %.2f\n", subspace_u_speed );
  8888.         dc_printf( "v: %.2f\n", subspace_v_speed );
  8889. +       return;
  8890.     }
  8891. +
  8892. +   dc_stuff_string_white(arg);
  8893. +   if (arg == "u") {
  8894. +       dc_stuff_float(&value);
  8895. +
  8896. +       if ( value < 0.0f ) {
  8897. +           dc_printf("Error: speed must be non-negative");
  8898. +           return;
  8899. +       }
  8900. +       subspace_u_speed = value;
  8901. +
  8902. +   } else if (arg == "v") {
  8903. +       dc_stuff_float(&value);
  8904. +
  8905. +       if (value < 0.0f) {
  8906. +           dc_printf("Error: speed must be non-negative");
  8907. +           return;
  8908. +       }
  8909. +       subspace_v_speed = value;
  8910. +
  8911. +   } else {
  8912. +       dc_printf("Error: Unknown axis '%s'", arg.c_str());
  8913. +   }
  8914.  }
  8915.  //XSTR:ON
  8916.  
  8917. Index: starfield/supernova.cpp
  8918. ===================================================================
  8919. --- starfield/supernova.cpp (Revision 10462)
  8920. +++ starfield/supernova.cpp (Arbeitskopie)
  8921. @@ -21,6 +21,7 @@
  8922.  #include "gamesequence/gamesequence.h"
  8923.  #include "gamesnd/gamesnd.h"
  8924.  #include "cmdline/cmdline.h"
  8925. +#include "debugconsole/console.h"
  8926.  
  8927.  // --------------------------------------------------------------------------------------------------------------------------
  8928.  // SUPERNOVA DEFINES/VARS
  8929. @@ -116,11 +117,8 @@
  8930.  
  8931.  
  8932.  int sn_particles = 100;
  8933. -DCF(sn_part, "")
  8934. -{
  8935. -   dc_get_arg(ARG_INT);
  8936. -   sn_particles = Dc_arg_int;
  8937. -}
  8938. +DCF_INT2(sn_part, sn_particles, 0, INT_MAX, "Sets number of supernova particles (default is 100)");
  8939. +
  8940.  void supernova_do_particles()
  8941.  {
  8942.     int idx;
  8943. @@ -181,11 +179,7 @@
  8944.  
  8945.  // call once per frame
  8946.  float sn_shudder = 0.45f;
  8947. -DCF(sn_shud, "")
  8948. -{
  8949. -   dc_get_arg(ARG_FLOAT);
  8950. -   sn_shudder = Dc_arg_float;
  8951. -}
  8952. +DCF_FLOAT2(sn_shud, sn_shudder, 0.0, FLT_MAX, "Sets camera shudder rate for being in supernova shockwave (default is 0.45)");
  8953.  
  8954.  void supernova_process()
  8955.  {
  8956. @@ -318,18 +312,11 @@
  8957.  // get view params from supernova
  8958.  float sn_distance = 300.0f;                // shockwave moving at 1000/ms ?
  8959.  float sn_cam_distance = 25.0f;
  8960. -DCF(sn_dist, "")
  8961. -{
  8962. -   dc_get_arg(ARG_FLOAT);
  8963. -   sn_distance = Dc_arg_float;
  8964. -}
  8965. +DCF_FLOAT2(sn_dist, sn_distance, 0.0, FLT_MAX, "Sets supernova shockwave distance (default is 300.0f)");
  8966.  
  8967. -DCF(sn_cam_dist, "")
  8968. -{
  8969. -   dc_get_arg(ARG_FLOAT);
  8970. -   sn_cam_distance = Dc_arg_float;
  8971. -}
  8972.  
  8973. +DCF_FLOAT2(sn_cam_dist, sn_cam_distance, 0.0, FLT_MAX, "Sets supernova camera distance (default is 25.0f)");
  8974. +
  8975.  void supernova_get_eye(vec3d *eye_pos, matrix *eye_orient)
  8976.  {
  8977.     // supernova camera pos
  8978. Index: stats/medals.cpp
  8979. ===================================================================
  8980. --- stats/medals.cpp    (Revision 10462)
  8981. +++ stats/medals.cpp    (Arbeitskopie)
  8982. @@ -21,6 +21,7 @@
  8983.  #include "globalincs/alphacolors.h"
  8984.  #include "localization/localize.h"
  8985.  #include "parse/parselo.h"
  8986. +#include "debugconsole/console.h"
  8987.  
  8988.  #ifndef NDEBUG
  8989.  #include "cmdline/cmdline.h"
  8990. @@ -437,88 +438,74 @@
  8991.  DCF(medals, "Grant or revoke medals")
  8992.  {
  8993.     int i;
  8994. +   int idx;
  8995.  
  8996. -   if (Dc_command)
  8997. +   if (dc_optional_string_either("help", "--help"))
  8998.     {
  8999. -       dc_get_arg(ARG_STRING | ARG_INT | ARG_NONE);
  9000. +       dc_printf ("Usage: medals all | clear | promote | demote | [index]\n");
  9001. +       dc_printf ("       [index] --  index of medal to grant\n");
  9002. +       dc_printf ("       with no parameters, displays the available medals\n");
  9003. +       return;
  9004. +   }
  9005.  
  9006. -       if (Dc_arg_type & ARG_INT)
  9007. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?"))
  9008. +   {
  9009. +       dc_printf("You have the following medals:\n");
  9010. +
  9011. +       for (i = 0; i < Num_medals; i++)
  9012.         {
  9013. -           int idx = Dc_arg_int;
  9014. +           if (Player->stats.medal_counts[i] > 0)
  9015. +               dc_printf("%d %s\n", Player->stats.medal_counts[i], Medals[i].name);
  9016. +       }
  9017. +       dc_printf("%s\n", Ranks[Player->stats.rank].name);
  9018. +       return;
  9019. +   }
  9020.  
  9021. -           if (idx < 0 || idx >= Num_medals)
  9022. -           {
  9023. -               dc_printf("Medal index %d is out of range\n", idx);
  9024. -               return;
  9025. -           }
  9026. +   if (dc_optional_string("all")) {
  9027. +       for (i = 0; i < Num_medals; i++) {
  9028. +           Player->stats.medal_counts[i]++;
  9029. +       }
  9030. +       dc_printf("Granted all medals\n");
  9031. +       return;
  9032.  
  9033. -           dc_printf("Granted %s\n", Medals[idx].name);
  9034. -           Player->stats.medal_counts[idx]++;
  9035. +   } else if (dc_optional_string("clear")) {
  9036. +       for (i = 0; i < Num_medals; i++) {
  9037. +           Player->stats.medal_counts[i] = 0;
  9038.         }
  9039. -       else if (Dc_arg_type & ARG_STRING)
  9040. -       {
  9041. -           if (!strcmp(Dc_arg, "all"))
  9042. -           {
  9043. -               for (i = 0; i < Num_medals; i++)
  9044. -                   Player->stats.medal_counts[i]++;
  9045. +       dc_printf("Cleared all medals\n");
  9046. +       return;
  9047.  
  9048. -               dc_printf("Granted all medals\n");
  9049. -           }
  9050. -           else if (!strcmp(Dc_arg, "clear"))
  9051. -           {
  9052. -               for (i = 0; i < Num_medals; i++)
  9053. -                   Player->stats.medal_counts[i] = 0;
  9054. +   } else if (dc_optional_string("promote")) {
  9055. +       if (Player->stats.rank < MAX_FREESPACE2_RANK) {
  9056. +           Player->stats.rank++;
  9057. +       }
  9058. +       dc_printf("Promoted to %s\n", Ranks[Player->stats.rank].name);
  9059. +       return;
  9060.  
  9061. -               dc_printf("Cleared all medals\n");
  9062. -           }
  9063. -           else if (!strcmp(Dc_arg, "demote"))
  9064. -           {
  9065. -               if (Player->stats.rank > 0)
  9066. -                   Player->stats.rank--;
  9067. +   } else if (dc_optional_string("demote")) {
  9068. +       if (Player->stats.rank > 0) {
  9069. +           Player->stats.rank--;
  9070. +       }
  9071. +       dc_printf("Demoted to %s\n", Ranks[Player->stats.rank].name);
  9072. +       return;
  9073. +   }
  9074.  
  9075. -               dc_printf("Demoted to %s\n", Ranks[Player->stats.rank].name);
  9076. -           }
  9077. -           else if (!strcmp(Dc_arg, "promote"))
  9078. -           {
  9079. -               if (Player->stats.rank < MAX_FREESPACE2_RANK)
  9080. -                   Player->stats.rank++;
  9081. -
  9082. -               dc_printf("Promoted to %s\n", Ranks[Player->stats.rank].name);
  9083. -           }
  9084. -           else
  9085. -           {
  9086. -               Dc_help = 1;
  9087. -           }
  9088. -       }
  9089. -       else
  9090. +   if (dc_maybe_stuff_int(&idx)) {
  9091. +       if (idx < 0 || idx >= Num_medals)
  9092.         {
  9093. -           dc_printf("The following medals are available:\n");
  9094. -           for (i = 0; i < Num_medals; i++)
  9095. -               dc_printf("%d: %s\n", i, Medals[i].name);
  9096. +           dc_printf("Medal index %d is out of range\n", idx);
  9097. +           return;
  9098.         }
  9099.  
  9100. -       Dc_status = 0;
  9101. +       dc_printf("Granted %s\n", Medals[idx].name);
  9102. +       Player->stats.medal_counts[idx]++;
  9103. +       return;
  9104.     }
  9105.  
  9106. -   if (Dc_help)
  9107. -   {
  9108. -       dc_printf ("Usage: gimmemedals all | clear | promote | demote | [index]\n");
  9109. -       dc_printf ("       [index] --  index of medal to grant\n");
  9110. -       dc_printf ("       with no parameters, displays the available medals\n");
  9111. -       Dc_status = 0;
  9112. +   dc_printf("The following medals are available:\n");
  9113. +   for (i = 0; i < Num_medals; i++) {
  9114. +       dc_printf("%d: %s\n", i, Medals[i].name);
  9115.     }
  9116. -
  9117. -   if (Dc_status)
  9118. -   {
  9119. -       dc_printf("You have the following medals:\n");
  9120. -
  9121. -       for (i = 0; i < Num_medals; i++)
  9122. -       {
  9123. -           if (Player->stats.medal_counts[i] > 0)
  9124. -               dc_printf("%d %s\n", Player->stats.medal_counts[i], Medals[i].name);
  9125. -       }
  9126. -       dc_printf("%s\n", Ranks[Player->stats.rank].name);
  9127. -   }
  9128.  }
  9129.  
  9130.  
  9131. Index: stats/scoring.cpp
  9132. ===================================================================
  9133. --- stats/scoring.cpp   (Revision 10462)
  9134. +++ stats/scoring.cpp   (Arbeitskopie)
  9135. @@ -31,6 +31,7 @@
  9136.  #include "network/multi_pmsg.h"
  9137.  #include "ai/ai_profiles.h"
  9138.  #include "pilotfile/pilotfile.h"
  9139. +#include "debugconsole/console.h"
  9140.  
  9141.  /*
  9142.  // uncomment to get extra debug messages when a player scores
  9143. @@ -1509,20 +1510,42 @@
  9144.     pl->stats.rank = rank;
  9145.  }
  9146.  
  9147. -DCF(rank, "changes scoring vars")
  9148. +DCF(rank, "changes player rank")
  9149.  {
  9150. -   if(Dc_command){    
  9151. -       dc_get_arg(ARG_INT);       
  9152. -      
  9153. -       // parse the argument and change things around accordingly     
  9154. -       if((Dc_arg_type & ARG_INT) && (Player != NULL)){                           
  9155. -           scoring_bash_rank(Player,Dc_arg_int);
  9156. -       }      
  9157. +   int rank;
  9158. +
  9159. +   if (dc_optional_string_either("help", "--help")) {
  9160. +       dc_printf("Usage: rank <index>\n");
  9161. +       dc_printf(" <index> The rank index you wish to have. For retail ranks, these correspond to:\n");
  9162. +       dc_printf("\t0 : Ensign\n");
  9163. +       dc_printf("\t1 : Lieutenant Junior Grade\n");
  9164. +       dc_printf("\t2 : Lietenant\n");
  9165. +       dc_printf("\t3 : Lieutenant Commander\n");
  9166. +       dc_printf("\t4 : Commander\n");
  9167. +       dc_printf("\t5 : Captain\n");
  9168. +       dc_printf("\t6 : Commodore\n");
  9169. +       dc_printf("\t7 : Rear Admiral\n");
  9170. +       dc_printf("\t8 : Vice Admiral\n");
  9171. +       dc_printf("\t9 : Admiral\n\n");
  9172. +       return;
  9173.     }
  9174. -   dc_printf("Usage\n0 : Ensign\n1 : Lieutenant Junior Grade\n");
  9175. -   dc_printf("2 : Lietenant\n3 : Lieutenant Commander\n");
  9176. -   dc_printf("4 : Commander\n5 : Captain\n6 : Commodore\n");
  9177. -   dc_printf("7 : Rear Admiral\n8 : Vice Admiral\n9 : Admiral");
  9178. +
  9179. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  9180. +       if (Player != NULL) {
  9181. +           dc_printf("Current rank is %i\n", Player->stats.rank);
  9182. +       } else {
  9183. +           dc_printf("Error! Current Player not active or loaded\n");
  9184. +       }
  9185. +   }
  9186. +
  9187. +   dc_stuff_int(&rank);
  9188. +  
  9189. +   // parse the argument and change things around accordingly
  9190. +   if (Player != NULL) {
  9191. +           scoring_bash_rank(Player, rank);
  9192. +   } else {
  9193. +       dc_printf("Error! Current Player not active or loaded\n");
  9194. +   }
  9195.  }
  9196.  
  9197.  void scoreing_close()
  9198. Index: weapon/beam.cpp
  9199. ===================================================================
  9200. --- weapon/beam.cpp (Revision 10462)
  9201. +++ weapon/beam.cpp (Arbeitskopie)
  9202. @@ -36,6 +36,7 @@
  9203.  #include "globalincs/globals.h"
  9204.  #include "cmdline/cmdline.h"
  9205.  #include "parse/scripting.h"
  9206. +#include "debugconsole/console.h"
  9207.  
  9208.  extern int Cmdline_nohtl;
  9209.  // ------------------------------------------------------------------------------------------------
  9210. @@ -119,20 +120,22 @@
  9211.  float b_whack_big = 10000.0f;  // used to be 1500.0f with the retail whack bug
  9212.  float b_whack_damage = 150.0f;
  9213.  
  9214. -DCF(b_whack_small, "")
  9215. +DCF(b_whack_small, "Sets the whack factor for small whacks (Default is 2000f)")
  9216.  {
  9217. -   dc_get_arg(ARG_FLOAT);
  9218. -   b_whack_small = Dc_arg_float;
  9219. +   dc_stuff_float(&b_whack_small);
  9220.  }
  9221. -DCF(b_whack_big, "")
  9222. +DCF(b_whack_big, "Sets the whack factor for big whacks (Default is 10000f)")
  9223.  {
  9224. -   dc_get_arg(ARG_FLOAT);
  9225. -   b_whack_big = Dc_arg_float;
  9226. +   dc_stuff_float(&b_whack_big);
  9227.  }
  9228. -DCF(b_whack_damage, "")
  9229. +DCF(b_whack_damage, "Sets the whack damage threshold (Default is 150f)")
  9230.  {
  9231. -   dc_get_arg(ARG_FLOAT);
  9232. -   b_whack_damage = Dc_arg_float;
  9233. +   if (dc_optional_string_either("help", "--help")) {
  9234. +       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");
  9235. +       return;
  9236. +   }
  9237. +
  9238. +   dc_stuff_float(&b_whack_damage);
  9239.  }
  9240.  
  9241.  
  9242. @@ -1254,10 +1257,9 @@
  9243.  
  9244.  // generate particles for the muzzle glow
  9245.  int hack_time = 100;
  9246. -DCF(h_time, "")
  9247. +DCF(h_time, "Sets the hack time for beam muzzle glow (Default is 100)")
  9248.  {
  9249. -   dc_get_arg(ARG_INT);
  9250. -   hack_time = Dc_arg_int;
  9251. +   dc_stuff_int(&hack_time);
  9252.  }
  9253.  
  9254.  void beam_generate_muzzle_particles(beam *b)
  9255. @@ -1479,10 +1481,9 @@
  9256.  
  9257.  // light scale factor
  9258.  float blight = 25.5f;
  9259. -DCF(blight, "")
  9260. +DCF(blight, "Sets the beam light scale factor (Default is 25.5f)")
  9261.  {
  9262. -   dc_get_arg(ARG_FLOAT);
  9263. -   blight = Dc_arg_float;
  9264. +   dc_stuff_float(&blight);
  9265.  }
  9266.  
  9267.  // call to add a light source to a small object
  9268. @@ -3446,12 +3447,11 @@
  9269.  }
  9270.  
  9271.  float beam_accuracy = 1.0f;
  9272. -DCF(b_aim, "")
  9273. +DCF(b_aim, "Adjusts the beam accuracy factor (Default is 1.0f)")
  9274.  {
  9275. -   dc_get_arg(ARG_FLOAT);
  9276. -   beam_accuracy = Dc_arg_float;
  9277. +   dc_stuff_float(&beam_accuracy);
  9278.  }
  9279. -DCF(beam_list, "")
  9280. +DCF(beam_list, "Lists all beams")
  9281.  {
  9282.     int idx;
  9283.     int b_count = 0;
  9284. Index: weapon/corkscrew.cpp
  9285. ===================================================================
  9286. --- weapon/corkscrew.cpp    (Revision 10462)
  9287. +++ weapon/corkscrew.cpp    (Arbeitskopie)
  9288. @@ -15,6 +15,7 @@
  9289.  #include "io/timer.h"
  9290.  #include "freespace2/freespace.h"  // for Missiontime
  9291.  #include "object/object.h"
  9292. +#include "debugconsole/console.h"
  9293.  
  9294.  
  9295.  
  9296. @@ -293,41 +294,25 @@
  9297.  
  9298.  DCF(cscrew_delay, "Change the delay between corkscrew firing")
  9299.  { 
  9300. -   dc_get_arg(ARG_INT);
  9301. -   if(Dc_arg_type & ARG_INT){
  9302. -       Corkscrew_missile_delay = Dc_arg_int;      
  9303. -   }
  9304. -
  9305. +   dc_stuff_int(&Corkscrew_missile_delay);
  9306.     cscrew_display_dcf();
  9307.  }
  9308.  
  9309.  DCF(cscrew_count, "Change the # of corkscrew missiles fired")
  9310.  { 
  9311. -   dc_get_arg(ARG_INT);
  9312. -   if(Dc_arg_type & ARG_INT){
  9313. -       Corkscrew_num_missiles_fired = Dc_arg_int;     
  9314. -   }
  9315. -
  9316. +   dc_stuff_int(&Corkscrew_num_missiles_fired);
  9317.     cscrew_display_dcf();
  9318.  }
  9319.  
  9320.  DCF(cscrew_radius, "Change the radius of corkscrew missiles")
  9321.  { 
  9322. -   dc_get_arg(ARG_FLOAT);
  9323. -   if(Dc_arg_type & ARG_FLOAT){
  9324. -       Corkscrew_radius = Dc_arg_float;
  9325. -   }
  9326. -
  9327. +   dc_stuff_float(&Corkscrew_radius);
  9328.     cscrew_display_dcf();
  9329.  }
  9330.  
  9331.  DCF(cscrew_twist, "Change the rate of the corkscrew twist")
  9332.  {
  9333. -   dc_get_arg(ARG_FLOAT);
  9334. -   if(Dc_arg_type & ARG_FLOAT){
  9335. -       Corkscrew_twist = Dc_arg_float;
  9336. -   }
  9337. -
  9338. +   dc_stuff_float(&Corkscrew_twist);
  9339.     cscrew_display_dcf();
  9340.  }
  9341.  
  9342. @@ -354,11 +339,7 @@
  9343.  
  9344.  DCF(cscrew_shrinkval, "Change the rate at which the radii shrink")
  9345.  {
  9346. -   dc_get_arg(ARG_FLOAT);
  9347. -   if(Dc_arg_type & ARG_FLOAT){
  9348. -       Corkscrew_shrink_val = Dc_arg_float;
  9349. -   }
  9350. -
  9351. +   dc_stuff_float(&Corkscrew_shrink_val);
  9352.     cscrew_display_dcf();
  9353.  }
  9354.  
  9355. Index: weapon/emp.cpp
  9356. ===================================================================
  9357. --- weapon/emp.cpp  (Revision 10462)
  9358. +++ weapon/emp.cpp  (Arbeitskopie)
  9359. @@ -26,6 +26,7 @@
  9360.  #include "iff_defs/iff_defs.h"
  9361.  #include "network/multimsgs.h"
  9362.  #include "network/multi.h"
  9363. +#include "debugconsole/console.h"
  9364.  
  9365.  
  9366.  
  9367. @@ -637,13 +638,12 @@
  9368.  DCF(zap, "zap a ship with an EMP effect")
  9369.  {
  9370.     int shipnum;
  9371. +   char ship_str[NAME_LENGTH];
  9372.  
  9373. -   dc_get_arg(ARG_STRING);
  9374. -   if(Dc_arg_type & ARG_STRING){
  9375. -        shipnum = ship_name_lookup(Dc_arg, 1);
  9376. +   dc_stuff_string_white(ship_str, NAME_LENGTH);
  9377. +   shipnum = ship_name_lookup(ship_str, 1);
  9378.  
  9379. -        if(shipnum >= 0){
  9380. -           emp_start_ship(&Objects[Ships[shipnum].objnum], 500.0f, 10.0f);
  9381. -        }
  9382. +   if(shipnum >= 0){
  9383. +       emp_start_ship(&Objects[Ships[shipnum].objnum], 500.0f, 10.0f);
  9384.     }
  9385.  }
  9386. Index: weapon/weapons.cpp
  9387. ===================================================================
  9388. --- weapon/weapons.cpp  (Revision 10462)
  9389. +++ weapon/weapons.cpp  (Arbeitskopie)
  9390. @@ -47,6 +47,7 @@
  9391.  #include "parse/scripting.h"
  9392.  #include "stats/scoring.h"
  9393.  #include "mod_table/mod_table.h"
  9394. +#include "debugconsole/console.h"
  9395.  
  9396.  
  9397.  #ifndef NDEBUG
  9398. @@ -6657,77 +6658,139 @@
  9399.  /**
  9400.   * Debug console functionality
  9401.   */
  9402. -void pspew_display_dcf()
  9403. +void dcf_pspew();
  9404. +DCF(pspew_count, "Number of particles spewed at a time")
  9405.  {
  9406. -   dc_printf("Particle spew settings\n\n");
  9407. -   dc_printf("Particle spew count (pspew_count) : %d\n", Weapon_particle_spew_count);
  9408. -   dc_printf("Particle spew time (pspew_time) : %d\n", Weapon_particle_spew_time);
  9409. -   dc_printf("Particle spew velocity (pspew_vel) : %f\n", Weapon_particle_spew_vel);
  9410. -   dc_printf("Particle spew size (pspew_size) : %f\n", Weapon_particle_spew_radius);
  9411. -   dc_printf("Particle spew lifetime (pspew_life) : %f\n", Weapon_particle_spew_lifetime);
  9412. -   dc_printf("Particle spew scale (psnew_scale) : %f\n", Weapon_particle_spew_scale);
  9413. -}
  9414. +   if (dc_optional_string_either("help", "--help")) {
  9415. +       dcf_pspew();
  9416. +       return;
  9417. +   }
  9418.  
  9419. -DCF(pspew_count, "Number of particles spewed at a time")
  9420. -{ 
  9421. -   dc_get_arg(ARG_INT);
  9422. -   if(Dc_arg_type & ARG_INT){
  9423. -       Weapon_particle_spew_count = Dc_arg_int;
  9424. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  9425. +           dc_printf("Partical count is %i\n", Weapon_particle_spew_count);
  9426. +           return;
  9427.     }
  9428.  
  9429. -   pspew_display_dcf();
  9430. +   dc_stuff_int(&Weapon_particle_spew_count);
  9431. +  
  9432. +   dc_printf("Partical count set to %i\n", Weapon_particle_spew_count);
  9433.  }
  9434.  
  9435.  DCF(pspew_time, "Time between particle spews")
  9436. -{ 
  9437. -   dc_get_arg(ARG_INT);
  9438. -   if(Dc_arg_type & ARG_INT){
  9439. -       Weapon_particle_spew_time = Dc_arg_int;
  9440. +{
  9441. +   if (dc_optional_string_either("help", "--help")) {
  9442. +       dcf_pspew();
  9443. +       return;
  9444.     }
  9445.  
  9446. -   pspew_display_dcf();
  9447. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  9448. +       dc_printf("Particle spawn period is %i\n", Weapon_particle_spew_time);
  9449. +       return;
  9450. +   }
  9451. +
  9452. +   dc_stuff_int(&Weapon_particle_spew_time);
  9453. +
  9454. +   dc_printf("Particle spawn period set to %i\n", Weapon_particle_spew_time);
  9455.  }
  9456.  
  9457.  DCF(pspew_vel, "Relative velocity of particles (0.0 - 1.0)")
  9458. -{ 
  9459. -   dc_get_arg(ARG_FLOAT);
  9460. -   if(Dc_arg_type & ARG_FLOAT){
  9461. -       Weapon_particle_spew_vel = Dc_arg_float;
  9462. +{
  9463. +   if (dc_optional_string_either("help", "--help")) {
  9464. +       dcf_pspew();
  9465. +       return;
  9466.     }
  9467.  
  9468. -   pspew_display_dcf();
  9469. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  9470. +       dc_printf("Particle relative velocity is %f\n", Weapon_particle_spew_vel);
  9471. +       return;
  9472. +   }
  9473. +
  9474. +   dc_stuff_float(&Weapon_particle_spew_vel);
  9475. +
  9476. +   dc_printf("Particle relative velocity set to %f\n", Weapon_particle_spew_vel);
  9477.  }
  9478.  
  9479.  DCF(pspew_size, "Size of spewed particles")
  9480. -{ 
  9481. -   dc_get_arg(ARG_FLOAT);
  9482. -   if(Dc_arg_type & ARG_FLOAT){
  9483. -       Weapon_particle_spew_radius = Dc_arg_float;
  9484. +{
  9485. +   if (dc_optional_string_either("help", "--help")) {
  9486. +       dcf_pspew();
  9487. +       return;
  9488.     }
  9489.  
  9490. -   pspew_display_dcf();
  9491. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  9492. +       dc_printf("Particle size is %f\n", Weapon_particle_spew_radius);
  9493. +       return;
  9494. +   }
  9495. +
  9496. +   dc_stuff_float(&Weapon_particle_spew_radius);
  9497. +
  9498. +   dc_printf("Particle size set to %f\n", Weapon_particle_spew_radius);
  9499.  }
  9500.  
  9501.  DCF(pspew_life, "Lifetime of spewed particles")
  9502. -{ 
  9503. -   dc_get_arg(ARG_FLOAT);
  9504. -   if(Dc_arg_type & ARG_FLOAT){
  9505. -       Weapon_particle_spew_lifetime = Dc_arg_float;
  9506. +{
  9507. +   if (dc_optional_string_either("help", "--help")) {
  9508. +       dcf_pspew();
  9509. +       return;
  9510.     }
  9511.  
  9512. -   pspew_display_dcf();
  9513. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  9514. +       dc_printf("Particle lifetime is %f\n", Weapon_particle_spew_lifetime);
  9515. +       return;
  9516. +   }
  9517. +
  9518. +   dc_stuff_float(&Weapon_particle_spew_lifetime);
  9519. +
  9520. +   dc_printf("Particle lifetime set to %f\n", Weapon_particle_spew_lifetime);
  9521.  }
  9522.  
  9523.  DCF(pspew_scale, "How far away particles are from the weapon path")
  9524. -{ 
  9525. -   dc_get_arg(ARG_FLOAT);
  9526. -   if(Dc_arg_type & ARG_FLOAT){
  9527. -       Weapon_particle_spew_scale = Dc_arg_float;
  9528. +{
  9529. +   if (dc_optional_string_either("help", "--help")) {
  9530. +       dcf_pspew();
  9531. +       return;
  9532.     }
  9533.  
  9534. -   pspew_display_dcf();
  9535. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  9536. +       dc_printf("Particle scale is %f\n", Weapon_particle_spew_scale);
  9537. +   }
  9538. +
  9539. +   dc_stuff_float(&Weapon_particle_spew_scale);
  9540. +
  9541. +   dc_printf("Particle scale set to %f\n", Weapon_particle_spew_scale);
  9542.  }
  9543.  
  9544. +// Help and Status provider
  9545. +DCF(pspew, "Particle spew help and status provider")
  9546. +{
  9547. +   if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {
  9548. +       dc_printf("Particle spew settings\n\n");
  9549. +
  9550. +       dc_printf(" Count   (pspew_count) : %d\n", Weapon_particle_spew_count);
  9551. +       dc_printf(" Time     (pspew_time) : %d\n", Weapon_particle_spew_time);
  9552. +       dc_printf(" Velocity  (pspew_vel) : %f\n", Weapon_particle_spew_vel);
  9553. +       dc_printf(" Size     (pspew_size) : %f\n", Weapon_particle_spew_radius);
  9554. +       dc_printf(" Lifetime (pspew_life) : %f\n", Weapon_particle_spew_lifetime);
  9555. +       dc_printf(" Scale   (psnew_scale) : %f\n", Weapon_particle_spew_scale);
  9556. +       return;
  9557. +   }
  9558. +
  9559. +   dc_printf("Available particlar spew commands:\n");
  9560. +   dc_printf("pspew_count : %s\n", dcmd_pspew_count.help);
  9561. +   dc_printf("pspew_time  : %s\n", dcmd_pspew_time.help);
  9562. +   dc_printf("pspew_vel   : %s\n", dcmd_pspew_vel.help);
  9563. +   dc_printf("pspew_size  : %s\n", dcmd_pspew_size.help);
  9564. +   dc_printf("pspew_life  : %s\n", dcmd_pspew_life.help);
  9565. +   dc_printf("pspew_scale : %s\n\n", dcmd_pspew_scale.help);
  9566. +
  9567. +   dc_printf("To view status of all pspew settings, type in 'pspew --status'.\n");
  9568. +   dc_printf("Passing '--status' as an argument to any of the individual spew commands will show the status of that variable only.\n\n");
  9569. +
  9570. +   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");
  9571. +   dc_printf("Generally, a large particle count with small size and scale will result in a nice dense particle spew.\n");
  9572. +   dc_printf("Be advised, this effect is applied to _ALL_ weapons, and as such may drastically reduce framerates on lower powered platforms.\n");
  9573. +}
  9574. +
  9575.  /**
  9576.   * Return a scale factor for damage which should be applied for 2 collisions
  9577.   */
  9578. Index: windows_stub/stubs.cpp
  9579. ===================================================================
  9580. --- windows_stub/stubs.cpp  (Revision 10462)
  9581. +++ windows_stub/stubs.cpp  (Arbeitskopie)
  9582. @@ -23,6 +23,7 @@
  9583.  #include "globalincs/pstypes.h"
  9584.  #include "parse/lua.h"
  9585.  #include "cmdline/cmdline.h"
  9586. +#include "debugconsole/console.h"
  9587.  
  9588.  bool env_enabled = false;
  9589.  bool cell_enabled = false;
  9590. @@ -402,7 +403,7 @@
  9591.  #endif
  9592.  
  9593.  int Watch_malloc = 0;
  9594. -DCF_BOOL(watch_malloc, Watch_malloc )
  9595. +DCF_BOOL(watch_malloc, Watch_malloc );
  9596.  
  9597.  
  9598.  #ifndef NDEBUG
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement