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.

272 lines
7.4 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "cbase.h"
  7. #include "hud.h"
  8. #include "hudelement.h"
  9. #include "hud_macros.h"
  10. #include "hud_numericdisplay.h"
  11. #include "iclientmode.h"
  12. #include "c_basehlplayer.h"
  13. #include "VGuiMatSurface/IMatSystemSurface.h"
  14. #include "materialsystem/imaterial.h"
  15. #include "materialsystem/imesh.h"
  16. #include "materialsystem/imaterialvar.h"
  17. #include "../hud_crosshair.h"
  18. #include <vgui/IScheme.h>
  19. #include <vgui/ISurface.h>
  20. #include <KeyValues.h>
  21. #include <vgui_controls/AnimationController.h>
  22. // memdbgon must be the last include file in a .cpp file!!!
  23. #include "tier0/memdbgon.h"
  24. //-----------------------------------------------------------------------------
  25. // Purpose: Draws the zoom screen
  26. //-----------------------------------------------------------------------------
  27. class CHudZoom : public vgui::Panel, public CHudElement
  28. {
  29. DECLARE_CLASS_SIMPLE( CHudZoom, vgui::Panel );
  30. public:
  31. CHudZoom( const char *pElementName );
  32. bool ShouldDraw( void );
  33. void Init( void );
  34. void LevelInit( void );
  35. protected:
  36. virtual void ApplySchemeSettings(vgui::IScheme *scheme);
  37. virtual void Paint( void );
  38. private:
  39. bool m_bZoomOn;
  40. float m_flZoomStartTime;
  41. bool m_bPainted;
  42. CPanelAnimationVarAliasType( float, m_flCircle1Radius, "Circle1Radius", "66", "proportional_float" );
  43. CPanelAnimationVarAliasType( float, m_flCircle2Radius, "Circle2Radius", "74", "proportional_float" );
  44. CPanelAnimationVarAliasType( float, m_flDashGap, "DashGap", "16", "proportional_float" );
  45. CPanelAnimationVarAliasType( float, m_flDashHeight, "DashHeight", "4", "proportional_float" );
  46. CMaterialReference m_ZoomMaterial;
  47. };
  48. DECLARE_HUDELEMENT( CHudZoom );
  49. using namespace vgui;
  50. //-----------------------------------------------------------------------------
  51. // Purpose: Constructor
  52. //-----------------------------------------------------------------------------
  53. CHudZoom::CHudZoom( const char *pElementName ) : CHudElement(pElementName), BaseClass(NULL, "HudZoom")
  54. {
  55. vgui::Panel *pParent = g_pClientMode->GetViewport();
  56. SetParent( pParent );
  57. SetHiddenBits( HIDEHUD_HEALTH | HIDEHUD_PLAYERDEAD | HIDEHUD_NEEDSUIT );
  58. }
  59. //-----------------------------------------------------------------------------
  60. // Purpose: standard hud element init function
  61. //-----------------------------------------------------------------------------
  62. void CHudZoom::Init( void )
  63. {
  64. m_bZoomOn = false;
  65. m_bPainted = false;
  66. m_flZoomStartTime = -999.0f;
  67. m_ZoomMaterial.Init( "vgui/zoom", TEXTURE_GROUP_VGUI );
  68. }
  69. //-----------------------------------------------------------------------------
  70. // Purpose: standard hud element init function
  71. //-----------------------------------------------------------------------------
  72. void CHudZoom::LevelInit( void )
  73. {
  74. Init();
  75. }
  76. //-----------------------------------------------------------------------------
  77. // Purpose: sets scheme colors
  78. //-----------------------------------------------------------------------------
  79. void CHudZoom::ApplySchemeSettings( vgui::IScheme *scheme )
  80. {
  81. BaseClass::ApplySchemeSettings(scheme);
  82. SetPaintBackgroundEnabled(false);
  83. SetPaintBorderEnabled(false);
  84. SetFgColor(scheme->GetColor("ZoomReticleColor", GetFgColor()));
  85. SetForceStereoRenderToFrameBuffer( true );
  86. int x, y;
  87. int screenWide, screenTall;
  88. surface()->GetFullscreenViewport( x, y, screenWide, screenTall );
  89. SetBounds(0, 0, screenWide, screenTall);
  90. }
  91. //-----------------------------------------------------------------------------
  92. // Purpose: Save CPU cycles by letting the HUD system early cull
  93. // costly traversal. Called per frame, return true if thinking and
  94. // painting need to occur.
  95. //-----------------------------------------------------------------------------
  96. bool CHudZoom::ShouldDraw( void )
  97. {
  98. bool bNeedsDraw = false;
  99. C_BaseHLPlayer *pPlayer = dynamic_cast<C_BaseHLPlayer *>(C_BasePlayer::GetLocalPlayer());
  100. if ( pPlayer == NULL )
  101. return false;
  102. if ( pPlayer->m_HL2Local.m_bZooming )
  103. {
  104. // need to paint
  105. bNeedsDraw = true;
  106. }
  107. else if ( m_bPainted )
  108. {
  109. // keep painting until state is finished
  110. bNeedsDraw = true;
  111. }
  112. return ( bNeedsDraw && CHudElement::ShouldDraw() );
  113. }
  114. #define ZOOM_FADE_TIME 0.4f
  115. //-----------------------------------------------------------------------------
  116. // Purpose: draws the zoom effect
  117. //-----------------------------------------------------------------------------
  118. void CHudZoom::Paint( void )
  119. {
  120. m_bPainted = false;
  121. // see if we're zoomed any
  122. C_BaseHLPlayer *pPlayer = dynamic_cast<C_BaseHLPlayer *>(C_BasePlayer::GetLocalPlayer());
  123. if ( pPlayer == NULL )
  124. return;
  125. if ( pPlayer->m_HL2Local.m_bZooming && m_bZoomOn == false )
  126. {
  127. m_bZoomOn = true;
  128. m_flZoomStartTime = gpGlobals->curtime;
  129. }
  130. else if ( pPlayer->m_HL2Local.m_bZooming == false && m_bZoomOn )
  131. {
  132. m_bZoomOn = false;
  133. m_flZoomStartTime = gpGlobals->curtime;
  134. }
  135. // draw the appropriately scaled zoom animation
  136. float deltaTime = ( gpGlobals->curtime - m_flZoomStartTime );
  137. float scale = clamp( deltaTime / ZOOM_FADE_TIME, 0.0f, 1.0f );
  138. float alpha;
  139. if ( m_bZoomOn )
  140. {
  141. alpha = scale;
  142. }
  143. else
  144. {
  145. if ( scale >= 1.0f )
  146. return;
  147. alpha = ( 1.0f - scale ) * 0.25f;
  148. scale = 1.0f - ( scale * 0.5f );
  149. }
  150. Color col = GetFgColor();
  151. col[3] = alpha * 64;
  152. surface()->DrawSetColor( col );
  153. // draw zoom circles
  154. float fX, fY;
  155. bool bBehindCamera = false;
  156. CHudCrosshair::GetDrawPosition( &fX, &fY, &bBehindCamera );
  157. if( bBehindCamera )
  158. return;
  159. int xCrosshair = (int)fX;
  160. int yCrosshair = (int)fY;
  161. int wide, tall;
  162. GetSize( wide, tall );
  163. surface()->DrawOutlinedCircle( xCrosshair, yCrosshair, m_flCircle1Radius * scale, 48);
  164. surface()->DrawOutlinedCircle( xCrosshair, yCrosshair, m_flCircle2Radius * scale, 64);
  165. // draw dashed lines
  166. int dashCount = 2;
  167. int ypos = yCrosshair - m_flDashHeight / 2.f;
  168. float fGap = m_flDashGap * MAX(scale,0.1f);
  169. int dashMax = Max(fX, (float)wide - fX ) / fGap;
  170. while ( dashCount < dashMax )
  171. {
  172. int xpos = (int)(fX - fGap * dashCount + 0.5f);
  173. surface()->DrawFilledRect(xpos, ypos, xpos + 1, ypos + m_flDashHeight);
  174. xpos = (int)(fX + fGap * dashCount + 0.5f);
  175. surface()->DrawFilledRect(xpos, ypos, xpos + 1, ypos + m_flDashHeight);
  176. dashCount++;
  177. }
  178. // draw the darkened edges, with a rotated texture in the four corners
  179. CMatRenderContextPtr pRenderContext( materials );
  180. pRenderContext->Bind( m_ZoomMaterial );
  181. IMesh *pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, NULL );
  182. float x0 = 0.0f, x1 = fX, x2 = wide;
  183. float y0 = 0.0f, y1 = fY, y2 = tall;
  184. float uv1 = 1.0f - (1.0f / 255.0f);
  185. float uv2 = 0.0f + (1.0f / 255.0f);
  186. struct coord_t
  187. {
  188. float x, y;
  189. float u, v;
  190. };
  191. coord_t coords[16] =
  192. {
  193. // top-left
  194. { x0, y0, uv1, uv2 },
  195. { x1, y0, uv2, uv2 },
  196. { x1, y1, uv2, uv1 },
  197. { x0, y1, uv1, uv1 },
  198. // top-right
  199. { x1, y0, uv2, uv2 },
  200. { x2, y0, uv1, uv2 },
  201. { x2, y1, uv1, uv1 },
  202. { x1, y1, uv2, uv1 },
  203. // bottom-right
  204. { x1, y1, uv2, uv1 },
  205. { x2, y1, uv1, uv1 },
  206. { x2, y2, uv1, uv2 },
  207. { x1, y2, uv2, uv2 },
  208. // bottom-left
  209. { x0, y1, uv1, uv1 },
  210. { x1, y1, uv2, uv1 },
  211. { x1, y2, uv2, uv2 },
  212. { x0, y2, uv1, uv2 },
  213. };
  214. CMeshBuilder meshBuilder;
  215. meshBuilder.Begin( pMesh, MATERIAL_QUADS, 4 );
  216. for (int i = 0; i < 16; i++)
  217. {
  218. meshBuilder.Color4f( 0.0, 0.0, 0.0, alpha );
  219. meshBuilder.TexCoord2f( 0, coords[i].u, coords[i].v );
  220. meshBuilder.Position3f( coords[i].x, coords[i].y, 0.0f );
  221. meshBuilder.AdvanceVertex();
  222. }
  223. meshBuilder.End();
  224. pMesh->Draw();
  225. m_bPainted = true;
  226. }