Team Fortress 2 Source Code as on 22/4/2020
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.

1574 lines
39 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "hudelement.h"
  8. #include "hud_numericdisplay.h"
  9. #include <vgui_controls/Panel.h>
  10. #include "hud.h"
  11. #include "hud_suitpower.h"
  12. #include "hud_macros.h"
  13. #include "iclientmode.h"
  14. #include <vgui_controls/AnimationController.h>
  15. #include <vgui/ISurface.h>
  16. #include <vgui/ILocalize.h>
  17. #include "KeyValues.h"
  18. #include "filesystem.h"
  19. // memdbgon must be the last include file in a .cpp file!!!
  20. #include "tier0/memdbgon.h"
  21. struct portalcreditname_t
  22. {
  23. char szCreditName[256];
  24. char szFontName[256];
  25. wchar_t szLyricLine[256];
  26. float flYPos;
  27. float flXPos;
  28. bool bActive;
  29. float flTime;
  30. float flTimeAdd;
  31. float flTimeStart;
  32. float flTimeEnd;
  33. float flTimeInit;
  34. int iAsciiIndex;
  35. bool bReset;
  36. int iXOffset;
  37. int iSlot;
  38. };
  39. #define CREDITS_FILE "scripts/credits.txt"
  40. #define CREDITS_FILE_PORTAL "scripts/credits.txt"
  41. enum
  42. {
  43. LOGO_FADEIN = 0,
  44. LOGO_FADEHOLD,
  45. LOGO_FADEOUT,
  46. LOGO_FADEOFF,
  47. };
  48. #define CREDITS_LOGO 1
  49. #define CREDITS_INTRO 2
  50. #define CREDITS_OUTRO 3
  51. #define CREDITS_OUTRO_PORTAL 4
  52. bool g_bPortalRollingCredits = false;
  53. int g_iPortalCreditsPixelHeight = 0;
  54. //-----------------------------------------------------------------------------
  55. // Purpose: Shows the flashlight icon
  56. //-----------------------------------------------------------------------------
  57. class CHudPortalCredits : public CHudElement, public vgui::Panel
  58. {
  59. DECLARE_CLASS_SIMPLE( CHudPortalCredits, vgui::Panel );
  60. public:
  61. CHudPortalCredits( const char *pElementName );
  62. virtual void Init( void );
  63. virtual void LevelShutdown( void );
  64. int GetStringPixelWidth ( wchar_t *pString, vgui::HFont hFont );
  65. int GetPixelWidth( char *pString, vgui::HFont hFont );
  66. void MsgFunc_CreditsPortalMsg( bf_read &msg );
  67. void MsgFunc_LogoTimeMsg( bf_read &msg );
  68. virtual bool ShouldDraw( void )
  69. {
  70. g_bPortalRollingCredits = IsActive();
  71. if ( g_bPortalRollingCredits && m_iCreditsType == CREDITS_INTRO )
  72. g_bPortalRollingCredits = false;
  73. return IsActive();
  74. }
  75. protected:
  76. virtual void Paint();
  77. virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
  78. private:
  79. void Clear();
  80. void ReadNames( KeyValues *pKeyValue );
  81. void ReadLyrics( KeyValues *pKeyValue );
  82. void ReadAscii( KeyValues *pKeyValue );
  83. void ReadParams( KeyValues *pKeyValue );
  84. void PrepareCredits( const char *pKeyName );
  85. void DrawOutroCreditsName( void );
  86. void DrawPortalOutroCreditsName( void );
  87. void DrawPortalOutroCreditsLyrics( void );
  88. void DrawIntroCreditsName( void );
  89. void DrawPortalAsciiArt( void );
  90. void DrawLogo( void );
  91. void PrepareLogo( float flTime );
  92. void PrepareOutroCredits( void );
  93. void PreparePortalOutroCredits( void );
  94. void PrepareIntroCredits( void );
  95. float FadeBlend( float fadein, float fadeout, float hold, float localTime );
  96. CPanelAnimationVar( vgui::HFont, m_hTextFont, "TextFont", "Default" );
  97. CPanelAnimationVar( Color, m_TextColor, "TextColor", "FgColor" );
  98. CUtlVector<portalcreditname_t> m_CreditsList;
  99. CUtlVector<portalcreditname_t> m_LyricsList;
  100. CUtlVector<portalcreditname_t> m_AsciiList;
  101. char m_szCreditPrint[256];
  102. char m_szBorderH[512];
  103. float m_flScrollTime;
  104. float m_flSeparation;
  105. float m_flFadeTime;
  106. float m_flCursorBlinkTime;
  107. bool m_bLastOneInPlace;
  108. int m_Alpha;
  109. char m_szAsciiArtFont[256];
  110. int m_iCreditsType;
  111. int m_iLogoState;
  112. int m_iCurrentAsciiArt;
  113. int m_iCurrentLowY;
  114. int m_iYOffset;
  115. int m_iYOffsetNames;
  116. int m_iYDrawOffset;
  117. int m_iXOffset;
  118. int m_iXOffsetNames;
  119. int m_iLongestName;
  120. float m_flFadeInTime;
  121. float m_flFadeHoldTime;
  122. float m_flFadeOutTime;
  123. float m_flNextStartTime;
  124. float m_flPauseBetweenWaves;
  125. float m_flLastPaintTime;
  126. float m_flLastBlinkTime;
  127. float m_flCurrentDelayTime;
  128. float m_flNameCharTime;
  129. float m_flScrollCreditsStart;
  130. float m_flSongStartTime;
  131. //Screen adjustment properties
  132. int m_iScreenXOffset;
  133. int m_iScreenYOffset;
  134. int m_iScreenWidthAdjustment;
  135. int m_iScreenHeightAdjustment;
  136. //Ascii Art positioning
  137. int m_iAASeparation;
  138. int m_iAAScreenXOffset;
  139. int m_iAAScreenYOffset;
  140. float m_flLogoTimeMod;
  141. float m_flLogoTime;
  142. float m_flLogoDesiredLength;
  143. float m_flX;
  144. float m_flY;
  145. bool m_bStartSong;
  146. float m_flLyricsStartTime;
  147. Color m_cColor;
  148. };
  149. void CHudPortalCredits::PrepareCredits( const char *pKeyName )
  150. {
  151. Clear();
  152. KeyValues *pKV= new KeyValues( "CreditsFile" );
  153. if (m_iCreditsType == CREDITS_OUTRO_PORTAL)
  154. {
  155. if ( !pKV->LoadFromFile( filesystem, CREDITS_FILE_PORTAL, "MOD" ) )
  156. {
  157. pKV->deleteThis();
  158. Assert( !"env_portal_credits couldn't be initialized!" );
  159. return;
  160. }
  161. }
  162. else
  163. {
  164. if ( !pKV->LoadFromFile( filesystem, CREDITS_FILE, "MOD" ) )
  165. {
  166. pKV->deleteThis();
  167. Assert( !"env_portal_credits couldn't be initialized!" );
  168. return;
  169. }
  170. }
  171. KeyValues *pKVSubkey = pKV->FindKey( pKeyName );
  172. ReadNames( pKVSubkey );
  173. pKVSubkey = pKV->FindKey( "CreditsParams" );
  174. ReadParams( pKVSubkey );
  175. pKVSubkey = pKV->FindKey( "OutroSongLyrics" );
  176. ReadLyrics( pKVSubkey );
  177. pKVSubkey = pKV->FindKey( "OutroAsciiArt" );
  178. ReadAscii( pKVSubkey );
  179. pKV->deleteThis();
  180. }
  181. using namespace vgui;
  182. DECLARE_HUDELEMENT( CHudPortalCredits );
  183. DECLARE_HUD_MESSAGE( CHudPortalCredits, CreditsPortalMsg );
  184. DECLARE_HUD_MESSAGE( CHudPortalCredits, LogoTimeMsg );
  185. //-----------------------------------------------------------------------------
  186. // Purpose: Constructor
  187. //-----------------------------------------------------------------------------
  188. CHudPortalCredits::CHudPortalCredits( const char *pElementName ) : CHudElement( pElementName ), BaseClass( NULL, "HudCredits" )
  189. {
  190. vgui::Panel *pParent = g_pClientMode->GetViewport();
  191. SetParent( pParent );
  192. }
  193. void CHudPortalCredits::LevelShutdown()
  194. {
  195. Clear();
  196. }
  197. void CHudPortalCredits::Clear( void )
  198. {
  199. SetActive( false );
  200. m_CreditsList.RemoveAll();
  201. m_LyricsList.RemoveAll();
  202. m_bLastOneInPlace = false;
  203. m_Alpha = m_TextColor[3];
  204. m_iLogoState = LOGO_FADEOFF;
  205. }
  206. //-----------------------------------------------------------------------------
  207. // Purpose:
  208. //-----------------------------------------------------------------------------
  209. void CHudPortalCredits::Init()
  210. {
  211. HOOK_HUD_MESSAGE( CHudPortalCredits, CreditsPortalMsg );
  212. HOOK_HUD_MESSAGE( CHudPortalCredits, LogoTimeMsg );
  213. SetActive( false );
  214. }
  215. void CHudPortalCredits::ReadNames( KeyValues *pKeyValue )
  216. {
  217. if ( pKeyValue == NULL )
  218. {
  219. Assert( !"CHudPortalCredits couldn't be initialized!" );
  220. return;
  221. }
  222. // Now try and parse out each act busy anim
  223. KeyValues *pKVNames = pKeyValue->GetFirstSubKey();
  224. char *cTmp;
  225. while ( pKVNames )
  226. {
  227. portalcreditname_t Credits;
  228. V_strcpy_safe( Credits.szCreditName, pKVNames->GetName() );
  229. V_strcpy_safe( Credits.szFontName, pKeyValue->GetString( Credits.szCreditName, "Default" ) );
  230. Credits.flTimeInit = 0.00;
  231. cTmp=Q_strstr(Credits.szCreditName,"[");
  232. if (!(cTmp == NULL)) {
  233. Credits.flTimeInit = Q_atof(cTmp+1);
  234. }
  235. cTmp=Q_strstr(Credits.szCreditName,"]");
  236. if (!(cTmp == NULL)) {
  237. Q_strcpy(Credits.szCreditName,cTmp+1);
  238. }
  239. m_CreditsList.AddToTail( Credits );
  240. pKVNames = pKVNames->GetNextKey();
  241. }
  242. }
  243. void CHudPortalCredits::ReadLyrics( KeyValues *pKeyValue )
  244. {
  245. if ( pKeyValue == NULL )
  246. {
  247. Assert( !"CHudPortalCredits couldn't be initialized!" );
  248. return;
  249. }
  250. KeyValues *pKVNames = pKeyValue->GetFirstSubKey();
  251. char *cTmp;
  252. int iHeight = 0;
  253. int iXOffsetTemp = 0;
  254. bool bNextOnSameLine = false;
  255. bool bNoY = false;
  256. char tmpstr[255] = "";
  257. float flTotalTime = 0.00;
  258. while ( pKVNames )
  259. {
  260. bNoY = false;
  261. portalcreditname_t Credits;
  262. vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
  263. vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( "CreditsOutroText", true );
  264. V_strcpy_safe( Credits.szCreditName, pKVNames->GetName());
  265. V_strcpy_safe( Credits.szFontName, pKeyValue->GetString( Credits.szCreditName, "Default" ) );
  266. Credits.flTimeInit = 0.00;
  267. cTmp=Q_strstr(Credits.szCreditName,"[");
  268. if (!(cTmp == NULL)) {
  269. Credits.flTimeInit = Q_atof(cTmp+1);
  270. }
  271. cTmp=Q_strstr(Credits.szCreditName,"]");
  272. if (!(cTmp == NULL)) {
  273. Q_strcpy(Credits.szCreditName,cTmp+1);
  274. }
  275. Credits.iAsciiIndex = 0;
  276. cTmp=Q_strstr(Credits.szCreditName,"<<<");
  277. if (!(cTmp == NULL)) {
  278. Credits.iAsciiIndex = Q_atoi(cTmp+3);
  279. }
  280. cTmp=Q_strstr(Credits.szCreditName,">>>");
  281. if (!(cTmp == NULL)) {
  282. Q_strcpy(Credits.szCreditName,cTmp+3);
  283. }
  284. if (Q_strcmp("&",Credits.szCreditName)==0) //clear screen code
  285. {
  286. iHeight = 0;
  287. Credits.bReset = true;
  288. Q_strcpy(Credits.szCreditName," ");
  289. }
  290. else Credits.bReset = false;
  291. Credits.flYPos = iHeight;
  292. Credits.bActive = false;
  293. if (bNextOnSameLine)
  294. {
  295. Credits.iXOffset=iXOffsetTemp;
  296. //GetPixelWidth( tmpstr, m_hTFont )
  297. bNextOnSameLine = false;
  298. }
  299. else
  300. {
  301. iXOffsetTemp=0;
  302. Credits.iXOffset = 0;
  303. }
  304. if (Credits.szCreditName[0] == '*')
  305. {
  306. bNextOnSameLine = true;
  307. Q_strcpy(tmpstr,&Credits.szCreditName[1]);
  308. Q_strcpy(Credits.szCreditName,tmpstr);
  309. bNoY = true;
  310. }
  311. if ((!(Q_strcmp(" ",Credits.szCreditName)==0)) && !bNoY)
  312. {
  313. iHeight += surface()->GetFontTall ( m_hTFont ) + m_flSeparation;
  314. if (Q_strcmp("^",Credits.szCreditName)==0)
  315. {
  316. Q_strcpy(Credits.szCreditName," ");
  317. }
  318. }
  319. if ( Credits.szCreditName[0] == '#' )
  320. {
  321. g_pVGuiLocalize->ConstructString( Credits.szLyricLine, sizeof(Credits.szLyricLine), g_pVGuiLocalize->Find(Credits.szCreditName), 0 );
  322. if (bNextOnSameLine)
  323. {
  324. iXOffsetTemp+=GetStringPixelWidth( Credits.szLyricLine, m_hTFont );
  325. }
  326. }
  327. else
  328. {
  329. g_pVGuiLocalize->ConvertANSIToUnicode( Credits.szCreditName, Credits.szLyricLine, sizeof( Credits.szLyricLine ) );
  330. if (bNextOnSameLine)
  331. {
  332. iXOffsetTemp+=GetStringPixelWidth( Credits.szLyricLine, m_hTFont );
  333. }
  334. }
  335. Credits.flTimeStart = flTotalTime;
  336. flTotalTime+=Credits.flTimeInit;
  337. Credits.flTimeEnd = flTotalTime;
  338. m_LyricsList.AddToTail( Credits );
  339. pKVNames = pKVNames->GetNextKey();
  340. }
  341. g_iPortalCreditsPixelHeight = iHeight;
  342. }
  343. void CHudPortalCredits::ReadAscii( KeyValues *pKeyValue )
  344. {
  345. if ( pKeyValue == NULL )
  346. {
  347. Assert( !"CHudPortalCredits couldn't be initialized!" );
  348. return;
  349. }
  350. KeyValues *pKVNames = pKeyValue->GetFirstSubKey();
  351. char *cTmp;
  352. while ( pKVNames )
  353. {
  354. portalcreditname_t Credits;
  355. //Q_strcpy( Credits.szCreditName, pKVNames->GetName());
  356. //Q_strcpy( Credits.szFontName, pKeyValue->GetString( Credits.szCreditName, "Default" ) );
  357. V_strcpy_safe( Credits.szFontName, pKVNames->GetName() );
  358. V_strcpy_safe( Credits.szCreditName, pKeyValue->GetString( Credits.szFontName, "Default" ) );
  359. Credits.flTimeInit = 0.00;
  360. cTmp=Q_strstr(Credits.szCreditName,"[");
  361. if (!(cTmp == NULL)) {
  362. Credits.flTimeInit = Q_atof(cTmp+1);
  363. }
  364. cTmp=Q_strstr(Credits.szCreditName,"]");
  365. if (!(cTmp == NULL)) {
  366. Q_strcpy(Credits.szCreditName,cTmp+1);
  367. }
  368. m_AsciiList.AddToTail( Credits );
  369. pKVNames = pKVNames->GetNextKey();
  370. }
  371. }
  372. void CHudPortalCredits::ReadParams( KeyValues *pKeyValue )
  373. {
  374. if ( pKeyValue == NULL )
  375. {
  376. Assert( !"CHudPortalCredits couldn't be initialized!" );
  377. return;
  378. }
  379. m_flScrollTime = pKeyValue->GetFloat( "scrolltime", 57 );
  380. m_flSeparation = pKeyValue->GetFloat( "separation", 5 );
  381. m_flFadeInTime = pKeyValue->GetFloat( "fadeintime", 1 );
  382. m_flFadeHoldTime = pKeyValue->GetFloat( "fadeholdtime", 3 );
  383. m_flFadeOutTime = pKeyValue->GetFloat( "fadeouttime", 2 );
  384. m_flNextStartTime = pKeyValue->GetFloat( "nextfadetime", 2 );
  385. m_flPauseBetweenWaves = pKeyValue->GetFloat( "pausebetweenwaves", 2 );
  386. m_flCursorBlinkTime = pKeyValue->GetFloat( "cursorblinktime", 0.3 );
  387. m_flLogoTimeMod = pKeyValue->GetFloat( "logotime", 2 );
  388. m_flScrollCreditsStart = pKeyValue->GetFloat( "scrollcreditsstart", 6 );
  389. m_flSongStartTime = pKeyValue->GetFloat( "songstarttime", 6.85 );
  390. m_iScreenXOffset = pKeyValue->GetInt( "screenxoffset", 0 );
  391. m_iScreenYOffset = pKeyValue->GetInt( "screenyoffset", 0 );
  392. m_iScreenWidthAdjustment = pKeyValue->GetInt( "screenwidthadjustment", 0 );
  393. m_iScreenHeightAdjustment = pKeyValue->GetInt( "screenheightadjustment", 0 );
  394. V_strcpy_safe( m_szAsciiArtFont, pKeyValue->GetString( "asciiartfont", "Default" ) );
  395. m_iAAScreenXOffset = pKeyValue->GetInt( "aascreenxoffset", 0 );
  396. m_iAAScreenYOffset = pKeyValue->GetInt( "aascreenyoffset", 0 );
  397. m_iAASeparation = pKeyValue->GetInt( "aaseparation", 0 );
  398. m_flX = pKeyValue->GetFloat( "posx", 2 );
  399. m_flY = pKeyValue->GetFloat( "posy", 2 );
  400. m_cColor = pKeyValue->GetColor( "color" );
  401. }
  402. int CHudPortalCredits::GetStringPixelWidth( wchar_t *pString, vgui::HFont hFont )
  403. {
  404. int iLength = 0;
  405. for ( wchar_t *wch = pString; *wch != 0; wch++ )
  406. {
  407. iLength += surface()->GetCharacterWidth( hFont, *wch );
  408. }
  409. return iLength;
  410. }
  411. int CHudPortalCredits::GetPixelWidth( char *pString, vgui::HFont hFont )
  412. {
  413. int iLength = 0;
  414. int iStrLen = Q_strlen(pString);
  415. for ( int i=0; i<iStrLen; i++ )
  416. {
  417. iLength += surface()->GetCharacterWidth( hFont, pString[i] );
  418. }
  419. return iLength;
  420. }
  421. void CHudPortalCredits::DrawOutroCreditsName( void )
  422. {
  423. if ( m_CreditsList.Count() == 0 )
  424. return;
  425. // fill the screen
  426. int iWidth, iTall;
  427. GetHudSize(iWidth, iTall);
  428. iWidth = static_cast<int>( static_cast<float>(iTall) * (4.0f/3.0f) );
  429. SetSize( iWidth, iTall );
  430. for ( int i = 0; i < m_CreditsList.Count(); i++ )
  431. {
  432. portalcreditname_t *pCredit = &m_CreditsList[i];
  433. if ( pCredit == NULL )
  434. continue;
  435. vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
  436. vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( pCredit->szFontName, true );
  437. int iFontTall = surface()->GetFontTall ( m_hTFont );
  438. if ( pCredit->flYPos < -iFontTall || pCredit->flYPos > iTall )
  439. {
  440. pCredit->bActive = false;
  441. }
  442. else
  443. {
  444. pCredit->bActive = true;
  445. }
  446. Color cColor = m_TextColor;
  447. //HACKHACK
  448. //Last one stays on screen and fades out
  449. if ( i == m_CreditsList.Count()-1 )
  450. {
  451. if ( m_bLastOneInPlace == false )
  452. {
  453. pCredit->flYPos -= gpGlobals->frametime * ( (float)g_iPortalCreditsPixelHeight / m_flScrollTime );
  454. if ( (int)pCredit->flYPos + ( iFontTall / 2 ) <= iTall / 2 )
  455. {
  456. m_bLastOneInPlace = true;
  457. m_flFadeTime = gpGlobals->curtime + 10.0f;
  458. }
  459. }
  460. else
  461. {
  462. if ( m_flFadeTime <= gpGlobals->curtime )
  463. {
  464. if ( m_Alpha > 0 )
  465. {
  466. m_Alpha -= gpGlobals->frametime * ( m_flScrollTime * 2 );
  467. if ( m_Alpha <= 0 )
  468. {
  469. pCredit->bActive = false;
  470. engine->ClientCmd( "creditsdone" );
  471. }
  472. }
  473. }
  474. cColor[3] = MAX( 0, m_Alpha );
  475. }
  476. }
  477. else
  478. {
  479. pCredit->flYPos -= gpGlobals->frametime * ( (float)g_iPortalCreditsPixelHeight / m_flScrollTime );
  480. }
  481. if ( pCredit->bActive == false )
  482. continue;
  483. surface()->DrawSetTextFont( m_hTFont );
  484. surface()->DrawSetTextColor( cColor[0], cColor[1], cColor[2], cColor[3] );
  485. wchar_t unicode[256];
  486. if ( pCredit->szCreditName[0] == '#' )
  487. {
  488. g_pVGuiLocalize->ConstructString( unicode, sizeof(unicode), g_pVGuiLocalize->Find(pCredit->szCreditName), 0 );
  489. }
  490. else
  491. {
  492. g_pVGuiLocalize->ConvertANSIToUnicode( pCredit->szCreditName, unicode, sizeof( unicode ) );
  493. }
  494. int iStringWidth = GetStringPixelWidth( unicode, m_hTFont );
  495. surface()->DrawSetTextPos( ( iWidth / 2 ) - ( iStringWidth / 2 ), pCredit->flYPos );
  496. surface()->DrawUnicodeString( unicode );
  497. }
  498. }
  499. void CHudPortalCredits::DrawPortalOutroCreditsName( void )
  500. {
  501. if ( m_CreditsList.Count() == 0 )
  502. return;
  503. static int iCounter=0;
  504. static bool bCursor = false;
  505. // fill the screen
  506. int iWidth, iTall;
  507. GetHudSize(iWidth, iTall);
  508. iWidth = static_cast<int>( static_cast<float>(iTall) * (4.0f/3.0f) );
  509. iWidth += m_iScreenWidthAdjustment;
  510. iTall += m_iScreenHeightAdjustment;
  511. SetSize( iWidth+m_iScreenXOffset, iTall+m_iScreenYOffset );
  512. if (gpGlobals->curtime - m_flLastPaintTime > 0.05)
  513. {
  514. m_flLastPaintTime = gpGlobals->curtime;
  515. iCounter += 100;
  516. if (iCounter> (int)m_flScrollTime && m_iYOffset<(m_CreditsList.Count()-1))
  517. {
  518. bCursor = !bCursor;
  519. iCounter = 0;
  520. m_iXOffset += 1;
  521. if (m_iXOffset > Q_strlen(m_CreditsList[m_iYOffset].szCreditName) && m_iYOffset<(m_CreditsList.Count()-1))
  522. {
  523. m_iXOffset = 1;
  524. m_iYOffset += 1;
  525. vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
  526. vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( m_CreditsList[m_iYOffset].szFontName, true );
  527. int iFontTall = surface()->GetFontTall ( m_hTFont )+ m_flSeparation;
  528. if ( m_CreditsList[m_iYOffset].flYPos +iFontTall > iTall )
  529. {
  530. for ( int i = 0; i < m_CreditsList.Count(); i++ )
  531. {
  532. portalcreditname_t *pCredit = &m_CreditsList[i];
  533. if ( pCredit == NULL )
  534. continue;
  535. vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
  536. vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( pCredit->szFontName, true );
  537. int iFontTall = surface()->GetFontTall ( m_hTFont )+ m_flSeparation;
  538. pCredit->flYPos -= iFontTall;
  539. }
  540. }
  541. }
  542. }
  543. }
  544. for ( int i = 0; i < m_CreditsList.Count(); i++ )
  545. {
  546. portalcreditname_t *pCredit = &m_CreditsList[i];
  547. if ( pCredit == NULL )
  548. continue;
  549. vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
  550. vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( pCredit->szFontName, true );
  551. int iFontTall = surface()->GetFontTall ( m_hTFont );
  552. if ( pCredit->flYPos < -iFontTall || pCredit->flYPos > iTall )
  553. {
  554. pCredit->bActive = false;
  555. }
  556. else
  557. {
  558. if (i <= m_iYOffset)
  559. pCredit->bActive = true;
  560. }
  561. Color cColor = m_TextColor;
  562. //HACKHACK
  563. //Last one stays on screen and fades out
  564. if ( i == m_CreditsList.Count()-1 )
  565. {
  566. if ( m_bLastOneInPlace == false )
  567. {
  568. pCredit->flYPos -= gpGlobals->frametime * ( (float)g_iPortalCreditsPixelHeight / m_flScrollTime );
  569. if ( (int)pCredit->flYPos + ( iFontTall / 2 ) <= iTall / 2 )
  570. {
  571. m_bLastOneInPlace = true;
  572. m_flFadeTime = gpGlobals->curtime + 10.0f;
  573. }
  574. }
  575. else
  576. {
  577. if ( m_flFadeTime <= gpGlobals->curtime )
  578. {
  579. if ( m_Alpha > 0 )
  580. {
  581. m_Alpha -= gpGlobals->frametime * ( m_flScrollTime * 2 );
  582. if ( m_Alpha <= 0 )
  583. {
  584. pCredit->bActive = false;
  585. engine->ClientCmd( "creditsdone" );
  586. }
  587. }
  588. }
  589. cColor[3] = MAX( 0, m_Alpha );
  590. }
  591. }
  592. else
  593. {
  594. //m_iYOffset += (int) (gpGlobals->frametime * ( (float)g_iPortalCreditsPixelHeight / m_flScrollTime ));
  595. //m_iYOffset += (int) (gpGlobals->frametime * ( (float)g_iPortalCreditsPixelHeight / 1000 ));
  596. //iCounter += 1;
  597. //pCredit->flYPos -= gpGlobals->frametime * ( (float)g_iPortalCreditsPixelHeight / m_flScrollTime );
  598. }
  599. if ( pCredit->bActive == false )
  600. continue;
  601. surface()->DrawSetTextFont( m_hTFont );
  602. surface()->DrawSetTextColor( cColor[0], cColor[1], cColor[2], cColor[3] );
  603. wchar_t unicode[256];
  604. char tmpstr[256];
  605. if (m_iYOffset == i)
  606. {
  607. char tmpstr2[256];
  608. Q_strncpy( tmpstr2, pCredit->szCreditName, m_iXOffset );
  609. if (bCursor)
  610. Q_snprintf( tmpstr, 256, "%s_",tmpstr2);
  611. else
  612. Q_snprintf( tmpstr, 256, "%s",tmpstr2);
  613. }
  614. else
  615. {
  616. Q_strncpy( tmpstr, pCredit->szCreditName, Q_strlen( pCredit->szCreditName )+1 );
  617. }
  618. if ( tmpstr[0] == '#' )
  619. {
  620. g_pVGuiLocalize->ConstructString( unicode, sizeof(unicode), g_pVGuiLocalize->Find(tmpstr), 0 );
  621. }
  622. else
  623. {
  624. g_pVGuiLocalize->ConvertANSIToUnicode( tmpstr, unicode, sizeof( unicode ) );
  625. }
  626. // int iStringWidth = GetStringPixelWidth( unicode, m_hTFont );
  627. // surface()->DrawSetTextPos( ( iWidth / 2 ) - ( iStringWidth / 2 ), pCredit->flYPos );
  628. surface()->DrawSetTextColor( m_cColor[0], m_cColor[1], m_cColor[2], 255 );
  629. surface()->DrawSetTextPos( 20+m_iScreenXOffset, pCredit->flYPos + m_iScreenYOffset );
  630. surface()->DrawUnicodeString( unicode );
  631. }
  632. }
  633. void CHudPortalCredits::DrawPortalAsciiArt( void )
  634. {
  635. if ( m_AsciiList.Count() == 0 )
  636. return;
  637. if (m_iCurrentAsciiArt == 0)
  638. return;
  639. //get the screen stats
  640. int iWidth, iTall;
  641. GetHudSize(iWidth, iTall);
  642. iWidth = static_cast<int>( static_cast<float>(iTall) * (4.0f/3.0f) );
  643. iWidth += m_iScreenWidthAdjustment;
  644. iTall += m_iScreenHeightAdjustment;
  645. SetSize( iWidth+m_iScreenXOffset, iTall+m_iScreenYOffset );
  646. int ift = 0;
  647. for ( int i = 0; i < 20; i++ )
  648. {
  649. portalcreditname_t *pCredit = &m_AsciiList[((m_iCurrentAsciiArt - 1) *20)+i];
  650. if ( pCredit == NULL )
  651. continue;
  652. vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
  653. //vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( pCredit->szFontName, true );
  654. vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( m_szAsciiArtFont, true );
  655. int iFontTall = surface()->GetFontTall ( m_hTFont );
  656. if (ift == 0) {
  657. ift = iFontTall;
  658. ift+=m_iAASeparation;
  659. }
  660. iFontTall+= (int) m_flSeparation;
  661. Color cColor = m_TextColor;
  662. surface()->DrawSetTextFont( m_hTFont );
  663. surface()->DrawSetTextColor( cColor[0], cColor[1], cColor[2], cColor[3] );
  664. wchar_t unicode[256];
  665. char tmpstr[256];
  666. Q_strncpy( tmpstr, pCredit->szCreditName, Q_strlen( pCredit->szCreditName )+1 );
  667. //Q_strncpy( tmpstr, pCredit->szFontName, Q_strlen( pCredit->szFontName )+1 );
  668. //if ( tmpstr[0] == '#' )
  669. //{
  670. // g_pVGuiLocalize->ConstructString( unicode, sizeof(unicode), g_pVGuiLocalize->Find(tmpstr), 0 );
  671. //}
  672. //else
  673. //{
  674. g_pVGuiLocalize->ConvertANSIToUnicode( tmpstr, unicode, sizeof( unicode ) );
  675. //}
  676. surface()->DrawSetTextColor( m_cColor[0], m_cColor[1], m_cColor[2], cColor[3] );
  677. //surface()->DrawSetTextPos( 20+(iWidth/2), 10+(iTall/2)+(i*iFontTall) );
  678. surface()->DrawSetTextPos( 20+(iWidth/2)+m_iAAScreenXOffset, 10+(iTall/2)+m_iAAScreenYOffset+(i*ift) );
  679. surface()->DrawUnicodeString( unicode );
  680. }
  681. }
  682. void CHudPortalCredits::DrawPortalOutroCreditsLyrics( void )
  683. {
  684. if ( m_LyricsList.Count() == 0 )
  685. return;
  686. static bool bCursor = false;
  687. static int iLastNameY = 0;
  688. if (m_flLyricsStartTime == -1) m_flLyricsStartTime = gpGlobals->curtime;
  689. //get the screen stats
  690. int iWidth, iTall;
  691. GetHudSize(iWidth, iTall);
  692. iWidth = static_cast<int>( static_cast<float>(iTall) * (4.0f/3.0f) );
  693. iWidth += m_iScreenWidthAdjustment;
  694. iTall += m_iScreenHeightAdjustment;
  695. SetSize( iWidth+m_iScreenXOffset, iTall+m_iScreenYOffset );
  696. if (gpGlobals->curtime - m_flLastBlinkTime > m_flCursorBlinkTime)
  697. {
  698. bCursor = !bCursor;
  699. m_flLastBlinkTime = gpGlobals->curtime;
  700. }
  701. float flCurTime = gpGlobals->curtime - m_flLyricsStartTime;
  702. if (m_bStartSong && flCurTime>= m_flSongStartTime)
  703. {
  704. surface()->PlaySound( "music/portal_still_alive.mp3" );
  705. m_bStartSong=false;
  706. //engine->ClientCmd( "play music/portal_still_alive.mp3" );
  707. }
  708. //Draw Lyrics
  709. bool bBorders = false;
  710. for ( int i = 0; i < m_LyricsList.Count(); i++ )
  711. {
  712. portalcreditname_t *pCredit = &m_LyricsList[i];
  713. if ( pCredit == NULL )
  714. continue;
  715. if (pCredit->flTimeStart > flCurTime) break;
  716. if (pCredit->flTimeStart <= flCurTime && pCredit->flTimeEnd > flCurTime)
  717. {
  718. m_iYOffset = i;
  719. if (pCredit->bReset)
  720. {
  721. m_iCurrentLowY = i;
  722. }
  723. m_iXOffset = (int) (((flCurTime-pCredit->flTimeStart) / pCredit->flTimeInit)*Q_wcslen(pCredit->szLyricLine))+1;
  724. if ( m_iXOffset<1 )
  725. m_iXOffset = 1;
  726. else if ( m_iXOffset>Q_wcslen(pCredit->szLyricLine) )
  727. m_iXOffset = Q_wcslen(pCredit->szLyricLine);
  728. }
  729. vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
  730. vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( pCredit->szFontName, true );
  731. int iFontTall = surface()->GetFontTall ( m_hTFont )+ (int) m_flSeparation;
  732. if ( pCredit->flYPos < -iFontTall || pCredit->flYPos > iTall || i<m_iCurrentLowY)
  733. {
  734. pCredit->bActive = false;
  735. }
  736. else
  737. {
  738. if (i <= m_iYOffset)
  739. pCredit->bActive = true;
  740. }
  741. Color cColor = m_TextColor;
  742. if ( pCredit->bActive == false )
  743. continue;
  744. if (pCredit->iAsciiIndex>0)
  745. {
  746. m_iCurrentAsciiArt = pCredit->iAsciiIndex;
  747. }
  748. surface()->DrawSetTextFont( m_hTFont );
  749. surface()->DrawSetTextColor( cColor[0], cColor[1], cColor[2], cColor[3] );
  750. if (!bBorders)
  751. {
  752. wchar_t bunicode[512];
  753. wchar_t bVunicode[2];
  754. wchar_t bVunicode2[3];
  755. int iBorderEndX = GetPixelWidth( m_szBorderH, m_hTFont );
  756. g_pVGuiLocalize->ConvertANSIToUnicode( m_szBorderH, bunicode, sizeof( bunicode ) );
  757. g_pVGuiLocalize->ConvertANSIToUnicode( "|", bVunicode, sizeof( bVunicode ) );
  758. g_pVGuiLocalize->ConvertANSIToUnicode( "||", bVunicode2, sizeof( bVunicode2 ) );
  759. int iBorderPipeWidth = GetPixelWidth( "||", m_hTFont);
  760. surface()->DrawSetTextColor( m_cColor[0], m_cColor[1], m_cColor[2], cColor[3] );
  761. surface()->DrawSetTextPos( 5+m_iScreenXOffset, 10+m_iScreenYOffset);
  762. surface()->DrawUnicodeString( bunicode );
  763. surface()->DrawSetTextPos( (iWidth/2)+m_iScreenXOffset, 10+m_iScreenYOffset);
  764. surface()->DrawUnicodeString( bunicode );
  765. surface()->DrawSetTextPos( 5+m_iScreenXOffset, (iTall - (iFontTall*2))+m_iScreenYOffset);
  766. surface()->DrawUnicodeString( bunicode );
  767. surface()->DrawSetTextPos( (iWidth/2)+m_iScreenXOffset, (iTall/2)+m_iScreenYOffset);
  768. surface()->DrawUnicodeString( bunicode );
  769. int iBorderY = 10+iFontTall;
  770. while (iBorderY < (iTall - (iFontTall*3)))
  771. {
  772. surface()->DrawSetTextPos( 5+m_iScreenXOffset, iBorderY+m_iScreenYOffset);
  773. surface()->DrawUnicodeString( bVunicode );
  774. surface()->DrawSetTextPos( iBorderEndX+m_iScreenXOffset, iBorderY+m_iScreenYOffset);
  775. if (iBorderY<(iTall/2))
  776. {
  777. surface()->DrawUnicodeString( bVunicode2 );
  778. surface()->DrawSetTextPos( (iWidth-iBorderPipeWidth)+m_iScreenXOffset, iBorderY+m_iScreenYOffset);
  779. surface()->DrawUnicodeString( bVunicode );
  780. }
  781. else
  782. {
  783. surface()->DrawUnicodeString( bVunicode );
  784. }
  785. iBorderY+=iFontTall;
  786. }
  787. bBorders = true;
  788. }
  789. wchar_t tmpstr[256];
  790. memset( tmpstr, 0, sizeof(tmpstr));
  791. if (m_iYOffset == i)
  792. {
  793. Q_wcsncpy( tmpstr, pCredit->szLyricLine, m_iXOffset * sizeof( wchar_t ) );
  794. if (bCursor)
  795. tmpstr[m_iXOffset - 1] = '_';
  796. }
  797. else
  798. {
  799. Q_wcsncpy( tmpstr, pCredit->szLyricLine, (Q_wcslen( pCredit->szLyricLine ) + 1) * sizeof( wchar_t ));
  800. }
  801. surface()->DrawSetTextColor( m_cColor[0], m_cColor[1], m_cColor[2], cColor[3] );
  802. surface()->DrawSetTextPos( 20+pCredit->iXOffset+m_iScreenXOffset, 30+pCredit->flYPos+m_iScreenYOffset );
  803. surface()->DrawUnicodeString( tmpstr );
  804. }
  805. DrawPortalAsciiArt();
  806. //Draw Credits
  807. int iCreditsListCount = m_CreditsList.Count();
  808. for ( int i = iCreditsListCount-1; i >=0; i-- )
  809. {
  810. portalcreditname_t *pCredit = &m_CreditsList[i];
  811. if ( pCredit == NULL )
  812. continue;
  813. if (pCredit->flYPos < 0) break;
  814. vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
  815. vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( pCredit->szFontName, true );
  816. int iFontTall = surface()->GetFontTall ( m_hTFont );
  817. if (pCredit->flTimeStart <= flCurTime && pCredit->flTimeEnd > flCurTime)
  818. {
  819. if (iLastNameY!=i)
  820. {
  821. int iYDelta = iFontTall + (int) m_flSeparation;
  822. for (int j = 0; j <i; j++)
  823. {
  824. m_CreditsList[j].flYPos -= (float) iYDelta;
  825. }
  826. m_CreditsList[i].flYPos = (iTall/2) - iYDelta;
  827. iLastNameY=i;
  828. }
  829. m_iYOffsetNames = i;
  830. m_iXOffsetNames = (int) (((flCurTime-pCredit->flTimeStart) / pCredit->flTimeInit)*Q_strlen(pCredit->szCreditName))+1;
  831. if (m_iXOffsetNames<1) m_iXOffsetNames = 1;
  832. else if (m_iXOffsetNames>Q_strlen(pCredit->szCreditName) ) m_iXOffsetNames = Q_strlen(pCredit->szCreditName);
  833. }
  834. //if ( pCredit->flYPos < -iFontTall || pCredit->flYPos > iTall)
  835. if ( pCredit->flYPos < 20 || pCredit->flYPos > (iTall/2))
  836. {
  837. pCredit->bActive = false;
  838. }
  839. else
  840. {
  841. if (i <= m_iYOffsetNames)
  842. pCredit->bActive = true;
  843. }
  844. Color cColor = m_TextColor;
  845. if ( pCredit->bActive == false )
  846. continue;
  847. surface()->DrawSetTextFont( m_hTFont );
  848. surface()->DrawSetTextColor( cColor[0], cColor[1], cColor[2], cColor[3] );
  849. wchar_t unicode[256];
  850. char tmpstr[256];
  851. if (m_iYOffsetNames == i)
  852. {
  853. char tmpstr2[256];
  854. Q_strncpy( tmpstr2, pCredit->szCreditName, m_iXOffsetNames );
  855. if (!bCursor)
  856. Q_snprintf( tmpstr, 256, "%s_",tmpstr2);
  857. else
  858. Q_snprintf( tmpstr, 256, "%s",tmpstr2);
  859. }
  860. else
  861. {
  862. Q_strncpy( tmpstr, pCredit->szCreditName, Q_strlen( pCredit->szCreditName )+1 );
  863. }
  864. if ( tmpstr[0] == '#' )
  865. {
  866. g_pVGuiLocalize->ConstructString( unicode, sizeof(unicode), g_pVGuiLocalize->Find(tmpstr), 0 );
  867. }
  868. else
  869. {
  870. g_pVGuiLocalize->ConvertANSIToUnicode( tmpstr, unicode, sizeof( unicode ) );
  871. }
  872. // int iStringWidth = GetStringPixelWidth( unicode, m_hTFont );
  873. // surface()->DrawSetTextPos( ( iWidth / 2 ) - ( iStringWidth / 2 ), pCredit->flYPos );
  874. surface()->DrawSetTextColor( m_cColor[0], m_cColor[1], m_cColor[2], cColor[3] );
  875. surface()->DrawSetTextPos( (iWidth/2)+10+m_iScreenXOffset, pCredit->flYPos+m_iScreenYOffset );
  876. surface()->DrawUnicodeString( unicode );
  877. }
  878. }
  879. void CHudPortalCredits::DrawLogo( void )
  880. {
  881. if( m_iLogoState == LOGO_FADEOFF )
  882. {
  883. SetActive( false );
  884. return;
  885. }
  886. switch( m_iLogoState )
  887. {
  888. case LOGO_FADEIN:
  889. {
  890. float flDeltaTime = ( m_flFadeTime - gpGlobals->curtime );
  891. m_Alpha = MAX( 0, RemapValClamped( flDeltaTime, 5.0f, 0, -128, 255 ) );
  892. if ( flDeltaTime <= 0.0f )
  893. {
  894. m_iLogoState = LOGO_FADEHOLD;
  895. m_flFadeTime = gpGlobals->curtime + m_flLogoDesiredLength;
  896. }
  897. break;
  898. }
  899. case LOGO_FADEHOLD:
  900. {
  901. if ( m_flFadeTime <= gpGlobals->curtime )
  902. {
  903. m_iLogoState = LOGO_FADEOUT;
  904. m_flFadeTime = gpGlobals->curtime + 2.0f;
  905. }
  906. break;
  907. }
  908. case LOGO_FADEOUT:
  909. {
  910. float flDeltaTime = ( m_flFadeTime - gpGlobals->curtime );
  911. m_Alpha = RemapValClamped( flDeltaTime, 0.0f, 2.0f, 0, 255 );
  912. if ( flDeltaTime <= 0.0f )
  913. {
  914. m_iLogoState = LOGO_FADEOFF;
  915. SetActive( false );
  916. }
  917. break;
  918. }
  919. }
  920. // fill the screen
  921. int iWidth, iTall;
  922. GetHudSize(iWidth, iTall);
  923. iWidth = static_cast<int>( static_cast<float>(iTall) * (4.0f/3.0f) );
  924. iWidth += m_iScreenWidthAdjustment;
  925. iTall += m_iScreenHeightAdjustment;
  926. SetSize( iWidth, iTall );
  927. char szLogoFont[64];
  928. if ( IsXbox() )
  929. {
  930. Q_snprintf( szLogoFont, sizeof( szLogoFont ), "WeaponIcons_Small" );
  931. }
  932. else if ( hl2_episodic.GetBool() )
  933. {
  934. Q_snprintf( szLogoFont, sizeof( szLogoFont ), "ClientTitleFont" );
  935. }
  936. else
  937. {
  938. Q_snprintf( szLogoFont, sizeof( szLogoFont ), "WeaponIcons" );
  939. }
  940. vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
  941. vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( szLogoFont );
  942. int iFontTall = surface()->GetFontTall ( m_hTFont );
  943. Color cColor = m_TextColor;
  944. cColor[3] = m_Alpha;
  945. surface()->DrawSetTextFont( m_hTFont );
  946. surface()->DrawSetTextColor( cColor[0], cColor[1], cColor[2], cColor[3] );
  947. wchar_t unicode[256];
  948. g_pVGuiLocalize->ConvertANSIToUnicode( "HALF-LIFE'", unicode, sizeof( unicode ) );
  949. int iStringWidth = GetStringPixelWidth( unicode, m_hTFont );
  950. surface()->DrawSetTextPos( ( iWidth / 2 ) - ( iStringWidth / 2 ), ( iTall / 2 ) - ( iFontTall / 2 ) );
  951. surface()->DrawUnicodeString( unicode );
  952. //Adrian: This should really be exposed.
  953. if ( hl2_episodic.GetBool() )
  954. {
  955. g_pVGuiLocalize->ConvertANSIToUnicode( "== episode one==", unicode, sizeof( unicode ) );
  956. iStringWidth = GetStringPixelWidth( unicode, m_hTFont );
  957. surface()->DrawSetTextPos( ( iWidth / 2 ) - ( iStringWidth / 2 ), ( iTall / 2 ) + ( iFontTall / 2 ));
  958. surface()->DrawUnicodeString( unicode );
  959. }
  960. }
  961. //-----------------------------------------------------------------------------
  962. // Purpose:
  963. //-----------------------------------------------------------------------------
  964. float CHudPortalCredits::FadeBlend( float fadein, float fadeout, float hold, float localTime )
  965. {
  966. float fadeTime = fadein + hold;
  967. float fadeBlend;
  968. if ( localTime < 0 )
  969. return 0;
  970. if ( localTime < fadein )
  971. {
  972. fadeBlend = 1 - ((fadein - localTime) / fadein);
  973. }
  974. else if ( localTime > fadeTime )
  975. {
  976. if ( fadeout > 0 )
  977. fadeBlend = 1 - ((localTime - fadeTime) / fadeout);
  978. else
  979. fadeBlend = 0;
  980. }
  981. else
  982. fadeBlend = 1;
  983. if ( fadeBlend < 0 )
  984. fadeBlend = 0;
  985. return fadeBlend;
  986. }
  987. void CHudPortalCredits::DrawIntroCreditsName( void )
  988. {
  989. if ( m_CreditsList.Count() == 0 )
  990. return;
  991. // fill the screen
  992. int iWidth, iTall;
  993. GetHudSize(iWidth, iTall);
  994. iWidth = static_cast<int>( static_cast<float>(iTall) * (4.0f/3.0f) );
  995. SetSize( iWidth, iTall );
  996. for ( int i = 0; i < m_CreditsList.Count(); i++ )
  997. {
  998. portalcreditname_t *pCredit = &m_CreditsList[i];
  999. if ( pCredit == NULL )
  1000. continue;
  1001. if ( pCredit->bActive == false )
  1002. continue;
  1003. vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
  1004. vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( pCredit->szFontName );
  1005. float localTime = gpGlobals->curtime - pCredit->flTimeStart;
  1006. surface()->DrawSetTextFont( m_hTFont );
  1007. surface()->DrawSetTextColor( m_cColor[0], m_cColor[1], m_cColor[2], FadeBlend( m_flFadeInTime, m_flFadeOutTime, m_flFadeHoldTime + pCredit->flTimeAdd, localTime ) * m_cColor[3] );
  1008. wchar_t unicode[256];
  1009. g_pVGuiLocalize->ConvertANSIToUnicode( pCredit->szCreditName, unicode, sizeof( unicode ) );
  1010. surface()->DrawSetTextPos( XRES( pCredit->flXPos ), YRES( pCredit->flYPos ) );
  1011. surface()->DrawUnicodeString( unicode );
  1012. if ( m_flLogoTime > gpGlobals->curtime )
  1013. continue;
  1014. if ( pCredit->flTime - m_flNextStartTime <= gpGlobals->curtime )
  1015. {
  1016. if ( m_CreditsList.IsValidIndex( i + 3 ) )
  1017. {
  1018. portalcreditname_t *pNextCredits = &m_CreditsList[i + 3];
  1019. if ( pNextCredits && pNextCredits->flTime == 0.0f )
  1020. {
  1021. pNextCredits->bActive = true;
  1022. if ( i < 3 )
  1023. {
  1024. pNextCredits->flTimeAdd = ( i + 1.0f );
  1025. pNextCredits->flTime = gpGlobals->curtime + m_flFadeInTime + m_flFadeOutTime + m_flFadeHoldTime + pNextCredits->flTimeAdd;
  1026. }
  1027. else
  1028. {
  1029. pNextCredits->flTimeAdd = m_flPauseBetweenWaves;
  1030. pNextCredits->flTime = gpGlobals->curtime + m_flFadeInTime + m_flFadeOutTime + m_flFadeHoldTime + pNextCredits->flTimeAdd;
  1031. }
  1032. pNextCredits->flTimeStart = gpGlobals->curtime;
  1033. pNextCredits->iSlot = pCredit->iSlot;
  1034. }
  1035. }
  1036. }
  1037. if ( pCredit->flTime <= gpGlobals->curtime )
  1038. {
  1039. pCredit->bActive = false;
  1040. if ( i == m_CreditsList.Count()-1 )
  1041. {
  1042. Clear();
  1043. }
  1044. }
  1045. }
  1046. }
  1047. void CHudPortalCredits::ApplySchemeSettings( IScheme *pScheme )
  1048. {
  1049. BaseClass::ApplySchemeSettings( pScheme );
  1050. SetVisible( ShouldDraw() );
  1051. SetBgColor( Color(0, 0, 0, 0) );
  1052. }
  1053. void CHudPortalCredits::Paint()
  1054. {
  1055. if ( m_iCreditsType == CREDITS_LOGO )
  1056. {
  1057. DrawLogo();
  1058. }
  1059. else if ( m_iCreditsType == CREDITS_INTRO )
  1060. {
  1061. DrawIntroCreditsName();
  1062. }
  1063. else if ( m_iCreditsType == CREDITS_OUTRO )
  1064. {
  1065. DrawOutroCreditsName();
  1066. }
  1067. else if ( m_iCreditsType == CREDITS_OUTRO_PORTAL )
  1068. {
  1069. //DrawPortalOutroCreditsName();
  1070. DrawPortalOutroCreditsLyrics();
  1071. }
  1072. }
  1073. void CHudPortalCredits::PrepareLogo( float flTime )
  1074. {
  1075. m_Alpha = 0;
  1076. m_flLogoDesiredLength = flTime;
  1077. m_flFadeTime = gpGlobals->curtime + 5.0f;
  1078. m_iLogoState = LOGO_FADEIN;
  1079. SetActive( true );
  1080. }
  1081. void CHudPortalCredits::PrepareOutroCredits( void )
  1082. {
  1083. PrepareCredits( "OutroCreditsNames" );
  1084. if ( m_CreditsList.Count() == 0 )
  1085. return;
  1086. // fill the screen
  1087. int iWidth, iTall;
  1088. GetHudSize(iWidth, iTall);
  1089. iWidth = static_cast<int>( static_cast<float>(iTall) * (4.0f/3.0f) );
  1090. SetSize( iWidth, iTall );
  1091. int iHeight = iTall;
  1092. for ( int i = 0; i < m_CreditsList.Count(); i++ )
  1093. {
  1094. portalcreditname_t *pCredit = &m_CreditsList[i];
  1095. if ( pCredit == NULL )
  1096. continue;
  1097. vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
  1098. vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( pCredit->szFontName, true );
  1099. pCredit->flYPos = iHeight;
  1100. pCredit->bActive = false;
  1101. iHeight += surface()->GetFontTall ( m_hTFont ) + m_flSeparation;
  1102. }
  1103. SetActive( true );
  1104. g_iPortalCreditsPixelHeight = iHeight;
  1105. }
  1106. void CHudPortalCredits::PreparePortalOutroCredits( void )
  1107. {
  1108. m_iCurrentLowY = 0;
  1109. m_bStartSong = true;
  1110. m_flLyricsStartTime = -1;
  1111. m_iCurrentAsciiArt = 0;
  1112. PrepareCredits( "OutroCreditsNames" );
  1113. if ( m_CreditsList.Count() == 0 )
  1114. return;
  1115. // fill the screen
  1116. int iWidth, iTall;
  1117. GetHudSize(iWidth, iTall);
  1118. iWidth = static_cast<int>( static_cast<float>(iTall) * (4.0f/3.0f) );
  1119. iWidth += m_iScreenWidthAdjustment;
  1120. iTall += m_iScreenHeightAdjustment;
  1121. SetSize( iWidth+m_iScreenXOffset, iTall +m_iScreenYOffset );
  1122. m_iYOffset = 0;
  1123. m_iXOffset = 1;
  1124. m_iYOffsetNames = 0;
  1125. m_iXOffsetNames = 1;
  1126. //int iHeight = iTall;
  1127. int iHeight = -1;
  1128. int iTotalNameLen = 0;
  1129. //Prepare Credit Names
  1130. for ( int i = 0; i < m_CreditsList.Count(); i++ )
  1131. {
  1132. portalcreditname_t *pCredit = &m_CreditsList[i];
  1133. if ( pCredit == NULL )
  1134. continue;
  1135. vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
  1136. vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( pCredit->szFontName, true );
  1137. if (iHeight == -1) iHeight = (iTall/2) - (surface()->GetFontTall ( m_hTFont ) + m_flSeparation);
  1138. else iHeight += surface()->GetFontTall ( m_hTFont ) + m_flSeparation;
  1139. if (i==0)
  1140. {
  1141. Q_strcpy(m_szBorderH,"-");
  1142. while(GetPixelWidth( m_szBorderH, m_hTFont )< ((iWidth/2)-GetPixelWidth( "---", m_hTFont )))
  1143. {
  1144. int iCurrentLength = Q_strlen(m_szBorderH);
  1145. if (iCurrentLength < sizeof(m_szBorderH))
  1146. {
  1147. m_szBorderH[iCurrentLength] = '-';
  1148. }
  1149. else
  1150. {
  1151. break;
  1152. }
  1153. }
  1154. }
  1155. pCredit->flYPos = iHeight;
  1156. pCredit->bActive = false;
  1157. iTotalNameLen += Q_strlen(pCredit->szCreditName);
  1158. }
  1159. m_flNameCharTime = m_flScrollTime / iTotalNameLen;
  1160. float flStart = m_flScrollCreditsStart;
  1161. for ( int i = 0; i < m_CreditsList.Count(); i++ )
  1162. {
  1163. m_CreditsList[i].flTimeStart=flStart;
  1164. m_CreditsList[i].flTimeInit = Q_strlen(m_CreditsList[i].szCreditName)*m_flNameCharTime;
  1165. flStart += m_CreditsList[i].flTimeInit;
  1166. m_CreditsList[i].flTimeEnd=flStart;
  1167. }
  1168. SetActive( true );
  1169. m_flScrollTime = 2;
  1170. m_flLastPaintTime = gpGlobals->curtime;
  1171. m_flLastBlinkTime = gpGlobals->curtime;
  1172. }
  1173. void CHudPortalCredits::PrepareIntroCredits( void )
  1174. {
  1175. PrepareCredits( "IntroCreditsNames" );
  1176. int iSlot = 0;
  1177. for ( int i = 0; i < m_CreditsList.Count(); i++ )
  1178. {
  1179. portalcreditname_t *pCredit = &m_CreditsList[i];
  1180. if ( pCredit == NULL )
  1181. continue;
  1182. vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" );
  1183. vgui::HFont m_hTFont = vgui::scheme()->GetIScheme(scheme)->GetFont( pCredit->szFontName );
  1184. pCredit->flYPos = m_flY + ( iSlot * surface()->GetFontTall ( m_hTFont ) );
  1185. pCredit->flXPos = m_flX;
  1186. if ( i < 3 )
  1187. {
  1188. pCredit->bActive = true;
  1189. pCredit->iSlot = iSlot;
  1190. pCredit->flTime = gpGlobals->curtime + m_flFadeInTime + m_flFadeOutTime + m_flFadeHoldTime;
  1191. pCredit->flTimeStart = gpGlobals->curtime;
  1192. m_flLogoTime = pCredit->flTime + m_flLogoTimeMod;
  1193. }
  1194. else
  1195. {
  1196. pCredit->bActive = false;
  1197. pCredit->flTime = 0.0f;
  1198. }
  1199. iSlot = ( iSlot + 1 ) % 3;
  1200. }
  1201. SetActive( true );
  1202. }
  1203. void CHudPortalCredits::MsgFunc_CreditsPortalMsg( bf_read &msg )
  1204. {
  1205. m_iCreditsType = msg.ReadByte();
  1206. switch ( m_iCreditsType )
  1207. {
  1208. case CREDITS_LOGO:
  1209. {
  1210. PrepareLogo( 5.0f );
  1211. break;
  1212. }
  1213. case CREDITS_INTRO:
  1214. {
  1215. PrepareIntroCredits();
  1216. break;
  1217. }
  1218. case CREDITS_OUTRO:
  1219. {
  1220. PrepareOutroCredits();
  1221. break;
  1222. }
  1223. case CREDITS_OUTRO_PORTAL:
  1224. {
  1225. PreparePortalOutroCredits();
  1226. break;
  1227. }
  1228. }
  1229. }
  1230. void CHudPortalCredits::MsgFunc_LogoTimeMsg( bf_read &msg )
  1231. {
  1232. m_iCreditsType = CREDITS_LOGO;
  1233. PrepareLogo( msg.ReadFloat() );
  1234. }