]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/framework/DeclFX.cpp
Various Mac OS X tweaks to get this to build. Probably breaking things.
[icculus/iodoom3.git] / neo / framework / DeclFX.cpp
1 /*
2 ===========================================================================
3
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. 
6
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).  
8
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code.  If not, see <http://www.gnu.org/licenses/>.
21
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code.  If not, please request a copy in writing from id Software at the address below.
23
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25
26 ===========================================================================
27 */
28
29 #include "../idlib/precompiled.h"
30 #pragma hdrstop
31
32
33 /*
34 =================
35 idDeclFX::Size
36 =================
37 */
38 size_t idDeclFX::Size( void ) const {
39         return sizeof( idDeclFX );
40 }
41
42 /*
43 ===============
44 idDeclFX::Print
45 ===============
46 */
47 void idDeclFX::Print( void ) const {
48         const idDeclFX *list = this;
49
50         common->Printf("%d events\n", list->events.Num() );
51         for( int i = 0; i < list->events.Num(); i++ ) {
52                 switch( list->events[i].type ) {
53                         case FX_LIGHT:
54                                 common->Printf("FX_LIGHT %s\n", list->events[i].data.c_str());
55                                 break;
56                         case FX_PARTICLE:
57                                 common->Printf("FX_PARTICLE %s\n", list->events[i].data.c_str());
58                                 break;
59                         case FX_MODEL:
60                                 common->Printf("FX_MODEL %s\n", list->events[i].data.c_str());
61                                 break;
62                         case FX_SOUND:
63                                 common->Printf("FX_SOUND %s\n", list->events[i].data.c_str());
64                                 break;
65                         case FX_DECAL:
66                                 common->Printf("FX_DECAL %s\n", list->events[i].data.c_str());
67                                 break;
68                         case FX_SHAKE:
69                                 common->Printf("FX_SHAKE %s\n", list->events[i].data.c_str());
70                                 break;
71                         case FX_ATTACHLIGHT:
72                                 common->Printf("FX_ATTACHLIGHT %s\n", list->events[i].data.c_str());
73                                 break;
74                         case FX_ATTACHENTITY:
75                                 common->Printf("FX_ATTACHENTITY %s\n", list->events[i].data.c_str());
76                                 break;
77                         case FX_LAUNCH:
78                                 common->Printf("FX_LAUNCH %s\n", list->events[i].data.c_str());
79                                 break;
80                         case FX_SHOCKWAVE:
81                                 common->Printf("FX_SHOCKWAVE %s\n", list->events[i].data.c_str());
82                                 break;
83                 }
84         }
85 }
86
87 /*
88 ===============
89 idDeclFX::List
90 ===============
91 */
92 void idDeclFX::List( void ) const {
93         common->Printf("%s, %d stages\n", GetName(), events.Num() );
94 }
95
96 /*
97 ================
98 idDeclFX::ParseSingleFXAction
99 ================
100 */
101 void idDeclFX::ParseSingleFXAction( idLexer &src, idFXSingleAction& FXAction ) {
102         idToken token;
103
104         FXAction.type = -1;
105         FXAction.sibling = -1;
106
107         FXAction.data = "<none>";
108         FXAction.name = "<none>";
109         FXAction.fire = "<none>";
110
111         FXAction.delay = 0.0f;
112         FXAction.duration = 0.0f;
113         FXAction.restart = 0.0f;
114         FXAction.size = 0.0f;
115         FXAction.fadeInTime = 0.0f;
116         FXAction.fadeOutTime = 0.0f;
117         FXAction.shakeTime = 0.0f;
118         FXAction.shakeAmplitude = 0.0f;
119         FXAction.shakeDistance = 0.0f;
120         FXAction.shakeFalloff = false;
121         FXAction.shakeImpulse = 0.0f;
122         FXAction.shakeIgnoreMaster = false;
123         FXAction.lightRadius = 0.0f;
124         FXAction.rotate = 0.0f;
125         FXAction.random1 = 0.0f;
126         FXAction.random2 = 0.0f;
127
128         FXAction.lightColor = vec3_origin;
129         FXAction.offset = vec3_origin;
130         FXAction.axis = mat3_identity;
131
132         FXAction.bindParticles = false;
133         FXAction.explicitAxis = false;
134         FXAction.noshadows = false;
135         FXAction.particleTrackVelocity = false;
136         FXAction.trackOrigin = false;
137         FXAction.soundStarted = false;
138
139         while (1) {
140                 if ( !src.ReadToken( &token ) ) {
141                         break;
142                 }
143
144                 if ( !token.Icmp( "}" ) ) {
145                         break;
146                 }
147
148                 if ( !token.Icmp( "shake" ) ) {
149                         FXAction.type = FX_SHAKE;
150                         FXAction.shakeTime = src.ParseFloat();
151                         src.ExpectTokenString(",");
152                         FXAction.shakeAmplitude = src.ParseFloat();
153                         src.ExpectTokenString(",");
154                         FXAction.shakeDistance = src.ParseFloat();
155                         src.ExpectTokenString(",");
156                         FXAction.shakeFalloff = src.ParseBool();
157                         src.ExpectTokenString(",");
158                         FXAction.shakeImpulse = src.ParseFloat();
159                         continue;
160                 }
161
162                 if ( !token.Icmp( "noshadows" ) ) {
163                         FXAction.noshadows = true;
164                         continue;
165                 }
166
167                 if ( !token.Icmp( "name" ) ) {
168                         src.ReadToken( &token );
169                         FXAction.name = token;
170                         continue;
171                 }
172
173                 if ( !token.Icmp( "fire") ) {
174                         src.ReadToken( &token );
175                         FXAction.fire = token;
176                         continue;
177                 }
178
179                 if ( !token.Icmp( "random" ) ) {
180                         FXAction.random1 = src.ParseFloat();
181                         src.ExpectTokenString( "," );
182                         FXAction.random2 = src.ParseFloat();
183                         FXAction.delay = 0.0f;          // check random
184                         continue;
185                 }
186
187                 if ( !token.Icmp( "delay" ) ) {
188                         FXAction.delay = src.ParseFloat();
189                         continue;
190                 }
191
192                 if ( !token.Icmp( "rotate" ) ) {
193                         FXAction.rotate = src.ParseFloat();
194                         continue;
195                 }
196
197                 if ( !token.Icmp( "duration" ) ) {
198                         FXAction.duration = src.ParseFloat();
199                         continue;
200                 }
201
202                 if ( !token.Icmp( "trackorigin" ) ) {
203                         FXAction.trackOrigin = src.ParseBool();
204                         continue;
205                 }
206
207                 if (!token.Icmp("restart")) {
208                         FXAction.restart = src.ParseFloat();
209                         continue;
210                 }
211
212                 if ( !token.Icmp( "fadeIn" ) ) {
213                         FXAction.fadeInTime = src.ParseFloat();
214                         continue;
215                 }
216
217                 if ( !token.Icmp( "fadeOut" ) ) {
218                         FXAction.fadeOutTime = src.ParseFloat();
219                         continue;
220                 }
221
222                 if ( !token.Icmp( "size" ) ) {
223                         FXAction.size = src.ParseFloat();
224                         continue;
225                 }
226
227                 if ( !token.Icmp( "offset" ) ) {
228                         FXAction.offset.x = src.ParseFloat();
229                         src.ExpectTokenString( "," );
230                         FXAction.offset.y = src.ParseFloat();
231                         src.ExpectTokenString( "," );
232                         FXAction.offset.z = src.ParseFloat();
233                         continue;
234                 }
235
236                 if ( !token.Icmp( "axis" ) ) {
237                         idVec3 v;
238                         v.x = src.ParseFloat();
239                         src.ExpectTokenString( "," );
240                         v.y = src.ParseFloat();
241                         src.ExpectTokenString( "," );
242                         v.z = src.ParseFloat();
243                         v.Normalize();
244                         FXAction.axis = v.ToMat3();
245                         FXAction.explicitAxis = true;
246                         continue;
247                 }
248
249                 if ( !token.Icmp( "angle" ) ) {
250                         idAngles a;
251                         a[0] = src.ParseFloat();
252                         src.ExpectTokenString( "," );
253                         a[1] = src.ParseFloat();
254                         src.ExpectTokenString( "," );
255                         a[2] = src.ParseFloat();
256                         FXAction.axis = a.ToMat3();
257                         FXAction.explicitAxis = true;
258                         continue;
259                 }
260
261                 if ( !token.Icmp( "uselight" ) ) {
262                         src.ReadToken( &token );
263                         FXAction.data = token;
264                         for( int i = 0; i < events.Num(); i++ ) {
265                                 if ( events[i].name.Icmp( FXAction.data ) == 0 ) {
266                                         FXAction.sibling = i;
267                                         FXAction.lightColor = events[i].lightColor;
268                                         FXAction.lightRadius = events[i].lightRadius;
269                                 }
270                         }
271                         FXAction.type = FX_LIGHT;
272
273                         // precache the light material
274                         declManager->FindMaterial( FXAction.data );
275                         continue;
276                 }
277
278                 if ( !token.Icmp( "attachlight" ) ) {
279                         src.ReadToken( &token );
280                         FXAction.data = token;
281                         FXAction.type = FX_ATTACHLIGHT;
282
283                         // precache it
284                         declManager->FindMaterial( FXAction.data );
285                         continue;
286                 }
287
288                 if ( !token.Icmp( "attachentity" ) ) {
289                         src.ReadToken( &token );
290                         FXAction.data = token;
291                         FXAction.type = FX_ATTACHENTITY;
292
293                         // precache the model
294                         renderModelManager->FindModel( FXAction.data );
295                         continue;
296                 }
297
298                 if ( !token.Icmp( "launch" ) ) {
299                         src.ReadToken( &token );
300                         FXAction.data = token;
301                         FXAction.type = FX_LAUNCH;
302
303                         // precache the entity def
304                         declManager->FindType( DECL_ENTITYDEF, FXAction.data );
305                         continue;
306                 }
307
308                 if ( !token.Icmp( "useModel" ) ) {
309                         src.ReadToken( &token );
310                         FXAction.data = token;
311                         for( int i = 0; i < events.Num(); i++ ) {
312                                 if ( events[i].name.Icmp( FXAction.data ) == 0 ) {
313                                         FXAction.sibling = i;
314                                 }
315                         }
316                         FXAction.type = FX_MODEL;
317
318                         // precache the model
319                         renderModelManager->FindModel( FXAction.data );
320                         continue;
321                 }
322
323                 if ( !token.Icmp( "light" ) ) {
324                         src.ReadToken( &token );
325                         FXAction.data = token;
326                         src.ExpectTokenString( "," );
327                         FXAction.lightColor[0] = src.ParseFloat();
328                         src.ExpectTokenString( "," );
329                         FXAction.lightColor[1] = src.ParseFloat();
330                         src.ExpectTokenString( "," );
331                         FXAction.lightColor[2] = src.ParseFloat();
332                         src.ExpectTokenString( "," );
333                         FXAction.lightRadius = src.ParseFloat();
334                         FXAction.type = FX_LIGHT;
335
336                         // precache the light material
337                         declManager->FindMaterial( FXAction.data );
338                         continue;
339                 }
340         
341                 if ( !token.Icmp( "model" ) ) {
342                         src.ReadToken( &token );
343                         FXAction.data = token;
344                         FXAction.type = FX_MODEL;
345
346                         // precache it
347                         renderModelManager->FindModel( FXAction.data );
348                         continue;
349                 }
350
351                 if ( !token.Icmp( "particle" ) ) {      // FIXME: now the same as model
352                         src.ReadToken( &token );
353                         FXAction.data = token;
354                         FXAction.type = FX_PARTICLE;
355
356                         // precache it
357                         renderModelManager->FindModel( FXAction.data );
358                         continue;
359                 }
360
361                 if ( !token.Icmp( "decal" ) ) {
362                         src.ReadToken( &token );
363                         FXAction.data = token;
364                         FXAction.type = FX_DECAL;
365
366                         // precache it
367                         declManager->FindMaterial( FXAction.data );
368                         continue;
369                 }
370
371                 if ( !token.Icmp( "particleTrackVelocity" ) ) {
372                         FXAction.particleTrackVelocity = true;
373                         continue;
374                 }
375
376                 if ( !token.Icmp( "sound" ) ) {
377                         src.ReadToken( &token );
378                         FXAction.data = token;
379                         FXAction.type = FX_SOUND;
380
381                         // precache it
382                         declManager->FindSound( FXAction.data );
383                         continue;
384                 }
385
386                 if ( !token.Icmp( "ignoreMaster" ) ) {
387                         FXAction.shakeIgnoreMaster = true;
388                         continue;
389                 }
390
391                 if ( !token.Icmp( "shockwave" ) ) {
392                         src.ReadToken( &token );
393                         FXAction.data = token;
394                         FXAction.type = FX_SHOCKWAVE;
395
396                         // precache the entity def
397                         declManager->FindType( DECL_ENTITYDEF, FXAction.data );
398                         continue;
399                 }
400
401                 src.Warning( "FX File: bad token" );
402                 continue;
403         }
404 }
405
406 /*
407 ================
408 idDeclFX::Parse
409 ================
410 */
411 bool idDeclFX::Parse( const char *text, const int textLength ) {
412         idLexer src;
413         idToken token;
414
415         src.LoadMemory( text, textLength, GetFileName(), GetLineNum() );
416         src.SetFlags( DECL_LEXER_FLAGS );
417         src.SkipUntilString( "{" );
418
419         // scan through, identifying each individual parameter
420         while( 1 ) {
421                 
422                 if ( !src.ReadToken( &token ) ) {
423                         break;
424                 }
425
426                 if ( token == "}" ) {
427                         break;
428                 }
429
430                 if ( !token.Icmp( "bindto" ) ) {
431                         src.ReadToken( &token );
432                         joint = token;
433                         continue;
434                 }
435
436                 if ( !token.Icmp( "{" ) ) {
437                         idFXSingleAction action;
438                         ParseSingleFXAction( src, action );
439                         events.Append( action );
440                         continue;
441                 }
442         }
443
444         if ( src.HadError() ) {
445                 src.Warning( "FX decl '%s' had a parse error", GetName() );
446                 return false;
447         }
448         return true;
449 }
450
451 /*
452 ===================
453 idDeclFX::DefaultDefinition
454 ===================
455 */
456 const char *idDeclFX::DefaultDefinition( void ) const {
457         return
458                 "{\n"
459         "\t"    "{\n"
460         "\t\t"          "duration\t5\n"
461         "\t\t"          "model\t\t_default\n"
462         "\t"    "}\n"
463                 "}"; 
464 }
465
466 /*
467 ===================
468 idDeclFX::FreeData
469 ===================
470 */
471 void idDeclFX::FreeData( void ) {
472         events.Clear();
473 }