Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3863 lines
95 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #if defined(_WIN32) && !defined(_X360)
  9. #include <windows.h>
  10. #endif
  11. #include "basetypes.h"
  12. #include <stdio.h>
  13. #include "choreoscene.h"
  14. #include "choreoevent.h"
  15. #include "choreochannel.h"
  16. #include "choreoactor.h"
  17. #include "ichoreoeventcallback.h"
  18. #include "iscenetokenprocessor.h"
  19. #include "utlbuffer.h"
  20. #include "filesystem.h"
  21. #include "utlrbtree.h"
  22. #include "mathlib/mathlib.h"
  23. #include "tier1/strtools.h"
  24. #include "tier2/tier2.h"
  25. // memdbgon must be the last include file in a .cpp file!!!
  26. #include "tier0/memdbgon.h"
  27. #pragma warning( disable : 4127 )
  28. // Let scene linger for 1/4 second so blends can finish
  29. #define SCENE_LINGER_TIME 0.25f
  30. // The engine turns this to true in dlls/sceneentity.cpp at bool SceneCacheInit()!!!
  31. bool CChoreoScene::s_bEditingDisabled = false;
  32. //-----------------------------------------------------------------------------
  33. // Purpose: Creates scene from a file
  34. // Input : *filename -
  35. // *pfn -
  36. // Output : CChoreoScene
  37. //-----------------------------------------------------------------------------
  38. CChoreoScene *ChoreoLoadScene(
  39. char const *filename,
  40. IChoreoEventCallback *callback,
  41. ISceneTokenProcessor *tokenizer,
  42. void ( *pfn ) ( const char *fmt, ... ) )
  43. {
  44. MEM_ALLOC_CREDIT();
  45. CChoreoScene *scene = new CChoreoScene( callback );
  46. Assert( scene );
  47. scene->ParseFromBuffer( filename, tokenizer );
  48. scene->SetPrintFunc( pfn );
  49. return scene;
  50. }
  51. bool IsBufferBinaryVCD( char *pBuffer, int bufferSize )
  52. {
  53. if ( bufferSize > 4 && *(int *)pBuffer == SCENE_BINARY_TAG )
  54. {
  55. return true;
  56. }
  57. return false;
  58. }
  59. //-----------------------------------------------------------------------------
  60. // Purpose: Debug printout
  61. // Input : level -
  62. // *fmt -
  63. // ... -
  64. //-----------------------------------------------------------------------------
  65. void CChoreoScene::choreoprintf( int level, const char *fmt, ... )
  66. {
  67. char string[ 2048 ];
  68. va_list argptr;
  69. va_start( argptr, fmt );
  70. Q_vsnprintf( string, sizeof(string), fmt, argptr );
  71. va_end( argptr );
  72. while ( level-- > 0 )
  73. {
  74. if (m_pfnPrint )
  75. {
  76. (*m_pfnPrint)( " " );
  77. }
  78. else
  79. {
  80. printf( " " );
  81. }
  82. Msg( " " );
  83. }
  84. if ( m_pfnPrint )
  85. {
  86. (*m_pfnPrint)( string );
  87. }
  88. else
  89. {
  90. printf( "%s", string );
  91. }
  92. Msg( "%s", string );
  93. }
  94. //-----------------------------------------------------------------------------
  95. // Purpose:
  96. //-----------------------------------------------------------------------------
  97. CChoreoScene::CChoreoScene( IChoreoEventCallback *callback )
  98. {
  99. Init( callback );
  100. }
  101. //-----------------------------------------------------------------------------
  102. // Purpose: // Assignment
  103. // Input : src -
  104. // Output : CChoreoScene&
  105. //-----------------------------------------------------------------------------
  106. CChoreoScene& CChoreoScene::operator=( const CChoreoScene& src )
  107. {
  108. Init( src.m_pIChoreoEventCallback );
  109. // Delete existing
  110. int i;
  111. for ( i = 0; i < m_Actors.Size(); i++ )
  112. {
  113. CChoreoActor *a = m_Actors[ i ];
  114. Assert( a );
  115. delete a;
  116. }
  117. m_Actors.RemoveAll();
  118. for ( i = 0; i < m_Events.Size(); i++ )
  119. {
  120. CChoreoEvent *e = m_Events[ i ];
  121. Assert( e );
  122. delete e;
  123. }
  124. m_Events.RemoveAll();
  125. for ( i = 0 ; i < m_Channels.Size(); i++ )
  126. {
  127. CChoreoChannel *c = m_Channels[ i ];
  128. Assert( c );
  129. delete c;
  130. }
  131. m_Channels.RemoveAll();
  132. m_pTokenizer = src.m_pTokenizer;
  133. m_flCurrentTime = src.m_flCurrentTime;
  134. m_flStartLoopTime = src.m_flStartLoopTime;
  135. m_flStartTime = src.m_flStartTime;
  136. m_flEndTime = src.m_flEndTime;
  137. m_flSoundSystemLatency = src.m_flSoundSystemLatency;
  138. m_pfnPrint = src.m_pfnPrint;
  139. m_flLastActiveTime = src.m_flLastActiveTime;
  140. m_pTokenizer = src.m_pTokenizer;
  141. m_bSubScene = src.m_bSubScene;
  142. m_nSceneFPS = src.m_nSceneFPS;
  143. m_bUseFrameSnap = src.m_bUseFrameSnap;
  144. m_bIgnorePhonemes = src.m_bIgnorePhonemes;
  145. // Now copy the object tree
  146. // First copy the global events
  147. for ( i = 0; i < src.m_Events.Size(); i++ )
  148. {
  149. CChoreoEvent *event = src.m_Events[ i ];
  150. if ( event->GetActor() == NULL )
  151. {
  152. MEM_ALLOC_CREDIT();
  153. // Copy it
  154. CChoreoEvent *newEvent = AllocEvent();
  155. *newEvent = *event;
  156. }
  157. }
  158. // Finally, push actors, channels, events onto global stacks
  159. for ( i = 0; i < src.m_Actors.Size(); i++ )
  160. {
  161. CChoreoActor *actor = src.m_Actors[ i ];
  162. CChoreoActor *newActor = AllocActor();
  163. *newActor = *actor;
  164. for ( int j = 0; j < newActor->GetNumChannels() ; j++ )
  165. {
  166. CChoreoChannel *ch = newActor->GetChannel( j );
  167. m_Channels.AddToTail( ch );
  168. for ( int k = 0; k < ch->GetNumEvents(); k++ )
  169. {
  170. CChoreoEvent *ev = ch->GetEvent( k );
  171. m_Events.AddToTail( ev );
  172. ev->SetScene( this );
  173. }
  174. }
  175. }
  176. Q_strncpy( m_szMapname, src.m_szMapname, sizeof( m_szMapname ) );
  177. m_SceneRamp = src.m_SceneRamp;
  178. m_TimeZoomLookup.RemoveAll();
  179. for ( i = 0; i < (int)src.m_TimeZoomLookup.Count(); i++ )
  180. {
  181. m_TimeZoomLookup.Insert( src.m_TimeZoomLookup.GetElementName( i ), src.m_TimeZoomLookup[ i ] );
  182. }
  183. Q_strncpy( m_szFileName, src.m_szFileName, sizeof( m_szFileName ) );
  184. m_nLastPauseEvent = src.m_nLastPauseEvent;
  185. m_flPrecomputedStopTime = src.m_flPrecomputedStopTime;
  186. m_bitvecHasEventOfType = src.m_bitvecHasEventOfType;
  187. return *this;
  188. }
  189. //-----------------------------------------------------------------------------
  190. // Purpose:
  191. //-----------------------------------------------------------------------------
  192. void CChoreoScene::Init( IChoreoEventCallback *callback )
  193. {
  194. m_flPrecomputedStopTime = 0.0f;
  195. m_pTokenizer = NULL;
  196. m_szMapname[ 0 ] = 0;
  197. m_flCurrentTime = 0.0f;
  198. m_flStartLoopTime = -1.f;
  199. m_flStartTime = 0.0f;
  200. m_flEndTime = 0.0f;
  201. m_flSoundSystemLatency = 0.0f;
  202. m_pfnPrint = NULL;
  203. m_flLastActiveTime = 0.0f;
  204. m_flEarliestTime = 0.0f;
  205. m_flLatestTime = 0.0f;
  206. m_nActiveEvents = 0;
  207. m_pIChoreoEventCallback = callback;
  208. m_bSubScene = false;
  209. m_nSceneFPS = DEFAULT_SCENE_FPS;
  210. m_bUseFrameSnap = false;
  211. m_szFileName[0] = 0;
  212. m_bIsBackground = false;
  213. m_bitvecHasEventOfType.ClearAll();
  214. m_nLastPauseEvent = -1;
  215. m_bIgnorePhonemes = false;
  216. }
  217. //-----------------------------------------------------------------------------
  218. // Purpose: Destroy objects and queues
  219. //-----------------------------------------------------------------------------
  220. CChoreoScene::~CChoreoScene( void )
  221. {
  222. int i;
  223. for ( i = 0; i < m_Actors.Size(); i++ )
  224. {
  225. CChoreoActor *a = m_Actors[ i ];
  226. Assert( a );
  227. delete a;
  228. }
  229. m_Actors.RemoveAll();
  230. for ( i = 0; i < m_Events.Size(); i++ )
  231. {
  232. CChoreoEvent *e = m_Events[ i ];
  233. Assert( e );
  234. delete e;
  235. }
  236. m_Events.RemoveAll();
  237. for ( i = 0 ; i < m_Channels.Size(); i++ )
  238. {
  239. CChoreoChannel *c = m_Channels[ i ];
  240. Assert( c );
  241. delete c;
  242. }
  243. m_Channels.RemoveAll();
  244. }
  245. //-----------------------------------------------------------------------------
  246. // Ignore phonemes
  247. //-----------------------------------------------------------------------------
  248. void CChoreoScene::IgnorePhonemes( bool bIgnore )
  249. {
  250. m_bIgnorePhonemes = bIgnore;
  251. }
  252. bool CChoreoScene::ShouldIgnorePhonemes() const
  253. {
  254. return m_bIgnorePhonemes;
  255. }
  256. //-----------------------------------------------------------------------------
  257. // Purpose:
  258. // Input : *callback -
  259. //-----------------------------------------------------------------------------
  260. void CChoreoScene::SetEventCallbackInterface( IChoreoEventCallback *callback )
  261. {
  262. m_pIChoreoEventCallback = callback;
  263. }
  264. //-----------------------------------------------------------------------------
  265. // Purpose:
  266. // Input : level -
  267. // *e -
  268. //-----------------------------------------------------------------------------
  269. void CChoreoScene::PrintEvent( int level, CChoreoEvent *e )
  270. {
  271. choreoprintf( level, "event %s \"%s\"\n", CChoreoEvent::NameForType( e->GetType() ), e->GetName() );
  272. choreoprintf( level, "{\n" );
  273. choreoprintf( level + 1, "time %f %f\n", e->GetStartTime(), e->GetEndTime() );
  274. choreoprintf( level + 1, "param \"%s\"\n", e->GetParameters() );
  275. if ( strlen( e->GetParameters2() ) > 0 )
  276. {
  277. choreoprintf( level + 1, "param2 \"%s\"\n", e->GetParameters2() );
  278. }
  279. if ( strlen( e->GetParameters3() ) > 0 )
  280. {
  281. choreoprintf( level + 1, "param3 \"%s\"\n", e->GetParameters3() );
  282. }
  283. choreoprintf( level, "}\n" );
  284. }
  285. //-----------------------------------------------------------------------------
  286. // Purpose:
  287. // Input : level -
  288. // *c -
  289. //-----------------------------------------------------------------------------
  290. void CChoreoScene::PrintChannel( int level, CChoreoChannel *c )
  291. {
  292. choreoprintf( level, "channel \"%s\"\n", c->GetName() );
  293. choreoprintf( level, "{\n" );
  294. for ( int i = 0; i < c->GetNumEvents(); i++ )
  295. {
  296. CChoreoEvent *e = c->GetEvent( i );
  297. if ( e )
  298. {
  299. PrintEvent( level + 1, e );
  300. }
  301. }
  302. choreoprintf( level, "}\n" );
  303. }
  304. //-----------------------------------------------------------------------------
  305. // Purpose:
  306. // Input : level -
  307. // *a -
  308. //-----------------------------------------------------------------------------
  309. void CChoreoScene::PrintActor( int level, CChoreoActor *a )
  310. {
  311. choreoprintf( level, "actor \"%s\"\n", a->GetName() );
  312. choreoprintf( level, "{\n" );
  313. for ( int i = 0; i < a->GetNumChannels(); i++ )
  314. {
  315. CChoreoChannel *c = a->GetChannel( i );
  316. if ( c )
  317. {
  318. PrintChannel( level + 1, c );
  319. }
  320. }
  321. choreoprintf( level, "}\n\n" );
  322. }
  323. //-----------------------------------------------------------------------------
  324. // Purpose:
  325. //-----------------------------------------------------------------------------
  326. void CChoreoScene::Print( void )
  327. {
  328. // Look for events that don't have actor/channel set
  329. int i;
  330. for ( i = 0 ; i < m_Events.Size(); i++ )
  331. {
  332. CChoreoEvent *e = m_Events[ i ];
  333. if ( e->GetActor() )
  334. continue;
  335. PrintEvent( 0, e );
  336. }
  337. for ( i = 0 ; i < m_Actors.Size(); i++ )
  338. {
  339. CChoreoActor *a = m_Actors[ i ];
  340. if ( !a )
  341. continue;
  342. PrintActor( 0, a );
  343. }
  344. }
  345. //-----------------------------------------------------------------------------
  346. // Purpose: prints if m_pfnPrint is active
  347. // Output :
  348. //-----------------------------------------------------------------------------
  349. void CChoreoScene::SceneMsg( const char *pFormat, ... )
  350. {
  351. char string[ 2048 ];
  352. va_list argptr;
  353. va_start( argptr, pFormat );
  354. Q_vsnprintf( string, sizeof(string), pFormat, argptr );
  355. va_end( argptr );
  356. if ( m_pfnPrint )
  357. {
  358. (*m_pfnPrint)( string );
  359. }
  360. else
  361. {
  362. Msg( "%s", string );
  363. }
  364. }
  365. //-----------------------------------------------------------------------------
  366. // Purpose:
  367. // Output : CChoreoEvent
  368. //-----------------------------------------------------------------------------
  369. CChoreoEvent *CChoreoScene::AllocEvent( void )
  370. {
  371. MEM_ALLOC_CREDIT_CLASS();
  372. CChoreoEvent *e = new CChoreoEvent( this );
  373. Assert( e );
  374. m_Events.AddToTail( e );
  375. return e;
  376. }
  377. //-----------------------------------------------------------------------------
  378. // Purpose:
  379. // Output : CChoreoChannel
  380. //-----------------------------------------------------------------------------
  381. CChoreoChannel *CChoreoScene::AllocChannel( void )
  382. {
  383. MEM_ALLOC_CREDIT_CLASS();
  384. CChoreoChannel *c = new CChoreoChannel();
  385. Assert( c );
  386. m_Channels.AddToTail( c );
  387. return c;
  388. }
  389. //-----------------------------------------------------------------------------
  390. // Purpose:
  391. // Output : CChoreoActor
  392. //-----------------------------------------------------------------------------
  393. CChoreoActor *CChoreoScene::AllocActor( void )
  394. {
  395. MEM_ALLOC_CREDIT_CLASS();
  396. CChoreoActor *a = new CChoreoActor;
  397. Assert( a );
  398. m_Actors.AddToTail( a );
  399. return a;
  400. }
  401. //-----------------------------------------------------------------------------
  402. // Purpose:
  403. // Input : *name -
  404. // Output : CChoreoActor
  405. //-----------------------------------------------------------------------------
  406. CChoreoActor *CChoreoScene::FindActor( const char *name )
  407. {
  408. for ( int i = 0; i < m_Actors.Size(); i++ )
  409. {
  410. CChoreoActor *a = m_Actors[ i ];
  411. if ( !a )
  412. continue;
  413. if ( !Q_stricmp( a->GetName(), name ) )
  414. return a;
  415. }
  416. return NULL;
  417. }
  418. //-----------------------------------------------------------------------------
  419. // Purpose:
  420. // Output : int
  421. //-----------------------------------------------------------------------------
  422. int CChoreoScene::GetNumEvents( void )
  423. {
  424. return m_Events.Size();
  425. }
  426. //-----------------------------------------------------------------------------
  427. // Purpose:
  428. // Input : event -
  429. // Output : CChoreoEvent
  430. //-----------------------------------------------------------------------------
  431. CChoreoEvent *CChoreoScene::GetEvent( int event )
  432. {
  433. if ( event < 0 || event >= m_Events.Size() )
  434. return NULL;
  435. return m_Events[ event ];
  436. }
  437. //-----------------------------------------------------------------------------
  438. // Purpose:
  439. // Output : int
  440. //-----------------------------------------------------------------------------
  441. int CChoreoScene::GetNumActors( void )
  442. {
  443. return m_Actors.Size();
  444. }
  445. //-----------------------------------------------------------------------------
  446. // Purpose:
  447. // Input : actor -
  448. // Output : CChoreoActor
  449. //-----------------------------------------------------------------------------
  450. CChoreoActor *CChoreoScene::GetActor( int actor )
  451. {
  452. if ( actor < 0 || actor >= GetNumActors() )
  453. return NULL;
  454. return m_Actors[ actor ];
  455. }
  456. //-----------------------------------------------------------------------------
  457. // Purpose:
  458. // Output : int
  459. //-----------------------------------------------------------------------------
  460. int CChoreoScene::GetNumChannels( void )
  461. {
  462. return m_Channels.Size();
  463. }
  464. //-----------------------------------------------------------------------------
  465. // Purpose:
  466. // Input : channel -
  467. // Output : CChoreoChannel
  468. //-----------------------------------------------------------------------------
  469. CChoreoChannel *CChoreoScene::GetChannel( int channel )
  470. {
  471. if ( channel < 0 || channel >= GetNumChannels() )
  472. return NULL;
  473. return m_Channels[ channel ];
  474. }
  475. void CChoreoScene::ParseRamp( ISceneTokenProcessor *tokenizer, CChoreoEvent *e )
  476. {
  477. e->GetRamp()->Parse( tokenizer, e );
  478. }
  479. void CChoreoScene::ParseSceneRamp( ISceneTokenProcessor *tokenizer, CChoreoScene *scene )
  480. {
  481. scene->m_SceneRamp.Parse( tokenizer, scene );
  482. }
  483. void CCurveData::Parse( ISceneTokenProcessor *tokenizer, ICurveDataAccessor *data )
  484. {
  485. Clear();
  486. tokenizer->GetToken( true );
  487. if ( !Q_stricmp( tokenizer->CurrentToken(), "leftedge" ) )
  488. {
  489. CChoreoScene::ParseEdgeInfo( tokenizer, &m_RampEdgeInfo[ 0 ] );
  490. }
  491. if ( !Q_stricmp( tokenizer->CurrentToken(), "rightedge" ) )
  492. {
  493. CChoreoScene::ParseEdgeInfo( tokenizer, &m_RampEdgeInfo[ 1 ] );
  494. }
  495. if ( stricmp( tokenizer->CurrentToken(), "{" ) )
  496. tokenizer->Error( "expecting {\n" );
  497. while ( 1 )
  498. {
  499. // Parse until }
  500. tokenizer->GetToken( true );
  501. if ( strlen( tokenizer->CurrentToken() ) <= 0 )
  502. {
  503. tokenizer->Error( "expecting ramp data\n" );
  504. break;
  505. }
  506. if ( !Q_stricmp( tokenizer->CurrentToken(), "}" ) )
  507. break;
  508. CUtlVector< CExpressionSample > samples;
  509. float time = (float)atof( tokenizer->CurrentToken() );
  510. tokenizer->GetToken( false );
  511. float value = (float)atof( tokenizer->CurrentToken() );
  512. // Add to counter
  513. int idx = samples.AddToTail();
  514. CExpressionSample *s = &samples[ idx ];
  515. s->time = time;
  516. s->value = value;
  517. // If there are more tokens on this line, then it's a new format curve name
  518. if ( tokenizer->TokenAvailable() )
  519. {
  520. tokenizer->GetToken( false );
  521. int curveType = Interpolator_CurveTypeForName( tokenizer->CurrentToken() );
  522. s->SetCurveType( curveType );
  523. }
  524. if ( samples.Size() >= 1 )
  525. {
  526. for ( int i = 0; i < samples.Size(); i++ )
  527. {
  528. CExpressionSample sample = samples[ i ];
  529. CExpressionSample *newSample = Add( sample.time, sample.value, false );
  530. newSample->SetCurveType( sample.GetCurveType() );
  531. }
  532. }
  533. }
  534. Resort( data );
  535. }
  536. //-----------------------------------------------------------------------------
  537. // Purpose: Helper for restoring edge info
  538. // Input : *edgeinfo -
  539. //-----------------------------------------------------------------------------
  540. void CChoreoScene::ParseEdgeInfo( ISceneTokenProcessor *tokenizer, EdgeInfo_t *edgeinfo )
  541. {
  542. Assert( edgeinfo );
  543. Assert( tokenizer );
  544. tokenizer->GetToken( false );
  545. edgeinfo->m_bActive = true;
  546. edgeinfo->m_CurveType = Interpolator_CurveTypeForName( tokenizer->CurrentToken() );
  547. tokenizer->GetToken( false );
  548. edgeinfo->m_flZeroPos = atof( tokenizer->CurrentToken() );
  549. tokenizer->GetToken( true );
  550. }
  551. //-----------------------------------------------------------------------------
  552. // Purpose:
  553. // Input : *tokenizer -
  554. // *e -
  555. //-----------------------------------------------------------------------------
  556. void CChoreoScene::ParseFlexAnimations( ISceneTokenProcessor *tokenizer, CChoreoEvent *e, bool removeold /*= true*/ )
  557. {
  558. Assert( e );
  559. if ( removeold )
  560. {
  561. // Make sure there's nothing already there...
  562. e->RemoveAllTracks();
  563. // Make it re-index
  564. e->SetTrackLookupSet( false );
  565. }
  566. // BACKWARD COMPATABILITY
  567. // in the old system the samples were 0.0 to 1.0 mapped to endtime - starttime
  568. // if samples_use_time is true, then samples are actually offsets of time from starttime
  569. bool samples_use_realtime = false;
  570. // Parse tags between { }
  571. //
  572. tokenizer->GetToken( true );
  573. Assert( e->HasEndTime() );
  574. float endtime = e->GetEndTime();
  575. float starttime = e->GetStartTime();
  576. float event_time = endtime - starttime;
  577. int nDefaultCurveType = CURVE_DEFAULT;
  578. // Is it the new file format?
  579. if ( !Q_stricmp( tokenizer->CurrentToken(), "samples_use_time" ) )
  580. {
  581. samples_use_realtime = true;
  582. tokenizer->GetToken( true );
  583. }
  584. // Check for default curve type
  585. if ( !Q_strnicmp( tokenizer->CurrentToken(), "defaultcurvetype", 16 ) )
  586. {
  587. const char *pTest = tokenizer->CurrentToken() + 16;
  588. if ( *pTest == 0 )
  589. {
  590. tokenizer->GetToken( true );
  591. pTest = tokenizer->CurrentToken();
  592. }
  593. if ( *pTest != '=' )
  594. {
  595. tokenizer->Error( "expecting =\n" );
  596. }
  597. ++pTest;
  598. if ( *pTest == 0 )
  599. {
  600. tokenizer->GetToken( true );
  601. pTest = tokenizer->CurrentToken();
  602. }
  603. nDefaultCurveType = Interpolator_CurveTypeForName( pTest );
  604. tokenizer->GetToken( true );
  605. e->SetDefaultCurveType( nDefaultCurveType );
  606. }
  607. if ( stricmp( tokenizer->CurrentToken(), "{" ) )
  608. {
  609. tokenizer->Error( "expecting {\n" );
  610. }
  611. while ( 1 )
  612. {
  613. // Parse until }
  614. tokenizer->GetToken( true );
  615. if ( strlen( tokenizer->CurrentToken() ) <= 0 )
  616. {
  617. tokenizer->Error( "expecting flex animation data\n" );
  618. break;
  619. }
  620. if ( !Q_stricmp( tokenizer->CurrentToken(), "}" ) )
  621. break;
  622. char flexcontroller[ CFlexAnimationTrack::MAX_CONTROLLER_NAME ];
  623. Q_strncpy( flexcontroller, tokenizer->CurrentToken(), sizeof( flexcontroller ) );
  624. // Animations default to active
  625. bool active = true;
  626. bool combo = false;
  627. float range_min = 0.0f;
  628. float range_max = 1.0f;
  629. tokenizer->GetToken( true );
  630. EdgeInfo_t edgeinfo[ 2 ];
  631. if ( !Q_stricmp( tokenizer->CurrentToken(), "disabled" ) )
  632. {
  633. active = false;
  634. tokenizer->GetToken( true );
  635. }
  636. if ( !Q_stricmp( tokenizer->CurrentToken(), "combo" ) )
  637. {
  638. combo = true;
  639. tokenizer->GetToken( true );
  640. }
  641. if ( !Q_stricmp( tokenizer->CurrentToken(), "range" ) )
  642. {
  643. tokenizer->GetToken( false );
  644. range_min = atof( tokenizer->CurrentToken() );
  645. tokenizer->GetToken( false );
  646. range_max = atof( tokenizer->CurrentToken() );
  647. tokenizer->GetToken( true );
  648. }
  649. if ( !Q_stricmp( tokenizer->CurrentToken(), "leftedge" ) )
  650. {
  651. ParseEdgeInfo( tokenizer, &edgeinfo[ 0 ] );
  652. }
  653. if ( !Q_stricmp( tokenizer->CurrentToken(), "rightedge" ) )
  654. {
  655. ParseEdgeInfo( tokenizer, &edgeinfo[ 1 ] );
  656. }
  657. CUtlVector< CExpressionSample > samples[2];
  658. for ( int samplecount = 0; samplecount < ( combo ? 2 : 1 ); samplecount++ )
  659. {
  660. if ( stricmp( tokenizer->CurrentToken(), "{" ) )
  661. {
  662. tokenizer->Error( "expecting {\n" );
  663. }
  664. while ( 1 )
  665. {
  666. tokenizer->GetToken( true );
  667. if ( strlen( tokenizer->CurrentToken() ) <= 0 )
  668. {
  669. tokenizer->Error( "expecting flex animation data\n" );
  670. break;
  671. }
  672. if ( !Q_stricmp( tokenizer->CurrentToken(), "}" ) )
  673. break;
  674. float time = (float)atof( tokenizer->CurrentToken() );
  675. tokenizer->GetToken( false );
  676. float value = (float)atof( tokenizer->CurrentToken() );
  677. // Add to counter
  678. int idx = samples[ samplecount ].AddToTail();
  679. CExpressionSample *s = &samples[ samplecount ][ idx ];
  680. if ( samples_use_realtime )
  681. {
  682. s->time = time;
  683. }
  684. else
  685. {
  686. // Time is an old style fraction (0 to 1) map into real time
  687. s->time = time * event_time;
  688. }
  689. s->value = value;
  690. // If there are more tokens on this line, then it's a new format curve name
  691. if ( tokenizer->TokenAvailable() )
  692. {
  693. tokenizer->GetToken( false );
  694. int curveType = Interpolator_CurveTypeForName( tokenizer->CurrentToken() );
  695. s->SetCurveType( curveType );
  696. }
  697. else
  698. {
  699. s->SetCurveType( nDefaultCurveType );
  700. }
  701. }
  702. if ( combo && samplecount == 0 )
  703. {
  704. tokenizer->GetToken( true );
  705. }
  706. }
  707. if ( active || samples[ 0 ].Size() >= 1 )
  708. {
  709. // Add it in
  710. CFlexAnimationTrack *track = e->AddTrack( flexcontroller );
  711. Assert( track );
  712. track->SetTrackActive( active );
  713. track->SetComboType( combo );
  714. track->SetMin( range_min );
  715. track->SetMax( range_max );
  716. for ( int t = 0; t < ( combo ? 2 : 1 ); t++ )
  717. {
  718. for ( int i = 0; i < samples[ t ].Size(); i++ )
  719. {
  720. CExpressionSample *sample = &samples[ t ][ i ];
  721. CExpressionSample *added = track->AddSample( sample->time, sample->value, t );
  722. Assert( added );
  723. added->SetCurveType( sample->GetCurveType() );
  724. }
  725. }
  726. for ( int edge = 0; edge < 2; ++edge )
  727. {
  728. if ( !edgeinfo[ edge ].m_bActive )
  729. continue;
  730. track->SetEdgeActive( edge == 0 ? true : false, true );
  731. track->SetEdgeInfo( edge == 0 ? true : false, edgeinfo[ edge ].m_CurveType, edgeinfo[ edge ].m_flZeroPos );
  732. }
  733. track->Resort( 0 );
  734. track->Resort( 1 );
  735. }
  736. }
  737. }
  738. //-----------------------------------------------------------------------------
  739. // Purpose:
  740. // Input : *actor -
  741. // *channel -
  742. // Output : CChoreoEvent
  743. //-----------------------------------------------------------------------------
  744. CChoreoEvent *CChoreoScene::ParseEvent( CChoreoActor *actor, CChoreoChannel *channel )
  745. {
  746. // For conversion of old style attack/sustain/decay ramps
  747. bool hadramp = false;
  748. float attack = 1.0f, sustain = 1.0f, decay = 1.0f;
  749. CChoreoEvent *e;
  750. {
  751. MEM_ALLOC_CREDIT();
  752. e = AllocEvent();
  753. }
  754. MEM_ALLOC_CREDIT();
  755. Assert( e );
  756. // read event type
  757. m_pTokenizer->GetToken( false );
  758. e->SetType( CChoreoEvent::TypeForName( m_pTokenizer->CurrentToken() ) );
  759. m_pTokenizer->GetToken( false );
  760. e->SetName( m_pTokenizer->CurrentToken() );
  761. m_pTokenizer->GetToken( true );
  762. if ( stricmp( m_pTokenizer->CurrentToken(), "{" ) )
  763. m_pTokenizer->Error( "expecting {\n" );
  764. while ( 1 )
  765. {
  766. m_pTokenizer->GetToken( true );
  767. if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "}" ) )
  768. break;
  769. if ( strlen( m_pTokenizer->CurrentToken() ) <= 0 )
  770. {
  771. m_pTokenizer->Error( "expecting more tokens!" );
  772. break;
  773. }
  774. if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "time" ) )
  775. {
  776. float start, end = 1.0f;
  777. m_pTokenizer->GetToken( false );
  778. start = (float)atof( m_pTokenizer->CurrentToken() );
  779. if ( m_pTokenizer->TokenAvailable() )
  780. {
  781. m_pTokenizer->GetToken( false );
  782. end = (float)atof( m_pTokenizer->CurrentToken() );
  783. }
  784. e->SetStartTime( start );
  785. e->SetEndTime( end );
  786. }
  787. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "ramp" ) )
  788. {
  789. hadramp = true;
  790. m_pTokenizer->GetToken( false );
  791. attack = (float)atof( m_pTokenizer->CurrentToken() );
  792. if ( m_pTokenizer->TokenAvailable() )
  793. {
  794. m_pTokenizer->GetToken( false );
  795. sustain = (float)atof( m_pTokenizer->CurrentToken() );
  796. }
  797. if ( m_pTokenizer->TokenAvailable() )
  798. {
  799. m_pTokenizer->GetToken( false );
  800. decay = (float)atof( m_pTokenizer->CurrentToken() );
  801. }
  802. }
  803. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "param" ) )
  804. {
  805. m_pTokenizer->GetToken( false );
  806. e->SetParameters( m_pTokenizer->CurrentToken() );
  807. }
  808. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "param2" ) )
  809. {
  810. m_pTokenizer->GetToken( false );
  811. e->SetParameters2( m_pTokenizer->CurrentToken() );
  812. }
  813. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "param3" ) )
  814. {
  815. m_pTokenizer->GetToken( false );
  816. e->SetParameters3( m_pTokenizer->CurrentToken() );
  817. }
  818. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "pitch" ) )
  819. {
  820. m_pTokenizer->GetToken( false );
  821. e->SetPitch( atoi( m_pTokenizer->CurrentToken() ) );
  822. }
  823. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "yaw" ) )
  824. {
  825. m_pTokenizer->GetToken( false );
  826. e->SetYaw( atoi( m_pTokenizer->CurrentToken() ) );
  827. }
  828. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "loopcount" ) )
  829. {
  830. m_pTokenizer->GetToken( false );
  831. e->SetLoopCount( atoi( m_pTokenizer->CurrentToken() ) );
  832. }
  833. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "resumecondition" ) )
  834. {
  835. e->SetResumeCondition( true );
  836. }
  837. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "fixedlength" ) )
  838. {
  839. e->SetFixedLength( true );
  840. }
  841. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "lockbodyfacing" ) )
  842. {
  843. e->SetLockBodyFacing( true );
  844. }
  845. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "distancetotarget" ) )
  846. {
  847. m_pTokenizer->GetToken( false );
  848. e->SetDistanceToTarget( atof( m_pTokenizer->CurrentToken() ) );
  849. }
  850. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "forceshortmovement" ) )
  851. {
  852. e->SetForceShortMovement( true );
  853. }
  854. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "synctofollowinggesture" ) )
  855. {
  856. e->SetSyncToFollowingGesture( true );
  857. }
  858. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "active" ) )
  859. {
  860. m_pTokenizer->GetToken( false );
  861. e->SetActive( atoi( m_pTokenizer->CurrentToken() ) ? true : false );
  862. }
  863. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "playoverscript" ) )
  864. {
  865. e->SetPlayOverScript( true );
  866. }
  867. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "tags" ) )
  868. {
  869. // Parse tags between { }
  870. //
  871. m_pTokenizer->GetToken( true );
  872. if ( stricmp( m_pTokenizer->CurrentToken(), "{" ) )
  873. m_pTokenizer->Error( "expecting {\n" );
  874. while ( 1 )
  875. {
  876. // Parse until }
  877. m_pTokenizer->GetToken( true );
  878. if ( strlen( m_pTokenizer->CurrentToken() ) <= 0 )
  879. {
  880. m_pTokenizer->Error( "expecting relative tag\n" );
  881. break;
  882. }
  883. if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "}" ) )
  884. break;
  885. char tagname[ CEventRelativeTag::MAX_EVENTTAG_LENGTH ];
  886. float percentage;
  887. Q_strncpy( tagname, m_pTokenizer->CurrentToken(), sizeof( tagname ) );
  888. m_pTokenizer->GetToken( false );
  889. percentage = (float)atof( m_pTokenizer->CurrentToken() );
  890. e->AddRelativeTag( tagname, percentage );
  891. }
  892. }
  893. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "sequenceduration" ) )
  894. {
  895. float duration = 0.0f;
  896. m_pTokenizer->GetToken( false );
  897. duration = (float)atof( m_pTokenizer->CurrentToken() );
  898. e->SetGestureSequenceDuration( duration );
  899. }
  900. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "absolutetags" ) )
  901. {
  902. m_pTokenizer->GetToken( true );
  903. CChoreoEvent::AbsTagType tagtype;
  904. tagtype = CChoreoEvent::TypeForAbsoluteTagName( m_pTokenizer->CurrentToken() );
  905. if ( tagtype == (CChoreoEvent::AbsTagType) -1 )
  906. {
  907. m_pTokenizer->Error( "expecting valid tag type!!!" );
  908. }
  909. // Parse tags between { }
  910. //
  911. m_pTokenizer->GetToken( true );
  912. if ( stricmp( m_pTokenizer->CurrentToken(), "{" ) )
  913. m_pTokenizer->Error( "expecting {\n" );
  914. while ( 1 )
  915. {
  916. // Parse until }
  917. m_pTokenizer->GetToken( true );
  918. if ( strlen( m_pTokenizer->CurrentToken() ) <= 0 )
  919. {
  920. m_pTokenizer->Error( "expecting relative tag\n" );
  921. break;
  922. }
  923. if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "}" ) )
  924. break;
  925. char tagname[ CFlexTimingTag::MAX_EVENTTAG_LENGTH ];
  926. float t;
  927. Q_strncpy( tagname, m_pTokenizer->CurrentToken(), sizeof( tagname ) );
  928. m_pTokenizer->GetToken( false );
  929. t = (float)atof( m_pTokenizer->CurrentToken() );
  930. e->AddAbsoluteTag( tagtype, tagname, t );
  931. }
  932. }
  933. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "flextimingtags" ) )
  934. {
  935. // Parse tags between { }
  936. //
  937. m_pTokenizer->GetToken( true );
  938. if ( stricmp( m_pTokenizer->CurrentToken(), "{" ) )
  939. m_pTokenizer->Error( "expecting {\n" );
  940. while ( 1 )
  941. {
  942. // Parse until }
  943. m_pTokenizer->GetToken( true );
  944. if ( strlen( m_pTokenizer->CurrentToken() ) <= 0 )
  945. {
  946. m_pTokenizer->Error( "expecting relative tag\n" );
  947. break;
  948. }
  949. if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "}" ) )
  950. break;
  951. char tagname[ CFlexTimingTag::MAX_EVENTTAG_LENGTH ];
  952. float percentage;
  953. bool locked;
  954. Q_strncpy( tagname, m_pTokenizer->CurrentToken(), sizeof( tagname ) );
  955. m_pTokenizer->GetToken( false );
  956. percentage = (float)atof( m_pTokenizer->CurrentToken() );
  957. m_pTokenizer->GetToken( false );
  958. locked = atoi( m_pTokenizer->CurrentToken() ) ? true : false;
  959. e->AddTimingTag( tagname, percentage, locked );
  960. }
  961. }
  962. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "relativetag" ) )
  963. {
  964. char tagname[ CChoreoEvent::MAX_TAGNAME_STRING ];
  965. char wavname[ CChoreoEvent::MAX_TAGNAME_STRING ];
  966. m_pTokenizer->GetToken( false );
  967. Q_strncpy( tagname, m_pTokenizer->CurrentToken(), sizeof( tagname ) );
  968. m_pTokenizer->GetToken( false );
  969. Q_strncpy( wavname, m_pTokenizer->CurrentToken(), sizeof( wavname ) );
  970. e->SetUsingRelativeTag( true, tagname, wavname );
  971. }
  972. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "flexanimations" ) )
  973. {
  974. ParseFlexAnimations( m_pTokenizer, e );
  975. }
  976. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "event_ramp" ) )
  977. {
  978. ParseRamp( m_pTokenizer, e );
  979. }
  980. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "cctype" ) )
  981. {
  982. m_pTokenizer->GetToken( false );
  983. e->SetCloseCaptionType( CChoreoEvent::CCTypeForName( m_pTokenizer->CurrentToken() ) );
  984. }
  985. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "cctoken" ) )
  986. {
  987. m_pTokenizer->GetToken( false );
  988. e->SetCloseCaptionToken( m_pTokenizer->CurrentToken() );
  989. }
  990. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "cc_usingcombinedfile" ) )
  991. {
  992. e->SetUsingCombinedFile( true );
  993. }
  994. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "cc_combinedusesgender" ) )
  995. {
  996. e->SetCombinedUsingGenderToken( true );
  997. }
  998. else if( !Q_stricmp( m_pTokenizer->CurrentToken(), "cc_noattenuate" ) )
  999. {
  1000. e->SetSuppressingCaptionAttenuation( true );
  1001. }
  1002. }
  1003. if ( channel )
  1004. {
  1005. channel->AddEvent( e );
  1006. }
  1007. e->SetActor( actor );
  1008. e->SetChannel( channel );
  1009. // It had old sytle ramp and none of the new style stuff
  1010. // Convert it
  1011. if ( hadramp && !e->GetRampCount() )
  1012. {
  1013. // Only retrofit if something was changed by user
  1014. if ( attack != 1.0f ||
  1015. sustain != 1.0f ||
  1016. decay != 1.0f )
  1017. {
  1018. float attacktime = ( 1.0f - attack ) * e->GetDuration();
  1019. float decaytime = decay * e->GetDuration();
  1020. float midpoint = ( attacktime + decaytime ) * 0.5f;
  1021. e->AddRamp( attacktime, sustain, false );
  1022. e->AddRamp( midpoint, sustain, false );
  1023. e->AddRamp( decaytime, sustain, false );
  1024. e->ResortRamp();
  1025. }
  1026. }
  1027. return e;
  1028. }
  1029. //-----------------------------------------------------------------------------
  1030. // Purpose:
  1031. // Output : CChoreoActor
  1032. //-----------------------------------------------------------------------------
  1033. CChoreoActor *CChoreoScene::ParseActor( void )
  1034. {
  1035. CChoreoActor *a = AllocActor();
  1036. Assert( a );
  1037. m_pTokenizer->GetToken( false );
  1038. a->SetName( m_pTokenizer->CurrentToken() );
  1039. m_pTokenizer->GetToken( true );
  1040. if ( stricmp( m_pTokenizer->CurrentToken(), "{" ) )
  1041. m_pTokenizer->Error( "expecting {" );
  1042. // Parse channels
  1043. while ( 1 )
  1044. {
  1045. m_pTokenizer->GetToken( true );
  1046. if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "}" ) )
  1047. break;
  1048. if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "channel" ) )
  1049. {
  1050. ParseChannel( a );
  1051. }
  1052. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "faceposermodel" ) )
  1053. {
  1054. ParseFacePoserModel( a );
  1055. }
  1056. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "active" ) )
  1057. {
  1058. m_pTokenizer->GetToken( true );
  1059. a->SetActive( atoi( m_pTokenizer->CurrentToken() ) ? true : false );
  1060. }
  1061. else
  1062. {
  1063. m_pTokenizer->Error( "expecting channel got %s\n", m_pTokenizer->CurrentToken() );
  1064. }
  1065. }
  1066. return a;
  1067. }
  1068. //-----------------------------------------------------------------------------
  1069. // Output : char const
  1070. //-----------------------------------------------------------------------------
  1071. const char *CChoreoScene::GetMapname( void )
  1072. {
  1073. return m_szMapname;
  1074. }
  1075. //-----------------------------------------------------------------------------
  1076. // Purpose:
  1077. // Input : *name -
  1078. //-----------------------------------------------------------------------------
  1079. void CChoreoScene::SetMapname( const char *name )
  1080. {
  1081. Q_strncpy( m_szMapname, name, sizeof( m_szMapname ) );
  1082. }
  1083. //-----------------------------------------------------------------------------
  1084. // Purpose:
  1085. //-----------------------------------------------------------------------------
  1086. void CChoreoScene::ParseMapname( void )
  1087. {
  1088. m_szMapname[ 0 ] = 0;
  1089. m_pTokenizer->GetToken( true );
  1090. Q_strncpy( m_szMapname, m_pTokenizer->CurrentToken(), sizeof( m_szMapname ) );
  1091. }
  1092. //-----------------------------------------------------------------------------
  1093. // Purpose:
  1094. //-----------------------------------------------------------------------------
  1095. void CChoreoScene::ParseFPS( void )
  1096. {
  1097. m_pTokenizer->GetToken( true );
  1098. m_nSceneFPS = atoi( m_pTokenizer->CurrentToken() );
  1099. // Clamp to valid range
  1100. m_nSceneFPS = clamp( m_nSceneFPS, MIN_SCENE_FPS, MAX_SCENE_FPS);
  1101. }
  1102. //-----------------------------------------------------------------------------
  1103. // Purpose:
  1104. //-----------------------------------------------------------------------------
  1105. void CChoreoScene::ParseSnap( void )
  1106. {
  1107. m_pTokenizer->GetToken( true );
  1108. m_bUseFrameSnap = !Q_stricmp( m_pTokenizer->CurrentToken(), "on" ) ? true : false;
  1109. }
  1110. //-----------------------------------------------------------------------------
  1111. // Purpose:
  1112. //-----------------------------------------------------------------------------
  1113. void CChoreoScene::ParseIgnorePhonemes( void )
  1114. {
  1115. m_pTokenizer->GetToken( true );
  1116. m_bIgnorePhonemes = !Q_stricmp( m_pTokenizer->CurrentToken(), "on" ) ? true : false;
  1117. }
  1118. //-----------------------------------------------------------------------------
  1119. // Purpose:
  1120. // Input : *actor -
  1121. //-----------------------------------------------------------------------------
  1122. void CChoreoScene::ParseFacePoserModel( CChoreoActor *actor )
  1123. {
  1124. m_pTokenizer->GetToken( true );
  1125. actor->SetFacePoserModelName( m_pTokenizer->CurrentToken() );
  1126. }
  1127. //-----------------------------------------------------------------------------
  1128. // Purpose:
  1129. // Input : *actor -
  1130. // Output : CChoreoChannel
  1131. //-----------------------------------------------------------------------------
  1132. CChoreoChannel *CChoreoScene::ParseChannel( CChoreoActor *actor )
  1133. {
  1134. CChoreoChannel *c = AllocChannel();
  1135. Assert( c );
  1136. m_pTokenizer->GetToken( false );
  1137. c->SetName( m_pTokenizer->CurrentToken() );
  1138. m_pTokenizer->GetToken( true );
  1139. if ( stricmp( m_pTokenizer->CurrentToken(), "{" ) )
  1140. m_pTokenizer->Error( "expecting {" );
  1141. // Parse channels
  1142. while ( 1 )
  1143. {
  1144. m_pTokenizer->GetToken( true );
  1145. if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "}" ) )
  1146. break;
  1147. if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "event" ) )
  1148. {
  1149. ParseEvent( actor, c );
  1150. }
  1151. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "active" ) )
  1152. {
  1153. m_pTokenizer->GetToken( true );
  1154. c->SetActive( atoi( m_pTokenizer->CurrentToken() ) ? true : false );
  1155. }
  1156. else
  1157. {
  1158. m_pTokenizer->Error( "expecting event got %s\n", m_pTokenizer->CurrentToken() );
  1159. }
  1160. }
  1161. Assert( actor );
  1162. if ( actor )
  1163. {
  1164. actor->AddChannel( c );
  1165. c->SetActor( actor );
  1166. }
  1167. return c;
  1168. }
  1169. //-----------------------------------------------------------------------------
  1170. // Purpose:
  1171. // Output : Returns true on success, false on failure.
  1172. //-----------------------------------------------------------------------------
  1173. bool CChoreoScene::ParseFromBuffer( const char *pFilename, ISceneTokenProcessor *tokenizer )
  1174. {
  1175. Q_strncpy( m_szFileName, pFilename, sizeof(m_szFileName) );
  1176. m_pTokenizer = tokenizer;
  1177. while ( 1 )
  1178. {
  1179. if ( !m_pTokenizer->GetToken( true ) )
  1180. {
  1181. break;
  1182. }
  1183. if ( strlen( m_pTokenizer->CurrentToken() ) <= 0 )
  1184. break;
  1185. if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "event" ) )
  1186. {
  1187. ParseEvent( NULL, NULL );
  1188. }
  1189. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "actor" ) )
  1190. {
  1191. ParseActor();
  1192. }
  1193. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "mapname" ) )
  1194. {
  1195. ParseMapname();
  1196. }
  1197. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "fps" ) )
  1198. {
  1199. ParseFPS();
  1200. }
  1201. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "snap" ) )
  1202. {
  1203. ParseSnap();
  1204. }
  1205. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "ignorePhonemes" ) )
  1206. {
  1207. ParseIgnorePhonemes();
  1208. }
  1209. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "scene_ramp" ) )
  1210. {
  1211. ParseSceneRamp( m_pTokenizer, this );
  1212. }
  1213. else if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "scalesettings" ) )
  1214. {
  1215. ParseScaleSettings( m_pTokenizer, this );
  1216. }
  1217. else
  1218. {
  1219. m_pTokenizer->Error( "%s: unexpected token %s\n", m_szFileName, m_pTokenizer->CurrentToken() );
  1220. break;
  1221. }
  1222. }
  1223. // Fixup time tags
  1224. ReconcileTags();
  1225. ReconcileGestureTimes();
  1226. ReconcileCloseCaption();
  1227. InternalDetermineEventTypes();
  1228. if ( CChoreoScene::s_bEditingDisabled )
  1229. {
  1230. m_flPrecomputedStopTime = FindStopTime();
  1231. }
  1232. return true;
  1233. }
  1234. void CChoreoScene::RemoveEventsExceptTypes( int* typeList, int count )
  1235. {
  1236. int i;
  1237. for ( i = 0 ; i < m_Actors.Count(); i++ )
  1238. {
  1239. CChoreoActor *a = m_Actors[ i ];
  1240. if ( !a )
  1241. continue;
  1242. for ( int j = 0; j < a->GetNumChannels(); j++ )
  1243. {
  1244. CChoreoChannel *c = a->GetChannel( j );
  1245. if ( !c )
  1246. continue;
  1247. int num = c->GetNumEvents();
  1248. for ( int k = num - 1 ; k >= 0; --k )
  1249. {
  1250. CChoreoEvent *e = c->GetEvent( k );
  1251. if ( !e )
  1252. continue;
  1253. bool found = false;
  1254. for ( int idx = 0; idx < count; ++idx )
  1255. {
  1256. if ( e->GetType() == ( CChoreoEvent::EVENTTYPE )typeList[ idx ] )
  1257. {
  1258. found = true;
  1259. break;
  1260. }
  1261. }
  1262. if ( !found )
  1263. {
  1264. c->RemoveEvent( e );
  1265. DeleteReferencedObjects( e );
  1266. }
  1267. }
  1268. }
  1269. }
  1270. // Remvoe non-matching global events, too
  1271. for ( i = m_Events.Count() - 1 ; i >= 0; --i )
  1272. {
  1273. CChoreoEvent *e = m_Events[ i ];
  1274. // This was already dealt with above...
  1275. if ( e->GetActor() )
  1276. continue;
  1277. bool found = false;
  1278. for ( int idx = 0; idx < count; ++idx )
  1279. {
  1280. if ( e->GetType() == ( CChoreoEvent::EVENTTYPE )typeList[ idx ] )
  1281. {
  1282. found = true;
  1283. break;
  1284. }
  1285. }
  1286. if ( !found )
  1287. {
  1288. DeleteReferencedObjects( e );
  1289. }
  1290. }
  1291. }
  1292. void CChoreoScene::InternalDetermineEventTypes()
  1293. {
  1294. m_bitvecHasEventOfType.ClearAll();
  1295. for ( int i = 0 ; i < m_Actors.Size(); i++ )
  1296. {
  1297. CChoreoActor *a = m_Actors[ i ];
  1298. if ( !a )
  1299. continue;
  1300. for ( int j = 0; j < a->GetNumChannels(); j++ )
  1301. {
  1302. CChoreoChannel *c = a->GetChannel( j );
  1303. if ( !c )
  1304. continue;
  1305. for ( int k = 0 ; k < c->GetNumEvents(); k++ )
  1306. {
  1307. CChoreoEvent *e = c->GetEvent( k );
  1308. if ( !e )
  1309. continue;
  1310. m_bitvecHasEventOfType.Set( e->GetType(), true );
  1311. }
  1312. }
  1313. }
  1314. }
  1315. //-----------------------------------------------------------------------------
  1316. // Purpose:
  1317. // Output : float
  1318. //-----------------------------------------------------------------------------
  1319. float CChoreoScene::FindStopTime( void )
  1320. {
  1321. if ( m_flPrecomputedStopTime != 0.0f )
  1322. {
  1323. return m_flPrecomputedStopTime;
  1324. }
  1325. float lasttime = 0.0f;
  1326. int c = m_Events.Count();
  1327. for ( int i = 0; i < c ; i++ )
  1328. {
  1329. CChoreoEvent *e = m_Events[ i ];
  1330. Assert( e );
  1331. float checktime = e->HasEndTime() ? e->GetEndTime() : e->GetStartTime();
  1332. if ( checktime > lasttime )
  1333. {
  1334. lasttime = checktime;
  1335. }
  1336. }
  1337. return lasttime;
  1338. }
  1339. //-----------------------------------------------------------------------------
  1340. // Purpose:
  1341. // Input : *fp -
  1342. // level -
  1343. // *fmt -
  1344. // ... -
  1345. //-----------------------------------------------------------------------------
  1346. void CChoreoScene::FilePrintf( CUtlBuffer& buf, int level, const char *fmt, ... )
  1347. {
  1348. va_list argptr;
  1349. va_start( argptr, fmt );
  1350. while ( level-- > 0 )
  1351. {
  1352. buf.Printf( " " );
  1353. }
  1354. buf.VaPrintf( fmt, argptr );
  1355. va_end( argptr );
  1356. }
  1357. //-----------------------------------------------------------------------------
  1358. // Purpose:
  1359. // Input : *fp -
  1360. //-----------------------------------------------------------------------------
  1361. void CChoreoScene::FileSaveHeader( CUtlBuffer& buf )
  1362. {
  1363. FilePrintf( buf, 0, "// Choreo version 1\n" );
  1364. }
  1365. //-----------------------------------------------------------------------------
  1366. // Purpose:
  1367. // Input : mark -
  1368. //-----------------------------------------------------------------------------
  1369. void CChoreoScene::MarkForSaveAll( bool mark )
  1370. {
  1371. int i;
  1372. // Mark global events
  1373. for ( i = 0 ; i < m_Events.Size(); i++ )
  1374. {
  1375. CChoreoEvent *e = m_Events[ i ];
  1376. if ( e->GetActor() )
  1377. continue;
  1378. e->SetMarkedForSave( mark );
  1379. }
  1380. // Recursively mark everything else
  1381. for ( i = 0 ; i < m_Actors.Size(); i++ )
  1382. {
  1383. CChoreoActor *a = m_Actors[ i ];
  1384. if ( !a )
  1385. continue;
  1386. a->MarkForSaveAll( mark );
  1387. }
  1388. }
  1389. //-----------------------------------------------------------------------------
  1390. // Purpose:
  1391. // Input : *filename -
  1392. // Output : Returns true on success, false on failure.
  1393. //-----------------------------------------------------------------------------
  1394. bool CChoreoScene::ExportMarkedToFile( const char *filename )
  1395. {
  1396. // Create a serialization buffer
  1397. CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
  1398. FileSaveHeader( buf );
  1399. // Look for events that don't have actor/channel set
  1400. int i;
  1401. for ( i = 0 ; i < m_Events.Size(); i++ )
  1402. {
  1403. CChoreoEvent *e = m_Events[ i ];
  1404. if ( e->GetActor() )
  1405. continue;
  1406. FileSaveEvent( buf, 0, e );
  1407. }
  1408. for ( i = 0 ; i < m_Actors.Size(); i++ )
  1409. {
  1410. CChoreoActor *a = m_Actors[ i ];
  1411. if ( !a )
  1412. continue;
  1413. FileSaveActor( buf, 0, a );
  1414. }
  1415. // Write it out baby
  1416. FileHandle_t fh = g_pFullFileSystem->Open( filename, "wt" );
  1417. if (fh)
  1418. {
  1419. g_pFullFileSystem->Write( buf.Base(), buf.TellPut(), fh );
  1420. g_pFullFileSystem->Close(fh);
  1421. return true;
  1422. }
  1423. return false;
  1424. }
  1425. //-----------------------------------------------------------------------------
  1426. // Purpose:
  1427. // Input : *filename -
  1428. //-----------------------------------------------------------------------------
  1429. bool CChoreoScene::SaveToFile( const char *filename )
  1430. {
  1431. // Create a serialization buffer
  1432. CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
  1433. FileSaveHeader( buf );
  1434. MarkForSaveAll( true );
  1435. // Look for events that don't have actor/channel set
  1436. int i;
  1437. for ( i = 0 ; i < m_Events.Size(); i++ )
  1438. {
  1439. CChoreoEvent *e = m_Events[ i ];
  1440. if ( e->GetActor() )
  1441. continue;
  1442. FileSaveEvent( buf, 0, e );
  1443. }
  1444. for ( i = 0 ; i < m_Actors.Size(); i++ )
  1445. {
  1446. CChoreoActor *a = m_Actors[ i ];
  1447. if ( !a )
  1448. continue;
  1449. FileSaveActor( buf, 0, a );
  1450. }
  1451. if ( m_szMapname[ 0 ] )
  1452. {
  1453. FilePrintf( buf, 0, "mapname \"%s\"\n", m_szMapname );
  1454. }
  1455. FileSaveSceneRamp( buf, 0 );
  1456. FileSaveScaleSettings( buf, 0, this );
  1457. FilePrintf( buf, 0, "fps %i\n", m_nSceneFPS );
  1458. FilePrintf( buf, 0, "snap %s\n", m_bUseFrameSnap ? "on" : "off" );
  1459. FilePrintf( buf, 0, "ignorePhonemes %s\n", m_bIgnorePhonemes ? "on" : "off" );
  1460. // Write it out baby
  1461. FileHandle_t fh = g_pFullFileSystem->Open( filename, "wt" );
  1462. if (fh)
  1463. {
  1464. g_pFullFileSystem->Write( buf.Base(), buf.TellPut(), fh );
  1465. g_pFullFileSystem->Close(fh);
  1466. return true;
  1467. }
  1468. return false;
  1469. }
  1470. //-----------------------------------------------------------------------------
  1471. // Purpose:
  1472. // Input : buf -
  1473. // level -
  1474. // *e -
  1475. //-----------------------------------------------------------------------------
  1476. void CChoreoScene::FileSaveRamp( CUtlBuffer& buf, int level, CChoreoEvent *e )
  1477. {
  1478. e->GetRamp()->FileSave( buf, level, "event_ramp" );
  1479. }
  1480. //-----------------------------------------------------------------------------
  1481. // Purpose:
  1482. // Input : buf -
  1483. // level -
  1484. // *e -
  1485. //-----------------------------------------------------------------------------
  1486. void CChoreoScene::FileSaveSceneRamp( CUtlBuffer& buf, int level )
  1487. {
  1488. m_SceneRamp.FileSave( buf, level, "scene_ramp" );
  1489. }
  1490. void CCurveData::FileSave( CUtlBuffer& buf, int level, const char *name )
  1491. {
  1492. // Nothing to save?
  1493. int c = GetCount();
  1494. if ( c <= 0 &&
  1495. !IsEdgeActive( true ) &&
  1496. !IsEdgeActive( false ) )
  1497. return;
  1498. char line[ 1024 ];
  1499. Q_strncpy( line, name, sizeof( line ) );
  1500. if ( IsEdgeActive( true ) || IsEdgeActive( false ) )
  1501. {
  1502. if ( IsEdgeActive( true ) )
  1503. {
  1504. char sz[ 256 ];
  1505. Q_snprintf( sz, sizeof( sz ), " leftedge %s %.3f", Interpolator_NameForCurveType( GetEdgeCurveType( true ), false ), GetEdgeZeroValue( true ) );
  1506. Q_strncat( line, sz, sizeof( line ), COPY_ALL_CHARACTERS );
  1507. }
  1508. if ( IsEdgeActive( false ) )
  1509. {
  1510. char sz[ 256 ];
  1511. Q_snprintf( sz, sizeof( sz )," rightedge %s %.3f", Interpolator_NameForCurveType( GetEdgeCurveType( false ), false ), GetEdgeZeroValue( false ) );
  1512. Q_strncat( line, sz, sizeof( line ), COPY_ALL_CHARACTERS );
  1513. }
  1514. }
  1515. CChoreoScene::FilePrintf( buf, level, "%s\n", line );
  1516. CChoreoScene::FilePrintf( buf, level, "{\n" );
  1517. for ( int i = 0; i < c; i++ )
  1518. {
  1519. CExpressionSample *sample = Get( i );
  1520. if ( sample->GetCurveType() != CURVE_DEFAULT )
  1521. {
  1522. CChoreoScene::FilePrintf( buf, level + 1, "%.4f %.4f \"%s\"\n",
  1523. sample->time,
  1524. sample->value,
  1525. Interpolator_NameForCurveType( sample->GetCurveType(), false ) );
  1526. }
  1527. else
  1528. {
  1529. CChoreoScene::FilePrintf( buf, level + 1, "%.4f %.4f\n",
  1530. sample->time,
  1531. sample->value );
  1532. }
  1533. }
  1534. CChoreoScene::FilePrintf( buf, level, "}\n" );
  1535. }
  1536. void CChoreoScene::FileSaveScaleSettings( CUtlBuffer& buf, int level, CChoreoScene *scene )
  1537. {
  1538. // Nothing to save?
  1539. int c = scene->m_TimeZoomLookup.Count();
  1540. if ( c <= 0 )
  1541. return;
  1542. FilePrintf( buf, level, "scalesettings\n" );
  1543. FilePrintf( buf, level, "{\n" );
  1544. for ( int i = 0; i < c; i++ )
  1545. {
  1546. int value = scene->m_TimeZoomLookup[ i ];
  1547. FilePrintf( buf, level + 1, "\"%s\" \"%i\"\n",
  1548. scene->m_TimeZoomLookup.GetElementName( i ),
  1549. value );
  1550. }
  1551. FilePrintf( buf, level, "}\n" );
  1552. }
  1553. //-----------------------------------------------------------------------------
  1554. // Purpose:
  1555. // Input : buf -
  1556. // level -
  1557. // *track -
  1558. //-----------------------------------------------------------------------------
  1559. void CChoreoScene::FileSaveFlexAnimationTrack( CUtlBuffer& buf, int level, CFlexAnimationTrack *track, int nDefaultCurveType )
  1560. {
  1561. if ( !track )
  1562. return;
  1563. if ( !track->IsTrackActive() && track->GetNumSamples() <= 0 )
  1564. return;
  1565. char line[ 1024 ];
  1566. Q_snprintf( line, sizeof( line ), "\"%s\" ", track->GetFlexControllerName() );
  1567. if ( !track->IsTrackActive() )
  1568. {
  1569. char sz[ 256 ];
  1570. Q_snprintf( sz, sizeof( sz ), "disabled " );
  1571. Q_strncat( line, sz, sizeof( line ), COPY_ALL_CHARACTERS );
  1572. }
  1573. if ( track->IsComboType() )
  1574. {
  1575. char sz[ 256 ];
  1576. Q_snprintf( sz, sizeof( sz ), "combo " );
  1577. Q_strncat( line, sz, sizeof( line ), COPY_ALL_CHARACTERS );
  1578. }
  1579. if ( track->GetMin() != 0.0f || track->GetMax() != 1.0f)
  1580. {
  1581. char sz[ 256 ];
  1582. Q_snprintf( sz, sizeof( sz ), "range %.1f %.1f ", track->GetMin(), track->GetMax() );
  1583. Q_strncat( line, sz, sizeof( line ), COPY_ALL_CHARACTERS );
  1584. }
  1585. if ( track->IsEdgeActive( true ) || track->IsEdgeActive( false ) )
  1586. {
  1587. char edgestr[ 512 ];
  1588. edgestr[ 0 ] = 0;
  1589. if ( track->IsEdgeActive( true ) )
  1590. {
  1591. char sz[ 256 ];
  1592. Q_snprintf( sz, sizeof( sz ), "leftedge %s %.3f ", Interpolator_NameForCurveType( track->GetEdgeCurveType( true ), false ), track->GetEdgeZeroValue( true ) );
  1593. Q_strncat( edgestr, sz, sizeof( edgestr ), COPY_ALL_CHARACTERS );
  1594. }
  1595. if ( track->IsEdgeActive( false ) )
  1596. {
  1597. char sz[ 256 ];
  1598. Q_snprintf( sz, sizeof( sz ), "rightedge %s %.3f ", Interpolator_NameForCurveType( track->GetEdgeCurveType( false ), false ), track->GetEdgeZeroValue( false ) );
  1599. Q_strncat( edgestr, sz, sizeof( edgestr ), COPY_ALL_CHARACTERS );
  1600. }
  1601. Q_strncat( line, edgestr, sizeof( line ), COPY_ALL_CHARACTERS );
  1602. }
  1603. FilePrintf( buf, level + 2, "%s\n", line );
  1604. // Write out samples
  1605. FilePrintf( buf, level + 2, "{\n" );
  1606. for ( int j = 0 ; j < track->GetNumSamples( 0 ) ; j++ )
  1607. {
  1608. CExpressionSample *s = track->GetSample( j, 0 );
  1609. if ( !s )
  1610. continue;
  1611. if ( s->GetCurveType() != nDefaultCurveType && s->GetCurveType() != CURVE_DEFAULT )
  1612. {
  1613. FilePrintf( buf, level + 3, "%.4f %.4f \"%s\"\n",
  1614. s->time,
  1615. s->value,
  1616. Interpolator_NameForCurveType( s->GetCurveType(), false ) );
  1617. }
  1618. else
  1619. {
  1620. FilePrintf( buf, level + 3, "%.4f %.4f\n",
  1621. s->time,
  1622. s->value );
  1623. }
  1624. }
  1625. FilePrintf( buf, level + 2, "}\n" );
  1626. // Write out combo samples
  1627. if ( track->IsComboType() )
  1628. {
  1629. FilePrintf( buf, level + 2, "{\n" );
  1630. for ( int j = 0 ; j < track->GetNumSamples( 1) ; j++ )
  1631. {
  1632. CExpressionSample *s = track->GetSample( j, 1 );
  1633. if ( !s )
  1634. continue;
  1635. if ( s->GetCurveType() != nDefaultCurveType && s->GetCurveType() != CURVE_DEFAULT )
  1636. {
  1637. FilePrintf( buf, level + 3, "%.4f %.4f \"%s\"\n",
  1638. s->time,
  1639. s->value,
  1640. Interpolator_NameForCurveType( s->GetCurveType(), false ) );
  1641. }
  1642. else
  1643. {
  1644. FilePrintf( buf, level + 3, "%.4f %.4f\n",
  1645. s->time,
  1646. s->value );
  1647. }
  1648. }
  1649. FilePrintf( buf, level + 2, "}\n" );
  1650. }
  1651. }
  1652. //-----------------------------------------------------------------------------
  1653. // Purpose:
  1654. // Input : buf -
  1655. // level -
  1656. // *e -
  1657. //-----------------------------------------------------------------------------
  1658. void CChoreoScene::FileSaveFlexAnimations( CUtlBuffer& buf, int level, CChoreoEvent *e )
  1659. {
  1660. // Nothing to save
  1661. if ( e->GetNumFlexAnimationTracks() <= 0 )
  1662. return;
  1663. if ( e->GetDefaultCurveType() != CURVE_DEFAULT )
  1664. {
  1665. FilePrintf( buf, level + 1, "flexanimations samples_use_time defaultcurvetype=%s\n",
  1666. Interpolator_NameForCurveType( e->GetDefaultCurveType(), false ) );
  1667. }
  1668. else
  1669. {
  1670. FilePrintf( buf, level + 1, "flexanimations samples_use_time\n" );
  1671. }
  1672. FilePrintf( buf, level + 1, "{\n" );
  1673. for ( int i = 0; i < e->GetNumFlexAnimationTracks(); i++ )
  1674. {
  1675. CFlexAnimationTrack *track = e->GetFlexAnimationTrack( i );
  1676. FileSaveFlexAnimationTrack( buf, level, track, e->GetDefaultCurveType() );
  1677. }
  1678. FilePrintf( buf, level + 1, "}\n" );
  1679. }
  1680. //-----------------------------------------------------------------------------
  1681. // Purpose:
  1682. // Input : *fp -
  1683. // level -
  1684. // *e -
  1685. //-----------------------------------------------------------------------------
  1686. void CChoreoScene::FileSaveEvent( CUtlBuffer& buf, int level, CChoreoEvent *e )
  1687. {
  1688. if ( !e->IsMarkedForSave() )
  1689. return;
  1690. FilePrintf( buf, level, "event %s \"%s\"\n", CChoreoEvent::NameForType( e->GetType() ), e->GetName() );
  1691. FilePrintf( buf, level, "{\n" );
  1692. float st, et;
  1693. st = e->GetStartTime();
  1694. et = e->GetEndTime();
  1695. FilePrintf( buf, level + 1, "time %f %f\n", st, et );
  1696. FilePrintf( buf, level + 1, "param \"%s\"\n", e->GetParameters() );
  1697. if ( strlen( e->GetParameters2() ) > 0 )
  1698. {
  1699. FilePrintf( buf, level + 1, "param2 \"%s\"\n", e->GetParameters2() );
  1700. }
  1701. if ( strlen( e->GetParameters3() ) > 0 )
  1702. {
  1703. FilePrintf( buf, level + 1, "param3 \"%s\"\n", e->GetParameters3() );
  1704. }
  1705. if ( e->GetRampCount() > 0 )
  1706. {
  1707. FileSaveRamp( buf, level + 1, e );
  1708. }
  1709. if ( e->GetPitch() != 0 )
  1710. {
  1711. FilePrintf( buf, level + 1, "pitch \"%i\"\n", e->GetPitch() );
  1712. }
  1713. if ( e->GetYaw() != 0 )
  1714. {
  1715. FilePrintf( buf, level + 1, "yaw \"%i\"\n", e->GetYaw() );
  1716. }
  1717. if ( e->IsResumeCondition() )
  1718. {
  1719. FilePrintf( buf, level + 1, "resumecondition\n" );
  1720. }
  1721. if ( e->IsLockBodyFacing() )
  1722. {
  1723. FilePrintf( buf, level + 1, "lockbodyfacing\n" );
  1724. }
  1725. if ( e->GetDistanceToTarget() > 0.0f )
  1726. {
  1727. FilePrintf( buf, level + 1, "distancetotarget %.2f\n", e->GetDistanceToTarget() );
  1728. }
  1729. if ( e->GetForceShortMovement() )
  1730. {
  1731. FilePrintf( buf, level + 1, "forceshortmovement\n" );
  1732. }
  1733. if ( e->GetSyncToFollowingGesture() )
  1734. {
  1735. FilePrintf( buf, level + 1, "synctofollowinggesture\n" );
  1736. }
  1737. if ( !e->GetActive() )
  1738. {
  1739. FilePrintf( buf, level + 1, "active 0\n" );
  1740. }
  1741. if ( e->GetPlayOverScript() )
  1742. {
  1743. FilePrintf( buf, level + 1, "playoverscript\n" );
  1744. }
  1745. if ( e->IsFixedLength() )
  1746. {
  1747. FilePrintf( buf, level + 1, "fixedlength\n" );
  1748. }
  1749. if ( e->GetNumRelativeTags() > 0 )
  1750. {
  1751. FilePrintf( buf, level + 1, "tags\n" );
  1752. FilePrintf( buf, level + 1, "{\n" );
  1753. for ( int t = 0; t < e->GetNumRelativeTags(); t++ )
  1754. {
  1755. CEventRelativeTag *rt = e->GetRelativeTag( t );
  1756. Assert( rt );
  1757. FilePrintf( buf, level + 2, "\"%s\" %f\n", rt->GetName(), rt->GetPercentage() );
  1758. }
  1759. FilePrintf( buf, level + 1, "}\n" );
  1760. }
  1761. if ( e->GetNumTimingTags() > 0 )
  1762. {
  1763. FilePrintf( buf, level + 1, "flextimingtags\n" );
  1764. FilePrintf( buf, level + 1, "{\n" );
  1765. for ( int t = 0; t < e->GetNumTimingTags(); t++ )
  1766. {
  1767. CFlexTimingTag *tt = e->GetTimingTag( t );
  1768. Assert( tt );
  1769. FilePrintf( buf, level + 2, "\"%s\" %f %i\n", tt->GetName(), tt->GetPercentage(), tt->GetLocked() ? 1 : 0 );
  1770. }
  1771. FilePrintf( buf, level + 1, "}\n" );
  1772. }
  1773. int tagtype;
  1774. for ( tagtype = 0; tagtype < CChoreoEvent::NUM_ABS_TAG_TYPES; tagtype++ )
  1775. {
  1776. if ( e->GetNumAbsoluteTags( (CChoreoEvent::AbsTagType)tagtype ) > 0 )
  1777. {
  1778. FilePrintf( buf, level + 1, "absolutetags %s\n", CChoreoEvent::NameForAbsoluteTagType( (CChoreoEvent::AbsTagType)tagtype ) );
  1779. FilePrintf( buf, level + 1, "{\n" );
  1780. for ( int t = 0; t < e->GetNumAbsoluteTags( (CChoreoEvent::AbsTagType)tagtype ); t++ )
  1781. {
  1782. CEventAbsoluteTag *abstag = e->GetAbsoluteTag( (CChoreoEvent::AbsTagType)tagtype, t );
  1783. Assert( abstag );
  1784. FilePrintf( buf, level + 2, "\"%s\" %f\n", abstag->GetName(), abstag->GetPercentage() );
  1785. }
  1786. FilePrintf( buf, level + 1, "}\n" );
  1787. }
  1788. }
  1789. if ( e->GetType() == CChoreoEvent::GESTURE )
  1790. {
  1791. float duration;
  1792. if ( e->GetGestureSequenceDuration( duration ) )
  1793. {
  1794. FilePrintf( buf, level + 1, "sequenceduration %f\n", duration );
  1795. }
  1796. }
  1797. if ( e->IsUsingRelativeTag() )
  1798. {
  1799. FilePrintf( buf, level + 1, "relativetag \"%s\" \"%s\"\n",
  1800. e->GetRelativeTagName(), e->GetRelativeWavName() );
  1801. }
  1802. if ( e->GetNumFlexAnimationTracks() > 0 )
  1803. {
  1804. FileSaveFlexAnimations( buf, level, e );
  1805. }
  1806. if ( e->GetType() == CChoreoEvent::LOOP )
  1807. {
  1808. FilePrintf( buf, level + 1, "loopcount \"%i\"\n", e->GetLoopCount() );
  1809. }
  1810. if ( e->GetType() == CChoreoEvent::SPEAK )
  1811. {
  1812. FilePrintf( buf, level + 1, "cctype \"%s\"\n", CChoreoEvent::NameForCCType( e->GetCloseCaptionType() ) );
  1813. FilePrintf( buf, level + 1, "cctoken \"%s\"\n", e->GetCloseCaptionToken() );
  1814. if ( e->GetCloseCaptionType() != CChoreoEvent::CC_DISABLED &&
  1815. e->IsUsingCombinedFile() )
  1816. {
  1817. FilePrintf( buf, level + 1, "cc_usingcombinedfile\n" );
  1818. }
  1819. if ( e->IsCombinedUsingGenderToken() )
  1820. {
  1821. FilePrintf( buf, level + 1, "cc_combinedusesgender\n" );
  1822. }
  1823. if ( e->IsSuppressingCaptionAttenuation() )
  1824. {
  1825. FilePrintf( buf, level + 1, "cc_noattenuate\n" );
  1826. }
  1827. }
  1828. FilePrintf( buf, level, "}\n" );
  1829. }
  1830. //-----------------------------------------------------------------------------
  1831. // Purpose:
  1832. // Input : *fp -
  1833. // level -
  1834. // *c -
  1835. //-----------------------------------------------------------------------------
  1836. void CChoreoScene::FileSaveChannel( CUtlBuffer& buf, int level, CChoreoChannel *c )
  1837. {
  1838. if ( !c->IsMarkedForSave() )
  1839. return;
  1840. FilePrintf( buf, level, "channel \"%s\"\n", c->GetName() );
  1841. FilePrintf( buf, level, "{\n" );
  1842. for ( int i = 0; i < c->GetNumEvents(); i++ )
  1843. {
  1844. CChoreoEvent *e = c->GetEvent( i );
  1845. if ( e )
  1846. {
  1847. FileSaveEvent( buf, level + 1, e );
  1848. }
  1849. }
  1850. if ( !c->GetActive() )
  1851. {
  1852. // Only write out inactive
  1853. FilePrintf( buf, level + 1, "active \"0\"\n" );
  1854. }
  1855. FilePrintf( buf, level, "}\n" );
  1856. }
  1857. //-----------------------------------------------------------------------------
  1858. // Purpose:
  1859. // Input : *fp -
  1860. // level -
  1861. // *a -
  1862. //-----------------------------------------------------------------------------
  1863. void CChoreoScene::FileSaveActor( CUtlBuffer& buf, int level, CChoreoActor *a )
  1864. {
  1865. if ( !a->IsMarkedForSave() )
  1866. return;
  1867. FilePrintf( buf, level, "actor \"%s\"\n", a->GetName() );
  1868. FilePrintf( buf, level, "{\n" );
  1869. for ( int i = 0; i < a->GetNumChannels(); i++ )
  1870. {
  1871. CChoreoChannel *c = a->GetChannel( i );
  1872. if ( c )
  1873. {
  1874. FileSaveChannel( buf, level + 1, c );
  1875. }
  1876. }
  1877. if ( Q_strlen( a->GetFacePoserModelName() ) > 0 )
  1878. {
  1879. FilePrintf( buf, level + 1, "faceposermodel \"%s\"\n", a->GetFacePoserModelName() );
  1880. }
  1881. if ( !a->GetActive() )
  1882. {
  1883. // Only write out inactive
  1884. FilePrintf( buf, level + 1, "active \"0\"\n" );
  1885. }
  1886. FilePrintf( buf, level, "}\n\n" );
  1887. }
  1888. //-----------------------------------------------------------------------------
  1889. // Purpose:
  1890. // Output : float
  1891. //-----------------------------------------------------------------------------
  1892. float CChoreoScene::FindAdjustedStartTime( void )
  1893. {
  1894. float earliest_time = 0.0f;
  1895. CChoreoEvent *e;
  1896. for ( int i = 0; i < m_Events.Size(); i++ )
  1897. {
  1898. e = m_Events[ i ];
  1899. float starttime = e->GetStartTime();
  1900. // If it's a wav file, pre-queue the starting time by the sound system's
  1901. // current latency
  1902. if ( e->GetType() == CChoreoEvent::SPEAK )
  1903. {
  1904. starttime -= m_flSoundSystemLatency;
  1905. }
  1906. if ( starttime < earliest_time )
  1907. {
  1908. earliest_time = starttime;
  1909. }
  1910. }
  1911. return earliest_time;
  1912. }
  1913. //-----------------------------------------------------------------------------
  1914. // Purpose:
  1915. // Output : float
  1916. //-----------------------------------------------------------------------------
  1917. float CChoreoScene::FindAdjustedEndTime( void )
  1918. {
  1919. float latest_time = 0.0f;
  1920. CChoreoEvent *e;
  1921. for ( int i = 0; i < m_Events.Size(); i++ )
  1922. {
  1923. e = m_Events[ i ];
  1924. float endtime = e->GetStartTime();
  1925. if ( e->HasEndTime() )
  1926. {
  1927. endtime = e->GetEndTime();
  1928. }
  1929. // If it's a wav file, pre-queue the starting time by the sound system's
  1930. // current latency
  1931. if ( e->GetType() == CChoreoEvent::SPEAK )
  1932. {
  1933. endtime += m_flSoundSystemLatency;
  1934. }
  1935. if ( endtime > latest_time )
  1936. {
  1937. latest_time = endtime;
  1938. }
  1939. }
  1940. return latest_time;
  1941. }
  1942. //-----------------------------------------------------------------------------
  1943. // Purpose:
  1944. //-----------------------------------------------------------------------------
  1945. void CChoreoScene::ResetSimulation( bool forward /*= true*/, float starttime /*= 0.0f*/, float endtime /*= 0.0f*/ )
  1946. {
  1947. CChoreoEvent *e;
  1948. m_ActiveResumeConditions.RemoveAll();
  1949. m_ResumeConditions.RemoveAll();
  1950. m_PauseEvents.RemoveAll();
  1951. // Put all items into the pending queue
  1952. for ( int i = 0; i < m_Events.Size(); i++ )
  1953. {
  1954. e = m_Events[ i ];
  1955. e->ResetProcessing();
  1956. if ( e->GetType() == CChoreoEvent::SECTION )
  1957. {
  1958. m_PauseEvents.AddToTail( e );
  1959. continue;
  1960. }
  1961. if ( e->IsResumeCondition() )
  1962. {
  1963. m_ResumeConditions.AddToTail( e );
  1964. continue;
  1965. }
  1966. }
  1967. // Find earliest adjusted start time
  1968. m_flEarliestTime = FindAdjustedStartTime();
  1969. m_flLatestTime = FindAdjustedEndTime();
  1970. m_flCurrentTime = forward ? m_flEarliestTime : m_flLatestTime;
  1971. m_flStartLoopTime = -1.f;
  1972. // choreoprintf( 0, "Start time %f\n", m_flCurrentTime );
  1973. m_flLastActiveTime = 0.0f;
  1974. m_nActiveEvents = m_Events.Size();
  1975. m_flStartTime = starttime;
  1976. m_flEndTime = endtime;
  1977. }
  1978. //-----------------------------------------------------------------------------
  1979. // Purpose:
  1980. //-----------------------------------------------------------------------------
  1981. bool CChoreoScene::CheckEventCompletion( void )
  1982. {
  1983. CChoreoEvent *e;
  1984. bool bAllCompleted = true;
  1985. // check all items in the active pending queue
  1986. for ( int i = 0; i < m_ActiveResumeConditions.Size(); i++ )
  1987. {
  1988. e = m_ActiveResumeConditions[ i ];
  1989. bAllCompleted = bAllCompleted && e->CheckProcessing( m_pIChoreoEventCallback, this, m_flCurrentTime );
  1990. }
  1991. return bAllCompleted;
  1992. }
  1993. //-----------------------------------------------------------------------------
  1994. // Purpose:
  1995. // Output : Returns true on success, false on failure.
  1996. //-----------------------------------------------------------------------------
  1997. bool CChoreoScene::SimulationFinished( void )
  1998. {
  1999. // Scene's linger for a little bit to allow things to settle
  2000. // check for events that are still active...
  2001. if ( m_flCurrentTime > m_flLatestTime )
  2002. {
  2003. if ( m_nActiveEvents != 0 )
  2004. {
  2005. return false;
  2006. }
  2007. return true;
  2008. }
  2009. if ( m_flCurrentTime < m_flEarliestTime )
  2010. {
  2011. return true;
  2012. }
  2013. return false;
  2014. }
  2015. //-----------------------------------------------------------------------------
  2016. // Purpose:
  2017. //-----------------------------------------------------------------------------
  2018. CChoreoEvent *CChoreoScene::FindPauseBetweenTimes( float starttime, float endtime )
  2019. {
  2020. CChoreoEvent *e;
  2021. // Iterate through all events in the scene
  2022. for ( int i = 0; i < m_PauseEvents.Size(); i++ )
  2023. {
  2024. e = m_PauseEvents[ i ];
  2025. if ( !e )
  2026. continue;
  2027. Assert( e->GetType() == CChoreoEvent::SECTION );
  2028. int time_is = IsTimeInRange( e->GetStartTime(), starttime, endtime );
  2029. if ( IN_RANGE != time_is )
  2030. continue;
  2031. // Found a pause in between start and end time
  2032. return e;
  2033. }
  2034. // No pause inside the specified time span
  2035. return NULL;
  2036. }
  2037. int CChoreoScene::IsTimeInRange( float t, float starttime, float endtime )
  2038. {
  2039. if ( t > endtime )
  2040. {
  2041. return AFTER_RANGE;
  2042. }
  2043. else if ( t < starttime )
  2044. {
  2045. return BEFORE_RANGE;
  2046. }
  2047. return IN_RANGE;
  2048. }
  2049. int CChoreoScene::EventThink( CChoreoEvent *e, float frame_start_time, float frame_end_time, bool playing_forward, PROCESSING_TYPE& disposition )
  2050. {
  2051. disposition = PROCESSING_TYPE_IGNORE;
  2052. int iret = 0;
  2053. bool hasend = e->HasEndTime();
  2054. float starttime, endtime;
  2055. starttime = e->GetStartTime();
  2056. endtime = hasend ? e->GetEndTime() : e->GetStartTime();
  2057. if ( !playing_forward )
  2058. {
  2059. // Swap intervals
  2060. float temp = frame_start_time;
  2061. frame_start_time = frame_end_time;
  2062. frame_end_time = temp;
  2063. }
  2064. bool suppressed = false;
  2065. // Special processing
  2066. switch ( e->GetType() )
  2067. {
  2068. default:
  2069. break;
  2070. case CChoreoEvent::SPEAK:
  2071. // If it's a wav file, pre-queue the starting/endtime time by the sound system's
  2072. // current latency
  2073. {
  2074. if ( playing_forward )
  2075. {
  2076. starttime -= m_flSoundSystemLatency;
  2077. // Search for pause condition in between the original time and the
  2078. // adjusted start time, but make sure that the pause event hasn't already triggered...
  2079. CChoreoEvent *pauseEvent = FindPauseBetweenTimes( starttime, starttime + m_flSoundSystemLatency );
  2080. if ( pauseEvent &&
  2081. ( frame_start_time <= pauseEvent->GetStartTime() ) )
  2082. {
  2083. pauseEvent->AddEventDependency( e );
  2084. suppressed = true;
  2085. }
  2086. }
  2087. /*
  2088. else
  2089. // Don't bother if playing backward!!!
  2090. {
  2091. endtime += m_flSoundSystemLatency;
  2092. // Search for pause condition in between the original time and the
  2093. // adjusted start time
  2094. CChoreoEvent *pauseEvent = FindPauseBetweenTimes( endtime - m_flSoundSystemLatency, endtime );
  2095. if ( pauseEvent )
  2096. {
  2097. pauseEvent->AddEventDependency( e );
  2098. suppressed = true;
  2099. }
  2100. }
  2101. */
  2102. if ( !suppressed )
  2103. {
  2104. // if this SPEAK event starts before the beginning of the current loop, don't play the SPEAK event again in the loop
  2105. if ( m_flStartLoopTime >= 0.f && starttime < m_flStartLoopTime )
  2106. {
  2107. return iret;
  2108. }
  2109. }
  2110. }
  2111. break;
  2112. case CChoreoEvent::SUBSCENE:
  2113. {
  2114. if ( IsSubScene() )
  2115. {
  2116. suppressed = true;
  2117. }
  2118. }
  2119. break;
  2120. }
  2121. if ( suppressed )
  2122. {
  2123. if ( e->IsProcessing() )
  2124. {
  2125. disposition = PROCESSING_TYPE_STOP;
  2126. }
  2127. return iret;
  2128. }
  2129. int where_is_event;
  2130. if ( e->IsProcessing() )
  2131. {
  2132. where_is_event = IsTimeInRange( frame_start_time, starttime, endtime );
  2133. if ( IN_RANGE == where_is_event )
  2134. {
  2135. disposition = PROCESSING_TYPE_CONTINUE;
  2136. iret = 1;
  2137. }
  2138. else
  2139. {
  2140. disposition = PROCESSING_TYPE_STOP;
  2141. }
  2142. }
  2143. else
  2144. {
  2145. // Is the event supposed to be active at this time
  2146. where_is_event = IsTimeInRange( frame_start_time, starttime, endtime );
  2147. if ( IN_RANGE == where_is_event )
  2148. {
  2149. if ( e->IsResumeCondition() )
  2150. {
  2151. disposition = PROCESSING_TYPE_START_RESUMECONDITION;
  2152. }
  2153. else
  2154. {
  2155. disposition = PROCESSING_TYPE_START;
  2156. }
  2157. iret = 1;
  2158. }
  2159. // See if it's a single fire event which should occur during this frame
  2160. else if ( !hasend )
  2161. {
  2162. where_is_event = IsTimeInRange( starttime, frame_start_time, frame_end_time );
  2163. if ( IN_RANGE == where_is_event )
  2164. {
  2165. disposition = PROCESSING_TYPE_START;
  2166. iret = 1;
  2167. }
  2168. }
  2169. }
  2170. return iret;
  2171. }
  2172. //-----------------------------------------------------------------------------
  2173. // Purpose:
  2174. // Input : &e0 -
  2175. // &e1 -
  2176. // Output : static bool
  2177. //-----------------------------------------------------------------------------
  2178. bool CChoreoScene::EventLess( const CChoreoScene::ActiveList &al0, const CChoreoScene::ActiveList &al1 )
  2179. {
  2180. CChoreoEvent *event0, *event1;
  2181. event0 = const_cast< CChoreoEvent * >( al0.e );
  2182. event1 = const_cast< CChoreoEvent * >( al1.e );
  2183. if ( event0->GetStartTime() < event1->GetStartTime() )
  2184. {
  2185. return true;
  2186. }
  2187. if ( event0->GetStartTime() > event1->GetStartTime() )
  2188. {
  2189. return false;
  2190. }
  2191. // Check for end time overlap
  2192. if ( event0->HasEndTime() && event1->HasEndTime() )
  2193. {
  2194. if ( event0->GetEndTime() > event1->GetEndTime() )
  2195. return true;
  2196. else if ( event0->GetEndTime() < event1->GetEndTime() )
  2197. return false;
  2198. }
  2199. CChoreoActor *a0, *a1;
  2200. a0 = event0->GetActor();
  2201. a1 = event1->GetActor();
  2202. // Start time equal, go to order in channel
  2203. if ( !a0 || !a1 || a0 != a1 )
  2204. {
  2205. return strcmp( event0->GetName(), event1->GetName() ) == -1;
  2206. }
  2207. CChoreoChannel *c0 = event0->GetChannel();
  2208. CChoreoChannel *c1 = event1->GetChannel();
  2209. if ( !c0 || !c1 || c0 != c1 )
  2210. {
  2211. return strcmp( event0->GetName(), event1->GetName() ) == -1;
  2212. }
  2213. // Go by slot within channel
  2214. int index0 = a0->FindChannelIndex( c0 );
  2215. int index1 = a1->FindChannelIndex( c1 );
  2216. return ( index0 < index1 );
  2217. }
  2218. //-----------------------------------------------------------------------------
  2219. // Purpose:
  2220. //-----------------------------------------------------------------------------
  2221. void CChoreoScene::ClearPauseEventDependencies()
  2222. {
  2223. int c = m_PauseEvents.Count();
  2224. for ( int i = 0 ; i < c; ++i )
  2225. {
  2226. CChoreoEvent *pause = m_PauseEvents[ i ];
  2227. Assert( pause );
  2228. pause->ClearEventDependencies();
  2229. }
  2230. }
  2231. //-----------------------------------------------------------------------------
  2232. // Purpose:
  2233. // Input : *pauseEvent -
  2234. // *suppressed -
  2235. //-----------------------------------------------------------------------------
  2236. void CChoreoScene::AddPauseEventDependency( CChoreoEvent *pauseEvent, CChoreoEvent *suppressed )
  2237. {
  2238. Assert( pauseEvent );
  2239. Assert( pauseEvent != suppressed );
  2240. pauseEvent->AddEventDependency( suppressed );
  2241. }
  2242. //-----------------------------------------------------------------------------
  2243. // Purpose:
  2244. // Input : curtime -
  2245. //-----------------------------------------------------------------------------
  2246. void CChoreoScene::Think( float curtime )
  2247. {
  2248. CChoreoEvent *e;
  2249. float oldt = m_flCurrentTime;
  2250. float dt;
  2251. m_nActiveEvents = 0;
  2252. ClearPauseEventDependencies();
  2253. CUtlRBTree< ActiveList, int > pending(0,0,EventLess);
  2254. // Handle loop events first:
  2255. //float flLoopPoint = LoopThink( curtime );
  2256. LoopThink( curtime );
  2257. if ( m_flCurrentTime != oldt )
  2258. {
  2259. // We hit a loop, we need to adjust the times.
  2260. //curtime = m_flCurrentTime + ( oldt - flLoopPoint ); // if we overshot, skip by how much we overshot
  2261. curtime = m_flCurrentTime;
  2262. Assert( curtime > 0.0f );
  2263. }
  2264. dt = curtime - oldt;
  2265. oldt = m_flCurrentTime;
  2266. bool playing_forward = ( dt >= 0.0f ) ? true : false;
  2267. //if ( !playing_forward )
  2268. //{
  2269. // Msg( "-----dt was negative. %f oldt: %f t: %f\n", dt, oldt, curtime );
  2270. //}
  2271. //else
  2272. //{
  2273. // Msg( "+++++dt was positive. %f oldt: %f t: %f\n", dt, oldt, curtime );
  2274. //}
  2275. // Iterate through all events in the scene
  2276. int i;
  2277. for ( i = 0; i < m_Events.Size(); i++ )
  2278. {
  2279. e = m_Events[ i ];
  2280. if ( !e )
  2281. continue;
  2282. PROCESSING_TYPE disposition;
  2283. m_nActiveEvents += EventThink( e, m_flCurrentTime, curtime, playing_forward, disposition );
  2284. if ( disposition != PROCESSING_TYPE_IGNORE )
  2285. {
  2286. ActiveList entry;
  2287. entry.e = e;
  2288. entry.pt = disposition;
  2289. pending.Insert( entry );
  2290. }
  2291. }
  2292. // Events are sorted start time and then by channel and actor slot or by name if those aren't equal
  2293. i = pending.FirstInorder();
  2294. while ( i != pending.InvalidIndex() )
  2295. {
  2296. ActiveList *entry = &pending[ i ];
  2297. Assert( entry->e );
  2298. ProcessActiveListEntry( entry );
  2299. i = pending.NextInorder( i );
  2300. }
  2301. // If a Process call slams this time, don't override it!!!
  2302. if ( oldt == m_flCurrentTime )
  2303. {
  2304. m_flCurrentTime = curtime;
  2305. }
  2306. // Still processing?
  2307. if ( m_nActiveEvents )
  2308. {
  2309. m_flLastActiveTime = m_flCurrentTime;
  2310. }
  2311. }
  2312. //-----------------------------------------------------------------------------
  2313. // Purpose: Loop points are handled prior to other events
  2314. // Input : curtime -
  2315. //-----------------------------------------------------------------------------
  2316. float CChoreoScene::LoopThink( float curtime )
  2317. {
  2318. float oldt = m_flCurrentTime;
  2319. float dt = curtime - oldt;
  2320. bool playing_forward = ( dt >= 0.0f ) ? true : false;
  2321. // Iterate through all events in the scene
  2322. CChoreoEvent *e;
  2323. int i;
  2324. for ( i = 0; i < m_Events.Size(); i++ )
  2325. {
  2326. e = m_Events[ i ];
  2327. if ( !e || e->GetType() != CChoreoEvent::LOOP )
  2328. continue;
  2329. PROCESSING_TYPE disposition;
  2330. m_nActiveEvents += EventThink( e, m_flCurrentTime, curtime, playing_forward, disposition );
  2331. if ( disposition != PROCESSING_TYPE_IGNORE )
  2332. {
  2333. ActiveList entry;
  2334. entry.e = e;
  2335. entry.pt = disposition;
  2336. //float ret = (float)atof( e->GetParameters() );
  2337. float ret = e->GetStartTime();
  2338. ProcessActiveListEntry( &entry );
  2339. return ret;
  2340. }
  2341. }
  2342. return 0.0f;
  2343. }
  2344. //-----------------------------------------------------------------------------
  2345. // Purpose:
  2346. // Input : entry -
  2347. //-----------------------------------------------------------------------------
  2348. void CChoreoScene::ProcessActiveListEntry( ActiveList *entry )
  2349. {
  2350. const bool dump = false;
  2351. if ( dump )
  2352. {
  2353. Msg( "%f == %s starting at %f (actor %p channel %p)\n",
  2354. m_flCurrentTime, entry->e->GetName(), entry->e->GetStartTime(),
  2355. entry->e->GetActor(), entry->e->GetChannel() );
  2356. }
  2357. switch ( entry->pt )
  2358. {
  2359. default:
  2360. case PROCESSING_TYPE_IGNORE:
  2361. {
  2362. Assert( 0 );
  2363. }
  2364. break;
  2365. case PROCESSING_TYPE_START:
  2366. case PROCESSING_TYPE_START_RESUMECONDITION:
  2367. {
  2368. entry->e->StartProcessing( m_pIChoreoEventCallback, this, m_flCurrentTime );
  2369. if ( entry->pt == PROCESSING_TYPE_START_RESUMECONDITION )
  2370. {
  2371. Assert( entry->e->IsResumeCondition() );
  2372. m_ActiveResumeConditions.AddToTail( entry->e );
  2373. }
  2374. // This event can "pause" the scene, so we need to remember who "paused" the scene so that
  2375. // when we resume we can resume any suppressed events dependent on this pauser...
  2376. if ( entry->e->GetType() == CChoreoEvent::SECTION )
  2377. {
  2378. // So this event should be in the pauseevents list, otherwise this'll be -1
  2379. m_nLastPauseEvent = m_PauseEvents.Find( entry->e );
  2380. }
  2381. }
  2382. break;
  2383. case PROCESSING_TYPE_CONTINUE:
  2384. {
  2385. entry->e->ContinueProcessing( m_pIChoreoEventCallback, this, m_flCurrentTime );
  2386. }
  2387. break;
  2388. case PROCESSING_TYPE_STOP:
  2389. {
  2390. entry->e->StopProcessing( m_pIChoreoEventCallback, this, m_flCurrentTime );
  2391. }
  2392. break;
  2393. }
  2394. }
  2395. //-----------------------------------------------------------------------------
  2396. // Purpose:
  2397. // Output : float
  2398. //-----------------------------------------------------------------------------
  2399. float CChoreoScene::GetTime( void )
  2400. {
  2401. return m_flCurrentTime;
  2402. }
  2403. //-----------------------------------------------------------------------------
  2404. // Purpose:
  2405. // Input : t -
  2406. //-----------------------------------------------------------------------------
  2407. void CChoreoScene::SetTime( float t )
  2408. {
  2409. m_flCurrentTime = t;
  2410. }
  2411. //-----------------------------------------------------------------------------
  2412. // Purpose:
  2413. // Input : t -
  2414. //-----------------------------------------------------------------------------
  2415. void CChoreoScene::LoopToTime( float t )
  2416. {
  2417. m_flCurrentTime = t;
  2418. m_flStartLoopTime = t;
  2419. }
  2420. //-----------------------------------------------------------------------------
  2421. // Purpose:
  2422. // Input : *pfn -
  2423. //-----------------------------------------------------------------------------
  2424. void CChoreoScene::SetPrintFunc( void ( *pfn ) ( const char *fmt, ... ) )
  2425. {
  2426. m_pfnPrint = pfn;
  2427. }
  2428. //-----------------------------------------------------------------------------
  2429. // Purpose:
  2430. // Input : *actor -
  2431. //-----------------------------------------------------------------------------
  2432. void CChoreoScene::RemoveActor( CChoreoActor *actor )
  2433. {
  2434. int idx = FindActorIndex( actor );
  2435. if ( idx == -1 )
  2436. return;
  2437. m_Actors.Remove( idx );
  2438. }
  2439. //-----------------------------------------------------------------------------
  2440. // Purpose:
  2441. // Input : *actor -
  2442. // Output : int
  2443. //-----------------------------------------------------------------------------
  2444. int CChoreoScene::FindActorIndex( CChoreoActor *actor )
  2445. {
  2446. for ( int i = 0; i < m_Actors.Size(); i++ )
  2447. {
  2448. if ( actor == m_Actors[ i ] )
  2449. {
  2450. return i;
  2451. }
  2452. }
  2453. return -1;
  2454. }
  2455. //-----------------------------------------------------------------------------
  2456. // Purpose:
  2457. // Input : a1 -
  2458. // a2 -
  2459. //-----------------------------------------------------------------------------
  2460. void CChoreoScene::SwapActors( int a1, int a2 )
  2461. {
  2462. CChoreoActor *temp;
  2463. temp = m_Actors[ a1 ];
  2464. m_Actors[ a1 ] = m_Actors[ a2 ];
  2465. m_Actors[ a2 ] = temp;
  2466. }
  2467. //-----------------------------------------------------------------------------
  2468. // Purpose:
  2469. // Input : *actor -
  2470. //-----------------------------------------------------------------------------
  2471. void CChoreoScene::DeleteReferencedObjects( CChoreoActor *actor )
  2472. {
  2473. for ( int i = 0; i < actor->GetNumChannels(); i++ )
  2474. {
  2475. CChoreoChannel *channel = actor->GetChannel( i );
  2476. actor->RemoveChannel( channel );
  2477. DeleteReferencedObjects( channel );
  2478. }
  2479. DestroyActor( actor );
  2480. }
  2481. //-----------------------------------------------------------------------------
  2482. // Purpose:
  2483. // Input : *channel -
  2484. //-----------------------------------------------------------------------------
  2485. void CChoreoScene::DeleteReferencedObjects( CChoreoChannel *channel )
  2486. {
  2487. for ( int i = 0; i < channel->GetNumEvents(); i++ )
  2488. {
  2489. CChoreoEvent *event = channel->GetEvent( i );
  2490. channel->RemoveEvent( event );
  2491. DeleteReferencedObjects( event );
  2492. }
  2493. DestroyChannel( channel );
  2494. }
  2495. //-----------------------------------------------------------------------------
  2496. // Purpose:
  2497. // Input : *event -
  2498. //-----------------------------------------------------------------------------
  2499. void CChoreoScene::DeleteReferencedObjects( CChoreoEvent *event )
  2500. {
  2501. int idx = m_PauseEvents.Find( event );
  2502. if ( idx != m_PauseEvents.InvalidIndex() )
  2503. {
  2504. m_PauseEvents.Remove( idx );
  2505. }
  2506. // Events don't reference anything lower
  2507. DestroyEvent( event );
  2508. }
  2509. //-----------------------------------------------------------------------------
  2510. // Purpose:
  2511. // Input : *actor -
  2512. //-----------------------------------------------------------------------------
  2513. void CChoreoScene::DestroyActor( CChoreoActor *actor )
  2514. {
  2515. int size = m_Actors.Size();
  2516. for ( int i = size - 1; i >= 0; i-- )
  2517. {
  2518. CChoreoActor *a = m_Actors[ i ];
  2519. if ( a == actor )
  2520. {
  2521. m_Actors.Remove( i );
  2522. }
  2523. }
  2524. delete actor;
  2525. }
  2526. //-----------------------------------------------------------------------------
  2527. // Purpose:
  2528. // Input : *channel -
  2529. //-----------------------------------------------------------------------------
  2530. void CChoreoScene::DestroyChannel( CChoreoChannel *channel )
  2531. {
  2532. int size = m_Channels.Size();
  2533. for ( int i = size - 1; i >= 0; i-- )
  2534. {
  2535. CChoreoChannel *c = m_Channels[ i ];
  2536. if ( c == channel )
  2537. {
  2538. m_Channels.Remove( i );
  2539. }
  2540. }
  2541. delete channel;
  2542. }
  2543. //-----------------------------------------------------------------------------
  2544. // Purpose:
  2545. // Input : *event -
  2546. //-----------------------------------------------------------------------------
  2547. void CChoreoScene::DestroyEvent( CChoreoEvent *event )
  2548. {
  2549. int size = m_Events.Size();
  2550. for ( int i = size - 1; i >= 0; i-- )
  2551. {
  2552. CChoreoEvent *e = m_Events[ i ];
  2553. if ( e == event )
  2554. {
  2555. m_Events.Remove( i );
  2556. }
  2557. }
  2558. delete event;
  2559. }
  2560. //-----------------------------------------------------------------------------
  2561. // Purpose:
  2562. //-----------------------------------------------------------------------------
  2563. void CChoreoScene::ResumeSimulation( void )
  2564. {
  2565. // If the thing that paused us was a SECTION pause event, then this will be set
  2566. if ( m_nLastPauseEvent >= 0 &&
  2567. m_nLastPauseEvent < m_PauseEvents.Count() )
  2568. {
  2569. // Start any suppressed dependencies immediately, should only be .wav files!!!
  2570. // These are .wav files which are placed at or just after the SECTION pause event
  2571. // in the .vcd, but due to the user's sound system latency, they would have triggered before the
  2572. // pause (we pre-queue sounds). Since we suppressed that, we need to unsupress / start these sounds
  2573. // now that the SECTION pause is being resumed from
  2574. CUtlVector< CChoreoEvent * > deps;
  2575. CChoreoEvent *pauseEvent = m_PauseEvents[ m_nLastPauseEvent ];
  2576. Assert( pauseEvent );
  2577. // Sanity check ( this should be about 1 tick usually 15 msec)
  2578. float timeSincePaused = m_flCurrentTime - pauseEvent->GetStartTime();
  2579. if ( fabs( timeSincePaused ) > 1.0f )
  2580. {
  2581. Assert( !"Resume simulation with unexpected pause event" );
  2582. }
  2583. // Snag any sounds which were suppressed by this issue
  2584. pauseEvent->GetEventDependencies( deps );
  2585. for ( int j = 0; j < deps.Count(); ++j )
  2586. {
  2587. CChoreoEvent *startEvent = deps[ j ];
  2588. Assert( startEvent );
  2589. // Start them now. Yes, they won't pre-queue, but it's better than totally skipping the sound!!!
  2590. startEvent->StartProcessing( m_pIChoreoEventCallback, this, m_flCurrentTime );
  2591. }
  2592. }
  2593. // Reset section pause signal
  2594. m_nLastPauseEvent = -1;
  2595. m_ActiveResumeConditions.RemoveAll();
  2596. }
  2597. // Sound system needs to have sounds pre-queued by this much time
  2598. void CChoreoScene::SetSoundFileStartupLatency( float time )
  2599. {
  2600. Assert( time >= 0 );
  2601. m_flSoundSystemLatency = time;
  2602. }
  2603. //-----------------------------------------------------------------------------
  2604. // Purpose:
  2605. // Input : start -
  2606. // end -
  2607. //-----------------------------------------------------------------------------
  2608. void CChoreoScene::GetSceneTimes( float& start, float& end )
  2609. {
  2610. start = m_flStartTime;
  2611. end = m_flEndTime;
  2612. }
  2613. //-----------------------------------------------------------------------------
  2614. // Purpose: Do housekeeping on times that are relative to tags
  2615. //-----------------------------------------------------------------------------
  2616. void CChoreoScene::ReconcileTags( void )
  2617. {
  2618. for ( int i = 0 ; i < m_Actors.Size(); i++ )
  2619. {
  2620. CChoreoActor *a = m_Actors[ i ];
  2621. if ( !a )
  2622. continue;
  2623. for ( int j = 0; j < a->GetNumChannels(); j++ )
  2624. {
  2625. CChoreoChannel *c = a->GetChannel( j );
  2626. if ( !c )
  2627. continue;
  2628. for ( int k = 0 ; k < c->GetNumEvents(); k++ )
  2629. {
  2630. CChoreoEvent *e = c->GetEvent( k );
  2631. if ( !e )
  2632. continue;
  2633. if ( !e->IsUsingRelativeTag() )
  2634. continue;
  2635. CEventRelativeTag *tag = FindTagByName(
  2636. e->GetRelativeWavName(),
  2637. e->GetRelativeTagName() );
  2638. if ( tag )
  2639. {
  2640. // Determine correct starting time based on tag
  2641. float starttime = tag->GetStartTime();
  2642. // Figure out delta
  2643. float dt = starttime - e->GetStartTime();
  2644. // Fix up start and possible end time
  2645. e->OffsetTime( dt );
  2646. }
  2647. else
  2648. {
  2649. // The tag was missing!!! unflag it
  2650. choreoprintf( 0, "Event %s was missing tag %s for wav %s\n",
  2651. e->GetName(), e->GetRelativeWavName(), e->GetRelativeTagName() );
  2652. e->SetUsingRelativeTag( false, "", "" );
  2653. }
  2654. }
  2655. }
  2656. }
  2657. }
  2658. //-----------------------------------------------------------------------------
  2659. // Purpose:
  2660. // Input : *wavname -
  2661. // *name -
  2662. // Output : CChoreoEvent
  2663. //-----------------------------------------------------------------------------
  2664. CChoreoEvent *CChoreoScene::FindTargetingEvent( const char *wavname, const char *name )
  2665. {
  2666. for ( int i = 0 ; i < m_Actors.Size(); i++ )
  2667. {
  2668. CChoreoActor *a = m_Actors[ i ];
  2669. if ( !a )
  2670. continue;
  2671. for ( int j = 0; j < a->GetNumChannels(); j++ )
  2672. {
  2673. CChoreoChannel *c = a->GetChannel( j );
  2674. if ( !c )
  2675. continue;
  2676. for ( int k = 0 ; k < c->GetNumEvents(); k++ )
  2677. {
  2678. CChoreoEvent *e = c->GetEvent( k );
  2679. if ( !e )
  2680. continue;
  2681. if ( !e->IsUsingRelativeTag() )
  2682. continue;
  2683. if ( stricmp( wavname, e->GetRelativeWavName() ) )
  2684. continue;
  2685. if ( stricmp( name, e->GetRelativeTagName() ) )
  2686. continue;
  2687. return e;
  2688. }
  2689. }
  2690. }
  2691. return NULL;
  2692. }
  2693. //-----------------------------------------------------------------------------
  2694. // Purpose:
  2695. // Input : *wavname -
  2696. // *name -
  2697. // Output : CEventRelativeTag
  2698. //-----------------------------------------------------------------------------
  2699. CEventRelativeTag *CChoreoScene::FindTagByName( const char *wavname, const char *name )
  2700. {
  2701. for ( int i = 0 ; i < m_Actors.Size(); i++ )
  2702. {
  2703. CChoreoActor *a = m_Actors[ i ];
  2704. if ( !a )
  2705. continue;
  2706. for ( int j = 0; j < a->GetNumChannels(); j++ )
  2707. {
  2708. CChoreoChannel *c = a->GetChannel( j );
  2709. if ( !c )
  2710. continue;
  2711. for ( int k = 0 ; k < c->GetNumEvents(); k++ )
  2712. {
  2713. CChoreoEvent *e = c->GetEvent( k );
  2714. if ( !e )
  2715. continue;
  2716. if ( e->GetType() != CChoreoEvent::SPEAK )
  2717. continue;
  2718. // Search for tag by name
  2719. if ( !strstr( e->GetParameters(), wavname ) )
  2720. continue;
  2721. CEventRelativeTag *tag = e->FindRelativeTag( name );
  2722. if ( !tag )
  2723. continue;
  2724. return tag;
  2725. }
  2726. }
  2727. }
  2728. return NULL;
  2729. }
  2730. //-----------------------------------------------------------------------------
  2731. // Purpose:
  2732. // Input : *filename -
  2733. //-----------------------------------------------------------------------------
  2734. void CChoreoScene::ExportEvents( const char *filename, CUtlVector< CChoreoEvent * >& events )
  2735. {
  2736. if ( events.Size() <= 0 )
  2737. return;
  2738. // Create a serialization buffer
  2739. CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
  2740. FilePrintf( buf, 0, "// Choreo version 1: <%i> Exported Events\n", events.Size() );
  2741. // Save out the selected events.
  2742. int i;
  2743. for ( i = 0 ; i < events.Size(); i++ )
  2744. {
  2745. CChoreoEvent *e = events[ i ];
  2746. if ( !e->GetActor() )
  2747. continue;
  2748. FileSaveEvent( buf, 0, e );
  2749. }
  2750. // Write it out baby
  2751. FileHandle_t fh = g_pFullFileSystem->Open( filename, "wt" );
  2752. if (fh)
  2753. {
  2754. g_pFullFileSystem->Write( buf.Base(), buf.TellPut(), fh );
  2755. g_pFullFileSystem->Close(fh);
  2756. }
  2757. }
  2758. //-----------------------------------------------------------------------------
  2759. // Purpose:
  2760. // Input : *actor -
  2761. // *channel -
  2762. // starttime -
  2763. //-----------------------------------------------------------------------------
  2764. void CChoreoScene::ImportEvents( ISceneTokenProcessor *tokenizer, CChoreoActor *actor, CChoreoChannel *channel )
  2765. {
  2766. m_pTokenizer = tokenizer;
  2767. while ( 1 )
  2768. {
  2769. if ( !m_pTokenizer->GetToken( true ) )
  2770. {
  2771. break;
  2772. }
  2773. if ( strlen( m_pTokenizer->CurrentToken() ) <= 0 )
  2774. break;
  2775. if ( !Q_stricmp( m_pTokenizer->CurrentToken(), "event" ) )
  2776. {
  2777. ParseEvent( actor, channel );
  2778. }
  2779. else
  2780. {
  2781. m_pTokenizer->Error( "unexpected token %s\n", m_pTokenizer->CurrentToken() );
  2782. break;
  2783. }
  2784. }
  2785. // Fixup time tags
  2786. ReconcileTags();
  2787. }
  2788. void CChoreoScene::SetSubScene( bool sub )
  2789. {
  2790. m_bSubScene = sub;
  2791. }
  2792. bool CChoreoScene::IsSubScene( void ) const
  2793. {
  2794. return m_bSubScene;
  2795. }
  2796. //-----------------------------------------------------------------------------
  2797. // Purpose:
  2798. // Output : int
  2799. //-----------------------------------------------------------------------------
  2800. int CChoreoScene::GetSceneFPS( void ) const
  2801. {
  2802. return m_nSceneFPS;
  2803. }
  2804. //-----------------------------------------------------------------------------
  2805. // Purpose:
  2806. // Input : fps -
  2807. //-----------------------------------------------------------------------------
  2808. void CChoreoScene::SetSceneFPS( int fps )
  2809. {
  2810. m_nSceneFPS = fps;
  2811. }
  2812. //-----------------------------------------------------------------------------
  2813. // Purpose:
  2814. // Output : Returns true on success, false on failure.
  2815. //-----------------------------------------------------------------------------
  2816. bool CChoreoScene::IsUsingFrameSnap( void ) const
  2817. {
  2818. return m_bUseFrameSnap;
  2819. }
  2820. //-----------------------------------------------------------------------------
  2821. // Purpose:
  2822. // Input : snap -
  2823. //-----------------------------------------------------------------------------
  2824. void CChoreoScene::SetUsingFrameSnap( bool snap )
  2825. {
  2826. m_bUseFrameSnap = snap;
  2827. }
  2828. //-----------------------------------------------------------------------------
  2829. // Purpose:
  2830. // Input : t -
  2831. // Output : float
  2832. //-----------------------------------------------------------------------------
  2833. float CChoreoScene::SnapTime( float t )
  2834. {
  2835. if ( !IsUsingFrameSnap() )
  2836. return t;
  2837. float fps = (float)GetSceneFPS();
  2838. Assert( fps > 0 );
  2839. int itime = (int)( t * fps + 0.5f );
  2840. t = (float)itime / fps;
  2841. // FIXME: If FPS is set and "using grid", snap to proper fractional time value
  2842. return t;
  2843. }
  2844. //-----------------------------------------------------------------------------
  2845. // Purpose:
  2846. //-----------------------------------------------------------------------------
  2847. void CChoreoScene::ReconcileGestureTimes()
  2848. {
  2849. for ( int i = 0 ; i < m_Actors.Size(); i++ )
  2850. {
  2851. CChoreoActor *a = m_Actors[ i ];
  2852. if ( !a )
  2853. continue;
  2854. for ( int j = 0; j < a->GetNumChannels(); j++ )
  2855. {
  2856. CChoreoChannel *c = a->GetChannel( j );
  2857. if ( !c )
  2858. continue;
  2859. c->ReconcileGestureTimes();
  2860. }
  2861. }
  2862. }
  2863. int CChoreoScene::TimeZoomFirst()
  2864. {
  2865. return m_TimeZoomLookup.First();
  2866. }
  2867. int CChoreoScene::TimeZoomNext( int i )
  2868. {
  2869. return m_TimeZoomLookup.Next( i );
  2870. }
  2871. int CChoreoScene::TimeZoomInvalid() const
  2872. {
  2873. return m_TimeZoomLookup.InvalidIndex();
  2874. }
  2875. char const *CChoreoScene::TimeZoomName( int i )
  2876. {
  2877. return m_TimeZoomLookup.GetElementName( i );
  2878. }
  2879. //-----------------------------------------------------------------------------
  2880. // Purpose:
  2881. // Input : *tool -
  2882. // Output : int
  2883. //-----------------------------------------------------------------------------
  2884. int CChoreoScene::GetTimeZoom( char const *tool )
  2885. {
  2886. // If not present add it
  2887. int idx = m_TimeZoomLookup.Find( tool );
  2888. if ( idx == m_TimeZoomLookup.InvalidIndex() )
  2889. {
  2890. idx = m_TimeZoomLookup.Insert( tool, 100 );
  2891. }
  2892. return m_TimeZoomLookup[ idx ];
  2893. }
  2894. //-----------------------------------------------------------------------------
  2895. // Purpose:
  2896. // Input : *tool -
  2897. // tz -
  2898. //-----------------------------------------------------------------------------
  2899. void CChoreoScene::SetTimeZoom( char const *tool, int tz )
  2900. {
  2901. // If not present add it
  2902. int idx = m_TimeZoomLookup.Find( tool );
  2903. if ( idx == m_TimeZoomLookup.InvalidIndex() )
  2904. {
  2905. idx = m_TimeZoomLookup.Insert( tool, 100 );
  2906. }
  2907. m_TimeZoomLookup[ idx ] = tz;
  2908. }
  2909. void CChoreoScene::ParseScaleSettings( ISceneTokenProcessor *tokenizer, CChoreoScene *scene )
  2910. {
  2911. tokenizer->GetToken( true );
  2912. if ( stricmp( tokenizer->CurrentToken(), "{" ) )
  2913. tokenizer->Error( "expecting {\n" );
  2914. while ( 1 )
  2915. {
  2916. // Parse until }
  2917. tokenizer->GetToken( true );
  2918. if ( strlen( tokenizer->CurrentToken() ) <= 0 )
  2919. {
  2920. tokenizer->Error( "expecting scalesettings data\n" );
  2921. break;
  2922. }
  2923. if ( !Q_stricmp( tokenizer->CurrentToken(), "}" ) )
  2924. break;
  2925. char tool[ 256 ];
  2926. Q_strncpy( tool, tokenizer->CurrentToken(), sizeof( tool ) );
  2927. tokenizer->GetToken( false );
  2928. int tz = Q_atoi( tokenizer->CurrentToken() );
  2929. if ( tz <= 0 )
  2930. tz = 100;
  2931. scene->SetTimeZoom( tool, tz );
  2932. }
  2933. }
  2934. // Merges two .vcd's together
  2935. bool CChoreoScene::Merge( CChoreoScene *other )
  2936. {
  2937. int acount = 0;
  2938. int ccount = 0;
  2939. int ecount = 0;
  2940. // Look for events that don't have actor/channel set
  2941. int i;
  2942. for ( i = 0 ; i < other->m_Events.Size(); i++ )
  2943. {
  2944. CChoreoEvent *e = other->m_Events[ i ];
  2945. if ( e->GetActor() )
  2946. continue;
  2947. MEM_ALLOC_CREDIT();
  2948. // Make a copy of the other event and add it to this scene
  2949. CChoreoEvent *newEvent = AllocEvent();
  2950. *newEvent = *e;
  2951. newEvent->SetScene( this );
  2952. ecount++;
  2953. }
  2954. for ( i = 0 ; i < other->m_Actors.Size(); i++ )
  2955. {
  2956. CChoreoActor *a = other->m_Actors[ i ];
  2957. // See if that actor already exists
  2958. bool newActor = false;
  2959. CChoreoActor *destActor = FindActor( a->GetName() );
  2960. if ( !destActor )
  2961. {
  2962. newActor = true;
  2963. destActor = AllocActor();
  2964. *destActor = *a;
  2965. destActor->RemoveAllChannels();
  2966. acount++;
  2967. }
  2968. // Now we have a destination actor, work on channels
  2969. for ( int j = 0; j < a->GetNumChannels(); j++ )
  2970. {
  2971. CChoreoChannel *ch = a->GetChannel( j );
  2972. bool newChannel = false;
  2973. CChoreoChannel *destChannel = NULL;
  2974. destChannel = destActor->FindChannel( ch->GetName() );
  2975. if ( !destChannel )
  2976. {
  2977. destChannel = AllocChannel();
  2978. *destChannel = *ch;
  2979. destChannel->RemoveAllEvents();
  2980. newChannel = true;
  2981. ccount++;
  2982. }
  2983. if ( newChannel )
  2984. {
  2985. destActor->AddChannel( destChannel );
  2986. destChannel->SetActor( destActor );
  2987. }
  2988. // Now we have a destination channel, work on events themselves
  2989. for ( int k = 0 ; k < ch->GetNumEvents(); k++ )
  2990. {
  2991. CChoreoEvent *e = ch->GetEvent( k );
  2992. // Just import them wholesale, no checking
  2993. MEM_ALLOC_CREDIT();
  2994. CChoreoEvent *newEvent = AllocEvent();
  2995. *newEvent = *e;
  2996. newEvent->SetScene( this );
  2997. destChannel->AddEvent( newEvent );
  2998. newEvent->SetChannel( destChannel );
  2999. newEvent->SetActor( destActor );
  3000. ecount++;
  3001. }
  3002. }
  3003. }
  3004. Msg( "Merged in (%i) actors, (%i) channels, and (%i) events\n",
  3005. acount, ccount, ecount );
  3006. return ( ecount || acount || ccount );
  3007. }
  3008. //-----------------------------------------------------------------------------
  3009. // Purpose: Updates master/slave status info per channel
  3010. //-----------------------------------------------------------------------------
  3011. void CChoreoScene::ReconcileCloseCaption()
  3012. {
  3013. for ( int i = 0 ; i < m_Actors.Size(); i++ )
  3014. {
  3015. CChoreoActor *a = m_Actors[ i ];
  3016. if ( !a )
  3017. continue;
  3018. for ( int j = 0; j < a->GetNumChannels(); j++ )
  3019. {
  3020. CChoreoChannel *c = a->GetChannel( j );
  3021. if ( !c )
  3022. continue;
  3023. c->ReconcileCloseCaption();
  3024. }
  3025. }
  3026. }
  3027. //-----------------------------------------------------------------------------
  3028. // Purpose:
  3029. // Output : char const
  3030. //-----------------------------------------------------------------------------
  3031. char const *CChoreoScene::GetFilename() const
  3032. {
  3033. return m_szFileName;
  3034. }
  3035. void CChoreoScene::SetFileName( char const *fn )
  3036. {
  3037. Q_strncpy( m_szFileName, fn, sizeof( m_szFileName ) );
  3038. }
  3039. bool CChoreoScene::GetPlayingSoundName( char *pchBuff, int iBuffLength )
  3040. {
  3041. for ( int i = 0; i < m_Events.Size(); i++ )
  3042. {
  3043. CChoreoEvent *e = m_Events[ i ];
  3044. if ( e->GetType() == CChoreoEvent::SPEAK && e->IsProcessing() )
  3045. {
  3046. Q_strncpy( pchBuff, e->GetParameters(), iBuffLength );
  3047. return true;
  3048. }
  3049. }
  3050. return false;
  3051. }
  3052. //-----------------------------------------------------------------------------
  3053. // Purpose: Returns true if this scene has speech events that haven't played yet
  3054. //-----------------------------------------------------------------------------
  3055. bool CChoreoScene::HasUnplayedSpeech()
  3056. {
  3057. for ( int i = 0; i < m_Events.Size(); i++ )
  3058. {
  3059. CChoreoEvent *e = m_Events[ i ];
  3060. if ( e->GetType() == CChoreoEvent::SPEAK )
  3061. {
  3062. // Have we played it yet?
  3063. if ( m_flCurrentTime < e->GetStartTime() )
  3064. return true;
  3065. }
  3066. }
  3067. return false;
  3068. }
  3069. //-----------------------------------------------------------------------------
  3070. // Purpose: Returns true if this scene has flex animation events that are playing
  3071. //-----------------------------------------------------------------------------
  3072. bool CChoreoScene::HasFlexAnimation()
  3073. {
  3074. for ( int i = 0; i < m_Events.Size(); i++ )
  3075. {
  3076. CChoreoEvent *e = m_Events[ i ];
  3077. if ( e->GetType() == CChoreoEvent::FLEXANIMATION )
  3078. {
  3079. // Have we played it yet?
  3080. if ( m_flCurrentTime >= e->GetStartTime() && m_flCurrentTime <= e->GetEndTime() )
  3081. return true;
  3082. }
  3083. }
  3084. return false;
  3085. }
  3086. //-----------------------------------------------------------------------------
  3087. // Purpose:
  3088. //-----------------------------------------------------------------------------
  3089. void CChoreoScene::SetBackground( bool bIsBackground )
  3090. {
  3091. m_bIsBackground = bIsBackground;
  3092. }
  3093. //-----------------------------------------------------------------------------
  3094. // Purpose:
  3095. //-----------------------------------------------------------------------------
  3096. bool CChoreoScene::IsBackground( )
  3097. {
  3098. return m_bIsBackground;
  3099. }
  3100. bool CChoreoScene::HasEventsOfType( CChoreoEvent::EVENTTYPE type ) const
  3101. {
  3102. return m_bitvecHasEventOfType.IsBitSet( type );
  3103. }
  3104. // ICurveDataAccessor method
  3105. bool CChoreoScene::CurveHasEndTime()
  3106. {
  3107. return true;
  3108. }
  3109. int CChoreoScene::GetDefaultCurveType()
  3110. {
  3111. return CURVE_CATMULL_ROM_TO_CATMULL_ROM;
  3112. }
  3113. bool CChoreoScene::SaveBinary( char const *pszBinaryFileName, char const *pPathID, unsigned int nTextVersionCRC, IChoreoStringPool *pStringPool )
  3114. {
  3115. bool bret = false;
  3116. CUtlBuffer buf;
  3117. SaveToBinaryBuffer( buf, nTextVersionCRC, pStringPool );
  3118. if ( g_pFullFileSystem->FileExists( pszBinaryFileName, pPathID ) &&
  3119. !g_pFullFileSystem->IsFileWritable( pszBinaryFileName, pPathID ) )
  3120. {
  3121. Warning( "Forcing '%s' to be writable!!!\n", pszBinaryFileName );
  3122. g_pFullFileSystem->SetFileWritable( pszBinaryFileName, true, pPathID );
  3123. }
  3124. FileHandle_t fh = g_pFullFileSystem->Open( pszBinaryFileName, "wb", pPathID );
  3125. if ( FILESYSTEM_INVALID_HANDLE != fh )
  3126. {
  3127. g_pFullFileSystem->Write( buf.Base(), buf.TellPut(), fh );
  3128. g_pFullFileSystem->Close( fh );
  3129. // Success
  3130. bret = true;
  3131. }
  3132. else
  3133. {
  3134. Warning( "Unable to open '%s' for writing!!!\n", pszBinaryFileName );
  3135. }
  3136. return bret;
  3137. }
  3138. void CChoreoScene::SaveToBinaryBuffer( CUtlBuffer& buf, unsigned int nTextVersionCRC, IChoreoStringPool *pStringPool )
  3139. {
  3140. buf.PutInt( SCENE_BINARY_TAG );
  3141. buf.PutChar( SCENE_BINARY_VERSION );
  3142. buf.PutInt( nTextVersionCRC );
  3143. // Look for events that don't have actor/channel set
  3144. CUtlVector< CChoreoEvent * > eventList;
  3145. int i;
  3146. for ( i = 0 ; i < m_Events.Size(); i++ )
  3147. {
  3148. CChoreoEvent *e = m_Events[ i ];
  3149. if ( e->GetActor() )
  3150. continue;
  3151. eventList.AddToTail( e );
  3152. }
  3153. int c = eventList.Count();
  3154. Assert( c <= 255 );
  3155. buf.PutUnsignedChar( c );
  3156. for ( i = 0; i < c; ++i )
  3157. {
  3158. CChoreoEvent *e = eventList[ i ];
  3159. e->SaveToBuffer( buf, this, pStringPool );
  3160. }
  3161. // Now serialize the actors themselves
  3162. CUtlVector< CChoreoActor * > actorList;
  3163. for ( i = 0 ; i < m_Actors.Size(); i++ )
  3164. {
  3165. CChoreoActor *a = m_Actors[ i ];
  3166. if ( !a )
  3167. continue;
  3168. actorList.AddToTail( a );
  3169. }
  3170. c = actorList.Count();
  3171. Assert( c <= 255 );
  3172. buf.PutUnsignedChar( c );
  3173. for ( i = 0; i < c; ++i )
  3174. {
  3175. CChoreoActor *a = actorList[ i ];
  3176. a->SaveToBuffer( buf, this, pStringPool );
  3177. }
  3178. /*
  3179. // compiled version strips out map name, only used by editor
  3180. if ( m_szMapname[ 0 ] )
  3181. {
  3182. FilePrintf( buf, 0, "mapname \"%s\"\n", m_szMapname );
  3183. }
  3184. */
  3185. m_SceneRamp.SaveToBuffer( buf, pStringPool );
  3186. /*
  3187. // compiled version strips out scale settings fps and snap, only used by editor
  3188. FileSaveScaleSettings( buf, 0, this );
  3189. FilePrintf( buf, 0, "fps %i\n", m_nSceneFPS );
  3190. FilePrintf( buf, 0, "snap %s\n", m_bUseFrameSnap ? "on" : "off" );
  3191. */
  3192. buf.PutUnsignedChar( m_bIgnorePhonemes );
  3193. }
  3194. //-----------------------------------------------------------------------------
  3195. // Purpose: Static method to extract just the CRC from a binary .xcd file
  3196. // Input : buf -
  3197. // crc -
  3198. // Output : Returns true on success, false on failure.
  3199. //-----------------------------------------------------------------------------
  3200. bool CChoreoScene::GetCRCFromBinaryBuffer( CUtlBuffer& buf, unsigned int& crc )
  3201. {
  3202. bool bret = false;
  3203. int pos = buf.TellGet();
  3204. int tag = buf.GetInt();
  3205. if ( tag == SCENE_BINARY_TAG )
  3206. {
  3207. byte ver = buf.GetChar();
  3208. if ( ver == SCENE_BINARY_VERSION )
  3209. {
  3210. bret = true;
  3211. crc = (unsigned int)buf.GetInt();
  3212. }
  3213. }
  3214. buf.SeekGet( CUtlBuffer::SEEK_HEAD, pos );
  3215. return bret;
  3216. }
  3217. bool CChoreoScene::RestoreFromBinaryBuffer( CUtlBuffer& buf, char const *filename, IChoreoStringPool *pStringPool )
  3218. {
  3219. Q_strncpy( m_szFileName, filename, sizeof( m_szFileName ) );
  3220. int tag = buf.GetInt();
  3221. if ( tag != SCENE_BINARY_TAG )
  3222. return false;
  3223. byte ver = buf.GetChar();
  3224. if ( ver != SCENE_BINARY_VERSION )
  3225. return false;
  3226. // Skip the CRC
  3227. buf.GetInt();
  3228. int i;
  3229. int eventCount = buf.GetUnsignedChar();
  3230. for ( i = 0; i < eventCount; ++i )
  3231. {
  3232. MEM_ALLOC_CREDIT();
  3233. CChoreoEvent *e = AllocEvent();
  3234. Assert( e );
  3235. if ( e->RestoreFromBuffer( buf, this, pStringPool ) )
  3236. {
  3237. continue;
  3238. }
  3239. return false;
  3240. }
  3241. int actorCount = buf.GetUnsignedChar();
  3242. for ( i = 0; i < actorCount; ++i )
  3243. {
  3244. CChoreoActor *a = AllocActor();
  3245. Assert( a );
  3246. if ( a->RestoreFromBuffer( buf, this, pStringPool ) )
  3247. {
  3248. continue;
  3249. }
  3250. return false;
  3251. }
  3252. if ( !m_SceneRamp.RestoreFromBuffer( buf, pStringPool ) )
  3253. {
  3254. return false;
  3255. }
  3256. m_bIgnorePhonemes = ( buf.GetUnsignedChar( ) != 0 );
  3257. // FIXME: Are these ever needed on restore?
  3258. // ReconcileTags();
  3259. // ReconcileGestureTimes();
  3260. ReconcileCloseCaption();
  3261. InternalDetermineEventTypes();
  3262. if ( CChoreoScene::s_bEditingDisabled )
  3263. {
  3264. m_flPrecomputedStopTime = FindStopTime();
  3265. }
  3266. return true;
  3267. }