]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - tools/quake3/q3map2/bspfile_rbsp.c
Merge branch 'master' into divVerent/farplanedist-sky-fix
[xonotic/netradiant.git] / tools / quake3 / q3map2 / bspfile_rbsp.c
index 2e09510c9566c2c684c5ae4c79a4eca9474d79a1..b1ff0304dde7dd4888c53e77b6ae5df054cc12d6 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_RBSP_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 LUMP_LIGHTARRAY                17\r
-#define        HEADER_LUMPS            18\r
-\r
-\r
-/* types */\r
-typedef struct\r
-{\r
-       char            ident[ 4 ];\r
-       int                     version;\r
-       \r
-       bspLump_t       lumps[ HEADER_LUMPS ];\r
-}\r
-rbspHeader_t;\r
-\r
-\r
-\r
-/* light grid */\r
-#define MAX_MAP_GRID           0xffff\r
-#define MAX_MAP_GRIDARRAY      0x100000\r
-#define LG_EPSILON                     4\r
-\r
-\r
-static void CopyLightGridLumps( rbspHeader_t *header )\r
-{\r
-       int                             i;\r
-       unsigned short  *inArray;\r
-       bspGridPoint_t  *in, *out;\r
-       \r
-       \r
-       /* get count */\r
-       numBSPGridPoints = GetLumpElements( (bspHeader_t*) header, LUMP_LIGHTARRAY, sizeof( *inArray ) );\r
-       \r
-       /* allocate buffer */\r
-       bspGridPoints = safe_malloc( numBSPGridPoints * sizeof( *bspGridPoints ) );\r
-       memset( bspGridPoints, 0, numBSPGridPoints * sizeof( *bspGridPoints ) );\r
-       \r
-       /* copy */\r
-       inArray = GetLump( (bspHeader_t*) header, LUMP_LIGHTARRAY );\r
-       in = GetLump( (bspHeader_t*) header, LUMP_LIGHTGRID );\r
-       out = bspGridPoints;\r
-       for( i = 0; i < numBSPGridPoints; i++ )\r
-       {\r
-               memcpy( out, &in[ *inArray ], sizeof( *in ) );\r
-               inArray++;\r
-               out++;\r
-       }\r
-}\r
-\r
-\r
-static void AddLightGridLumps( FILE *file, rbspHeader_t *header )\r
-{\r
-       int                             i, j, k, c, d;\r
-       int                             numGridPoints, maxGridPoints;\r
-       bspGridPoint_t  *gridPoints, *in, *out;\r
-       int                             numGridArray;\r
-       unsigned short  *gridArray;\r
-       qboolean                bad;\r
-       \r
-       \r
-       /* allocate temporary buffers */\r
-       maxGridPoints = (numBSPGridPoints < MAX_MAP_GRID) ? numBSPGridPoints : MAX_MAP_GRID;\r
-       gridPoints = safe_malloc( maxGridPoints * sizeof( *gridPoints ) );\r
-       gridArray = safe_malloc( numBSPGridPoints * sizeof( *gridArray ) );\r
-       \r
-       /* zero out */\r
-       numGridPoints = 0;\r
-       numGridArray = numBSPGridPoints;\r
-       \r
-       /* for each bsp grid point, find an approximate twin */\r
-       Sys_Printf( "Storing lightgrid: %d points\n", numBSPGridPoints );\r
-       for( i = 0; i < numGridArray; i++ )\r
-       {\r
-               /* get points */\r
-               in = &bspGridPoints[ i ];\r
-               \r
-               /* walk existing list */\r
-               for( j = 0; j < numGridPoints; j++ )\r
-               {\r
-                       /* get point */\r
-                       out = &gridPoints[ j ];\r
-                       \r
-                       /* compare styles */\r
-                       if( *((unsigned int*) in->styles) != *((unsigned int*) out->styles) )\r
-                               continue;\r
-                       \r
-                       /* compare direction */\r
-                       d = abs( in->latLong[ 0 ] - out->latLong[ 0 ] );\r
-                       if( d < (255 - LG_EPSILON) && d > LG_EPSILON )\r
-                               continue;\r
-                       d = abs( in->latLong[ 1 ] - out->latLong[ 1 ] );\r
-                       if( d < 255 - LG_EPSILON && d > LG_EPSILON )\r
-                               continue;\r
-                       \r
-                       /* compare light */\r
-                       bad = qfalse;\r
-                       for( k = 0; (k < MAX_LIGHTMAPS && bad == qfalse); k++ )\r
-                       {\r
-                               for( c = 0; c < 3; c++ )\r
-                               {\r
-                                       if( abs( (int) in->ambient[ k ][ c ] - (int) out->ambient[ k ][ c ]) > LG_EPSILON ||\r
-                                               abs( (int) in->directed[ k ][ c ] - (int) out->directed[ k ][ c ]) > LG_EPSILON )\r
-                                       {\r
-                                               bad = qtrue;\r
-                                               break;\r
-                                       }\r
-                               }\r
-                       }\r
-                       \r
-                       /* failure */\r
-                       if( bad )\r
-                               continue;\r
-                       \r
-                       /* this sample is ok */\r
-                       break;\r
-               }\r
-               \r
-               /* set sample index */\r
-               gridArray[ i ] = (unsigned short) j;\r
-               \r
-               /* if no sample found, add a new one */\r
-               if( j >= numGridPoints && numGridPoints < maxGridPoints )\r
-               {\r
-                       out = &gridPoints[ numGridPoints++ ];\r
-                       memcpy( out, in, sizeof( *in ) );\r
-               }\r
-       }\r
-       \r
-       /* swap array */\r
-       for( i = 0; i < numGridArray; i++ )\r
-               gridArray[ i ] = LittleShort( gridArray[ i ] );\r
-       \r
-       /* write lumps */\r
-       AddLump( file, (bspHeader_t*) header, LUMP_LIGHTGRID, gridPoints, (numGridPoints * sizeof( *gridPoints )) );\r
-       AddLump( file, (bspHeader_t*) header, LUMP_LIGHTARRAY, gridArray, (numGridArray * sizeof( *gridArray )) );\r
-       \r
-       /* free buffers */\r
-       free( gridPoints );\r
-       free( gridArray );\r
-}\r
-\r
-\r
-\r
-/*\r
-LoadRBSPFile()\r
-loads a raven bsp file into memory\r
-*/\r
-\r
-void LoadRBSPFile( const char *filename )\r
-{\r
-       rbspHeader_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
-       numBSPBrushSides = CopyLump( (bspHeader_t*) header, LUMP_BRUSHSIDES, bspBrushSides, sizeof( bspBrushSide_t ) );\r
-       \r
-       numBSPDrawVerts = GetLumpElements( (bspHeader_t*) header, LUMP_DRAWVERTS, sizeof( bspDrawVerts[ 0 ] ) );\r
-               SetDrawVerts( numBSPDrawVerts );\r
-               CopyLump( (bspHeader_t*) header, LUMP_DRAWVERTS, bspDrawVerts, sizeof( bspDrawVerts[ 0 ] ) );\r
-       \r
-       numBSPDrawSurfaces = GetLumpElements( (bspHeader_t*) header, LUMP_SURFACES, sizeof( bspDrawSurfaces[ 0 ] ) );\r
-               SetDrawSurfaces( numBSPDrawSurfaces );\r
-               CopyLump( (bspHeader_t*) header, LUMP_SURFACES, bspDrawSurfaces, sizeof( bspDrawSurfaces[ 0 ] ) );\r
-       \r
-       numBSPFogs = CopyLump( (bspHeader_t*) header, LUMP_FOGS, bspFogs, sizeof( bspFogs[ 0 ] ) );\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
-WriteRBSPFile()\r
-writes a raven bsp file\r
-*/\r
-\r
-void WriteRBSPFile( const char *filename )\r
-{              \r
-       rbspHeader_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
-       AddLump( file, (bspHeader_t*) header, LUMP_BRUSHSIDES, bspBrushSides, numBSPBrushSides * sizeof( bspBrushSides[ 0 ] ) );\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
-       AddLump( file, (bspHeader_t*) header, LUMP_DRAWVERTS, bspDrawVerts, numBSPDrawVerts * sizeof( bspDrawVerts[ 0 ] ) );\r
-       AddLump( file, (bspHeader_t*) header, LUMP_SURFACES, bspDrawSurfaces, numBSPDrawSurfaces * sizeof( bspDrawSurfaces[ 0 ] ) );\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_RBSP_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_LIGHTARRAY     17
+#define HEADER_LUMPS        18
+
+
+/* types */
+typedef struct
+{
+       char ident[ 4 ];
+       int version;
+
+       bspLump_t lumps[ HEADER_LUMPS ];
+}
+rbspHeader_t;
+
+
+
+/* light grid */
+#define MAX_MAP_GRID        0xffff
+#define MAX_MAP_GRIDARRAY   0x100000
+#define LG_EPSILON          4
+
+
+static void CopyLightGridLumps( rbspHeader_t *header ){
+       int i;
+       unsigned short  *inArray;
+       bspGridPoint_t  *in, *out;
+
+
+       /* get count */
+       numBSPGridPoints = GetLumpElements( (bspHeader_t*) header, LUMP_LIGHTARRAY, sizeof( *inArray ) );
+
+       /* allocate buffer */
+       bspGridPoints = safe_malloc( numBSPGridPoints * sizeof( *bspGridPoints ) );
+       memset( bspGridPoints, 0, numBSPGridPoints * sizeof( *bspGridPoints ) );
+
+       /* copy */
+       inArray = GetLump( (bspHeader_t*) header, LUMP_LIGHTARRAY );
+       in = GetLump( (bspHeader_t*) header, LUMP_LIGHTGRID );
+       out = bspGridPoints;
+       for ( i = 0; i < numBSPGridPoints; i++ )
+       {
+               memcpy( out, &in[ *inArray ], sizeof( *in ) );
+               inArray++;
+               out++;
+       }
+}
+
+
+static void AddLightGridLumps( FILE *file, rbspHeader_t *header ){
+       int i, j, k, c, d;
+       int numGridPoints, maxGridPoints;
+       bspGridPoint_t  *gridPoints, *in, *out;
+       int numGridArray;
+       unsigned short  *gridArray;
+       qboolean bad;
+
+
+       /* allocate temporary buffers */
+       maxGridPoints = ( numBSPGridPoints < MAX_MAP_GRID ) ? numBSPGridPoints : MAX_MAP_GRID;
+       gridPoints = safe_malloc( maxGridPoints * sizeof( *gridPoints ) );
+       gridArray = safe_malloc( numBSPGridPoints * sizeof( *gridArray ) );
+
+       /* zero out */
+       numGridPoints = 0;
+       numGridArray = numBSPGridPoints;
+
+       /* for each bsp grid point, find an approximate twin */
+       Sys_Printf( "Storing lightgrid: %d points\n", numBSPGridPoints );
+       for ( i = 0; i < numGridArray; i++ )
+       {
+               /* get points */
+               in = &bspGridPoints[ i ];
+
+               /* walk existing list */
+               for ( j = 0; j < numGridPoints; j++ )
+               {
+                       /* get point */
+                       out = &gridPoints[ j ];
+
+                       /* compare styles */
+                       if ( memcmp( in->styles, out->styles, MAX_LIGHTMAPS ) ) {
+                               continue;
+                       }
+
+                       /* compare direction */
+                       d = abs( in->latLong[ 0 ] - out->latLong[ 0 ] );
+                       if ( d < ( 255 - LG_EPSILON ) && d > LG_EPSILON ) {
+                               continue;
+                       }
+                       d = abs( in->latLong[ 1 ] - out->latLong[ 1 ] );
+                       if ( d < 255 - LG_EPSILON && d > LG_EPSILON ) {
+                               continue;
+                       }
+
+                       /* compare light */
+                       bad = qfalse;
+                       for ( k = 0; ( k < MAX_LIGHTMAPS && bad == qfalse ); k++ )
+                       {
+                               for ( c = 0; c < 3; c++ )
+                               {
+                                       if ( abs( (int) in->ambient[ k ][ c ] - (int) out->ambient[ k ][ c ] ) > LG_EPSILON ||
+                                                abs( (int) in->directed[ k ][ c ] - (int) out->directed[ k ][ c ] ) > LG_EPSILON ) {
+                                               bad = qtrue;
+                                               break;
+                                       }
+                               }
+                       }
+
+                       /* failure */
+                       if ( bad ) {
+                               continue;
+                       }
+
+                       /* this sample is ok */
+                       break;
+               }
+
+               /* set sample index */
+               gridArray[ i ] = (unsigned short) j;
+
+               /* if no sample found, add a new one */
+               if ( j >= numGridPoints && numGridPoints < maxGridPoints ) {
+                       out = &gridPoints[ numGridPoints++ ];
+                       memcpy( out, in, sizeof( *in ) );
+               }
+       }
+
+       /* swap array */
+       for ( i = 0; i < numGridArray; i++ )
+               gridArray[ i ] = LittleShort( gridArray[ i ] );
+
+       /* write lumps */
+       AddLump( file, (bspHeader_t*) header, LUMP_LIGHTGRID, gridPoints, ( numGridPoints * sizeof( *gridPoints ) ) );
+       AddLump( file, (bspHeader_t*) header, LUMP_LIGHTARRAY, gridArray, ( numGridArray * sizeof( *gridArray ) ) );
+
+       /* free buffers */
+       free( gridPoints );
+       free( gridArray );
+}
+
+
+
+/*
+   LoadRBSPFile()
+   loads a raven bsp file into memory
+ */
+
+void LoadRBSPFile( const char *filename ){
+       rbspHeader_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_Allocate( (bspHeader_t*) header, LUMP_SHADERS, (void **) &bspShaders, sizeof( bspShader_t ), &allocatedBSPShaders );
+
+       numBSPModels = CopyLump_Allocate( (bspHeader_t*) header, LUMP_MODELS, (void **) &bspModels, sizeof( bspModel_t ), &allocatedBSPModels );
+
+       numBSPPlanes = CopyLump_Allocate( (bspHeader_t*) header, LUMP_PLANES, (void **) &bspPlanes, sizeof( bspPlane_t ), &allocatedBSPPlanes );
+
+       numBSPLeafs = CopyLump( (bspHeader_t*) header, LUMP_LEAFS, bspLeafs, sizeof( bspLeaf_t ) );
+
+       numBSPNodes = CopyLump_Allocate( (bspHeader_t*) header, LUMP_NODES, (void **) &bspNodes, sizeof( bspNode_t ), &allocatedBSPNodes );
+
+       numBSPLeafSurfaces = CopyLump_Allocate( (bspHeader_t*) header, LUMP_LEAFSURFACES, (void **) &bspLeafSurfaces, sizeof( bspLeafSurfaces[ 0 ] ), &allocatedBSPLeafSurfaces );
+
+       numBSPLeafBrushes = CopyLump_Allocate( (bspHeader_t*) header, LUMP_LEAFBRUSHES, (void **) &bspLeafBrushes, sizeof( bspLeafBrushes[ 0 ] ), &allocatedBSPLeafBrushes );
+
+       numBSPBrushes = CopyLump_Allocate( (bspHeader_t*) header, LUMP_BRUSHES, (void **) &bspBrushes, sizeof( bspBrush_t ), &allocatedBSPLeafBrushes );
+
+       numBSPBrushSides = CopyLump_Allocate( (bspHeader_t*) header, LUMP_BRUSHSIDES, (void **) &bspBrushSides, sizeof( bspBrushSide_t ), &allocatedBSPBrushSides );
+
+       numBSPDrawVerts = GetLumpElements( (bspHeader_t*) header, LUMP_DRAWVERTS, sizeof( bspDrawVerts[ 0 ] ) );
+       SetDrawVerts( numBSPDrawVerts );
+       CopyLump( (bspHeader_t*) header, LUMP_DRAWVERTS, bspDrawVerts, sizeof( bspDrawVerts[ 0 ] ) );
+
+       numBSPDrawSurfaces = GetLumpElements( (bspHeader_t*) header, LUMP_SURFACES, sizeof( bspDrawSurfaces[ 0 ] ) );
+       SetDrawSurfaces( numBSPDrawSurfaces );
+       CopyLump( (bspHeader_t*) header, LUMP_SURFACES, bspDrawSurfaces, sizeof( bspDrawSurfaces[ 0 ] ) );
+
+       numBSPFogs = CopyLump( (bspHeader_t*) header, LUMP_FOGS, bspFogs, sizeof( bspFogs[ 0 ] ) );
+
+       numBSPDrawIndexes = CopyLump_Allocate( (bspHeader_t*) header, LUMP_DRAWINDEXES, (void **) &bspDrawIndexes, sizeof( bspDrawIndexes[ 0 ] ), &allocatedBSPDrawIndexes );
+
+       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_Allocate( (bspHeader_t*) header, LUMP_ENTITIES, (void **) &bspEntData, 1, &allocatedBSPEntData );
+
+       CopyLightGridLumps( header );
+
+       /* free the file buffer */
+       free( header );
+}
+
+
+
+/*
+   WriteRBSPFile()
+   writes a raven bsp file
+ */
+
+void WriteRBSPFile( const char *filename ){
+       rbspHeader_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 ) );
+       AddLump( file, (bspHeader_t*) header, LUMP_BRUSHSIDES, bspBrushSides, numBSPBrushSides * sizeof( bspBrushSides[ 0 ] ) );
+       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 ) );
+       AddLump( file, (bspHeader_t*) header, LUMP_DRAWVERTS, bspDrawVerts, numBSPDrawVerts * sizeof( bspDrawVerts[ 0 ] ) );
+       AddLump( file, (bspHeader_t*) header, LUMP_SURFACES, bspDrawSurfaces, numBSPDrawSurfaces * sizeof( bspDrawSurfaces[ 0 ] ) );
+       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 ] ) );
+
+       /* 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 );
+}