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