]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake3/q3map2/surface_extra.c
eol style
[xonotic/netradiant.git] / tools / quake3 / q3map2 / surface_extra.c
1 /*
2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20
21 ----------------------------------------------------------------------------------
22
23 This code has been altered significantly from its original form, to support
24 several games based on the Quake III Arena engine, in the form of "Q3Map2."
25
26 ------------------------------------------------------------------------------- */
27
28
29
30 /* marker */
31 #define SURFACE_EXTRA_C
32
33
34
35 /* dependencies */
36 #include "q3map2.h"
37
38
39
40 /* -------------------------------------------------------------------------------
41
42 ydnar: srf file module
43
44 ------------------------------------------------------------------------------- */
45
46 typedef struct surfaceExtra_s
47 {
48         mapDrawSurface_t                *mds;
49         shaderInfo_t                    *si;
50         int                                             parentSurfaceNum;
51         int                                             entityNum;
52         int                                             castShadows, recvShadows;
53         int                                             sampleSize;
54         float                                   longestCurve;
55         vec3_t                                  lightmapAxis;
56 }
57 surfaceExtra_t;
58
59 #define GROW_SURFACE_EXTRAS     1024
60
61 int                                                     numSurfaceExtras = 0;
62 int                                                     maxSurfaceExtras = 0;
63 surfaceExtra_t                          *surfaceExtras;
64 surfaceExtra_t                          seDefault = { NULL, NULL, -1, 0, WORLDSPAWN_CAST_SHADOWS, WORLDSPAWN_RECV_SHADOWS, 0, 0, { 0, 0, 0 } };
65
66
67
68 /*
69 AllocSurfaceExtra()
70 allocates a new extra storage
71 */
72
73 static surfaceExtra_t *AllocSurfaceExtra( void )
74 {
75         surfaceExtra_t  *se;
76         
77         
78         /* enough space? */
79         if( numSurfaceExtras >= maxSurfaceExtras )
80         {
81                 /* reallocate more room */
82                 maxSurfaceExtras += GROW_SURFACE_EXTRAS;
83                 se = safe_malloc( maxSurfaceExtras * sizeof( surfaceExtra_t ) );
84                 if( surfaceExtras != NULL )
85                 {
86                         memcpy( se, surfaceExtras, numSurfaceExtras * sizeof( surfaceExtra_t ) );
87                         free( surfaceExtras );
88                 }
89                 surfaceExtras = se;
90         }
91         
92         /* add another */
93         se = &surfaceExtras[ numSurfaceExtras ];
94         numSurfaceExtras++;
95         memcpy( se, &seDefault, sizeof( surfaceExtra_t ) );
96         
97         /* return it */
98         return se;
99 }
100
101
102
103 /*
104 SetDefaultSampleSize()
105 sets the default lightmap sample size
106 */
107
108 void SetDefaultSampleSize( int sampleSize )
109 {
110         seDefault.sampleSize = sampleSize;
111 }
112
113
114
115 /*
116 SetSurfaceExtra()
117 stores extra (q3map2) data for the specific numbered drawsurface
118 */
119
120 void SetSurfaceExtra( mapDrawSurface_t *ds, int num )
121 {
122         surfaceExtra_t  *se;
123         
124         
125         /* dummy check */
126         if( ds == NULL || num < 0 )
127                 return;
128         
129         /* get a new extra */
130         se = AllocSurfaceExtra();
131         
132         /* copy out the relevant bits */
133         se->mds = ds;
134         se->si = ds->shaderInfo;
135         se->parentSurfaceNum = ds->parent != NULL ? ds->parent->outputNum : -1;
136         se->entityNum = ds->entityNum;
137         se->castShadows = ds->castShadows;
138         se->recvShadows = ds->recvShadows;
139         se->sampleSize = ds->sampleSize;
140         se->longestCurve = ds->longestCurve;
141         VectorCopy( ds->lightmapAxis, se->lightmapAxis );
142         
143         /* debug code */
144         //%     Sys_FPrintf( SYS_VRB, "SetSurfaceExtra(): entityNum = %d\n", ds->entityNum );
145 }
146
147
148
149 /*
150 GetSurfaceExtra*()
151 getter functions for extra surface data
152 */
153
154 static surfaceExtra_t *GetSurfaceExtra( int num )
155 {
156         if( num < 0 || num >= numSurfaceExtras )
157                 return &seDefault;
158         return &surfaceExtras[ num ];
159 }
160
161
162 shaderInfo_t *GetSurfaceExtraShaderInfo( int num )
163 {
164         surfaceExtra_t  *se = GetSurfaceExtra( num );
165         return se->si;
166 }
167
168
169 int GetSurfaceExtraParentSurfaceNum( int num )
170 {
171         surfaceExtra_t  *se = GetSurfaceExtra( num );
172         return se->parentSurfaceNum;
173 }
174
175
176 int GetSurfaceExtraEntityNum( int num )
177 {
178         surfaceExtra_t  *se = GetSurfaceExtra( num );
179         return se->entityNum;
180 }
181
182
183 int GetSurfaceExtraCastShadows( int num )
184 {
185         surfaceExtra_t  *se = GetSurfaceExtra( num );
186         return se->castShadows;
187 }
188
189
190 int GetSurfaceExtraRecvShadows( int num )
191 {
192         surfaceExtra_t  *se = GetSurfaceExtra( num );
193         return se->recvShadows;
194 }
195
196
197 int GetSurfaceExtraSampleSize( int num )
198 {
199         surfaceExtra_t  *se = GetSurfaceExtra( num );
200         return se->sampleSize;
201 }
202
203
204 float GetSurfaceExtraLongestCurve( int num )
205 {
206         surfaceExtra_t  *se = GetSurfaceExtra( num );
207         return se->longestCurve;
208 }
209
210
211 void GetSurfaceExtraLightmapAxis( int num, vec3_t lightmapAxis )
212 {
213         surfaceExtra_t  *se = GetSurfaceExtra( num );
214         VectorCopy( se->lightmapAxis, lightmapAxis );
215 }
216
217
218
219
220 /*
221 WriteSurfaceExtraFile()
222 writes out a surface info file (<map>.srf)
223 */
224
225 void WriteSurfaceExtraFile( const char *path )
226 {
227         char                    srfPath[ 1024 ];
228         FILE                    *sf;
229         surfaceExtra_t  *se;
230         int                             i;
231         
232         
233         /* dummy check */
234         if( path == NULL || path[ 0 ] == '\0' )
235                 return;
236         
237         /* note it */
238         Sys_Printf( "--- WriteSurfaceExtraFile ---\n" );
239         
240         /* open the file */
241         strcpy( srfPath, path );
242         StripExtension( srfPath );
243         strcat( srfPath, ".srf" );
244         Sys_Printf( "Writing %s\n", srfPath );
245         sf = fopen( srfPath, "w" );
246         if( sf == NULL )
247                 Error( "Error opening %s for writing", srfPath );
248         
249         /* lap through the extras list */
250         for( i = -1; i < numSurfaceExtras; i++ )
251         {
252                 /* get extra */
253                 se = GetSurfaceExtra( i );
254                 
255                 /* default or surface num? */
256                 if( i < 0 )
257                         fprintf( sf, "default" );
258                 else
259                         fprintf( sf, "%d", i );
260                 
261                 /* valid map drawsurf? */
262                 if( se->mds == NULL )
263                         fprintf( sf, "\n" );
264                 else
265                 {
266                         fprintf( sf, " // %s V: %d I: %d %s\n",
267                                 surfaceTypes[ se->mds->type ],
268                                 se->mds->numVerts,
269                                 se->mds->numIndexes,
270                                 (se->mds->planar ? "planar" : "") );
271                 }
272                 
273                 /* open braces */
274                 fprintf( sf, "{\n" );
275                 
276                         /* shader */
277                         if( se->si != NULL )
278                                 fprintf( sf, "\tshader %s\n", se->si->shader );
279                         
280                         /* parent surface number */
281                         if( se->parentSurfaceNum != seDefault.parentSurfaceNum )
282                                 fprintf( sf, "\tparent %d\n", se->parentSurfaceNum );
283                         
284                         /* entity number */
285                         if( se->entityNum != seDefault.entityNum )
286                                 fprintf( sf, "\tentity %d\n", se->entityNum );
287                         
288                         /* cast shadows */
289                         if( se->castShadows != seDefault.castShadows || se == &seDefault )
290                                 fprintf( sf, "\tcastShadows %d\n", se->castShadows );
291                         
292                         /* recv shadows */
293                         if( se->recvShadows != seDefault.recvShadows || se == &seDefault )
294                                 fprintf( sf, "\treceiveShadows %d\n", se->recvShadows );
295                         
296                         /* lightmap sample size */
297                         if( se->sampleSize != seDefault.sampleSize || se == &seDefault )
298                                 fprintf( sf, "\tsampleSize %d\n", se->sampleSize );
299                         
300                         /* longest curve */
301                         if( se->longestCurve != seDefault.longestCurve || se == &seDefault )
302                                 fprintf( sf, "\tlongestCurve %f\n", se->longestCurve );
303                         
304                         /* lightmap axis vector */
305                         if( VectorCompare( se->lightmapAxis, seDefault.lightmapAxis ) == qfalse )
306                                 fprintf( sf, "\tlightmapAxis ( %f %f %f )\n", se->lightmapAxis[ 0 ], se->lightmapAxis[ 1 ], se->lightmapAxis[ 2 ] );
307                 
308                 /* close braces */
309                 fprintf( sf, "}\n\n" );
310         }
311         
312         /* close the file */
313         fclose( sf );
314 }
315
316
317
318 /*
319 LoadSurfaceExtraFile()
320 reads a surface info file (<map>.srf)
321 */
322
323 void LoadSurfaceExtraFile( const char *path )
324 {
325         char                    srfPath[ 1024 ];
326         surfaceExtra_t  *se;
327         int                             surfaceNum, size;
328         byte                    *buffer;
329         
330         
331         /* dummy check */
332         if( path == NULL || path[ 0 ] == '\0' )
333                 return;
334         
335         /* load the file */
336         strcpy( srfPath, path );
337         StripExtension( srfPath );
338         strcat( srfPath, ".srf" );
339         Sys_Printf( "Loading %s\n", srfPath );
340         size = LoadFile( srfPath, (void**) &buffer );
341         if( size <= 0 )
342         {
343                 Sys_Printf( "WARNING: Unable to find surface file %s, using defaults.\n", srfPath );
344                 return;
345         }
346         
347         /* parse the file */
348         ParseFromMemory( buffer, size );
349         
350         /* tokenize it */
351         while( 1 )
352         {
353                 /* test for end of file */
354                 if( !GetToken( qtrue ) )
355                         break;
356                 
357                 /* default? */
358                 if( !Q_stricmp( token, "default" ) )
359                         se = &seDefault;
360
361                 /* surface number */
362                 else
363                 {
364                         surfaceNum = atoi( token );
365                         if( surfaceNum < 0 || surfaceNum > MAX_MAP_DRAW_SURFS )
366                                 Error( "ReadSurfaceExtraFile(): %s, line %d: bogus surface num %d", srfPath, scriptline, surfaceNum );
367                         while( surfaceNum >= numSurfaceExtras )
368                                 se = AllocSurfaceExtra();
369                         se = &surfaceExtras[ surfaceNum ];
370                 }
371                 
372                 /* handle { } section */
373                 if( !GetToken( qtrue ) || strcmp( token, "{" ) )
374                         Error( "ReadSurfaceExtraFile(): %s, line %d: { not found", srfPath, scriptline );
375                 while( 1 )
376                 {
377                         if( !GetToken( qtrue ) )
378                                 break;
379                         if( !strcmp( token, "}" ) )
380                                 break;
381                         
382                         /* shader */
383                         if( !Q_stricmp( token, "shader" ) )
384                         {
385                                 GetToken( qfalse );
386                                 se->si = ShaderInfoForShader( token );
387                         }
388                         
389                         /* parent surface number */
390                         else if( !Q_stricmp( token, "parent" ) )
391                         {
392                                 GetToken( qfalse );
393                                 se->parentSurfaceNum = atoi( token );
394                         }
395                         
396                         /* entity number */
397                         else if( !Q_stricmp( token, "entity" ) )
398                         {
399                                 GetToken( qfalse );
400                                 se->entityNum = atoi( token );
401                         }
402                         
403                         /* cast shadows */
404                         else if( !Q_stricmp( token, "castShadows" ) )
405                         {
406                                 GetToken( qfalse );
407                                 se->castShadows = atoi( token );
408                         }
409                         
410                         /* recv shadows */
411                         else if( !Q_stricmp( token, "receiveShadows" ) )
412                         {
413                                 GetToken( qfalse );
414                                 se->recvShadows = atoi( token );
415                         }
416                         
417                         /* lightmap sample size */
418                         else if( !Q_stricmp( token, "sampleSize" ) )
419                         {
420                                 GetToken( qfalse );
421                                 se->sampleSize = atoi( token );
422                         }
423                         
424                         /* longest curve */
425                         else if( !Q_stricmp( token, "longestCurve" ) )
426                         {
427                                 GetToken( qfalse );
428                                 se->longestCurve = atof( token );
429                         }
430                         
431                         /* lightmap axis vector */
432                         else if( !Q_stricmp( token, "lightmapAxis" ) )
433                                 Parse1DMatrix( 3, se->lightmapAxis );
434                         
435                         /* ignore all other tokens on the line */
436                         while( TokenAvailable() )
437                                 GetToken( qfalse );
438                 }
439         }
440         
441         /* free the buffer */
442         free( buffer );
443 }
444