]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake3/q3map2/bspfile_ibsp.c
my own uncrustify run
[xonotic/netradiant.git] / tools / quake3 / q3map2 / bspfile_ibsp.c
1 /* -------------------------------------------------------------------------------
2
3    Copyright (C) 1999-2007 id Software, Inc. and contributors.
4    For a list of contributors, see the accompanying CONTRIBUTORS file.
5
6    This file is part of GtkRadiant.
7
8    GtkRadiant is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12
13    GtkRadiant is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with GtkRadiant; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21
22    ----------------------------------------------------------------------------------
23
24    This code has been altered significantly from its original form, to support
25    several games based on the Quake III Arena engine, in the form of "Q3Map2."
26
27    ------------------------------------------------------------------------------- */
28
29
30
31 /* marker */
32 #define BSPFILE_IBSP_C
33
34
35
36 /* dependencies */
37 #include "q3map2.h"
38
39
40
41
42 /* -------------------------------------------------------------------------------
43
44    this file handles translating the bsp file format used by quake 3, rtcw, and ef
45    into the abstracted bsp file used by q3map2.
46
47    ------------------------------------------------------------------------------- */
48
49 /* constants */
50 #define LUMP_ENTITIES       0
51 #define LUMP_SHADERS        1
52 #define LUMP_PLANES         2
53 #define LUMP_NODES          3
54 #define LUMP_LEAFS          4
55 #define LUMP_LEAFSURFACES   5
56 #define LUMP_LEAFBRUSHES    6
57 #define LUMP_MODELS         7
58 #define LUMP_BRUSHES        8
59 #define LUMP_BRUSHSIDES     9
60 #define LUMP_DRAWVERTS      10
61 #define LUMP_DRAWINDEXES    11
62 #define LUMP_FOGS           12
63 #define LUMP_SURFACES       13
64 #define LUMP_LIGHTMAPS      14
65 #define LUMP_LIGHTGRID      15
66 #define LUMP_VISIBILITY     16
67 #define LUMP_ADVERTISEMENTS 17
68 #define HEADER_LUMPS        18
69
70
71 /* types */
72 typedef struct
73 {
74         char ident[ 4 ];
75         int version;
76
77         bspLump_t lumps[ HEADER_LUMPS ];
78 }
79 ibspHeader_t;
80
81
82
83 /* brush sides */
84 typedef struct
85 {
86         int planeNum;
87         int shaderNum;
88 }
89 ibspBrushSide_t;
90
91
92 static void CopyBrushSidesLump( ibspHeader_t *header ){
93         int i;
94         ibspBrushSide_t *in;
95         bspBrushSide_t  *out;
96
97
98         /* get count */
99         numBSPBrushSides = GetLumpElements( (bspHeader_t*) header, LUMP_BRUSHSIDES, sizeof( *in ) );
100
101         /* copy */
102         in = GetLump( (bspHeader_t*) header, LUMP_BRUSHSIDES );
103         for ( i = 0; i < numBSPBrushSides; i++ )
104         {
105                 AUTOEXPAND_BY_REALLOC( bspBrushSides, i, allocatedBSPBrushSides, 1024 );
106                 out = &bspBrushSides[i];
107                 out->planeNum = in->planeNum;
108                 out->shaderNum = in->shaderNum;
109                 out->surfaceNum = -1;
110                 in++;
111         }
112 }
113
114
115 static void AddBrushSidesLump( FILE *file, ibspHeader_t *header ){
116         int i, size;
117         bspBrushSide_t  *in;
118         ibspBrushSide_t *buffer, *out;
119
120
121         /* allocate output buffer */
122         size = numBSPBrushSides * sizeof( *buffer );
123         buffer = safe_malloc( size );
124         memset( buffer, 0, size );
125
126         /* convert */
127         in = bspBrushSides;
128         out = buffer;
129         for ( i = 0; i < numBSPBrushSides; i++ )
130         {
131                 out->planeNum = in->planeNum;
132                 out->shaderNum = in->shaderNum;
133                 in++;
134                 out++;
135         }
136
137         /* write lump */
138         AddLump( file, (bspHeader_t*) header, LUMP_BRUSHSIDES, buffer, size );
139
140         /* free buffer */
141         free( buffer );
142 }
143
144
145
146 /* drawsurfaces */
147 typedef struct ibspDrawSurface_s
148 {
149         int shaderNum;
150         int fogNum;
151         int surfaceType;
152
153         int firstVert;
154         int numVerts;
155
156         int firstIndex;
157         int numIndexes;
158
159         int lightmapNum;
160         int lightmapX, lightmapY;
161         int lightmapWidth, lightmapHeight;
162
163         vec3_t lightmapOrigin;
164         vec3_t lightmapVecs[ 3 ];
165
166         int patchWidth;
167         int patchHeight;
168 }
169 ibspDrawSurface_t;
170
171
172 static void CopyDrawSurfacesLump( ibspHeader_t *header ){
173         int i, j;
174         ibspDrawSurface_t   *in;
175         bspDrawSurface_t    *out;
176
177
178         /* get count */
179         numBSPDrawSurfaces = GetLumpElements( (bspHeader_t*) header, LUMP_SURFACES, sizeof( *in ) );
180         SetDrawSurfaces( numBSPDrawSurfaces );
181
182         /* copy */
183         in = GetLump( (bspHeader_t*) header, LUMP_SURFACES );
184         out = bspDrawSurfaces;
185         for ( i = 0; i < numBSPDrawSurfaces; i++ )
186         {
187                 out->shaderNum = in->shaderNum;
188                 out->fogNum = in->fogNum;
189                 out->surfaceType = in->surfaceType;
190                 out->firstVert = in->firstVert;
191                 out->numVerts = in->numVerts;
192                 out->firstIndex = in->firstIndex;
193                 out->numIndexes = in->numIndexes;
194
195                 out->lightmapStyles[ 0 ] = LS_NORMAL;
196                 out->vertexStyles[ 0 ] = LS_NORMAL;
197                 out->lightmapNum[ 0 ] = in->lightmapNum;
198                 out->lightmapX[ 0 ] = in->lightmapX;
199                 out->lightmapY[ 0 ] = in->lightmapY;
200
201                 for ( j = 1; j < MAX_LIGHTMAPS; j++ )
202                 {
203                         out->lightmapStyles[ j ] = LS_NONE;
204                         out->vertexStyles[ j ] = LS_NONE;
205                         out->lightmapNum[ j ] = -3;
206                         out->lightmapX[ j ] = 0;
207                         out->lightmapY[ j ] = 0;
208                 }
209
210                 out->lightmapWidth = in->lightmapWidth;
211                 out->lightmapHeight = in->lightmapHeight;
212
213                 VectorCopy( in->lightmapOrigin, out->lightmapOrigin );
214                 VectorCopy( in->lightmapVecs[ 0 ], out->lightmapVecs[ 0 ] );
215                 VectorCopy( in->lightmapVecs[ 1 ], out->lightmapVecs[ 1 ] );
216                 VectorCopy( in->lightmapVecs[ 2 ], out->lightmapVecs[ 2 ] );
217
218                 out->patchWidth = in->patchWidth;
219                 out->patchHeight = in->patchHeight;
220
221                 in++;
222                 out++;
223         }
224 }
225
226
227 static void AddDrawSurfacesLump( FILE *file, ibspHeader_t *header ){
228         int i, size;
229         bspDrawSurface_t    *in;
230         ibspDrawSurface_t   *buffer, *out;
231
232
233         /* allocate output buffer */
234         size = numBSPDrawSurfaces * sizeof( *buffer );
235         buffer = safe_malloc( size );
236         memset( buffer, 0, size );
237
238         /* convert */
239         in = bspDrawSurfaces;
240         out = buffer;
241         for ( i = 0; i < numBSPDrawSurfaces; i++ )
242         {
243                 out->shaderNum = in->shaderNum;
244                 out->fogNum = in->fogNum;
245                 out->surfaceType = in->surfaceType;
246                 out->firstVert = in->firstVert;
247                 out->numVerts = in->numVerts;
248                 out->firstIndex = in->firstIndex;
249                 out->numIndexes = in->numIndexes;
250
251                 out->lightmapNum = in->lightmapNum[ 0 ];
252                 out->lightmapX = in->lightmapX[ 0 ];
253                 out->lightmapY = in->lightmapY[ 0 ];
254                 out->lightmapWidth = in->lightmapWidth;
255                 out->lightmapHeight = in->lightmapHeight;
256
257                 VectorCopy( in->lightmapOrigin, out->lightmapOrigin );
258                 VectorCopy( in->lightmapVecs[ 0 ], out->lightmapVecs[ 0 ] );
259                 VectorCopy( in->lightmapVecs[ 1 ], out->lightmapVecs[ 1 ] );
260                 VectorCopy( in->lightmapVecs[ 2 ], out->lightmapVecs[ 2 ] );
261
262                 out->patchWidth = in->patchWidth;
263                 out->patchHeight = in->patchHeight;
264
265                 in++;
266                 out++;
267         }
268
269         /* write lump */
270         AddLump( file, (bspHeader_t*) header, LUMP_SURFACES, buffer, size );
271
272         /* free buffer */
273         free( buffer );
274 }
275
276
277
278 /* drawverts */
279 typedef struct
280 {
281         vec3_t xyz;
282         float st[ 2 ];
283         float lightmap[ 2 ];
284         vec3_t normal;
285         byte color[ 4 ];
286 }
287 ibspDrawVert_t;
288
289
290 static void CopyDrawVertsLump( ibspHeader_t *header ){
291         int i;
292         ibspDrawVert_t  *in;
293         bspDrawVert_t   *out;
294
295
296         /* get count */
297         numBSPDrawVerts = GetLumpElements( (bspHeader_t*) header, LUMP_DRAWVERTS, sizeof( *in ) );
298         SetDrawVerts( numBSPDrawVerts );
299
300         /* copy */
301         in = GetLump( (bspHeader_t*) header, LUMP_DRAWVERTS );
302         out = bspDrawVerts;
303         for ( i = 0; i < numBSPDrawVerts; i++ )
304         {
305                 VectorCopy( in->xyz, out->xyz );
306                 out->st[ 0 ] = in->st[ 0 ];
307                 out->st[ 1 ] = in->st[ 1 ];
308
309                 out->lightmap[ 0 ][ 0 ] = in->lightmap[ 0 ];
310                 out->lightmap[ 0 ][ 1 ] = in->lightmap[ 1 ];
311
312                 VectorCopy( in->normal, out->normal );
313
314                 out->color[ 0 ][ 0 ] = in->color[ 0 ];
315                 out->color[ 0 ][ 1 ] = in->color[ 1 ];
316                 out->color[ 0 ][ 2 ] = in->color[ 2 ];
317                 out->color[ 0 ][ 3 ] = in->color[ 3 ];
318
319                 in++;
320                 out++;
321         }
322 }
323
324
325 static void AddDrawVertsLump( FILE *file, ibspHeader_t *header ){
326         int i, size;
327         bspDrawVert_t   *in;
328         ibspDrawVert_t  *buffer, *out;
329
330
331         /* allocate output buffer */
332         size = numBSPDrawVerts * sizeof( *buffer );
333         buffer = safe_malloc( size );
334         memset( buffer, 0, size );
335
336         /* convert */
337         in = bspDrawVerts;
338         out = buffer;
339         for ( i = 0; i < numBSPDrawVerts; i++ )
340         {
341                 VectorCopy( in->xyz, out->xyz );
342                 out->st[ 0 ] = in->st[ 0 ];
343                 out->st[ 1 ] = in->st[ 1 ];
344
345                 out->lightmap[ 0 ] = in->lightmap[ 0 ][ 0 ];
346                 out->lightmap[ 1 ] = in->lightmap[ 0 ][ 1 ];
347
348                 VectorCopy( in->normal, out->normal );
349
350                 out->color[ 0 ] = in->color[ 0 ][ 0 ];
351                 out->color[ 1 ] = in->color[ 0 ][ 1 ];
352                 out->color[ 2 ] = in->color[ 0 ][ 2 ];
353                 out->color[ 3 ] = in->color[ 0 ][ 3 ];
354
355                 in++;
356                 out++;
357         }
358
359         /* write lump */
360         AddLump( file, (bspHeader_t*) header, LUMP_DRAWVERTS, buffer, size );
361
362         /* free buffer */
363         free( buffer );
364 }
365
366
367
368 /* light grid */
369 typedef struct
370 {
371         byte ambient[ 3 ];
372         byte directed[ 3 ];
373         byte latLong[ 2 ];
374 }
375 ibspGridPoint_t;
376
377
378 static void CopyLightGridLumps( ibspHeader_t *header ){
379         int i, j;
380         ibspGridPoint_t *in;
381         bspGridPoint_t  *out;
382
383
384         /* get count */
385         numBSPGridPoints = GetLumpElements( (bspHeader_t*) header, LUMP_LIGHTGRID, sizeof( *in ) );
386
387         /* allocate buffer */
388         bspGridPoints = safe_malloc( numBSPGridPoints * sizeof( *bspGridPoints ) );
389         memset( bspGridPoints, 0, numBSPGridPoints * sizeof( *bspGridPoints ) );
390
391         /* copy */
392         in = GetLump( (bspHeader_t*) header, LUMP_LIGHTGRID );
393         out = bspGridPoints;
394         for ( i = 0; i < numBSPGridPoints; i++ )
395         {
396                 for ( j = 0; j < MAX_LIGHTMAPS; j++ )
397                 {
398                         VectorCopy( in->ambient, out->ambient[ j ] );
399                         VectorCopy( in->directed, out->directed[ j ] );
400                         out->styles[ j ] = LS_NONE;
401                 }
402
403                 out->styles[ 0 ] = LS_NORMAL;
404
405                 out->latLong[ 0 ] = in->latLong[ 0 ];
406                 out->latLong[ 1 ] = in->latLong[ 1 ];
407
408                 in++;
409                 out++;
410         }
411 }
412
413
414 static void AddLightGridLumps( FILE *file, ibspHeader_t *header ){
415         int i;
416         bspGridPoint_t  *in;
417         ibspGridPoint_t *buffer, *out;
418
419
420         /* dummy check */
421         if ( bspGridPoints == NULL ) {
422                 return;
423         }
424
425         /* allocate temporary buffer */
426         buffer = safe_malloc( numBSPGridPoints * sizeof( *out ) );
427
428         /* convert */
429         in = bspGridPoints;
430         out = buffer;
431         for ( i = 0; i < numBSPGridPoints; i++ )
432         {
433                 VectorCopy( in->ambient[ 0 ], out->ambient );
434                 VectorCopy( in->directed[ 0 ], out->directed );
435
436                 out->latLong[ 0 ] = in->latLong[ 0 ];
437                 out->latLong[ 1 ] = in->latLong[ 1 ];
438
439                 in++;
440                 out++;
441         }
442
443         /* write lumps */
444         AddLump( file, (bspHeader_t*) header, LUMP_LIGHTGRID, buffer, ( numBSPGridPoints * sizeof( *out ) ) );
445
446         /* free buffer (ydnar 2002-10-22: [bug 641] thanks Rap70r! */
447         free( buffer );
448 }
449
450 /*
451    LoadIBSPFile()
452    loads a quake 3 bsp file into memory
453  */
454
455 void LoadIBSPFile( const char *filename ){
456         ibspHeader_t    *header;
457
458
459         /* load the file header */
460         LoadFile( filename, (void**) &header );
461
462         /* swap the header (except the first 4 bytes) */
463         SwapBlock( (int*) ( (byte*) header + sizeof( int ) ), sizeof( *header ) - sizeof( int ) );
464
465         /* make sure it matches the format we're trying to load */
466         if ( force == qfalse && *( (int*) header->ident ) != *( (int*) game->bspIdent ) ) {
467                 Error( "%s is not a %s file", filename, game->bspIdent );
468         }
469         if ( force == qfalse && header->version != game->bspVersion ) {
470                 Error( "%s is version %d, not %d", filename, header->version, game->bspVersion );
471         }
472
473         /* load/convert lumps */
474         numBSPShaders = CopyLump_Allocate( (bspHeader_t*) header, LUMP_SHADERS, (void **) &bspShaders, sizeof( bspShader_t ), &allocatedBSPShaders );
475
476         numBSPModels = CopyLump_Allocate( (bspHeader_t*) header, LUMP_MODELS, (void **) &bspModels, sizeof( bspModel_t ), &allocatedBSPModels );
477
478         numBSPPlanes = CopyLump_Allocate( (bspHeader_t*) header, LUMP_PLANES, (void **) &bspPlanes, sizeof( bspPlane_t ), &allocatedBSPPlanes );
479
480         numBSPLeafs = CopyLump( (bspHeader_t*) header, LUMP_LEAFS, bspLeafs, sizeof( bspLeaf_t ) ); // TODO fix overflow
481
482         numBSPNodes = CopyLump_Allocate( (bspHeader_t*) header, LUMP_NODES, (void **) &bspNodes, sizeof( bspNode_t ), &allocatedBSPNodes );
483
484         numBSPLeafSurfaces = CopyLump_Allocate( (bspHeader_t*) header, LUMP_LEAFSURFACES, (void **) &bspLeafSurfaces, sizeof( bspLeafSurfaces[ 0 ] ), &allocatedBSPLeafSurfaces );
485
486         numBSPLeafBrushes = CopyLump_Allocate( (bspHeader_t*) header, LUMP_LEAFBRUSHES, (void **) &bspLeafBrushes, sizeof( bspLeafBrushes[ 0 ] ), &allocatedBSPLeafBrushes );
487
488         numBSPBrushes = CopyLump_Allocate( (bspHeader_t*) header, LUMP_BRUSHES, (void **) &bspBrushes, sizeof( bspBrush_t ), &allocatedBSPLeafBrushes );
489
490         CopyBrushSidesLump( header );
491
492         CopyDrawVertsLump( header );
493
494         CopyDrawSurfacesLump( header );
495
496         numBSPFogs = CopyLump( (bspHeader_t*) header, LUMP_FOGS, bspFogs, sizeof( bspFog_t ) ); // TODO fix overflow
497
498         numBSPDrawIndexes = CopyLump_Allocate( (bspHeader_t*) header, LUMP_DRAWINDEXES, (void **) &bspDrawIndexes, sizeof( bspDrawIndexes[ 0 ] ), &allocatedBSPDrawIndexes );
499
500         numBSPVisBytes = CopyLump( (bspHeader_t*) header, LUMP_VISIBILITY, bspVisBytes, 1 ); // TODO fix overflow
501
502         numBSPLightBytes = GetLumpElements( (bspHeader_t*) header, LUMP_LIGHTMAPS, 1 ); // TODO change to CopyLump_Allocate
503         bspLightBytes = safe_malloc( numBSPLightBytes );
504         CopyLump( (bspHeader_t*) header, LUMP_LIGHTMAPS, bspLightBytes, 1 );
505
506         bspEntDataSize = CopyLump_Allocate( (bspHeader_t*) header, LUMP_ENTITIES, (void **) &bspEntData, 1, &allocatedBSPEntData );
507
508         CopyLightGridLumps( header );
509
510         /* advertisements */
511         if ( header->version == 47 ) { // quake live's bsp version
512                 numBSPAds = CopyLump( (bspHeader_t*) header, LUMP_ADVERTISEMENTS, bspAds, sizeof( bspAdvertisement_t ) );
513         }
514         else{
515                 numBSPAds = 0;
516         }
517
518         /* free the file buffer */
519         free( header );
520 }
521
522
523
524 /*
525    WriteIBSPFile()
526    writes an id bsp file
527  */
528
529 void WriteIBSPFile( const char *filename ){
530         ibspHeader_t outheader, *header;
531         FILE            *file;
532         time_t t;
533         char marker[ 1024 ];
534         int size;
535
536
537         /* set header */
538         header = &outheader;
539         memset( header, 0, sizeof( *header ) );
540
541         //%     Swapfile();
542
543         /* set up header */
544         *( (int*) (bspHeader_t*) header->ident ) = *( (int*) game->bspIdent );
545         header->version = LittleLong( game->bspVersion );
546
547         /* write initial header */
548         file = SafeOpenWrite( filename );
549         SafeWrite( file, (bspHeader_t*) header, sizeof( *header ) );    /* overwritten later */
550
551         /* add marker lump */
552         time( &t );
553         sprintf( marker, "I LOVE MY Q3MAP2 %s on %s)", Q3MAP_VERSION, asctime( localtime( &t ) ) );
554         AddLump( file, (bspHeader_t*) header, 0, marker, strlen( marker ) + 1 );
555
556         /* add lumps */
557         AddLump( file, (bspHeader_t*) header, LUMP_SHADERS, bspShaders, numBSPShaders * sizeof( bspShader_t ) );
558         AddLump( file, (bspHeader_t*) header, LUMP_PLANES, bspPlanes, numBSPPlanes * sizeof( bspPlane_t ) );
559         AddLump( file, (bspHeader_t*) header, LUMP_LEAFS, bspLeafs, numBSPLeafs * sizeof( bspLeaf_t ) );
560         AddLump( file, (bspHeader_t*) header, LUMP_NODES, bspNodes, numBSPNodes * sizeof( bspNode_t ) );
561         AddLump( file, (bspHeader_t*) header, LUMP_BRUSHES, bspBrushes, numBSPBrushes * sizeof( bspBrush_t ) );
562         AddBrushSidesLump( file, header );
563         AddLump( file, (bspHeader_t*) header, LUMP_LEAFSURFACES, bspLeafSurfaces, numBSPLeafSurfaces * sizeof( bspLeafSurfaces[ 0 ] ) );
564         AddLump( file, (bspHeader_t*) header, LUMP_LEAFBRUSHES, bspLeafBrushes, numBSPLeafBrushes * sizeof( bspLeafBrushes[ 0 ] ) );
565         AddLump( file, (bspHeader_t*) header, LUMP_MODELS, bspModels, numBSPModels * sizeof( bspModel_t ) );
566         AddDrawVertsLump( file, header );
567         AddDrawSurfacesLump( file, header );
568         AddLump( file, (bspHeader_t*) header, LUMP_VISIBILITY, bspVisBytes, numBSPVisBytes );
569         AddLump( file, (bspHeader_t*) header, LUMP_LIGHTMAPS, bspLightBytes, numBSPLightBytes );
570         AddLightGridLumps( file, header );
571         AddLump( file, (bspHeader_t*) header, LUMP_ENTITIES, bspEntData, bspEntDataSize );
572         AddLump( file, (bspHeader_t*) header, LUMP_FOGS, bspFogs, numBSPFogs * sizeof( bspFog_t ) );
573         AddLump( file, (bspHeader_t*) header, LUMP_DRAWINDEXES, bspDrawIndexes, numBSPDrawIndexes * sizeof( bspDrawIndexes[ 0 ] ) );
574
575         /* advertisements */
576         AddLump( file, (bspHeader_t*) header, LUMP_ADVERTISEMENTS, bspAds, numBSPAds * sizeof( bspAdvertisement_t ) );
577
578         /* emit bsp size */
579         size = ftell( file );
580         Sys_Printf( "Wrote %.1f MB (%d bytes)\n", (float) size / ( 1024 * 1024 ), size );
581
582         /* write the completed header */
583         fseek( file, 0, SEEK_SET );
584         SafeWrite( file, header, sizeof( *header ) );
585
586         /* close the file */
587         fclose( file );
588 }