]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake3/q3map2/main.c
eol style
[xonotic/netradiant.git] / tools / quake3 / q3map2 / 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 This code has been altered significantly from its original form, to support
24 several games based on the Quake III Arena engine, in the form of "Q3Map2."
25
26 ------------------------------------------------------------------------------- */
27
28
29
30 /* marker */
31 #define MAIN_C
32
33
34
35 /* dependencies */
36 #include "q3map2.h"
37
38
39
40 /*
41 Random()
42 returns a pseudorandom number between 0 and 1
43 */
44
45 vec_t Random( void )
46 {
47         return (vec_t) rand() / RAND_MAX;
48 }
49
50
51
52 /*
53 ExitQ3Map()
54 cleanup routine
55 */
56
57 static void ExitQ3Map( void )
58 {
59         BSPFilesCleanup();
60         if( mapDrawSurfs != NULL )
61                 free( mapDrawSurfs );
62 }
63
64
65
66 /*
67 BSPInfo()
68 emits statistics about the bsp file
69 */
70
71 int BSPInfo( int count, char **fileNames )
72 {
73         int                     i;
74         char            source[ 1024 ], ext[ 64 ];
75         int                     size;
76         FILE            *f;
77         
78         
79         /* dummy check */
80         if( count < 1 )
81         {
82                 Sys_Printf( "No files to dump info for.\n");
83                 return -1;
84         }
85         
86         /* enable info mode */
87         infoMode = qtrue;
88         
89         /* walk file list */
90         for( i = 0; i < count; i++ )
91         {
92                 Sys_Printf( "---------------------------------\n" );
93                 
94                 /* mangle filename and get size */
95                 strcpy( source, fileNames[ i ] );
96                 ExtractFileExtension( source, ext );
97                 if( !Q_stricmp( ext, "map" ) )
98                         StripExtension( source );
99                 DefaultExtension( source, ".bsp" );
100                 f = fopen( source, "rb" );
101                 if( f )
102                 {
103                         size = Q_filelength (f);
104                         fclose( f );
105                 }
106                 else
107                         size = 0;
108                 
109                 /* load the bsp file and print lump sizes */
110                 Sys_Printf( "%s\n", source );
111                 LoadBSPFile( source );          
112                 PrintBSPFileSizes();
113                 
114                 /* print sizes */
115                 Sys_Printf( "\n" );
116                 Sys_Printf( "          total         %9d\n", size );
117                 Sys_Printf( "                        %9d KB\n", size / 1024 );
118                 Sys_Printf( "                        %9d MB\n", size / (1024 * 1024) );
119                 
120                 Sys_Printf( "---------------------------------\n" );
121         }
122         
123         /* return count */
124         return i;
125 }
126
127
128
129 /*
130 ScaleBSPMain()
131 amaze and confuse your enemies with wierd scaled maps!
132 */
133
134 int ScaleBSPMain( int argc, char **argv )
135 {
136         int                     i;
137         float           f, scale;
138         vec3_t          vec;
139         char            str[ 1024 ];
140         
141         
142         /* arg checking */
143         if( argc < 2 )
144         {
145                 Sys_Printf( "Usage: q3map -scale <value> [-v] <mapname>\n" );
146                 return 0;
147         }
148         
149         /* get scale */
150         scale = atof( argv[ argc - 2 ] );
151         if( scale == 0.0f )
152         {
153                 Sys_Printf( "Usage: q3map -scale <value> [-v] <mapname>\n" );
154                 Sys_Printf( "Non-zero scale value required.\n" );
155                 return 0;
156         }
157         
158         /* do some path mangling */
159         strcpy( source, ExpandArg( argv[ argc - 1 ] ) );
160         StripExtension( source );
161         DefaultExtension( source, ".bsp" );
162         
163         /* load the bsp */
164         Sys_Printf( "Loading %s\n", source );
165         LoadBSPFile( source );
166         ParseEntities();
167         
168         /* note it */
169         Sys_Printf( "--- ScaleBSP ---\n" );
170         Sys_FPrintf( SYS_VRB, "%9d entities\n", numEntities );
171         
172         /* scale entity keys */
173         for( i = 0; i < numBSPEntities && i < numEntities; i++ )
174         {
175                 /* scale origin */
176                 GetVectorForKey( &entities[ i ], "origin", vec );
177                 if( (vec[ 0 ] + vec[ 1 ] + vec[ 2 ]) )
178                 {
179                         VectorScale( vec, scale, vec );
180                         sprintf( str, "%f %f %f", vec[ 0 ], vec[ 1 ], vec[ 2 ] );
181                         SetKeyValue( &entities[ i ], "origin", str );
182                 }
183                 
184                 /* scale door lip */
185                 f = FloatForKey( &entities[ i ], "lip" );
186                 if( f )
187                 {
188                         f *= scale;
189                         sprintf( str, "%f", f );
190                         SetKeyValue( &entities[ i ], "lip", str );
191                 }
192         }
193         
194         /* scale models */
195         for( i = 0; i < numBSPModels; i++ )
196         {
197                 VectorScale( bspModels[ i ].mins, scale, bspModels[ i ].mins );
198                 VectorScale( bspModels[ i ].maxs, scale, bspModels[ i ].maxs );
199         }
200         
201         /* scale nodes */
202         for( i = 0; i < numBSPNodes; i++ )
203         {
204                 VectorScale( bspNodes[ i ].mins, scale, bspNodes[ i ].mins );
205                 VectorScale( bspNodes[ i ].maxs, scale, bspNodes[ i ].maxs );
206         }
207         
208         /* scale leafs */
209         for( i = 0; i < numBSPLeafs; i++ )
210         {
211                 VectorScale( bspLeafs[ i ].mins, scale, bspLeafs[ i ].mins );
212                 VectorScale( bspLeafs[ i ].maxs, scale, bspLeafs[ i ].maxs );
213         }
214         
215         /* scale drawverts */
216         for( i = 0; i < numBSPDrawVerts; i++ )
217                 VectorScale( bspDrawVerts[ i ].xyz, scale, bspDrawVerts[ i ].xyz );
218         
219         /* scale planes */
220         for( i = 0; i < numBSPPlanes; i++ )
221                 bspPlanes[ i ].dist *= scale;
222         
223         /* scale gridsize */
224         GetVectorForKey( &entities[ 0 ], "gridsize", vec );
225         if( (vec[ 0 ] + vec[ 1 ] + vec[ 2 ]) == 0.0f )
226                 VectorCopy( gridSize, vec );
227         VectorScale( vec, scale, vec );
228         sprintf( str, "%f %f %f", vec[ 0 ], vec[ 1 ], vec[ 2 ] );
229         SetKeyValue( &entities[ 0 ], "gridsize", str );
230         
231         /* write the bsp */
232         UnparseEntities();
233         StripExtension( source );
234         DefaultExtension( source, "_s.bsp" );
235         Sys_Printf( "Writing %s\n", source );
236         WriteBSPFile( source );
237         
238         /* return to sender */
239         return 0;
240 }
241
242
243
244 /*
245 ConvertBSPMain()
246 main argument processing function for bsp conversion
247 */
248
249 int ConvertBSPMain( int argc, char **argv )
250 {
251         int             i;
252         int             (*convertFunc)( char * );
253         
254         
255         /* set default */
256         convertFunc = ConvertBSPToASE;
257         
258         /* arg checking */
259         if( argc < 1 )
260         {
261                 Sys_Printf( "Usage: q3map -scale <value> [-v] <mapname>\n" );
262                 return 0;
263         }
264         
265         /* process arguments */
266         for( i = 1; i < (argc - 1); i++ )
267         {
268                 /* -format map|ase|... */
269                 if( !strcmp( argv[ i ],  "-format" ) )
270                 {
271                         i++;
272                         if( !Q_stricmp( argv[ i ], "ase" ) )
273                                 convertFunc = ConvertBSPToASE;
274                         else if( !Q_stricmp( argv[ i ], "map" ) )
275                                 convertFunc = ConvertBSPToMap;
276                         else
277                                 Sys_Printf( "Unknown conversion format \"%s\". Defaulting to ASE.\n", argv[ i ] );
278                 }
279         }
280         
281         /* clean up map name */
282         strcpy( source, ExpandArg( argv[ i ] ) );
283         StripExtension( source );
284         DefaultExtension( source, ".bsp" );
285         
286         LoadShaderInfo();
287         
288         Sys_Printf( "Loading %s\n", source );
289         
290         /* ydnar: load surface file */
291         //%     LoadSurfaceExtraFile( source );
292         
293         LoadBSPFile( source );
294         
295         /* parse bsp entities */
296         ParseEntities();
297         
298         /* convert */
299         return convertFunc( source );
300 }
301
302
303
304 /*
305 main()
306 q3map mojo...
307 */
308
309 int main( int argc, char **argv )
310 {
311         int             i, r;
312         double  start, end;
313         
314         
315         /* we want consistent 'randomness' */
316         srand( 0 );
317         
318         /* start timer */
319         start = I_FloatTime();
320
321         /* this was changed to emit version number over the network */
322         printf( Q3MAP_VERSION "\n" );
323         
324         /* set exit call */
325         atexit( ExitQ3Map );
326         
327         /* read general options first */
328         for( i = 1; i < argc; i++ )
329         {
330                 /* -connect */
331                 if( !strcmp( argv[ i ], "-connect" ) )
332                 {
333                         argv[ i ] = NULL;
334                         i++;
335                         Broadcast_Setup( argv[ i ] );
336                         argv[ i ] = NULL;
337                 }
338                 
339                 /* verbose */
340                 else if( !strcmp( argv[ i ], "-v" ) )
341                 {
342                         verbose = qtrue;
343                         argv[ i ] = NULL;
344                 }
345                 
346                 /* force */
347                 else if( !strcmp( argv[ i ], "-force" ) )
348                 {
349                         force = qtrue;
350                         argv[ i ] = NULL;
351                 }
352                 
353                 /* patch subdivisions */
354                 else if( !strcmp( argv[ i ], "-subdivisions" ) )
355                 {
356                         argv[ i ] = NULL;
357                         i++;
358                         patchSubdivisions = atoi( argv[ i ] );
359                         argv[ i ] = NULL;
360                         if( patchSubdivisions <= 0 )
361                                 patchSubdivisions = 1;
362                 }
363                 
364                 /* threads */
365                 else if( !strcmp( argv[ i ], "-threads" ) )
366                 {
367                         argv[ i ] = NULL;
368                         i++;
369                         numthreads = atoi( argv[ i ] );
370                         argv[ i ] = NULL;
371                 }
372         }
373         
374         /* init model library */
375         PicoInit();
376         PicoSetMallocFunc( safe_malloc );
377         PicoSetFreeFunc( free );
378         PicoSetPrintFunc( PicoPrintFunc );
379         PicoSetLoadFileFunc( PicoLoadFileFunc );
380         PicoSetFreeFileFunc( free );
381         
382         /* set number of threads */
383         ThreadSetDefault();
384         
385         /* generate sinusoid jitter table */
386         for( i = 0; i < MAX_JITTERS; i++ )
387         {
388                 jitters[ i ] = sin( i * 139.54152147 );
389                 //%     Sys_Printf( "Jitter %4d: %f\n", i, jitters[ i ] );
390         }
391         
392         /* we print out two versions, q3map's main version (since it evolves a bit out of GtkRadiant)
393            and we put the GtkRadiant version to make it easy to track with what version of Radiant it was built with */
394         
395         Sys_Printf( "Q3Map         - v1.0r (c) 1999 Id Software Inc.\n" );
396         Sys_Printf( "Q3Map (ydnar) - v" Q3MAP_VERSION "\n" );
397         Sys_Printf( "GtkRadiant    - v" RADIANT_VERSION " " __DATE__ " " __TIME__ "\n" );
398         Sys_Printf( "%s\n", Q3MAP_MOTD );
399         
400         /* ydnar: new path initialization */
401         InitPaths( &argc, argv );
402         
403         /* check if we have enough options left to attempt something */
404         if( argc < 2 )
405                 Error( "Usage: %s [general options] [options] mapfile", argv[ 0 ] );
406         
407         /* info */
408         if( !strcmp( argv[ 1 ], "-info" ) )
409                 r = BSPInfo( argc - 2, argv + 2 );
410         
411         /* vis */
412         else if( !strcmp( argv[ 1 ], "-vis" ) )
413                 r = VisMain( argc - 1, argv + 1 );
414         
415         /* light */
416         else if( !strcmp( argv[ 1 ], "-light" ) )
417                 r = LightMain( argc - 1, argv + 1 );
418         
419         /* vlight */
420         else if( !strcmp( argv[ 1 ], "-vlight" ) )
421         {
422                 Sys_Printf( "WARNING: VLight is no longer supported, defaulting to -light -fast instead\n\n" );
423                 argv[ 1 ] = "-fast";    /* eek a hack */
424                 r = LightMain( argc, argv );
425         }
426         
427         /* ydnar: lightmap export */
428         else if( !strcmp( argv[ 1 ], "-export" ) )
429                 r = ExportLightmapsMain( argc - 1, argv + 1 );
430         
431         /* ydnar: lightmap import */
432         else if( !strcmp( argv[ 1 ], "-import" ) )
433                 r = ImportLightmapsMain( argc - 1, argv + 1 );
434         
435         /* ydnar: bsp scaling */
436         else if( !strcmp( argv[ 1 ], "-scale" ) )
437                 r = ScaleBSPMain( argc - 1, argv + 1 );
438         
439         /* ydnar: bsp conversion */
440         else if( !strcmp( argv[ 1 ], "-convert" ) )
441                 r = ConvertBSPMain( argc - 1, argv + 1 );
442         
443         /* ydnar: otherwise create a bsp */
444         else
445                 r = BSPMain( argc, argv );
446         
447         /* emit time */
448         end = I_FloatTime();
449         Sys_Printf( "%9.0f seconds elapsed\n", end - start );
450         
451         /* shut down connection */
452         Broadcast_Shutdown();
453         
454         /* return any error code */
455         return r;
456 }