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