]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake2/q2map/main.c
transfer from internal tree r5311 branches/1.4-gpl
[xonotic/netradiant.git] / tools / quake2 / q2map / main.c
1 /*\r
2 Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
3 For a list of contributors, see the accompanying CONTRIBUTORS file.\r
4 \r
5 This file is part of GtkRadiant.\r
6 \r
7 GtkRadiant is free software; you can redistribute it and/or modify\r
8 it under the terms of the GNU General Public License as published by\r
9 the Free Software Foundation; either version 2 of the License, or\r
10 (at your option) any later version.\r
11 \r
12 GtkRadiant is distributed in the hope that it will be useful,\r
13 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15 GNU General Public License for more details.\r
16 \r
17 You should have received a copy of the GNU General Public License\r
18 along with GtkRadiant; if not, write to the Free Software\r
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
20 */\r
21 \r
22 \r
23 /* marker */\r
24 #define MAIN_C\r
25 \r
26 \r
27 \r
28 /* dependencies */\r
29 #include "q2map.h"\r
30 \r
31 #define qtrue true\r
32 #define qfalse false\r
33 \r
34 char    *mapname;\r
35 char    game[64];\r
36 extern  qboolean        verbose;\r
37 \r
38 /// BSP \r
39 extern  qboolean        drawflag;\r
40 extern  qboolean        noprune;\r
41 extern  qboolean        glview;\r
42 extern  qboolean        nodetail;\r
43 extern  qboolean        fulldetail;\r
44 extern  qboolean        onlyents;\r
45 extern  qboolean        nomerge;\r
46 extern  qboolean        nowater;\r
47 extern  qboolean        nofill;\r
48 extern  qboolean        nocsg;\r
49 extern  qboolean        noweld;\r
50 extern  qboolean        noshare;\r
51 extern  qboolean        nosubdiv;\r
52 extern  qboolean        notjunc;\r
53 extern  qboolean        noopt;\r
54 extern  qboolean        leaktest;\r
55 extern  qboolean        verboseentities;\r
56 extern  char            outbase[32];\r
57 extern  int             block_xl, block_xh, block_yl, block_yh;\r
58 extern  vec_t           microvolume;\r
59 extern  float           subdivide_size;\r
60 \r
61 // VIS\r
62 extern  char            inbase[32];\r
63 extern  qboolean        fastvis;\r
64 extern  qboolean        nosort;\r
65 extern  int             testlevel;\r
66 \r
67 // RAD\r
68 extern  qboolean        dumppatches;\r
69 extern  int             numbounce;\r
70 extern  qboolean        extrasamples;\r
71 extern  float           subdiv;\r
72 extern  float           lightscale;\r
73 extern  float           direct_scale;\r
74 extern  float           entity_scale;\r
75 extern  qboolean        nopvs;\r
76 extern  float           ambient;\r
77 extern  float           maxlight;\r
78 \r
79 \r
80 void InitPaths( int *argc, char **argv );\r
81 \r
82 /*\r
83 Random()\r
84 returns a pseudorandom number between 0 and 1\r
85 */\r
86 /*\r
87 vec_t Random( void )\r
88 {\r
89         return (vec_t) rand() / RAND_MAX;\r
90 }\r
91 */\r
92 \r
93 \r
94 /*\r
95 ExitQ2Map()\r
96 cleanup routine\r
97 */\r
98 /*\r
99 static void ExitQ2Map( void )\r
100 {\r
101         BSPFilesCleanup();\r
102         if( mapDrawSurfs != NULL )\r
103                 free( mapDrawSurfs );\r
104 }\r
105 */\r
106 \r
107 \r
108 /*\r
109 BSPInfo()\r
110 emits statistics about the bsp file\r
111 */\r
112 \r
113 int BSPInfo()\r
114 {\r
115         char            source[ 1024 ], ext[ 64 ];\r
116         int                     size;\r
117         FILE            *f;\r
118         \r
119         Sys_Printf ("\n----- INFO ----\n\n");\r
120         \r
121         /* dummy check */\r
122         if( mapname == NULL )\r
123         {\r
124                 Sys_Printf( "No files to dump info for.\n");\r
125                 return -1;\r
126         }\r
127         \r
128         /* enable info mode */\r
129         //infoMode = qtrue;\r
130         \r
131         \r
132         /* mangle filename and get size */\r
133         strcpy( source, mapname );\r
134         ExtractFileExtension( source, ext );\r
135         if( !Q_stricmp( ext, "map" ) )\r
136                 StripExtension( source );\r
137         DefaultExtension( source, ".bsp" );\r
138         f = fopen( source, "rb" );\r
139         if( f )\r
140         {\r
141                 size = Q_filelength (f);\r
142                 fclose( f );\r
143         }\r
144         else\r
145                 size = 0;\r
146         \r
147         /* load the bsp file and print lump sizes */\r
148         Sys_Printf( "Map: %s\n\n", source );\r
149         \r
150         Sys_Printf( "-----------------------------------------------------\n" );\r
151         \r
152         LoadBSPFile( source );          \r
153         PrintBSPFileSizes();\r
154         \r
155         Sys_Printf( "-----------------------------------------------------\n" );\r
156         \r
157         /* print sizes */\r
158         Sys_Printf( "Total:  %d B = %.3f kB = %.3f MB\n", size, size / 1024.0, size / (1024.0 * 1024.0) );\r
159         \r
160         Sys_Printf( "-----------------------------------------------------\n" );\r
161         \r
162         /* return count */\r
163         return 0;\r
164 }\r
165 \r
166 \r
167 \r
168 /*\r
169 ScaleBSPMain()\r
170 amaze and confuse your enemies with wierd scaled maps!\r
171 */\r
172 /*\r
173 int ScaleBSPMain( int argc, char **argv )\r
174 {\r
175         int                     i;\r
176         float           f, scale;\r
177         vec3_t          vec;\r
178         char            str[ 1024 ];\r
179         \r
180         \r
181         // arg checking \r
182         if( argc < 2 )\r
183         {\r
184                 Sys_Printf( "Usage: q3map -scale <value> [-v] <mapname>\n" );\r
185                 return 0;\r
186         }\r
187         \r
188         // get scale \r
189         scale = atof( argv[ argc - 2 ] );\r
190         if( scale == 0.0f )\r
191         {\r
192                 Sys_Printf( "Usage: q3map -scale <value> [-v] <mapname>\n" );\r
193                 Sys_Printf( "Non-zero scale value required.\n" );\r
194                 return 0;\r
195         }\r
196         \r
197         // do some path mangling \r
198         strcpy( source, ExpandArg( argv[ argc - 1 ] ) );\r
199         StripExtension( source );\r
200         DefaultExtension( source, ".bsp" );\r
201         \r
202         // load the bsp \r
203         Sys_Printf( "Loading %s\n", source );\r
204         LoadBSPFile( source );\r
205         ParseEntities();\r
206         \r
207         // note it \r
208         Sys_Printf( "--- ScaleBSP ---\n" );\r
209         Sys_FPrintf( SYS_VRB, "%9d entities\n", numEntities );\r
210         \r
211         // scale entity keys \r
212         for( i = 0; i < numBSPEntities && i < numEntities; i++ )\r
213         {\r
214                 // scale origin \r
215                 GetVectorForKey( &entities[ i ], "origin", vec );\r
216                 if( (vec[ 0 ] + vec[ 1 ] + vec[ 2 ]) )\r
217                 {\r
218                         VectorScale( vec, scale, vec );\r
219                         sprintf( str, "%f %f %f", vec[ 0 ], vec[ 1 ], vec[ 2 ] );\r
220                         SetKeyValue( &entities[ i ], "origin", str );\r
221                 }\r
222                 \r
223                 // scale door lip \r
224                 f = FloatForKey( &entities[ i ], "lip" );\r
225                 if( f )\r
226                 {\r
227                         f *= scale;\r
228                         sprintf( str, "%f", f );\r
229                         SetKeyValue( &entities[ i ], "lip", str );\r
230                 }\r
231         }\r
232         \r
233         // scale models \r
234         for( i = 0; i < numBSPModels; i++ )\r
235         {\r
236                 VectorScale( bspModels[ i ].mins, scale, bspModels[ i ].mins );\r
237                 VectorScale( bspModels[ i ].maxs, scale, bspModels[ i ].maxs );\r
238         }\r
239         \r
240         // scale nodes \r
241         for( i = 0; i < numBSPNodes; i++ )\r
242         {\r
243                 VectorScale( bspNodes[ i ].mins, scale, bspNodes[ i ].mins );\r
244                 VectorScale( bspNodes[ i ].maxs, scale, bspNodes[ i ].maxs );\r
245         }\r
246         \r
247         // scale leafs \r
248         for( i = 0; i < numBSPLeafs; i++ )\r
249         {\r
250                 VectorScale( bspLeafs[ i ].mins, scale, bspLeafs[ i ].mins );\r
251                 VectorScale( bspLeafs[ i ].maxs, scale, bspLeafs[ i ].maxs );\r
252         }\r
253         \r
254         // scale drawverts \r
255         for( i = 0; i < numBSPDrawVerts; i++ )\r
256                 VectorScale( bspDrawVerts[ i ].xyz, scale, bspDrawVerts[ i ].xyz );\r
257         \r
258         // scale planes \r
259         for( i = 0; i < numBSPPlanes; i++ )\r
260                 bspPlanes[ i ].dist *= scale;\r
261         \r
262         // scale gridsize \r
263         GetVectorForKey( &entities[ 0 ], "gridsize", vec );\r
264         if( (vec[ 0 ] + vec[ 1 ] + vec[ 2 ]) == 0.0f )\r
265                 VectorCopy( gridSize, vec );\r
266         VectorScale( vec, scale, vec );\r
267         sprintf( str, "%f %f %f", vec[ 0 ], vec[ 1 ], vec[ 2 ] );\r
268         SetKeyValue( &entities[ 0 ], "gridsize", str );\r
269         \r
270         // write the bsp \r
271         UnparseEntities();\r
272         StripExtension( source );\r
273         DefaultExtension( source, "_s.bsp" );\r
274         Sys_Printf( "Writing %s\n", source );\r
275         WriteBSPFile( source );\r
276         \r
277         // return to sender \r
278         return 0;\r
279 }\r
280 */\r
281 \r
282 \r
283 /*\r
284 ConvertBSPMain()\r
285 main argument processing function for bsp conversion\r
286 */\r
287 /*\r
288 int ConvertBSPMain( int argc, char **argv )\r
289 {\r
290         int             i;\r
291         int             (*convertFunc)( char * );\r
292         \r
293         \r
294         // set default \r
295         convertFunc = ConvertBSPToASE;\r
296         \r
297         // arg checking \r
298         if( argc < 1 )\r
299         {\r
300                 Sys_Printf( "Usage: q3map -scale <value> [-v] <mapname>\n" );\r
301                 return 0;\r
302         }\r
303         \r
304         // process arguments \r
305         for( i = 1; i < (argc - 1); i++ )\r
306         {\r
307                 // -format map|ase|... \r
308                 if( !strcmp( argv[ i ],  "-format" ) )\r
309                 {\r
310                         i++;\r
311                         if( !Q_stricmp( argv[ i ], "ase" ) )\r
312                                 convertFunc = ConvertBSPToASE;\r
313                         else if( !Q_stricmp( argv[ i ], "map" ) )\r
314                                 convertFunc = ConvertBSPToMap;\r
315                         else\r
316                                 Sys_Printf( "Unknown conversion format \"%s\". Defaulting to ASE.\n", argv[ i ] );\r
317                 }\r
318         }\r
319         \r
320         // clean up map name \r
321         strcpy( source, ExpandArg( argv[ i ] ) );\r
322         StripExtension( source );\r
323         DefaultExtension( source, ".bsp" );\r
324         \r
325         LoadShaderInfo();\r
326         \r
327         Sys_Printf( "Loading %s\n", source );\r
328         \r
329         // ydnar: load surface file \r
330         //%     LoadSurfaceExtraFile( source );\r
331         \r
332         LoadBSPFile( source );\r
333         \r
334         // parse bsp entities \r
335         ParseEntities();\r
336         \r
337         // convert \r
338         return convertFunc( source );\r
339 }\r
340 */\r
341 \r
342 int Check_BSP_Options( int argc, char **argv )\r
343 {\r
344         int i;\r
345         \r
346         for (i=1 ; i<argc ; i++)\r
347         {\r
348                 if (!strcmp(argv[i],"-glview"))\r
349                 {\r
350                         glview = true;\r
351                 }\r
352                 else if (!strcmp(argv[i], "-draw"))\r
353                 {\r
354                         Sys_Printf ("drawflag = true\n");\r
355                         drawflag = true;\r
356                 }\r
357                 else if (!strcmp(argv[i], "-noweld"))\r
358                 {\r
359                         Sys_Printf ("noweld = true\n");\r
360                         noweld = true;\r
361                 }\r
362                 else if (!strcmp(argv[i], "-nocsg"))\r
363                 {\r
364                         Sys_Printf ("nocsg = true\n");\r
365                         nocsg = true;\r
366                 }\r
367                 else if (!strcmp(argv[i], "-noshare"))\r
368                 {\r
369                         Sys_Printf ("noshare = true\n");\r
370                         noshare = true;\r
371                 }\r
372                 else if (!strcmp(argv[i], "-notjunc"))\r
373                 {\r
374                         Sys_Printf ("notjunc = true\n");\r
375                         notjunc = true;\r
376                 }\r
377                 else if (!strcmp(argv[i], "-nowater"))\r
378                 {\r
379                         Sys_Printf ("nowater = true\n");\r
380                         nowater = true;\r
381                 }\r
382                 else if (!strcmp(argv[i], "-noopt"))\r
383                 {\r
384                         Sys_Printf ("noopt = true\n");\r
385                         noopt = true;\r
386                 }\r
387                 else if (!strcmp(argv[i], "-noprune"))\r
388                 {\r
389                         Sys_Printf ("noprune = true\n");\r
390                         noprune = true;\r
391                 }\r
392                 else if (!strcmp(argv[i], "-nofill"))\r
393                 {\r
394                         Sys_Printf ("nofill = true\n");\r
395                         nofill = true;\r
396                 }\r
397                 else if (!strcmp(argv[i], "-nomerge"))\r
398                 {\r
399                         Sys_Printf ("nomerge = true\n");\r
400                         nomerge = true;\r
401                 }\r
402                 else if (!strcmp(argv[i], "-nosubdiv"))\r
403                 {\r
404                         Sys_Printf ("nosubdiv = true\n");\r
405                         nosubdiv = true;\r
406                 }\r
407                 else if (!strcmp(argv[i], "-nodetail"))\r
408                 {\r
409                         Sys_Printf ("nodetail = true\n");\r
410                         nodetail = true;\r
411                 }\r
412                 else if (!strcmp(argv[i], "-fulldetail"))\r
413                 {\r
414                         Sys_Printf ("fulldetail = true\n");\r
415                         fulldetail = true;\r
416                 }\r
417                 else if (!strcmp(argv[i], "-onlyents"))\r
418                 {\r
419                         Sys_Printf ("onlyents = true\n");\r
420                         onlyents = true;\r
421                 }\r
422                 else if (!strcmp(argv[i], "-micro"))\r
423                 {\r
424                         microvolume = atof(argv[i+1]);\r
425                         Sys_Printf ("microvolume = %f\n", microvolume);\r
426                         i++;\r
427                 }\r
428                 else if (!strcmp(argv[i], "-leaktest"))\r
429                 {\r
430                         Sys_Printf ("leaktest = true\n");\r
431                         leaktest = true;\r
432                 }\r
433                 else if (!strcmp(argv[i], "-verboseentities"))\r
434                 {\r
435                         Sys_Printf ("verboseentities = true\n");\r
436                         verboseentities = true;\r
437                 }\r
438                 else if (!strcmp(argv[i], "-chop"))\r
439                 {\r
440                         subdivide_size = atof(argv[i+1]);\r
441                         Sys_Printf ("subdivide_size = %f\n", subdivide_size);\r
442                         i++;\r
443                 }\r
444                 else if (!strcmp(argv[i], "-block"))\r
445                 {\r
446                         block_xl = block_xh = atoi(argv[i+1]);\r
447                         block_yl = block_yh = atoi(argv[i+2]);\r
448                         Sys_Printf ("block: %i,%i\n", block_xl, block_yl);\r
449                         i+=2;\r
450                 }\r
451                 else if (!strcmp(argv[i], "-blocks"))\r
452                 {\r
453                         block_xl = atoi(argv[i+1]);\r
454                         block_yl = atoi(argv[i+2]);\r
455                         block_xh = atoi(argv[i+3]);\r
456                         block_yh = atoi(argv[i+4]);\r
457                         Sys_Printf ("blocks: %i,%i to %i,%i\n", \r
458                                 block_xl, block_yl, block_xh, block_yh);\r
459                         i+=4;\r
460                 }\r
461                 else if (!strcmp (argv[i],"-tmpout"))\r
462                 {\r
463                         strcpy (outbase, "/tmp");\r
464                 }\r
465                 else\r
466                         break;\r
467         }\r
468 \r
469 \r
470         return 0;\r
471 }\r
472 \r
473 int Check_VIS_Options( int argc, char **argv )\r
474 {\r
475         int i;\r
476         \r
477         for (i=1 ; i<argc ; i++)\r
478         {\r
479                 if (!strcmp(argv[i], "-fast"))\r
480                 {\r
481                         Sys_Printf ("fastvis = true\n");\r
482                         fastvis = true;\r
483                 }\r
484                 else if (!strcmp(argv[i], "-level"))\r
485                 {\r
486                         testlevel = atoi(argv[i+1]);\r
487                         Sys_Printf ("testlevel = %i\n", testlevel);\r
488                         i++;\r
489                 }\r
490                 else if (!strcmp (argv[i],"-nosort"))\r
491                 {\r
492                         Sys_Printf ("nosort = true\n");\r
493                         nosort = true;\r
494                 }\r
495                 else if (!strcmp (argv[i],"-tmpin"))\r
496                         strcpy (inbase, "/tmp");\r
497                 else if (!strcmp (argv[i],"-tmpout"))\r
498                         strcpy (outbase, "/tmp");\r
499                 else\r
500                         break;\r
501         }\r
502 \r
503         return 0;\r
504 }\r
505 \r
506 int Check_RAD_Options( int argc, char **argv )\r
507 {\r
508         int i;\r
509         \r
510         for (i=1 ; i<argc ; i++)\r
511         {\r
512                 if (!strcmp(argv[i],"-dump"))\r
513                         dumppatches = true;\r
514                 else if (!strcmp(argv[i],"-bounce"))\r
515                 {\r
516                         numbounce = atoi (argv[i+1]);\r
517                         i++;\r
518                 }\r
519                 else if (!strcmp(argv[i],"-extra"))\r
520                 {\r
521                         extrasamples = true;\r
522                         Sys_Printf ("extrasamples = true\n");\r
523                 }\r
524                 else if (!strcmp(argv[i],"-chop"))\r
525                 {\r
526                         subdiv = atoi (argv[i+1]);\r
527                         i++;\r
528                 }\r
529                 else if (!strcmp(argv[i],"-scale"))\r
530                 {\r
531                         lightscale = atof (argv[i+1]);\r
532                         i++;\r
533                 }\r
534                 else if (!strcmp(argv[i],"-direct"))\r
535                 {\r
536                         direct_scale *= atof(argv[i+1]);\r
537                         Sys_Printf ("direct light scaling at %f\n", direct_scale);\r
538                         i++;\r
539                 }\r
540                 else if (!strcmp(argv[i],"-entity"))\r
541                 {\r
542                         entity_scale *= atof(argv[i+1]);\r
543                         Sys_Printf ("entity light scaling at %f\n", entity_scale);\r
544                         i++;\r
545                 }\r
546                 else if (!strcmp(argv[i],"-glview"))\r
547                 {\r
548                         glview = true;\r
549                         Sys_Printf ("glview = true\n");\r
550                 }\r
551                 else if (!strcmp(argv[i],"-nopvs"))\r
552                 {\r
553                         nopvs = true;\r
554                         Sys_Printf ("nopvs = true\n");\r
555                 }\r
556                 else if (!strcmp(argv[i],"-ambient"))\r
557                 {\r
558                         ambient = atof (argv[i+1]) * 128;\r
559                         i++;\r
560                 }\r
561                 else if (!strcmp(argv[i],"-maxlight"))\r
562                 {\r
563                         maxlight = atof (argv[i+1]) * 128;\r
564                         i++;\r
565                 }\r
566                 else if (!strcmp (argv[i],"-tmpin"))\r
567                         strcpy (inbase, "/tmp");\r
568                 else if (!strcmp (argv[i],"-tmpout"))\r
569                         strcpy (outbase, "/tmp");\r
570                 else\r
571                         break;\r
572         }\r
573 \r
574         return 0;\r
575 }\r
576 \r
577 /*\r
578 main()\r
579 */\r
580 \r
581 int main( int argc, char **argv )\r
582 {\r
583         int     i;\r
584         int     r=0;\r
585         int     total_time;\r
586         double  start, end;\r
587         int     alt_argc;\r
588         char**  alt_argv;\r
589         qboolean        do_info=qfalse;\r
590         qboolean        do_bsp=qfalse;\r
591         qboolean        do_vis=qfalse;\r
592         qboolean        do_rad=qfalse;\r
593         \r
594         \r
595         /* we want consistent 'randomness' */\r
596         srand( 0 );\r
597         \r
598         /* start timer */\r
599         start = I_FloatTime();\r
600 \r
601         Sys_Printf( "\nQ2Map - Ver. 1.0\n" );\r
602 \r
603         /* set exit call */\r
604         //atexit( ExitQ3Map );\r
605         \r
606         game[0] = 0;\r
607         \r
608         if ( argc < 2 )\r
609         {\r
610                 Sys_Printf(" %s: -game [quake2,heretic2] -fs_basepath basepath -info -bsp -vis -rad mapname\n",argv[0]);\r
611                 return -1;\r
612         }\r
613         /* read general options first */\r
614         for( i = 1; i < argc; i++ )\r
615         {\r
616                 /* -connect */\r
617                 if( !strcmp( argv[ i ], "-connect" ) )\r
618                 {\r
619                         i++;\r
620                         Broadcast_Setup( argv[ i ] );\r
621                 }\r
622                 \r
623                 /* verbose */\r
624                 else if( !strcmp( argv[ i ], "-v" ) )\r
625                 {\r
626                         verbose = qtrue;\r
627                 }\r
628                 \r
629                 /* threads */\r
630                  else if( !strcmp( argv[ i ], "-threads" ) )\r
631                 {\r
632                         i++;\r
633                         numthreads = atoi( argv[ i ] );\r
634                 }\r
635                 else if( !strcmp( argv[ i ], "-game" ) )\r
636                 {\r
637                         i++;\r
638                         strncpy (game, argv[ i ] , 64);\r
639                         strlower(game);\r
640                 } \r
641         }\r
642         \r
643         /* set number of threads */\r
644         ThreadSetDefault();\r
645         \r
646         /* ydnar: new path initialization */\r
647         InitPaths( &argc, argv );\r
648         \r
649         /* read compiling options */\r
650         for( i = 1; i < argc; i++ )\r
651         {\r
652                 /* info */\r
653                 if( !strcmp( argv[ i ], "-info" ) )\r
654                 {\r
655                         do_info=qtrue;\r
656                 }\r
657 \r
658                 /* bsp */\r
659                 if( !strcmp( argv[ i ], "-bsp" ) )\r
660                 {\r
661                         do_bsp=qtrue;\r
662                         alt_argc=argc - i;\r
663                         alt_argv= (char **) ( argv + i );\r
664                         Check_BSP_Options( alt_argc, alt_argv );\r
665                 }\r
666 \r
667                 /* vis */\r
668                 if( !strcmp( argv[ i ], "-vis" ) )\r
669                 {\r
670                         do_vis=qtrue;\r
671                         alt_argc=argc - i;\r
672                         alt_argv= (char **) ( argv + i );\r
673                         Check_VIS_Options( alt_argc, alt_argv );\r
674                 }\r
675 \r
676                 /* rad */\r
677                 if( !strcmp( argv[ i ], "-rad" ) )\r
678                 {\r
679                         do_rad=qtrue;\r
680                         alt_argc=argc - i;\r
681                         alt_argv= (char **) ( argv + i );\r
682                         Check_RAD_Options( alt_argc, alt_argv );\r
683                 }\r
684         }\r
685         \r
686         if (game[0] == 0)\r
687                 strncpy( game, "quake2", 7);\r
688                 \r
689         Sys_Printf("Game: %s\n", game);\r
690         \r
691         if ( !do_info && !do_bsp && !do_vis && !do_rad)\r
692                 Sys_Printf("ERROR: -bsp, -vis, -light, nor -info specified.\nWhat to you want me to do?\n\n");\r
693         else\r
694         {\r
695                 mapname=argv[argc-1];\r
696                 \r
697                 if (do_bsp)\r
698                         BSP_Main();\r
699                 if (do_vis)\r
700                         VIS_Main();\r
701                 if (do_rad)\r
702                         RAD_Main();\r
703                 if (do_info)\r
704                         BSPInfo();\r
705                 \r
706         }\r
707         \r
708         /* emit time */\r
709         end = I_FloatTime();\r
710         total_time = (int) (end-start);\r
711         Sys_Printf("\nTotal Time: ");\r
712         if ( total_time > 59 )\r
713                 Sys_Printf("%d Minutes ", total_time/60 );\r
714         Sys_Printf( "%d Seconds\n", total_time%60 );\r
715         \r
716         /* shut down connection */\r
717         Broadcast_Shutdown();\r
718         \r
719         /* return any error code */\r
720         return r;\r
721 }\r