-/*\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 SURFACE_EXTRA_C\r
-\r
-\r
-\r
-/* dependencies */\r
-#include "q3map2.h"\r
-\r
-\r
-\r
-/* -------------------------------------------------------------------------------\r
-\r
-ydnar: srf file module\r
-\r
-------------------------------------------------------------------------------- */\r
-\r
-typedef struct surfaceExtra_s\r
-{\r
- mapDrawSurface_t *mds;\r
- shaderInfo_t *si;\r
- int parentSurfaceNum;\r
- int entityNum;\r
- int castShadows, recvShadows;\r
- int sampleSize;\r
- float longestCurve;\r
- vec3_t lightmapAxis;\r
-}\r
-surfaceExtra_t;\r
-\r
-#define GROW_SURFACE_EXTRAS 1024\r
-\r
-int numSurfaceExtras = 0;\r
-int maxSurfaceExtras = 0;\r
-surfaceExtra_t *surfaceExtras;\r
-surfaceExtra_t seDefault = { NULL, NULL, -1, 0, WORLDSPAWN_CAST_SHADOWS, WORLDSPAWN_RECV_SHADOWS, 0, 0, { 0, 0, 0 } };\r
-\r
-\r
-\r
-/*\r
-AllocSurfaceExtra()\r
-allocates a new extra storage\r
-*/\r
-\r
-static surfaceExtra_t *AllocSurfaceExtra( void )\r
-{\r
- surfaceExtra_t *se;\r
- \r
- \r
- /* enough space? */\r
- if( numSurfaceExtras >= maxSurfaceExtras )\r
- {\r
- /* reallocate more room */\r
- maxSurfaceExtras += GROW_SURFACE_EXTRAS;\r
- se = safe_malloc( maxSurfaceExtras * sizeof( surfaceExtra_t ) );\r
- if( surfaceExtras != NULL )\r
- {\r
- memcpy( se, surfaceExtras, numSurfaceExtras * sizeof( surfaceExtra_t ) );\r
- free( surfaceExtras );\r
- }\r
- surfaceExtras = se;\r
- }\r
- \r
- /* add another */\r
- se = &surfaceExtras[ numSurfaceExtras ];\r
- numSurfaceExtras++;\r
- memcpy( se, &seDefault, sizeof( surfaceExtra_t ) );\r
- \r
- /* return it */\r
- return se;\r
-}\r
-\r
-\r
-\r
-/*\r
-SetDefaultSampleSize()\r
-sets the default lightmap sample size\r
-*/\r
-\r
-void SetDefaultSampleSize( int sampleSize )\r
-{\r
- seDefault.sampleSize = sampleSize;\r
-}\r
-\r
-\r
-\r
-/*\r
-SetSurfaceExtra()\r
-stores extra (q3map2) data for the specific numbered drawsurface\r
-*/\r
-\r
-void SetSurfaceExtra( mapDrawSurface_t *ds, int num )\r
-{\r
- surfaceExtra_t *se;\r
- \r
- \r
- /* dummy check */\r
- if( ds == NULL || num < 0 )\r
- return;\r
- \r
- /* get a new extra */\r
- se = AllocSurfaceExtra();\r
- \r
- /* copy out the relevant bits */\r
- se->mds = ds;\r
- se->si = ds->shaderInfo;\r
- se->parentSurfaceNum = ds->parent != NULL ? ds->parent->outputNum : -1;\r
- se->entityNum = ds->entityNum;\r
- se->castShadows = ds->castShadows;\r
- se->recvShadows = ds->recvShadows;\r
- se->sampleSize = ds->sampleSize;\r
- se->longestCurve = ds->longestCurve;\r
- VectorCopy( ds->lightmapAxis, se->lightmapAxis );\r
- \r
- /* debug code */\r
- //% Sys_FPrintf( SYS_VRB, "SetSurfaceExtra(): entityNum = %d\n", ds->entityNum );\r
-}\r
-\r
-\r
-\r
-/*\r
-GetSurfaceExtra*()\r
-getter functions for extra surface data\r
-*/\r
-\r
-static surfaceExtra_t *GetSurfaceExtra( int num )\r
-{\r
- if( num < 0 || num >= numSurfaceExtras )\r
- return &seDefault;\r
- return &surfaceExtras[ num ];\r
-}\r
-\r
-\r
-shaderInfo_t *GetSurfaceExtraShaderInfo( int num )\r
-{\r
- surfaceExtra_t *se = GetSurfaceExtra( num );\r
- return se->si;\r
-}\r
-\r
-\r
-int GetSurfaceExtraParentSurfaceNum( int num )\r
-{\r
- surfaceExtra_t *se = GetSurfaceExtra( num );\r
- return se->parentSurfaceNum;\r
-}\r
-\r
-\r
-int GetSurfaceExtraEntityNum( int num )\r
-{\r
- surfaceExtra_t *se = GetSurfaceExtra( num );\r
- return se->entityNum;\r
-}\r
-\r
-\r
-int GetSurfaceExtraCastShadows( int num )\r
-{\r
- surfaceExtra_t *se = GetSurfaceExtra( num );\r
- return se->castShadows;\r
-}\r
-\r
-\r
-int GetSurfaceExtraRecvShadows( int num )\r
-{\r
- surfaceExtra_t *se = GetSurfaceExtra( num );\r
- return se->recvShadows;\r
-}\r
-\r
-\r
-int GetSurfaceExtraSampleSize( int num )\r
-{\r
- surfaceExtra_t *se = GetSurfaceExtra( num );\r
- return se->sampleSize;\r
-}\r
-\r
-\r
-float GetSurfaceExtraLongestCurve( int num )\r
-{\r
- surfaceExtra_t *se = GetSurfaceExtra( num );\r
- return se->longestCurve;\r
-}\r
-\r
-\r
-void GetSurfaceExtraLightmapAxis( int num, vec3_t lightmapAxis )\r
-{\r
- surfaceExtra_t *se = GetSurfaceExtra( num );\r
- VectorCopy( se->lightmapAxis, lightmapAxis );\r
-}\r
-\r
-\r
-\r
-\r
-/*\r
-WriteSurfaceExtraFile()\r
-writes out a surface info file (<map>.srf)\r
-*/\r
-\r
-void WriteSurfaceExtraFile( const char *path )\r
-{\r
- char srfPath[ 1024 ];\r
- FILE *sf;\r
- surfaceExtra_t *se;\r
- int i;\r
- \r
- \r
- /* dummy check */\r
- if( path == NULL || path[ 0 ] == '\0' )\r
- return;\r
- \r
- /* note it */\r
- Sys_Printf( "--- WriteSurfaceExtraFile ---\n" );\r
- \r
- /* open the file */\r
- strcpy( srfPath, path );\r
- StripExtension( srfPath );\r
- strcat( srfPath, ".srf" );\r
- Sys_Printf( "Writing %s\n", srfPath );\r
- sf = fopen( srfPath, "w" );\r
- if( sf == NULL )\r
- Error( "Error opening %s for writing", srfPath );\r
- \r
- /* lap through the extras list */\r
- for( i = -1; i < numSurfaceExtras; i++ )\r
- {\r
- /* get extra */\r
- se = GetSurfaceExtra( i );\r
- \r
- /* default or surface num? */\r
- if( i < 0 )\r
- fprintf( sf, "default" );\r
- else\r
- fprintf( sf, "%d", i );\r
- \r
- /* valid map drawsurf? */\r
- if( se->mds == NULL )\r
- fprintf( sf, "\n" );\r
- else\r
- {\r
- fprintf( sf, " // %s V: %d I: %d %s\n",\r
- surfaceTypes[ se->mds->type ],\r
- se->mds->numVerts,\r
- se->mds->numIndexes,\r
- (se->mds->planar ? "planar" : "") );\r
- }\r
- \r
- /* open braces */\r
- fprintf( sf, "{\n" );\r
- \r
- /* shader */\r
- if( se->si != NULL )\r
- fprintf( sf, "\tshader %s\n", se->si->shader );\r
- \r
- /* parent surface number */\r
- if( se->parentSurfaceNum != seDefault.parentSurfaceNum )\r
- fprintf( sf, "\tparent %d\n", se->parentSurfaceNum );\r
- \r
- /* entity number */\r
- if( se->entityNum != seDefault.entityNum )\r
- fprintf( sf, "\tentity %d\n", se->entityNum );\r
- \r
- /* cast shadows */\r
- if( se->castShadows != seDefault.castShadows || se == &seDefault )\r
- fprintf( sf, "\tcastShadows %d\n", se->castShadows );\r
- \r
- /* recv shadows */\r
- if( se->recvShadows != seDefault.recvShadows || se == &seDefault )\r
- fprintf( sf, "\treceiveShadows %d\n", se->recvShadows );\r
- \r
- /* lightmap sample size */\r
- if( se->sampleSize != seDefault.sampleSize || se == &seDefault )\r
- fprintf( sf, "\tsampleSize %d\n", se->sampleSize );\r
- \r
- /* longest curve */\r
- if( se->longestCurve != seDefault.longestCurve || se == &seDefault )\r
- fprintf( sf, "\tlongestCurve %f\n", se->longestCurve );\r
- \r
- /* lightmap axis vector */\r
- if( VectorCompare( se->lightmapAxis, seDefault.lightmapAxis ) == qfalse )\r
- fprintf( sf, "\tlightmapAxis ( %f %f %f )\n", se->lightmapAxis[ 0 ], se->lightmapAxis[ 1 ], se->lightmapAxis[ 2 ] );\r
- \r
- /* close braces */\r
- fprintf( sf, "}\n\n" );\r
- }\r
- \r
- /* close the file */\r
- fclose( sf );\r
-}\r
-\r
-\r
-\r
-/*\r
-LoadSurfaceExtraFile()\r
-reads a surface info file (<map>.srf)\r
-*/\r
-\r
-void LoadSurfaceExtraFile( const char *path )\r
-{\r
- char srfPath[ 1024 ];\r
- surfaceExtra_t *se;\r
- int surfaceNum, size;\r
- byte *buffer;\r
- \r
- \r
- /* dummy check */\r
- if( path == NULL || path[ 0 ] == '\0' )\r
- return;\r
- \r
- /* load the file */\r
- strcpy( srfPath, path );\r
- StripExtension( srfPath );\r
- strcat( srfPath, ".srf" );\r
- Sys_Printf( "Loading %s\n", srfPath );\r
- size = LoadFile( srfPath, (void**) &buffer );\r
- if( size <= 0 )\r
- {\r
- Sys_Printf( "WARNING: Unable to find surface file %s, using defaults.\n", srfPath );\r
- return;\r
- }\r
- \r
- /* parse the file */\r
- ParseFromMemory( buffer, size );\r
- \r
- /* tokenize it */\r
- while( 1 )\r
- {\r
- /* test for end of file */\r
- if( !GetToken( qtrue ) )\r
- break;\r
- \r
- /* default? */\r
- if( !Q_stricmp( token, "default" ) )\r
- se = &seDefault;\r
-\r
- /* surface number */\r
- else\r
- {\r
- surfaceNum = atoi( token );\r
- if( surfaceNum < 0 || surfaceNum > MAX_MAP_DRAW_SURFS )\r
- Error( "ReadSurfaceExtraFile(): %s, line %d: bogus surface num %d", srfPath, scriptline, surfaceNum );\r
- while( surfaceNum >= numSurfaceExtras )\r
- se = AllocSurfaceExtra();\r
- se = &surfaceExtras[ surfaceNum ];\r
- }\r
- \r
- /* handle { } section */\r
- if( !GetToken( qtrue ) || strcmp( token, "{" ) )\r
- Error( "ReadSurfaceExtraFile(): %s, line %d: { not found", srfPath, scriptline );\r
- while( 1 )\r
- {\r
- if( !GetToken( qtrue ) )\r
- break;\r
- if( !strcmp( token, "}" ) )\r
- break;\r
- \r
- /* shader */\r
- if( !Q_stricmp( token, "shader" ) )\r
- {\r
- GetToken( qfalse );\r
- se->si = ShaderInfoForShader( token );\r
- }\r
- \r
- /* parent surface number */\r
- else if( !Q_stricmp( token, "parent" ) )\r
- {\r
- GetToken( qfalse );\r
- se->parentSurfaceNum = atoi( token );\r
- }\r
- \r
- /* entity number */\r
- else if( !Q_stricmp( token, "entity" ) )\r
- {\r
- GetToken( qfalse );\r
- se->entityNum = atoi( token );\r
- }\r
- \r
- /* cast shadows */\r
- else if( !Q_stricmp( token, "castShadows" ) )\r
- {\r
- GetToken( qfalse );\r
- se->castShadows = atoi( token );\r
- }\r
- \r
- /* recv shadows */\r
- else if( !Q_stricmp( token, "receiveShadows" ) )\r
- {\r
- GetToken( qfalse );\r
- se->recvShadows = atoi( token );\r
- }\r
- \r
- /* lightmap sample size */\r
- else if( !Q_stricmp( token, "sampleSize" ) )\r
- {\r
- GetToken( qfalse );\r
- se->sampleSize = atoi( token );\r
- }\r
- \r
- /* longest curve */\r
- else if( !Q_stricmp( token, "longestCurve" ) )\r
- {\r
- GetToken( qfalse );\r
- se->longestCurve = atof( token );\r
- }\r
- \r
- /* lightmap axis vector */\r
- else if( !Q_stricmp( token, "lightmapAxis" ) )\r
- Parse1DMatrix( 3, se->lightmapAxis );\r
- \r
- /* ignore all other tokens on the line */\r
- while( TokenAvailable() )\r
- GetToken( qfalse );\r
- }\r
- }\r
- \r
- /* free the buffer */\r
- free( buffer );\r
-}\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 SURFACE_EXTRA_C
+
+
+
+/* dependencies */
+#include "q3map2.h"
+
+
+
+/* -------------------------------------------------------------------------------
+
+ ydnar: srf file module
+
+ ------------------------------------------------------------------------------- */
+
+typedef struct surfaceExtra_s
+{
+ mapDrawSurface_t *mds;
+ shaderInfo_t *si;
+ int parentSurfaceNum;
+ int entityNum;
+ int castShadows, recvShadows;
+ int sampleSize;
+ float longestCurve;
+ vec3_t lightmapAxis;
+}
+surfaceExtra_t;
+
+#define GROW_SURFACE_EXTRAS 1024
+
+int numSurfaceExtras = 0;
+int maxSurfaceExtras = 0;
+surfaceExtra_t *surfaceExtras;
+surfaceExtra_t seDefault = { NULL, NULL, -1, 0, WORLDSPAWN_CAST_SHADOWS, WORLDSPAWN_RECV_SHADOWS, 0, 0, { 0, 0, 0 } };
+
+
+
+/*
+ AllocSurfaceExtra()
+ allocates a new extra storage
+ */
+
+static surfaceExtra_t *AllocSurfaceExtra( void ){
+ surfaceExtra_t *se;
+
+
+ /* enough space? */
+ if ( numSurfaceExtras >= maxSurfaceExtras ) {
+ /* reallocate more room */
+ maxSurfaceExtras += GROW_SURFACE_EXTRAS;
+ se = safe_malloc( maxSurfaceExtras * sizeof( surfaceExtra_t ) );
+ if ( surfaceExtras != NULL ) {
+ memcpy( se, surfaceExtras, numSurfaceExtras * sizeof( surfaceExtra_t ) );
+ free( surfaceExtras );
+ }
+ surfaceExtras = se;
+ }
+
+ /* add another */
+ se = &surfaceExtras[ numSurfaceExtras ];
+ numSurfaceExtras++;
+ memcpy( se, &seDefault, sizeof( surfaceExtra_t ) );
+
+ /* return it */
+ return se;
+}
+
+
+
+/*
+ SetDefaultSampleSize()
+ sets the default lightmap sample size
+ */
+
+void SetDefaultSampleSize( int sampleSize ){
+ seDefault.sampleSize = sampleSize;
+}
+
+
+
+/*
+ SetSurfaceExtra()
+ stores extra (q3map2) data for the specific numbered drawsurface
+ */
+
+void SetSurfaceExtra( mapDrawSurface_t *ds, int num ){
+ surfaceExtra_t *se;
+
+
+ /* dummy check */
+ if ( ds == NULL || num < 0 ) {
+ return;
+ }
+
+ /* get a new extra */
+ se = AllocSurfaceExtra();
+
+ /* copy out the relevant bits */
+ se->mds = ds;
+ se->si = ds->shaderInfo;
+ se->parentSurfaceNum = ds->parent != NULL ? ds->parent->outputNum : -1;
+ se->entityNum = ds->entityNum;
+ se->castShadows = ds->castShadows;
+ se->recvShadows = ds->recvShadows;
+ se->sampleSize = ds->sampleSize;
+ se->longestCurve = ds->longestCurve;
+ VectorCopy( ds->lightmapAxis, se->lightmapAxis );
+
+ /* debug code */
+ //% Sys_FPrintf( SYS_VRB, "SetSurfaceExtra(): entityNum = %d\n", ds->entityNum );
+}
+
+
+
+/*
+ GetSurfaceExtra*()
+ getter functions for extra surface data
+ */
+
+static surfaceExtra_t *GetSurfaceExtra( int num ){
+ if ( num < 0 || num >= numSurfaceExtras ) {
+ return &seDefault;
+ }
+ return &surfaceExtras[ num ];
+}
+
+
+shaderInfo_t *GetSurfaceExtraShaderInfo( int num ){
+ surfaceExtra_t *se = GetSurfaceExtra( num );
+ return se->si;
+}
+
+
+int GetSurfaceExtraParentSurfaceNum( int num ){
+ surfaceExtra_t *se = GetSurfaceExtra( num );
+ return se->parentSurfaceNum;
+}
+
+
+int GetSurfaceExtraEntityNum( int num ){
+ surfaceExtra_t *se = GetSurfaceExtra( num );
+ return se->entityNum;
+}
+
+
+int GetSurfaceExtraCastShadows( int num ){
+ surfaceExtra_t *se = GetSurfaceExtra( num );
+ return se->castShadows;
+}
+
+
+int GetSurfaceExtraRecvShadows( int num ){
+ surfaceExtra_t *se = GetSurfaceExtra( num );
+ return se->recvShadows;
+}
+
+
+int GetSurfaceExtraSampleSize( int num ){
+ surfaceExtra_t *se = GetSurfaceExtra( num );
+ return se->sampleSize;
+}
+
+
+float GetSurfaceExtraLongestCurve( int num ){
+ surfaceExtra_t *se = GetSurfaceExtra( num );
+ return se->longestCurve;
+}
+
+
+void GetSurfaceExtraLightmapAxis( int num, vec3_t lightmapAxis ){
+ surfaceExtra_t *se = GetSurfaceExtra( num );
+ VectorCopy( se->lightmapAxis, lightmapAxis );
+}
+
+
+
+
+/*
+ WriteSurfaceExtraFile()
+ writes out a surface info file (<map>.srf)
+ */
+
+void WriteSurfaceExtraFile( const char *surfaceFilePath ){
+ FILE *sf;
+ surfaceExtra_t *se;
+ int i;
+
+
+ /* dummy check */
+ if ( surfaceFilePath == NULL || surfaceFilePath[ 0 ] == '\0' ) {
+ return;
+ }
+
+ /* note it */
+ Sys_Printf( "--- WriteSurfaceExtraFile ---\n" );
+
+ /* open the file */
+ Sys_Printf( "Writing %s\n", surfaceFilePath );
+ sf = fopen( surfaceFilePath, "w" );
+ if ( sf == NULL ) {
+ Error( "Error opening %s for writing", surfaceFilePath );
+ }
+
+ /* lap through the extras list */
+ for ( i = -1; i < numSurfaceExtras; i++ )
+ {
+ /* get extra */
+ se = GetSurfaceExtra( i );
+
+ /* default or surface num? */
+ if ( i < 0 ) {
+ fprintf( sf, "default" );
+ }
+ else{
+ fprintf( sf, "%d", i );
+ }
+
+ /* valid map drawsurf? */
+ if ( se->mds == NULL ) {
+ fprintf( sf, "\n" );
+ }
+ else
+ {
+ fprintf( sf, " // %s V: %d I: %d %s\n",
+ surfaceTypes[ se->mds->type ],
+ se->mds->numVerts,
+ se->mds->numIndexes,
+ ( se->mds->planar ? "planar" : "" ) );
+ }
+
+ /* open braces */
+ fprintf( sf, "{\n" );
+
+ /* shader */
+ if ( se->si != NULL ) {
+ fprintf( sf, "\tshader %s\n", se->si->shader );
+ }
+
+ /* parent surface number */
+ if ( se->parentSurfaceNum != seDefault.parentSurfaceNum ) {
+ fprintf( sf, "\tparent %d\n", se->parentSurfaceNum );
+ }
+
+ /* entity number */
+ if ( se->entityNum != seDefault.entityNum ) {
+ fprintf( sf, "\tentity %d\n", se->entityNum );
+ }
+
+ /* cast shadows */
+ if ( se->castShadows != seDefault.castShadows || se == &seDefault ) {
+ fprintf( sf, "\tcastShadows %d\n", se->castShadows );
+ }
+
+ /* recv shadows */
+ if ( se->recvShadows != seDefault.recvShadows || se == &seDefault ) {
+ fprintf( sf, "\treceiveShadows %d\n", se->recvShadows );
+ }
+
+ /* lightmap sample size */
+ if ( se->sampleSize != seDefault.sampleSize || se == &seDefault ) {
+ fprintf( sf, "\tsampleSize %d\n", se->sampleSize );
+ }
+
+ /* longest curve */
+ if ( se->longestCurve != seDefault.longestCurve || se == &seDefault ) {
+ fprintf( sf, "\tlongestCurve %f\n", se->longestCurve );
+ }
+
+ /* lightmap axis vector */
+ if ( VectorCompare( se->lightmapAxis, seDefault.lightmapAxis ) == qfalse ) {
+ fprintf( sf, "\tlightmapAxis ( %f %f %f )\n", se->lightmapAxis[ 0 ], se->lightmapAxis[ 1 ], se->lightmapAxis[ 2 ] );
+ }
+
+ /* close braces */
+ fprintf( sf, "}\n\n" );
+ }
+
+ /* close the file */
+ fclose( sf );
+}
+
+
+
+/*
+ LoadSurfaceExtraFile()
+ reads a surface info file (<map>.srf)
+ */
+
+void LoadSurfaceExtraFile( const char *surfaceFilePath ){
+ surfaceExtra_t *se;
+ int surfaceNum, size;
+ byte *buffer;
+
+
+ /* dummy check */
+ if ( surfaceFilePath == NULL || surfaceFilePath[ 0 ] == '\0' ) {
+ return;
+ }
+
+ /* load the file */
+ Sys_Printf( "Loading %s\n", surfaceFilePath );
+ size = LoadFile( surfaceFilePath, (void**) &buffer );
+ if ( size <= 0 ) {
+ Sys_FPrintf( SYS_WRN, "WARNING: Unable to find surface file %s, using defaults.\n", surfaceFilePath );
+ return;
+ }
+
+ /* parse the file */
+ ParseFromMemory( (char*) buffer, size );
+
+ /* tokenize it */
+ while ( 1 )
+ {
+ /* test for end of file */
+ if ( !GetToken( qtrue ) ) {
+ break;
+ }
+
+ /* default? */
+ if ( !Q_stricmp( token, "default" ) ) {
+ se = &seDefault;
+ }
+
+ /* surface number */
+ else
+ {
+ surfaceNum = atoi( token );
+ if ( surfaceNum < 0 || surfaceNum > MAX_MAP_DRAW_SURFS ) {
+ Error( "ReadSurfaceExtraFile(): %s, line %d: bogus surface num %d", surfaceFilePath, scriptline, surfaceNum );
+ }
+ while ( surfaceNum >= numSurfaceExtras )
+ se = AllocSurfaceExtra();
+ se = &surfaceExtras[ surfaceNum ];
+ }
+
+ /* handle { } section */
+ if ( !GetToken( qtrue ) || strcmp( token, "{" ) ) {
+ Error( "ReadSurfaceExtraFile(): %s, line %d: { not found", surfaceFilePath, scriptline );
+ }
+ while ( 1 )
+ {
+ if ( !GetToken( qtrue ) ) {
+ break;
+ }
+ if ( !strcmp( token, "}" ) ) {
+ break;
+ }
+
+ /* shader */
+ if ( !Q_stricmp( token, "shader" ) ) {
+ GetToken( qfalse );
+ se->si = ShaderInfoForShader( token );
+ }
+
+ /* parent surface number */
+ else if ( !Q_stricmp( token, "parent" ) ) {
+ GetToken( qfalse );
+ se->parentSurfaceNum = atoi( token );
+ }
+
+ /* entity number */
+ else if ( !Q_stricmp( token, "entity" ) ) {
+ GetToken( qfalse );
+ se->entityNum = atoi( token );
+ }
+
+ /* cast shadows */
+ else if ( !Q_stricmp( token, "castShadows" ) ) {
+ GetToken( qfalse );
+ se->castShadows = atoi( token );
+ }
+
+ /* recv shadows */
+ else if ( !Q_stricmp( token, "receiveShadows" ) ) {
+ GetToken( qfalse );
+ se->recvShadows = atoi( token );
+ }
+
+ /* lightmap sample size */
+ else if ( !Q_stricmp( token, "sampleSize" ) ) {
+ GetToken( qfalse );
+ se->sampleSize = atoi( token );
+ }
+
+ /* longest curve */
+ else if ( !Q_stricmp( token, "longestCurve" ) ) {
+ GetToken( qfalse );
+ se->longestCurve = atof( token );
+ }
+
+ /* lightmap axis vector */
+ else if ( !Q_stricmp( token, "lightmapAxis" ) ) {
+ Parse1DMatrix( 3, se->lightmapAxis );
+ }
+
+ /* ignore all other tokens on the line */
+ while ( TokenAvailable() )
+ GetToken( qfalse );
+ }
+ }
+
+ /* free the buffer */
+ free( buffer );
+}