Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1388 lines
39 KiB

  1. //========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. //
  9. // hud.cpp
  10. //
  11. // implementation of CHud class
  12. //
  13. #include "cbase.h"
  14. #include "hud_macros.h"
  15. #include "history_resource.h"
  16. #include "iinput.h"
  17. #include "clientmode.h"
  18. #include "in_buttons.h"
  19. #include <vgui_controls/Controls.h>
  20. #include <vgui/ISurface.h>
  21. #include <keyvalues.h>
  22. #include "itextmessage.h"
  23. #include "mempool.h"
  24. #include <keyvalues.h>
  25. #include "filesystem.h"
  26. #include <vgui_controls/AnimationController.h>
  27. #include <vgui/ISurface.h>
  28. #include "hud_lcd.h"
  29. #if defined( CSTRIKE15 )
  30. #include "c_cs_player.h"
  31. #include "cs_gamerules.h"
  32. #endif
  33. // memdbgon must be the last include file in a .cpp file!!!
  34. #include "tier0/memdbgon.h"
  35. static CClassMemoryPool< CHudTexture > g_HudTextureMemoryPool( 128 );
  36. //-----------------------------------------------------------------------------
  37. // Purpose: Parses the weapon txt files to get the sprites needed.
  38. //-----------------------------------------------------------------------------
  39. void LoadHudTextures( CUtlDict< CHudTexture *, int >& list, char *szFilenameWithoutExtension, const unsigned char *pICEKey )
  40. {
  41. KeyValues *pTemp, *pTextureSection;
  42. KeyValues *pKeyValuesData = ReadEncryptedKVFile( filesystem, szFilenameWithoutExtension, pICEKey );
  43. if ( pKeyValuesData )
  44. {
  45. pTextureSection = pKeyValuesData->FindKey( "TextureData" );
  46. if ( pTextureSection )
  47. {
  48. // Read the sprite data
  49. pTemp = pTextureSection->GetFirstSubKey();
  50. while ( pTemp )
  51. {
  52. CHudTexture *tex = new CHudTexture();
  53. // Key Name is the sprite name
  54. Q_strncpy( tex->szShortName, pTemp->GetName(), sizeof( tex->szShortName ) );
  55. if ( pTemp->GetString( "font", NULL ) )
  56. {
  57. // it's a font-based icon
  58. tex->bRenderUsingFont = true;
  59. tex->cCharacterInFont = *( pTemp->GetString( "character", "" ));
  60. Q_strncpy( tex->szTextureFile, pTemp->GetString( "font" ), sizeof( tex->szTextureFile ) );
  61. }
  62. else
  63. {
  64. tex->bRenderUsingFont = false;
  65. Q_strncpy( tex->szTextureFile, pTemp->GetString( "file" ), sizeof( tex->szTextureFile ) );
  66. tex->rc.left = pTemp->GetInt( "x", 0 );
  67. tex->rc.top = pTemp->GetInt( "y", 0 );
  68. tex->rc.right = pTemp->GetInt( "width", 0 ) + tex->rc.left;
  69. tex->rc.bottom = pTemp->GetInt( "height", 0 ) + tex->rc.top;
  70. }
  71. list.Insert( tex->szShortName, tex );
  72. pTemp = pTemp->GetNextKey();
  73. }
  74. }
  75. }
  76. // Failed for some reason. Delete the Key data and abort.
  77. pKeyValuesData->deleteThis();
  78. }
  79. //-----------------------------------------------------------------------------
  80. // Purpose:
  81. // Input : * -
  82. // list -
  83. //-----------------------------------------------------------------------------
  84. void FreeHudTextureList( CUtlDict< CHudTexture *, int >& list )
  85. {
  86. int c = list.Count();
  87. for ( int i = 0; i < c; i++ )
  88. {
  89. CHudTexture *tex = list[ i ];
  90. delete tex;
  91. }
  92. list.RemoveAll();
  93. }
  94. // Globally-used fonts
  95. vgui::HFont g_hFontTrebuchet24 = vgui::INVALID_FONT;
  96. //=======================================================================================================================
  97. // Hud Element Visibility handling
  98. //=======================================================================================================================
  99. typedef struct hudelement_hidden_s
  100. {
  101. char *sElementName;
  102. int iHiddenBits; // Bits in which this hud element is hidden
  103. } hudelement_hidden_t;
  104. ConVar hidehud( "hidehud", "0", FCVAR_CHEAT | FCVAR_SS );
  105. //=======================================================================================================================
  106. // CHudElement
  107. // All hud elements are derived from this class.
  108. //=======================================================================================================================
  109. //-----------------------------------------------------------------------------
  110. // Purpose: Registers the hud element in a global list, in CHud
  111. //-----------------------------------------------------------------------------
  112. CHudElement::CHudElement( const char *pElementName )
  113. {
  114. InitCHudElementAfterConstruction( pElementName );
  115. }
  116. void CHudElement::InitCHudElementAfterConstruction( const char* pElementName )
  117. {
  118. m_pHud = NULL;
  119. m_bActive = false;
  120. m_iHiddenBits = 0;
  121. m_pElementName = pElementName;
  122. m_nSplitScreenPlayerSlot = -1;
  123. SetNeedsRemove( false );
  124. m_bIsParentedToClientDLLRootPanel = false;
  125. m_ignoreGlobalHudDisable = false;
  126. m_bWantLateUpdate = false;
  127. // Make this for all hud elements, but when its a bit safer
  128. #if defined( TF_CLIENT_DLL )
  129. RegisterForRenderGroup( "global" );
  130. #endif
  131. }
  132. //-----------------------------------------------------------------------------
  133. // Purpose: Remove this hud element from the global list in CHUD
  134. //-----------------------------------------------------------------------------
  135. CHudElement::~CHudElement()
  136. {
  137. if ( m_bNeedsRemove )
  138. {
  139. GetHud().RemoveHudElement( this );
  140. }
  141. }
  142. void CHudElement::SetHud( CHud *pHud )
  143. {
  144. m_pHud = pHud;
  145. }
  146. //-----------------------------------------------------------------------------
  147. // Purpose:
  148. //-----------------------------------------------------------------------------
  149. void CHudElement::SetActive( bool bActive )
  150. {
  151. m_bActive = bActive;
  152. }
  153. //-----------------------------------------------------------------------------
  154. // Purpose:
  155. // Input : needsremove -
  156. //-----------------------------------------------------------------------------
  157. void CHudElement::SetNeedsRemove( bool needsremove )
  158. {
  159. m_bNeedsRemove = needsremove;
  160. }
  161. //-----------------------------------------------------------------------------
  162. // Purpose:
  163. //-----------------------------------------------------------------------------
  164. void CHudElement::SetHiddenBits( int iBits )
  165. {
  166. m_iHiddenBits = iBits;
  167. }
  168. //-----------------------------------------------------------------------------
  169. // Purpose:
  170. //-----------------------------------------------------------------------------
  171. void CHudElement::SetIgnoreGlobalHudDisable( bool hide )
  172. {
  173. m_ignoreGlobalHudDisable = hide;
  174. }
  175. //-----------------------------------------------------------------------------
  176. // Purpose:
  177. //-----------------------------------------------------------------------------
  178. bool CHudElement::GetIgnoreGlobalHudDisable( void )
  179. {
  180. return m_ignoreGlobalHudDisable;
  181. }
  182. //-----------------------------------------------------------------------------
  183. // Purpose:
  184. //-----------------------------------------------------------------------------
  185. bool CHudElement::ShouldDraw( void )
  186. {
  187. bool bShouldDraw = m_pHud && !m_pHud->IsHidden( m_iHiddenBits );
  188. if ( bShouldDraw )
  189. {
  190. // for each render group
  191. int iNumGroups = m_HudRenderGroups.Count();
  192. for ( int iGroupIndex = 0; iGroupIndex < iNumGroups; iGroupIndex++ )
  193. {
  194. if ( GetHud().IsRenderGroupLockedFor( this, m_HudRenderGroups.Element( iGroupIndex ) ) )
  195. return false;
  196. }
  197. }
  198. return bShouldDraw;
  199. }
  200. //-----------------------------------------------------------------------------
  201. // Purpose:
  202. // Output : Returns true on success, false on failure.
  203. //-----------------------------------------------------------------------------
  204. bool CHudElement::IsParentedToClientDLLRootPanel() const
  205. {
  206. return m_bIsParentedToClientDLLRootPanel;
  207. }
  208. //-----------------------------------------------------------------------------
  209. // Purpose:
  210. // Input : parented -
  211. //-----------------------------------------------------------------------------
  212. void CHudElement::SetParentedToClientDLLRootPanel( bool parented )
  213. {
  214. m_bIsParentedToClientDLLRootPanel = parented;
  215. }
  216. //-----------------------------------------------------------------------------
  217. // Purpose: We can register to be affected by multiple hud render groups
  218. //-----------------------------------------------------------------------------
  219. void CHudElement::RegisterForRenderGroup( const char *pszGroupName )
  220. {
  221. int iGroupIndex = GetHud().RegisterForRenderGroup( pszGroupName );
  222. // add group index to our list of registered groups
  223. if ( m_HudRenderGroups.Find( iGroupIndex ) == m_HudRenderGroups.InvalidIndex() )
  224. {
  225. m_HudRenderGroups.AddToTail( iGroupIndex );
  226. }
  227. }
  228. void CHudElement::UnregisterForRenderGroup( const char *pszGroupName )
  229. {
  230. int iGroupIndex = GetHud().RegisterForRenderGroup( pszGroupName );
  231. m_HudRenderGroups.FindAndRemove( iGroupIndex );
  232. }
  233. //-----------------------------------------------------------------------------
  234. // Purpose: We want to obscure other elements in this group
  235. //-----------------------------------------------------------------------------
  236. void CHudElement::HideLowerPriorityHudElementsInGroup( const char *pszGroupName )
  237. {
  238. // look up the render group
  239. int iGroupIndex = GetHud().LookupRenderGroupIndexByName( pszGroupName );
  240. // lock the group
  241. GetHud().LockRenderGroup( iGroupIndex, this );
  242. }
  243. //-----------------------------------------------------------------------------
  244. // Purpose: Stop obscuring other elements in this group
  245. //-----------------------------------------------------------------------------
  246. void CHudElement::UnhideLowerPriorityHudElementsInGroup( const char *pszGroupName )
  247. {
  248. // look up the render group
  249. int iGroupIndex = GetHud().LookupRenderGroupIndexByName( pszGroupName );
  250. // unlock the group
  251. GetHud().UnlockRenderGroup( iGroupIndex, this );
  252. }
  253. //-----------------------------------------------------------------------------
  254. // Purpose:
  255. //-----------------------------------------------------------------------------
  256. int CHudElement::GetRenderGroupPriority( void )
  257. {
  258. return 0;
  259. }
  260. int CHudElement::GetSplitScreenPlayerSlot() const
  261. {
  262. return m_nSplitScreenPlayerSlot;
  263. }
  264. void CHudElement::SetSplitScreenPlayerSlot( int nSlot )
  265. {
  266. m_nSplitScreenPlayerSlot = nSlot;
  267. }
  268. CHud gHUD[ MAX_SPLITSCREEN_PLAYERS ]; // global HUD objects
  269. CHud &GetHud( int nSlot /*= -1*/ )
  270. {
  271. if ( nSlot == -1 )
  272. {
  273. ASSERT_LOCAL_PLAYER_RESOLVABLE();
  274. nSlot = GET_ACTIVE_SPLITSCREEN_SLOT();
  275. }
  276. return gHUD[ nSlot ];
  277. }
  278. bool MsgFunc_ResetHUD( const CCSUsrMsg_ResetHud& msg )
  279. {
  280. ASSERT_LOCAL_PLAYER_RESOLVABLE();
  281. return gHUD[ GET_ACTIVE_SPLITSCREEN_SLOT() ].MsgFunc_ResetHUD( msg );
  282. }
  283. #ifdef CSTRIKE_DLL
  284. bool MsgFunc_SendAudio( const CCSUsrMsg_SendAudio& msg )
  285. {
  286. ASSERT_LOCAL_PLAYER_RESOLVABLE();
  287. return gHUD[ GET_ACTIVE_SPLITSCREEN_SLOT() ].MsgFunc_SendAudio( msg );
  288. }
  289. #endif
  290. class CSplitHudHelper
  291. {
  292. public:
  293. CUserMessageBinder m_UMCMsgResetHud;
  294. CUserMessageBinder m_UMCMsgSendAudio;
  295. void Init()
  296. {
  297. m_UMCMsgResetHud.Bind< CS_UM_ResetHud, CCSUsrMsg_ResetHud >( UtlMakeDelegate( MsgFunc_ResetHUD ) );
  298. #ifdef CSTRIKE_DLL
  299. m_UMCMsgSendAudio.Bind< CS_UM_SendAudio, CCSUsrMsg_SendAudio >( UtlMakeDelegate( MsgFunc_SendAudio ) );
  300. #endif
  301. }
  302. };
  303. static CSplitHudHelper g_HudHelper;
  304. CHud::CHud()
  305. {
  306. SetDefLessFunc( m_RenderGroups );
  307. m_flScreenShotTime = -1;
  308. m_nSplitScreenSlot = -1;
  309. m_bEngineIsInGame = false;
  310. }
  311. CUtlVector< CHudElement * > &CHud::GetHudList()
  312. {
  313. return m_HudList;
  314. }
  315. const CUtlVector< CHudElement * > &CHud::GetHudList() const
  316. {
  317. return m_HudList;
  318. }
  319. CUtlVector< vgui::Panel * > &CHud::GetHudPanelList()
  320. {
  321. return m_HudPanelList;
  322. }
  323. const CUtlVector< vgui::Panel * > &CHud::GetHudPanelList() const
  324. {
  325. return m_HudPanelList;
  326. }
  327. //-----------------------------------------------------------------------------
  328. // Purpose: This is called every time the DLL is loaded
  329. //-----------------------------------------------------------------------------
  330. void CHud::Init( void )
  331. {
  332. ASSERT_LOCAL_PLAYER_RESOLVABLE();
  333. m_nSplitScreenSlot = GET_ACTIVE_SPLITSCREEN_SLOT();
  334. g_HudHelper.Init();
  335. m_iDisabledCount = 0;
  336. InitFonts();
  337. // Create all the Hud elements
  338. CHudElementHelper::CreateAllElements();
  339. gLCD.Init();
  340. // Initialize all created elements
  341. for ( int i = 0; i < GetHudList().Count(); i++ )
  342. {
  343. GetHudList()[ i ]->Init();
  344. }
  345. KeyValues *kv = new KeyValues( "layout" );
  346. if ( kv )
  347. {
  348. if ( kv->LoadFromFile( filesystem, "scripts/HudLayout.res" ) )
  349. {
  350. int numelements = GetHudList().Count();
  351. for ( int i = 0; i < numelements; i++ )
  352. {
  353. CHudElement *element = GetHudList()[i];
  354. vgui::Panel *pPanel = GetHudPanelList()[i];
  355. if ( pPanel )
  356. {
  357. KeyValues *key = kv->FindKey( pPanel->GetName(), false );
  358. if ( !key )
  359. {
  360. Msg( "Hud element '%s' doesn't have an entry '%s' in scripts/HudLayout.res\n", element->GetName(), pPanel->GetName() );
  361. }
  362. // Note: When a panel is parented to the module root, it's "parent" is returned as NULL.
  363. if ( !element->IsParentedToClientDLLRootPanel() &&
  364. !pPanel->GetParent() )
  365. {
  366. DevMsg( "Hud element '%s'/'%s' doesn't have a parent\n", element->GetName(), pPanel->GetName() );
  367. }
  368. }
  369. }
  370. }
  371. kv->deleteThis();
  372. }
  373. if ( GET_ACTIVE_SPLITSCREEN_SLOT() == 0 )
  374. {
  375. HudIcons().Init();
  376. }
  377. }
  378. //-----------------------------------------------------------------------------
  379. // Purpose: Init Hud global colors
  380. // Input : *scheme -
  381. //-----------------------------------------------------------------------------
  382. void CHud::InitColors( vgui::IScheme *scheme )
  383. {
  384. m_clrNormal = scheme->GetColor( "Normal", Color( 255, 208, 64 ,255 ) );
  385. m_clrCaution = scheme->GetColor( "Caution", Color( 255, 48, 0, 255 ) );
  386. m_clrYellowish = scheme->GetColor( "Yellowish", Color( 255, 160, 0, 255 ) );
  387. }
  388. //-----------------------------------------------------------------------------
  389. // Initializes fonts
  390. //-----------------------------------------------------------------------------
  391. void CHud::InitFonts()
  392. {
  393. vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
  394. vgui::IScheme *pScheme = vgui::scheme()->GetIScheme( scheme );
  395. g_hFontTrebuchet24 = pScheme->GetFont( "DefaultLarge", true );
  396. }
  397. //-----------------------------------------------------------------------------
  398. // Purpose:
  399. //-----------------------------------------------------------------------------
  400. void CHud::Shutdown( void )
  401. {
  402. gLCD.Shutdown();
  403. // Delete all the Hud elements
  404. int iMax = GetHudList().Count();
  405. for ( int i = iMax-1; i >= 0; i-- )
  406. {
  407. delete GetHudList()[i];
  408. }
  409. GetHudList().Purge();
  410. GetHudPanelList().Purge();
  411. if ( GET_ACTIVE_SPLITSCREEN_SLOT() == 0 )
  412. {
  413. HudIcons().Shutdown();
  414. }
  415. }
  416. //-----------------------------------------------------------------------------
  417. // Purpose: LevelInit's called whenever a new level's starting
  418. //-----------------------------------------------------------------------------
  419. void CHud::LevelInit( void )
  420. {
  421. // Tell all the registered hud elements to LevelInit
  422. for ( int i = 0; i < GetHudList().Count(); i++ )
  423. {
  424. GetHudList()[ i ]->LevelInit();
  425. }
  426. // Unhide all render groups
  427. int iCount = m_RenderGroups.Count();
  428. for ( int i = 0; i < iCount; i++ )
  429. {
  430. CHudRenderGroup *group = m_RenderGroups[ i ];
  431. group->bHidden = false;
  432. group->m_pLockingElements.Purge();
  433. }
  434. }
  435. //-----------------------------------------------------------------------------
  436. // Purpose: LevelShutdown's called whenever a level's finishing
  437. //-----------------------------------------------------------------------------
  438. void CHud::LevelShutdown( void )
  439. {
  440. // Tell all the registered hud elements to LevelInit
  441. for ( int i = 0; i < GetHudList().Count(); i++ )
  442. {
  443. GetHudList()[ i ]->LevelShutdown();
  444. }
  445. }
  446. //-----------------------------------------------------------------------------
  447. // Purpose: cleans up memory allocated for m_rg* arrays
  448. //-----------------------------------------------------------------------------
  449. CHud::~CHud()
  450. {
  451. int c = m_RenderGroups.Count();
  452. for ( int i = c - 1; i >= 0; i-- )
  453. {
  454. CHudRenderGroup *group = m_RenderGroups[ i ];
  455. m_RenderGroups.RemoveAt( i );
  456. delete group;
  457. }
  458. }
  459. void CHudTexture::Precache( void )
  460. {
  461. // costly function, used selectively on specific hud elements to get font pages built out at load time
  462. if ( bRenderUsingFont && !bPrecached && hFont != vgui::INVALID_FONT )
  463. {
  464. wchar_t wideChars[2];
  465. wideChars[0] = ( wchar_t )cCharacterInFont;
  466. wideChars[1] = 0;
  467. vgui::surface()->PrecacheFontCharacters( hFont, wideChars );
  468. bPrecached = true;
  469. }
  470. }
  471. void CHudTexture::DrawSelf( int x, int y, const Color& clr, float flApparentZ ) const
  472. {
  473. DrawSelf( x, y, Width(), Height(), clr, flApparentZ );
  474. }
  475. void CHudTexture::DrawSelf( int x, int y, int w, int h, const Color& clr, float flApparentZ ) const
  476. {
  477. if ( bRenderUsingFont )
  478. {
  479. vgui::surface()->DrawSetApparentDepth( flApparentZ );
  480. vgui::surface()->DrawSetTextFont( hFont );
  481. vgui::surface()->DrawSetTextColor( clr );
  482. vgui::surface()->DrawSetTextPos( x, y );
  483. vgui::surface()->DrawUnicodeChar( cCharacterInFont );
  484. vgui::surface()->DrawClearApparentDepth();
  485. }
  486. else
  487. {
  488. if ( textureId == -1 )
  489. return;
  490. vgui::surface()->DrawSetApparentDepth( flApparentZ );
  491. vgui::surface()->DrawSetTexture( textureId );
  492. vgui::surface()->DrawSetColor( clr );
  493. vgui::surface()->DrawTexturedSubRect( x, y, x + w, y + h,
  494. texCoords[ 0 ], texCoords[ 1 ], texCoords[ 2 ], texCoords[ 3 ] );
  495. vgui::surface()->DrawClearApparentDepth();
  496. }
  497. }
  498. void CHudTexture::DrawSelfCropped( int x, int y, int cropx, int cropy, int cropw, int croph, int finalWidth, int finalHeight, Color clr, float flApparentZ ) const
  499. {
  500. if ( bRenderUsingFont )
  501. {
  502. // work out how much we've been cropped
  503. int height = vgui::surface()->GetFontTall( hFont );
  504. float frac = ( height - croph ) / ( float )height;
  505. y -= cropy;
  506. vgui::surface()->DrawSetApparentDepth( flApparentZ );
  507. vgui::surface()->DrawSetTextFont( hFont );
  508. vgui::surface()->DrawSetTextColor( clr );
  509. vgui::surface()->DrawSetTextPos( x, y );
  510. FontCharRenderInfo info;
  511. if ( vgui::surface()->DrawGetUnicodeCharRenderInfo( cCharacterInFont, info ) )
  512. {
  513. if ( cropy )
  514. {
  515. info.verts[0].m_Position.y = Lerp( frac, info.verts[0].m_Position.y, info.verts[1].m_Position.y );
  516. info.verts[0].m_TexCoord.y = Lerp( frac, info.verts[0].m_TexCoord.y, info.verts[1].m_TexCoord.y );
  517. }
  518. else if ( croph != height )
  519. {
  520. info.verts[1].m_Position.y = Lerp( 1.0f - frac, info.verts[0].m_Position.y, info.verts[1].m_Position.y );
  521. info.verts[1].m_TexCoord.y = Lerp( 1.0f - frac, info.verts[0].m_TexCoord.y, info.verts[1].m_TexCoord.y );
  522. }
  523. vgui::surface()->DrawRenderCharFromInfo( info );
  524. }
  525. vgui::surface()->DrawClearApparentDepth();
  526. }
  527. else
  528. {
  529. if ( textureId == -1 )
  530. return;
  531. float fw = ( float )Width();
  532. float fh = ( float )Height();
  533. float twidth = texCoords[ 2 ] - texCoords[ 0 ];
  534. float theight = texCoords[ 3 ] - texCoords[ 1 ];
  535. // Interpolate coords
  536. float tCoords[ 4 ];
  537. tCoords[ 0 ] = texCoords[ 0 ] + ( ( float )cropx / fw ) * twidth;
  538. tCoords[ 1 ] = texCoords[ 1 ] + ( ( float )cropy / fh ) * theight;
  539. tCoords[ 2 ] = texCoords[ 0 ] + ( ( float )( cropx + cropw ) / fw ) * twidth;
  540. tCoords[ 3 ] = texCoords[ 1 ] + ( ( float )( cropy + croph ) / fh ) * theight;
  541. vgui::surface()->DrawSetApparentDepth( flApparentZ );
  542. vgui::surface()->DrawSetTexture( textureId );
  543. vgui::surface()->DrawSetColor( clr );
  544. vgui::surface()->DrawTexturedSubRect(
  545. x, y,
  546. x + finalWidth, y + finalHeight,
  547. tCoords[ 0 ], tCoords[ 1 ],
  548. tCoords[ 2 ], tCoords[ 3 ] );
  549. vgui::surface()->DrawClearApparentDepth();
  550. }
  551. }
  552. void CHudTexture::DrawSelfCropped( int x, int y, int cropx, int cropy, int cropw, int croph, Color clr, float flApparentZ ) const
  553. {
  554. DrawSelfCropped( x, y, cropx, cropy, cropw, croph, cropw, croph, clr, flApparentZ );
  555. }
  556. void CHudTexture::DrawSelfScalableCorners( int drawX, int drawY, int w, int h, int iSrcCornerW, int iSrcCornerH, int iDrawCornerW, int iDrawCornerH, Color clr, float flApparentZ ) const
  557. {
  558. if ( bRenderUsingFont )
  559. {
  560. Assert( !"DrawSelfScalableCorners does not support drawing a font" );
  561. return;
  562. }
  563. if ( textureId == -1 )
  564. return;
  565. float fw = ( float )Width();
  566. float fh = ( float )Height();
  567. float flCornerWidthPercent = ( fw > 0 ) ? ( ( float )iSrcCornerW / fw ) : 0;
  568. float flCornerHeightPercent = ( fh > 0 ) ? ( ( float )iSrcCornerH / fh ) : 0;
  569. vgui::surface()->DrawSetColor( clr );
  570. vgui::surface()->DrawSetTexture( textureId );
  571. float uvx = 0;
  572. float uvy = 0;
  573. float uvw, uvh;
  574. float drawW, drawH;
  575. int x = drawX;
  576. int y = drawY;
  577. int row, col;
  578. for ( row=0;row<3;row++ )
  579. {
  580. x = drawX;
  581. uvx = 0;
  582. if ( row == 0 || row == 2 )
  583. {
  584. //uvh - row 0 or 2, is src_corner_height
  585. uvh = flCornerHeightPercent;
  586. drawH = iDrawCornerH;
  587. }
  588. else
  589. {
  590. //uvh - row 1, is tall - ( 2 * src_corner_height ) ( min 0 )
  591. uvh = MAX( 1.0 - 2 * flCornerHeightPercent, 0.0f );
  592. drawH = MAX( 0, ( h - 2 * iDrawCornerH ) );
  593. }
  594. for ( col=0;col<3;col++ )
  595. {
  596. if ( col == 0 || col == 2 )
  597. {
  598. //uvw - col 0 or 2, is src_corner_width
  599. uvw = flCornerWidthPercent;
  600. drawW = iDrawCornerW;
  601. }
  602. else
  603. {
  604. //uvw - col 1, is wide - ( 2 * src_corner_width ) ( min 0 )
  605. uvw = MAX( 1.0 - 2 * flCornerWidthPercent, 0.0f );
  606. drawW = MAX( 0, ( w - 2 * iDrawCornerW ) );
  607. }
  608. Vector2D uv11( uvx, uvy );
  609. Vector2D uv21( uvx+uvw, uvy );
  610. Vector2D uv22( uvx+uvw, uvy+uvh );
  611. Vector2D uv12( uvx, uvy+uvh );
  612. vgui::Vertex_t verts[4];
  613. verts[0].Init( Vector2D( x, y ), uv11 );
  614. verts[1].Init( Vector2D( x+drawW, y ), uv21 );
  615. verts[2].Init( Vector2D( x+drawW, y+drawH ), uv22 );
  616. verts[3].Init( Vector2D( x, y+drawH ), uv12 );
  617. vgui::surface()->DrawTexturedPolygon( 4, verts, false );
  618. x += drawW;
  619. uvx += uvw;
  620. }
  621. y += drawH;
  622. uvy += uvh;
  623. }
  624. vgui::surface()->DrawSetTexture( 0 );
  625. }
  626. //-----------------------------------------------------------------------------
  627. // Purpose: returns width of texture with scale factor applied. ( If rendered
  628. // using font, scale factor is ignored. )
  629. //-----------------------------------------------------------------------------
  630. int CHudTexture::EffectiveWidth( float flScale ) const
  631. {
  632. if ( !bRenderUsingFont )
  633. {
  634. return ( int ) ( Width() * flScale );
  635. }
  636. else
  637. {
  638. return vgui::surface()->GetCharacterWidth( hFont, cCharacterInFont );
  639. }
  640. }
  641. //-----------------------------------------------------------------------------
  642. // Purpose: returns height of texture with scale factor applied. ( If rendered
  643. // using font, scale factor is ignored. )
  644. //-----------------------------------------------------------------------------
  645. int CHudTexture::EffectiveHeight( float flScale ) const
  646. {
  647. if ( !bRenderUsingFont )
  648. {
  649. return ( int ) ( Height() * flScale );
  650. }
  651. else
  652. {
  653. return vgui::surface()->GetFontAscent( hFont, cCharacterInFont );
  654. }
  655. }
  656. //-----------------------------------------------------------------------------
  657. // Purpose:
  658. //-----------------------------------------------------------------------------
  659. void CHud::OnRestore()
  660. {
  661. ResetHUD();
  662. }
  663. //-----------------------------------------------------------------------------
  664. // Purpose:
  665. //-----------------------------------------------------------------------------
  666. void CHud::VidInit( void )
  667. {
  668. for ( int i = 0; i < GetHudList().Count(); i++ )
  669. {
  670. GetHudList()[ i ]->VidInit();
  671. }
  672. ResetHUD();
  673. }
  674. //-----------------------------------------------------------------------------
  675. // Purpose:
  676. //-----------------------------------------------------------------------------
  677. CHudElement *CHud::FindElement( const char *pName )
  678. {
  679. for ( int i = 0; i < GetHudList().Count(); i++ )
  680. {
  681. if ( stricmp( GetHudList()[ i ]->GetName(), pName ) == 0 )
  682. return GetHudList()[i];
  683. }
  684. DevWarning( 1, "[%d] Could not find Hud Element: %s\n", m_nSplitScreenSlot, pName );
  685. Assert( 0 );
  686. return NULL;
  687. }
  688. //-----------------------------------------------------------------------------
  689. // Purpose: Adds a member to the HUD
  690. //-----------------------------------------------------------------------------
  691. void CHud::AddHudElement( CHudElement *pHudElement )
  692. {
  693. pHudElement->SetSplitScreenPlayerSlot( GET_ACTIVE_SPLITSCREEN_SLOT() );
  694. // Add the hud element to the end of the array
  695. GetHudList().AddToTail( pHudElement );
  696. vgui::Panel *pPanel = dynamic_cast< vgui::Panel * >( pHudElement );
  697. GetHudPanelList().AddToTail( pPanel );
  698. pHudElement->SetHud( this );
  699. pHudElement->SetNeedsRemove( true );
  700. }
  701. //-----------------------------------------------------------------------------
  702. // Purpose: Remove an element from the HUD
  703. //-----------------------------------------------------------------------------
  704. void CHud::RemoveHudElement( CHudElement *pHudElement )
  705. {
  706. int location = GetHudList().Find( pHudElement );
  707. GetHudList().Remove( location );
  708. GetHudPanelList().Remove( location );
  709. }
  710. //-----------------------------------------------------------------------------
  711. // Purpose: Returns current mouse sensitivity setting
  712. // Output : float - the return value
  713. //-----------------------------------------------------------------------------
  714. float CHud::GetSensitivity( void )
  715. {
  716. return m_flMouseSensitivity;
  717. }
  718. float CHud::GetFOVSensitivityAdjust()
  719. {
  720. return m_flFOVSensitivityAdjust;
  721. }
  722. void CHud::DisableHud( void )
  723. {
  724. if ( m_iDisabledCount < 1 )
  725. m_iDisabledCount = 1;
  726. else
  727. m_iDisabledCount++;
  728. }
  729. void CHud::EnableHud( void )
  730. {
  731. if ( m_iDisabledCount <= 0 )
  732. DebuggerBreakIfDebugging();
  733. m_iDisabledCount--;
  734. }
  735. bool CHud::HudDisabled( void )
  736. {
  737. return m_iDisabledCount > 0;
  738. }
  739. //-----------------------------------------------------------------------------
  740. // Purpose: Return true if the passed in sections of the HUD shouldn't be drawn
  741. //-----------------------------------------------------------------------------
  742. bool CHud::IsHidden( int iHudFlags )
  743. {
  744. // Not in game?
  745. if ( !m_bEngineIsInGame )
  746. return true;
  747. // Grab the local or observed player
  748. C_BasePlayer *pPlayer = GetHudPlayer();
  749. // Grab the local player
  750. C_CSPlayer *localPlayer = C_CSPlayer::GetLocalCSPlayer();
  751. if ( !pPlayer )
  752. return true;
  753. int iHideHud = pPlayer->m_Local.m_iHideHUD;
  754. ConVarRef hidehudref( "hidehud" );
  755. if ( hidehudref.GetInt() )
  756. {
  757. iHideHud = hidehudref.GetInt();
  758. }
  759. // Everything hidden?
  760. if ( iHideHud & HIDEHUD_ALL )
  761. return true;
  762. // hide health if not chasing a target
  763. if ( localPlayer->GetObserverMode() == OBS_MODE_ROAMING ||
  764. localPlayer->GetObserverMode() == OBS_MODE_FIXED ||
  765. localPlayer->GetObserverMode() == OBS_MODE_FREEZECAM ||
  766. localPlayer->GetObserverMode() == OBS_MODE_DEATHCAM )
  767. {
  768. if ( (iHudFlags & HIDEHUD_HEALTH) || (iHudFlags & HIDEHUD_WEAPONSELECTION) )
  769. return true;
  770. }
  771. // Hide all hud elements if we're blurring the background, since they don't blur properly
  772. if ( GetClientMode()->GetBlurFade() )
  773. return true;
  774. // Don't show hud elements when we're at the mainmenu with a background map running
  775. if ( engine->IsLevelMainMenuBackground() )
  776. return true;
  777. // Local player dead?
  778. if ( ( iHudFlags & HIDEHUD_PLAYERDEAD ) && ( pPlayer->GetHealth() <= 0 ) )
  779. return true;
  780. // Need the HEV suit ( HL2 )
  781. if ( ( iHudFlags & HIDEHUD_NEEDSUIT ) && ( !pPlayer->IsSuitEquipped() ) )
  782. return true;
  783. #if defined( CSTRIKE15 )
  784. if ( CSGameRules() && CSGameRules()->IsPlayingTraining() )
  785. {
  786. C_CSPlayer *pCSPlayer = static_cast<C_CSPlayer *>( pPlayer );
  787. // hide the mini scoreboard?
  788. if ( ( iHudFlags & HIDEHUD_MINISCOREBOARD ) && ( pCSPlayer && pCSPlayer->IsMiniScoreHidden() ) )
  789. return true;
  790. // hide the radar?
  791. if ( ( iHudFlags & HIDEHUD_RADAR ) && ( pCSPlayer && pCSPlayer->IsRadarHidden() ) )
  792. return true;
  793. }
  794. #endif
  795. return ( ( iHudFlags & iHideHud ) != 0 );
  796. }
  797. //-----------------------------------------------------------------------------
  798. // Purpose: Allows HUD to modify input data
  799. //-----------------------------------------------------------------------------
  800. void CHud::ProcessInput( bool bActive )
  801. {
  802. if ( bActive )
  803. {
  804. m_iKeyBits = input->GetButtonBits( false );
  805. // Weaponbits need to be sent down as a UserMsg now.
  806. GetHud().Think();
  807. }
  808. }
  809. int CHud::LookupRenderGroupIndexByName( const char *pszGroupName )
  810. {
  811. int iIndex = m_RenderGroupNames.Find( pszGroupName );
  812. Assert( m_RenderGroupNames.IsValidIndex( iIndex ) );
  813. return iIndex;
  814. }
  815. //-----------------------------------------------------------------------------
  816. // Purpose: A hud element wants to lock this render group so other panels in the
  817. // group do not draw
  818. //-----------------------------------------------------------------------------
  819. bool CHud::LockRenderGroup( int iGroupIndex, CHudElement *pLocker /* = NULL */ )
  820. {
  821. // does this index exist?
  822. if ( !DoesRenderGroupExist( iGroupIndex ) )
  823. return false;
  824. int i = m_RenderGroups.Find( iGroupIndex );
  825. Assert( m_RenderGroups.IsValidIndex( i ) );
  826. CHudRenderGroup *group = m_RenderGroups.Element( i );
  827. Assert( group );
  828. if ( group )
  829. {
  830. // NULL pLocker means some higher power is globally hiding this group
  831. if ( pLocker == NULL )
  832. {
  833. group->bHidden = true;
  834. }
  835. else
  836. {
  837. bool bFound = false;
  838. // See if we have it locked already
  839. int iNumLockers = group->m_pLockingElements.Count();
  840. for ( int i=0;i<iNumLockers;i++ )
  841. {
  842. if ( pLocker == group->m_pLockingElements.Element( i ) )
  843. {
  844. bFound = true;
  845. break;
  846. }
  847. }
  848. // otherwise lock us
  849. if ( !bFound )
  850. group->m_pLockingElements.Insert( pLocker );
  851. }
  852. return true;
  853. }
  854. return false;
  855. }
  856. //-----------------------------------------------------------------------------
  857. // Purpose: A hud element wants to release the lock on this render group
  858. //-----------------------------------------------------------------------------
  859. bool CHud::UnlockRenderGroup( int iGroupIndex, CHudElement *pLocker /* = NULL */ )
  860. {
  861. // does this index exist?
  862. if ( !DoesRenderGroupExist( iGroupIndex ) )
  863. return false;
  864. int i = m_RenderGroups.Find( iGroupIndex );
  865. Assert( m_RenderGroups.IsValidIndex( i ) );
  866. CHudRenderGroup *group = m_RenderGroups.Element( i );
  867. if ( group )
  868. {
  869. // NULL pLocker means some higher power is globally hiding this group
  870. if ( group->bHidden && pLocker == NULL )
  871. {
  872. group->bHidden = false;
  873. return true;
  874. }
  875. int iNumLockers = group->m_pLockingElements.Count();
  876. for ( int i=0;i<iNumLockers;i++ )
  877. {
  878. if ( pLocker == group->m_pLockingElements.Element( i ) )
  879. {
  880. group->m_pLockingElements.RemoveAt( i );
  881. return true;
  882. }
  883. }
  884. }
  885. return false;
  886. }
  887. //-----------------------------------------------------------------------------
  888. // Purpose: See if we should draw based on a hud render group
  889. // Return true if this group is locked, hud elem will be hidden
  890. //-----------------------------------------------------------------------------
  891. bool CHud::IsRenderGroupLockedFor( CHudElement *pHudElement, int iGroupIndex )
  892. {
  893. // does this index exist?
  894. if ( !DoesRenderGroupExist( iGroupIndex ) )
  895. return false;
  896. int i = m_RenderGroups.Find( iGroupIndex );
  897. Assert( m_RenderGroups.IsValidIndex( i ) );
  898. CHudRenderGroup *group = m_RenderGroups.Element( i );
  899. if ( !group )
  900. return false;
  901. // hidden for everyone!
  902. if ( group->bHidden )
  903. return true;
  904. if ( group->m_pLockingElements.Count() == 0 )
  905. return false;
  906. if ( !pHudElement )
  907. return true;
  908. CHudElement *pLocker = group->m_pLockingElements.ElementAtHead();
  909. return ( pLocker != pHudElement && pLocker->GetRenderGroupPriority() > pHudElement->GetRenderGroupPriority() );
  910. }
  911. //-----------------------------------------------------------------------------
  912. // Purpose: CHudElements can ask for the index of hud element render groups
  913. // returns a group index
  914. //-----------------------------------------------------------------------------
  915. int CHud::RegisterForRenderGroup( const char *pszGroupName )
  916. {
  917. int iGroupNameIndex = m_RenderGroupNames.Find( pszGroupName );
  918. if ( iGroupNameIndex != m_RenderGroupNames.InvalidIndex() )
  919. {
  920. return iGroupNameIndex;
  921. }
  922. // otherwise add the group
  923. return AddHudRenderGroup( pszGroupName );
  924. }
  925. //-----------------------------------------------------------------------------
  926. // Purpose: Create a new hud render group
  927. // returns a group index
  928. //-----------------------------------------------------------------------------
  929. int CHud::AddHudRenderGroup( const char *pszGroupName )
  930. {
  931. // we tried to register for a group but didn't find it, add a new one
  932. int iGroupNameIndex = m_RenderGroupNames.AddToTail( pszGroupName );
  933. CHudRenderGroup *group = new CHudRenderGroup();
  934. return m_RenderGroups.Insert( iGroupNameIndex, group );
  935. }
  936. //-----------------------------------------------------------------------------
  937. // Purpose:
  938. //-----------------------------------------------------------------------------
  939. bool CHud::DoesRenderGroupExist( int iGroupIndex )
  940. {
  941. return ( m_RenderGroups.Find( iGroupIndex ) != m_RenderGroups.InvalidIndex() );
  942. }
  943. //-----------------------------------------------------------------------------
  944. // Purpose: Allows HUD to Think and modify input data
  945. // Input : *cdata -
  946. // time -
  947. // Output : int - 1 if there were changes, 0 otherwise
  948. //-----------------------------------------------------------------------------
  949. void CHud::UpdateHud( bool bActive )
  950. {
  951. // clear the weapon bits.
  952. m_iKeyBits &= ( ~( IN_WEAPON1|IN_WEAPON2 ));
  953. GetClientMode()->Update();
  954. gLCD.Update();
  955. }
  956. void CHud::OnSplitScreenStateChanged()
  957. {
  958. for ( int i = 0; i < GetHudList().Count(); ++i )
  959. {
  960. GetHudList()[ i ]->OnSplitScreenStateChanged();
  961. }
  962. }
  963. //-----------------------------------------------------------------------------
  964. // Purpose: Force a Hud UI anim to play
  965. //-----------------------------------------------------------------------------
  966. CON_COMMAND_F( testhudanim, "Test a hud element animation.\n\tArguments: <anim name>\n", FCVAR_CHEAT )
  967. {
  968. if ( args.ArgC() != 2 )
  969. {
  970. Msg( "Usage:\n testhudanim <anim name>\n" );
  971. return;
  972. }
  973. GetClientMode()->GetViewportAnimationController()->StartAnimationSequence( args[1] );
  974. }
  975. CHudIcons::CHudIcons() :
  976. m_bHudTexturesLoaded( false )
  977. {
  978. }
  979. CHudIcons::~CHudIcons()
  980. {
  981. int c = m_Icons.Count();
  982. for ( int i = c - 1; i >= 0; i-- )
  983. {
  984. CHudTexture *tex = m_Icons[ i ];
  985. g_HudTextureMemoryPool.Free( tex );
  986. }
  987. m_Icons.Purge();
  988. }
  989. void CHudIcons::Init()
  990. {
  991. if ( m_bHudTexturesLoaded )
  992. return;
  993. m_bHudTexturesLoaded = true;
  994. CUtlDict< CHudTexture *, int > textureList;
  995. // check to see if we have sprites for this res; if not, step down
  996. LoadHudTextures( textureList, "scripts/hud_textures", NULL );
  997. LoadHudTextures( textureList, "scripts/mod_textures", NULL );
  998. LoadHudTextures( textureList, "scripts/instructor_textures", NULL );
  999. LoadHudTextures( textureList, "scripts/instructor_modtextures", NULL );
  1000. #ifdef PORTAL2
  1001. LoadHudTextures( textureList, "scripts/signifier_textures", NULL );
  1002. #endif
  1003. // PORTAL2
  1004. int c = textureList.Count();
  1005. for ( int index = 0; index < c; index++ )
  1006. {
  1007. CHudTexture* tex = textureList[ index ];
  1008. AddSearchableHudIconToList( *tex );
  1009. }
  1010. FreeHudTextureList( textureList );
  1011. }
  1012. void CHudIcons::Shutdown()
  1013. {
  1014. m_bHudTexturesLoaded = false;
  1015. }
  1016. //-----------------------------------------------------------------------------
  1017. // Purpose:
  1018. //-----------------------------------------------------------------------------
  1019. CHudTexture *CHudIcons::AddUnsearchableHudIconToList( CHudTexture& texture )
  1020. {
  1021. // These names are composed based on the texture file name
  1022. char composedName[ 512 ];
  1023. if ( texture.bRenderUsingFont )
  1024. {
  1025. Q_snprintf( composedName, sizeof( composedName ), "%s_c%i",
  1026. texture.szTextureFile, texture.cCharacterInFont );
  1027. }
  1028. else
  1029. {
  1030. Q_snprintf( composedName, sizeof( composedName ), "%s_%i_%i_%i_%i",
  1031. texture.szTextureFile, texture.rc.left, texture.rc.top, texture.rc.right, texture.rc.bottom );
  1032. }
  1033. CHudTexture *icon = GetIcon( composedName );
  1034. if ( icon )
  1035. {
  1036. return icon;
  1037. }
  1038. CHudTexture *newTexture = ( CHudTexture * )g_HudTextureMemoryPool.Alloc();
  1039. *newTexture = texture;
  1040. SetupNewHudTexture( newTexture );
  1041. int idx = m_Icons.Insert( composedName, newTexture );
  1042. return m_Icons[ idx ];
  1043. }
  1044. //-----------------------------------------------------------------------------
  1045. // Purpose:
  1046. //-----------------------------------------------------------------------------
  1047. CHudTexture *CHudIcons::AddSearchableHudIconToList( CHudTexture& texture )
  1048. {
  1049. CHudTexture *icon = GetIcon( texture.szShortName );
  1050. if ( icon )
  1051. {
  1052. return icon;
  1053. }
  1054. CHudTexture *newTexture = ( CHudTexture * )g_HudTextureMemoryPool.Alloc();
  1055. *newTexture = texture;
  1056. SetupNewHudTexture( newTexture );
  1057. int idx = m_Icons.Insert( texture.szShortName, newTexture );
  1058. return m_Icons[ idx ];
  1059. }
  1060. //-----------------------------------------------------------------------------
  1061. // Purpose: returns a pointer to an icon in the list
  1062. //-----------------------------------------------------------------------------
  1063. CHudTexture *CHudIcons::GetIcon( const char *szIcon )
  1064. {
  1065. int i = m_Icons.Find( szIcon );
  1066. if ( i == m_Icons.InvalidIndex() )
  1067. return NULL;
  1068. return m_Icons[ i ];
  1069. }
  1070. //-----------------------------------------------------------------------------
  1071. // Purpose: Gets texture handles for the hud icon
  1072. //-----------------------------------------------------------------------------
  1073. void CHudIcons::SetupNewHudTexture( CHudTexture *t )
  1074. {
  1075. if ( t->bRenderUsingFont )
  1076. {
  1077. vgui::HScheme scheme = vgui::scheme()->GetScheme( "basemodui_scheme" );
  1078. t->hFont = vgui::scheme()->GetIScheme( scheme )->GetFont( t->szTextureFile, true );
  1079. t->rc.top = 0;
  1080. t->rc.left = 0;
  1081. t->rc.right = vgui::surface()->GetCharacterWidth( t->hFont, t->cCharacterInFont );
  1082. t->rc.bottom = vgui::surface()->GetFontTall( t->hFont );
  1083. }
  1084. else
  1085. {
  1086. // Set up texture id and texture coordinates
  1087. t->textureId = vgui::surface()->CreateNewTextureID();
  1088. vgui::surface()->DrawSetTextureFile( t->textureId, t->szTextureFile, false, false );
  1089. int wide, tall;
  1090. vgui::surface()->DrawGetTextureSize( t->textureId, wide, tall );
  1091. t->texCoords[ 0 ] = ( float )( t->rc.left + 0.5f ) / ( float )wide;
  1092. t->texCoords[ 1 ] = ( float )( t->rc.top + 0.5f ) / ( float )tall;
  1093. t->texCoords[ 2 ] = ( float )( t->rc.right - 0.5f ) / ( float )wide;
  1094. t->texCoords[ 3 ] = ( float )( t->rc.bottom - 0.5f ) / ( float )tall;
  1095. }
  1096. }
  1097. //-----------------------------------------------------------------------------
  1098. // Purpose:
  1099. //-----------------------------------------------------------------------------
  1100. void CHudIcons::RefreshHudTextures()
  1101. {
  1102. if ( !m_bHudTexturesLoaded )
  1103. {
  1104. Assert( 0 );
  1105. return;
  1106. }
  1107. CUtlDict< CHudTexture *, int > textureList;
  1108. // check to see if we have sprites for this res; if not, step down
  1109. LoadHudTextures( textureList, "scripts/hud_textures", NULL );
  1110. LoadHudTextures( textureList, "scripts/mod_textures", NULL );
  1111. LoadHudTextures( textureList, "scripts/instructor_textures", NULL );
  1112. // fix up all the texture icons first
  1113. int c = textureList.Count();
  1114. for ( int index = 0; index < c; index++ )
  1115. {
  1116. CHudTexture *tex = textureList[ index ];
  1117. Assert( tex );
  1118. CHudTexture *icon = GetIcon( tex->szShortName );
  1119. if ( !icon )
  1120. continue;
  1121. // Update file
  1122. Q_strncpy( icon->szTextureFile, tex->szTextureFile, sizeof( icon->szTextureFile ) );
  1123. if ( !icon->bRenderUsingFont )
  1124. {
  1125. // Update subrect
  1126. icon->rc = tex->rc;
  1127. // Keep existing texture id, but now update texture file and texture coordinates
  1128. vgui::surface()->DrawSetTextureFile( icon->textureId, icon->szTextureFile, false, false );
  1129. // Get new texture dimensions in case it changed
  1130. int wide, tall;
  1131. vgui::surface()->DrawGetTextureSize( icon->textureId, wide, tall );
  1132. // Assign coords
  1133. icon->texCoords[ 0 ] = ( float )( icon->rc.left + 0.5f ) / ( float )wide;
  1134. icon->texCoords[ 1 ] = ( float )( icon->rc.top + 0.5f ) / ( float )tall;
  1135. icon->texCoords[ 2 ] = ( float )( icon->rc.right - 0.5f ) / ( float )wide;
  1136. icon->texCoords[ 3 ] = ( float )( icon->rc.bottom - 0.5f ) / ( float )tall;
  1137. }
  1138. }
  1139. FreeHudTextureList( textureList );
  1140. // fixup all the font icons
  1141. vgui::HScheme scheme = vgui::scheme()->GetScheme( "basemodui_scheme" );
  1142. for ( int i = m_Icons.First(); m_Icons.IsValidIndex( i ); i = m_Icons.Next( i ))
  1143. {
  1144. CHudTexture *icon = m_Icons[i];
  1145. if ( !icon )
  1146. continue;
  1147. // Update file
  1148. if ( icon->bRenderUsingFont )
  1149. {
  1150. icon->hFont = vgui::scheme()->GetIScheme( scheme )->GetFont( icon->szTextureFile, true );
  1151. icon->rc.top = 0;
  1152. icon->rc.left = 0;
  1153. icon->rc.right = vgui::surface()->GetCharacterWidth( icon->hFont, icon->cCharacterInFont );
  1154. icon->rc.bottom = vgui::surface()->GetFontTall( icon->hFont );
  1155. }
  1156. }
  1157. }
  1158. static CHudIcons g_HudIcons;
  1159. CHudIcons &HudIcons()
  1160. {
  1161. return g_HudIcons;
  1162. }