aboutsummaryrefslogtreecommitdiff
path: root/sp/src/game/client/hud_closecaption.h
blob: 180afe9d53bbe7688d33c401715efd7b71a1a0a8 (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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
// $NoKeywords: $
//=============================================================================//

#ifndef HUD_CLOSECAPTION_H
#define HUD_CLOSECAPTION_H
#ifdef _WIN32
#pragma once
#endif

#include "hudelement.h"
#include <vgui_controls/Panel.h>
#include "captioncompiler.h"
#include "tier1/UtlSortVector.h"
#include "tier1/utlsymbol.h"

class CSentence;
class C_BaseFlex;
class CCloseCaptionItem;
struct WorkUnitParams;
class CAsyncCaption;

typedef CUtlSortVector< CaptionLookup_t, CCaptionLookupLess > CaptionDictionary_t;
struct AsyncCaptionData_t;
struct AsyncCaption_t
{
	AsyncCaption_t() : 
		m_DataBaseFile( UTL_INVAL_SYMBOL ),
		m_RequestedBlocks( 0, 0, BlockInfo_t::Less )
	{
		Q_memset( &m_Header, 0, sizeof( m_Header ) );
	}

	struct BlockInfo_t
	{
		int			fileindex;
		int			blocknum;
		memhandle_t handle;

		static bool Less( const BlockInfo_t& lhs, const BlockInfo_t& rhs )
		{
			if ( lhs.fileindex != rhs.fileindex )
				return lhs.fileindex < rhs.fileindex;

			return lhs.blocknum < rhs.blocknum;
		}
	};

	AsyncCaption_t& operator =( const AsyncCaption_t& rhs )
	{
		if ( this == &rhs )
			return *this;

		m_CaptionDirectory = rhs.m_CaptionDirectory;
		m_Header = rhs.m_Header;
		m_DataBaseFile = rhs.m_DataBaseFile;

		for ( int i = rhs.m_RequestedBlocks.FirstInorder(); i != rhs.m_RequestedBlocks.InvalidIndex(); i = rhs.m_RequestedBlocks.NextInorder( i ) )
		{
			m_RequestedBlocks.Insert( rhs.m_RequestedBlocks[ i ] );
		}

		return *this;
	}

	CUtlRBTree< BlockInfo_t, unsigned short >	m_RequestedBlocks;

	CaptionDictionary_t		m_CaptionDirectory;
	CompiledCaptionHeader_t	m_Header;
	CUtlSymbol				m_DataBaseFile;
};

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
class CHudCloseCaption : public CHudElement, public vgui::Panel
{
	DECLARE_CLASS_SIMPLE( CHudCloseCaption, vgui::Panel );
public:
	DECLARE_MULTIPLY_INHERITED();

					CHudCloseCaption( const char *pElementName );
	virtual 		~CHudCloseCaption();

	// Expire lingering items
	virtual void	OnTick( void );

	virtual void	LevelInit( void );

	virtual void	LevelShutdown( void )
	{
		Reset();
	}

	// Painting methods
	virtual void	Paint();

	void MsgFunc_CloseCaption(bf_read &msg);

	// Clear all CC data
	void			Reset( void );
	void			Process( const wchar_t *stream, float duration, char const *tokenstream, bool fromplayer, bool direct = false );
	
	bool			ProcessCaption( char const *tokenname, float duration, bool fromplayer = false, bool direct = false );
	void			ProcessCaptionDirect( char const *tokenname, float duration, bool fromplayer = false );

	void			ProcessSentenceCaptionStream( char const *tokenstream );
	void			PlayRandomCaption();

	void				InitCaptionDictionary( char const *dbfile );
	void				OnFinishAsyncLoad( int nFileIndex, int nBlockNum, AsyncCaptionData_t *pData );

	void			Flush();
	void			TogglePaintDebug();

	enum
	{
		CCFONT_NORMAL = 0,
		CCFONT_ITALIC,
		CCFONT_BOLD,
		CCFONT_ITALICBOLD,
		CCFONT_SMALL,
		CCFONT_MAX
	};

	static int GetFontNumber( bool bold, bool italic );

	void			Lock( void );
	void			Unlock( void );

	void			FindSound( char const *pchANSI );

public:

	struct CaptionRepeat
	{
		CaptionRepeat() :
			m_nTokenIndex( 0 ),
			m_flLastEmitTime( 0 ),
			m_flInterval( 0 ),
			m_nLastEmitTick( 0 )
		{
		}
		int		m_nTokenIndex;
		int		m_nLastEmitTick;
		float	m_flLastEmitTime;
		float	m_flInterval;
	};

private:

	void ClearAsyncWork();
	void ProcessAsyncWork();
	bool AddAsyncWork( char const *tokenstream, bool bIsStream, float duration, bool fromplayer, bool direct = false );

	void _ProcessSentenceCaptionStream( int wordCount, char const *tokenstream, const wchar_t *caption_full );
	void _ProcessCaption( const wchar_t *caption, char const *tokenname, float duration, bool fromplayer, bool direct = false );

	CUtlLinkedList< CAsyncCaption *, unsigned short >	m_AsyncWork;

	CUtlRBTree< CaptionRepeat, int >	m_CloseCaptionRepeats;

private:

	static bool CaptionTokenLessFunc( const CaptionRepeat &lhs, const CaptionRepeat &rhs );

	void	DrawStream( wrect_t& rect, wrect_t &rcWindow, CCloseCaptionItem *item, int iFadeLine, float flFadeLineAlpha ); 
	void	ComputeStreamWork( int available_width, CCloseCaptionItem *item );
	bool	SplitCommand( wchar_t const **ppIn, wchar_t *cmd, wchar_t *args ) const;

	bool	StreamHasCommand( const wchar_t *stream, const wchar_t *findcmd ) const;
	bool	GetFloatCommandValue( const wchar_t *stream, const wchar_t *findcmd, float& value ) const;

	bool	GetNoRepeatValue( const wchar_t *caption, float &retval );

	void	ParseCloseCaptionStream( const wchar_t *in, int available_width );
	bool	StreamHasCommand( const wchar_t *stream, const wchar_t *search );

	void	DumpWork( CCloseCaptionItem *item );

	void AddWorkUnit( 
		CCloseCaptionItem *item,	
		WorkUnitParams& params );

	CUtlVector< CCloseCaptionItem * > m_Items;

	vgui::HFont		m_hFonts[CCFONT_MAX];

	void			CreateFonts( void );

	int			m_nLineHeight;

	int			m_nGoalHeight;
	int			m_nCurrentHeight;
	float		m_flGoalAlpha;
	float		m_flCurrentAlpha;
	float		m_flGoalHeightStartTime;
	float		m_flGoalHeightFinishTime;

	CPanelAnimationVar( float, m_flBackgroundAlpha, "BgAlpha", "192" );
	CPanelAnimationVar( float, m_flGrowTime, "GrowTime", "0.25" );
	CPanelAnimationVar( float, m_flItemHiddenTime, "ItemHiddenTime", "0.2" );
	CPanelAnimationVar( float, m_flItemFadeInTime, "ItemFadeInTime", "0.15" );
	CPanelAnimationVar( float, m_flItemFadeOutTime, "ItemFadeOutTime", "0.3" );
	CPanelAnimationVar( int, m_nTopOffset, "topoffset", "40" );

	CUtlVector< AsyncCaption_t > m_AsyncCaptions;
	bool		m_bLocked;
	bool		m_bVisibleDueToDirect;
	bool		m_bPaintDebugInfo;
	CUtlSymbol	m_CurrentLanguage;
};

#endif // HUD_CLOSECAPTION_H