Scenes.image
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...

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.