//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// #include #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(); }