]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - tools/quake3/q3map2/bspfile_abstract.c
Fix FloodEntities origin-less check
[xonotic/netradiant.git] / tools / quake3 / q3map2 / bspfile_abstract.c
index ae2fec3091c7bb89916f85d12d03d3d485c6e371..cea3239af0a3bed3594b530c0a16820eff3a8a27 100644 (file)
@@ -1,29 +1,30 @@
-/*
-Copyright (C) 1999-2007 id Software, Inc. and contributors.
-For a list of contributors, see the accompanying CONTRIBUTORS file.
+/* -------------------------------------------------------------------------------
+
+   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.
+   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 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.
+   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
+   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."
+   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."
 
-------------------------------------------------------------------------------- */
+   ------------------------------------------------------------------------------- */
 
 
 
@@ -40,100 +41,98 @@ several games based on the Quake III Arena engine, in the form of "Q3Map2."
 
 /* -------------------------------------------------------------------------------
 
-this file was copied out of the common directory in order to not break
-compatibility with the q3map 1.x tree. it was moved out in order to support
-the raven bsp format (RBSP) used in soldier of fortune 2 and jedi knight 2.
+   this file was copied out of the common directory in order to not break
+   compatibility with the q3map 1.x tree. it was moved out in order to support
+   the raven bsp format (RBSP) used in soldier of fortune 2 and jedi knight 2.
 
-since each game has its own set of particular features, the data structures
-below no longer directly correspond to the binary format of a particular game.
+   since each game has its own set of particular features, the data structures
+   below no longer directly correspond to the binary format of a particular game.
 
-the translation will be done at bsp load/save time to keep any sort of
-special-case code messiness out of the rest of the program.
+   the translation will be done at bsp load/save time to keep any sort of
+   special-case code messiness out of the rest of the program.
 
-------------------------------------------------------------------------------- */
+   ------------------------------------------------------------------------------- */
 
 
 
 /* FIXME: remove the functions below that handle memory management of bsp file chunks */
 
 int numBSPDrawVertsBuffer = 0;
