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.

329 lines
9.0 KiB

  1. //========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "cbase.h"
  8. #include "hud.h"
  9. #include "hud_crosshair.h"
  10. #include "iclientmode.h"
  11. #include "view.h"
  12. #include "vgui_controls/Controls.h"
  13. #include "vgui/ISurface.h"
  14. #include "ivrenderview.h"
  15. #ifdef PORTAL2
  16. #include "ivieweffects.h"
  17. #include "c_basehlplayer.h"
  18. #endif // PORTAL2
  19. #ifdef SIXENSE
  20. #include "sixense/in_sixense.h"
  21. #endif
  22. // memdbgon must be the last include file in a .cpp file!!!
  23. #include "tier0/memdbgon.h"
  24. #if !defined( CSTRIKE15 )
  25. ConVar crosshair( "crosshair", "1", FCVAR_ARCHIVE );
  26. ConVar cl_observercrosshair( "cl_observercrosshair", "1", FCVAR_ARCHIVE );
  27. #endif
  28. using namespace vgui;
  29. int ScreenTransform( const Vector& point, Vector& screen );
  30. DECLARE_HUDELEMENT( CHudCrosshair );
  31. CHudCrosshair::CHudCrosshair( const char *pElementName ) :
  32. CHudElement( pElementName ), BaseClass( NULL, "HudCrosshair" )
  33. {
  34. vgui::Panel *pParent = GetClientMode()->GetViewport();
  35. SetParent( pParent );
  36. m_pCrosshair = 0;
  37. m_clrCrosshair = Color( 0, 0, 0, 0 );
  38. m_vecCrossHairOffsetAngle.Init();
  39. SetHiddenBits( HIDEHUD_PLAYERDEAD | HIDEHUD_CROSSHAIR );
  40. }
  41. void CHudCrosshair::ApplySchemeSettings( IScheme *scheme )
  42. {
  43. BaseClass::ApplySchemeSettings( scheme );
  44. m_pDefaultCrosshair = HudIcons().GetIcon( "crosshair_default" );
  45. SetPaintBackgroundEnabled( false );
  46. SetSize( ScreenWidth(), ScreenHeight() );
  47. }
  48. //-----------------------------------------------------------------------------
  49. // Purpose: Save CPU cycles by letting the HUD system early cull
  50. // costly traversal. Called per frame, return true if thinking and
  51. // painting need to occur.
  52. //-----------------------------------------------------------------------------
  53. bool CHudCrosshair::ShouldDraw( void )
  54. {
  55. #if defined ( CSTRIKE15 )
  56. return false;
  57. #else
  58. bool bNeedsDraw;
  59. if ( m_bHideCrosshair )
  60. return false;
  61. C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer();
  62. if ( !pPlayer )
  63. return false;
  64. C_BaseCombatWeapon *pWeapon = pPlayer->GetActiveWeapon();
  65. if ( pWeapon && !pWeapon->ShouldDrawCrosshair() )
  66. return false;
  67. /* disabled to avoid assuming it's an HL2 player.
  68. // suppress crosshair in zoom.
  69. if ( pPlayer->m_HL2Local.m_bZooming )
  70. return false;
  71. */
  72. // draw a crosshair only if alive or spectating in eye
  73. if ( IsGameConsole() )
  74. {
  75. bNeedsDraw = m_pCrosshair &&
  76. !engine->IsDrawingLoadingImage() &&
  77. !engine->IsPaused() &&
  78. ( !pPlayer->IsSuitEquipped() || g_pGameRules->IsMultiplayer() ) &&
  79. GetClientMode()->ShouldDrawCrosshair() &&
  80. !( pPlayer->GetFlags() & FL_FROZEN ) &&
  81. ( pPlayer->IsViewEntity() ) &&
  82. ( pPlayer->IsAlive() || ( pPlayer->GetObserverMode() == OBS_MODE_IN_EYE ) || ( cl_observercrosshair.GetBool() && pPlayer->GetObserverMode() == OBS_MODE_ROAMING ) );
  83. }
  84. else
  85. {
  86. bNeedsDraw = m_pCrosshair &&
  87. crosshair.GetInt() &&
  88. !engine->IsDrawingLoadingImage() &&
  89. !engine->IsPaused() &&
  90. GetClientMode()->ShouldDrawCrosshair() &&
  91. !( pPlayer->GetFlags() & FL_FROZEN ) &&
  92. ( pPlayer->IsViewEntity() ) &&
  93. !pPlayer->IsInVGuiInputMode() &&
  94. ( pPlayer->IsAlive() || ( pPlayer->GetObserverMode() == OBS_MODE_IN_EYE ) || ( cl_observercrosshair.GetBool() && pPlayer->GetObserverMode() == OBS_MODE_ROAMING ) );
  95. }
  96. return ( bNeedsDraw && CHudElement::ShouldDraw() );
  97. #endif
  98. }
  99. void CHudCrosshair::Paint( void )
  100. {
  101. if ( !m_pCrosshair )
  102. return;
  103. if ( !IsCurrentViewAccessAllowed() )
  104. return;
  105. #ifdef SIXENSE
  106. float x=0, y=0;
  107. if( g_pSixenseInput->IsEnabled() && C_BasePlayer::GetLocalPlayer() && (C_BasePlayer::GetLocalPlayer()->GetObserverMode()==OBS_MODE_NONE) )
  108. {
  109. C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
  110. if ( player != NULL )
  111. {
  112. // Never autoaim a predicted weapon (for now)
  113. Vector aimVector;
  114. AngleVectors( CurrentViewAngles() - g_pSixenseInput->GetViewAngleOffset(), &aimVector );
  115. // calculate where the bullet would go so we can draw the cross appropriately
  116. Vector vecStart = player->Weapon_ShootPosition();
  117. Vector vecEnd = player->Weapon_ShootPosition() + aimVector * MAX_TRACE_LENGTH;
  118. trace_t tr;
  119. UTIL_TraceLine( vecStart, vecEnd, MASK_SHOT, player, COLLISION_GROUP_NONE, &tr );
  120. Vector screen;
  121. screen.Init();
  122. ScreenTransform(tr.endpos, screen);
  123. x = ScreenWidth() / 2;
  124. y = ScreenHeight() / 2;
  125. x += 0.5 * screen[0] * ScreenWidth() + 0.5;
  126. y += 0.5 * screen[1] * ScreenHeight() + 0.5;
  127. y = ScreenHeight() - y;
  128. }
  129. }
  130. else
  131. {
  132. x = ScreenWidth() / 2;
  133. y = ScreenHeight() / 2;
  134. }
  135. #else
  136. float x, y;
  137. x = ScreenWidth()/2;
  138. y = ScreenHeight()/2;
  139. #endif
  140. float flApparentZ = vgui::STEREO_NOOP;
  141. bool bStereoActive = materials->IsStereoActiveThisFrame();
  142. m_curViewAngles = CurrentViewAngles();
  143. m_curViewOrigin = CurrentViewOrigin();
  144. Vector screen;
  145. screen.Init();
  146. // TrackIR
  147. if ( IsHeadTrackingEnabled() )
  148. {
  149. C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer();
  150. if ( !pPlayer )
  151. return;
  152. // TrackIR
  153. // get the direction the player is aiming
  154. Vector aimVector = pPlayer->GetAutoaimVector( AUTOAIM_5DEGREES );
  155. // calculate where the bullet would go so we can draw the cross appropriately
  156. Vector vecEnd = pPlayer->Weapon_ShootPosition() + aimVector * MAX_TRACE_LENGTH;
  157. trace_t tr;
  158. UTIL_TraceLine( pPlayer->Weapon_ShootPosition(), vecEnd, MASK_SHOT, pPlayer, COLLISION_GROUP_NONE, &tr );
  159. QAngle angles;
  160. Vector forward;
  161. Vector point;
  162. // this code is wrong
  163. angles = m_curViewAngles + m_vecCrossHairOffsetAngle;
  164. AngleVectors( angles, &forward );
  165. // need to project forward into an object to see how far this
  166. // vector should be!!
  167. //forward *= 1000;
  168. //VectorAdd( m_curViewOrigin, forward, point );
  169. //ScreenTransform( point, screen );
  170. if ( bStereoActive && ( !tr.allsolid || !tr.startsolid ) )
  171. {
  172. // NOTE: This isn't exactly right, because the trace above starts with the gun and
  173. // not with the camera origin, so this will be slightly off. It shouldn't really matter.
  174. flApparentZ = ( tr.endpos - tr.startpos ).Length();
  175. }
  176. ScreenTransform( tr.endpos, screen );
  177. }
  178. // TrackIR
  179. else
  180. {
  181. Vector forward;
  182. // MattB - m_vecCrossHairOffsetAngle is the autoaim angle.
  183. // if we're not using autoaim, just draw in the middle of the
  184. // screen
  185. if ( m_vecCrossHairOffsetAngle != vec3_angle )
  186. {
  187. QAngle angles;
  188. Vector point;
  189. // this code is wrong
  190. angles = m_curViewAngles + m_vecCrossHairOffsetAngle;
  191. AngleVectors( angles, &forward );
  192. VectorAdd( m_curViewOrigin, forward, point );
  193. ScreenTransform( point, screen );
  194. }
  195. else
  196. {
  197. AngleVectors( m_curViewAngles, &forward );
  198. }
  199. if ( bStereoActive )
  200. {
  201. C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
  202. if ( pPlayer && m_clrCrosshair.a() != 0.0f ) // if we have a player and we're not going to ignore the results...
  203. {
  204. Vector vecEnd = m_curViewOrigin + ( forward * MAX_TRACE_LENGTH );
  205. trace_t tr;
  206. UTIL_TraceLine( m_curViewOrigin, vecEnd, MASK_SHOT, pPlayer, COLLISION_GROUP_NONE, &tr );
  207. if ( !tr.allsolid || !tr.startsolid )
  208. {
  209. // NOTE: This isn't exactly right, because the trace above starts with the gun and
  210. // not with the camera origin, so this will be slightly off. It shouldn't really matter.
  211. flApparentZ = ( tr.endpos - tr.startpos ).Length();
  212. }
  213. }
  214. }
  215. }
  216. x += 0.5f * screen[0] * ScreenWidth() + 0.5f;
  217. y += 0.5f * screen[1] * ScreenHeight() + 0.5f;
  218. #ifdef PORTAL2
  219. // Find any full-screen fades
  220. byte color[4];
  221. bool blend;
  222. GetViewEffects()->GetFadeParams( &color[0], &color[1], &color[2], &color[3], &blend );
  223. m_clrCrosshair[3] = SimpleSplineRemapValClamped( color[3], 0, 64, 255, 0 );
  224. #endif // PORTAL2
  225. C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer();
  226. if ( !pPlayer )
  227. return;
  228. float flWeaponScale = 1.f;
  229. float flW = m_pCrosshair->Width();
  230. float flH = m_pCrosshair->Height();
  231. C_BaseCombatWeapon *pWeapon = pPlayer->GetActiveWeapon();
  232. if ( pWeapon )
  233. {
  234. pWeapon->GetWeaponCrosshairScale( flWeaponScale );
  235. }
  236. m_pCrosshair->DrawSelfCropped(
  237. x - 0.5f * m_pCrosshair->Width() * flWeaponScale + 0.5,
  238. y - 0.5f * m_pCrosshair->Height() * flWeaponScale + 0.5,
  239. 0, 0, flW, flH, flW*flWeaponScale, flH*flWeaponScale,
  240. m_clrCrosshair );
  241. }
  242. //-----------------------------------------------------------------------------
  243. // Purpose:
  244. //-----------------------------------------------------------------------------
  245. void CHudCrosshair::SetCrosshairAngle( const QAngle& angle )
  246. {
  247. VectorCopy( angle, m_vecCrossHairOffsetAngle );
  248. }
  249. //-----------------------------------------------------------------------------
  250. // Purpose:
  251. //-----------------------------------------------------------------------------
  252. void CHudCrosshair::SetCrosshair( CHudTexture *texture, const Color& clr )
  253. {
  254. m_pCrosshair = texture;
  255. m_clrCrosshair = clr;
  256. }
  257. //-----------------------------------------------------------------------------
  258. // Purpose: Resets the crosshair back to the default
  259. //-----------------------------------------------------------------------------
  260. void CHudCrosshair::ResetCrosshair()
  261. {
  262. SetCrosshair( m_pDefaultCrosshair, Color( 255, 255, 255, 255 ) );
  263. }