aboutsummaryrefslogtreecommitdiff
path: root/sp/src/public/studio_generic_io.cpp
blob: 7345e9af50019ffcf21028ed116743bb426ee7f6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
//========= 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();
}