Beispiel #1
0
void C_SceneEntity::PostDataUpdate( DataUpdateType_t updateType )
{
	BaseClass::PostDataUpdate( updateType );

	char const *str = GetSceneFileName();

	if ( updateType == DATA_UPDATE_CREATED )
	{
		Assert( str && str[ 0 ] );
		if (  str && str[ 0 ] )
		{
			LoadSceneFromFile( str );

			// Kill everything except flex events
			Assert( m_pScene );
			if ( m_pScene )
			{
				int types[ 2 ];
				types[ 0 ] =  CChoreoEvent::FLEXANIMATION;
				types[ 1 ] =  CChoreoEvent::EXPRESSION;
				m_pScene->RemoveEventsExceptTypes( types, 2 );
			}

			SetNextClientThink( CLIENT_THINK_ALWAYS );
		}
	}

	// Playback state changed...
	if ( m_bWasPlaying != m_bIsPlayingBack )
	{
		for(int i = 0; i < m_hActorList.Count() ; ++i )
		{
			C_BaseFlex *actor = m_hActorList[ i ].Get();
			if ( !actor )
				continue;

			Assert( m_pScene );

			if ( m_pScene )
			{
				ClearSceneEvents( m_pScene, false );

				if ( m_bIsPlayingBack )
				{
					m_pScene->ResetSimulation();
					actor->StartChoreoScene( m_pScene );
				}
				else
				{
					m_pScene->ResetSimulation();
					actor->RemoveChoreoScene( m_pScene );
				}
			}
		}
	}
}
//-----------------------------------------------------------------------------
// Create binary compiled version of VCD. Stores to a dictionary for later
// post processing
//-----------------------------------------------------------------------------
bool CreateTargetFile_VCD( const char *pSourceName, const char *pTargetName, bool bWriteToZip, bool bLittleEndian )
{
	CUtlBuffer sourceBuf;
	if ( !scriptlib->ReadFileToBuffer( pSourceName, sourceBuf ) )
	{
		return false;
	}

	CRC32_t crcSource;
	CRC32_Init( &crcSource );
	CRC32_ProcessBuffer( &crcSource, sourceBuf.Base(), sourceBuf.TellMaxPut() );
	CRC32_Final( &crcSource );

	ParseFromMemory( (char *)sourceBuf.Base(), sourceBuf.TellMaxPut() );

	CChoreoScene *pChoreoScene = ChoreoLoadScene( pSourceName, NULL, &g_SceneTokenProcessor, Msg );
	if ( !pChoreoScene )
	{
		return false;
	}

	int iScene = g_SceneFiles.AddToTail();

	g_SceneFiles[iScene].fileName.Set( pSourceName );

	// Walk all events looking for SPEAK events
	CChoreoEvent *pEvent;
	for ( int i = 0; i < pChoreoScene->GetNumEvents(); ++i )
	{
		pEvent = pChoreoScene->GetEvent( i );
		FindSoundsInEvent( pEvent, g_SceneFiles[iScene].soundList );
	}

	// calc duration
	g_SceneFiles[iScene].msecs = (unsigned int)( pChoreoScene->FindStopTime() * 1000.0f + 0.5f );

	// compile to binary buffer
	g_SceneFiles[iScene].compiledBuffer.SetBigEndian( !bLittleEndian );
	pChoreoScene->SaveToBinaryBuffer( g_SceneFiles[iScene].compiledBuffer, crcSource, &g_ChoreoStringPool );

	unsigned int compressedSize;
	unsigned char *pCompressedBuffer = LZMA_Compress( (unsigned char *)g_SceneFiles[iScene].compiledBuffer.Base(), g_SceneFiles[iScene].compiledBuffer.TellMaxPut(), &compressedSize );
	if ( pCompressedBuffer )
	{
		// replace the compiled buffer with the compressed version
		g_SceneFiles[iScene].compiledBuffer.Purge();
		g_SceneFiles[iScene].compiledBuffer.EnsureCapacity( compressedSize );
		g_SceneFiles[iScene].compiledBuffer.Put( pCompressedBuffer, compressedSize );
		free( pCompressedBuffer );
	}

	delete pChoreoScene;

	return true;
}
Beispiel #3
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void C_SceneEntity::DoThink( float frametime )
{
	if ( !m_pScene )
		return;

	if ( !m_bIsPlayingBack )
	{
		WipeQueuedEvents();
		return;
	}

	CheckQueuedEvents();

	if ( m_bPaused )
	{
		return;
	}

	// Msg( "CL:  %d, %f for %s\n", gpGlobals->tickcount, m_flCurrentTime, m_pScene->GetFilename() );

	// Tell scene to go
	m_pScene->Think( m_flCurrentTime );
	// Drive simulation time for scene
	m_flCurrentTime += gpGlobals->frametime;
}
void CBaseEventPropertiesDialog::PopulateTagList( CEventParams *params )
{
	CChoreoScene *scene = params->m_pScene;
	if ( !scene )
		return;

	HWND control = GetControl( IDC_TAGS );
	if ( control )
	{
		SendMessage( control, CB_RESETCONTENT, 0, 0 ); 
		SendMessage( control, WM_SETTEXT , 0, (LPARAM)va( "\"%s\" \"%s\"", params->m_szTagName, params->m_szTagWav ) );

		for ( int i = 0; i < scene->GetNumActors(); i++ )
		{
			CChoreoActor *a = scene->GetActor( i );
			if ( !a )
				continue;

			for ( int j = 0; j < a->GetNumChannels(); j++ )
			{
				CChoreoChannel *c = a->GetChannel( j );
				if ( !c )
					continue;

				for ( int k = 0 ; k < c->GetNumEvents(); k++ )
				{
					CChoreoEvent *e = c->GetEvent( k );
					if ( !e )
						continue;

					if ( e->GetNumRelativeTags() <= 0 )
						continue;

					// add each tag to combo box
					for ( int t = 0; t < e->GetNumRelativeTags(); t++ )
					{
						CEventRelativeTag *tag = e->GetRelativeTag( t );
						if ( !tag )
							continue;

						SendMessage( control, CB_ADDSTRING, 0, (LPARAM)va( "\"%s\" \"%s\"", tag->GetName(), e->GetParameters() ) ); 
					}
				}
			}
		}
	}
}
CChoreoScene *C_SceneEntity::LoadScene( const char *filename )
{
	char loadfile[ 512 ];
	Q_strncpy( loadfile, filename, sizeof( loadfile ) );
	Q_SetExtension( loadfile, ".vcd", sizeof( loadfile ) );
	Q_FixSlashes( loadfile );

	char *pBuffer = NULL;
	size_t bufsize = scenefilecache->GetSceneBufferSize( loadfile );
	if ( bufsize <= 0 )
		return NULL;

	pBuffer = new char[ bufsize ];
	if ( !scenefilecache->GetSceneData( filename, (byte *)pBuffer, bufsize ) )
	{
		delete[] pBuffer;
		return NULL;
	}

	CChoreoScene *pScene;
	if ( IsBufferBinaryVCD( pBuffer, bufsize ) )
	{
		pScene = new CChoreoScene( this );
		CUtlBuffer buf( pBuffer, bufsize, CUtlBuffer::READ_ONLY );
		if ( !pScene->RestoreFromBinaryBuffer( buf, loadfile, &g_ChoreoStringPool ) )
		{
			Warning( "Unable to restore binary scene '%s'\n", loadfile );
			delete pScene;
			pScene = NULL;
		}
		else
		{
			pScene->SetPrintFunc( Scene_Printf );
			pScene->SetEventCallbackInterface( this );
		}
	}
	else
	{
		g_TokenProcessor.SetBuffer( pBuffer );
		pScene = ChoreoLoadScene( loadfile, this, &g_TokenProcessor, Scene_Printf );
	}

	delete[] pBuffer;
	return pScene;
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *actor - 
//			*parameters - 
//-----------------------------------------------------------------------------
void CBaseFlex::AddFlexSequence( CExpressionInfo *info )
{
	if ( !info )
		return;

	CChoreoEvent *event = info->m_pEvent;
	if ( !event )
		return;

	CChoreoScene *scene = info->m_pScene;
	if ( !scene )
		return;
	
	if (info->m_iLayer >= 0)
	{
		SetLayerWeight( info->m_iLayer, event->GetIntensity( scene->GetTime() ) );
	}
}
Beispiel #7
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void C_SceneEntity::UnloadScene( void )
{
	WipeQueuedEvents();

	if ( m_pScene )
	{
		ClearSceneEvents( m_pScene, false );
		for ( int i = 0 ; i < m_pScene->GetNumActors(); i++ )
		{
			C_BaseFlex *pTestActor = FindNamedActor( m_pScene->GetActor( i ) );

			if ( !pTestActor )
				continue;
		
			pTestActor->RemoveChoreoScene( m_pScene );
		}
	}
	delete m_pScene;
	m_pScene = NULL;
}
Beispiel #8
0
void C_SceneEntity::ClearSceneEvents( CChoreoScene *scene, bool canceled )
{
	if ( !m_pScene )
		return;

	Scene_Printf( "%s : %8.2f:  clearing events\n", GetSceneFileName(), m_flCurrentTime );

	int i;
	for ( i = 0 ; i < m_pScene->GetNumActors(); i++ )
	{
		C_BaseFlex *pActor = FindNamedActor( m_pScene->GetActor( i ) );
		if ( !pActor )
			continue;

		// Clear any existing expressions
		pActor->ClearSceneEvents( scene, canceled );
	}

	WipeQueuedEvents();
}
Beispiel #9
0
C_BaseFlex *C_SceneEntity::FindNamedActor( CChoreoActor *pChoreoActor )
{
	if ( !m_pScene )
		return NULL;

	int idx = m_pScene->FindActorIndex( pChoreoActor );
	if ( idx < 0 || idx >= m_hActorList.Count() )
		return NULL;

	return m_hActorList[ idx ].Get();
}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *actor - 
//			*parameters - 
//-----------------------------------------------------------------------------
void CBaseFlex::AddFlexGesture( CExpressionInfo *info )
{
	if ( !info )
		return;

	CChoreoEvent *event = info->m_pEvent;
	if ( !event )
		return;

	CChoreoScene *scene = info->m_pScene;
	if ( !scene )
		return;
	
	if (info->m_iLayer >= 0)
	{
		// this happens after StudioFrameAdvance()
		float duration = event->GetDuration( );
		float orig_duration = SequenceDuration( info->m_nSequence );

		// when we come by again after StudioFrameAdvance() has moved forward 0.1 seconds, what frame should we be on?
		float flCycle = GetLayerCycle( info->m_iLayer );
		float flNextCycle = event->GetShiftedTimeFromReferenceTime( (m_flAnimTime - info->m_flStartAnim + 0.1) / duration );

		// FIXME: what time should this use?
		SetLayerWeight( info->m_iLayer, event->GetIntensity( scene->GetTime() ) );

		float rate = (flNextCycle - flCycle) * orig_duration / 0.1;

		/*
		Msg( "%d : %.2f (%.2f) : %.3f %.3f : %.3f\n",
			info->m_iLayer,
			scene->GetTime(), 
			(scene->GetTime() - event->GetStartTime()) / duration,
			flCycle,
			flNextCycle,
			rate );
		*/

		SetLayerPlaybackRate( info->m_iLayer, rate );
	}
}
bool GetFirstSoundInScene( const char *pSceneFilename, char *pSoundName, int soundNameLen )
{
	CChoreoScene *pScene = HammerLoadScene( pSceneFilename );
	if ( !pScene )
		return false;
	
	for ( int i = 0; i < pScene->GetNumEvents(); i++ )
	{
		CChoreoEvent *e = pScene->GetEvent( i );
		if ( !e || e->GetType() != CChoreoEvent::SPEAK )
			continue;

		const char *pParameters = e->GetParameters();
		V_strncpy( pSoundName, pParameters, soundNameLen );
		delete pScene;
		return true;
	}
	
	delete pScene;
	return false;	
}
Beispiel #12
0
void CSceneCache::Rebuild( char const *filename )
{
	msecs = 0;
	sounds.RemoveAll();

	CChoreoScene *scene = BlockingLoadScene( filename );
	if ( scene )
	{
		// Walk all events looking for SPEAK events
		CChoreoEvent *event;
		int c = scene->GetNumEvents();
		for ( int i = 0; i < c; ++i )
		{
			event = scene->GetEvent( i );
			PrecacheSceneEvent( event, sounds );
		}

		// Update scene duration, too
		msecs = (int)( scene->FindStopTime() * 1000.0f + 0.5f );

		delete scene;
	}
}
	void Init( void )
	{
		if ( g_pChoreoView )
		{
			CChoreoScene *scene = g_pChoreoView->GetScene();
			if ( scene )
			{
				char sz[ 256 ];
				Q_snprintf( sz, sizeof( sz ), "%i fps", scene->GetSceneFPS() );
				m_btnFPS->setLabel( sz );

				Q_snprintf( sz, sizeof( sz ), "snap: %s", scene->IsUsingFrameSnap() ? "on" : "off" );
				m_btnGridSnap->setLabel( sz );

				m_btnFPS->setVisible( true );
				m_btnGridSnap->setVisible( true );
				return;
			}
		}
		
		m_btnFPS->setVisible( false );
		m_btnGridSnap->setVisible( false );
	}
	virtual void ShowRightClickMenu( int mx, int my )
	{
		mxPopupMenu *pop = new mxPopupMenu();
		Assert( pop );

		char const *current = "";
		char const *filename = "";
		int idx = getSelectedIndex();
		if ( idx >= 0 )
		{
			current = models->GetModelName( idx );
			filename = models->GetModelFileName( idx );
		}

		if ( models->Count() < MAX_FP_MODELS )
		{
			pop->add( "Load Model...", IDC_MODELTAB_LOAD );
		}
		if ( idx >= 0 )
		{
			pop->add( va( "Close '%s'", current ), IDC_MODELTAB_CLOSE );
		}
		if ( models->Count() > 0 )
		{
			pop->add( "Close All", IDC_MODELTAB_CLOSEALL );
		}
		if ( idx >= 0 )
		{
			pop->addSeparator();
			pop->add( va( "Center %s's face", current ), IDC_MODELTAB_CENTERONFACE );

			CChoreoScene *scene = g_pChoreoView->GetScene();
			if ( scene )
			{
				// See if there is already an actor with this model associated
				int c = scene->GetNumActors();
				bool hasassoc = false;
				for ( int i = 0; i < c; i++ )
				{
					CChoreoActor *a = scene->GetActor( i );
					Assert( a );
				
					if ( stricmp( a->GetFacePoserModelName(), filename ) )
						continue;
					hasassoc = true;
					break;
				}

				if ( hasassoc )
				{
					pop->add( va( "Change associated actor for %s", current ), IDC_MODELTAB_ASSOCIATEACTOR );
				}
				else
				{
					pop->add( va( "Associate actor to %s", current ), IDC_MODELTAB_ASSOCIATEACTOR );
				}
			}

			pop->addSeparator();

			bool visible = models->IsModelShownIn3DView( idx );
			if ( visible )
			{
				pop->add( va( "Remove %s from 3D View", current ), IDC_MODELTAB_TOGGLE3DVIEW );
			}
			else
			{
				pop->add( va( "Show %s in 3D View", current ), IDC_MODELTAB_TOGGLE3DVIEW );
			}
		}
		if ( models->Count() > 0 )
		{
			pop->addSeparator();
			pop->add( "Show All", IDC_MODELTAB_SHOWALL );
			pop->add( "Hide All", IDC_MODELTAB_HIDEALL );
		}

		// Convert click position
		POINT pt;
		pt.x = mx;
		pt.y = my;

		// Convert coordinate space
		pop->popup( this, pt.x, pt.y );
	}
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *event - 
//-----------------------------------------------------------------------------
void CBaseFlex::AddFlexAnimation( CExpressionInfo *info )
{
	if ( !info )
		return;

	CChoreoEvent *event = info->m_pEvent;
	if ( !event )
		return;

	CChoreoScene *scene = info->m_pScene;
	if ( !scene )
		return;

	if ( !event->GetTrackLookupSet() )
	{
		// Create lookup data
		for ( int i = 0; i < event->GetNumFlexAnimationTracks(); i++ )
		{
			CFlexAnimationTrack *track = event->GetFlexAnimationTrack( i );
			if ( !track )
				continue;

			if ( track->IsComboType() )
			{
				char name[ 512 ];
				Q_strncpy( name, "right_" ,sizeof(name));
				strcat( name, track->GetFlexControllerName() );

				track->SetFlexControllerIndex( 0, FindFlexController( name ), 0 );

				Q_strncpy( name, "left_" ,sizeof(name));
				strcat( name, track->GetFlexControllerName() );

				track->SetFlexControllerIndex( 0, FindFlexController( name ), 1 );
			}
			else
			{
				track->SetFlexControllerIndex( 0, FindFlexController( (char *)track->GetFlexControllerName() ) );
			}
		}

		event->SetTrackLookupSet( true );
	}

	float scenetime = scene->GetTime();

	float weight = event->GetIntensity( scenetime );

	// Compute intensity for each track in animation and apply
	// Iterate animation tracks
	for ( int i = 0; i < event->GetNumFlexAnimationTracks(); i++ )
	{
		CFlexAnimationTrack *track = event->GetFlexAnimationTrack( i );
		if ( !track )
			continue;

		// Disabled
		if ( !track->IsTrackActive() )
			continue;

		// Map track flex controller to global name
		if ( track->IsComboType() )
		{
			for ( int side = 0; side < 2; side++ )
			{
				int controller = track->GetFlexControllerIndex( side );

				// Get spline intensity for controller
				float flIntensity = track->GetIntensity( scenetime, side );
				if ( controller >= 0 )
				{
					float orig = GetFlexWeight( controller );
					SetFlexWeight( controller, orig * (1 - weight) + flIntensity * weight );
				}
			}
		}
		else
		{
			int controller = track->GetFlexControllerIndex( 0 );

			// Get spline intensity for controller
			float flIntensity = track->GetIntensity( scenetime, 0 );
			if ( controller >= 0 )
			{
				float orig = GetFlexWeight( controller );
				SetFlexWeight( controller, orig * (1 - weight) + flIntensity * weight );
			}
		}
	}

	info->m_bStarted = true;
}
	virtual int handleEvent( mxEvent *event )
	{
		int iret = 0;
		switch ( event->event )
		{
		default:
			break;
		case mxEvent::Action:
			{
				iret = 1;
				switch ( event->action )
				{
				default:
					iret = 0;
					break;
				case IDC_MODELTAB_SHOWALL:
				case IDC_MODELTAB_HIDEALL:
					{
						bool show = ( event->action == IDC_MODELTAB_SHOWALL ) ? true : false;
						int c = models->Count();
						for ( int i = 0; i < c ; i++ )
						{
							models->ShowModelIn3DView( i, show );
						}
					}
					break;
				case IDC_MODELTAB_LOAD:
					{
						const char *ptr = mxGetOpenFileName(
							this, 
							FacePoser_MakeWindowsSlashes( va( "%s/models/", GetGameDirectory() ) ), 
							"*.mdl" );

						if (ptr)
						{
							g_MDLViewer->LoadModelFile( ptr );
						}
					}
					break;
				case IDC_MODELTAB_CLOSE:
					{
						int idx = getSelectedIndex();
						if ( idx >= 0 )
						{
							models->FreeModel( idx );
						}
					}
					break;
				case IDC_MODELTAB_CLOSEALL:
					{
						models->CloseAllModels();
					}
					break;
				case IDC_MODELTAB_CENTERONFACE:
					{
						g_pControlPanel->CenterOnFace();
					}
					break;
				case IDC_MODELTAB_TOGGLE3DVIEW:
					{
						int idx = getSelectedIndex();
						if ( idx >= 0 )
						{
							bool visible = models->IsModelShownIn3DView( idx );
							models->ShowModelIn3DView( idx, !visible );
						}
					}
					break;
				case IDC_MODELTAB_ASSOCIATEACTOR:
					{
						int idx = getSelectedIndex();
						if ( idx >= 0 )
						{
							char const *modelname = models->GetModelFileName( idx );

							CChoreoScene *scene = g_pChoreoView->GetScene();
							if ( scene )
							{
								CChoiceParams params;
								strcpy( params.m_szDialogTitle, "Associate Actor" );

								params.m_bPositionDialog = false;
								params.m_nLeft = 0;
								params.m_nTop = 0;
								strcpy( params.m_szPrompt, "Choose actor:" );

								params.m_Choices.RemoveAll();

								params.m_nSelected = -1;
								int oldsel = -1;

								int c = scene->GetNumActors();
								ChoiceText text;
								for ( int i = 0; i < c; i++ )
								{
									CChoreoActor *a = scene->GetActor( i );
									Assert( a );

									
									strcpy( text.choice, a->GetName() );

									if ( !stricmp( a->GetFacePoserModelName(), modelname ) )
									{
										params.m_nSelected = i;
										oldsel = -1;
									}

									params.m_Choices.AddToTail( text );
								}
		
								if ( ChoiceProperties( &params ) && 
									params.m_nSelected != oldsel )
								{
									
									// Chose something new...
									CChoreoActor *a = scene->GetActor( params.m_nSelected );
									
									g_pChoreoView->AssociateModelToActor( a, idx );
								}
							}
						}

					}
				}
			}
			break;
		}
		if ( iret )
			return iret;
		return BaseClass::handleEvent( event );
	}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CBaseFlex::AddSceneExpressions( void )
{
	// Iterate expressions and look for active slots
	for ( int i = 0; i < m_Expressions.Count(); i++ )
	{
		CExpressionInfo *info = &m_Expressions[ i ];
		Assert( info );

		// FIXME:  Need a safe handle to m_pEvent in case of memory deletion?
		CChoreoEvent *event = info->m_pEvent;
		Assert( event );

		CChoreoScene *scene = info->m_pScene;
		Assert( scene );

		switch ( event->GetType() )
		{
		case CChoreoEvent::FLEXANIMATION:
			{
				if ( event->HasEndTime() )
				{
					AddFlexAnimation( info );
				}
			}
			break;
		case CChoreoEvent::EXPRESSION:
			{
				// Expressions have to have an end time!!!
				if ( event->HasEndTime() )
				{
					// Look up the actual strings
					const char *scenefile	= event->GetParameters();
					const char *name		= event->GetParameters2();
					
					// Have to find both strings
					if ( scenefile && name )
					{
						// Find the scene file
						flexsettinghdr_t *pExpHdr = ( flexsettinghdr_t * )FindSceneFile( scenefile );
						if ( pExpHdr )
						{
							flexsettinghdr_t  *pOverrideHdr = NULL;
							
							// Find overrides, if any exist
							studiohdr_t	*hdr = GetModelPtr();
							
							if ( hdr && scene_allowoverrides.GetBool() )
							{
								char overridefile[ 512 ];
								char shortname[ 128 ];
								char modelname[ 128 ];
								
								//Q_strncpy( modelname, modelinfo->GetModelName( model ) ,sizeof(modelname));
								Q_strncpy( modelname, hdr->name ,sizeof(modelname));
								
								// Fix up the name
								Extract_FileBase( modelname, shortname );
								
								Q_snprintf( overridefile,sizeof(overridefile), "%s/%s", shortname, scenefile );
								
								pOverrideHdr = ( flexsettinghdr_t * )FindSceneFile( overridefile );
							}
							
							float scenetime = scene->GetTime();
							
							float scale = event->GetIntensity( scenetime );
							
							// Add the named expression
							AddExpression( name, scale, pExpHdr, pOverrideHdr, !info->m_bStarted );
						}
					}
				}
			}
			break;
		case CChoreoEvent::SEQUENCE:
			{
				AddFlexSequence( info );
			}
			break;
		case CChoreoEvent::GESTURE:
			{
				AddFlexGesture( info );
			}
			break;
		default:
			break;
		}

		/*
		float scenetime = scene->GetTime();

		float scale = event->GetIntensity( scenetime );
		Msg( "%s %f : ", event->GetName(), scale );
	
		// Add the named expression
		AddExpression( name, scale, pExpHdr, pOverrideHdr, !info->m_bStarted );
		*/

		info->m_bStarted = true;
	}
}
	virtual int handleEvent( mxEvent *event )
	{
		int iret = 0;
		switch ( event->event )
		{
		default:
			break;
		case mxEvent::Size:
			{
				int leftedge = w2() * 0.45f;
				m_btnFPS->setBounds( 0, 0, leftedge, h2() );
				m_btnGridSnap->setBounds( leftedge, 0, w2() - leftedge, h2() );
				iret = 1;
			}
			break;
		case mxEvent::Action:
			{
				iret = 1;
				switch ( event->action )
				{
				default:
					iret = 0;
					break;
				case IDC_GRIDSETTINGS_FPS:
					{
						if ( g_pChoreoView )
						{
							CChoreoScene *scene = g_pChoreoView->GetScene();
							if ( scene )
							{
								int currentFPS = scene->GetSceneFPS();
								
								CInputParams params;
								memset( &params, 0, sizeof( params ) );
								
								strcpy( params.m_szDialogTitle, "Change FPS" );
								
								Q_snprintf( params.m_szInputText, sizeof( params.m_szInputText ),
									"%i", currentFPS );
								
								strcpy( params.m_szPrompt, "Current FPS:" );
								
								if ( InputProperties( &params ) )
								{
									int newFPS = atoi( params.m_szInputText );
									
									if ( ( newFPS > 0 ) && ( newFPS != currentFPS ) )
									{
										g_pChoreoView->SetDirty( true );
										g_pChoreoView->PushUndo( "Change Scene FPS" );
										scene->SetSceneFPS( newFPS );
										g_pChoreoView->PushRedo( "Change Scene FPS" );
										Init();

										Con_Printf( "FPS changed to %i\n", newFPS );
									}
								}
								
							}
						}
					}
					break;
				case IDC_GRIDSETTINGS_SNAP:
					{
						if ( g_pChoreoView )
						{
							CChoreoScene *scene = g_pChoreoView->GetScene();
							if ( scene )
							{
								g_pChoreoView->SetDirty( true );
								g_pChoreoView->PushUndo( "Change Snap Frame" );
								
								scene->SetUsingFrameSnap( !scene->IsUsingFrameSnap() );
								
								g_pChoreoView->PushRedo( "Change Snap Frame" );
								
								Init();

								Con_Printf( "Time frame snapping: %s\n",
									scene->IsUsingFrameSnap() ? "on" : "off" );
							}
						}


					}
					break;
				}
			}
		}
		return iret;
	}
void ProcessVCD( CUtlDict< VCDList, int >& database, CUtlSymbol& vcdname )
{
    // vprint( 0, "Processing '%s'\n", g_Analysis.symbols.String( vcdname ) );

    // Load the .vcd
    char fullname[ 512 ];
    Q_snprintf( fullname, sizeof( fullname ), "%s", g_Analysis.symbols.String( vcdname ) );

    LoadScriptFile( fullname );

    CChoreoScene *scene = ChoreoLoadScene( fullname, NULL, &g_TokenProcessor, Con_Printf );
    if ( scene )
    {
        bool first = true;
        // Now iterate the events looking for speak events
        int c = scene->GetNumEvents();
        for ( int i = 0; i < c; i++ )
        {
            CChoreoEvent *e = scene->GetEvent( i );

            if ( e->GetType() == CChoreoEvent::MOVETO )
            {
                SpewMoveto( first, fullname, e );
                first = false;
            }

            if ( e->GetType() != CChoreoEvent::SPEAK )
                continue;

            // Look up sound in sound emitter system
            char const *wavename = soundemitter->GetWavFileForSound( e->GetParameters(), NULL );
            if ( !wavename || !wavename[ 0 ] )
            {
                continue;
            }

            char fullwavename[ 512 ];
            Q_snprintf( fullwavename, sizeof( fullwavename ), "%ssound\\%s",
                        gamedir, wavename );
            Q_FixSlashes( fullwavename );

            // Now add to proper slot
            VCDList *entry = NULL;

            // Add vcd to database
            int slot = database.Find( fullwavename );
            if ( slot == database.InvalidIndex() )
            {
                VCDList nullEntry;
                slot = database.Insert( fullwavename, nullEntry );
            }

            entry = &database[ slot ];
            if ( entry->vcds.Find( vcdname ) == entry->vcds.InvalidIndex() )
            {
                entry->vcds.AddToTail( vcdname );
            }
        }

        if ( vcdonly )
        {
            CheckForOverlappingFlexTracks( scene );
        }
    }

    delete scene;
}