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