-/*\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 );
+}