Scenes.image

From Valve Developer Community
Revision as of 16:28, 5 November 2010 by TomEdwards (talk | contribs)
Jump to navigation Jump to search

scenes/scenes.image is a binary data blob from which Source 2007 (i.e. The Orange Box engine) loads choreography scenes. It was created to improve performance on consoles: it is loaded into memory its entirety when the engine starts, which eliminates the need for consoles' slow optical media to seek around on a disk for hundreds of loose .VCD files. It helps on PC too however, so has been ported across.

To build a scenes.image, load Faceposer and choose File > Rebuild scenes.image...

Warning.pngWarning:Only the VCD files in YOUR scenes/ folder will be built into the image. This means that you will need to extract Valve's scenes from your base game's GCFs before compiling if you want to use them. Remember that a lot of scenes used automatically by NPCs are in the original source engine.gcf. (Yes, doing all this sucks!) You don't need to distribute the extracted VCD files though.

Bypassing

If you are producing your own binaries, the old method of loading loose files can be reinstated:

CChoreoScene *CSceneEntity::LoadScene( const char *filename, IChoreoEventCallback *pCallback )
{
	char loadfile[MAX_PATH];
	Q_strncpy( loadfile, filename, sizeof( loadfile ) );
	Q_SetExtension( loadfile, ".vcd", sizeof( loadfile ) );
	Q_FixSlashes( loadfile );
	
	void *pBuffer = 0;
	CChoreoScene *pScene;

	int fileSize = filesystem->ReadFileEx( loadfile, "MOD", &pBuffer, true );
	if (fileSize)
	{
		g_TokenProcessor.SetBuffer((char*)pBuffer);
		pScene = ChoreoLoadScene( loadfile, NULL, &g_TokenProcessor, LocalScene_Printf );
	}
	else
	{
		// binary compiled vcd
		pScene = new CChoreoScene( NULL );
		if ( !CopySceneFileIntoMemory( loadfile, &pBuffer, &fileSize ) )
		{
			MissingSceneWarning( loadfile );
			return NULL;
		}
		CUtlBuffer buf( pBuffer, fileSize, CUtlBuffer::READ_ONLY );
		if ( !pScene->RestoreFromBinaryBuffer( buf, loadfile, &g_ChoreoStringPool ) )
		{
			Warning( "CSceneEntity::LoadScene: Unable to load scene '%s'\n", loadfile );
			delete pScene;
			pScene = NULL;
		}
	}
	
	if(pScene)
	{
		pScene->SetPrintFunc( LocalScene_Printf );
		pScene->SetEventCallbackInterface( pCallback );
	}

	FreeSceneFileMemory( pBuffer );
	return pScene;
}
}
CChoreoScene *C_SceneEntity::LoadScene( const char *filename )
{
	char loadfile[MAX_PATH];
	Q_strncpy( loadfile, filename, sizeof( loadfile ) );
	Q_SetExtension( loadfile, ".vcd", sizeof( loadfile ) );
	Q_FixSlashes( loadfile );

	void *pBuffer = 0;
	CChoreoScene *pScene;

	int fileSize = filesystem->ReadFileEx( loadfile, "MOD", &pBuffer, true );
	if (fileSize)
	{
		g_TokenProcessor.SetBuffer((char*)pBuffer);
		pScene = ChoreoLoadScene( loadfile, this, &g_TokenProcessor, Scene_Printf );
	}
	else
	{
		fileSize = scenefilecache->GetSceneBufferSize( loadfile );
		if ( fileSize <= 0 )
			return NULL;

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

	
		if ( IsBufferBinaryVCD( (char*)pBuffer, fileSize ) )
		{
			pScene = new CChoreoScene( this );
			CUtlBuffer buf( pBuffer, fileSize, CUtlBuffer::READ_ONLY );
			if ( !pScene->RestoreFromBinaryBuffer( buf, loadfile, &g_ChoreoStringPool ) )
			{
				Warning( "Unable to restore scene '%s'\n", loadfile );
				delete pScene;
				pScene = NULL;
			}
		}
	}

	if(pScene)
	{
		pScene->SetPrintFunc( Scene_Printf );
		pScene->SetEventCallbackInterface( this );
	}

	delete[] pBuffer;
	return pScene;
}

This code also fixes a bug where the maximum path length for a scene was longer on the server than on the client.