source-engine/public/studio_generic_io.cpp

157 lines
3.6 KiB
C++
Raw Normal View History

2020-04-23 00:56:21 +08:00
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <assert.h>
#include "studio.h"
#include "utlrbtree.h"
extern studiohdr_t *FindOrLoadGroupFile( char const *modelname );
virtualmodel_t *studiohdr_t::GetVirtualModel( void ) const
{
if (numincludemodels == 0)
{
return NULL;
}
virtualmodel_t *pVModel = (virtualmodel_t *)virtualModel;
if (pVModel == NULL)
{
pVModel = new virtualmodel_t;
// !!! Set cache handle? Set pointer to local virtual model??
virtualModel = (void *)pVModel;
int group = pVModel->m_group.AddToTail( );
pVModel->m_group[ group ].cache = (void *)this;
pVModel->AppendModels( 0, this );
}
return pVModel;
}
const studiohdr_t *studiohdr_t::FindModel( void **cache, char const *modelname ) const
{
studiohdr_t *hdr = (studiohdr_t *)(*cache);
if (hdr)
{
return hdr;
}
hdr = FindOrLoadGroupFile( modelname );
*cache = (void *)hdr;
return hdr;
}
const studiohdr_t *virtualgroup_t::GetStudioHdr( void ) const
{
return (studiohdr_t *)cache;
}
byte *studiohdr_t::GetAnimBlock( int i ) const
{
byte *hdr = (byte *)animblockModel;
if (!hdr)
{
hdr = (byte *)FindOrLoadGroupFile( pszAnimBlockName() );
animblockModel = hdr;
}
return hdr + pAnimBlock( i )->datastart;
}
//-----------------------------------------------------------------------------
// Purpose: Builds up a dictionary of autoplay indices by studiohdr_t *
// NOTE: This list never gets freed even if the model gets unloaded, but we're in a tool so we can probably live with that
//-----------------------------------------------------------------------------
struct AutoPlayGeneric_t
{
public:
AutoPlayGeneric_t() :
hdr( 0 )
{
}
// Implement copy constructor
AutoPlayGeneric_t( const AutoPlayGeneric_t& src )
{
hdr = src.hdr;
autoplaylist.EnsureCount( src.autoplaylist.Count() );
autoplaylist.CopyArray( src.autoplaylist.Base(), src.autoplaylist.Count() );
}
static bool AutoPlayGenericLessFunc( const AutoPlayGeneric_t& lhs, const AutoPlayGeneric_t& rhs )
{
return lhs.hdr < rhs.hdr;
}
public:
// Data
const studiohdr_t *hdr;
CUtlVector< unsigned short > autoplaylist;
};
// A global array to track this data
static CUtlRBTree< AutoPlayGeneric_t, int > g_AutoPlayGeneric( 0, 0, AutoPlayGeneric_t::AutoPlayGenericLessFunc );
int studiohdr_t::GetAutoplayList( unsigned short **pAutoplayList ) const
{
virtualmodel_t *pVirtualModel = GetVirtualModel();
if ( pVirtualModel )
{
if ( pAutoplayList && pVirtualModel->m_autoplaySequences.Count() )
{
*pAutoplayList = pVirtualModel->m_autoplaySequences.Base();
}
return pVirtualModel->m_autoplaySequences.Count();
}
AutoPlayGeneric_t *pData = NULL;
// Search for this studiohdr_t ptr in the global list
AutoPlayGeneric_t search;
search.hdr = this;
int index = g_AutoPlayGeneric.Find( search );
if ( index == g_AutoPlayGeneric.InvalidIndex() )
{
// Not there, so add it
index = g_AutoPlayGeneric.Insert( search );
pData = &g_AutoPlayGeneric[ index ];
// And compute the autoplay info this one time
int autoPlayCount = CountAutoplaySequences();
pData->autoplaylist.EnsureCount( autoPlayCount );
CopyAutoplaySequences( pData->autoplaylist.Base(), autoPlayCount );
}
else
{
// Refer to existing data
pData = &g_AutoPlayGeneric[ index ];
}
// Oops!!!
if ( !pData )
{
return 0;
}
// Give back data if it's being requested
if ( pAutoplayList )
{
*pAutoplayList = pData->autoplaylist.Base();
}
return pData->autoplaylist.Count();
}