]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - tools/quake3/q3map2/bspfile_abstract.c
don't care for singular/plural in -shaderasbitmap vs -shadersasbitmap etc.
[xonotic/netradiant.git] / tools / quake3 / q3map2 / bspfile_abstract.c
index 5b515fc8f815d06f00f7d2931cee29f92b253191..d55db338e32dde523abe0e9e37db589e0db866b5 100644 (file)
@@ -329,6 +329,13 @@ int CopyLump( bspHeader_t *header, int lump, void *dest, int size )
        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);
+}
 
 
 /*
@@ -538,13 +545,13 @@ qboolean ParseEntity( void )
                return qfalse;
        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 )
        {
@@ -578,7 +585,44 @@ void ParseEntities( void )
        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()
@@ -598,13 +642,22 @@ void UnparseEntities( void )
        
        
        /* 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++ )
        {
+               {
+                       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 )
@@ -641,7 +694,7 @@ void UnparseEntities( void )
                end += 2;
                
                /* check for overflow */
-               if( end > buf + MAX_MAP_ENTSTRING )
+               if( end > buf + allocatedBSPEntData )
                        Error( "Entity text too long" );
        }
        
@@ -698,7 +751,25 @@ 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()
@@ -818,7 +889,6 @@ void GetEntityShadowFlags( const entity_t *ent, const entity_t *ent2, int *castS
 {
        const char      *value;
        
-       
        /* get cast shadows */
        if( castShadows != NULL )
        {
@@ -846,5 +916,19 @@ void GetEntityShadowFlags( const entity_t *ent, const entity_t *ent2, int *castS
                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;
+               }
+       }
 }