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