-void IncDrawVerts()
-{
+void IncDrawVerts(){
        numBSPDrawVerts++;
 
-       if(bspDrawVerts == 0)
-       {
-               numBSPDrawVertsBuffer = MAX_MAP_DRAW_VERTS / 37;
-               
-               bspDrawVerts = safe_malloc_info(sizeof(bspDrawVert_t) * numBSPDrawVertsBuffer, "IncDrawVerts");
+       if ( bspDrawVerts == 0 ) {
+               numBSPDrawVertsBuffer = 1024;
+
+               bspDrawVerts = safe_malloc_info( sizeof( bspDrawVert_t ) * numBSPDrawVertsBuffer, "IncDrawVerts" );
 
        }
-       else if(numBSPDrawVerts > numBSPDrawVertsBuffer)
-       {
+       else if ( numBSPDrawVerts > numBSPDrawVertsBuffer ) {
                numBSPDrawVertsBuffer *= 3; // multiply by 1.5
                numBSPDrawVertsBuffer /= 2;
 
-               if(numBSPDrawVertsBuffer > MAX_MAP_DRAW_VERTS)
-                       numBSPDrawVertsBuffer = MAX_MAP_DRAW_VERTS;
+               bspDrawVerts = realloc( bspDrawVerts, sizeof( bspDrawVert_t ) * numBSPDrawVertsBuffer );
 
-               bspDrawVerts = realloc(bspDrawVerts, sizeof(bspDrawVert_t) * numBSPDrawVertsBuffer);
-
-               if(!bspDrawVerts)
-                       Error( "realloc() failed (IncDrawVerts)");
+               if ( !bspDrawVerts ) {
+                       Error( "realloc() failed (IncDrawVerts)" );
+               }
        }
 
-       memset(bspDrawVerts + (numBSPDrawVerts - 1), 0, sizeof(bspDrawVert_t));
+       memset( bspDrawVerts + ( numBSPDrawVerts - 1 ), 0, sizeof( bspDrawVert_t ) );
 }
 
-void SetDrawVerts(int n)
-{
-       if(bspDrawVerts != 0)
-               free(bspDrawVerts);
+void SetDrawVerts( int n ){
+       if ( bspDrawVerts != 0 ) {
+               free( bspDrawVerts );
+       }
 
        numBSPDrawVerts = n;
        numBSPDrawVertsBuffer = numBSPDrawVerts;
 
-       bspDrawVerts = safe_malloc_info(sizeof(bspDrawVert_t) * numBSPDrawVertsBuffer, "IncDrawVerts");
+       bspDrawVerts = safe_malloc_info( sizeof( bspDrawVert_t ) * numBSPDrawVertsBuffer, "IncDrawVerts" );
 
-       memset(bspDrawVerts, 0, n * sizeof(bspDrawVert_t));
+       memset( bspDrawVerts, 0, n * sizeof( bspDrawVert_t ) );
 }
 
 int numBSPDrawSurfacesBuffer = 0;
-void SetDrawSurfacesBuffer()
-{
-       if(bspDrawSurfaces != 0)
-               free(bspDrawSurfaces);
+void SetDrawSurfacesBuffer(){
+       if ( bspDrawSurfaces != 0 ) {
+               free( bspDrawSurfaces );
+       }
 
        numBSPDrawSurfacesBuffer = MAX_MAP_DRAW_SURFS;
 
-       bspDrawSurfaces = safe_malloc_info(sizeof(bspDrawSurface_t) * numBSPDrawSurfacesBuffer, "IncDrawSurfaces");
+       bspDrawSurfaces = safe_malloc_info( sizeof( bspDrawSurface_t ) * numBSPDrawSurfacesBuffer, "IncDrawSurfaces" );
 
-       memset(bspDrawSurfaces, 0, MAX_MAP_DRAW_SURFS * sizeof(bspDrawVert_t));
+       memset( bspDrawSurfaces, 0, MAX_MAP_DRAW_SURFS * sizeof( bspDrawVert_t ) );
 }
 
-void SetDrawSurfaces(int n)
-{
-       if(bspDrawSurfaces != 0)
-               free(bspDrawSurfaces);
+void SetDrawSurfaces( int n ){
+       if ( bspDrawSurfaces != 0 ) {
+               free( bspDrawSurfaces );
+       }
 
        numBSPDrawSurfaces = n;
        numBSPDrawSurfacesBuffer = numBSPDrawSurfaces;
 
-       bspDrawSurfaces = safe_malloc_info(sizeof(bspDrawSurface_t) * numBSPDrawSurfacesBuffer, "IncDrawSurfaces");
+       bspDrawSurfaces = safe_malloc_info( sizeof( bspDrawSurface_t ) * numBSPDrawSurfacesBuffer, "IncDrawSurfaces" );
 
-       memset(bspDrawSurfaces, 0, n * sizeof(bspDrawVert_t));
+       memset( bspDrawSurfaces, 0, n * sizeof( bspDrawVert_t ) );
 }
 
-void BSPFilesCleanup()
-{
-       if(bspDrawVerts != 0)
-               free(bspDrawVerts);
-       if(bspDrawSurfaces != 0)
-               free(bspDrawSurfaces);
-       if(bspLightBytes != 0)
-               free(bspLightBytes);
-       if(bspGridPoints != 0)
-               free(bspGridPoints);
+void BSPFilesCleanup(){
+       if ( bspDrawVerts != 0 ) {
+               free( bspDrawVerts );
+       }
+       if ( bspDrawSurfaces != 0 ) {
+               free( bspDrawSurfaces );
+       }
+       if ( bspLightBytes != 0 ) {
+               free( bspLightBytes );
+       }
+       if ( bspGridPoints != 0 ) {
+               free( bspGridPoints );
+       }
 }
 
 
@@ -142,42 +141,41 @@ void BSPFilesCleanup()
 
 
 /*
-SwapBlock()
-if all values are 32 bits, this can be used to swap everything
-*/
-
-void SwapBlock( int *block, int size )
-{
-       int             i;
-       
-       
+   SwapBlock()
+   if all values are 32 bits, this can be used to swap everything
+ */
+
+void SwapBlock( int *block, int size ){
+       int i;
+
+
        /* dummy check */
-       if( block == NULL )
+       if ( block == NULL ) {
                return;
-       
+       }
+
        /* swap */
        size >>= 2;
-       for( i = 0; i < size; i++ )
+       for ( i = 0; i < size; i++ )
                block[ i ] = LittleLong( block[ i ] );
 }
 
 
 
 /*
-SwapBSPFile()
-byte swaps all data in the abstract bsp
-*/
-
-void SwapBSPFile( void )
-{
-       int             i, j;
-       
-       
+   SwapBSPFile()
+   byte swaps all data in the abstract bsp
+ */
+
+void SwapBSPFile( void ){
+       int i, j;
+
+
        /* models */
        SwapBlock( (int*) bspModels, numBSPModels * sizeof( bspModels[ 0 ] ) );
 
        /* shaders (don't swap the name) */
-       for( i = 0; i < numBSPShaders ; i++ )
+       for ( i = 0; i < numBSPShaders ; i++ )
        {
                bspShaders[ i ].contentFlags = LittleLong( bspShaders[ i ].contentFlags );
                bspShaders[ i ].surfaceFlags = LittleLong( bspShaders[ i ].surfaceFlags );
@@ -185,7 +183,7 @@ void SwapBSPFile( void )
 
        /* planes */
        SwapBlock( (int*) bspPlanes, numBSPPlanes * sizeof( bspPlanes[ 0 ] ) );
-       
+
        /* nodes */
        SwapBlock( (int*) bspNodes, numBSPNodes * sizeof( bspNodes[ 0 ] ) );
 
@@ -205,11 +203,11 @@ void SwapBSPFile( void )
        SwapBlock( (int*) bspBrushSides, numBSPBrushSides * sizeof( bspBrushSides[ 0 ] ) );
 
        // vis
-       ((int*) &bspVisBytes)[ 0 ] = LittleLong( ((int*) &bspVisBytes)[ 0 ] );
-       ((int*) &bspVisBytes)[ 1 ] = LittleLong( ((int*) &bspVisBytes)[ 1 ] );
+       ( (int*) &bspVisBytes )[ 0 ] = LittleLong( ( (int*) &bspVisBytes )[ 0 ] );
+       ( (int*) &bspVisBytes )[ 1 ] = LittleLong( ( (int*) &bspVisBytes )[ 1 ] );
 
        /* drawverts (don't swap colors) */
-       for( i = 0; i < numBSPDrawVerts; i++ )
+       for ( i = 0; i < numBSPDrawVerts; i++ )
        {
                bspDrawVerts[ i ].xyz[ 0 ] = LittleFloat( bspDrawVerts[ i ].xyz[ 0 ] );
                bspDrawVerts[ i ].xyz[ 1 ] = LittleFloat( bspDrawVerts[ i ].xyz[ 1 ] );
@@ -219,13 +217,13 @@ void SwapBSPFile( void )
                bspDrawVerts[ i ].normal[ 2 ] = LittleFloat( bspDrawVerts[ i ].normal[ 2 ] );
                bspDrawVerts[ i ].st[ 0 ] = LittleFloat( bspDrawVerts[ i ].st[ 0 ] );
                bspDrawVerts[ i ].st[ 1 ] = LittleFloat( bspDrawVerts[ i ].st[ 1 ] );
-               for( j = 0; j < MAX_LIGHTMAPS; j++ )
+               for ( j = 0; j < MAX_LIGHTMAPS; j++ )
                {
                        bspDrawVerts[ i ].lightmap[ j ][ 0 ] = LittleFloat( bspDrawVerts[ i ].lightmap[ j ][ 0 ] );
                        bspDrawVerts[ i ].lightmap[ j ][ 1 ] = LittleFloat( bspDrawVerts[ i ].lightmap[ j ][ 1 ] );
                }
        }
-       
+
        /* drawindexes */
        SwapBlock( (int*) bspDrawIndexes, numBSPDrawIndexes * sizeof( bspDrawIndexes[0] ) );
 
@@ -234,34 +232,50 @@ void SwapBSPFile( void )
        SwapBlock( (int*) bspDrawSurfaces, numBSPDrawSurfaces * sizeof( bspDrawSurfaces[ 0 ] ) );
 
        /* fogs */
-       for( i = 0; i < numBSPFogs; i++ )
+       for ( i = 0; i < numBSPFogs; i++ )
        {
                bspFogs[ i ].brushNum = LittleLong( bspFogs[ i ].brushNum );
                bspFogs[ i ].visibleSide = LittleLong( bspFogs[ i ].visibleSide );
        }
+
+       /* advertisements */
+       for ( i = 0; i < numBSPAds; i++ )
+       {
+               bspAds[ i ].cellId = LittleLong( bspAds[ i ].cellId );
+               bspAds[ i ].normal[ 0 ] = LittleFloat( bspAds[ i ].normal[ 0 ] );
+               bspAds[ i ].normal[ 1 ] = LittleFloat( bspAds[ i ].normal[ 1 ] );
+               bspAds[ i ].normal[ 2 ] = LittleFloat( bspAds[ i ].normal[ 2 ] );
+
+               for ( j = 0; j < 4; j++ )
+               {
+                       bspAds[ i ].rect[j][ 0 ] = LittleFloat( bspAds[ i ].rect[j][ 0 ] );
+                       bspAds[ i ].rect[j][ 1 ] = LittleFloat( bspAds[ i ].rect[j][ 1 ] );
+                       bspAds[ i ].rect[j][ 2 ] = LittleFloat( bspAds[ i ].rect[j][ 2 ] );
+               }
+
+               //bspAds[ i ].model[ MAX_QPATH ];
+       }
 }
 
 
 
 /*
-GetLumpElements()
-gets the number of elements in a bsp lump
-*/
+   GetLumpElements()
+   gets the number of elements in a bsp lump
+ */
 
-int GetLumpElements( bspHeader_t *header, int lump, int size )
-{
+int GetLumpElements( bspHeader_t *header, int lump, int size ){
        /* check for odd size */
-       if( header->lumps[ lump ].length % size )
-       {
-               if( force )
-               {
+       if ( header->lumps[ lump ].length % size ) {
+               if ( force ) {
                        Sys_Printf( "WARNING: GetLumpElements: odd lump size (%d) in lump %d\n", header->lumps[ lump ].length, lump );
                        return 0;
                }
-               else
+               else{
                        Error( "GetLumpElements: odd lump size (%d) in lump %d", header->lumps[ lump ].length, lump );
+               }
        }
-       
+
        /* return element count */
        return header->lumps[ lump ].length / size;
 }
@@ -269,84 +283,87 @@ int GetLumpElements( bspHeader_t *header, int lump, int size )
 
 
 /*
-GetLump()
-returns a pointer to the specified lump
-*/
+   GetLump()
+   returns a pointer to the specified lump
+ */
 
-void *GetLump( bspHeader_t *header, int lump )
-{
-       return (void*)( (byte*) header + header->lumps[ lump ].offset);
+void *GetLump( bspHeader_t *header, int lump ){
+       return (void*)( (byte*) header + header->lumps[ lump ].offset );
 }
 
 
 
 /*
-CopyLump()
-copies a bsp file lump into a destination buffer
-*/
-
-int CopyLump( bspHeader_t *header, int lump, void *dest, int size )
-{
-       int             length, offset;
-       
-       
+   CopyLump()
+   copies a bsp file lump into a destination buffer
+ */
+
+int CopyLump( bspHeader_t *header, int lump, void *dest, int size ){
+       int length, offset;
+
+
        /* get lump length and offset */
        length = header->lumps[ lump ].length;
        offset = header->lumps[ lump ].offset;
-       
+
        /* handle erroneous cases */
-       if( length == 0 )
+       if ( length == 0 ) {
                return 0;
-       if( length % size )
-       {
-               if( force )
-               {
+       }
+       if ( length % size ) {
+               if ( force ) {
                        Sys_Printf( "WARNING: CopyLump: odd lump size (%d) in lump %d\n", length, lump );
                        return 0;
                }
-               else
+               else{
                        Error( "CopyLump: odd lump size (%d) in lump %d", length, lump );
+               }
        }
-       
+
        /* copy block of memory and return */
        memcpy( dest, (byte*) header + offset, length );
        return length / size;
 }
 
+int CopyLump_Allocate( bspHeader_t *header, int lump, void **dest, int size, int *allocationVariable ){
+       /* get lump length and offset */
+       *allocationVariable = header->lumps[ lump ].length / size;
+       *dest = realloc( *dest, size * *allocationVariable );
+       return CopyLump( header, lump, *dest, size );
+}
 
 
 /*
-AddLump()
-adds a lump to an outgoing bsp file
-*/
-
-void AddLump( FILE *file, bspHeader_t *header, int lumpNum, const void *data, int length )
-{
-       bspLump_t       *lump;
-       
-       
+   AddLump()
+   adds a lump to an outgoing bsp file
+ */
+
+void AddLump( FILE *file, bspHeader_t *header, int lumpNum, const void *data, int length ){
+       bspLump_t   *lump;
+
+
        /* add lump to bsp file header */
        lump = &header->lumps[ lumpNum ];
        lump->offset = LittleLong( ftell( file ) );
        lump->length = LittleLong( length );
-       
+
        /* write lump to file */
-       SafeWrite( file, data, (length + 3) & ~3 );
+       SafeWrite( file, data, ( length + 3 ) & ~3 );
 }
 
 
 
 /*
-LoadBSPFile()
-loads a bsp file into memory
-*/
+   LoadBSPFile()
+   loads a bsp file into memory
+ */
 
-void LoadBSPFile( const char *filename )
-{
+void LoadBSPFile( const char *filename ){
        /* dummy check */
-       if( game == NULL || game->load == NULL )
+       if ( game == NULL || game->load == NULL ) {
                Error( "LoadBSPFile: unsupported BSP file format" );
-       
+       }
+
        /* load it, then byte swap the in-memory version */
        game->load( filename );
        SwapBSPFile();
@@ -355,29 +372,29 @@ void LoadBSPFile( const char *filename )
 
 
 /*
-WriteBSPFile()
-writes a bsp file
-*/
-
-void WriteBSPFile( const char *filename )
-{
-       char    tempname[ 1024 ];
-       time_t  tm;
-       
-       
+   WriteBSPFile()
+   writes a bsp file
+ */
+
+void WriteBSPFile( const char *filename ){
+       char tempname[ 1024 ];
+       time_t tm;
+
+
        /* dummy check */
-       if( game == NULL || game->write == NULL )
+       if ( game == NULL || game->write == NULL ) {
                Error( "WriteBSPFile: unsupported BSP file format" );
-       
+       }
+
        /* make fake temp name so existing bsp file isn't damaged in case write process fails */
        time( &tm );
        sprintf( tempname, "%s.%08X", filename, (int) tm );
-       
+
        /* byteswap, write the bsp, then swap back so it can be manipulated further */
        SwapBSPFile();
        game->write( tempname );
        SwapBSPFile();
-       
+
        /* replace existing bsp file */
        remove( filename );
        rename( tempname, filename );
@@ -386,83 +403,82 @@ void WriteBSPFile( const char *filename )
 
 
 /*
-PrintBSPFileSizes()
-dumps info about current file
-*/
+   PrintBSPFileSizes()
+   dumps info about current file
+ */
 
-void PrintBSPFileSizes( void )
-{
+void PrintBSPFileSizes( void ){
        /* parse entities first */
-       if( numEntities <= 0 )
+       if ( numEntities <= 0 ) {
                ParseEntities();
-       
+       }
+
        /* note that this is abstracted */
        Sys_Printf( "Abstracted BSP file components (*actual sizes may differ)\n" );
-       
+
        /* print various and sundry bits */
        Sys_Printf( "%9d models        %9d\n",
-               numBSPModels, (int) (numBSPModels * sizeof( bspModel_t )) );
+                               numBSPModels, (int) ( numBSPModels * sizeof( bspModel_t ) ) );
        Sys_Printf( "%9d shaders       %9d\n",
-               numBSPShaders, (int) (numBSPShaders * sizeof( bspShader_t )) );
+                               numBSPShaders, (int) ( numBSPShaders * sizeof( bspShader_t ) ) );
        Sys_Printf( "%9d brushes       %9d\n",
-               numBSPBrushes, (int) (numBSPBrushes * sizeof( bspBrush_t )) );
+                               numBSPBrushes, (int) ( numBSPBrushes * sizeof( bspBrush_t ) ) );
        Sys_Printf( "%9d brushsides    %9d *\n",
-               numBSPBrushSides, (int) (numBSPBrushSides * sizeof( bspBrushSide_t )) );
+                               numBSPBrushSides, (int) ( numBSPBrushSides * sizeof( bspBrushSide_t ) ) );
        Sys_Printf( "%9d fogs          %9d\n",
-               numBSPFogs, (int) (numBSPFogs * sizeof( bspFog_t ) ) );
+                               numBSPFogs, (int) ( numBSPFogs * sizeof( bspFog_t ) ) );
        Sys_Printf( "%9d planes        %9d\n",
-               numBSPPlanes, (int) (numBSPPlanes * sizeof( bspPlane_t )) );
+                               numBSPPlanes, (int) ( numBSPPlanes * sizeof( bspPlane_t ) ) );
        Sys_Printf( "%9d entdata       %9d\n",
-               numEntities, bspEntDataSize );
-       Sys_Printf( "\n");
-       
+                               numEntities, bspEntDataSize );
+       Sys_Printf( "\n" );
+
        Sys_Printf( "%9d nodes         %9d\n",
-               numBSPNodes, (int) (numBSPNodes * sizeof( bspNode_t)) );
+                               numBSPNodes, (int) ( numBSPNodes * sizeof( bspNode_t ) ) );
        Sys_Printf( "%9d leafs         %9d\n",
-               numBSPLeafs, (int) (numBSPLeafs * sizeof( bspLeaf_t )) );
+                               numBSPLeafs, (int) ( numBSPLeafs * sizeof( bspLeaf_t ) ) );
        Sys_Printf( "%9d leafsurfaces  %9d\n",
-               numBSPLeafSurfaces, (int) (numBSPLeafSurfaces * sizeof( *bspLeafSurfaces )) );
+                               numBSPLeafSurfaces, (int) ( numBSPLeafSurfaces * sizeof( *bspLeafSurfaces ) ) );
        Sys_Printf( "%9d leafbrushes   %9d\n",
-               numBSPLeafBrushes, (int) (numBSPLeafBrushes * sizeof( *bspLeafBrushes )) );
-       Sys_Printf( "\n");
-       
+                               numBSPLeafBrushes, (int) ( numBSPLeafBrushes * sizeof( *bspLeafBrushes ) ) );
+       Sys_Printf( "\n" );
+
        Sys_Printf( "%9d drawsurfaces  %9d *\n",
-               numBSPDrawSurfaces, (int) (numBSPDrawSurfaces * sizeof( *bspDrawSurfaces )) );
+                               numBSPDrawSurfaces, (int) ( numBSPDrawSurfaces * sizeof( *bspDrawSurfaces ) ) );
        Sys_Printf( "%9d drawverts     %9d *\n",
-               numBSPDrawVerts, (int) (numBSPDrawVerts * sizeof( *bspDrawVerts )) );
+                               numBSPDrawVerts, (int) ( numBSPDrawVerts * sizeof( *bspDrawVerts ) ) );
        Sys_Printf( "%9d drawindexes   %9d\n",
-               numBSPDrawIndexes, (int) (numBSPDrawIndexes * sizeof( *bspDrawIndexes )) );
-       Sys_Printf( "\n");
-       
+                               numBSPDrawIndexes, (int) ( numBSPDrawIndexes * sizeof( *bspDrawIndexes ) ) );
+       Sys_Printf( "\n" );
+
        Sys_Printf( "%9d lightmaps     %9d\n",
-               numBSPLightBytes / (LIGHTMAP_WIDTH * LIGHTMAP_HEIGHT * 3), numBSPLightBytes );
+                               numBSPLightBytes / ( game->lightmapSize * game->lightmapSize * 3 ), numBSPLightBytes );
        Sys_Printf( "%9d lightgrid     %9d *\n",
-               numBSPGridPoints, (int) (numBSPGridPoints * sizeof( *bspGridPoints )) );
+                               numBSPGridPoints, (int) ( numBSPGridPoints * sizeof( *bspGridPoints ) ) );
        Sys_Printf( "          visibility    %9d\n",
-               numBSPVisBytes );
+                               numBSPVisBytes );
 }
 
 
 
 /* -------------------------------------------------------------------------------
 
-entity data handling
+   entity data handling
 
-------------------------------------------------------------------------------- */
+   ------------------------------------------------------------------------------- */
 
 
 /*
-StripTrailing()
-strips low byte chars off the end of a string
-*/
-
-void StripTrailing( char *e )
-{
-       char    *s;
-       
-       
+   StripTrailing()
+   strips low byte chars off the end of a string
+ */
+
+void StripTrailing( char *e ){
+       char    *s;
+
+
        s = e + strlen( e ) - 1;
-       while( s >= e && *s <= 32 )
+       while ( s >= e && *s <= 32 )
        {
                *s = 0;
                s--;
@@ -472,35 +488,36 @@ void StripTrailing( char *e )
 
 
 /*
-ParseEpair()
-parses a single quoted "key" "value" pair into an epair struct
-*/
-
-epair_t *ParseEPair( void )
-{
-       epair_t         *e;
-       
-       
+   ParseEpair()
+   parses a single quoted "key" "value" pair into an epair struct
+ */
+
+epair_t *ParseEPair( void ){
+       epair_t     *e;
+
+
        /* allocate and clear new epair */
        e = safe_malloc( sizeof( epair_t ) );
        memset( e, 0, sizeof( epair_t ) );
-       
+
        /* handle key */
-       if( strlen( token ) >= (MAX_KEY - 1) )
+       if ( strlen( token ) >= ( MAX_KEY - 1 ) ) {
                Error( "ParseEPair: token too long" );
-       
+       }
+
        e->key = copystring( token );
        GetToken( qfalse );
-       
+
        /* handle value */
-       if( strlen( token ) >= MAX_VALUE - 1 )
+       if ( strlen( token ) >= MAX_VALUE - 1 ) {
                Error( "ParseEpar: token too long" );
+       }
        e->value = copystring( token );
-       
+
        /* strip trailing spaces that sometimes get accidentally added in the editor */
        StripTrailing( e->key );
        StripTrailing( e->value );
-       
+
        /* return it */
        return e;
 }
@@ -508,39 +525,42 @@ epair_t *ParseEPair( void )
 
 
 /*
-ParseEntity()
-parses an entity's epairs
-*/
-
-qboolean ParseEntity( void )
-{
-       epair_t         *e;
-       
-       
+   ParseEntity()
+   parses an entity's epairs
+ */
+
+qboolean ParseEntity( void ){
+       epair_t     *e;
+
+
        /* dummy check */
-       if( !GetToken( qtrue ) )
+       if ( !GetToken( qtrue ) ) {
                return qfalse;
-       if( strcmp( token, "{" ) )
+       }
+       if ( strcmp( token, "{" ) ) {
                Error( "ParseEntity: { not found" );
-       if( numEntities == MAX_MAP_ENTITIES )
-               Error( "numEntities == MAX_MAP_ENTITIES" );
-       
+       }
+       AUTOEXPAND_BY_REALLOC( entities, numEntities, allocatedEntities, 32 );
+
        /* create new entity */
        mapEnt = &entities[ numEntities ];
        numEntities++;
-       
+       memset( mapEnt, 0, sizeof( *mapEnt ) );
+
        /* parse */
-       while( 1 )
+       while ( 1 )
        {
-               if( !GetToken( qtrue ) )
+               if ( !GetToken( qtrue ) ) {
                        Error( "ParseEntity: EOF without closing brace" );
-               if( !EPAIR_STRCMP( token, "}" ) )
+               }
+               if ( !EPAIR_STRCMP( token, "}" ) ) {
                        break;
+               }
                e = ParseEPair();
                e->next = mapEnt->epairs;
                mapEnt->epairs = e;
        }
-       
+
        /* return to sender */
        return qtrue;
 }
@@ -548,87 +568,136 @@ qboolean ParseEntity( void )
 
 
 /*
-ParseEntities()
-parses the bsp entity data string into entities
-*/
+   ParseEntities()
+   parses the bsp entity data string into entities
+ */
 
-void ParseEntities( void )
-{
+void ParseEntities( void ){
        numEntities = 0;
        ParseFromMemory( bspEntData, bspEntDataSize );
-       while( ParseEntity() );
-       
+       while ( ParseEntity() ) ;
+
        /* ydnar: set number of bsp entities in case a map is loaded on top */
        numBSPEntities = numEntities;
 }
 
+/*
+ * must be called before UnparseEntities
+ */
+void InjectCommandLine( char **argv, int beginArgs, int endArgs ){
+       const char *previousCommandLine;
+       char newCommandLine[1024];
+       const char *inpos;
+       char *outpos = newCommandLine;
+       char *sentinel = newCommandLine + sizeof( newCommandLine ) - 1;
+       int i;
+
+       previousCommandLine = ValueForKey( &entities[0], "_q3map2_cmdline" );
+       if ( previousCommandLine && *previousCommandLine ) {
+               inpos = previousCommandLine;
+               while ( outpos != sentinel && *inpos )
+                       *outpos++ = *inpos++;
+               if ( outpos != sentinel ) {
+                       *outpos++ = ';';
+               }
+               if ( outpos != sentinel ) {
+                       *outpos++ = ' ';
+               }
+       }
 
+       for ( i = beginArgs; i < endArgs; ++i )
+       {
+               if ( outpos != sentinel && i != beginArgs ) {
+                       *outpos++ = ' ';
+               }
+               inpos = argv[i];
+               while ( outpos != sentinel && *inpos )
+                       if ( *inpos != '\\' && *inpos != '"' && *inpos != ';' && (unsigned char) *inpos >= ' ' ) {
+                               *outpos++ = *inpos++;
+                       }
+       }
+
+       *outpos = 0;
+       SetKeyValue( &entities[0], "_q3map2_cmdline", newCommandLine );
+       SetKeyValue( &entities[0], "_q3map2_version", Q3MAP_VERSION );
+}
 
 /*
-UnparseEntities()
-generates the dentdata string from all the entities.
-this allows the utilities to add or remove key/value
-pairs to the data created by the map editor
-*/
-
-void UnparseEntities( void )
-{
-       int                     i;
-       char            *buf, *end;
-       epair_t         *ep;
-       char            line[ 2048 ];
-       char            key[ 1024 ], value[ 1024 ];
-       const char      *value2;
-       
-       
+   UnparseEntities()
+   generates the dentdata string from all the entities.
+   this allows the utilities to add or remove key/value
+   pairs to the data created by the map editor
+ */
+
+void UnparseEntities( void ){
+       int i;
+       char        *buf, *end;
+       epair_t     *ep;
+       char line[ 2048 ];
+       char key[ 1024 ], value[ 1024 ];
+       const char  *value2;
+
+
        /* setup */
+       AUTOEXPAND_BY_REALLOC( bspEntData, 0, allocatedBSPEntData, 1024 );
        buf = bspEntData;
        end = buf;
        *end = 0;
-       
+
+
        /* run through entity list */
-       for( i = 0; i < numBSPEntities && i < numEntities; i++ )
+       for ( i = 0; i < numBSPEntities && i < numEntities; i++ )
        {
+               {
+                       int sz = end - buf;
+                       AUTOEXPAND_BY_REALLOC( bspEntData, sz + 65536, allocatedBSPEntData, 1024 );
+                       buf = bspEntData;
+                       end = buf + sz;
+               }
+
                /* get epair */
                ep = entities[ i ].epairs;
-               if( ep == NULL )
-                       continue;       /* ent got removed */
-               
+               if ( ep == NULL ) {
+                       continue;   /* ent got removed */
+
+               }
                /* ydnar: certain entities get stripped from bsp file */
                value2 = ValueForKey( &entities[ i ], "classname" );
-               if( !Q_stricmp( value2, "misc_model" ) ||
-                       !Q_stricmp( value2, "_decal" ) ||
-                       !Q_stricmp( value2, "_skybox" ) )
+               if ( !Q_stricmp( value2, "misc_model" ) ||
+                        !Q_stricmp( value2, "_decal" ) ||
+                        !Q_stricmp( value2, "_skybox" ) ) {
                        continue;
-               
+               }
+
                /* add beginning brace */
                strcat( end, "{\n" );
                end += 2;
-               
+
                /* walk epair list */
-               for( ep = entities[ i ].epairs; ep != NULL; ep = ep->next )
+               for ( ep = entities[ i ].epairs; ep != NULL; ep = ep->next )
                {
                        /* copy and clean */
                        strcpy( key, ep->key );
                        StripTrailing( key );
                        strcpy( value, ep->value );
                        StripTrailing( value );
-                       
+
                        /* add to buffer */
                        sprintf( line, "\"%s\" \"%s\"\n", key, value );
                        strcat( end, line );
                        end += strlen( line );
                }
-               
+
                /* add trailing brace */
                strcat( end,"}\n" );
                end += 2;
-               
+
                /* check for overflow */
-               if( end > buf + MAX_MAP_ENTSTRING )
+               if ( end > buf + allocatedBSPEntData ) {
                        Error( "Entity text too long" );
+               }
        }
-       
+
        /* set size */
        bspEntDataSize = end - buf + 1;
 }
@@ -636,17 +705,16 @@ void UnparseEntities( void )
 
 
 /*
-PrintEntity()
-prints an entity's epairs to the console
-*/
+   PrintEntity()
+   prints an entity's epairs to the console
+ */
+
+void PrintEntity( const entity_t *ent ){
+       epair_t *ep;
 
-void PrintEntity( const entity_t *ent )
-{
-       epair_t *ep;
-       
 
        Sys_Printf( "------- entity %p -------\n", ent );
-       for( ep = ent->epairs; ep != NULL; ep = ep->next )
+       for ( ep = ent->epairs; ep != NULL; ep = ep->next )
                Sys_Printf( "%s = %s\n", ep->key, ep->value );
 
 }
@@ -654,26 +722,24 @@ void PrintEntity( const entity_t *ent )
 
 
 /*
-SetKeyValue()
-sets an epair in an entity
-*/
-
-void SetKeyValue( entity_t *ent, const char *key, const char *value )
-{
-       epair_t *ep;
-       
-       
+   SetKeyValue()
+   sets an epair in an entity
+ */
+
+void SetKeyValue( entity_t *ent, const char *key, const char *value ){
+       epair_t *ep;
+
+
        /* check for existing epair */
-       for( ep = ent->epairs; ep != NULL; ep = ep->next )
+       for ( ep = ent->epairs; ep != NULL; ep = ep->next )
        {
-               if( !EPAIR_STRCMP( ep->key, key ) )
-               {
+               if ( !EPAIR_STRCMP( ep->key, key ) ) {
                        free( ep->value );
                        ep->value = copystring( value );
                        return;
                }
        }
-       
+
        /* create new epair */
        ep = safe_malloc( sizeof( *ep ) );
        ep->next = ent->epairs;
@@ -682,29 +748,48 @@ void SetKeyValue( entity_t *ent, const char *key, const char *value )
        ep->value = copystring( value );
 }
 
+/*
+   KeyExists()
+   returns true if entity has this key
+ */
 
+qboolean KeyExists( const entity_t *ent, const char *key ){
+       epair_t *ep;
+
+       /* walk epair list */
+       for ( ep = ent->epairs; ep != NULL; ep = ep->next )
+       {
+               if ( !EPAIR_STRCMP( ep->key, key ) ) {
+                       return qtrue;
+               }
+       }
+
+       /* no match */
+       return qfalse;
+}
 
 /*
-ValueForKey()
-gets the value for an entity key
-*/
-
-const char *ValueForKey( const entity_t *ent, const char *key )
-{
-       epair_t *ep;
-       
-       
+   ValueForKey()
+   gets the value for an entity key
+ */
+
+const char *ValueForKey( const entity_t *ent, const char *key ){
+       epair_t *ep;
+
+
        /* dummy check */
-       if( ent == NULL )
+       if ( ent == NULL ) {
                return "";
-       
+       }
+
        /* walk epair list */
-       for( ep = ent->epairs; ep != NULL; ep = ep->next )
+       for ( ep = ent->epairs; ep != NULL; ep = ep->next )
        {
-               if( !EPAIR_STRCMP( ep->key, key ) )
+               if ( !EPAIR_STRCMP( ep->key, key ) ) {
                        return ep->value;
+               }
        }
-       
+
        /* if no match, return empty string */
        return "";
 }
@@ -712,15 +797,14 @@ const char *ValueForKey( const entity_t *ent, const char *key )
 
 
 /*
-IntForKey()
-gets the integer point value for an entity key
-*/
-
-int IntForKey( const entity_t *ent, const char *key )
-{
-       const char      *k;
-       
-       
+   IntForKey()
+   gets the integer point value for an entity key
+ */
+
+int IntForKey( const entity_t *ent, const char *key ){
+       const char  *k;
+
+
        k = ValueForKey( ent, key );
        return atoi( k );
 }
@@ -728,15 +812,14 @@ int IntForKey( const entity_t *ent, const char *key )
 
 
 /*
-FloatForKey()
-gets the floating point value for an entity key
-*/
-
-vec_t FloatForKey( const entity_t *ent, const char *key )
-{
-       const char      *k;
-       
-       
+   FloatForKey()
+   gets the floating point value for an entity key
+ */
+
+vec_t FloatForKey( const entity_t *ent, const char *key ){
+       const char  *k;
+
+
        k = ValueForKey( ent, key );
        return atof( k );
 }
@@ -744,48 +827,50 @@ vec_t FloatForKey( const entity_t *ent, const char *key )
 
 
 /*
-GetVectorForKey()
-gets a 3-element vector value for an entity key
-*/
+   GetVectorForKey()
+   gets a 3-element vector value for an entity key
+ */
+
+qboolean GetVectorForKey( const entity_t *ent, const char *key, vec3_t vec ){
+       const char  *k;
+       double v1, v2, v3;
 
-void GetVectorForKey( const entity_t *ent, const char *key, vec3_t vec )
-{
-       const char      *k;
-       double          v1, v2, v3;
-       
 
        /* get value */
        k = ValueForKey( ent, key );
-       
+
        /* scanf into doubles, then assign, so it is vec_t size independent */
        v1 = v2 = v3 = 0.0;
        sscanf( k, "%lf %lf %lf", &v1, &v2, &v3 );
        vec[ 0 ] = v1;
        vec[ 1 ] = v2;
        vec[ 2 ] = v3;
+
+       /* true if the key is found, false otherwise */
+       return strlen( k );
 }
 
 
 
 /*
-FindTargetEntity()
-finds an entity target
-*/
+   FindTargetEntity()
+   finds an entity target
+ */
+
+entity_t *FindTargetEntity( const char *target ){
+       int i;
+       const char  *n;
 
-entity_t *FindTargetEntity( const char *target )
-{
-       int                     i;
-       const char      *n;
 
-       
        /* walk entity list */
-       for( i = 0; i < numEntities; i++ )
+       for ( i = 0; i < numEntities; i++ )
        {
                n = ValueForKey( &entities[ i ], "targetname" );
-               if ( !strcmp( n, target ) )
+               if ( !strcmp( n, target ) ) {
                        return &entities[ i ];
+               }
        }
-       
+
        /* nada */
        return NULL;
 }
@@ -793,42 +878,59 @@ entity_t *FindTargetEntity( const char *target )
 
 
 /*
-GetEntityShadowFlags() - ydnar
-gets an entity's shadow flags
-note: does not set them to defaults if the keys are not found!
-*/
-
-void GetEntityShadowFlags( const entity_t *ent, const entity_t *ent2, int *castShadows, int *recvShadows )
-{
-       const char      *value;
-       
-       
+   GetEntityShadowFlags() - ydnar
+   gets an entity's shadow flags
+   note: does not set them to defaults if the keys are not found!
+ */
+
+void GetEntityShadowFlags( const entity_t *ent, const entity_t *ent2, int *castShadows, int *recvShadows ){
+       const char  *value;
+
        /* get cast shadows */
-       if( castShadows != NULL )
-       {
+       if ( castShadows != NULL ) {
                value = ValueForKey( ent, "_castShadows" );
-               if( value[ 0 ] == '\0' )
+               if ( value[ 0 ] == '\0' ) {
                        value = ValueForKey( ent, "_cs" );
-               if( value[ 0 ] == '\0' )
+               }
+               if ( value[ 0 ] == '\0' ) {
                        value = ValueForKey( ent2, "_castShadows" );
-               if( value[ 0 ] == '\0' )
+               }
+               if ( value[ 0 ] == '\0' ) {
                        value = ValueForKey( ent2, "_cs" );
-               if( value[ 0 ] != '\0' )
+               }
+               if ( value[ 0 ] != '\0' ) {
                        *castShadows = atoi( value );
+               }
        }
-       
+
        /* receive */
-       if( recvShadows != NULL )
-       {
+       if ( recvShadows != NULL ) {
                value = ValueForKey( ent, "_receiveShadows" );
-               if( value[ 0 ] == '\0' )
+               if ( value[ 0 ] == '\0' ) {
                        value = ValueForKey( ent, "_rs" );
-               if( value[ 0 ] == '\0' )
+               }
+               if ( value[ 0 ] == '\0' ) {
                        value = ValueForKey( ent2, "_receiveShadows" );
-               if( value[ 0 ] == '\0' )
+               }
+               if ( value[ 0 ] == '\0' ) {
                        value = ValueForKey( ent2, "_rs" );
-               if( value[ 0 ] != '\0' )
+               }
+               if ( value[ 0 ] != '\0' ) {
                        *recvShadows = atoi( value );
+               }
        }
-}
 
+       /* vortex: game-specific default eneity keys */
+       value = ValueForKey( ent, "classname" );
+       if ( !Q_stricmp( game->magic, "dq" ) || !Q_stricmp( game->magic, "prophecy" ) ) {
+               /* vortex: deluxe quake default shadow flags */
+               if ( !Q_stricmp( value, "func_wall" ) ) {
+                       if ( recvShadows != NULL ) {
+                               *recvShadows = 1;
+                       }
+                       if ( castShadows != NULL ) {
+                               *castShadows = 1;
+                       }
+               }
+       }
+}