diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/hud_crosshair.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/client/hud_crosshair.cpp')
| -rw-r--r-- | game/client/hud_crosshair.cpp | 306 |
1 files changed, 306 insertions, 0 deletions
diff --git a/game/client/hud_crosshair.cpp b/game/client/hud_crosshair.cpp new file mode 100644 index 0000000..fc7714f --- /dev/null +++ b/game/client/hud_crosshair.cpp @@ -0,0 +1,306 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" +#include "hud.h" +#include "hud_crosshair.h" +#include "iclientmode.h" +#include "view.h" +#include "vgui_controls/Controls.h" +#include "vgui/ISurface.h" +#include "ivrenderview.h" +#include "materialsystem/imaterialsystem.h" +#include "VGuiMatSurface/IMatSystemSurface.h" +#include "client_virtualreality.h" +#include "sourcevr/isourcevirtualreality.h" + +#ifdef SIXENSE +#include "sixense/in_sixense.h" +#endif + +#ifdef PORTAL +#include "c_portal_player.h" +#endif // PORTAL + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +ConVar crosshair( "crosshair", "1", FCVAR_ARCHIVE ); +ConVar cl_observercrosshair( "cl_observercrosshair", "1", FCVAR_ARCHIVE ); + +using namespace vgui; + +int ScreenTransform( const Vector& point, Vector& screen ); + +#ifdef TF_CLIENT_DLL +// If running TF, we use CHudTFCrosshair instead (which is derived from CHudCrosshair) +#else +DECLARE_HUDELEMENT( CHudCrosshair ); +#endif + +CHudCrosshair::CHudCrosshair( const char *pElementName ) : + CHudElement( pElementName ), BaseClass( NULL, "HudCrosshair" ) +{ + vgui::Panel *pParent = g_pClientMode->GetViewport(); + SetParent( pParent ); + + m_pCrosshair = 0; + + m_clrCrosshair = Color( 0, 0, 0, 0 ); + + m_vecCrossHairOffsetAngle.Init(); + + SetHiddenBits( HIDEHUD_PLAYERDEAD | HIDEHUD_CROSSHAIR ); +} + +CHudCrosshair::~CHudCrosshair() +{ +} + +void CHudCrosshair::ApplySchemeSettings( IScheme *scheme ) +{ + BaseClass::ApplySchemeSettings( scheme ); + + m_pDefaultCrosshair = gHUD.GetIcon("crosshair_default"); + SetPaintBackgroundEnabled( false ); + + SetSize( ScreenWidth(), ScreenHeight() ); + + SetForceStereoRenderToFrameBuffer( true ); +} + +//----------------------------------------------------------------------------- +// Purpose: Save CPU cycles by letting the HUD system early cull +// costly traversal. Called per frame, return true if thinking and +// painting need to occur. +//----------------------------------------------------------------------------- +bool CHudCrosshair::ShouldDraw( void ) +{ + bool bNeedsDraw; + + if ( m_bHideCrosshair ) + return false; + + C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer(); + if ( !pPlayer ) + return false; + + C_BaseCombatWeapon *pWeapon = pPlayer->GetActiveWeapon(); + if ( pWeapon && !pWeapon->ShouldDrawCrosshair() ) + return false; + +#ifdef PORTAL + C_Portal_Player *portalPlayer = ToPortalPlayer(pPlayer); + if ( portalPlayer && portalPlayer->IsSuppressingCrosshair() ) + return false; +#endif // PORTAL + + /* disabled to avoid assuming it's an HL2 player. + // suppress crosshair in zoom. + if ( pPlayer->m_HL2Local.m_bZooming ) + return false; + */ + + // draw a crosshair only if alive or spectating in eye + if ( IsX360() ) + { + bNeedsDraw = m_pCrosshair && + !engine->IsDrawingLoadingImage() && + !engine->IsPaused() && + ( !pPlayer->IsSuitEquipped() || g_pGameRules->IsMultiplayer() ) && + g_pClientMode->ShouldDrawCrosshair() && + !( pPlayer->GetFlags() & FL_FROZEN ) && + ( pPlayer->entindex() == render->GetViewEntity() ) && + ( pPlayer->IsAlive() || ( pPlayer->GetObserverMode() == OBS_MODE_IN_EYE ) || ( cl_observercrosshair.GetBool() && pPlayer->GetObserverMode() == OBS_MODE_ROAMING ) ); + } + else + { + bNeedsDraw = m_pCrosshair && + crosshair.GetInt() && + !engine->IsDrawingLoadingImage() && + !engine->IsPaused() && + g_pClientMode->ShouldDrawCrosshair() && + !( pPlayer->GetFlags() & FL_FROZEN ) && + ( pPlayer->entindex() == render->GetViewEntity() ) && + !pPlayer->IsInVGuiInputMode() && + ( pPlayer->IsAlive() || ( pPlayer->GetObserverMode() == OBS_MODE_IN_EYE ) || ( cl_observercrosshair.GetBool() && pPlayer->GetObserverMode() == OBS_MODE_ROAMING ) ); + } + + return ( bNeedsDraw && CHudElement::ShouldDraw() ); +} + +#ifdef TF_CLIENT_DLL +extern ConVar cl_crosshair_red; +extern ConVar cl_crosshair_green; +extern ConVar cl_crosshair_blue; +extern ConVar cl_crosshair_scale; +#endif + + +void CHudCrosshair::GetDrawPosition ( float *pX, float *pY, bool *pbBehindCamera, QAngle angleCrosshairOffset ) +{ + QAngle curViewAngles = CurrentViewAngles(); + Vector curViewOrigin = CurrentViewOrigin(); + + int vx, vy, vw, vh; + vgui::surface()->GetFullscreenViewport( vx, vy, vw, vh ); + + float screenWidth = vw; + float screenHeight = vh; + + float x = screenWidth / 2; + float y = screenHeight / 2; + + bool bBehindCamera = false; + + C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer(); + if ( ( pPlayer != NULL ) && ( pPlayer->GetObserverMode()==OBS_MODE_NONE ) ) + { + bool bUseOffset = false; + + Vector vecStart; + Vector vecEnd; + + if ( UseVR() ) + { + // These are the correct values to use, but they lag the high-speed view data... + vecStart = pPlayer->Weapon_ShootPosition(); + Vector vecAimDirection = pPlayer->GetAutoaimVector( 1.0f ); + // ...so in some aim modes, they get zapped by something completely up-to-date. + g_ClientVirtualReality.OverrideWeaponHudAimVectors ( &vecStart, &vecAimDirection ); + vecEnd = vecStart + vecAimDirection * MAX_TRACE_LENGTH; + + bUseOffset = true; + } + +#ifdef SIXENSE + // TODO: actually test this Sixsense code interaction with things like HMDs & stereo. + if ( g_pSixenseInput->IsEnabled() && !UseVR() ) + { + // Never autoaim a predicted weapon (for now) + vecStart = pPlayer->Weapon_ShootPosition(); + Vector aimVector; + AngleVectors( CurrentViewAngles() - g_pSixenseInput->GetViewAngleOffset(), &aimVector ); + // calculate where the bullet would go so we can draw the cross appropriately + vecEnd = vecStart + aimVector * MAX_TRACE_LENGTH; + bUseOffset = true; + } +#endif + + if ( bUseOffset ) + { + trace_t tr; + UTIL_TraceLine( vecStart, vecEnd, MASK_SHOT, pPlayer, COLLISION_GROUP_NONE, &tr ); + + Vector screen; + screen.Init(); + bBehindCamera = ScreenTransform(tr.endpos, screen) != 0; + + x = 0.5f * ( 1.0f + screen[0] ) * screenWidth + 0.5f; + y = 0.5f * ( 1.0f - screen[1] ) * screenHeight + 0.5f; + } + } + + // MattB - angleCrosshairOffset is the autoaim angle. + // if we're not using autoaim, just draw in the middle of the + // screen + if ( angleCrosshairOffset != vec3_angle ) + { + QAngle angles; + Vector forward; + Vector point, screen; + + // this code is wrong + angles = curViewAngles + angleCrosshairOffset; + AngleVectors( angles, &forward ); + VectorAdd( curViewOrigin, forward, point ); + ScreenTransform( point, screen ); + + x += 0.5f * screen[0] * screenWidth + 0.5f; + y += 0.5f * screen[1] * screenHeight + 0.5f; + } + + *pX = x; + *pY = y; + *pbBehindCamera = bBehindCamera; +} + + +void CHudCrosshair::Paint( void ) +{ + if ( !m_pCrosshair ) + return; + + if ( !IsCurrentViewAccessAllowed() ) + return; + + C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer(); + if ( !pPlayer ) + return; + + float x, y; + bool bBehindCamera; + GetDrawPosition ( &x, &y, &bBehindCamera, m_vecCrossHairOffsetAngle ); + + if( bBehindCamera ) + return; + + float flWeaponScale = 1.f; + int iTextureW = m_pCrosshair->Width(); + int iTextureH = m_pCrosshair->Height(); + C_BaseCombatWeapon *pWeapon = pPlayer->GetActiveWeapon(); + if ( pWeapon ) + { + pWeapon->GetWeaponCrosshairScale( flWeaponScale ); + } + + float flPlayerScale = 1.0f; +#ifdef TF_CLIENT_DLL + Color clr( cl_crosshair_red.GetInt(), cl_crosshair_green.GetInt(), cl_crosshair_blue.GetInt(), 255 ); + flPlayerScale = cl_crosshair_scale.GetFloat() / 32.0f; // the player can change the scale in the options/multiplayer tab +#else + Color clr = m_clrCrosshair; +#endif + float flWidth = flWeaponScale * flPlayerScale * (float)iTextureW; + float flHeight = flWeaponScale * flPlayerScale * (float)iTextureH; + int iWidth = (int)( flWidth + 0.5f ); + int iHeight = (int)( flHeight + 0.5f ); + int iX = (int)( x + 0.5f ); + int iY = (int)( y + 0.5f ); + + m_pCrosshair->DrawSelfCropped ( + iX-(iWidth/2), iY-(iHeight/2), + 0, 0, + iTextureW, iTextureH, + iWidth, iHeight, + clr ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudCrosshair::SetCrosshairAngle( const QAngle& angle ) +{ + VectorCopy( angle, m_vecCrossHairOffsetAngle ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHudCrosshair::SetCrosshair( CHudTexture *texture, const Color& clr ) +{ + m_pCrosshair = texture; + m_clrCrosshair = clr; +} + +//----------------------------------------------------------------------------- +// Purpose: Resets the crosshair back to the default +//----------------------------------------------------------------------------- +void CHudCrosshair::ResetCrosshair() +{ + SetCrosshair( m_pDefaultCrosshair, Color(255, 255, 255, 255) ); +} |