]> icculus.org git repositories - taylor/freespace2.git/blob - src/globalincs/systemvars.cpp
added copyright header
[taylor/freespace2.git] / src / globalincs / systemvars.cpp
1 /*
2  * Copyright (C) Volition, Inc. 1999.  All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell 
5  * or otherwise commercially exploit the source or things you created based on
6  * the source.
7  */
8
9 /*
10  * $Logfile: /Freespace2/code/GlobalIncs/SystemVars.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  * Variables and constants common to FreeSpace and Fred.
16  *
17  * $Log$
18  * Revision 1.3  2002/06/09 04:41:17  relnev
19  * added copyright header
20  *
21  * Revision 1.2  2002/05/07 03:16:45  theoddone33
22  * The Great Newline Fix
23  *
24  * Revision 1.1.1.1  2002/05/03 03:28:09  root
25  * Initial import.
26  *
27  * 
28  * 12    9/09/99 8:53p Dave
29  * Fixed multiplayer degenerate orientation case problem. Make sure warp
30  * effect never goes lower than LOD 1. 
31  * 
32  * 11    9/06/99 11:25a Mikek
33  * Decrease some settings for High detail level.
34  * 
35  * 10    8/05/99 2:05a Dave
36  * Whee.
37  * 
38  * 9     7/29/99 10:47p Dave
39  * Standardized D3D fogging using vertex fog. Shook out Savage 4 bugs.
40  * 
41  * 8     7/29/99 12:05a Dave
42  * Nebula speed optimizations.
43  * 
44  * 7     6/22/99 7:03p Dave
45  * New detail options screen.
46  * 
47  * 6     6/16/99 4:06p Dave
48  * New pilot info popup. Added new draw-bitmap-as-poly function.
49  * 
50  * 5     5/24/99 5:45p Dave
51  * Added detail levels to the nebula, with a decent speedup. Split nebula
52  * lightning into its own section.
53  * 
54  * 4     11/30/98 1:07p Dave
55  * 16 bit conversion, first run.
56  * 
57  * 3     10/07/98 6:27p Dave
58  * Globalized mission and campaign file extensions. Removed Silent Threat
59  * special code. Moved \cache \players and \multidata into the \data
60  * directory.
61  * 
62  * 2     10/07/98 10:52a Dave
63  * Initial checkin.
64  * 
65  * 1     10/07/98 10:48a Dave
66  * 
67  * 38    9/21/98 8:46p Dave
68  * Put in special check in fred for identifying unknown ships.
69  * 
70  * 37    8/17/98 5:07p Dave
71  * First rev of corkscrewing missiles.
72  * 
73  * 36    5/13/98 11:34p Mike
74  * Model caching system.
75  * 
76  * 35    4/25/98 4:06p John
77  * Made defaults make a little more sense
78  * 
79  * 34    4/20/98 8:41p John
80  * Made debris culling actually reduce Glide texture resolution.
81  * 
82  * 33    4/12/98 9:56a John
83  * Made lighting detail flags work.   Made explosions cast light on
84  * highest.
85  * 
86  * 32    4/08/98 8:34p Lawrance
87  * Fix up how custom button works on the detail tab.
88  * 
89  * 31    4/01/98 5:34p John
90  * Made only the used POFs page in for a level.   Reduced some interp
91  * arrays.    Made custom detail level work differently.
92  * 
93  * 30    3/31/98 5:18p John
94  * Removed demo/save/restore.  Made NDEBUG defined compile.  Removed a
95  * bunch of debug stuff out of player file.  Made model code be able to
96  * unload models and malloc out only however many models are needed.
97  *  
98  * 
99  * 29    3/30/98 2:38p Mike
100  * Add asteroid_density to detail level support.
101  * No force explosion damage in training missions.
102  * Make cargo deathrolls shorter.
103  * 
104  * 28    3/24/98 8:16a John
105  * made highest detail different than next one down
106  * 
107  * 27    3/23/98 5:19p John
108  * Upped number of default detail levels to 4
109  * 
110  * 26    3/22/98 4:11p Andsager
111  * Remove global Freespace_running
112  * 
113  * 25    3/22/98 3:28p John
114  * Added in stippled alpha for lower details.  Made medium detail use
115  * engine glow.
116  * 
117  * 24    3/22/98 2:41p John
118  * Added lighting into the detail structure.
119  * 
120  * 23    3/22/98 11:06a John
121  * Changed default detail levels
122  * 
123  * 22    3/22/98 11:02a John
124  * Made a bunch of the detail levels actually do something
125  * 
126  * 21    3/22/98 9:53a John
127  * Added in first stage of new detail level stuff
128  * 
129  * 20    3/09/98 12:13a Andsager
130  * Add code to help find jumps in position.
131  * 
132  * 19    2/28/98 7:03p Lawrance
133  * get slew working in any view
134  * 
135  * 18    2/16/98 4:16p John
136  * Added loading animation
137  * 
138  * 17    2/10/98 9:06a John
139  * Added variables for restoring
140  * 
141  * 16    2/05/98 9:27p John
142  * took out ending min/max etc on monitor
143  * 
144  * 15    2/05/98 9:21p John
145  * Some new Direct3D code.   Added code to monitor a ton of stuff in the
146  * game.
147  * 
148  * 14    2/03/98 9:25p John
149  * Upgraded Direct3D code to new version 5.0 code.  Separated the D3D code
150  * more.  Added a global variable D3D_enabled flag.
151  * 
152  * 13    1/17/98 12:17p John
153  * fixed erroneous print
154  * 
155  * 12    1/17/98 12:14p John
156  * Added loading... bar to freespace.
157  * 
158  * 11    1/11/98 2:15p John
159  * Changed a lot of stuff that had to do with bitmap loading.   Made cfile
160  * not do callbacks, I put that in global code.   Made only bitmaps that
161  * need to load for a level load.
162  * 
163  * 10    12/16/97 6:20p Hoffoss
164  * Added more debugging code for demos, and fixed a bug in demo
165  * recording/playback.
166  * 
167  * 9     12/05/97 3:46p John
168  * made ship thruster glow scale instead of being an animation.
169  * 
170  * 8     8/05/97 10:18a Lawrance
171  * my_rand() being used temporarily instead of rand()
172  * 
173  * 7     8/04/97 10:21a Dave
174  * Added Is_standalone global var
175  * 
176  * 6     6/24/97 6:21p John
177  * added detail flags.
178  * sped up motion debris system a bit.
179  * 
180  * 5     4/15/97 11:28p Mike
181  * External view system
182  * 
183  * 4     4/15/97 4:00p Mike
184  * Intermediate checkin caused by getting other files.  Working on camera
185  * slewing system.
186  * 
187  * 3     4/08/97 8:47a John
188  * Added a global varible for detail level
189  * 
190  * 2     4/01/97 11:07p Mike
191  * Clean up game sequencing functions.  Get rid of Multiplayer and add
192  * Game_mode.  Add SystemVars.cpp
193  * 
194  * 1     4/01/97 10:59p Mike
195  *
196  * $NoKeywords: $
197  */
198
199 #include "pstypes.h"
200 #include "systemvars.h"
201 #include "timer.h"
202 #include "neb.h"
203
204 fix Missiontime;
205 fix Frametime;
206 int     Framecount=0;
207
208 int Game_mode;
209
210 int Game_restoring = 0;         // If set, this means we are restoring data from disk
211
212 int     Viewer_mode;            //      Viewer's mode, see VM_xxxx flags.
213
214 // The detail level.  Anything below zero draws simple models earlier than it
215 // should.   Anything above zero draws higher detail models longer than it should.
216 // -2=lowest
217 // -1=low
218 // 0=normal (medium)    
219 // 1=high
220 // 2=extra high
221 int Game_detail_level = 0;
222 uint Game_detail_flags = DETAIL_DEFAULT;        // see systemvars.h for explanation
223
224 angles  Viewer_slew_angles;                     //      Angles of viewer relative to forward.
225 vei             Viewer_external_info;           //      Viewer angles to ship in external view.
226 vci             Viewer_chase_info;                      // View chase camera information
227
228 int Is_standalone;
229 int Rand_count;
230
231 int Interface_last_tick = -1;                   // last timer tick on flip
232
233 // for notifying players of unknown ship types
234 int Fred_found_unknown_ship_during_parsing = 0;
235
236 // If true, then we are using Direct3D hardware.  This is used for game type stuff
237 // that changes when you're using hardware.
238 int D3D_enabled = 0;                    
239
240 // Values used for noise for thruster animations
241 float Noise[NOISE_NUM_FRAMES] = { 
242         0.468225f,
243         0.168765f,
244         0.318945f,
245         0.292866f,
246         0.553357f,
247         0.468225f,
248         0.180456f,
249         0.418465f,
250         0.489958f,
251         1.000000f,
252         0.468225f,
253         0.599820f,
254         0.664718f,
255         0.294215f,
256         0.000000f
257 };
258
259
260 int myrand()
261 {
262         int rval;
263         rval = rand();
264         Rand_count++;
265 //      nprintf(("Alan","RAND: %d\n", rval));
266         return rval;
267 }
268
269
270 // Variables for the loading callback hooks
271 static int cf_timestamp = -1;
272 static void (*cf_callback)(int count) = NULL;
273 static int cf_in_callback = 0;  
274 static int cb_counter = 0;
275 static int cb_last_counter = 0;
276 static int cb_delta_step = -1;
277
278 // Call this with the name of a function.  That function will
279 // then get called around 10x per second.  The callback function
280 // gets passed a 'count' which is how many times game_busy has
281 // been called since the callback was set.   It gets called
282 // one last time with count=-1 when you turn off the callback
283 // by calling game_busy_callback(NULL).   Game_busy_callback
284 // returns the current count, so you can tell how many times
285 // game_busy got called.
286 int game_busy_callback( void (*callback)(int count), int delta_step )
287 {
288         if ( !callback ) {
289
290                 // Call it once more to finalize things
291                 cf_in_callback++;
292                 (*cf_callback)(-1);
293                 cf_in_callback--;
294
295                 cf_timestamp = -1;
296                 cf_callback = NULL;
297         } else {
298                 cb_counter = 0;
299                 cb_last_counter = 0;
300                 cb_delta_step = delta_step;
301                 cf_timestamp = timer_get_milliseconds()+(1000/10);
302                 cf_callback = callback;
303
304                 // Call it once
305                 cf_in_callback++;
306                 (*cf_callback)(0);              // pass 0 first time!
307                 cf_in_callback--;
308         
309         }
310
311         return cb_counter;
312 }
313
314 // Call whenever loading to display cursor
315 void game_busy()
316 {
317         if ( cf_in_callback != 0 ) return;      // don't call callback if we're already in it.
318         if ( cf_timestamp < 0 ) return;
319         if ( !cf_callback ) return;
320
321         cb_counter++;
322
323 //      mprintf(( "CB_COUNTER=%d\n", cb_counter ));
324
325         int t1 = timer_get_milliseconds();
326
327         if ( (t1 > cf_timestamp) || ((cb_counter>cb_last_counter+155)&&(cb_delta_step>0)) )     {
328                 cb_last_counter = cb_counter;
329                 cf_in_callback++;
330                 (*cf_callback)(cb_counter);
331                 cf_in_callback--;
332                 cf_timestamp = t1 + +(1000/10);
333         }
334 }
335
336 //======================== CODE TO MONITOR EVENTS ======================
337
338 #ifndef NDEBUG
339
340 #define MAX_MONITORS 64
341
342 static int Num_monitors = 0;
343 static monitor *Monitor[MAX_MONITORS];
344
345 monitor::monitor( char *_name )
346 {
347         int i;
348
349         if ( Num_monitors >= MAX_MONITORS )     {
350                 Int3();                 // Too many monitor variables!! Increase MAX_MONITORS!!
351                 return;
352         }
353
354         for (i=0; i<Num_monitors; i++ ) {
355                 int ret  = stricmp( Monitor[i]->name, _name );
356
357                 if ( ret == 0)  {
358                         Int3();         // This monitor variable already exists!!!! 
359                         return;
360                 } else if ( ret > 0 )   {
361                         break;          // Insert it here
362
363                 } else if ( ret < 0 )   {
364                         // do nothing
365                 }
366         }
367
368         if ( i < Num_monitors ) {
369                 // Insert it at element i
370                 int j;
371                 for (j=Num_monitors; j>i; j-- ) {
372                         Monitor[j] = Monitor[j-1];
373                 }
374                 Monitor[i] = this;              
375                 Num_monitors++;
376         } else {
377                 Monitor[Num_monitors] = this;           
378                 Num_monitors++;
379         }
380
381         name = _name;
382         value = 0;
383 }
384
385
386 int Monitor_inited = 0;
387 char Monitor_filename[128];
388 fix monitor_last_time = -1;
389
390 DCF(monitor,"Monitors game performace")
391 {
392         if ( Dc_command )       {
393                 dc_get_arg(ARG_STRING|ARG_NONE);
394                 if ( Dc_arg_type == ARG_NONE )  {
395                         if ( Monitor_inited )   {
396                                 Monitor_inited = 0;
397
398 /*
399                                 FILE *fp = fopen( Monitor_filename, "at" );
400                                 if ( fp )       {
401                                         fprintf( fp, "\n\n" );
402                                         fprintf( fp, "Name\tMin\tMax\tAvg\n" );
403                                         for (int i=0; i<Num_monitors; i++ )     {
404                                                 if ( Monitor[i]->cnt > 0 )      {
405                                                         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  );
406                                                 } else {
407                                                         fprintf( fp, "%s\t%d\t%d\t?\n", Monitor[i]->name, Monitor[i]->min, Monitor[i]->max );
408                                                 }
409                                         }
410                                         fclose(fp);
411                                 }
412 */
413
414                                 dc_printf( "Monitor to file '%s' turned off\n", Monitor_filename );
415                         } else {
416                                 dc_printf( "Monitor isn't on\n" );
417                         }
418                 } else {
419                         if ( Monitor_inited )   {
420                                 dc_printf( "Monitor already on\n" );
421                         } else {
422                                 Monitor_inited = 1;
423
424                                 strcpy( Monitor_filename, Dc_arg );
425
426                                 // Reset them all
427                                 int i;
428                                 for (i=0; i<Num_monitors; i++ ) {
429                                         Monitor[i]->value = 0;
430                                         Monitor[i]->sum = 0;
431                                         Monitor[i]->cnt = 0;
432                                         Monitor[i]->min = 0;
433                                         Monitor[i]->max = 0;
434                                 }
435
436                                 FILE *fp = fopen( Monitor_filename, "wt" );
437                                 if ( fp )       {
438                                         for (i=0; i<Num_monitors; i++ ) {
439                                                 if ( i > 0 )    {
440                                                         fprintf( fp, "\t" );
441                                                 }
442                                                 fprintf( fp, "%s", Monitor[i]->name );
443                                         
444                                         }
445                                         fprintf( fp, "\n" );
446                                         fclose(fp);
447                                 }
448                                 dc_printf( "Monitor outputting to file '%s'\n", Monitor_filename );
449                                 monitor_last_time = -1;
450                         }
451                 }
452         }
453         if ( Dc_help )  {
454                 dc_printf( "Usage: monitor filename\nOutputs monitoring info to filename. No filename turns it off\n" );
455         }
456         
457 }
458
459
460 MONITOR(FrameRateX100);
461
462 void monitor_update()
463 {
464         int i;
465         FILE * fp;
466
467         fix this_time = timer_get_fixed_seconds();
468         fix frametime;
469
470         if ( monitor_last_time != -1 )  {
471                 frametime = this_time - monitor_last_time;
472         } else {
473                 frametime = 0;
474         }
475
476         if ( frametime > 0 )    {
477                 MONITOR_INC(FrameRateX100, (F1_0*100) / frametime );
478         } else {
479                 MONITOR_INC(FrameRateX100, 0 );
480         }
481
482                 
483         if ( !Monitor_inited )  {
484                 return;
485         }
486
487         if ( frametime != 0 )   {
488                 fp = fopen( Monitor_filename, "at" );
489                 if ( fp )       {
490
491                         for (i=0; i<Num_monitors; i++ ) {
492                                 if (i>0) fprintf( fp, "\t" );
493                                 fprintf( fp, "%d", Monitor[i]->value );
494                         }
495                         fprintf( fp, "\n" );
496                         fclose(fp);
497                 }
498
499                 for (i=0; i<Num_monitors; i++ ) {
500
501                         // Record stats
502                         Monitor[i]->sum += Monitor[i]->value;
503
504                         if ( (Monitor[i]->cnt < 1)  || (Monitor[i]->value < Monitor[i]->min ))  {
505                                 Monitor[i]->min = Monitor[i]->value;
506                         }
507
508                         if ( (Monitor[i]->cnt < 1)  || (Monitor[i]->value > Monitor[i]->max ))  {
509                                 Monitor[i]->max = Monitor[i]->value;
510                         }
511
512                         Monitor[i]->cnt++;
513
514                         //      Reset the value
515                         Monitor[i]->value = 0;
516                 }
517         } else {
518                 for (i=0; i<Num_monitors; i++ ) {
519                         //      Reset the value
520                         Monitor[i]->value = 0;
521                 }
522         }
523
524         monitor_last_time = timer_get_fixed_seconds();
525
526 }
527 #endif  //NDEBUG
528
529
530 #if MAX_DETAIL_LEVEL != 4
531 #error MAX_DETAIL_LEVEL is assumed to be 4 in SystemVars.cpp
532 #endif
533
534 #if NUM_DEFAULT_DETAIL_LEVELS != 4
535 #error NUM_DEFAULT_DETAIL_LEVELS is assumed to be 4 in SystemVars.cpp
536 #endif
537
538 // Detail level stuff
539 detail_levels Detail_defaults[NUM_DEFAULT_DETAIL_LEVELS] = {
540         {                               // Low
541                 0,                      // setting
542                                         // ===== Analogs (0-MAX_DETAIL_LEVEL) ====
543                 0,                      // nebula_detail;                               // 0=lowest detail, MAX_DETAIL_LEVEL=highest detail
544                 0,                      // detail_distance;                     // 0=lowest MAX_DETAIL_LEVEL=highest            
545                 0,                      //      hardware_textures;                      // 0=max culling, MAX_DETAIL_LEVEL=no culling
546                 0,                      //      num_small_debris;                       // 0=min number, MAX_DETAIL_LEVEL=max number
547                 0,                      //      num_particles;                          // 0=min number, MAX_DETAIL_LEVEL=max number
548                 0,                      //      num_stars;                                      // 0=min number, MAX_DETAIL_LEVEL=max number
549                 0,                      //      shield_effects;                 // 0=min, MAX_DETAIL_LEVEL=max
550                 2,                      // lighting;                                    // 0=min, MAX_DETAIL_LEVEL=max          
551
552                                         // ====  Booleans ====
553                 0,                      //      targetview_model;                       // 0=off, 1=on          
554                 0,                      //      planets_suns;                           // 0=off, 1=on          
555                 0,                      // weapon_extras
556         },
557         {                               // Medium
558                 1,                      // setting
559                                         // ===== Analogs (0-MAX_DETAIL_LEVEL) ====
560                 1,                      // nebula_detail;                               // 0=lowest detail, MAX_DETAIL_LEVEL=highest detail
561                 1,                      // detail_distance;                     // 0=lowest MAX_DETAIL_LEVEL=highest            
562                 1,                      //      hardware_textures;                      // 0=max culling, MAX_DETAIL_LEVEL=no culling
563                 2,                      //      num_small_debris;                       // 0=min number, MAX_DETAIL_LEVEL=max number
564                 2,                      //      num_particles;                          // 0=min number, MAX_DETAIL_LEVEL=max number
565                 2,                      //      num_stars;                                      // 0=min number, MAX_DETAIL_LEVEL=max number
566                 1,                      //      shield_effects;                 // 0=min, MAX_DETAIL_LEVEL=max
567                 3,                      // lighting;                                    // 0=min, MAX_DETAIL_LEVEL=max          
568
569                 // ====  Booleans ====
570                 1,                      //      targetview_model;                       // 0=off, 1=on          
571                 1,                      //      planets_suns;                           // 0=off, 1=on
572                 1,                      // weapon extras                                
573         },
574         {                               // High level
575                 2,                      // setting
576                                         // ===== Analogs (0-MAX_DETAIL_LEVEL) ====
577                 2,                      // nebula_detail;                               // 0=lowest detail, MAX_DETAIL_LEVEL=highest detail
578                 3,                      // detail_distance;                     // 0=lowest MAX_DETAIL_LEVEL=highest            
579                 3,                      //      hardware_textures;                      // 0=max culling, MAX_DETAIL_LEVEL=no culling
580                 3,                      //      num_small_debris;                       // 0=min number, MAX_DETAIL_LEVEL=max number
581                 3,                      //      num_particles;                          // 0=min number, MAX_DETAIL_LEVEL=max number
582                 4,                      //      num_stars;                                      // 0=min number, MAX_DETAIL_LEVEL=max number
583                 3,                      //      shield_effects;                 // 0=min, MAX_DETAIL_LEVEL=max
584                 4,                      // lighting;                                    // 0=min, MAX_DETAIL_LEVEL=max          
585
586                                                                                 // ====  Booleans ====
587                 1,                      //      targetview_model;                       // 0=off, 1=on          
588                 1,                      //      planets_suns;                           // 0=off, 1=on
589                 1,                      // weapon_extras
590         },
591         {                               // Highest level
592                 3,                      // setting
593                                         // ===== Analogs (0-MAX_DETAIL_LEVEL) ====
594                 3,                      // nebula_detail;                               // 0=lowest detail, MAX_DETAIL_LEVEL=highest detail
595                 3,                      // detail_distance;                     // 0=lowest MAX_DETAIL_LEVEL=highest            
596                 4,                      //      hardware_textures;                      // 0=max culling, MAX_DETAIL_LEVEL=no culling
597                 4,                      //      num_small_debris;                       // 0=min number, MAX_DETAIL_LEVEL=max number
598                 3,                      //      num_particles;                          // 0=min number, MAX_DETAIL_LEVEL=max number
599                 4,                      //      num_stars;                                      // 0=min number, MAX_DETAIL_LEVEL=max number
600                 4,                      //      shield_effects;                 // 0=min, MAX_DETAIL_LEVEL=max
601                 4,                      // lighting;                                    // 0=min, MAX_DETAIL_LEVEL=max          
602
603                                                                                 // ====  Booleans ====
604                 1,                      //      targetview_model;                       // 0=off, 1=on          
605                 1,                      //      planets_suns;                           // 0=off, 1=on
606                 1,                      // weapon_extras
607         },
608 };
609
610
611 // Global used to access detail levels in game and libs
612 detail_levels Detail = Detail_defaults[NUM_DEFAULT_DETAIL_LEVELS-1];
613
614 // Call this with:
615 // 0 - lowest
616 // NUM_DETAIL_LEVELS - highest
617 // To set the parameters in Detail to some set of defaults
618 void detail_level_set(int level)
619 {
620         if ( level < 0 )        {
621                 Detail.setting = -1;
622                 return;
623         }
624         Assert( level >= 0 );
625         Assert( level < NUM_DEFAULT_DETAIL_LEVELS );
626
627         Detail = Detail_defaults[level];
628
629         // reset nebula stuff
630         neb2_set_detail_level(level);
631 }
632
633 // Returns the current detail level or -1 if custom.
634 int current_detail_level()
635 {
636 //      return Detail.setting;
637         int i;
638
639         for (i=0; i<NUM_DEFAULT_DETAIL_LEVELS; i++ )    {
640                 if ( memcmp( &Detail, &Detail_defaults[i], sizeof(detail_levels) )==0 ) {
641                         return i;
642                 }
643         }
644         return -1;
645 }
646
647 #ifndef NDEBUG
648 DCF(detail_level,"Change the detail level")
649 {
650         if ( Dc_command )       {
651                 dc_get_arg(ARG_INT|ARG_NONE);
652                 if ( Dc_arg_type & ARG_NONE )   {
653                         Game_detail_level = 0;
654                         dc_printf( "Detail level reset\n" );
655                 }
656                 if ( Dc_arg_type & ARG_INT )    {
657                         Game_detail_level = Dc_arg_int;
658                 }
659         }
660
661         if ( Dc_help )  
662                 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" );
663
664         if ( Dc_status )                                
665                 dc_printf("Detail level set to %d\n", Game_detail_level);
666 }
667
668 DCF(detail, "Turns on/off parts of the game for speed testing" )
669 {
670         if ( Dc_command )       {
671                 dc_get_arg(ARG_INT|ARG_NONE);
672                 if ( Dc_arg_type & ARG_NONE )   {
673                         if ( Game_detail_flags == DETAIL_DEFAULT )      {
674                                 Game_detail_flags = DETAIL_FLAG_CLEAR;
675                                 dc_printf( "Detail flags set lowest (except has screen clear)\n" );
676                         } else {
677                                 Game_detail_flags = DETAIL_DEFAULT;
678                                 dc_printf( "Detail flags set highest\n" );
679                         }
680                 }
681                 if ( Dc_arg_type & ARG_INT )    {
682                         Game_detail_flags ^= Dc_arg_int;
683                 }
684         }
685
686         if ( Dc_help )  {
687                 dc_printf( "Usage: detail [n]\nn is detail bit to toggle.\n" );
688                 dc_printf( "   1: draw the stars\n" );
689                 dc_printf( "   2: draw the nebulas\n" );
690                 dc_printf( "   4: draw the motion debris\n" );
691                 dc_printf( "   8: draw planets\n" );
692                 dc_printf( "  16: draw models not as blobs\n" );
693                 dc_printf( "  32: draw lasers not as pixels\n" );
694                 dc_printf( "  64: clear screen background after each frame\n" );
695                 dc_printf( " 128: draw hud stuff\n" );
696                 dc_printf( " 256: draw fireballs\n" );
697                 dc_printf( " 512: do collision detection\n" );
698         }
699
700         if ( Dc_status )        {
701                 dc_printf("Detail flags set to 0x%08x\n", Game_detail_flags);
702                 dc_printf( "   1: draw the stars: %s\n", (Game_detail_flags&1?"on":"off") );
703                 dc_printf( "   2: draw the nebulas: %s\n", (Game_detail_flags&2?"on":"off") );
704                 dc_printf( "   4: draw the motion debris: %s\n", (Game_detail_flags&4?"on":"off")  );
705                 dc_printf( "   8: draw planets: %s\n", (Game_detail_flags&8?"on":"off")  );
706                 dc_printf( "  16: draw models not as blobs: %s\n", (Game_detail_flags&16?"on":"off")  );
707                 dc_printf( "  32: draw lasers not as pixels: %s\n", (Game_detail_flags&32?"on":"off")  );
708                 dc_printf( "  64: clear screen background after each frame: %s\n", (Game_detail_flags&64?"on":"off")  );
709                 dc_printf( " 128: draw hud stuff: %s\n", (Game_detail_flags&128?"on":"off")  );
710                 dc_printf( " 256: draw fireballs: %s\n", (Game_detail_flags&256?"on":"off")  );
711                 dc_printf( " 512: do collision detection: %s\n", (Game_detail_flags&512?"on":"off")  );
712         }
713 }
714 #endif