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/tf/tf_hud_scope.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/client/tf/tf_hud_scope.cpp')
| -rw-r--r-- | game/client/tf/tf_hud_scope.cpp | 527 |
1 files changed, 527 insertions, 0 deletions
diff --git a/game/client/tf/tf_hud_scope.cpp b/game/client/tf/tf_hud_scope.cpp new file mode 100644 index 0000000..686c68f --- /dev/null +++ b/game/client/tf/tf_hud_scope.cpp @@ -0,0 +1,527 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//=============================================================================// + +#include "cbase.h" +#include "hud.h" +#include "hudelement.h" +#include "hud_macros.h" +#include "hud_numericdisplay.h" +#include "iclientmode.h" +#include "c_tf_player.h" +#include "VGuiMatSurface/IMatSystemSurface.h" +#include "materialsystem/imaterial.h" +#include "materialsystem/imesh.h" +#include "materialsystem/imaterialvar.h" +#include "client_virtualreality.h" +#include "sourcevr/isourcevirtualreality.h" +#include <vgui/IScheme.h> +#include <vgui/ISurface.h> +#include <KeyValues.h> +#include <vgui_controls/AnimationController.h> + +//for screenfade +#include "ivieweffects.h" +#include "shake.h" +#include "view_scene.h" + +#include "tf_weapon_sniperrifle.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +//----------------------------------------------------------------------------- +// Purpose: Figure out where the sniper scope should be drawn. +//----------------------------------------------------------------------------- +void WhereToDrawSniperScope ( int *pX, int *pY, int screenWide, int screenTall ) +{ + C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer(); + if ( pPlayer != NULL ) + { + // These are the correct values to use, but they lag the high-speed view data... + Vector 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 ); + + Vector vAimPoint; + // Here we just put the aim point a set distance from the viewer - same depth as the HUD. + float fVrHudDistance = g_ClientVirtualReality.GetHUDDistance(); + vAimPoint = vecStart + vecAimDirection * fVrHudDistance; + + Vector screen; + screen.Init(); + ScreenTransform(vAimPoint, screen); + + // screen[0][1] are in range (-1, 1) + float x = 0.5 * ( 1.0f + screen[0] ) * screenWide + 0.5; + float y = 0.5 * ( 1.0f - screen[1] ) * screenTall + 0.5; + + *pX = (int)( x + 0.5f ); + *pY = (int)( y + 0.5f ); + } +} + + + +//----------------------------------------------------------------------------- +// Purpose: Draws the sniper chargeup meter +//----------------------------------------------------------------------------- +class CHudScopeCharge : public vgui::Panel, public CHudElement +{ + DECLARE_CLASS_SIMPLE( CHudScopeCharge, vgui::Panel ); + +public: + CHudScopeCharge( const char *pElementName ); + virtual ~CHudScopeCharge( void ); + + void Init( void ); + +protected: + virtual void ApplySchemeSettings(vgui::IScheme *scheme); + virtual void Paint( void ); + +private: + int m_iChargeupTexture; + int m_iChargeupTextureWidth; + CPanelAnimationVarAliasType( float, m_iChargeup_xpos, "chargeup_xpos", "0", "proportional_float" ); + CPanelAnimationVarAliasType( float, m_iChargeup_ypos, "chargeup_ypos", "0", "proportional_float" ); + CPanelAnimationVarAliasType( float, m_iChargeup_wide, "chargeup_wide", "0", "proportional_float" ); + CPanelAnimationVarAliasType( float, m_iChargeup_tall, "chargeup_tall", "0", "proportional_float" ); + + bool m_bJarateMode; +}; + +DECLARE_HUDELEMENT_DEPTH( CHudScopeCharge, 100 ); + +using namespace vgui; + +//----------------------------------------------------------------------------- +// Purpose: Constructor +//----------------------------------------------------------------------------- +CHudScopeCharge::CHudScopeCharge( const char *pElementName ) : CHudElement(pElementName), BaseClass(NULL, "HudScopeCharge") +{ + vgui::Panel *pParent = g_pClientMode->GetViewport(); + SetParent( pParent ); + + SetHiddenBits( HIDEHUD_PLAYERDEAD ); + + m_bJarateMode = false; + + m_iChargeupTexture = -1; +} + +CHudScopeCharge::~CHudScopeCharge( void ) +{ + if ( vgui::surface() && m_iChargeupTexture != -1 ) + { + vgui::surface()->DestroyTextureID( m_iChargeupTexture ); + m_iChargeupTexture = -1; + } +} + +//----------------------------------------------------------------------------- +// Purpose: standard hud element init function +//----------------------------------------------------------------------------- +void CHudScopeCharge::Init( void ) +{ + if ( m_iChargeupTexture == -1 ) + { + m_iChargeupTexture = vgui::surface()->CreateNewTextureID(); + vgui::surface()->DrawSetTextureFile(m_iChargeupTexture, "HUD/sniperscope_numbers", true, false); + } + + // Get the texture size + int ignored; + surface()->DrawGetTextureSize( m_iChargeupTexture, m_iChargeupTextureWidth, ignored ); +} + +//----------------------------------------------------------------------------- +// Purpose: sets scheme colors +//----------------------------------------------------------------------------- +void CHudScopeCharge::ApplySchemeSettings( vgui::IScheme *scheme ) +{ + BaseClass::ApplySchemeSettings(scheme); + + SetPaintBackgroundEnabled(false); + SetPaintBorderEnabled(false); + + if ( UseVR() ) + { + // Force it to go direct to the framebuffer. + SetForceStereoRenderToFrameBuffer( true ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: draws the zoom effect +//----------------------------------------------------------------------------- +void CHudScopeCharge::Paint( void ) +{ + C_TFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer(); + + if ( GetSpectatorTarget() != 0 && GetSpectatorMode() == OBS_MODE_IN_EYE ) + { + pPlayer = (C_TFPlayer *)UTIL_PlayerByIndex( GetSpectatorTarget() ); + } + + if ( !pPlayer ) + return; + + if ( !pPlayer->m_Shared.InCond( TF_COND_ZOOMED ) ) + return; + + // Make sure the current weapon is a sniper rifle + CTFSniperRifle *pWeapon = assert_cast<CTFSniperRifle*>(pPlayer->GetActiveTFWeapon()); + if ( !pWeapon ) + return; + + if ( pWeapon->IsJarateRifle() && !m_bJarateMode ) + { + vgui::surface()->DrawSetTextureFile(m_iChargeupTexture, "HUD/sniperscope_numbers_jar", true, false); + m_bJarateMode = true; + } + else if ( !pWeapon->IsJarateRifle() && m_bJarateMode ) + { + vgui::surface()->DrawSetTextureFile(m_iChargeupTexture, "HUD/sniperscope_numbers", true, false); + m_bJarateMode = false; + } + + // Actual charge value is set through a material proxy in the sniper rifle class + + int wide, tall; + GetSize( wide, tall ); + + int x = 0; + int y = 0; + bool bDisableClipping = false; + if ( UseVR() ) + { + int vx, vy, vw, vh; + vgui::surface()->GetFullscreenViewport( vx, vy, vw, vh ); + + int screenWide = vw; + int screenTall = vh; + bDisableClipping = true; + WhereToDrawSniperScope ( &x, &y, screenWide, screenTall ); + + // The origin is wherever the property file put it, so (0,0) means "the right place, if the scope is in the middle of the screen" + // So offset from there. But additional fun - the rendering coordinates are in the UI space, not the actual screen space. + int UiScreenWide, UiScreenTall; + GetHudSize(UiScreenWide, UiScreenTall); + x -= ( UiScreenWide / 2 ); + y -= ( UiScreenTall / 2 ); + } + + if( bDisableClipping ) + g_pMatSystemSurface->DisableClipping( true ); + vgui::surface()->DrawSetColor(255,255,255,255); + vgui::surface()->DrawSetTexture(m_iChargeupTexture); + vgui::surface()->DrawTexturedRect( x, y, x+wide, y+tall ); + if( bDisableClipping ) + g_pMatSystemSurface->DisableClipping( false ); +} + +//----------------------------------------------------------------------------- +// Purpose: Draws the zoom screen +//----------------------------------------------------------------------------- +class CHudScope : public vgui::Panel, public CHudElement +{ + DECLARE_CLASS_SIMPLE( CHudScope, vgui::Panel ); + +public: + CHudScope( const char *pElementName ); + virtual ~CHudScope( void ); + + void Init( void ); + +protected: + virtual void ApplySchemeSettings(vgui::IScheme *scheme); + virtual void Paint( void ); + virtual bool ShouldDraw( void ); + +private: + int m_iScopeTexture[4]; + int m_iScopeTextureAlt[4]; + bool m_bAltScopeMode; +}; + +DECLARE_HUDELEMENT_DEPTH( CHudScope, 100 ); + +using namespace vgui; + +//----------------------------------------------------------------------------- +// Purpose: Constructor +//----------------------------------------------------------------------------- +CHudScope::CHudScope( const char *pElementName ) : CHudElement(pElementName), BaseClass(NULL, "HudScope") +{ + vgui::Panel *pParent = g_pClientMode->GetViewport(); + SetParent( pParent ); + + SetHiddenBits( HIDEHUD_PLAYERDEAD ); + + for ( int i = 0; i < ARRAYSIZE( m_iScopeTexture ); i++ ) + { + m_iScopeTexture[ i ] = -1; + } + + for ( int i = 0; i < ARRAYSIZE( m_iScopeTextureAlt ); i++ ) + { + m_iScopeTextureAlt[i] = -1; + } + + m_bAltScopeMode = false; +} + +CHudScope::~CHudScope( void ) +{ + if ( vgui::surface() ) + { + for ( int i = 0; i < ARRAYSIZE( m_iScopeTexture ); i++ ) + { + if ( m_iScopeTexture[ i ] != -1 ) + { + vgui::surface()->DestroyTextureID( m_iScopeTexture[ i ] ); + m_iScopeTexture[ i ] = -1; + } + } + + for ( int i = 0; i < ARRAYSIZE( m_iScopeTextureAlt ); i++ ) + { + if ( m_iScopeTextureAlt[i] != -1 ) + { + vgui::surface()->DestroyTextureID( m_iScopeTextureAlt[i] ); + m_iScopeTextureAlt[i] = -1; + } + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: standard hud element init function +//----------------------------------------------------------------------------- +void CHudScope::Init( void ) +{ + for ( int i = 0; i < ARRAYSIZE( m_iScopeTexture ); i++ ) + { + if ( m_iScopeTexture[ i ] == -1 ) + { + m_iScopeTexture[ i ] = vgui::surface()->CreateNewTextureID(); + } + } + + vgui::surface()->DrawSetTextureFile( m_iScopeTexture[0], "HUD/scope_sniper_ul", true, false ); + vgui::surface()->DrawSetTextureFile( m_iScopeTexture[1], "HUD/scope_sniper_ur", true, false ); + vgui::surface()->DrawSetTextureFile( m_iScopeTexture[2], "HUD/scope_sniper_lr", true, false ); + vgui::surface()->DrawSetTextureFile( m_iScopeTexture[3], "HUD/scope_sniper_ll", true, false ); + + for ( int i = 0; i < ARRAYSIZE( m_iScopeTextureAlt ); i++ ) + { + if ( m_iScopeTextureAlt[i] == -1 ) + { + m_iScopeTextureAlt[i] = vgui::surface()->CreateNewTextureID(); + } + } + + vgui::surface()->DrawSetTextureFile( m_iScopeTextureAlt[0], "HUD/scope_sniper_alt_ul", true, false ); + vgui::surface()->DrawSetTextureFile( m_iScopeTextureAlt[1], "HUD/scope_sniper_alt_ur", true, false ); + vgui::surface()->DrawSetTextureFile( m_iScopeTextureAlt[2], "HUD/scope_sniper_alt_lr", true, false ); + vgui::surface()->DrawSetTextureFile( m_iScopeTextureAlt[3], "HUD/scope_sniper_alt_ll", true, false ); + + // remove ourselves from the global group so the scoreboard doesn't hide us + UnregisterForRenderGroup( "global" ); +} + +//----------------------------------------------------------------------------- +// Purpose: sets scheme colors +//----------------------------------------------------------------------------- +void CHudScope::ApplySchemeSettings( vgui::IScheme *scheme ) +{ + BaseClass::ApplySchemeSettings(scheme); + + SetPaintBackgroundEnabled(false); + SetPaintBorderEnabled(false); + + if ( UseVR() ) + { + // Make it fill the screen. + int iViewportWidth, iViewportHeight; + g_pSourceVR->GetViewportBounds( ISourceVirtualReality::VREye_Left, NULL, NULL, &iViewportWidth, &iViewportHeight ); + SetSize ( iViewportWidth, iViewportHeight ); + SetBounds ( 0, 0, iViewportWidth, iViewportHeight ); + // Force it to go direct to the framebuffer. + SetForceStereoRenderToFrameBuffer( true ); + } + else + { + int screenWide, screenTall; + GetHudSize(screenWide, screenTall); + SetBounds(0, 0, screenWide, screenTall); + } + + // Move behind the spectator GUI, so we can be visible at the same time. + SetZPos( -1 ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CHudScope::ShouldDraw( void ) +{ + C_TFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer(); + if ( GetSpectatorTarget() != 0 && GetSpectatorMode() == OBS_MODE_IN_EYE ) + { + pPlayer = (C_TFPlayer *)UTIL_PlayerByIndex( GetSpectatorTarget() ); + } + + if ( !pPlayer || !pPlayer->m_Shared.InCond( TF_COND_ZOOMED ) ) + return false; + + if ( pPlayer->GetActiveTFWeapon() ) + { + m_bAltScopeMode = ( pPlayer->GetActiveTFWeapon()->GetWeaponID() == TF_WEAPON_SNIPERRIFLE_CLASSIC ); + } + + return CHudElement::ShouldDraw(); +} + +//----------------------------------------------------------------------------- +// Purpose: draws the zoom effect +//----------------------------------------------------------------------------- +void CHudScope::Paint( void ) +{ + // We need to update the refraction texture so the scope can refract it + UpdateRefractTexture(); + + int screenWide; + int screenTall; + + GetHudSize(screenWide, screenTall); + + // calculate the bounds in which we should draw the scope + int xMid = screenWide / 2; + int yMid = screenTall / 2; + + // width of the drawn scope. in widescreen, we draw the sides with primitives + int wide, tall; + if( screenWide > screenTall ) + { + wide = ( screenTall * 4 ) / 3; + tall = screenTall; + } + else + { + wide = screenWide; + tall = ( screenWide * 3 ) / 4; + } + + bool bDisableClipping = false; + if ( UseVR() ) + { + int vx, vy, vw, vh; + vgui::surface()->GetFullscreenViewport( vx, vy, vw, vh ); + + screenWide = vw; + screenTall = vh; + // This is actually awful - the scope is drawn in HUD-space, which is this completely + // artifical 640*480 space that we invent for VR and which doesn't even have square pixels. Ugh. + // Hacked good enough to ship. TODO: don't hack it. + float fMagnification = 1.0f / g_ClientVirtualReality.GetZoomedModeMagnification(); + wide = (int)( fMagnification * (float)screenWide ); + tall = ( wide * 3 ) / 4; + + bDisableClipping = true; + WhereToDrawSniperScope ( &xMid, &yMid, screenWide, screenTall ); + } + + int xLeft = xMid - wide/2; + int xRight = xMid + wide/2; + int yTop = yMid - tall/2; + int yBottom = yMid + tall/2; + + float uv1 = 0.5f / 256.0f, uv2 = 1.0f - uv1; + + vgui::Vertex_t vert[4]; + + Vector2D uv11( uv1, uv1 ); + Vector2D uv12( uv1, uv2 ); + Vector2D uv21( uv2, uv1 ); + Vector2D uv22( uv2, uv2 ); + + vgui::surface()->DrawSetColor(0,0,0,255); + + if( bDisableClipping ) + g_pMatSystemSurface->DisableClipping( true ); + + //upper left + vgui::surface()->DrawSetTexture( m_bAltScopeMode ? m_iScopeTextureAlt[0] : m_iScopeTexture[0] ); + vert[0].Init( Vector2D( xLeft, yTop ), uv11 ); + vert[1].Init( Vector2D( xMid, yTop ), uv21 ); + vert[2].Init( Vector2D( xMid, yMid ), uv22 ); + vert[3].Init( Vector2D( xLeft, yMid ), uv12 ); + vgui::surface()->DrawTexturedPolygon( 4, vert ); + + // top right + if ( m_bAltScopeMode ) + { + vgui::surface()->DrawSetTexture( m_iScopeTextureAlt[1] ); + vert[0].Init( Vector2D( xMid, yTop ), uv11 ); + vert[1].Init( Vector2D( xRight, yTop ), uv21 ); + vert[2].Init( Vector2D( xRight, yMid ), uv22 ); + vert[3].Init( Vector2D( xMid, yMid ), uv12 ); + vgui::surface()->DrawTexturedPolygon( 4, vert ); + } + else + { + vgui::surface()->DrawSetTexture( m_iScopeTexture[1] ); + vert[0].Init( Vector2D( xMid - 1, yTop ), uv11 ); + vert[1].Init( Vector2D( xRight, yTop ), uv21 ); + vert[2].Init( Vector2D( xRight, yMid + 1 ), uv22 ); + vert[3].Init( Vector2D( xMid - 1, yMid + 1 ), uv12 ); + vgui::surface()->DrawTexturedPolygon( 4, vert ); + } + + // bottom right + vgui::surface()->DrawSetTexture( m_bAltScopeMode ? m_iScopeTextureAlt[2] : m_iScopeTexture[2] ); + vert[0].Init( Vector2D( xMid, yMid ), uv11 ); + vert[1].Init( Vector2D( xRight, yMid ), uv21 ); + vert[2].Init( Vector2D( xRight, yBottom ), uv22 ); + vert[3].Init( Vector2D( xMid, yBottom ), uv12 ); + vgui::surface()->DrawTexturedPolygon( 4, vert ); + + // bottom left + vgui::surface()->DrawSetTexture( m_bAltScopeMode ? m_iScopeTextureAlt[3] : m_iScopeTexture[3] ); + vert[0].Init( Vector2D( xLeft, yMid ), uv11 ); + vert[1].Init( Vector2D( xMid, yMid ), uv21 ); + vert[2].Init( Vector2D( xMid, yBottom ), uv22 ); + vert[3].Init( Vector2D( xLeft, yBottom), uv12 ); + vgui::surface()->DrawTexturedPolygon( 4, vert ); + + if ( xLeft > 0 ) + { + // Left block + vgui::surface()->DrawFilledRect( 0, 0, xLeft, screenTall ); + } + if ( screenWide > xRight ) + { + // Right block + vgui::surface()->DrawFilledRect( xRight, 0, screenWide, screenTall ); + } + if ( yTop > 0 ) + { + // top block + vgui::surface()->DrawFilledRect( 0, 0, screenWide, yTop ); + } + if ( screenTall > yBottom ) + { + // bottom block + vgui::surface()->DrawFilledRect( 0, yBottom, screenWide, screenTall ); + } + + if( bDisableClipping ) + g_pMatSystemSurface->DisableClipping( false ); + +}
\ No newline at end of file |