X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fnetradiant.git;a=blobdiff_plain;f=tools%2Fquake3%2Fq3map2%2Fwritebsp.c;h=3fbed1cc64dfb25a1f4a705baf50e9e22aa1d53c;hp=8fd073cdfdfe90e40220e6637830c2417ab9966e;hb=38056549ede3da5736686243a1242a2e67a35ec1;hpb=830125fad042fad35dc029b6eb57c8156ad7e176 diff --git a/tools/quake3/q3map2/writebsp.c b/tools/quake3/q3map2/writebsp.c index 8fd073cd..3fbed1cc 100644 --- a/tools/quake3/q3map2/writebsp.c +++ b/tools/quake3/q3map2/writebsp.c @@ -38,6 +38,61 @@ +//prefixInfo-stats +typedef struct { + char *name; + int surfaceFlags; +} prefixInfo_t; + +static prefixInfo_t prefixInfo[] = { + { "metal", TEX_SURF_METAL}, + { "wood", TEX_SURF_WOOD}, + { "cloth", TEX_SURF_CLOTH}, + { "dirt", TEX_SURF_DIRT}, + { "glass", TEX_SURF_GLASS}, + { "plant", TEX_SURF_PLANT}, + { "sand", TEX_SURF_SAND}, + { "snow", TEX_SURF_SNOW}, + { "stone", TEX_SURF_STONE}, + { "water", TEX_SURF_WATER}, + { "grass", TEX_SURF_GRASS}, +}; + +#define NUM_PREFIXINFO 11 /* very important */ + +//Added by Spoon to recognize surfaceparms by shadernames +int GetSurfaceParm(const char *tex){ + char surf[MAX_QPATH], tex2[MAX_QPATH]; + int i, j = 0; + + strcpy(tex2, tex); + + /* find last dir */ + for(i = 0; i < 64 && tex2[i] != '\0'; i++){ + if(tex2[i] == '\\' || tex2[i] == '/') + j=i+1; + } + + strcpy(surf, tex2+j); + + for(i=0; i<10; i++){ + if(surf[i] == '_') + break; + } + surf[i] = '\0'; + + /* Sys_Printf("%s\n", surf); */ + + for(i=0; i < NUM_PREFIXINFO; i++){ + if(!Q_stricmp(surf, prefixInfo[i].name)){ + return prefixInfo[i].surfaceFlags; + } + } + return 0; +} + + + /* EmitShader() emits a bsp shader entry @@ -56,12 +111,16 @@ int EmitShader( const char *shader, int *contentFlags, int *surfaceFlags ){ /* try to find an existing shader */ for ( i = 0; i < numBSPShaders; i++ ) { - /* ydnar: handle custom surface/content flags */ - if ( surfaceFlags != NULL && bspShaders[ i ].surfaceFlags != *surfaceFlags ) { - continue; - } - if ( contentFlags != NULL && bspShaders[ i ].contentFlags != *contentFlags ) { - continue; + /* if not Smokin'Guns like tex file */ + if ( !game->texFile ) + { + /* ydnar: handle custom surface/content flags */ + if ( surfaceFlags != NULL && bspShaders[ i ].surfaceFlags != *surfaceFlags ) { + continue; + } + if ( contentFlags != NULL && bspShaders[ i ].contentFlags != *contentFlags ) { + continue; + } } /* compare name */ @@ -74,20 +133,30 @@ int EmitShader( const char *shader, int *contentFlags, int *surfaceFlags ){ si = ShaderInfoForShader( shader ); /* emit a new shader */ - if ( i == MAX_MAP_SHADERS ) { - Error( "MAX_MAP_SHADERS" ); - } + AUTOEXPAND_BY_REALLOC_BSP( Shaders, 1024 ); + numBSPShaders++; strcpy( bspShaders[ i ].shader, shader ); bspShaders[ i ].surfaceFlags = si->surfaceFlags; - bspShaders[ i ].contentFlags = si->contentFlags; - /* handle custom content/surface flags */ - if ( surfaceFlags != NULL ) { - bspShaders[ i ].surfaceFlags = *surfaceFlags; + if ( game->texFile ) + { + /* Smokin'Guns like tex file */ + bspShaders[ i ].surfaceFlags |= GetSurfaceParm(si->shader); } - if ( contentFlags != NULL ) { - bspShaders[ i ].contentFlags = *contentFlags; + + bspShaders[ i ].contentFlags = si->contentFlags; + + /* if not Smokin'Guns like tex file */ + if ( !game->texFile ) + { + /* handle custom content/surface flags */ + if ( surfaceFlags != NULL ) { + bspShaders[ i ].surfaceFlags = *surfaceFlags; + } + if ( contentFlags != NULL ) { + bspShaders[ i ].contentFlags = *contentFlags; + } } /* recursively emit any damage shaders */ @@ -118,6 +187,7 @@ void EmitPlanes( void ){ mp = mapplanes; for ( i = 0; i < nummapplanes; i++, mp++ ) { + AUTOEXPAND_BY_REALLOC_BSP( Planes, 1024 ); bp = &bspPlanes[ numBSPPlanes ]; VectorCopy( mp->normal, bp->normal ); bp->dist = mp->dist; @@ -162,15 +232,13 @@ void EmitLeaf( node_t *node ){ { /* something is corrupting brushes */ if ( (size_t) b < 256 ) { - Sys_Printf( "WARNING: Node brush list corrupted (0x%08X)\n", b ); + Sys_FPrintf( SYS_WRN, "WARNING: Node brush list corrupted (0x%08X)\n", b ); break; } //% if( b->guard != 0xDEADBEEF ) //% Sys_Printf( "Brush %6d: 0x%08X Guard: 0x%08X Next: 0x%08X Original: 0x%08X Sides: %d\n", b->brushNum, b, b, b->next, b->original, b->numsides ); - if ( numBSPLeafBrushes >= MAX_MAP_LEAFBRUSHES ) { - Error( "MAX_MAP_LEAFBRUSHES" ); - } + AUTOEXPAND_BY_REALLOC_BSP( LeafBrushes, 1024 ); bspLeafBrushes[ numBSPLeafBrushes ] = b->original->outputNum; numBSPLeafBrushes++; } @@ -186,9 +254,7 @@ void EmitLeaf( node_t *node ){ leaf_p->firstBSPLeafSurface = numBSPLeafSurfaces; for ( dsr = node->drawSurfReferences; dsr; dsr = dsr->nextRef ) { - if ( numBSPLeafSurfaces >= MAX_MAP_LEAFFACES ) { - Error( "MAX_MAP_LEAFFACES" ); - } + AUTOEXPAND_BY_REALLOC_BSP( LeafSurfaces, 1024 ); bspLeafSurfaces[ numBSPLeafSurfaces ] = dsr->outputNum; numBSPLeafSurfaces++; } @@ -204,7 +270,7 @@ void EmitLeaf( node_t *node ){ int EmitDrawNode_r( node_t *node ){ bspNode_t *n; - int i; + int i, n0; /* check for leafnode */ @@ -214,10 +280,9 @@ int EmitDrawNode_r( node_t *node ){ } /* emit a node */ - if ( numBSPNodes == MAX_MAP_NODES ) { - Error( "MAX_MAP_NODES" ); - } - n = &bspNodes[ numBSPNodes ]; + AUTOEXPAND_BY_REALLOC_BSP( Nodes, 1024 ); + n0 = numBSPNodes; + n = &bspNodes[ n0 ]; numBSPNodes++; VectorCopy( node->mins, n->mins ); @@ -241,6 +306,8 @@ int EmitDrawNode_r( node_t *node ){ { n->children[i] = numBSPNodes; EmitDrawNode_r( node->children[i] ); + // n may have become invalid here, so... + n = &bspNodes[ n0 ]; } } @@ -280,7 +347,6 @@ void SetModelNumbers( void ){ void SetLightStyles( void ){ int i, j, style, numStyles; - qboolean keepLights; const char *t; entity_t *e; epair_t *ep, *next; @@ -288,10 +354,16 @@ void SetLightStyles( void ){ char lightTargets[ MAX_SWITCHED_LIGHTS ][ 64 ]; int lightStyles[ MAX_SWITCHED_LIGHTS ]; + /* -keeplights option: force lights to be kept and ignore what the map file says */ + if ( keepLights ) { + SetKeyValue( &entities[0], "_keepLights", "1" ); + } /* ydnar: determine if we keep lights in the bsp */ - t = ValueForKey( &entities[ 0 ], "_keepLights" ); - keepLights = ( t[ 0 ] == '1' ) ? qtrue : qfalse; + if ( KeyExists( &entities[ 0 ], "_keepLights" ) == qtrue ) { + t = ValueForKey( &entities[ 0 ], "_keepLights" ); + keepLights = ( t[ 0 ] == '1' ) ? qtrue : qfalse; + } /* any light that is controlled (has a targetname) must have a unique style number generated for it */ numStyles = 0; @@ -382,6 +454,7 @@ void BeginBSPFile( void ){ /* ydnar: gs mods: set the first 6 drawindexes to 0 1 2 2 1 3 for triangles and quads */ numBSPDrawIndexes = 6; + AUTOEXPAND_BY_REALLOC_BSP( DrawIndexes, 1024 ); bspDrawIndexes[ 0 ] = 0; bspDrawIndexes[ 1 ] = 1; bspDrawIndexes[ 2 ] = 2; @@ -392,14 +465,85 @@ void BeginBSPFile( void ){ +/* + RestoreSurfaceFlags() + read Smokin'Guns like tex file + added by spoon to get back the changed surfaceflags + */ + +void RestoreSurfaceFlags( char *filename ) { + int i; + FILE *texfile; + int surfaceFlags[ MAX_MAP_DRAW_SURFS ]; + int numTexInfos; + + /* first parse the tex file */ + texfile = fopen( filename, "r" ); + + if ( texfile ) { + fscanf( texfile, "TEXFILE\n%i\n", &numTexInfos ); + + /* Sys_Printf( "%i\n", numTexInfos ); */ + + for ( i = 0; i < numTexInfos; i++ ) { + vec3_t color; + + fscanf( texfile, "%i %f %f %f\n", &surfaceFlags[ i ], + &color[ 0 ], &color[ 1 ], &color[ 2 ]); + + bspShaders[ i ].surfaceFlags = surfaceFlags[ i ]; + + /* Sys_Printf( "%i\n", surfaceFlags[ i ] ); */ + } + } else { + Sys_Printf("couldn't find %s not tex-file is now writed without surfaceFlags!\n", filename); + } +} + + + +/* + WriteTexFile() + write Smokin'Guns like tex file + added by spoon + */ + +void WriteTexFile( char* filename ) { + FILE *texfile; + int i; + + if ( !compile_map ) { + RestoreSurfaceFlags( filename ); + } + + Sys_Printf( "Writing %s ...\n", filename ); + + texfile = fopen ( filename, "w" ); + + fprintf( texfile, "TEXFILE\n" ); + + fprintf( texfile, "%i\n", numBSPShaders ); + + for ( i = 0 ; i < numBSPShaders ; i++ ) { + shaderInfo_t *se = ShaderInfoForShader( bspShaders[ i ].shader ); + + fprintf( texfile, "\n%i %f %f %f", bspShaders[ i ].surfaceFlags, + se->color[ 0 ], se->color[ 1 ], se->color[ 2 ] ); + + bspShaders[ i ].surfaceFlags = i; + } + + fclose( texfile ); +} + + + /* EndBSPFile() finishes a new bsp and writes to disk */ -void EndBSPFile( void ){ - char path[ 1024 ]; - +void EndBSPFile( qboolean do_write, const char *BSPFilePath, const char *surfaceFilePath ){ Sys_FPrintf( SYS_VRB, "--- EndBSPFile ---\n" ); @@ -408,13 +552,25 @@ void EndBSPFile( void ){ numBSPEntities = numEntities; UnparseEntities(); - /* write the surface extra file */ - WriteSurfaceExtraFile( source ); + if ( do_write ) { + /* write the surface extra file */ + WriteSurfaceExtraFile( surfaceFilePath ); + + if ( game->texFile ) + { + char basename[ 1024 ]; + char filename[ 1024 ]; + strncpy( basename, BSPFilePath, sizeof(basename) ); + sprintf( filename, "%s.tex", basename ); + + /* only create tex file if it is the first compile */ + WriteTexFile( filename ); + } - /* write the bsp */ - sprintf( path, "%s.bsp", source ); - Sys_Printf( "Writing %s\n", path ); - WriteBSPFile( path ); + /* write the bsp */ + Sys_Printf( "Writing %s\n", BSPFilePath ); + WriteBSPFile( BSPFilePath ); + } } @@ -443,9 +599,7 @@ void EmitBrushes( brush_t *brushes, int *firstBrush, int *numBrushes ){ for ( b = brushes; b != NULL; b = b->next ) { /* check limits */ - if ( numBSPBrushes == MAX_MAP_BRUSHES ) { - Error( "MAX_MAP_BRUSHES (%d)", numBSPBrushes ); - } + AUTOEXPAND_BY_REALLOC_BSP( Brushes, 1024 ); /* get bsp brush */ b->outputNum = numBSPBrushes; @@ -466,9 +620,7 @@ void EmitBrushes( brush_t *brushes, int *firstBrush, int *numBrushes ){ b->sides[ j ].outputNum = -1; /* check count */ - if ( numBSPBrushSides == MAX_MAP_BRUSHSIDES ) { - Error( "MAX_MAP_BRUSHSIDES " ); - } + AUTOEXPAND_BY_REALLOC_BSP( BrushSides, 1024 ); /* emit side */ b->sides[ j ].outputNum = numBSPBrushSides; @@ -555,9 +707,7 @@ void BeginModel( void ){ /* test limits */ - if ( numBSPModels == MAX_MAP_MODELS ) { - Error( "MAX_MAP_MODELS" ); - } + AUTOEXPAND_BY_REALLOC_BSP( Models, 256 ); /* get model and entity */ mod = &bspModels[ numBSPModels ];