2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
\r
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
\r
5 This file is part of GtkRadiant.
\r
7 GtkRadiant is free software; you can redistribute it and/or modify
\r
8 it under the terms of the GNU General Public License as published by
\r
9 the Free Software Foundation; either version 2 of the License, or
\r
10 (at your option) any later version.
\r
12 GtkRadiant is distributed in the hope that it will be useful,
\r
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
15 GNU General Public License for more details.
\r
17 You should have received a copy of the GNU General Public License
\r
18 along with GtkRadiant; if not, write to the Free Software
\r
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\r
21 ----------------------------------------------------------------------------------
\r
23 This code has been altered significantly from its original form, to support
\r
24 several games based on the Quake III Arena engine, in the form of "Q3Map2."
\r
26 ------------------------------------------------------------------------------- */
\r
31 #define SURFACE_EXTRA_C
\r
40 /* -------------------------------------------------------------------------------
\r
42 ydnar: srf file module
\r
44 ------------------------------------------------------------------------------- */
\r
46 typedef struct surfaceExtra_s
\r
48 mapDrawSurface_t *mds;
\r
50 int parentSurfaceNum;
\r
52 int castShadows, recvShadows;
\r
55 vec3_t lightmapAxis;
\r
59 #define GROW_SURFACE_EXTRAS 1024
\r
61 int numSurfaceExtras = 0;
\r
62 int maxSurfaceExtras = 0;
\r
63 surfaceExtra_t *surfaceExtras;
\r
64 surfaceExtra_t seDefault = { NULL, NULL, -1, 0, WORLDSPAWN_CAST_SHADOWS, WORLDSPAWN_RECV_SHADOWS, 0, 0, { 0, 0, 0 } };
\r
70 allocates a new extra storage
\r
73 static surfaceExtra_t *AllocSurfaceExtra( void )
\r
79 if( numSurfaceExtras >= maxSurfaceExtras )
\r
81 /* reallocate more room */
\r
82 maxSurfaceExtras += GROW_SURFACE_EXTRAS;
\r
83 se = safe_malloc( maxSurfaceExtras * sizeof( surfaceExtra_t ) );
\r
84 if( surfaceExtras != NULL )
\r
86 memcpy( se, surfaceExtras, numSurfaceExtras * sizeof( surfaceExtra_t ) );
\r
87 free( surfaceExtras );
\r
93 se = &surfaceExtras[ numSurfaceExtras ];
\r
95 memcpy( se, &seDefault, sizeof( surfaceExtra_t ) );
\r
104 SetDefaultSampleSize()
\r
105 sets the default lightmap sample size
\r
108 void SetDefaultSampleSize( int sampleSize )
\r
110 seDefault.sampleSize = sampleSize;
\r
117 stores extra (q3map2) data for the specific numbered drawsurface
\r
120 void SetSurfaceExtra( mapDrawSurface_t *ds, int num )
\r
122 surfaceExtra_t *se;
\r
126 if( ds == NULL || num < 0 )
\r
129 /* get a new extra */
\r
130 se = AllocSurfaceExtra();
\r
132 /* copy out the relevant bits */
\r
134 se->si = ds->shaderInfo;
\r
135 se->parentSurfaceNum = ds->parent != NULL ? ds->parent->outputNum : -1;
\r
136 se->entityNum = ds->entityNum;
\r
137 se->castShadows = ds->castShadows;
\r
138 se->recvShadows = ds->recvShadows;
\r
139 se->sampleSize = ds->sampleSize;
\r
140 se->longestCurve = ds->longestCurve;
\r
141 VectorCopy( ds->lightmapAxis, se->lightmapAxis );
\r
144 //% Sys_FPrintf( SYS_VRB, "SetSurfaceExtra(): entityNum = %d\n", ds->entityNum );
\r
151 getter functions for extra surface data
\r
154 static surfaceExtra_t *GetSurfaceExtra( int num )
\r
156 if( num < 0 || num >= numSurfaceExtras )
\r
158 return &surfaceExtras[ num ];
\r
162 shaderInfo_t *GetSurfaceExtraShaderInfo( int num )
\r
164 surfaceExtra_t *se = GetSurfaceExtra( num );
\r
169 int GetSurfaceExtraParentSurfaceNum( int num )
\r
171 surfaceExtra_t *se = GetSurfaceExtra( num );
\r
172 return se->parentSurfaceNum;
\r
176 int GetSurfaceExtraEntityNum( int num )
\r
178 surfaceExtra_t *se = GetSurfaceExtra( num );
\r
179 return se->entityNum;
\r
183 int GetSurfaceExtraCastShadows( int num )
\r
185 surfaceExtra_t *se = GetSurfaceExtra( num );
\r
186 return se->castShadows;
\r
190 int GetSurfaceExtraRecvShadows( int num )
\r
192 surfaceExtra_t *se = GetSurfaceExtra( num );
\r
193 return se->recvShadows;
\r
197 int GetSurfaceExtraSampleSize( int num )
\r
199 surfaceExtra_t *se = GetSurfaceExtra( num );
\r
200 return se->sampleSize;
\r
204 float GetSurfaceExtraLongestCurve( int num )
\r
206 surfaceExtra_t *se = GetSurfaceExtra( num );
\r
207 return se->longestCurve;
\r
211 void GetSurfaceExtraLightmapAxis( int num, vec3_t lightmapAxis )
\r
213 surfaceExtra_t *se = GetSurfaceExtra( num );
\r
214 VectorCopy( se->lightmapAxis, lightmapAxis );
\r
221 WriteSurfaceExtraFile()
\r
222 writes out a surface info file (<map>.srf)
\r
225 void WriteSurfaceExtraFile( const char *path )
\r
227 char srfPath[ 1024 ];
\r
229 surfaceExtra_t *se;
\r
234 if( path == NULL || path[ 0 ] == '\0' )
\r
238 Sys_Printf( "--- WriteSurfaceExtraFile ---\n" );
\r
240 /* open the file */
\r
241 strcpy( srfPath, path );
\r
242 StripExtension( srfPath );
\r
243 strcat( srfPath, ".srf" );
\r
244 Sys_Printf( "Writing %s\n", srfPath );
\r
245 sf = fopen( srfPath, "w" );
\r
247 Error( "Error opening %s for writing", srfPath );
\r
249 /* lap through the extras list */
\r
250 for( i = -1; i < numSurfaceExtras; i++ )
\r
253 se = GetSurfaceExtra( i );
\r
255 /* default or surface num? */
\r
257 fprintf( sf, "default" );
\r
259 fprintf( sf, "%d", i );
\r
261 /* valid map drawsurf? */
\r
262 if( se->mds == NULL )
\r
263 fprintf( sf, "\n" );
\r
266 fprintf( sf, " // %s V: %d I: %d %s\n",
\r
267 surfaceTypes[ se->mds->type ],
\r
269 se->mds->numIndexes,
\r
270 (se->mds->planar ? "planar" : "") );
\r
274 fprintf( sf, "{\n" );
\r
277 if( se->si != NULL )
\r
278 fprintf( sf, "\tshader %s\n", se->si->shader );
\r
280 /* parent surface number */
\r
281 if( se->parentSurfaceNum != seDefault.parentSurfaceNum )
\r
282 fprintf( sf, "\tparent %d\n", se->parentSurfaceNum );
\r
284 /* entity number */
\r
285 if( se->entityNum != seDefault.entityNum )
\r
286 fprintf( sf, "\tentity %d\n", se->entityNum );
\r
289 if( se->castShadows != seDefault.castShadows || se == &seDefault )
\r
290 fprintf( sf, "\tcastShadows %d\n", se->castShadows );
\r
293 if( se->recvShadows != seDefault.recvShadows || se == &seDefault )
\r
294 fprintf( sf, "\treceiveShadows %d\n", se->recvShadows );
\r
296 /* lightmap sample size */
\r
297 if( se->sampleSize != seDefault.sampleSize || se == &seDefault )
\r
298 fprintf( sf, "\tsampleSize %d\n", se->sampleSize );
\r
300 /* longest curve */
\r
301 if( se->longestCurve != seDefault.longestCurve || se == &seDefault )
\r
302 fprintf( sf, "\tlongestCurve %f\n", se->longestCurve );
\r
304 /* lightmap axis vector */
\r
305 if( VectorCompare( se->lightmapAxis, seDefault.lightmapAxis ) == qfalse )
\r
306 fprintf( sf, "\tlightmapAxis ( %f %f %f )\n", se->lightmapAxis[ 0 ], se->lightmapAxis[ 1 ], se->lightmapAxis[ 2 ] );
\r
309 fprintf( sf, "}\n\n" );
\r
312 /* close the file */
\r
319 LoadSurfaceExtraFile()
\r
320 reads a surface info file (<map>.srf)
\r
323 void LoadSurfaceExtraFile( const char *path )
\r
325 char srfPath[ 1024 ];
\r
326 surfaceExtra_t *se;
\r
327 int surfaceNum, size;
\r
332 if( path == NULL || path[ 0 ] == '\0' )
\r
335 /* load the file */
\r
336 strcpy( srfPath, path );
\r
337 StripExtension( srfPath );
\r
338 strcat( srfPath, ".srf" );
\r
339 Sys_Printf( "Loading %s\n", srfPath );
\r
340 size = LoadFile( srfPath, (void**) &buffer );
\r
343 Sys_Printf( "WARNING: Unable to find surface file %s, using defaults.\n", srfPath );
\r
347 /* parse the file */
\r
348 ParseFromMemory( buffer, size );
\r
353 /* test for end of file */
\r
354 if( !GetToken( qtrue ) )
\r
358 if( !Q_stricmp( token, "default" ) )
\r
361 /* surface number */
\r
364 surfaceNum = atoi( token );
\r
365 if( surfaceNum < 0 || surfaceNum > MAX_MAP_DRAW_SURFS )
\r
366 Error( "ReadSurfaceExtraFile(): %s, line %d: bogus surface num %d", srfPath, scriptline, surfaceNum );
\r
367 while( surfaceNum >= numSurfaceExtras )
\r
368 se = AllocSurfaceExtra();
\r
369 se = &surfaceExtras[ surfaceNum ];
\r
372 /* handle { } section */
\r
373 if( !GetToken( qtrue ) || strcmp( token, "{" ) )
\r
374 Error( "ReadSurfaceExtraFile(): %s, line %d: { not found", srfPath, scriptline );
\r
377 if( !GetToken( qtrue ) )
\r
379 if( !strcmp( token, "}" ) )
\r
383 if( !Q_stricmp( token, "shader" ) )
\r
385 GetToken( qfalse );
\r
386 se->si = ShaderInfoForShader( token );
\r
389 /* parent surface number */
\r
390 else if( !Q_stricmp( token, "parent" ) )
\r
392 GetToken( qfalse );
\r
393 se->parentSurfaceNum = atoi( token );
\r
396 /* entity number */
\r
397 else if( !Q_stricmp( token, "entity" ) )
\r
399 GetToken( qfalse );
\r
400 se->entityNum = atoi( token );
\r
404 else if( !Q_stricmp( token, "castShadows" ) )
\r
406 GetToken( qfalse );
\r
407 se->castShadows = atoi( token );
\r
411 else if( !Q_stricmp( token, "receiveShadows" ) )
\r
413 GetToken( qfalse );
\r
414 se->recvShadows = atoi( token );
\r
417 /* lightmap sample size */
\r
418 else if( !Q_stricmp( token, "sampleSize" ) )
\r
420 GetToken( qfalse );
\r
421 se->sampleSize = atoi( token );
\r
424 /* longest curve */
\r
425 else if( !Q_stricmp( token, "longestCurve" ) )
\r
427 GetToken( qfalse );
\r
428 se->longestCurve = atof( token );
\r
431 /* lightmap axis vector */
\r
432 else if( !Q_stricmp( token, "lightmapAxis" ) )
\r
433 Parse1DMatrix( 3, se->lightmapAxis );
\r
435 /* ignore all other tokens on the line */
\r
436 while( TokenAvailable() )
\r
437 GetToken( qfalse );
\r
441 /* free the buffer */
\r