//========= 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 #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