]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - tools/quake3/q3map2/bspfile_ibsp.c
merge branch work back into trunk
[xonotic/netradiant.git] / tools / quake3 / q3map2 / bspfile_ibsp.c
index dddf63cacf18f75fcd93a6a95e74fa9242b1612d..9c941070dec598c7b04520502ffb42a1d225d893 100644 (file)
-/*\r
-Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
-For a list of contributors, see the accompanying CONTRIBUTORS file.\r
-\r
-This file is part of GtkRadiant.\r
-\r
-GtkRadiant is free software; you can redistribute it and/or modify\r
-it under the terms of the GNU General Public License as published by\r
-the Free Software Foundation; either version 2 of the License, or\r
-(at your option) any later version.\r
-\r
-GtkRadiant is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-GNU General Public License for more details.\r
-\r
-You should have received a copy of the GNU General Public License\r
-along with GtkRadiant; if not, write to the Free Software\r
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
-\r
-----------------------------------------------------------------------------------\r
-\r
-This code has been altered significantly from its original form, to support\r
-several games based on the Quake III Arena engine, in the form of "Q3Map2."\r
-\r
-------------------------------------------------------------------------------- */\r
-\r
-\r
-\r
-/* marker */\r
-#define BSPFILE_IBSP_C\r
-\r
-\r
-\r
-/* dependencies */\r
-#include "q3map2.h"\r
-\r
-\r
-\r
-\r
-/* -------------------------------------------------------------------------------\r
-\r
-this file handles translating the bsp file format used by quake 3, rtcw, and ef\r
-into the abstracted bsp file used by q3map2.\r
-\r
-------------------------------------------------------------------------------- */\r
-\r
-/* constants */\r
-#define        LUMP_ENTITIES           0\r
-#define        LUMP_SHADERS            1\r
-#define        LUMP_PLANES                     2\r
-#define        LUMP_NODES                      3\r
-#define        LUMP_LEAFS                      4\r
-#define        LUMP_LEAFSURFACES       5\r
-#define        LUMP_LEAFBRUSHES        6\r
-#define        LUMP_MODELS                     7\r
-#define        LUMP_BRUSHES            8\r
-#define        LUMP_BRUSHSIDES         9\r
-#define        LUMP_DRAWVERTS          10\r
-#define        LUMP_DRAWINDEXES        11\r
-#define        LUMP_FOGS                       12\r
-#define        LUMP_SURFACES           13\r
-#define        LUMP_LIGHTMAPS          14\r
-#define        LUMP_LIGHTGRID          15\r
-#define        LUMP_VISIBILITY         16\r
-#define        HEADER_LUMPS            17\r
-\r
-\r
-/* types */\r
-typedef struct\r
-{\r
-       char            ident[ 4 ];\r
-       int                     version;\r
-       \r
-       bspLump_t       lumps[ HEADER_LUMPS ];\r
-}\r
-ibspHeader_t;\r
-\r
-\r
-\r
-/* brush sides */\r
-typedef struct\r
-{\r
-       int                     planeNum;\r
-       int                     shaderNum;\r
-}\r
-ibspBrushSide_t;\r
-\r
-\r
-static void CopyBrushSidesLump( ibspHeader_t *header )\r
-{\r
-       int                             i;\r
-       ibspBrushSide_t *in;\r
-       bspBrushSide_t  *out;\r
-       \r
-       \r
-       /* get count */\r
-       numBSPBrushSides = GetLumpElements( (bspHeader_t*) header, LUMP_BRUSHSIDES, sizeof( *in ) );\r
-       \r
-       /* copy */\r
-       in = GetLump( (bspHeader_t*) header, LUMP_BRUSHSIDES );\r
-       out = bspBrushSides;\r
-       for( i = 0; i < numBSPBrushSides; i++ )\r
-       {\r
-               out->planeNum = in->planeNum;\r
-               out->shaderNum = in->shaderNum;\r
-               out->surfaceNum = -1;\r
-               in++;\r
-               out++;\r
-       }\r
-}\r
-\r
-\r
-static void AddBrushSidesLump( FILE *file, ibspHeader_t *header )\r
-{\r
-       int                             i, size;\r
-       bspBrushSide_t  *in;\r
-       ibspBrushSide_t *buffer, *out;\r
-       \r
-       \r
-       /* allocate output buffer */\r
-       size = numBSPBrushSides * sizeof( *buffer );\r
-       buffer = safe_malloc( size );\r
-       memset( buffer, 0, size );\r
-       \r
-       /* convert */\r
-       in = bspBrushSides;\r
-       out = buffer;\r
-       for( i = 0; i < numBSPBrushSides; i++ )\r
-       {\r
-               out->planeNum = in->planeNum;\r
-               out->shaderNum = in->shaderNum;\r
-               in++;\r
-               out++;\r
-       }\r
-       \r
-       /* write lump */\r
-       AddLump( file, (bspHeader_t*) header, LUMP_BRUSHSIDES, buffer, size );\r
-       \r
-       /* free buffer */\r
-       free( buffer );\r
-}\r
-\r
-\r
-\r
-/* drawsurfaces */\r
-typedef struct ibspDrawSurface_s\r
-{\r
-       int                     shaderNum;\r
-       int                     fogNum;\r
-       int                     surfaceType;\r
-       \r
-       int                     firstVert;\r
-       int                     numVerts;\r
-       \r
-       int                     firstIndex;\r
-       int                     numIndexes;\r
-       \r
-       int                     lightmapNum;\r
-       int                     lightmapX, lightmapY;\r
-       int                     lightmapWidth, lightmapHeight;\r
-       \r
-       vec3_t          lightmapOrigin;\r
-       vec3_t          lightmapVecs[ 3 ];\r
-       \r
-       int                     patchWidth;\r
-       int                     patchHeight;\r
-}\r
-ibspDrawSurface_t;\r
-\r
-\r
-static void CopyDrawSurfacesLump( ibspHeader_t *header )\r
-{\r
-       int                                     i, j;\r
-       ibspDrawSurface_t       *in;\r
-       bspDrawSurface_t        *out;\r
-       \r
-       \r
-       /* get count */\r
-       numBSPDrawSurfaces = GetLumpElements( (bspHeader_t*) header, LUMP_SURFACES, sizeof( *in ) );\r
-       SetDrawSurfaces( numBSPDrawSurfaces );\r
-       \r
-       /* copy */\r
-       in = GetLump( (bspHeader_t*) header, LUMP_SURFACES );\r
-       out = bspDrawSurfaces;\r
-       for( i = 0; i < numBSPDrawSurfaces; i++ )\r
-       {\r
-               out->shaderNum = in->shaderNum;\r
-               out->fogNum = in->fogNum;\r
-               out->surfaceType = in->surfaceType;\r
-               out->firstVert = in->firstVert;\r
-               out->numVerts = in->numVerts;\r
-               out->firstIndex = in->firstIndex;\r
-               out->numIndexes = in->numIndexes;\r
-               \r
-               out->lightmapStyles[ 0 ] = LS_NORMAL;\r
-               out->vertexStyles[ 0 ] = LS_NORMAL;\r
-               out->lightmapNum[ 0 ] = in->lightmapNum;\r
-               out->lightmapX[ 0 ] = in->lightmapX;\r
-               out->lightmapY[ 0 ] = in->lightmapY;\r
-               \r
-               for( j = 1; j < MAX_LIGHTMAPS; j++ )\r
-               {\r
-                       out->lightmapStyles[ j ] = LS_NONE;\r
-                       out->vertexStyles[ j ] = LS_NONE;\r
-                       out->lightmapNum[ j ] = -3;\r
-                       out->lightmapX[ j ] = 0;\r
-                       out->lightmapY[ j ] = 0;\r
-               }\r
-               \r
-               out->lightmapWidth = in->lightmapWidth;\r
-               out->lightmapHeight = in->lightmapHeight;\r
-               \r
-               VectorCopy( in->lightmapOrigin, out->lightmapOrigin );\r
-               VectorCopy( in->lightmapVecs[ 0 ], out->lightmapVecs[ 0 ] );\r
-               VectorCopy( in->lightmapVecs[ 1 ], out->lightmapVecs[ 1 ] );\r
-               VectorCopy( in->lightmapVecs[ 2 ], out->lightmapVecs[ 2 ] );\r
-               \r
-               out->patchWidth = in->patchWidth;\r
-               out->patchHeight = in->patchHeight;\r
-               \r
-               in++;\r
-               out++;\r
-       }\r
-}\r
-\r
-\r
-static void AddDrawSurfacesLump( FILE *file, ibspHeader_t *header )\r
-{\r
-       int                                     i, size;\r
-       bspDrawSurface_t        *in;\r
-       ibspDrawSurface_t       *buffer, *out;\r
-       \r
-       \r
-       /* allocate output buffer */\r
-       size = numBSPDrawSurfaces * sizeof( *buffer );\r
-       buffer = safe_malloc( size );\r
-       memset( buffer, 0, size );\r
-       \r
-       /* convert */\r
-       in = bspDrawSurfaces;\r
-       out = buffer;\r
-       for( i = 0; i < numBSPDrawSurfaces; i++ )\r
-       {\r
-               out->shaderNum = in->shaderNum;\r
-               out->fogNum = in->fogNum;\r
-               out->surfaceType = in->surfaceType;\r
-               out->firstVert = in->firstVert;\r
-               out->numVerts = in->numVerts;\r
-               out->firstIndex = in->firstIndex;\r
-               out->numIndexes = in->numIndexes;\r
-               \r
-               out->lightmapNum = in->lightmapNum[ 0 ];\r
-               out->lightmapX = in->lightmapX[ 0 ];\r
-               out->lightmapY = in->lightmapY[ 0 ];\r
-               out->lightmapWidth = in->lightmapWidth;\r
-               out->lightmapHeight = in->lightmapHeight;\r
-               \r
-               VectorCopy( in->lightmapOrigin, out->lightmapOrigin );\r
-               VectorCopy( in->lightmapVecs[ 0 ], out->lightmapVecs[ 0 ] );\r
-               VectorCopy( in->lightmapVecs[ 1 ], out->lightmapVecs[ 1 ] );\r
-               VectorCopy( in->lightmapVecs[ 2 ], out->lightmapVecs[ 2 ] );\r
-               \r
-               out->patchWidth = in->patchWidth;\r
-               out->patchHeight = in->patchHeight;\r
-               \r
-               in++;\r
-               out++;\r
-       }\r
-       \r
-       /* write lump */\r
-       AddLump( file, (bspHeader_t*) header, LUMP_SURFACES, buffer, size );\r
-       \r
-       /* free buffer */\r
-       free( buffer );\r
-}\r
-\r
-\r
-\r
-/* drawverts */\r
-typedef struct\r
-{\r
-       vec3_t          xyz;\r
-       float           st[ 2 ];\r
-       float           lightmap[ 2 ];\r
-       vec3_t          normal;\r
-       byte            color[ 4 ];\r
-}\r
-ibspDrawVert_t;\r
-\r
-\r
-static void CopyDrawVertsLump( ibspHeader_t *header )\r
-{\r
-       int                             i;\r
-       ibspDrawVert_t  *in;\r
-       bspDrawVert_t   *out;\r
-       \r
-       \r
-       /* get count */\r
-       numBSPDrawVerts = GetLumpElements( (bspHeader_t*) header, LUMP_DRAWVERTS, sizeof( *in ) );\r
-       SetDrawVerts( numBSPDrawVerts );\r
-       \r
-       /* copy */\r
-       in = GetLump( (bspHeader_t*) header, LUMP_DRAWVERTS );\r
-       out = bspDrawVerts;\r
-       for( i = 0; i < numBSPDrawVerts; i++ )\r
-       {\r
-               VectorCopy( in->xyz, out->xyz );\r
-               out->st[ 0 ] = in->st[ 0 ];\r
-               out->st[ 1 ] = in->st[ 1 ];\r
-               \r
-               out->lightmap[ 0 ][ 0 ] = in->lightmap[ 0 ];\r
-               out->lightmap[ 0 ][ 1 ] = in->lightmap[ 1 ];\r
-               \r
-               VectorCopy( in->normal, out->normal );\r
-               \r
-               out->color[ 0 ][ 0 ] = in->color[ 0 ];\r
-               out->color[ 0 ][ 1 ] = in->color[ 1 ];\r
-               out->color[ 0 ][ 2 ] = in->color[ 2 ];\r
-               out->color[ 0 ][ 3 ] = in->color[ 3 ];\r
-               \r
-               in++;\r
-               out++;\r
-       }\r
-}\r
-\r
-\r
-static void AddDrawVertsLump( FILE *file, ibspHeader_t *header )\r
-{\r
-       int                             i, size;\r
-       bspDrawVert_t   *in;\r
-       ibspDrawVert_t  *buffer, *out;\r
-       \r
-       \r
-       /* allocate output buffer */\r
-       size = numBSPDrawVerts * sizeof( *buffer );\r
-       buffer = safe_malloc( size );\r
-       memset( buffer, 0, size );\r
-       \r
-       /* convert */\r
-       in = bspDrawVerts;\r
-       out = buffer;\r
-       for( i = 0; i < numBSPDrawVerts; i++ )\r
-       {\r
-               VectorCopy( in->xyz, out->xyz );\r
-               out->st[ 0 ] = in->st[ 0 ];\r
-               out->st[ 1 ] = in->st[ 1 ];\r
-               \r
-               out->lightmap[ 0 ] = in->lightmap[ 0 ][ 0 ];\r
-               out->lightmap[ 1 ] = in->lightmap[ 0 ][ 1 ];\r
-               \r
-               VectorCopy( in->normal, out->normal );\r
-               \r
-               out->color[ 0 ] = in->color[ 0 ][ 0 ];\r
-               out->color[ 1 ] = in->color[ 0 ][ 1 ];\r
-               out->color[ 2 ] = in->color[ 0 ][ 2 ];\r
-               out->color[ 3 ] = in->color[ 0 ][ 3 ];\r
-               \r
-               in++;\r
-               out++;\r
-       }\r
-       \r
-       /* write lump */\r
-       AddLump( file, (bspHeader_t*) header, LUMP_DRAWVERTS, buffer, size );\r
-       \r
-       /* free buffer */\r
-       free( buffer );\r
-}\r
-\r
-\r
-\r
-/* light grid */\r
-typedef struct\r
-{\r
-       byte            ambient[ 3 ];\r
-       byte            directed[ 3 ];\r
-       byte            latLong[ 2 ];\r
-}\r
-ibspGridPoint_t;\r
-\r
-\r
-static void CopyLightGridLumps( ibspHeader_t *header )\r
-{\r
-       int                             i, j;\r
-       ibspGridPoint_t *in;\r
-       bspGridPoint_t  *out;\r
-       \r
-       \r
-       /* get count */\r
-       numBSPGridPoints = GetLumpElements( (bspHeader_t*) header, LUMP_LIGHTGRID, sizeof( *in ) );\r
-       \r
-       /* allocate buffer */\r
-       bspGridPoints = safe_malloc( numBSPGridPoints * sizeof( *bspGridPoints ) );\r
-       memset( bspGridPoints, 0, numBSPGridPoints * sizeof( *bspGridPoints ) );\r
-       \r
-       /* copy */\r
-       in = GetLump( (bspHeader_t*) header, LUMP_LIGHTGRID );\r
-       out = bspGridPoints;\r
-       for( i = 0; i < numBSPGridPoints; i++ )\r
-       {\r
-               for( j = 0; j < MAX_LIGHTMAPS; j++ )\r
-               {\r
-                       VectorCopy( in->ambient, out->ambient[ j ] );\r
-                       VectorCopy( in->directed, out->directed[ j ] );\r
-                       out->styles[ j ] = LS_NONE;\r
-               }\r
-               \r
-               out->styles[ 0 ] = LS_NORMAL;\r
-               \r
-               out->latLong[ 0 ] = in->latLong[ 0 ];\r
-               out->latLong[ 1 ] = in->latLong[ 1 ];\r
-               \r
-               in++;\r
-               out++;\r
-       }\r
-}\r
-\r
-\r
-static void AddLightGridLumps( FILE *file, ibspHeader_t *header )\r
-{\r
-       int                             i;\r
-       bspGridPoint_t  *in;\r
-       ibspGridPoint_t *buffer, *out;\r
-       \r
-       \r
-       /* dummy check */\r
-       if( bspGridPoints == NULL )\r
-               return;\r
-       \r
-       /* allocate temporary buffer */\r
-       buffer = safe_malloc( numBSPGridPoints * sizeof( *out ) );\r
-       \r
-       /* convert */\r
-       in = bspGridPoints;\r
-       out = buffer;\r
-       for( i = 0; i < numBSPGridPoints; i++ )\r
-       {\r
-               VectorCopy( in->ambient[ 0 ], out->ambient );\r
-               VectorCopy( in->directed[ 0 ], out->directed );\r
-               \r
-               out->latLong[ 0 ] = in->latLong[ 0 ];\r
-               out->latLong[ 1 ] = in->latLong[ 1 ];\r
-               \r
-               in++;\r
-               out++;\r
-       }\r
-       \r
-       /* write lumps */\r
-       AddLump( file, (bspHeader_t*) header, LUMP_LIGHTGRID, buffer, (numBSPGridPoints * sizeof( *out )) );\r
-       \r
-       /* free buffer (ydnar 2002-10-22: [bug 641] thanks Rap70r! */\r
-       free( buffer );\r
-}\r
-\r
-\r
-\r
-/*\r
-LoadIBSPFile()\r
-loads a quake 3 bsp file into memory\r
-*/\r
-\r
-void LoadIBSPFile( const char *filename )\r
-{\r
-       ibspHeader_t    *header;\r
-       \r
-       \r
-       /* load the file header */\r
-       LoadFile( filename, (void**) &header );\r
-\r
-       /* swap the header (except the first 4 bytes) */\r
-       SwapBlock( (int*) ((byte*) header + sizeof( int )), sizeof( *header ) - sizeof( int ) );\r
-       \r
-       /* make sure it matches the format we're trying to load */\r
-       if( force == qfalse && *((int*) header->ident) != *((int*) game->bspIdent) )\r
-               Error( "%s is not a %s file", filename, game->bspIdent );\r
-       if( force == qfalse && header->version != game->bspVersion )\r
-               Error( "%s is version %d, not %d", filename, header->version, game->bspVersion );\r
-       \r
-       /* load/convert lumps */\r
-       numBSPShaders = CopyLump( (bspHeader_t*) header, LUMP_SHADERS, bspShaders, sizeof( bspShader_t ) );\r
-       \r
-       numBSPModels = CopyLump( (bspHeader_t*) header, LUMP_MODELS, bspModels, sizeof( bspModel_t ) );\r
-       \r
-       numBSPPlanes = CopyLump( (bspHeader_t*) header, LUMP_PLANES, bspPlanes, sizeof( bspPlane_t ) );\r
-       \r
-       numBSPLeafs = CopyLump( (bspHeader_t*) header, LUMP_LEAFS, bspLeafs, sizeof( bspLeaf_t ) );\r
-       \r
-       numBSPNodes = CopyLump( (bspHeader_t*) header, LUMP_NODES, bspNodes, sizeof( bspNode_t ) );\r
-       \r
-       numBSPLeafSurfaces = CopyLump( (bspHeader_t*) header, LUMP_LEAFSURFACES, bspLeafSurfaces, sizeof( bspLeafSurfaces[ 0 ] ) );\r
-       \r
-       numBSPLeafBrushes = CopyLump( (bspHeader_t*) header, LUMP_LEAFBRUSHES, bspLeafBrushes, sizeof( bspLeafBrushes[ 0 ] ) );\r
-       \r
-       numBSPBrushes = CopyLump( (bspHeader_t*) header, LUMP_BRUSHES, bspBrushes, sizeof( bspBrush_t ) );\r
-       \r
-       CopyBrushSidesLump( header );\r
-\r
-       CopyDrawVertsLump( header );\r
-       \r
-       CopyDrawSurfacesLump( header );\r
-       \r
-       numBSPFogs = CopyLump( (bspHeader_t*) header, LUMP_FOGS, bspFogs, sizeof( bspFog_t ) );\r
-       \r
-       numBSPDrawIndexes = CopyLump( (bspHeader_t*) header, LUMP_DRAWINDEXES, bspDrawIndexes, sizeof( bspDrawIndexes[ 0 ] ) );\r
-       \r
-       numBSPVisBytes = CopyLump( (bspHeader_t*) header, LUMP_VISIBILITY, bspVisBytes, 1 );\r
-       \r
-       numBSPLightBytes = GetLumpElements( (bspHeader_t*) header, LUMP_LIGHTMAPS, 1 );\r
-               bspLightBytes = safe_malloc( numBSPLightBytes );\r
-               CopyLump( (bspHeader_t*) header, LUMP_LIGHTMAPS, bspLightBytes, 1 );\r
-       \r
-       bspEntDataSize = CopyLump( (bspHeader_t*) header, LUMP_ENTITIES, bspEntData, 1);\r
-       \r
-       CopyLightGridLumps( header );\r
-       \r
-       /* free the file buffer */\r
-       free( header );\r
-}\r
-\r
-\r
-\r
-/*\r
-WriteIBSPFile()\r
-writes an id bsp file\r
-*/\r
-\r
-void WriteIBSPFile( const char *filename )\r
-{              \r
-       ibspHeader_t    outheader, *header;\r
-       FILE                    *file;\r
-       time_t                  t;\r
-       char                    marker[ 1024 ];\r
-       int                             size;\r
-       \r
-       \r
-       /* set header */\r
-       header = &outheader;\r
-       memset( header, 0, sizeof( *header ) );\r
-       \r
-       //%     Swapfile();\r
-       \r
-       /* set up header */\r
-       *((int*) (bspHeader_t*) header->ident) = *((int*) game->bspIdent);\r
-       header->version = LittleLong( game->bspVersion );\r
-       \r
-       /* write initial header */\r
-       file = SafeOpenWrite( filename );\r
-       SafeWrite( file, (bspHeader_t*) header, sizeof( *header ) );    /* overwritten later */\r
-       \r
-       /* add marker lump */\r
-       time( &t );\r
-       sprintf( marker, "I LOVE MY Q3MAP2 %s on %s)", Q3MAP_VERSION, asctime( localtime( &t ) ) );\r
-       AddLump( file, (bspHeader_t*) header, 0, marker, strlen( marker ) + 1 );\r
-       \r
-       /* add lumps */\r
-       AddLump( file, (bspHeader_t*) header, LUMP_SHADERS, bspShaders, numBSPShaders * sizeof( bspShader_t ) );\r
-       AddLump( file, (bspHeader_t*) header, LUMP_PLANES, bspPlanes, numBSPPlanes * sizeof( bspPlane_t ) );\r
-       AddLump( file, (bspHeader_t*) header, LUMP_LEAFS, bspLeafs, numBSPLeafs * sizeof( bspLeaf_t ) );\r
-       AddLump( file, (bspHeader_t*) header, LUMP_NODES, bspNodes, numBSPNodes * sizeof( bspNode_t ) );\r
-       AddLump( file, (bspHeader_t*) header, LUMP_BRUSHES, bspBrushes, numBSPBrushes*sizeof( bspBrush_t ) );\r
-       AddBrushSidesLump( file, header );\r
-       AddLump( file, (bspHeader_t*) header, LUMP_LEAFSURFACES, bspLeafSurfaces, numBSPLeafSurfaces * sizeof( bspLeafSurfaces[ 0 ] ) );\r
-       AddLump( file, (bspHeader_t*) header, LUMP_LEAFBRUSHES, bspLeafBrushes, numBSPLeafBrushes * sizeof( bspLeafBrushes[ 0 ] ) );\r
-       AddLump( file, (bspHeader_t*) header, LUMP_MODELS, bspModels, numBSPModels * sizeof( bspModel_t ) );\r
-       AddDrawVertsLump( file, header );\r
-       AddDrawSurfacesLump( file, header );\r
-       AddLump( file, (bspHeader_t*) header, LUMP_VISIBILITY, bspVisBytes, numBSPVisBytes );\r
-       AddLump( file, (bspHeader_t*) header, LUMP_LIGHTMAPS, bspLightBytes, numBSPLightBytes );\r
-       AddLightGridLumps( file, header );\r
-       AddLump( file, (bspHeader_t*) header, LUMP_ENTITIES, bspEntData, bspEntDataSize );\r
-       AddLump( file, (bspHeader_t*) header, LUMP_FOGS, bspFogs, numBSPFogs * sizeof( bspFog_t ) );\r
-       AddLump( file, (bspHeader_t*) header, LUMP_DRAWINDEXES, bspDrawIndexes, numBSPDrawIndexes * sizeof( bspDrawIndexes[ 0 ] ) );\r
-       \r
-       /* emit bsp size */\r
-       size = ftell( file );\r
-       Sys_Printf( "Wrote %.1f MB (%d bytes)\n", (float) size / (1024 * 1024), size );\r
-       \r
-       /* write the completed header */\r
-       fseek( file, 0, SEEK_SET );\r
-       SafeWrite( file, header, sizeof( *header ) );\r
-       \r
-       /* close the file */\r
-       fclose( file ); \r
-}\r
+/* -------------------------------------------------------------------------------
+
+Copyright (C) 1999-2007 id Software, Inc. and contributors.
+For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+This file is part of GtkRadiant.
+
+GtkRadiant is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+GtkRadiant is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GtkRadiant; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+----------------------------------------------------------------------------------
+
+This code has been altered significantly from its original form, to support
+several games based on the Quake III Arena engine, in the form of "Q3Map2."
+
+------------------------------------------------------------------------------- */
+
+
+
+/* marker */
+#define BSPFILE_IBSP_C
+
+
+
+/* dependencies */
+#include "q3map2.h"
+
+
+
+
+/* -------------------------------------------------------------------------------
+
+this file handles translating the bsp file format used by quake 3, rtcw, and ef
+into the abstracted bsp file used by q3map2.
+
+------------------------------------------------------------------------------- */
+
+/* constants */
+#define        LUMP_ENTITIES           0
+#define        LUMP_SHADERS            1
+#define        LUMP_PLANES                     2
+#define        LUMP_NODES                      3
+#define        LUMP_LEAFS                      4
+#define        LUMP_LEAFSURFACES       5
+#define        LUMP_LEAFBRUSHES        6
+#define        LUMP_MODELS                     7
+#define        LUMP_BRUSHES            8
+#define        LUMP_BRUSHSIDES         9
+#define        LUMP_DRAWVERTS          10
+#define        LUMP_DRAWINDEXES        11
+#define        LUMP_FOGS                       12
+#define        LUMP_SURFACES           13
+#define        LUMP_LIGHTMAPS          14
+#define        LUMP_LIGHTGRID          15
+#define        LUMP_VISIBILITY         16
+#define LUMP_ADVERTISEMENTS 17
+#define        HEADER_LUMPS            18
+
+
+/* types */
+typedef struct
+{
+       char            ident[ 4 ];
+       int                     version;
+       
+       bspLump_t       lumps[ HEADER_LUMPS ];
+}
+ibspHeader_t;
+
+
+
+/* brush sides */
+typedef struct
+{
+       int                     planeNum;
+       int                     shaderNum;
+}
+ibspBrushSide_t;
+
+
+static void CopyBrushSidesLump( ibspHeader_t *header )
+{
+       int                             i;
+       ibspBrushSide_t *in;
+       bspBrushSide_t  *out;
+       
+       
+       /* get count */
+       numBSPBrushSides = GetLumpElements( (bspHeader_t*) header, LUMP_BRUSHSIDES, sizeof( *in ) );
+       
+       /* copy */
+       in = GetLump( (bspHeader_t*) header, LUMP_BRUSHSIDES );
+       out = bspBrushSides;
+       for( i = 0; i < numBSPBrushSides; i++ )
+       {
+               out->planeNum = in->planeNum;
+               out->shaderNum = in->shaderNum;
+               out->surfaceNum = -1;
+               in++;
+               out++;
+       }
+}
+
+
+static void AddBrushSidesLump( FILE *file, ibspHeader_t *header )
+{
+       int                             i, size;
+       bspBrushSide_t  *in;
+       ibspBrushSide_t *buffer, *out;
+       
+       
+       /* allocate output buffer */
+       size = numBSPBrushSides * sizeof( *buffer );
+       buffer = safe_malloc( size );
+       memset( buffer, 0, size );
+       
+       /* convert */
+       in = bspBrushSides;
+       out = buffer;
+       for( i = 0; i < numBSPBrushSides; i++ )
+       {
+               out->planeNum = in->planeNum;
+               out->shaderNum = in->shaderNum;
+               in++;
+               out++;
+       }
+       
+       /* write lump */
+       AddLump( file, (bspHeader_t*) header, LUMP_BRUSHSIDES, buffer, size );
+       
+       /* free buffer */
+       free( buffer );
+}
+
+
+
+/* drawsurfaces */
+typedef struct ibspDrawSurface_s
+{
+       int                     shaderNum;
+       int                     fogNum;
+       int                     surfaceType;
+       
+       int                     firstVert;
+       int                     numVerts;
+       
+       int                     firstIndex;
+       int                     numIndexes;
+       
+       int                     lightmapNum;
+       int                     lightmapX, lightmapY;
+       int                     lightmapWidth, lightmapHeight;
+       
+       vec3_t          lightmapOrigin;
+       vec3_t          lightmapVecs[ 3 ];
+       
+       int                     patchWidth;
+       int                     patchHeight;
+}
+ibspDrawSurface_t;
+
+
+static void CopyDrawSurfacesLump( ibspHeader_t *header )
+{
+       int                                     i, j;
+       ibspDrawSurface_t       *in;
+       bspDrawSurface_t        *out;
+       
+       
+       /* get count */
+       numBSPDrawSurfaces = GetLumpElements( (bspHeader_t*) header, LUMP_SURFACES, sizeof( *in ) );
+       SetDrawSurfaces( numBSPDrawSurfaces );
+       
+       /* copy */
+       in = GetLump( (bspHeader_t*) header, LUMP_SURFACES );
+       out = bspDrawSurfaces;
+       for( i = 0; i < numBSPDrawSurfaces; i++ )
+       {
+               out->shaderNum = in->shaderNum;
+               out->fogNum = in->fogNum;
+               out->surfaceType = in->surfaceType;
+               out->firstVert = in->firstVert;
+               out->numVerts = in->numVerts;
+               out->firstIndex = in->firstIndex;
+               out->numIndexes = in->numIndexes;
+               
+               out->lightmapStyles[ 0 ] = LS_NORMAL;
+               out->vertexStyles[ 0 ] = LS_NORMAL;
+               out->lightmapNum[ 0 ] = in->lightmapNum;
+               out->lightmapX[ 0 ] = in->lightmapX;
+               out->lightmapY[ 0 ] = in->lightmapY;
+               
+               for( j = 1; j < MAX_LIGHTMAPS; j++ )
+               {
+                       out->lightmapStyles[ j ] = LS_NONE;
+                       out->vertexStyles[ j ] = LS_NONE;
+                       out->lightmapNum[ j ] = -3;
+                       out->lightmapX[ j ] = 0;
+                       out->lightmapY[ j ] = 0;
+               }
+               
+               out->lightmapWidth = in->lightmapWidth;
+               out->lightmapHeight = in->lightmapHeight;
+               
+               VectorCopy( in->lightmapOrigin, out->lightmapOrigin );
+               VectorCopy( in->lightmapVecs[ 0 ], out->lightmapVecs[ 0 ] );
+               VectorCopy( in->lightmapVecs[ 1 ], out->lightmapVecs[ 1 ] );
+               VectorCopy( in->lightmapVecs[ 2 ], out->lightmapVecs[ 2 ] );
+               
+               out->patchWidth = in->patchWidth;
+               out->patchHeight = in->patchHeight;
+               
+               in++;
+               out++;
+       }
+}
+
+
+static void AddDrawSurfacesLump( FILE *file, ibspHeader_t *header )
+{
+       int                                     i, size;
+       bspDrawSurface_t        *in;
+       ibspDrawSurface_t       *buffer, *out;
+       
+       
+       /* allocate output buffer */
+       size = numBSPDrawSurfaces * sizeof( *buffer );
+       buffer = safe_malloc( size );
+       memset( buffer, 0, size );
+       
+       /* convert */
+       in = bspDrawSurfaces;
+       out = buffer;
+       for( i = 0; i < numBSPDrawSurfaces; i++ )
+       {
+               out->shaderNum = in->shaderNum;
+               out->fogNum = in->fogNum;
+               out->surfaceType = in->surfaceType;
+               out->firstVert = in->firstVert;
+               out->numVerts = in->numVerts;
+               out->firstIndex = in->firstIndex;
+               out->numIndexes = in->numIndexes;
+               
+               out->lightmapNum = in->lightmapNum[ 0 ];
+               out->lightmapX = in->lightmapX[ 0 ];
+               out->lightmapY = in->lightmapY[ 0 ];
+               out->lightmapWidth = in->lightmapWidth;
+               out->lightmapHeight = in->lightmapHeight;
+               
+               VectorCopy( in->lightmapOrigin, out->lightmapOrigin );
+               VectorCopy( in->lightmapVecs[ 0 ], out->lightmapVecs[ 0 ] );
+               VectorCopy( in->lightmapVecs[ 1 ], out->lightmapVecs[ 1 ] );
+               VectorCopy( in->lightmapVecs[ 2 ], out->lightmapVecs[ 2 ] );
+               
+               out->patchWidth = in->patchWidth;
+               out->patchHeight = in->patchHeight;
+               
+               in++;
+               out++;
+       }
+       
+       /* write lump */
+       AddLump( file, (bspHeader_t*) header, LUMP_SURFACES, buffer, size );
+       
+       /* free buffer */
+       free( buffer );
+}
+
+
+
+/* drawverts */
+typedef struct
+{
+       vec3_t          xyz;
+       float           st[ 2 ];
+       float           lightmap[ 2 ];
+       vec3_t          normal;
+       byte            color[ 4 ];
+}
+ibspDrawVert_t;
+
+
+static void CopyDrawVertsLump( ibspHeader_t *header )
+{
+       int                             i;
+       ibspDrawVert_t  *in;
+       bspDrawVert_t   *out;
+       
+       
+       /* get count */
+       numBSPDrawVerts = GetLumpElements( (bspHeader_t*) header, LUMP_DRAWVERTS, sizeof( *in ) );
+       SetDrawVerts( numBSPDrawVerts );
+       
+       /* copy */
+       in = GetLump( (bspHeader_t*) header, LUMP_DRAWVERTS );
+       out = bspDrawVerts;
+       for( i = 0; i < numBSPDrawVerts; i++ )
+       {
+               VectorCopy( in->xyz, out->xyz );
+               out->st[ 0 ] = in->st[ 0 ];
+               out->st[ 1 ] = in->st[ 1 ];
+               
+               out->lightmap[ 0 ][ 0 ] = in->lightmap[ 0 ];
+               out->lightmap[ 0 ][ 1 ] = in->lightmap[ 1 ];
+               
+               VectorCopy( in->normal, out->normal );
+               
+               out->color[ 0 ][ 0 ] = in->color[ 0 ];
+               out->color[ 0 ][ 1 ] = in->color[ 1 ];
+               out->color[ 0 ][ 2 ] = in->color[ 2 ];
+               out->color[ 0 ][ 3 ] = in->color[ 3 ];
+               
+               in++;
+               out++;
+       }
+}
+
+
+static void AddDrawVertsLump( FILE *file, ibspHeader_t *header )
+{
+       int                             i, size;
+       bspDrawVert_t   *in;
+       ibspDrawVert_t  *buffer, *out;
+       
+       
+       /* allocate output buffer */
+       size = numBSPDrawVerts * sizeof( *buffer );
+       buffer = safe_malloc( size );
+       memset( buffer, 0, size );
+       
+       /* convert */
+       in = bspDrawVerts;
+       out = buffer;
+       for( i = 0; i < numBSPDrawVerts; i++ )
+       {
+               VectorCopy( in->xyz, out->xyz );
+               out->st[ 0 ] = in->st[ 0 ];
+               out->st[ 1 ] = in->st[ 1 ];
+               
+               out->lightmap[ 0 ] = in->lightmap[ 0 ][ 0 ];
+               out->lightmap[ 1 ] = in->lightmap[ 0 ][ 1 ];
+               
+               VectorCopy( in->normal, out->normal );
+               
+               out->color[ 0 ] = in->color[ 0 ][ 0 ];
+               out->color[ 1 ] = in->color[ 0 ][ 1 ];
+               out->color[ 2 ] = in->color[ 0 ][ 2 ];
+               out->color[ 3 ] = in->color[ 0 ][ 3 ];
+               
+               in++;
+               out++;
+       }
+       
+       /* write lump */
+       AddLump( file, (bspHeader_t*) header, LUMP_DRAWVERTS, buffer, size );
+       
+       /* free buffer */
+       free( buffer );
+}
+
+
+
+/* light grid */
+typedef struct
+{
+       byte            ambient[ 3 ];
+       byte            directed[ 3 ];
+       byte            latLong[ 2 ];
+}
+ibspGridPoint_t;
+
+
+static void CopyLightGridLumps( ibspHeader_t *header )
+{
+       int                             i, j;
+       ibspGridPoint_t *in;
+       bspGridPoint_t  *out;
+       
+       
+       /* get count */
+       numBSPGridPoints = GetLumpElements( (bspHeader_t*) header, LUMP_LIGHTGRID, sizeof( *in ) );
+       
+       /* allocate buffer */
+       bspGridPoints = safe_malloc( numBSPGridPoints * sizeof( *bspGridPoints ) );
+       memset( bspGridPoints, 0, numBSPGridPoints * sizeof( *bspGridPoints ) );
+       
+       /* copy */
+       in = GetLump( (bspHeader_t*) header, LUMP_LIGHTGRID );
+       out = bspGridPoints;
+       for( i = 0; i < numBSPGridPoints; i++ )
+       {
+               for( j = 0; j < MAX_LIGHTMAPS; j++ )
+               {
+                       VectorCopy( in->ambient, out->ambient[ j ] );
+                       VectorCopy( in->directed, out->directed[ j ] );
+                       out->styles[ j ] = LS_NONE;
+               }
+               
+               out->styles[ 0 ] = LS_NORMAL;
+               
+               out->latLong[ 0 ] = in->latLong[ 0 ];
+               out->latLong[ 1 ] = in->latLong[ 1 ];
+               
+               in++;
+               out++;
+       }
+}
+
+
+static void AddLightGridLumps( FILE *file, ibspHeader_t *header )
+{
+       int                             i;
+       bspGridPoint_t  *in;
+       ibspGridPoint_t *buffer, *out;
+       
+       
+       /* dummy check */
+       if( bspGridPoints == NULL )
+               return;
+       
+       /* allocate temporary buffer */
+       buffer = safe_malloc( numBSPGridPoints * sizeof( *out ) );
+       
+       /* convert */
+       in = bspGridPoints;
+       out = buffer;
+       for( i = 0; i < numBSPGridPoints; i++ )
+       {
+               VectorCopy( in->ambient[ 0 ], out->ambient );
+               VectorCopy( in->directed[ 0 ], out->directed );
+               
+               out->latLong[ 0 ] = in->latLong[ 0 ];
+               out->latLong[ 1 ] = in->latLong[ 1 ];
+               
+               in++;
+               out++;
+       }
+       
+       /* write lumps */
+       AddLump( file, (bspHeader_t*) header, LUMP_LIGHTGRID, buffer, (numBSPGridPoints * sizeof( *out )) );
+       
+       /* free buffer (ydnar 2002-10-22: [bug 641] thanks Rap70r! */
+       free( buffer );
+}
+
+/*
+LoadIBSPFile()
+loads a quake 3 bsp file into memory
+*/
+
+void LoadIBSPFile( const char *filename )
+{
+       ibspHeader_t    *header;
+       
+       
+       /* load the file header */
+       LoadFile( filename, (void**) &header );
+
+       /* swap the header (except the first 4 bytes) */
+       SwapBlock( (int*) ((byte*) header + sizeof( int )), sizeof( *header ) - sizeof( int ) );
+       
+       /* make sure it matches the format we're trying to load */
+       if( force == qfalse && *((int*) header->ident) != *((int*) game->bspIdent) )
+               Error( "%s is not a %s file", filename, game->bspIdent );
+       if( force == qfalse && header->version != game->bspVersion )
+               Error( "%s is version %d, not %d", filename, header->version, game->bspVersion );
+       
+       /* load/convert lumps */
+       numBSPShaders = CopyLump( (bspHeader_t*) header, LUMP_SHADERS, bspShaders, sizeof( bspShader_t ) );
+       
+       numBSPModels = CopyLump( (bspHeader_t*) header, LUMP_MODELS, bspModels, sizeof( bspModel_t ) );
+       
+       numBSPPlanes = CopyLump( (bspHeader_t*) header, LUMP_PLANES, bspPlanes, sizeof( bspPlane_t ) );
+       
+       numBSPLeafs = CopyLump( (bspHeader_t*) header, LUMP_LEAFS, bspLeafs, sizeof( bspLeaf_t ) );
+       
+       numBSPNodes = CopyLump( (bspHeader_t*) header, LUMP_NODES, bspNodes, sizeof( bspNode_t ) );
+       
+       numBSPLeafSurfaces = CopyLump( (bspHeader_t*) header, LUMP_LEAFSURFACES, bspLeafSurfaces, sizeof( bspLeafSurfaces[ 0 ] ) );
+       
+       numBSPLeafBrushes = CopyLump( (bspHeader_t*) header, LUMP_LEAFBRUSHES, bspLeafBrushes, sizeof( bspLeafBrushes[ 0 ] ) );
+       
+       numBSPBrushes = CopyLump( (bspHeader_t*) header, LUMP_BRUSHES, bspBrushes, sizeof( bspBrush_t ) );
+       
+       CopyBrushSidesLump( header );
+
+       CopyDrawVertsLump( header );
+       
+       CopyDrawSurfacesLump( header );
+       
+       numBSPFogs = CopyLump( (bspHeader_t*) header, LUMP_FOGS, bspFogs, sizeof( bspFog_t ) );
+       
+       numBSPDrawIndexes = CopyLump( (bspHeader_t*) header, LUMP_DRAWINDEXES, bspDrawIndexes, sizeof( bspDrawIndexes[ 0 ] ) );
+       
+       numBSPVisBytes = CopyLump( (bspHeader_t*) header, LUMP_VISIBILITY, bspVisBytes, 1 );
+       
+       numBSPLightBytes = GetLumpElements( (bspHeader_t*) header, LUMP_LIGHTMAPS, 1 );
+               bspLightBytes = safe_malloc( numBSPLightBytes );
+               CopyLump( (bspHeader_t*) header, LUMP_LIGHTMAPS, bspLightBytes, 1 );
+       
+       bspEntDataSize = CopyLump( (bspHeader_t*) header, LUMP_ENTITIES, bspEntData, 1);
+       
+       CopyLightGridLumps( header );
+
+       /* advertisements */
+       numBSPAds = CopyLump( (bspHeader_t*) header, LUMP_ADVERTISEMENTS, bspAds, sizeof( bspAdvertisement_t ) );
+
+       /* free the file buffer */
+       free( header );
+}
+
+
+
+/*
+WriteIBSPFile()
+writes an id bsp file
+*/
+
+void WriteIBSPFile( const char *filename )
+{              
+       ibspHeader_t    outheader, *header;
+       FILE                    *file;
+       time_t                  t;
+       char                    marker[ 1024 ];
+       int                             size;
+       
+       
+       /* set header */
+       header = &outheader;
+       memset( header, 0, sizeof( *header ) );
+       
+       //%     Swapfile();
+       
+       /* set up header */
+       *((int*) (bspHeader_t*) header->ident) = *((int*) game->bspIdent);
+       header->version = LittleLong( game->bspVersion );
+       
+       /* write initial header */
+       file = SafeOpenWrite( filename );
+       SafeWrite( file, (bspHeader_t*) header, sizeof( *header ) );    /* overwritten later */
+       
+       /* add marker lump */
+       time( &t );
+       sprintf( marker, "I LOVE MY Q3MAP2 %s on %s)", Q3MAP_VERSION, asctime( localtime( &t ) ) );
+       AddLump( file, (bspHeader_t*) header, 0, marker, strlen( marker ) + 1 );
+       
+       /* add lumps */
+       AddLump( file, (bspHeader_t*) header, LUMP_SHADERS, bspShaders, numBSPShaders * sizeof( bspShader_t ) );
+       AddLump( file, (bspHeader_t*) header, LUMP_PLANES, bspPlanes, numBSPPlanes * sizeof( bspPlane_t ) );
+       AddLump( file, (bspHeader_t*) header, LUMP_LEAFS, bspLeafs, numBSPLeafs * sizeof( bspLeaf_t ) );
+       AddLump( file, (bspHeader_t*) header, LUMP_NODES, bspNodes, numBSPNodes * sizeof( bspNode_t ) );
+       AddLump( file, (bspHeader_t*) header, LUMP_BRUSHES, bspBrushes, numBSPBrushes*sizeof( bspBrush_t ) );
+       AddBrushSidesLump( file, header );
+       AddLump( file, (bspHeader_t*) header, LUMP_LEAFSURFACES, bspLeafSurfaces, numBSPLeafSurfaces * sizeof( bspLeafSurfaces[ 0 ] ) );
+       AddLump( file, (bspHeader_t*) header, LUMP_LEAFBRUSHES, bspLeafBrushes, numBSPLeafBrushes * sizeof( bspLeafBrushes[ 0 ] ) );
+       AddLump( file, (bspHeader_t*) header, LUMP_MODELS, bspModels, numBSPModels * sizeof( bspModel_t ) );
+       AddDrawVertsLump( file, header );
+       AddDrawSurfacesLump( file, header );
+       AddLump( file, (bspHeader_t*) header, LUMP_VISIBILITY, bspVisBytes, numBSPVisBytes );
+       AddLump( file, (bspHeader_t*) header, LUMP_LIGHTMAPS, bspLightBytes, numBSPLightBytes );
+       AddLightGridLumps( file, header );
+       AddLump( file, (bspHeader_t*) header, LUMP_ENTITIES, bspEntData, bspEntDataSize );
+       AddLump( file, (bspHeader_t*) header, LUMP_FOGS, bspFogs, numBSPFogs * sizeof( bspFog_t ) );
+       AddLump( file, (bspHeader_t*) header, LUMP_DRAWINDEXES, bspDrawIndexes, numBSPDrawIndexes * sizeof( bspDrawIndexes[ 0 ] ) );
+
+       /* advertisements */
+       AddLump( file, (bspHeader_t*) header, LUMP_ADVERTISEMENTS, bspAds, numBSPAds * sizeof( bspAdvertisement_t ) );
+
+       /* emit bsp size */
+       size = ftell( file );
+       Sys_Printf( "Wrote %.1f MB (%d bytes)\n", (float) size / (1024 * 1024), size );
+       
+       /* write the completed header */
+       fseek( file, 0, SEEK_SET );
+       SafeWrite( file, header, sizeof( *header ) );
+       
+       /* close the file */
+       fclose( file ); 
+}