X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=tools%2Fquake3%2Fq3map2%2Fbspfile_abstract.c;h=cea3239af0a3bed3594b530c0a16820eff3a8a27;hb=4f135b96bbce8ccfdf461f68347daa514df87e59;hp=a79d65b2b14515dfdfa0953e633a076dd92aa0fc;hpb=88cea027e6e647250b1f19862393306948801fca;p=xonotic%2Fnetradiant.git diff --git a/tools/quake3/q3map2/bspfile_abstract.c b/tools/quake3/q3map2/bspfile_abstract.c index a79d65b2..cea3239a 100644 --- a/tools/quake3/q3map2/bspfile_abstract.c +++ b/tools/quake3/q3map2/bspfile_abstract.c @@ -1,30 +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." -------------------------------------------------------------------------------- */ + ------------------------------------------------------------------------------- */ @@ -41,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 ); + } } @@ -143,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 ); @@ -186,7 +183,7 @@ void SwapBSPFile( void ) /* planes */ SwapBlock( (int*) bspPlanes, numBSPPlanes * sizeof( bspPlanes[ 0 ] ) ); - + /* nodes */ SwapBlock( (int*) bspNodes, numBSPNodes * sizeof( bspNodes[ 0 ] ) ); @@ -206,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 ] ); @@ -220,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] ) ); @@ -235,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; } @@ -270,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(); @@ -356,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 ); @@ -387,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 / (game->lightmapSize * game->lightmapSize * 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--; @@ -473,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; } @@ -509,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; } @@ -549,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; } @@ -637,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 ); } @@ -655,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; @@ -683,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 ""; } @@ -713,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 ); } @@ -729,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 ); } @@ -745,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; } @@ -794,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; + } + } + } +}