Counter Strike : Global Offensive Source Code
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.

3940 lines
98 KiB

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