|
|
//========= 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) ); }
|