DeclFX.cpp 11 KB

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