DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

DeclFX.cpp (11375B)


      1 /*
      2 ===========================================================================
      3 
      4 Doom 3 BFG Edition GPL Source Code
      5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 
      6 
      7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").  
      8 
      9 Doom 3 BFG Edition 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 BFG Edition 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 BFG Edition Source Code.  If not, see <http://www.gnu.org/licenses/>.
     21 
     22 In addition, the Doom 3 BFG Edition 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 BFG Edition 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() const {
     39 	return sizeof( idDeclFX );
     40 }
     41 
     42 /*
     43 ===============
     44 idDeclFX::Print
     45 ===============
     46 */
     47 void idDeclFX::Print() 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() 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, bool allowBinaryVersion ) {
    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() 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() {
    472 	events.Clear();
    473 }