View difference between Paste ID: dS87APbE and NNgaeYuv
SHOW: | | - or go back to the newest paste.
1-
Index: code/ai/aicode.cpp
1+
Index: Makefile.am
2
===================================================================
3-
--- code/ai/aicode.cpp	(revision 10462)
3+
--- Makefile.am	(Revision 10462)
4-
+++ code/ai/aicode.cpp	(working copy)
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-
@@ -11339,16 +11340,14 @@ float get_wing_largest_radius(object *objp, int formation_object_flag)
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-
Index: code/ai/aiturret.cpp
34+
35
-	Wing_y_scale = Dc_arg_float;
36-
--- code/ai/aiturret.cpp	(revision 10462)
36+
37-
+++ code/ai/aiturret.cpp	(working copy)
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-
@@ -1466,10 +1466,16 @@ ship_subsys *aifft_list[MAX_AIFFT_TURRETS];
56+
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-
Index: code/asteroid/asteroid.cpp
76+
77
-	dc_get_arg(ARG_INT);
78-
--- code/asteroid/asteroid.cpp	(revision 10462)
78+
79-
+++ code/asteroid/asteroid.cpp	(working copy)
79+
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-
@@ -1404,23 +1406,8 @@ void asteroid_level_close()
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-
Index: code/bmpman/bmpman.cpp
115+
116
-			Asteroids_enabled ^= 1;	
117-
--- code/bmpman/bmpman.cpp	(revision 10462)
117+
118-
+++ code/bmpman/bmpman.cpp	(working copy)
118+
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-
@@ -669,46 +670,53 @@ int bm_reload(int bitmap_handle, const char* filename)
127+
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-
@@ -2068,48 +2076,52 @@ void bm_unload_all()
215+
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-
Index: code/controlconfig/controlsconfig.cpp
304+
305
+		if (Bm_max_ram > 0) {
306-
--- code/controlconfig/controlsconfig.cpp (revision 10462)
306+
307-
+++ code/controlconfig/controlsconfig.cpp	(working copy)
307+
308-
@@ -28,7 +28,8 @@
308+
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-
@@ -347,7 +348,7 @@ int Config_allowed[] = {
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-
Index: code/debugconsole/console.cpp
326+
327
 
328-
--- code/debugconsole/console.cpp	(revision 10462)
328+
329-
+++ code/debugconsole/console.cpp	(working copy)
329+
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-
+		dc_printf("Command not found: '%s'\n", command);
955+
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-
+		dc_printf( "Ignoring the unused command line tail '%s'\n", command );
971+
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-
Index: code/debugconsole/console.h
1396+
1397
-	}
1398-
index 0000000..966cec6
1398+
1399-
--- code/debugconsole/console.h	(revision 0)
1399+
1400-
+++ code/debugconsole/console.h	(working copy)
1400+
1401-
@@ -0,0 +1,260 @@
1401+
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-
Index: code/debugconsole/consolecmds.cpp
1663+
1664
+
1665-
index 0000000..da30632
1665+
1666-
--- code/debugconsole/consolecmds.cpp	(revision 0)
1666+
1667-
+++ code/debugconsole/consolecmds.cpp	(working copy)
1667+
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-
+ * 1999. You may not sell or otherwise commercially exploit the source or things you 
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-
+	SCP_map<SCP_string, debug_command*>::iterator it = dc_commands.find(_name);
1699+
1700
+ * 
1701-
+	if (it != dc_commands.end()) {
1701+
1702-
+		Int3();		// Command already exists! Somebody didn't use the DCF macro as they should've...
1702+
1703
+ *
1704
+ * @details Usage example:
1705-
+	dc_commands[_name] = this;
1705+
1706
+ * {
1707-
+	name = _name;
1707+
1708-
+	help = _help;
1708+
1709-
+	func = _func;
1709+
1710
+ *     break;
1711
+ * 
1712
+ *     case dcm_help:
1713
+ *         dc_printf( "Usage: sample. Toggles This_var on/off.\n" );
1714-
+	SCP_string command = "";
1714+
1715-
+	Dc_debug_on = true;
1715+
1716
+ *     case dcm_status:
1717-
+	dc_stuff_string_white(command);
1717+
1718
+ *     break;
1719-
+	if (command == "") {
1719+
1720-
+		dc_printf("<debug> No command given");
1720+
1721
+ *             dc_printf( "<debug> Unknown command mode %i", Dc_mode);
1722-
+	} // Else, command is present.
1722+
1723
+ *     }
1724-
+	dc_commands_it it = dc_commands.find(command);
1724+
1725
+ *  
1726
+ *  In the console, the command will be listed as 'toggle_it', and help will display it as:
1727-
+		dc_printf("<debug> Command not found: '%s'\n", command);
1727+
1728
+ *  Note: The only allowed function type is a void fn( void )
1729-
+	} // Else, command exists. Run it.
1729+
1730
+#define DCF(function_name, help_text)	\
1731-
+	dc_printf("<debug> Executing command: '%s'\n", command);
1731+
1732-
+	// try {
1732+
1733-
+	(it->second)->func();
1733+
1734-
+	// } catch {
1734+
1735-
+	// }
1735+
1736
+/**
1737-
+	Dc_debug_on = false;
1737+
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-
+	extern uint DBCOLS;
1742+
1743-
+	unsigned int lines;
1743+
1744-
+	SCP_string command = "";
1744+
1745
+	void dcf_##function_name() {	\
1746-
+	dc_stuff_string_white(command);
1746+
1747
+				dc_printf( "Usage: %s [bool]\nSets %s to true or false.  If nothing passed, then toggles it.\n", #function_name, #bool_variable );	\
1748-
+	if (command != "") {
1748+
1749-
+		dc_commands_it it = dc_commands.find(command);
1749+
1750
+		if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {	\
1751-
+		if (it == dc_commands.end()) {
1751+
1752-
+			dc_printf("Command not found: '%s'\n", command);
1752+
1753
+		}	\
1754
+		if (!dc_maybe_stuff_boolean(&bool_variable)) {	\
1755
+			bool_variable = !bool_variable;	\
1756-
+		dc_printf((it->second)->help);
1756+
1757
+	}	\
1758-
+	} // Else, command line is empty, print out the help list
1758+
1759
+
1760-
+	dc_printf("FreeSpace Open Debug Console\n");
1760+
1761-
+	dc_printf(" These commands are defined internally.\n");
1761+
1762-
+	dc_printf(" Typing 'help function_name' will give the short help on the function.\n");
1762+
1763-
+	dc_printf(" Some functions may have detailed help, try passing \"help\" or \"--help\" to them.");
1763+
1764-
+	dc_printf(" F3 selects last command line. Up and Down arrow keys scroll through the command history\n");
1764+
1765-
+	dc_printf("\n");
1765+
1766
+#define DCF_BOOL2(function_name, bool_variable, short_help, long_help)	\
1767-
+	dc_printf(" Available commands:\n");
1767+
1768-
+	lines = 0;
1768+
1769-
+	for (dc_commands_it it = dc_commands.begin(); it != dc_commands.end(); ++it) {
1769+
1770-
+		if (lines >= (DBCOLS - 1)) {
1770+
1771-
+			if (dc_pause_output(lines) == true) {
1771+
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-
+		dc_printf(" %s\t\t- %s", (it->second)->name, (it->second)->help);
1776+
1777-
+		++lines;
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-
+	switch (Dc_mode) {
1789+
1790-
+	case dcm_command:
1790+
1791-
+		dc_printf("Sorry, This command is not implemented yet...");
1791+
1792
+	debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );	\
1793
+	void dcf_##function_name() {	\
1794-
+	case dcm_help:
1794+
1795-
+		dc_printf("Shell: Change/set various console-related settings.\n");
1795+
1796-
+		dc_printf(" Available arguments:\n");
1796+
1797-
+		dc_printf("\t-font       - Change the console font");
1797+
1798-
+		dc_printf("\t-resize     - Resize the console window\n");
1798+
1799-
+		dc_printf("\t-resize_buf - Resize the console buffer\n");
1799+
1800
+		float_variable = value;	\
1801
+		dc_printf("%s set to %f\n", #float_variable, float_variable);	\
1802-
+	case dcm_status:
1802+
1803-
+		dc_printf("<shell> No status available.\n");
1803+
1804
+ /**
1805
+  * @def Shortcut for single-variable setters/monitors with lower/upper bounds clamping
1806
+  *
1807-
+		dc_printf("<shell> Unknown command mode %i\n", Dc_mode);
1807+
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-
+	switch (Dc_mode) {
1813+
1814-
+	case dcm_command:
1814+
1815-
+		dc_printf("Sorry, This command is not implemented yet...");
1815+
1816
+		if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {	\
1817
+			dc_printf("%s = %f\n", #float_variable, float_variable);		\
1818-
+	case dcm_help:
1818+
1819-
+		dc_printf("Pause: Pause/Unpause the game.\n");
1819+
1820-
+		dc_printf(" Only available in singleplayer games.\n");
1820+
1821
+		CLAMP(float_variable, lower_bounds, upper_bounds);	\
1822
+		float_variable = value;	\
1823-
+	case dcm_status:
1823+
1824-
+		dc_printf("No status available.\n");
1824+
1825
+
1826
+ /**
1827
+  * @def Shortcut for single-variable setters/monitors
1828-
+		dc_printf("<pause> Unknown command mode %i\n", Dc_mode);
1828+
1829
+  * @param [in] function_name
1830
+  * @param [in] int_variable
1831-
Index: code/debugconsole/consoleparse.cpp
1831+
1832
+  */
1833-
index 0000000..2c9c2ae
1833+
1834-
--- code/debugconsole/consoleparse.cpp	(revision 0)
1834+
1835-
+++ code/debugconsole/consoleparse.cpp	(working copy)
1835+
1836-
@@ -0,0 +1,1452 @@
1836+
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-
+	si_start   = 0,
1863+
1864-
+	si_end     = 1,
1864+
1865-
+	si_invalid,
1865+
1866-
+	si_sign,        //!< Sign character, '-' '+'
1866+
1867-
+	si_prefix,      //!< prefix character sequence, 0b, 0o, or 0x
1867+
1868-
+	si_numeral,     //!< Numeral state, 0 - 9
1868+
1869-
+	si_numeral_bin,     //!< Numeral altstate, 0, 1
1869+
1870-
+	si_numeral_octal,   //!< Numeral altstate, 0 - 7
1870+
1871-
+	si_numeral_hex      //!< Numeral altstate, 0 - 9 and 'a' - 'f'
1871+
1872
+ *  
1873
+ *  @details
1874
+ *  Note: Long help, as evoked by '<command> help', should be handled by the function itself. It is recommended
1875-
+	sf_start = 0,
1875+
1876-
+	sf_end = 1,
1876+
1877-
+	sf_invalid,
1877+
1878-
+	sf_sign,		//!< Sign character for mantessa
1878+
1879-
+	sf_whole,		//!< Whole value numeral
1879+
1880-
+	sf_decimal,		//!< Decimal character
1880+
1881-
+	sf_fraction,	//!< Fractional value numeral
1881+
1882-
+	sf_expprefix,	//!< Exponent prefix, 'e', 'E'
1882+
1883-
+	sf_expsign,		//!< Exponent sign
1883+
1884-
+	sf_exponent		//!< Exponent value numeral
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-
+	return ((ch == '-') || (ch == '+'));
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-
+	return ((ch >= '0') && (ch <= '9'));
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-
+	return (ch == '.');
1932+
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-
+	return ((ch == '0') || (ch == '1'));
1938+
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-
+	return ((ch >= '0') && (ch <= '7'));
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-
+	return (((ch >= '0') && (ch <= '9')) || ((ch >= 'a') && (ch <= 'f')) || ((ch >= 'A') || (ch <= 'F')));
1950+
1951
+
1952
+#include "debugconsole/consoleparse.h"
1953
+#include "globalincs/pstypes.h"
1954
+#include "globalincs/vmallocator.h"
1955
+
1956-
+	return (ch == '0');
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-
+	return ((ch == 'b') || (ch == 'B'));
1962+
1963
+ *
1964
+ * @details Usage example:
1965
+ * DCF(toggle_it,"description")
1966
+ * {
1967
+ *     switch (Dc_mode) {
1968-
+	return ((ch == 'o') || (ch == 'O'));
1968+
1969
+ *          This_var = !This_var;
1970
+ *     break;
1971
+ * 
1972
+ *     case dcm_help:
1973
+ *         dc_printf( "Usage: sample. Toggles This_var on/off.\n" );
1974-
+	return ((ch == 'x') || (ch == 'X'));
1974+
1975
+ * 
1976
+ *     case dcm_status:
1977
+ *         dc_printf( "The status is %d.\n", This_var );
1978
+ *     break;
1979
+ *     default:
1980-
+	return ((ch == 'e') || (ch == 'E'));
1980+
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-
+	char token[MAX_TOKEN_LENGTH];
1989+
1990-
+	char *begin_ptr;
1990+
1991
+		void dcf_##function_name();	\
1992-
+	dc_ignore_gray_space();
1992+
1993
+		void dcf_##function_name()
1994-
+	begin_ptr = Cp;
1994+
1995
+
1996-
+	while ((*Cp != '\0') && !is_gray_space(*Cp)) {
1996+
1997-
+		Cp++;
1997+
1998
+ *  
1999
+ *  @param [in] function_name Name of the function, as shown in the debug console
2000-
+	strncpy(token, begin_ptr, (Cp - begin_ptr));
2000+
2001-
+	return token;
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-
+	char token[MAX_TOKEN_LENGTH];
2008+
2009-
+	char *begin_ptr;
2009+
2010-
+	char *ch_ptr = Cp;
2010+
2011
+			dc_printf("%s = %s\n", #function_name, (bool_variable ? "TRUE" : "FALSE"));		\
2012-
+	while ((*ch_ptr != '\0') && is_gray_space(*ch_ptr)) {
2012+
2013-
+		ch_ptr++;
2013+
2014
+		if (!dc_maybe_stuff_boolean(&bool_variable)) {	\
2015
+			bool_variable = !bool_variable;	\
2016-
+	begin_ptr = ch_ptr;
2016+
2017
+	}	\
2018-
+	while ((*ch_ptr != '\0') && !is_gray_space(*ch_ptr)) {
2018+
2019-
+		ch_ptr++;
2019+
2020
+/**
2021
+ *  @def Same as DCF_BOOL, but with custom help strings
2022-
+	strncpy(token, begin_ptr, (ch_ptr - begin_ptr));
2022+
2023-
+	return token;
2023+
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-
+	while (is_white_space(*Cp) && (*Cp != '\0')) {
2027+
2028-
+		Cp++;
2028+
2029
+	void dcf_##function_name() {	\
2030
+		if (dc_optional_string_either("help", "--help")) {	\
2031
+			dc_printf( #long_help );	\
2032
+				return;		\
2033-
+	while (is_gray_space(*Cp) && (*Cp != '\0')) {
2033+
2034-
+		Cp++;
2034+
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-
+	char *str_found = NULL;
2041+
2042
+
2043-
+	dc_ignore_gray_space();
2043+
2044
+  * @def Shortcut for single-variable setters/monitors
2045-
+	if (strnicmp(pstr, Cp, strlen(pstr))) {
2045+
2046-
+		str_found = pstr;
2046+
2047
+  * @param [in] float_variable
2048
+  * @param [in] short_help
2049-
+	if (str_found != NULL) {
2049+
2050-
+		// Found a required string
2050+
2051-
+		if (Dc_debug_on) {
2051+
2052-
+			dc_printf("<debug> Found required string [%s}\n", str_found);
2052+
2053
+	void dcf_##function_name() {	\
2054
+		float value;	\
2055-
+		Cp += strlen(str_found);
2055+
2056
+			dc_printf("%s = %f\n", #float_variable, float_variable);		\
2057-
+		// Didn't find a required string.
2057+
2058-
+		throw errParseString(dc_get_token_no_advance(), pstr);
2058+
2059
+		dc_stuff_float(&value);	\
2060-
+	return true;
2060+
2061
+		dc_printf("%s set to %f\n", #float_variable, float_variable);	\
2062
+	}	\
2063
+
2064
+ /**
2065-
+	char *str_found = NULL;
2065+
2066-
+	int i = -1;
2066+
2067
+  * @param [in] function_name
2068-
+	dc_ignore_gray_space();
2068+
2069
+  * @param [in] short_help
2070-
+	if (strncmp(str1, Cp, strlen(str1) == 0)) {
2070+
2071-
+		str_found = str1;
2071+
2072-
+		i = 0;
2072+
2073-
+	} else if (strncmp(str2, Cp, strlen(str2) == 0)) {
2073+
2074-
+		str_found = str2;
2074+
2075-
+		i = 1;
2075+
2076
+		if (dc_optional_string_either("status", "--status") || dc_optional_string_either("?", "--?")) {	\
2077
+			dc_printf("%s = %f\n", #float_variable, float_variable);		\
2078-
+	if (i > -1) {
2078+
2079-
+		// Found a required string
2079+
2080-
+		if (Dc_debug_on) {
2080+
2081-
+			dc_printf("<debug> Found required string [%s}\n", str_found);
2081+
2082
+		float_variable = value;	\
2083
+		dc_printf("%s set to %f\n", #float_variable, float_variable);	\
2084-
+		Cp += strlen(str_found);
2084+
2085
+
2086-
+		// Didn't find a required string.
2086+
2087-
+		throw errParseString(dc_get_token_no_advance(), str1, str2);
2087+
2088
+  *
2089
+  * @param [in] function_name
2090-
+	return i;
2090+
2091
+  * @param [in] short_help
2092
+  */
2093
+ #define DCF_INT(function_name, int_variable, short_help)	\
2094
+	void dcf_##function_name();		\
2095-
+	char *str_found = NULL;
2095+
2096-
+	int i = -1;
2096+
2097
+		float value;	\
2098-
+	dc_ignore_gray_space();
2098+
2099
+			dc_printf("%s = %f\n", #int_variable, int_variable);		\
2100-
+	if (strncmp(str1, Cp, strlen(str1) == 0)) {
2100+
2101-
+		str_found = str1;
2101+
2102-
+		i = 0;
2102+
2103-
+	} else if (strncmp(str2, Cp, strlen(str2) == 0)) {
2103+
2104-
+		str_found = str2;
2104+
2105-
+		i = 1;
2105+
2106-
+	} else if (strncmp(str3, Cp, strlen(str3) == 0)) {
2106+
2107-
+		str_found = str3;
2107+
2108-
+		i = 2;
2108+
2109
+  *
2110
+  * @param [in] function_name
2111-
+	if (i > -1) {
2111+
2112-
+		// Found a required string
2112+
2113-
+		if (Dc_debug_on) {
2113+
2114-
+			dc_printf("<debug> Found required string [%s}\n", str_found);
2114+
2115
+	void dcf_##function_name();		\
2116
+	debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );	\
2117-
+		Cp += strlen(str_found);
2117+
2118
+		float value;	\
2119-
+		// Didn't find a required string.
2119+
2120-
+		throw errParseString(dc_get_token_no_advance(), str1, str2, str3);
2120+
2121
+			return;		\
2122
+		}	\
2123-
+	return i;
2123+
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-
+	char *str_found = NULL;
2128+
2129-
+	int i = -1;
2129+
2130
+ *  @class debug_command
2131-
+	dc_ignore_gray_space();
2131+
2132
+ *  
2133-
+	if (strncmp(str1, Cp, strlen(str1) == 0)) {
2133+
2134-
+		str_found = str1;
2134+
2135-
+		i = 0;
2135+
2136-
+	} else if (strncmp(str2, Cp, strlen(str2) == 0)) {
2136+
2137-
+		str_found = str2;
2137+
2138-
+		i = 1;
2138+
2139-
+	} else if (strncmp(str3, Cp, strlen(str3) == 0)) {
2139+
2140-
+		str_found = str3;
2140+
2141-
+		i = 2;
2141+
2142-
+	} else if (strncmp(str4, Cp, strlen(str4) == 0)) {
2142+
2143-
+		str_found = str4;
2143+
2144-
+		i = 3;
2144+
2145
+	* @brief Adds a debug command to the debug_commands map, if it isn't in there already.
2146
+	*
2147-
+	if (i > -1) {
2147+
2148-
+		// Found a required string
2148+
2149-
+		if (Dc_debug_on) {
2149+
2150-
+			dc_printf("<debug> Found required string [%s}\n", str_found);
2150+
2151
+};
2152
+
2153-
+		Cp += strlen(str_found);
2153+
2154
+ * Dc_mode tells your function what to do.
2155-
+		// Didn't find a required string.
2155+
2156-
+		throw errParseString(dc_get_token_no_advance(), str1, str2, str3, str4);
2156+
2157
+ * It is recommended that each function have, at minimum, this switch statement:
2158
+ *   switch (Dc_mode) {
2159-
+	return i;
2159+
2160
+ *   	// process command
2161
+ *   	break;
2162
+ *   
2163
+ *   case dcm_help:
2164-
+	dc_ignore_gray_space();
2164+
2165
+ *   	break;
2166-
+	if (strncmp(pstr, Cp, strlen(pstr) != 0)) {
2166+
2167-
+		return false;
2167+
2168-
+	} // Else, optional string was found
2168+
2169
+ *   	break;
2170-
+	if (Dc_debug_on) {
2170+
2171-
+		dc_printf("<debug> Found optional string [%s]\n", pstr);
2171+
2172
+ *		// (optional)
2173
+ *   	dc_printf("<command_name> Unknown command mode %i\n", Dc_mode);
2174-
+	Cp += strlen(pstr);
2174+
2175-
+	return true;
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-
+	char * str_found = NULL;
2180+
2181
+
2182-
+	dc_ignore_gray_space();
2182+
2183
+extern bool Dc_debug_on;
2184-
+	if (strncmp(str1, Cp, strlen(str1)) == 0) {
2184+
2185-
+		str_found = str1;
2185+
2186-
+	} else if (strncmp(str2, Cp, strlen(str2)) == 0) {
2186+
2187-
+		str_found = str2;
2187+
2188
+void dc_printf( char *format, ... );				// Outputs to the debug console
2189-
+		return false;
2189+
2190
+
2191
+#endif // _CONSOLE_H
2192-
+	if (Dc_debug_on) {
2192+
2193-
+		dc_printf("<debug> Found optional string [%s]\n",str_found);
2193+
2194
+/*
2195
+ * z64555's debug console, created for the FreeSpace Source Code project
2196-
+	Cp += strlen(str_found);
2196+
2197-
+	return true;;
2197+
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-
+	strcpy(Command_string, str.c_str());
2207+
2208-
+	Cp = Command_string;
2208+
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-
+	char *ch_ptr = ch;
2222+
2223-
+	char *end_ptr;
2223+
2224-
+	double ret;
2224+
2225-
+	state_float state = sf_start;
2225+
2226-
+	SCP_string buffer_str;
2226+
2227
+ *     switch (Dc_mode) {
2228
+ *     case dcm_command:
2229-
+		if ((ch_ptr == '\0') || is_white_space(*ch_ptr)) {
2229+
2230-
+			state = sf_end;
2230+
2231
+ * 
2232
+ *     case dcm_help:
2233-
+		switch (state) {
2233+
2234-
+		case sf_start:
2234+
2235-
+			if (ch_is_sign(*ch_ptr)) {
2235+
2236-
+				state = sf_sign;
2236+
2237-
+				if (*ch_ptr == '-') {
2237+
2238-
+					buffer_str.push_back(*ch_ptr);
2238+
2239-
+				} // Else, sign is positive, and isn't needed on the buffer
2239+
2240-
+				ch_ptr++;
2240+
2241
+ *             dc_printf( "<debug> Unknown command mode %i", Dc_mode);
2242-
+			} else if (ch_is_numeral(*ch_ptr)) {
2242+
2243-
+				state = sf_whole;
2243+
2244-
+				buffer_str.push_back(*ch_ptr);
2244+
2245-
+				ch_ptr++;
2245+
2246
+ *  In the console, the command will be listed as 'toggle_it', and help will display it as:
2247-
+			} else if (ch_is_decimal(*ch_ptr)) {
2247+
2248-
+				state = sf_decimal;
2248+
2249-
+				buffer_str.push_back(*ch_ptr);
2249+
2250-
+				ch_ptr++;
2250+
2251
+		void dcf_##function_name();	\
2252
+		debug_command dcmd_##function_name(#function_name, help_text, dcf_##function_name);	\
2253-
+				if (Dc_debug_on) {
2253+
2254-
+					dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_start\n", *ch_ptr);
2254+
2255-
+				}
2255+
2256-
+				state = sf_invalid;
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-
+		case sf_end:
2260+
2261-
+			if ((buffer_str == "") || (buffer_str == "-"))
2261+
2262-
+			{
2262+
2263-
+				state = sf_invalid;
2263+
2264-
+			} // Else, we can convert the token.
2264+
2265-
+			// Do nothing, and allow the while loop exit condition to trigger
2265+
2266
+		if (dc_optional_string_either("help", "--help")) {	\
2267-
+		case sf_sign:
2267+
2268-
+			if (ch_is_numeral(*ch_ptr)) {
2268+
2269-
+				state = sf_whole;
2269+
2270-
+				buffer_str.push_back(*ch_ptr);
2270+
2271-
+				ch_ptr++;
2271+
2272
+			return;		\
2273-
+			} else if (ch_is_decimal(*ch_ptr)) {
2273+
2274-
+				state = sf_decimal;
2274+
2275-
+				buffer_str.push_back(*ch_ptr);
2275+
2276-
+				ch_ptr++;
2276+
2277
+	}	\
2278
+
2279-
+				if (Dc_debug_on) {
2279+
2280-
+					dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_sign\n", *ch_ptr);
2280+
2281-
+				}
2281+
2282-
+				state = sf_invalid;
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-
+		case sf_whole:
2286+
2287-
+			if (ch_is_numeral(*ch_ptr)) {
2287+
2288-
+				buffer_str.push_back(*ch_ptr);
2288+
2289-
+				ch_ptr++;
2289+
2290
+		if (dc_optional_string_either("help", "--help")) {	\
2291-
+			} else if (ch_is_decimal(*ch_ptr)) {
2291+
2292-
+				state = sf_decimal;
2292+
2293-
+				buffer_str.push_back(*ch_ptr);
2293+
2294-
+				ch_ptr++;
2294+
2295
+			dc_printf("%s = %s\n", #function_name, (bool_variable ? "TRUE" : "FALSE"));		\
2296-
+			} else if (ch_is_exp_prefix(*ch_ptr)) {
2296+
2297-
+				state = sf_expprefix;
2297+
2298-
+				buffer_str.push_back(*ch_ptr);
2298+
2299-
+				ch_ptr++;
2299+
2300
+		}	\
2301
+	}	\
2302-
+				if (Dc_debug_on) {
2302+
2303-
+					dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_whole\n", *ch_ptr);
2303+
2304-
+				}
2304+
2305-
+				state = sf_invalid;
2305+
2306
+  * @param [in] function_name
2307
+  * @param [in] float_variable
2308
+  * @param [in] short_help
2309-
+		case sf_decimal:
2309+
2310-
+			if (ch_is_numeral(*ch_ptr)) {
2310+
2311-
+				state = sf_fraction;
2311+
2312-
+				buffer_str.push_back(*ch_ptr);
2312+
2313-
+				ch_ptr++;
2313+
2314
+		float value;	\
2315-
+			} else if (ch_is_exp_prefix(*ch_ptr)) {
2315+
2316-
+				state = sf_expprefix;
2316+
2317-
+				buffer_str.push_back(*ch_ptr);
2317+
2318-
+				ch_ptr++;
2318+
2319
+		dc_stuff_float(&value);	\
2320
+		float_variable = value;	\
2321-
+				if (Dc_debug_on) {
2321+
2322-
+					dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_decimal\n", *ch_ptr);
2322+
2323-
+				}
2323+
2324-
+				state = sf_invalid;
2324+
2325
+  * @def Shortcut for single-variable setters/monitors with lower/upper bounds clamping
2326
+  *
2327
+  * @param [in] function_name
2328-
+		case sf_fraction:
2328+
2329-
+			if (ch_is_numeral(*ch_ptr)) {
2329+
2330-
+				buffer_str.push_back(*ch_ptr);
2330+
2331-
+				ch_ptr++;
2331+
2332
+	void dcf_##function_name();		\
2333-
+			} else if (ch_is_exp_prefix(*ch_ptr)) {
2333+
2334-
+				state = sf_expprefix;
2334+
2335-
+				buffer_str.push_back(*ch_ptr);
2335+
2336-
+				ch_ptr++;
2336+
2337
+			dc_printf("%s = %f\n", #float_variable, float_variable);		\
2338
+			return;		\
2339-
+				if (Dc_debug_on) {
2339+
2340-
+					dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_faction\n", *ch_ptr);
2340+
2341-
+				}
2341+
2342-
+				state = sf_invalid;
2342+
2343
+		dc_printf("%s set to %f\n", #float_variable, float_variable);	\
2344
+	}	\
2345
+
2346-
+		case sf_expprefix:
2346+
2347-
+			if (ch_is_sign(*ch_ptr)) {
2347+
2348-
+				state = sf_expsign;
2348+
2349-
+				buffer_str.push_back(*ch_ptr);
2349+
2350-
+				ch_ptr++;
2350+
2351
+  * @param [in] short_help
2352-
+			} else if (ch_is_numeral(*ch_ptr)) {
2352+
2353-
+				state = sf_exponent;
2353+
2354-
+				buffer_str.push_back(*ch_ptr);
2354+
2355-
+				ch_ptr++;
2355+
2356
+	void dcf_##function_name() {	\
2357
+		float value;	\
2358-
+				if (Dc_debug_on) {
2358+
2359-
+					dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_expprefix\n", *ch_ptr);
2359+
2360-
+				}
2360+
2361-
+				state = sf_invalid;
2361+
2362
+		dc_stuff_float(&value);	\
2363
+		int_variable = value;	\
2364
+		dc_printf("%s set to %f\n", #int_variable, int_variable);	\
2365-
+		case sf_expsign:
2365+
2366-
+			if (ch_is_numeral(*ch_ptr)) {
2366+
2367-
+				state = sf_exponent;
2367+
2368-
+				buffer_str.push_back(*ch_ptr);
2368+
2369-
+				ch_ptr++;
2369+
2370
+  * @param [in] function_name
2371
+  * @param [in] int_variable
2372-
+				if (Dc_debug_on) {
2372+
2373-
+					dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_expsign\n", *ch_ptr);
2373+
2374-
+				}
2374+
2375-
+				state = sf_invalid;
2375+
2376
+	debug_command dcmd_##function_name(#function_name, #short_help, dcf_##function_name );	\
2377
+	void dcf_##function_name() {	\
2378
+		float value;	\
2379-
+		case sf_exponent:
2379+
2380-
+			if (ch_is_numeral(*ch_ptr)) {
2380+
2381-
+				buffer_str.push_back(*ch_ptr);
2381+
2382-
+				ch_ptr++;
2382+
2383
+		dc_stuff_float(&value);	\
2384
+		CLAMP(int_variable, lower_bounds, upper_bounds);	\
2385-
+				if (Dc_debug_on) {
2385+
2386-
+					dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_exponent\n", *ch_ptr);
2386+
2387-
+				}
2387+
2388-
+				state = sf_invalid;
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-
+		case sf_invalid:
2392+
2393
+ *  @details
2394-
+			SCP_string token = dc_get_token_no_advance();
2394+
2395-
+			dc_printf("Syntax Error: Expected integer, found '%s'\n", token);
2395+
2396-
+			throw errParse(token.c_str(), type);
2396+
2397
+ */
2398-
+	} while (state != sf_end);
2398+
2399
+public:
2400-
+	ret = strtod(buffer_str.c_str(), &end_ptr);
2400+
2401
+	char *help;		//!< The short help string, as shown by 'help <command>'
2402-
+	return ret;
2402+
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-
+	char *ch_ptr = ch;
2421+
2422-
+	char *end_ptr;
2422+
2423-
+	int base = 10;
2423+
2424-
+	long ret;
2424+
2425-
+	state_int state = si_start;
2425+
2426-
+	SCP_string buffer_str;
2426+
2427
+ *   case dcm_status:
2428-
+	while ((*ch_ptr != '\0') || is_white_space(*ch_ptr)) {
2428+
2429-
+		ch_ptr++;
2429+
2430
+ *   
2431
+ *   default:
2432-
+	if (*ch_ptr == '\0') {
2432+
2433-
+		if (Dc_debug_on) {
2433+
2434-
+			dc_printf("<debug> [parse_long] no argument found\n");
2434+
2435
+ */
2436-
+		throw errParse("", type);
2436+
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-
+		if ((ch_ptr == '\0') || is_white_space(*ch_ptr)) {
2440+
2441-
+			state = si_end;
2441+
2442
+extern dc_mode Dc_mode;
2443
+extern bool Dc_debug_on;
2444-
+		switch (state) {
2444+
2445-
+		case si_start:
2445+
2446-
+			if (ch_is_sign(*ch_ptr)) {
2446+
2447-
+				state = si_sign;
2447+
2448-
+				if (*ch_ptr == '-') {
2448+
2449-
+					buffer_str.push_back(*ch_ptr);
2449+
2450-
+				} // Else, it's positive. Positive sign isn't needed for conversion
2450+
2451-
+				ch_ptr++;
2451+
2452
\ No newline at end of file
2453-
+			} else if (ch_is_prefix(*ch_ptr)) {
2453+
Index: debugconsole/consolecmds.cpp
2454-
+				// prefixes must be checked before numeral, because they all start with a numeral zero
2454+
2455-
+				state = si_prefix;
2455+
--- debugconsole/consolecmds.cpp	(Revision 0)
2456-
+				ch_ptr++;
2456+
+++ debugconsole/consolecmds.cpp	(Arbeitskopie)
2457
@@ -0,0 +1,162 @@
2458-
+			} else if (ch_is_numeral(*ch_ptr)) {
2458+
2459-
+				state = si_numeral;
2459+
2460-
+				buffer_str.push_back(*ch_ptr);
2460+
2461-
+				ch_ptr++;
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-
+				if (Dc_debug_on) {
2464+
2465-
+					dc_printf("<debug> [parse_long] Invalid character '%c' found in si_start\n", *ch_ptr);
2465+
2466-
+				}
2466+
2467-
+				state = si_invalid;
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-
+		case si_end:
2471+
2472-
+			if ((buffer_str == "") || (buffer_str == "-"))
2472+
2473-
+			{
2473+
2474-
+				state = si_invalid;
2474+
2475-
+			} // Else, we can convert the token.
2475+
2476-
+			// Do nothing, and allow the while loop exit condition to trigger
2476+
2477
+#include "debugconsole/console.h"
2478
+#include "debugconsole/consoleparse.h"
2479-
+		case si_sign:
2479+
2480-
+			state = process_state_sign(ch_ptr, buffer_str);
2480+
2481
+#include "io/key.h"
2482
+
2483-
+		case si_prefix:
2483+
2484-
+			state = process_state_prefix(ch_ptr, buffer_str, base);
2484+
2485
+
2486
+debug_command::debug_command(char *_name, char *_help, void (*_func)())
2487-
+		case si_numeral_bin:
2487+
2488-
+			state = process_state_numeral_bin(ch_ptr, buffer_str);
2488+
+       SCP_map<SCP_string, debug_command*>::iterator it = dc_commands.find(_name);
2489
+      
2490
+       if (it != dc_commands.end()) {
2491-
+		case si_numeral_octal:
2491+
+               Int3();         // Command already exists! Somebody didn't use the DCF macro as they should've...
2492-
+			state = process_state_numeral_octal(ch_ptr, buffer_str);
2492+
+       }
2493
+
2494
+       dc_commands[_name] = this;
2495-
+		case si_numeral_hex:
2495+
2496-
+			state = process_state_numeral_hex(ch_ptr, buffer_str);
2496+
+       name = _name;
2497
+       help = _help;
2498
+       func = _func;
2499-
+		case si_numeral:
2499+
2500-
+			state = process_state_numeral(ch_ptr, buffer_str);
2500+
2501
+DCF( debug, "Runs a command in debug mode.")
2502
+{
2503-
+		case si_invalid:
2503+
+       SCP_string command = "";
2504
+       Dc_debug_on = true;
2505-
+			SCP_string token = dc_get_token_no_advance();
2505+
2506-
+			dc_printf("Syntax Error: Expected integer, found '%s'\n", token);
2506+
+       dc_stuff_string_white(command);
2507-
+			throw errParse(token.c_str(), type);
2507+
2508
+       if (command == "") {
2509-
+	} while (state != si_end);
2509+
+               dc_printf("<debug> No command given");
2510
+               return;
2511-
+	ret = strtol(buffer_str.c_str(), &end_ptr, base);
2511+
+       } // Else, command is present.
2512
+
2513-
+	// This last check can be omitted once I can verify the operation of strtol in this sense
2513+
+       dc_commands_it it = dc_commands.find(command);
2514-
+	if (end_ptr != ch_ptr) {
2514+
2515-
+		dc_printf("Error: Could not convert all of the buffer '%s'.\n", buffer_str.c_str());
2515+
+       if (it == dc_commands.end()) {
2516-
+		if (Dc_debug_on) {
2516+
+               dc_printf("<debug> Command not found: '%s'\n", command.c_str());
2517-
+			dc_printf("<debug> Buffer value: %s\n", buffer_str.c_str());
2517+
+               return;
2518-
+			dc_printf("<debug> Return value: %i", ret);
2518+
+       } // Else, command exists. Run it.
2519
+
2520-
+		throw errParse(ch, type);
2520+
+       dc_printf("<debug> Executing command: '%s'\n", command.c_str());
2521
+       // try {
2522
+       (it->second)->func();
2523-
+	return ret;
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-
+	char *ch_ptr = ch;
2540+
+               if (it == dc_commands.end()) {
2541-
+	char *end_ptr;
2541+
+                       dc_printf("Command not found: '%s'\n", command.c_str());
2542-
+	int base = 10;
2542+
+                       return;
2543-
+	ulong ret;
2543+
+               }
2544-
+	state_int state = si_start;
2544+
2545-
+	SCP_string buffer_str;
2545+
+               dc_printf((it->second)->help);
2546
+               return;
2547-
+	while ((*ch_ptr != '\0') || is_white_space(*ch_ptr)) {
2547+
+       } // Else, command line is empty, print out the help list
2548-
+		ch_ptr++;
2548+
2549
+       dc_printf("FreeSpace Open Debug Console\n");
2550
+       dc_printf(" These commands are defined internally.\n");
2551-
+	if (*ch_ptr == '\0') {
2551+
+       dc_printf(" Typing 'help function_name' will give the short help on the function.\n");
2552-
+		if (Dc_debug_on) {
2552+
+       dc_printf(" Some functions may have detailed help, try passing \"help\" or \"--help\" to them.");
2553-
+			dc_printf("<debug> [parse_long] no argument found\n");
2553+
+       dc_printf(" F3 selects last command line. Up and Down arrow keys scroll through the command history\n");
2554
+       dc_printf("\n");
2555-
+		throw errParse("", type);
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 ((ch_ptr == '\0') || is_white_space(*ch_ptr)) {
2559+
+               if (lines >= (DBCOLS - 1)) {
2560-
+			state = si_end;
2560+
+                       if (dc_pause_output(lines) == true) {
2561
+                               break;
2562
+                       }
2563
+               }
2564-
+		switch (state) {
2564+
2565-
+		case si_start:
2565+
+               dc_printf(" %s\t\t- %s", (it->second)->name, (it->second)->help);
2566-
+			if (ch_is_prefix(*ch_ptr)) {
2566+
+               ++lines;
2567-
+				// prefixes must be checked before numeral, because they all start with a numeral zero
2567+
+       }
2568-
+				state = si_prefix;
2568+
2569-
+				ch_ptr++;
2569+
2570
+debug_command dc_man("man", "Also displays the help list", dcf_help);
2571-
+			} else if (ch_is_numeral(*ch_ptr)) {
2571+
2572-
+				state = si_numeral;
2572+
2573-
+				buffer_str.push_back(*ch_ptr);
2573+
2574-
+				ch_ptr++;
2574+
2575
+
2576
+DCF( shell, "Change/set various console-related settings.\n" )
2577-
+				if (Dc_debug_on) {
2577+
2578-
+					dc_printf("<debug> [parse_long] Invalid character '%s' found in si_start\n", *ch_ptr);
2578+
+       switch (Dc_mode) {
2579-
+				}
2579+
+       case dcm_command:
2580-
+				state = si_invalid;
2580+
+               dc_printf("Sorry, This command is not implemented yet...");
2581
+               break;
2582
+
2583
+       case dcm_help:
2584-
+		case si_end:
2584+
+               dc_printf("Shell: Change/set various console-related settings.\n");
2585-
+			if (buffer_str == "")
2585+
+               dc_printf(" Available arguments:\n");
2586-
+			{
2586+
+               dc_printf("\t-font       - Change the console font");
2587-
+				state = si_invalid;
2587+
+               dc_printf("\t-resize     - Resize the console window\n");
2588-
+			} // Else, we can convert the token.
2588+
+               dc_printf("\t-resize_buf - Resize the console buffer\n");
2589-
+			// Do nothing, and allow the while loop exit condition to trigger
2589+
+               break;
2590
+
2591
+       case dcm_status:
2592-
+		case si_sign:
2592+
+               dc_printf("<shell> No status available.\n");
2593-
+			state = process_state_sign(ch_ptr, buffer_str);
2593+
+               break;
2594
+
2595
+       default:
2596-
+		case si_prefix:
2596+
+               dc_printf("<shell> Unknown command mode %i\n", Dc_mode);
2597-
+			state = process_state_prefix(ch_ptr, buffer_str, base);
2597+
+       }
2598
+}
2599
+
2600-
+		case si_numeral_bin:
2600+
2601-
+			state = process_state_numeral_bin(ch_ptr, buffer_str);
2601+
2602
+       switch (Dc_mode) {
2603
+       case dcm_command:
2604-
+		case si_numeral_octal:
2604+
+               dc_printf("Sorry, This command is not implemented yet...");
2605-
+			state = process_state_numeral_octal(ch_ptr, buffer_str);
2605+
+               break;
2606
+
2607
+       case dcm_help:
2608-
+		case si_numeral_hex:
2608+
+               dc_printf("Pause: Pause/Unpause the game.\n");
2609-
+			state = process_state_numeral_hex(ch_ptr, buffer_str);
2609+
+               dc_printf(" Only available in singleplayer games.\n");
2610
+               break;
2611
+
2612-
+		case si_numeral:
2612+
+       case dcm_status:
2613-
+			state = process_state_numeral(ch_ptr, buffer_str);
2613+
+               dc_printf("No status available.\n");
2614
+               break;
2615
+
2616-
+		case si_invalid:
2616+
+       default:
2617
+               dc_printf("<pause> Unknown command mode %i\n", Dc_mode);
2618-
+			SCP_string token = dc_get_token();
2618+
+       }
2619-
+			dc_printf("Syntax Error: Expected unsigned integer, found '%s'\n", token);
2619+
2620-
+			throw errParse(token.c_str(), type);
2620+
Index: debugconsole/consoleparse.cpp
2621
===================================================================
2622-
+	} while (state != si_end);
2622+
--- debugconsole/consoleparse.cpp	(Revision 0)
2623
+++ debugconsole/consoleparse.cpp	(Arbeitskopie)
2624-
+	ret = strtoul(buffer_str.c_str(), &end_ptr, base);
2624+
@@ -0,0 +1,1453 @@
2625
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2626-
+	// This last check can be omitted once I can verify the operation of strtol in this sense
2626+
2627-
+	if (end_ptr != ch_ptr) {
2627+
2628-
+		dc_printf("Error: Could not convert all of the buffer '%s'.\n", buffer_str.c_str());
2628+
2629-
+		if (Dc_debug_on) {
2629+
2630-
+			dc_printf("<debug> Buffer value: %s\n", buffer_str.c_str());
2630+
2631-
+			dc_printf("<debug> Return value: %i", ret);
2631+
2632
+/////////////////
2633-
+		throw errParse(ch, type);
2633+
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-
+	return ret;
2636+
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-
+	double value_d;
2651+
2652
+       si_start   = 0,
2653-
+	dc_ignore_gray_space();
2653+
+       si_end     = 1,
2654
+       si_invalid,
2655-
+	value_d = dc_parse_double(Cp, DCT_FLOAT);
2655+
+       si_sign,        //!< Sign character, '-' '+'
2656
+       si_prefix,      //!< prefix character sequence, 0b, 0o, or 0x
2657-
+	if ((value_d < FLT_MAX) && (value_d > FLT_MIN)) {
2657+
+       si_numeral,     //!< Numeral state, 0 - 9
2658-
+		*f = value_d;
2658+
+       si_numeral_bin,     //!< Numeral altstate, 0, 1
2659-
+		dc_get_token();    // Advance Cp
2659+
+       si_numeral_octal,   //!< Numeral altstate, 0 - 7
2660
+       si_numeral_hex      //!< Numeral altstate, 0 - 9 and 'a' - 'f'
2661
+};
2662-
+		throw errParse(dc_get_token(), DCT_FLOAT);
2662+
2663
+enum state_float {
2664
+       sf_start = 0,
2665
+       sf_end = 1,
2666
+       sf_invalid,
2667
+       sf_sign,                //!< Sign character for mantessa
2668-
+	long value_l;
2668+
+       sf_whole,               //!< Whole value numeral
2669
+       sf_decimal,             //!< Decimal character
2670-
+	dc_ignore_gray_space();
2670+
+       sf_fraction,    //!< Fractional value numeral
2671
+       sf_expprefix,   //!< Exponent prefix, 'e', 'E'
2672-
+	value_l = dc_parse_long(Cp, DCT_INT);
2672+
+       sf_expsign,             //!< Exponent sign
2673
+       sf_exponent             //!< Exponent value numeral
2674-
+	if ((value_l < INT_MAX) && (value_l > INT_MIN)) {
2674+
2675-
+		*i = value_l;
2675+
2676-
+		dc_get_token();    // Advance Cp
2676+
2677
+bool ch_is_numeral(char ch);
2678
+bool ch_is_decimal(char ch);
2679-
+		throw errParse(dc_get_token(), DCT_INT);
2679+
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-
+	ulong value_l;
2685+
2686
+bool ch_is_hex_prefix(char ch);
2687-
+	dc_ignore_gray_space();
2687+
2688
+
2689-
+	value_l = dc_parse_long(Cp, DCT_INT);
2689+
2690
+char *dc_get_token_no_advance(void);
2691-
+	if (value_l < UINT_MAX) {
2691+
2692-
+		*i = value_l;
2692+
2693-
+		dc_get_token();    // Advance Cp
2693+
2694
+ulong  dc_parse_ulong(char *ch, dc_token type);
2695
+
2696-
+		throw errParse(dc_get_token(), DCT_INT);
2696+
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-
+	ulong value_ul;
2702+
2703
+
2704-
+	dc_ignore_gray_space();
2704+
2705
+// Character identification
2706-
+	value_ul = dc_parse_ulong(Cp, DCT_UBYTE);
2706+
2707
+bool ch_is_sign(char ch)
2708-
+	// Since some system's chars may be greater than 1 byte, we can't use UCHAR_MAX for a UBYTE
2708+
2709-
+	if ((value_ul <= 255) && (value_ul >= 0)) {
2709+
+       return ((ch == '-') || (ch == '+'));
2710-
+		*i = value_ul;
2710+
2711-
+		dc_get_token();    // Advance Cp
2711+
2712
+inline
2713
+bool ch_is_numeral(char ch)
2714-
+		throw errParse(dc_get_token(), DCT_UBYTE);
2714+
2715
+       return ((ch >= '0') && (ch <= '9'));
2716
+}
2717
+
2718
+inline
2719
+bool ch_is_decimal(char ch)
2720-
+	SCP_string token;
2720+
2721
+       return (ch == '.');
2722-
+	token = dc_get_token();
2722+
2723
+
2724-
+	if ((token == "yes")
2724+
2725-
+		|| (token == "true")
2725+
2726-
+		|| (token == "ja")          // German
2726+
2727-
+		|| (token == "Oui")         // French
2727+
+       return ((ch == '0') || (ch == '1'));
2728-
+		|| (token == "si")          // Spanish
2728+
2729-
+//		|| (token == "ita vero")    // Latin, not supported
2729+
2730-
+		|| (token == "HIja") || (token == "HISLaH"))    // Klingon
2730+
2731
+bool ch_is_octal(char ch)
2732-
+		*b = true;
2732+
2733
+       return ((ch >= '0') && (ch <= '7'));
2734-
+	} else if ((token == "no")
2734+
2735-
+		|| (token == "false")
2735+
2736-
+		|| (token == "nein")    // German
2736+
2737-
+		|| (token == "Non")     // French
2737+
2738-
+//		|| (token == "no")      // Spanish, redundant with English "no"
2738+
2739-
+//		|| (token == "minime")  // Latin, not supported
2739+
+       return (((ch >= '0') && (ch <= '9')) || ((ch >= 'a') && (ch <= 'f')) || ((ch >= 'A') || (ch <= 'F')));
2740-
+		|| (token == "ghobe'"))  // Klingon
2740+
2741
+
2742-
+		*b = false;
2742+
2743
+bool ch_is_prefix(char ch)
2744
+{
2745-
+		throw errParse(token.c_str(), DCT_BOOL);
2745+
+       return (ch == '0');
2746
+}
2747
+
2748
+inline
2749
+bool ch_is_binary_prefix(char ch)
2750
+{
2751
+       return ((ch == 'b') || (ch == 'B'));
2752-
+	bool value_b;
2752+
2753
+
2754-
+	dc_stuff_boolean(&value_b);
2754+
2755
+bool ch_is_octal_prefix(char ch)
2756-
+	value_b ? *i = 1 : *i = 0;
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-
+	size_t count = 0;
2769+
+       return ((ch == 'e') || (ch == 'E'));
2770-
+	char *c_ptr = Cp;
2770+
2771
+
2772-
+	Assert(Cp);
2772+
2773-
+	Assert(out_str);
2773+
2774
+/**
2775-
+	// Advance past grayspace, stopping at null terminator
2775+
2776-
+	while (is_gray_space(*c_ptr) && (*c_ptr != '\0')) {
2776+
2777-
+		c_ptr++;
2777+
2778
+       char token[MAX_TOKEN_LENGTH];
2779
+       char *begin_ptr;
2780-
+	// Bail if we're at the terminator
2780+
2781-
+	if (*c_ptr == '\0') {
2781+
+       dc_ignore_gray_space();
2782-
+		throw errParse("Nothing!", DCT_STRING);
2782+
2783
+       begin_ptr = Cp;
2784
+
2785
+       while ((*Cp != '\0') && !is_gray_space(*Cp)) {
2786-
+	// Scan the string, stopping at null terminator, or before we overflow
2786+
+               Cp++;
2787-
+	while ((*c_ptr != '\0') && (count < maxlen)) {
2787+
+       }
2788-
+		count++;
2788+
2789
+       strncpy(token, begin_ptr, (Cp - begin_ptr));
2790
+       return token;
2791-
+	// Bail if overflow
2791+
2792-
+	if (count == maxlen) {
2792+
2793-
+		throw errParse("", DCT_STRING);
2793+
2794
+ * @brief Returns a single token, but does not advances Cp
2795
+ */
2796
+char * dc_get_token_no_advance(void) {
2797-
+	// Copy string into out_str
2797+
+       char token[MAX_TOKEN_LENGTH];
2798-
+	strncpy(out_str, Cp, (c_ptr - Cp));
2798+
+       char *begin_ptr;
2799
+       char *ch_ptr = Cp;
2800-
+	// Advance the parser pointer past what we copied
2800+
2801-
+	Cp = c_ptr;
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-
+ * @details 
2809+
+       }
2810
+
2811
+       strncpy(token, begin_ptr, (ch_ptr - begin_ptr));
2812
+       return token;
2813-
+	size_t count = 0;
2813+
2814-
+	char *c_ptr = Cp;
2814+
2815
+void dc_ignore_white_space(void) {
2816-
+	Assert(Cp);
2816+
+       while (is_white_space(*Cp) && (*Cp != '\0')) {
2817
+               Cp++;
2818-
+	// Advance past grayspace, stopping at null terminator
2818+
+       }
2819-
+	while (is_gray_space(*c_ptr) && (*c_ptr != '\0')) {
2819+
2820-
+		c_ptr++;
2820+
2821
+void dc_ignore_gray_space(void) {
2822
+       while (is_gray_space(*Cp) && (*Cp != '\0')) {
2823-
+	// Bail if we're at the terminator
2823+
+               Cp++;
2824-
+	if (*c_ptr == '\0') {
2824+
+       }
2825-
+		throw errParse("Nothing!", DCT_STRING);
2825+
2826
+
2827
+// Required/Optional Strings
2828
+bool dc_required_string(char *pstr)
2829-
+	// Scan the string, stopping at null terminator, or before we overflow
2829+
2830-
+	while ((*c_ptr != '\0') && (count < out_str.max_size())) {
2830+
+       char *str_found = NULL;
2831-
+		count++;
2831+
2832
+       dc_ignore_gray_space();
2833
+
2834-
+	// Bail if overflow
2834+
+       if (strnicmp(pstr, Cp, strlen(pstr))) {
2835-
+	if (count == out_str.max_size()) {
2835+
+               str_found = pstr;
2836-
+		throw errParse("", DCT_STRING);
2836+
+       }
2837
+
2838
+       if (str_found != NULL) {
2839
+               // Found a required string
2840-
+	// Copy string into out_str
2840+
+               if (Dc_debug_on) {
2841-
+	out_str.copy(Cp, (c_ptr - Cp));
2841+
+                       dc_printf("<debug> Found required string [%s}\n", str_found);
2842
+               }
2843-
+	// Advance the parser pointer past what we copied
2843+
2844-
+	Cp = c_ptr;
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-
+	size_t count = 0;
2855+
+       int i = -1;
2856-
+	char *c_ptr = Cp;
2856+
2857
+       dc_ignore_gray_space();
2858-
+	Assert(Cp);
2858+
2859-
+	Assert(out_str);
2859+
+       if (strncmp(str1, Cp, strlen(str1) == 0)) {
2860
+               str_found = str1;
2861-
+	// Advance past grayspace, stopping at null terminator
2861+
+               i = 0;
2862-
+	while (is_gray_space(*c_ptr) && (*c_ptr != '\0')) {
2862+
+       } else if (strncmp(str2, Cp, strlen(str2) == 0)) {
2863-
+		c_ptr++;
2863+
+               str_found = str2;
2864
+               i = 1;
2865
+       }
2866-
+	// Bail if we're at the terminator
2866+
2867-
+	if (*c_ptr == '\0') {
2867+
+       if (i > -1) {
2868-
+		throw errParse("Nothing!", DCT_STRING);
2868+
+               // Found a required string
2869
+               if (Dc_debug_on) {
2870
+                       dc_printf("<debug> Found required string [%s}\n", str_found);
2871
+               }
2872-
+	// Scan the string, stopping at grayspace, null terminator, or before we overflow
2872+
2873-
+	while (!is_gray_space(*c_ptr) && (*c_ptr != '\0') && (count < maxlen)) {
2873+
+               Cp += strlen(str_found);
2874-
+		count++;
2874+
+       } else {
2875
+               // Didn't find a required string.
2876
+               throw errParseString(dc_get_token_no_advance(), str1, str2);
2877-
+	// Bail if overflow
2877+
+       }
2878-
+	if (count == maxlen) {
2878+
2879-
+		throw errParse("", DCT_STRING);
2879+
+       return i;
2880
+}
2881
+
2882
+int dc_required_string_3(char *str1, char *str2, char *str3)
2883-
+	// Copy string into out_str
2883+
2884-
+	strncpy(out_str, Cp, (c_ptr - Cp));
2884+
+       char *str_found = NULL;
2885
+       int i = -1;
2886-
+	// Advance the parser pointer past what we copied
2886+
2887-
+	Cp = c_ptr;
2887+
+       dc_ignore_gray_space();
2888
+
2889
+       if (strncmp(str1, Cp, strlen(str1) == 0)) {
2890
+               str_found = str1;
2891
+               i = 0;
2892-
+	size_t count = 0;
2892+
+       } else if (strncmp(str2, Cp, strlen(str2) == 0)) {
2893-
+	char *c_ptr = Cp;
2893+
+               str_found = str2;
2894
+               i = 1;
2895-
+	Assert(Cp);
2895+
+       } else if (strncmp(str3, Cp, strlen(str3) == 0)) {
2896
+               str_found = str3;
2897-
+	// Advance past grayspace, stopping at null terminator
2897+
+               i = 2;
2898-
+	while (is_gray_space(*c_ptr) && (*c_ptr != '\0')) {
2898+
+       }
2899-
+		c_ptr++;
2899+
2900
+       if (i > -1) {
2901
+               // Found a required string
2902-
+	// Bail if we're at the terminator
2902+
+               if (Dc_debug_on) {
2903-
+	if (*c_ptr == '\0') {
2903+
+                       dc_printf("<debug> Found required string [%s}\n", str_found);
2904-
+		throw errParse("Nothing!", DCT_STRING);
2904+
+               }
2905
+
2906
+               Cp += strlen(str_found);
2907
+       } else {
2908-
+	// Scan the string, stopping at grayspace, null terminator, or before we overflow
2908+
+               // Didn't find a required string.
2909-
+	while (!is_gray_space(*c_ptr) && (*c_ptr != '\0') && (count < out_str.max_size())) {
2909+
+               throw errParseString(dc_get_token_no_advance(), str1, str2, str3);
2910-
+		count++;
2910+
+       }
2911
+
2912
+       return i;
2913-
+	// Bail if overflow
2913+
2914-
+	if (count == out_str.max_size()) {
2914+
2915-
+		throw errParse("", DCT_STRING);
2915+
2916
+{
2917
+       char *str_found = NULL;
2918
+       int i = -1;
2919-
+	// Copy string into out_str
2919+
2920-
+	out_str.copy(Cp, (c_ptr - Cp));
2920+
+       dc_ignore_gray_space();
2921
+
2922-
+	// Advance the parser pointer past what we copied
2922+
+       if (strncmp(str1, Cp, strlen(str1) == 0)) {
2923-
+	Cp = c_ptr;
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-
+	dc_ignore_gray_space();
2943+
+       } else {
2944
+               // Didn't find a required string.
2945-
+	if (Cp != '\0') {
2945+
+               throw errParseString(dc_get_token_no_advance(), str1, str2, str3, str4);
2946-
+		dc_stuff_float(f);
2946+
+       }
2947-
+		return true;
2947+
2948
+       return i;
2949
+}
2950-
+		*f = 0;
2950+
2951-
+		return false;
2951+
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-
+	dc_ignore_gray_space();
2970+
2971
+       dc_ignore_gray_space();
2972-
+	if (Cp != '\0') {
2972+
2973-
+		dc_stuff_int(i);
2973+
+       if (strncmp(str1, Cp, strlen(str1)) == 0) {
2974-
+		return true;
2974+
+               str_found = str1;
2975
+       } else if (strncmp(str2, Cp, strlen(str2)) == 0) {
2976-
+		*i = 0;
2976+
+               str_found = str2;
2977-
+		return false;
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-
+	dc_ignore_gray_space();
2996+
+       strcpy(Command_string, str.c_str());
2997
+       Cp = Command_string;
2998-
+	if (Cp != '\0') {
2998+
2999-
+		dc_stuff_uint(i);
2999+
3000-
+		return true;
3000+
3001
+ * @brief Parses a double-precision floating point type. Supports, Whole, Fractional, and Mixed numbers, and supports
3002-
+		*i = 0;
3002+
3003-
+		return false;
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-
+	dc_ignore_gray_space();
3022+
+               switch (state) {
3023
+               case sf_start:
3024-
+	if (Cp != '\0') {
3024+
+                       if (ch_is_sign(*ch_ptr)) {
3025-
+		dc_stuff_ubyte(i);
3025+
+                               state = sf_sign;
3026-
+		return true;
3026+
+                               if (*ch_ptr == '-') {
3027
+                                       buffer_str.push_back(*ch_ptr);
3028-
+		*i = 0;
3028+
+                               } // Else, sign is positive, and isn't needed on the buffer
3029-
+		return false;
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-
+	dc_ignore_gray_space();
3048+
+                       break;
3049
+               case sf_end:
3050-
+	if (Cp != '\0') {
3050+
+                       if ((buffer_str == "") || (buffer_str == "-"))
3051-
+		dc_stuff_boolean(b);
3051+
+                       {
3052-
+		return true;
3052+
+                               state = sf_invalid;
3053
+                       } // Else, we can convert the token.
3054-
+		*b = false;
3054+
+                       // Do nothing, and allow the while loop exit condition to trigger
3055-
+		return false;
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-
+	dc_ignore_gray_space();
3074+
+                       break;
3075
+               case sf_whole:
3076-
+	if (Cp != '\0') {
3076+
+                       if (ch_is_numeral(*ch_ptr)) {
3077-
+		dc_stuff_boolean(i);
3077+
+                               buffer_str.push_back(*ch_ptr);
3078-
+		return true;
3078+
+                               ch_ptr++;
3079
+
3080-
+		*i = 0;
3080+
+                       } else if (ch_is_decimal(*ch_ptr)) {
3081-
+		return false;
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-
+	dc_ignore_gray_space();
3101+
+                               buffer_str.push_back(*ch_ptr);
3102
+                               ch_ptr++;
3103-
+	if (Cp != '\0') {
3103+
3104-
+		dc_stuff_string_white(str, len);
3104+
+                       } else if (ch_is_exp_prefix(*ch_ptr)) {
3105-
+		return true;
3105+
+                               state = sf_expprefix;
3106
+                               buffer_str.push_back(*ch_ptr);
3107-
+		*str = '\0';
3107+
+                               ch_ptr++;
3108-
+		return false;
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-
+ *   If there's a token on the command line, but we can't fit it inside of str (token.size() >= str.max_size()), then 
3123+
+                               state = sf_expprefix;
3124
+                               buffer_str.push_back(*ch_ptr);
3125
+                               ch_ptr++;
3126
+
3127
+                       } else {
3128-
+	dc_ignore_gray_space();
3128+
+                               if (Dc_debug_on) {
3129
+                                       dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_faction\n", *ch_ptr);
3130-
+	if (Cp != '\0') {
3130+
+                               }
3131-
+		dc_stuff_string_white(str);
3131+
+                               state = sf_invalid;
3132-
+		return true;
3132+
3133
+                       }
3134-
+		str = "";
3134+
+                       break;
3135-
+		return false;
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_int state = si_invalid;
3142+
+                               state = sf_exponent;
3143
+                               buffer_str.push_back(*ch_ptr);
3144-
+	if (ch_is_binary_prefix(*ch_ptr)) {
3144+
+                               ch_ptr++;
3145-
+		state = si_numeral_bin;
3145+
3146-
+		base = 2;
3146+
+                       } else {
3147-
+		ch_ptr++;
3147+
+                               if (Dc_debug_on) {
3148
+                                       dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_expprefix\n", *ch_ptr);
3149-
+	} else if (ch_is_octal_prefix(*ch_ptr)) {
3149+
+                               }
3150-
+		state = si_numeral_octal;
3150+
+                               state = sf_invalid;
3151-
+		base = 8;
3151+
3152-
+		ch_ptr++;
3152+
+                       }
3153
+                       break;
3154-
+	} else if (ch_is_hex_prefix(*ch_ptr)) {
3154+
+               case sf_expsign:
3155-
+		state = si_numeral_hex;
3155+
+                       if (ch_is_numeral(*ch_ptr)) {
3156-
+		base = 16;
3156+
+                               state = sf_exponent;
3157-
+		ch_ptr++;
3157+
+                               buffer_str.push_back(*ch_ptr);
3158
+                               ch_ptr++;
3159-
+	} else if (ch_is_numeral(*ch_ptr)) {
3159+
3160-
+		// User passed something like 0123
3160+
+                       } else {
3161-
+		// Just ignore the first 0, if the user passed something like 00001 then state si_numeral can handle it
3161+
+                               if (Dc_debug_on) {
3162-
+		state = si_numeral;
3162+
+                                       dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_expsign\n", *ch_ptr);
3163-
+		ch_ptr++;
3163+
+                               }
3164
+                               state = sf_invalid;
3165-
+	} else if ((*ch_ptr == '\0') || is_white_space(*ch_ptr)) {
3165+
3166-
+		// Just a 0 was passed.
3166+
+                       }
3167-
+		buffer_str.push_back('0');
3167+
+                       break;
3168-
+		state = si_end;
3168+
+               case sf_exponent:
3169
+                       if (ch_is_numeral(*ch_ptr)) {
3170
+                               buffer_str.push_back(*ch_ptr);
3171-
+		if (Dc_debug_on) {
3171+
+                               ch_ptr++;
3172-
+			dc_printf("<debug> [parse_long] Invalid character '%c' found in si_prefix\n", *ch_ptr);
3172+
3173
+                       } else {
3174-
+		state = si_invalid;
3174+
+                               if (Dc_debug_on) {
3175
+                                       dc_printf("<debug> [parse_double] Invalid character '%c' found in sf_exponent\n", *ch_ptr);
3176
+                               }
3177-
+	return state;
3177+
+                               state = sf_invalid;
3178
+
3179
+                       }
3180
+                       break;
3181
+               case sf_invalid:
3182-
+	state_int state;
3182+
+               default:
3183-
+	if (ch_is_numeral(*ch_ptr)) {
3183+
+                       SCP_string token = dc_get_token_no_advance();
3184-
+		state = si_numeral;
3184+
+                       dc_printf("Syntax Error: Expected integer, found '%s'\n", token.c_str());
3185-
+		buffer_str.push_back(*ch_ptr);
3185+
+                       throw errParse(token.c_str(), type);
3186-
+		ch_ptr++;
3186+
+               }
3187
+       } while (state != sf_end);
3188-
+	} else if (ch_is_prefix(*ch_ptr)) {
3188+
3189-
+		state = si_prefix;
3189+
+       ret = strtod(buffer_str.c_str(), &end_ptr);
3190-
+		ch_ptr++;
3190+
3191
+       return ret;
3192-
+	} else if ((*ch_ptr == '\0') || is_white_space(*ch_ptr)) {
3192+
3193-
+		// Error condition, but let si_end handle it (consistant with how the numerals handle it)
3193+
3194-
+		state = si_end;
3194+
3195
+ * @brief Parses a long integral type. Supports decimal, binary, octal, and hexidecimal strings.
3196
+ *
3197-
+		if (Dc_debug_on) {
3197+
3198-
+			dc_printf("<debug> [parse_long] Invalid character '%c' found in si_sign\n", *ch_ptr);
3198+
3199
+ *
3200-
+		state = si_invalid;
3200+
3201
+ * ! Non-decimal values must be prefixed by their corresponding sequence. Binary: "0b", Octal: "0o", Hex: "0x"
3202
+ *
3203-
+	return state;
3203+
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-
+	state_int state = si_numeral;
3208+
3209
+long dc_parse_long(char *ch, dc_token type) {
3210-
+	if (ch_is_numeral(*ch_ptr)) {
3210+
+       char *ch_ptr = ch;
3211-
+		buffer_str.push_back(*ch_ptr);
3211+
+       char *end_ptr;
3212-
+		ch_ptr++;
3212+
+       int base = 10;
3213
+       long ret;
3214-
+	} else if ((*ch_ptr == '\0') || is_white_space(*ch_ptr)) {
3214+
+       state_int state = si_start;
3215-
+		state = si_end;
3215+
+       SCP_string buffer_str;
3216
+
3217
+       while ((*ch_ptr != '\0') || is_white_space(*ch_ptr)) {
3218-
+		// Invalid character, throw and bail
3218+
+               ch_ptr++;
3219-
+		if (Dc_debug_on) {
3219+
+       }
3220-
+			dc_printf("<debug> [parse_long] Invalid character '%c' found in si_numeral\n", *ch_ptr);
3220+
3221
+       if (*ch_ptr == '\0') {
3222-
+		state = si_invalid;
3222+
+               if (Dc_debug_on) {
3223
+                       dc_printf("<debug> [parse_long] no argument found\n");
3224
+               }
3225-
+	return state;
3225+
+               throw errParse("", type);
3226
+       }
3227
+
3228
+       do {
3229
+               if ((ch_ptr == '\0') || is_white_space(*ch_ptr)) {
3230-
+	state_int state = si_numeral_bin;
3230+
+                       state = si_end;
3231
+               }
3232-
+	if (ch_is_binary(*ch_ptr)) {
3232+
3233-
+		buffer_str.push_back(*ch_ptr);
3233+
+               switch (state) {
3234-
+		ch_ptr++;
3234+
+               case si_start:
3235
+                       if (ch_is_sign(*ch_ptr)) {
3236-
+	} else if ((*ch_ptr == '\0') || is_white_space(*ch_ptr)) {
3236+
+                               state = si_sign;
3237-
+		state = si_end;
3237+
+                               if (*ch_ptr == '-') {
3238
+                                       buffer_str.push_back(*ch_ptr);
3239
+                               } // Else, it's positive. Positive sign isn't needed for conversion
3240-
+		if (Dc_debug_on) {
3240+
+                               ch_ptr++;
3241-
+			dc_printf("<debug> [parse_long] Invalid character '%c' found in si_numeral_bin\n", *ch_ptr);
3241+
3242
+                       } else if (ch_is_prefix(*ch_ptr)) {
3243-
+		state = si_invalid;
3243+
+                               // prefixes must be checked before numeral, because they all start with a numeral zero
3244
+                               state = si_prefix;
3245
+                               ch_ptr++;
3246-
+	return state;
3246+
+              
3247
+                       } else if (ch_is_numeral(*ch_ptr)) {
3248
+                               state = si_numeral;
3249
+                               buffer_str.push_back(*ch_ptr);
3250
+                               ch_ptr++;
3251-
+	state_int state = si_numeral_hex;
3251+
+              
3252
+                       } else {
3253-
+	if (ch_is_hex(*ch_ptr)) {
3253+
+                               if (Dc_debug_on) {
3254-
+		buffer_str.push_back(*ch_ptr);
3254+
+                                       dc_printf("<debug> [parse_long] Invalid character '%c' found in si_start\n", *ch_ptr);
3255-
+		ch_ptr++;
3255+
+                               }
3256
+                               state = si_invalid;
3257-
+	} else if ((*ch_ptr == '\0') || is_white_space(*ch_ptr)) {
3257+
3258-
+		state = si_end;
3258+
+                       }
3259
+                       break;
3260
+               case si_end:
3261-
+		if (Dc_debug_on) {
3261+
+                       if ((buffer_str == "") || (buffer_str == "-"))
3262-
+			dc_printf("<debug> [parse_long] Invalid character '%c' found in si_numeral_hex\n", *ch_ptr);
3262+
+                       {
3263
+                               state = si_invalid;
3264-
+		state = si_invalid;
3264+
+                       } // Else, we can convert the token.
3265
+                       // Do nothing, and allow the while loop exit condition to trigger
3266-
+	return state;
3266+
+                       break;
3267
+
3268
+               case si_sign:
3269
+                       state = process_state_sign(ch_ptr, buffer_str);
3270
+                       break;
3271-
+	state_int state = si_numeral_octal;
3271+
3272
+               case si_prefix:
3273-
+	if (ch_is_octal(*ch_ptr)) {
3273+
+                       state = process_state_prefix(ch_ptr, buffer_str, base);
3274-
+		buffer_str.push_back(*ch_ptr);
3274+
+                       break;
3275-
+		ch_ptr++;
3275+
3276
+               case si_numeral_bin:
3277-
+	} else if ((*ch_ptr == '\0') || is_white_space(*ch_ptr)) {
3277+
+                       state = process_state_numeral_bin(ch_ptr, buffer_str);
3278-
+		state = si_end;
3278+
+                       break;
3279
+
3280
+               case si_numeral_octal:
3281-
+		// Invalid character, throw and bail
3281+
+                       state = process_state_numeral_octal(ch_ptr, buffer_str);
3282-
+		if (Dc_debug_on) {
3282+
+                       break;
3283-
+			dc_printf("<debug> [parse_long] Invalid character '%c' found in si_numeral_octal\n", *ch_ptr);
3283+
3284
+               case si_numeral_hex:
3285-
+		state = si_invalid;
3285+
+                       state = process_state_numeral_hex(ch_ptr, buffer_str);
3286
+                       break;
3287-
+	return state;
3287+
3288
+               case si_numeral:
3289-
Index: code/debugconsole/consoleparse.h
3289+
+                       state = process_state_numeral(ch_ptr, buffer_str);
3290
+                       break;
3291-
index 0000000..9358476
3291+
3292-
--- code/debugconsole/consoleparse.h	(revision 0)
3292+
+               case si_invalid:
3293-
+++ code/debugconsole/consoleparse.h	(working copy)
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-
+	DCT_NONE = 0,
3317+
3318-
+	DCT_STRING,
3318+
3319-
+	DCT_FLOAT,
3319+
3320-
+	DCT_INT,
3320+
3321-
+	DCT_UINT,
3321+
3322-
+	DCT_BYTE,
3322+
3323-
+	DCT_UBYTE,
3323+
3324-
+	DCT_BOOL
3324+
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-
+	SCP_string found_token;
3340+
+       if (*ch_ptr == '\0') {
3341-
+	dc_token expected_type;
3341+
+               if (Dc_debug_on) {
3342
+                       dc_printf("<debug> [parse_long] no argument found\n");
3343
+               }
3344-
+	*  @brief Invalid/Unexpected token constructor
3344+
+               throw errParse("", type);
3345-
+	*  @param [in] found_str The token that was found
3345+
+       }
3346-
+	*  @param [in] expected_dct The token type that was expected
3346+
3347
+       do {
3348-
+	errParse(const char *found_str, dc_token expected_dct)
3348+
+               if ((ch_ptr == '\0') || is_white_space(*ch_ptr)) {
3349-
+		: found_token(found_str), expected_type(expected_dct)
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-
+	SCP_string expected_token1;
3362+
+                               buffer_str.push_back(*ch_ptr);
3363-
+	SCP_string expected_token2;
3363+
+                               ch_ptr++;
3364-
+	SCP_string expected_token3;
3364+
+              
3365-
+	SCP_string expected_token4;
3365+
+                       } else {
3366
+                               if (Dc_debug_on) {
3367-
+	 *  @brief Invalid/Unexpected token constructor.
3367+
+                                       dc_printf("<debug> [parse_long] Invalid character '%s' found in si_start\n", *ch_ptr);
3368-
+	 *  
3368+
+                               }
3369-
+	 *  @param [in] found_str The string that was found
3369+
+                               state = si_invalid;
3370-
+	 *  @param [in] str The token that was expected
3370+
3371
+                       }
3372-
+	errParseString(char *found_str, char *str)
3372+
+                       break;
3373-
+	    : errParse(found_str, DCT_STRING), expected_token1(str)
3373+
+               case si_end:
3374
+                       if (buffer_str == "")
3375
+                       {
3376
+                               state = si_invalid;
3377
+                       } // Else, we can convert the token.
3378-
+	 *  @brief Invalid/Unexpected token constructor.
3378+
+                       // Do nothing, and allow the while loop exit condition to trigger
3379-
+	 *  
3379+
+                       break;
3380-
+	 *  @param [in] found_str The string that was found
3380+
3381-
+	 *  @param [in] str1 The first token that was expected
3381+
+               case si_sign:
3382-
+	 *  @param [in] str2 The second token that was expected
3382+
+                       state = process_state_sign(ch_ptr, buffer_str);
3383
+                       break;
3384-
+	errParseString(char *found_str, char *str1, char *str2)
3384+
3385-
+	    : errParse(found_str, DCT_STRING), expected_token1(str1), expected_token2(str2)
3385+
+               case si_prefix:
3386
+                       state = process_state_prefix(ch_ptr, buffer_str, base);
3387
+                       break;
3388
+
3389
+               case si_numeral_bin:
3390-
+	 *  @brief Invalid/Unexpected token constructor.
3390+
+                       state = process_state_numeral_bin(ch_ptr, buffer_str);
3391-
+	 *  
3391+
+                       break;
3392-
+	 *  @param [in] found_str The string that was found
3392+
3393-
+	 *  @param [in] str1 The first token that was expected
3393+
+               case si_numeral_octal:
3394-
+	 *  @param [in] str2 The second token that was expected
3394+
+                       state = process_state_numeral_octal(ch_ptr, buffer_str);
3395-
+	 *  @param [in] str3 The third token that was expected
3395+
+                       break;
3396
+
3397-
+	errParseString(char *found_str, char *str1, char *str2, char *str3)
3397+
+               case si_numeral_hex:
3398-
+	    : errParse(found_str, DCT_STRING), expected_token1(str1), expected_token2(str2), expected_token3(str3)
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-
+	 *  @brief Invalid/Unexpected token constructor.
3403+
+                       break;
3404-
+	 *  
3404+
3405-
+	 *  @param [in] found_str The string that was found
3405+
+               case si_invalid:
3406-
+	 *  @param [in] str1 The first token that was expected
3406+
+               default:
3407-
+	 *  @param [in] str2 The second token that was expected
3407+
+                       SCP_string token = dc_get_token();
3408-
+	 *  @param [in] str3 The third token that was expected
3408+
+                       dc_printf("Syntax Error: Expected unsigned integer, found '%s'\n", token.c_str());
3409-
+	 *  @param [in] str4 The fourth token that was expected
3409+
+                       throw errParse(token.c_str(), type);
3410
+               }
3411-
+	errParseString(char *found_str, char *str1, char *str2, char *str3, char *str4)
3411+
+       } while (state != si_end);
3412-
+	    : errParse(found_str, DCT_STRING), expected_token1(str1), expected_token2(str2), expected_token3(str3), expected_token4(str4)
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_boolean(int *i);	// Stupid hack to get around plain C's lack of a bool type
3438+
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-
Index: code/freespace2/freespace.cpp
3459+
+       dc_ignore_gray_space();
3460
+
3461-
--- code/freespace2/freespace.cpp	(revision 10462)
3461+
+       value_l = dc_parse_long(Cp, DCT_INT);
3462-
+++ code/freespace2/freespace.cpp	(working copy)
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-
@@ -665,10 +666,9 @@ void big_explosion_flash(float flash)
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-
@@ -1499,80 +1499,101 @@ DCF_BOOL(i_framerate, Interface_framerate )
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-
@@ -1582,42 +1603,56 @@ DCF(show_cpu,"Toggles showing cpu usage")
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-
@@ -1627,14 +1662,26 @@ DCF(low_mem,"Uses low memory settings regardless of RAM")
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-
@@ -1643,37 +1690,33 @@ int	Framerate_delay = 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-
@@ -2399,33 +2442,54 @@ void game_show_time_left()
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-
@@ -2472,22 +2536,28 @@ int View_percent = 100;
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-
@@ -2814,65 +2884,86 @@ void do_timing_test(float frame_time)
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-
@@ -3774,87 +3865,71 @@ void john_debug_stuff(vec3d *eye_pos, matrix *eye_orient)
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-
@@ -6920,7 +6995,7 @@ void game_spew_pof_info()
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-
Index: code/gamehelp/contexthelp.cpp
4212+
4213
+int dc_required_string_3(char *str1, char *str2, char *str3);
4214-
--- code/gamehelp/contexthelp.cpp	(revision 10462)
4214+
4215-
+++ code/gamehelp/contexthelp.cpp	(working copy)
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-
@@ -556,20 +557,14 @@ void help_overlay_blit(int overlay_id)
4224+
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-
@@ -630,150 +625,115 @@ void showplinepos(int plinenum)
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-
@@ -781,46 +741,37 @@ DCF(help_nudgerbracket_y, "Use to visually position overlay right bracket.")
4455+
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-
Index: code/globalincs/pstypes.h
4520+
4521
-		if ( Dc_arg_type & ARG_TRUE )	Use_fullscreen_at_startup = 1;	
4522-
--- code/globalincs/pstypes.h	(revision 10462)
4522+
4523-
+++ code/globalincs/pstypes.h	(working copy)
4523+
4524-
@@ -319,113 +319,6 @@ extern int Fred_running;  // Is Fred running, or FreeSpace?
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-
Index: code/globalincs/systemvars.cpp
4638+
4639
+	if (!dc_maybe_stuff_boolean(&ai_paused)) {
4640-
--- code/globalincs/systemvars.cpp	(revision 10462)
4640+
4641-
+++ code/globalincs/systemvars.cpp	(working copy)
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-
@@ -248,73 +248,76 @@ int Monitor_inited = 0;
4651+
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_printf( "Monitor already on\n" );
4694+
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-
@@ -508,44 +511,41 @@ int current_detail_level()
4781+
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-
 		dc_printf("Detail level set to %d\n", Game_detail_level);
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-
@@ -555,21 +555,38 @@ DCF(detail, "Turns on/off parts of the game for speed testing" )
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-
Index: code/globalincs/vmallocator.h
4904+
4905
-			// Turn it off
4906-
--- code/globalincs/vmallocator.h	(revision 10462)
4906+
4907-
+++ code/globalincs/vmallocator.h	(working copy)
4907+
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-
@@ -127,6 +128,9 @@ class SCP_multimap : public std::multimap<T, U, std::less<T>, SCP_vm_allocator<s
4916+
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-
Index: code/globalincs/windebug.cpp
4926+
4927
 DCF(dump_frames30, "Starts/stop frame dumping at 30 hz")
4928-
--- code/globalincs/windebug.cpp	(revision 10462)
4928+
4929-
+++ code/globalincs/windebug.cpp	(working copy)
4929+
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-
@@ -1522,7 +1523,7 @@ void windebug_memwatch_init()
4938+
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-
Index: code/graphics/2d.cpp
4947+
4948
+		Debug_dump_trigger = 0;
4949-
--- code/graphics/2d.cpp	(revision 10462)
4949+
4950-
+++ code/graphics/2d.cpp	(working copy)
4950+
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-
@@ -266,12 +267,9 @@ DCF(clear_color, "set clear color r, g, b")
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-
Index: code/graphics/gropengl.cpp
4975+
4976
-		}
4977-
--- code/graphics/gropengl.cpp	(revision 10462)
4977+
4978-
+++ code/graphics/gropengl.cpp	(working copy)
4978+
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-
@@ -2078,56 +2079,61 @@ bool gr_opengl_init()
4987+
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("Error: Anisotropic filter is not settable!\n");
5028+
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_printf("Error: Anisotropic filter is not settable!\n");
5047+
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-
Index: code/hud/hudlock.cpp
5076+
5077
-			 h_textnum = Dc_arg_int;		
5078-
--- code/hud/hudlock.cpp	(revision 10462)
5078+
5079-
+++ code/hud/hudlock.cpp	(working copy)
5079+
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-
@@ -333,7 +334,7 @@ int hud_lock_has_homing_point()
5088+
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-
Index: code/io/joy.cpp
5097+
5098
+	dc_stuff_int(&h_textnum);
5099-
--- code/io/joy.cpp	(revision 10462)
5099+
5100-
+++ code/io/joy.cpp	(working copy)
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-
@@ -300,45 +301,51 @@ void joy_get_caps(int max)
5109+
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-
Index: code/lighting/lighting.cpp
5187+
5188
-		if(Dc_arg_type & ARG_INT){
5189-
--- code/lighting/lighting.cpp	(revision 10462)
5189+
5190-
+++ code/lighting/lighting.cpp	(working copy)
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-
@@ -62,52 +63,11 @@ int Lighting_flag = 1;
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-
@@ -117,18 +77,70 @@ DCF(light,"Changes lighting parameters")
5256+
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-
+			dc_printf(" Error: unknown light mode: '%s'\n", arg_str);
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-
Index: code/menuui/playermenu.cpp
5333+
5334
-
5335-
--- code/menuui/playermenu.cpp	(revision 10462)
5335+
5336-
+++ code/menuui/playermenu.cpp	(working copy)
5336+
5337
-	}
5338
-*/
5339
-
5340
-class debug_command {
5341
-	public:
5342
-	char *name;
5343
-	char *help;
5344
-	void (*func)();
5345-
@@ -1236,39 +1237,37 @@ void player_select_cancel_create()
5345+
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-
Index: code/mission/missiongoals.cpp
5409+
5410
-	void dcf_##function_name();	\
5411-
--- code/mission/missiongoals.cpp	(revision 10462)
5411+
5412-
+++ code/mission/missiongoals.cpp	(working copy)
5412+
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-
@@ -1262,77 +1263,101 @@ void mission_goal_mark_events_complete()
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-
Index: code/model/modelinterp.cpp
5579+
5580
-			Game_detail_level = 0;
5581-
--- code/model/modelinterp.cpp	(revision 10462)
5581+
5582-
+++ code/model/modelinterp.cpp	(working copy)
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-
@@ -1942,19 +1943,20 @@ float Interp_depth_scale = 1500.0f;
5591+
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-
 		dc_printf( "model_darkening = %.1f\n", Interp_depth_scale );
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-
@@ -2117,8 +2119,13 @@ float model_find_closest_point( vec3d *outpnt, int model_num, int submodel_num,
5621+
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-
Index: code/nebula/neb.cpp
5636+
5637
-	if ( Dc_help )	{
5638-
--- code/nebula/neb.cpp	(revision 10462)
5638+
5639-
+++ code/nebula/neb.cpp	(working copy)
5639+
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-
@@ -503,7 +504,7 @@ void neb2_page_in()
5648+
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-
@@ -896,12 +897,14 @@ void neb2_regen()
5657+
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-
@@ -1443,7 +1446,7 @@ int neb2_get_bitmap()
5674+
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-
@@ -1463,7 +1466,7 @@ DCF(neb2, "list nebula console commands")
5683+
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-
@@ -1471,95 +1474,91 @@ DCF(neb2, "list nebula console commands")
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-
@@ -1586,39 +1585,32 @@ DCF(neb2_mode, "")
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-
Index: code/nebula/neblightning.cpp
5880+
5881
@@ -333,7 +334,7 @@
5882-
--- code/nebula/neblightning.cpp	(revision 10462)
5882+
5883-
+++ code/nebula/neblightning.cpp	(working copy)
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-
@@ -81,52 +82,43 @@ vec3d Nebl_bolt_strike;			// strike point of the bolt being generated
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-
@@ -144,12 +136,12 @@ DCF(b_list, "")
5964+
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-
Index: code/network/multi.cpp
5982+
--- lighting/lighting.cpp	(Revision 10462)
5983
+++ lighting/lighting.cpp	(Arbeitskopie)
5984-
--- code/network/multi.cpp	(revision 10462)
5984+
5985-
+++ code/network/multi.cpp	(working copy)
5985+
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-
@@ -1105,14 +1106,15 @@ void multi_process_incoming()
5994+
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-
-	eye_tog = !eye_tog;
6001+
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-
+	eye_tog = !eye_tog;
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-
@@ -1772,13 +1774,14 @@ void multi_reset_timestamps()
6016+
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-
Index: code/network/multi_kick.cpp
6036+
6037
-			Dc_help = 1;
6038-
--- code/network/multi_kick.cpp	(revision 10462)
6038+
6039-
+++ code/network/multi_kick.cpp	(working copy)
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-
@@ -137,18 +138,14 @@ int multi_kick_is_banned(net_addr *addr)
6048+
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-
@@ -156,7 +153,7 @@ void multi_dcf_kick()
6070+
6071
+			dc_printf( "Lighting mode is: darken\n" );
6072
+			break;
6073
+		default:
6074
+			dc_printf( "Lighting mode is: UNKNOWN\n" );
6075-
+		dc_printf("Could not find player %s to kick!", arg);
6075+
6076
+		return;
6077
 	}
6078
+	
6079-
Index: code/network/multi_obj.cpp
6079+
6080
+		dc_stuff_float(&val_f);
6081-
--- code/network/multi_obj.cpp	(revision 10462)
6081+
6082-
+++ code/network/multi_obj.cpp	(working copy)
6082+
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-
@@ -1569,10 +1570,21 @@ int OO_server_rate_stamp = -1;
6091+
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-
@@ -1939,10 +1951,21 @@ void multi_oo_interp(object *objp)
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-
@@ -1994,14 +2017,16 @@ void oo_update_time()
6141+
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-
-	display_oo_bez = !display_oo_bez;
6148+
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-
+	display_oo_bez = !display_oo_bez;
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-
Index: code/network/multi_pxo.cpp
6164+
6165
+	}
6166-
--- code/network/multi_pxo.cpp	(revision 10462)
6166+
6167-
+++ code/network/multi_pxo.cpp	(working copy)
6167+
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-
@@ -461,14 +462,15 @@ void multi_pxo_scroll_players_down();
6176+
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-
 	// add a bunch of bogus players
6186+
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-
Index: code/network/multi_voice.cpp
6197+
6198
-	if (Dc_status) {
6199-
--- code/network/multi_voice.cpp	(revision 10462)
6199+
6200-
+++ code/network/multi_voice.cpp	(working copy)
6200+
6201-
@@ -22,7 +22,7 @@
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-
@@ -483,16 +483,17 @@ void multi_voice_process()
6210+
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-
Index: code/network/multilag.cpp
6236+
6237
-			type = Mission_goals[i].type & GOAL_TYPE_MASK;
6238-
--- code/network/multilag.cpp	(revision 10462)
6238+
6239-
+++ code/network/multilag.cpp	(working copy)
6239+
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-
@@ -392,6 +393,7 @@ void multi_lag_put_free(lag_buf *buf)
6248+
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-
@@ -400,183 +402,290 @@ void multi_lagloss_dcf()
6256+
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-
@@ -587,29 +696,46 @@ DCF(lagloss, "")
6654+
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-
@@ -627,7 +753,7 @@ DCF(lag_bad, "")
6709+
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-
@@ -635,6 +761,11 @@ DCF(lag_avg, "")
6718+
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-
@@ -651,7 +782,7 @@ DCF(lag_avg, "")
6730+
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-
@@ -659,6 +790,11 @@ DCF(lag_good, "")
6739+
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-
Index: code/network/multiui.cpp
6751+
6752
 }
6753-
--- code/network/multiui.cpp	(revision 10462)
6753+
6754-
+++ code/network/multiui.cpp	(working copy)
6754+
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-
@@ -754,13 +755,20 @@ int multi_join_maybe_warn();
6763+
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-
@@ -776,7 +784,7 @@ DCF(mj_make, "")
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-
Index: code/network/multiutil.cpp
6796+
6797
+		dc_printf("proper eye stuff is %s\n", eye_tog ? "ON" : "OFF");
6798-
--- code/network/multiutil.cpp	(revision 10462)
6798+
6799-
+++ code/network/multiutil.cpp	(working copy)
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-
@@ -3198,65 +3199,73 @@ short multi_get_new_id()
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-
@@ -3447,19 +3456,20 @@ Done:
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-
Index: code/object/collideshipship.cpp
6964+
6965
 #include "fs2netd/fs2netd_client.h"
6966-
--- code/object/collideshipship.cpp	(revision 10462)
6966+
6967-
+++ code/object/collideshipship.cpp	(working copy)
6967+
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-
Index: code/object/object.cpp
6976+
6977
 {
6978-
--- code/object/object.cpp	(revision 10462)
6978+
6979-
+++ code/object/object.cpp	(working copy)
6979+
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-
Index: code/object/objectsnd.cpp
6988+
6989
 		multi_pxo_add_player(name);
6990-
--- code/object/objectsnd.cpp	(revision 10462)
6990+
6991-
+++ code/object/objectsnd.cpp	(working copy)
6991+
6992-
@@ -22,7 +22,7 @@
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-
@@ -96,62 +96,65 @@ void obj_snd_source_pos(vec3d *sound_pos, obj_snd *osp)
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("Unknown argument '%s'\n", arg);
7109+
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-
Index: code/palman/palman.cpp
7113+
7114
 }
7115-
--- code/palman/palman.cpp	(revision 10462)
7115+
7116-
+++ code/palman/palman.cpp	(working copy)
7116+
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-
@@ -165,17 +166,14 @@ void palette_load_table( const char * filename )
7125+
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-
Index: code/parse/sexp.cpp
7149+
7150
-			dc_printf("Base value greater than max value, ignoring...");
7151-
--- code/parse/sexp.cpp	(revision 10462)
7151+
7152-
+++ code/parse/sexp.cpp	(working copy)
7152+
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-
@@ -24451,40 +24452,38 @@ int run_sexp(const char* sexpression)
7161+
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-
+	sprintf(sexp_always, "( when ( true ) ( %s ) )", sexp);
7191+
7192
-	dc_get_arg(ARG_INT);		
7193
+	if (dc_optional_string_either("help", "--help")) {
7194-
+	dc_printf("SEXP '%s' run, sexp_val = %d\n", sexp_always, sexp_val);
7194+
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-
+	dc_printf("SEXP '%s' run, sexp_val = %d\n", dc_command_str, sexp_val);
7220+
7221
+		Multi_lag_min = -1;
7222
+
7223
+	} else {
7224-
Index: code/particle/particle.cpp
7224+
7225
+	}
7226-
--- code/particle/particle.cpp	(revision 10462)
7226+
7227-
+++ code/particle/particle.cpp	(working copy)
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-
@@ -90,18 +91,7 @@ void particle_page_in()
7236+
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-
Index: code/playerman/playercontrol.cpp
7256+
7257
-			if(Dc_arg_int < 0){
7258-
--- code/playerman/playercontrol.cpp	(revision 10462)
7258+
7259-
+++ code/playerman/playercontrol.cpp	(working copy)
7259+
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-
@@ -286,10 +287,16 @@ void do_view_chase(float frame_time)
7268+
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-
Index: code/radar/radarsetup.cpp
7288+
@@ -497,33 +578,46 @@
7289
 		return;
7290-
--- code/radar/radarsetup.cpp	(revision 10462)
7290+
7291-
+++ code/radar/radarsetup.cpp	(working copy)
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-
@@ -84,7 +85,7 @@ extern int radar_iff_color[5][2][4];
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-
Index: code/render/3dlaser.cpp
7309+
7310
-			// switch the loss sim off
7311-
--- code/render/3dlaser.cpp	(revision 10462)
7311+
7312-
+++ code/render/3dlaser.cpp	(working copy)
7312+
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-
Index: code/ship/ship.cpp
7321+
7322
-			multi_lagloss_dcf();
7323-
--- code/ship/ship.cpp	(revision 10462)
7323+
7324-
+++ code/ship/ship.cpp	(working copy)
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-
@@ -8356,10 +8357,14 @@ int ship_subsys_disrupted(ship *sp, int type)
7333+
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-
@@ -9865,31 +9870,44 @@ float t_len = 10.0f;
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-
@@ -13610,26 +13628,25 @@ void ship_assign_sound_all()
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-
@@ -13637,26 +13654,24 @@ DCF(set_shield,"Change player ship shield strength")
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-
@@ -13665,70 +13680,65 @@ DCF(set_hull, "Change player ship hull strength")
7487+
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-
+		dc_printf("Erro: Unknown argument '%s'\n", arg);
7594+
7595
+	}
7596
 }
7597
 
7598
 void multi_join_notify_new_game()
7599-
+		dc_printf("Subsystem '%s' is at %f strength\n", arg, ship_get_subsystem_strength(Player_ship, subsystem));
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-
@@ -16419,11 +16429,11 @@ int ship_get_texture(int bitmap)
7615+
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-
Index: code/ship/shipfx.cpp
7630+
7631
-			// multi_show_basic_stats(0);
7632-
--- code/ship/shipfx.cpp	(revision 10462)
7632+
7633-
+++ code/ship/shipfx.cpp	(working copy)
7633+
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-
@@ -1355,42 +1356,58 @@ void shipfx_flash_do_frame(float frametime)
7642+
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-
@@ -1602,16 +1619,20 @@ int	Bs_exp_fire_low = 1;
7724+
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-
Index: code/sound/sound.cpp
7753+
7754
-		if(Dc_arg_type & ARG_STRING){
7755-
--- code/sound/sound.cpp	(revision 10462)
7755+
7756-
+++ code/sound/sound.cpp	(working copy)
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-
@@ -200,14 +201,15 @@ void snd_spew_info()
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-
-	Sound_spew = !Sound_spew;
7772+
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-
+	Sound_spew = !Sound_spew;
7782+
7783
 #include "weapon/swarm.h"
7784
 #include "weapon/weapon.h"
7785
+#include "debugconsole/console.h"
7786
 
7787-
Index: code/starfield/nebula.cpp
7787+
7788
 
7789-
--- code/starfield/nebula.cpp	(revision 10462)
7789+
Index: object/objectsnd.cpp
7790-
+++ code/starfield/nebula.cpp	(working copy)
7790+
7791-
@@ -15,7 +15,7 @@
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-
@@ -215,17 +215,19 @@ void nebula_render()
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-
Index: code/starfield/starfield.cpp
7830+
7831
+	
7832-
--- code/starfield/starfield.cpp	(revision 10462)
7832+
7833-
+++ code/starfield/starfield.cpp	(working copy)
7833+
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-
@@ -865,75 +866,11 @@ uint Star_flags = STAR_FLAG_DEFAULT;
7842+
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-
@@ -948,21 +885,105 @@ DCF(stars,"Set parameters for starfield")
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-
+			dc_printf("Error: unknown flag argument '%s'\n", arg);
8026+
8027
 
8028
Index: particle/particle.cpp
8029
===================================================================
8030-
+		dc_printf("Error: Unknown argument '%s'", arg);
8030+
--- particle/particle.cpp	(Revision 10462)
8031
+++ particle/particle.cpp	(Arbeitskopie)
8032
@@ -17,6 +17,7 @@
8033
 #include "object/object.h"
8034-
@@ -1283,39 +1304,44 @@ float Subspace_glow_rate = 1.0f;
8034+
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-
+		dc_printf("Error: Unknown axis '%s'", arg);
8104+
8105
@@ -84,7 +85,7 @@
8106
 
8107
 int See_all = 0;
8108-
Index: code/starfield/supernova.cpp
8108+
8109
-DCF_BOOL(see_all, See_all)
8110-
--- code/starfield/supernova.cpp	(revision 10462)
8110+
8111-
+++ code/starfield/supernova.cpp	(working copy)
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-
@@ -116,11 +117,8 @@ void supernova_stop()
8120+
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-
@@ -181,11 +179,7 @@ void supernova_do_particles()
8134+
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-
@@ -318,17 +312,10 @@ int supernova_camera_cut()
8147+
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-
Index: code/stats/medals.cpp
8168+
8169
+	
8170-
--- code/stats/medals.cpp	(revision 10462)
8170+
8171-
+++ code/stats/medals.cpp	(working copy)
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-
@@ -437,78 +438,17 @@ void parse_medal_tbl()
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-
 		dc_printf ("       [index] --  index of medal to grant\n");
8253+
@@ -13638,26 +13655,24 @@
8254-
 		dc_printf ("       with no parameters, displays the available medals\n");
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-
 		dc_printf("You have the following medals:\n");
8262+
8263
-			dc_printf("Hull set to %.2f\n", Player_obj->hull_strength );
8264-
@@ -518,6 +458,53 @@ DCF(medals, "Grant or revoke medals")
8264+
8265-
 				dc_printf("%d %s\n", Player->stats.medal_counts[i], Medals[i].name);
8265+
8266
-
8267-
 		dc_printf("%s\n", Ranks[Player->stats.rank].name);
8267+
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-
+		{
8302+
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-
Index: code/stats/scoring.cpp
8318+
8319
-			if ( (Dc_arg_float < 0.0f) || (Dc_arg_float > 1.0f) )	{
8320-
--- code/stats/scoring.cpp	(revision 10462)
8320+
8321-
+++ code/stats/scoring.cpp	(working copy)
8321+
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-
@@ -1509,20 +1510,42 @@ void scoring_bash_rank(player *pl,int rank)
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-
Index: code/weapon/beam.cpp
8385+
8386
+	} else if (arg == "sensors") {
8387-
--- code/weapon/beam.cpp	(revision 10462)
8387+
8388-
+++ code/weapon/beam.cpp	(working copy)
8388+
8389-
@@ -35,6 +35,7 @@
8389+
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-
@@ -119,20 +120,22 @@ float b_whack_small = 2000.0f;	// used to be 500.0f with the retail whack bug
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-
@@ -1254,10 +1257,9 @@ void beam_render(beam *b, float u_offset)
8429+
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-
@@ -1479,10 +1481,9 @@ void beam_calc_facing_pts( vec3d *top, vec3d *bot, vec3d *fvec, vec3d *pos, floa
8442+
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-
@@ -3355,12 +3356,11 @@ int beam_will_tool_target(beam *b, object *objp)
8455+
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-
Index: code/weapon/corkscrew.cpp
8471+
8472
+	Particle_width = value;
8473-
--- code/weapon/corkscrew.cpp	(revision 10462)
8473+
8474-
+++ code/weapon/corkscrew.cpp	(working copy)
8474+
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-
@@ -293,41 +294,25 @@ DCF(cscrew, "Listing of corkscrew missile debug console functions")
8483+
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-
@@ -354,11 +339,7 @@ DCF(cscrew_shrink, "Shrink the radius of every other missile")
8529+
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-
Index: code/weapon/emp.cpp
8542+
8543
-		}
8544-
--- code/weapon/emp.cpp	(revision 10462)
8544+
8545-
+++ code/weapon/emp.cpp	(working copy)
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-
@@ -637,13 +638,12 @@ float emp_current_intensity()
8554+
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-
Index: code/weapon/weapons.cpp
8573+
8574
 int Sound_spew = 0;
8575-
--- code/weapon/weapons.cpp	(revision 10462)
8575+
8576-
+++ code/weapon/weapons.cpp	(working copy)
8576+
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-
@@ -6470,75 +6471,137 @@ void weapon_maybe_spew_particle(object *obj)
8585+
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-
Index: projects/MSVC_2011/Freespace2.sln
8763+
8764
+		Num_stars = val_i;
8765-
--- projects/MSVC_2011/Freespace2.sln	(revision 10462)
8765+
8766-
+++ projects/MSVC_2011/Freespace2.sln	(working copy)
8766+
8767-
@@ -1,6 +1,6 @@
8767+
8768-
 ?
8768+
8769-
 Microsoft Visual Studio Solution File, Format Version 12.00
8769+
8770-
-# Visual Studio 2012
8770+
8771-
+# Visual Studio Express 2012 for Windows Desktop
8771+
8772-
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Freespace2", "Freespace2.vcxproj", "{A8030FA3-CEAB-4297-99E3-CD2CFB89830B}"
8772+
8773-
 EndProject
8773+
8774-
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libjpeg", "libjpeg.vcxproj", "{42A241F2-7996-4AAF-8491-FB885E2DC37D}"
8774+
8775-
@@ -143,7 +143,6 @@ Global
8775+
8776-
 		{92C8C611-75AA-4BD7-9B73-584822AAAEB5}.Debug SSE2|Win32.ActiveCfg = Debug SSE2|Win32
8776+
8777-
 		{92C8C611-75AA-4BD7-9B73-584822AAAEB5}.Debug SSE2|Win32.Build.0 = Debug SSE2|Win32
8777+
8778-
 		{92C8C611-75AA-4BD7-9B73-584822AAAEB5}.Debug|Win32.ActiveCfg = Debug|Win32
8778+
8779-
-		{92C8C611-75AA-4BD7-9B73-584822AAAEB5}.Debug|Win32.Build.0 = Debug|Win32
8779+
8780-
 		{92C8C611-75AA-4BD7-9B73-584822AAAEB5}.Release AVX|Win32.ActiveCfg = Release AVX|Win32
8780+
8781-
 		{92C8C611-75AA-4BD7-9B73-584822AAAEB5}.Release AVX|Win32.Build.0 = Release AVX|Win32
8781+
8782-
 		{92C8C611-75AA-4BD7-9B73-584822AAAEB5}.Release SSE|Win32.ActiveCfg = Release SSE|Win32
8782+
8783-
Index: projects/MSVC_2011/code.vcxproj
8783+
8784
+		}
8785-
--- projects/MSVC_2011/code.vcxproj	(revision 10462)
8785+
8786-
+++ projects/MSVC_2011/code.vcxproj	(working copy)
8786+
8787-
@@ -529,6 +529,9 @@
8787+
8788-
     <ClCompile Include="..\..\code\cutscene\oggplayer.cpp" />
8788+
8789-
     <ClCompile Include="..\..\code\Debris\debris.cpp" />
8789+
8790-
     <ClCompile Include="..\..\code\DebugConsole\console.cpp" />
8790+
8791-
+    <ClCompile Include="..\..\code\debugconsole\consolecmds.cpp" />
8791+
8792-
+    <ClCompile Include="..\..\code\debugconsole\consoleparse.cpp" />
8792+
8793-
+    <ClCompile Include="..\..\code\debugconsole\timerbar.cpp" />
8793+
8794-
     <ClCompile Include="..\..\code\fireball\fireballs.cpp" />
8794+
8795-
     <ClCompile Include="..\..\code\fireball\warpineffect.cpp" />
8795+
8796-
     <ClCompile Include="..\..\code\gamehelp\contexthelp.cpp" />
8796+
8797-
@@ -808,6 +811,9 @@
8797+
8798-
     <ClInclude Include="..\..\code\cutscene\mvelib.h" />
8798+
8799-
     <ClInclude Include="..\..\code\cutscene\oggplayer.h" />
8799+
8800-
     <ClInclude Include="..\..\code\Debris\debris.h" />
8800+
8801-
+    <ClInclude Include="..\..\code\debugconsole\console.h" />
8801+
8802-
+    <ClInclude Include="..\..\code\debugconsole\consoleparse.h" />
8802+
8803-
+    <ClInclude Include="..\..\code\debugconsole\timerbar.h" />
8803+
8804-
     <ClInclude Include="..\..\code\DirectX\vasync.h" />
8804+
8805-
     <ClInclude Include="..\..\code\DirectX\vdinput.h" />
8805+
8806-
     <ClInclude Include="..\..\code\DirectX\vdplay.h" />
8806+
8807-
Index: projects/MSVC_2011/code.vcxproj.filters
8807+
8808
+		Star_amount = STAR_AMOUNT_DEFAULT;
8809-
--- projects/MSVC_2011/code.vcxproj.filters	(revision 10462)
8809+
8810-
+++ projects/MSVC_2011/code.vcxproj.filters	(working copy)
8810+
8811-
@@ -1056,6 +1056,15 @@
8811+
8812-
     <ClCompile Include="..\..\code\globalincs\profiling.cpp">
8812+
8813-
       <Filter>GlobalIncs</Filter>
8813+
8814-
     </ClCompile>
8814+
8815-
+    <ClCompile Include="..\..\code\debugconsole\consolecmds.cpp">
8815+
8816-
+      <Filter>DebugConsole</Filter>
8816+
8817-
+    </ClCompile>
8817+
8818-
+    <ClCompile Include="..\..\code\debugconsole\consoleparse.cpp">
8818+
8819-
+      <Filter>DebugConsole</Filter>
8819+
8820-
+    </ClCompile>
8820+
8821-
+    <ClCompile Include="..\..\code\debugconsole\timerbar.cpp">
8821+
8822-
+      <Filter>DebugConsole</Filter>
8822+
8823-
+    </ClCompile>
8823+
8824-
   </ItemGroup>
8824+
8825-
   <ItemGroup>
8825+
8826-
     <ClInclude Include="..\..\code\ai\ai.h">
8826+
8827-
@@ -1856,6 +1865,15 @@
8827+
8828-
     <ClInclude Include="..\..\code\PilotFile\pilotfile.h">
8828+
8829-
       <Filter>PilotFile</Filter>
8829+
8830-
     </ClInclude>
8830+
8831-
+    <ClInclude Include="..\..\code\debugconsole\console.h">
8831+
8832-
+      <Filter>DebugConsole</Filter>
8832+
8833-
+    </ClInclude>
8833+
8834-
+    <ClInclude Include="..\..\code\debugconsole\consoleparse.h">
8834+
+			dc_printf("Error: unknown flag argument '%s'\n", arg.c_str());
8835-
+      <Filter>DebugConsole</Filter>
8835+
8836-
+    </ClInclude>
8836+
8837-
+    <ClInclude Include="..\..\code\debugconsole\timerbar.h">
8837+
8838-
+      <Filter>DebugConsole</Filter>
8838+
+		dc_printf("Error: Unknown argument '%s'", arg.c_str());
8839-
+    </ClInclude>
8839+
8840-
   </ItemGroup>
8840+
8841-
   <ItemGroup>
8841+
8842-
     <Library Include="..\..\code\directx\dxguid.lib">
8842+
8843
@@ -1284,40 +1305,45 @@
8844-
8844+
8845-
/* EOF - IGNORE *\
8845+
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