mirror of
https://github.com/nillerusr/source-engine.git
synced 2025-03-13 06:01:53 +00:00
initial GamepadUI from EZ2
This commit is contained in:
parent
29985681a1
commit
19ce478dd0
@ -820,7 +820,7 @@ void CVideoMode_Common::SetupStartupGraphic()
|
||||
// loading.vtf
|
||||
buf.Clear(); // added this Clear() because we saw cases where LoadVTF was not emptying the buf fully in the above section
|
||||
const char* loading = "materials/console/startup_loading.vtf";
|
||||
if ( IsSteamDeck() )
|
||||
if ( IsGamepadUI() )
|
||||
loading = "materials/gamepadui/game_logo.vtf";
|
||||
m_pLoadingTexture = LoadVTF( buf, loading );
|
||||
if ( !m_pLoadingTexture )
|
||||
@ -887,7 +887,7 @@ void CVideoMode_Common::DrawStartupGraphic()
|
||||
IMaterial *pMaterial = g_pMaterialSystem->CreateMaterial( "__background", pVMTKeyValues );
|
||||
|
||||
const char* loading = "console/startup_loading.vtf";
|
||||
if ( IsSteamDeck() )
|
||||
if ( IsGamepadUI() )
|
||||
loading = "gamepadui/game_logo.vtf";
|
||||
|
||||
pVMTKeyValues = new KeyValues( "UnlitGeneric" );
|
||||
@ -896,7 +896,7 @@ void CVideoMode_Common::DrawStartupGraphic()
|
||||
pVMTKeyValues->SetInt( "$ignorez", 1 );
|
||||
pVMTKeyValues->SetInt( "$nofog", 1 );
|
||||
pVMTKeyValues->SetInt( "$no_fullbright", 1 );
|
||||
pVMTKeyValues->SetInt( "$nocull", 1 );
|
||||
pVMTKeyValues->SetInt( "$nocull", 1 );
|
||||
IMaterial *pLoadingMaterial = g_pMaterialSystem->CreateMaterial( "__loading", pVMTKeyValues );
|
||||
|
||||
int w = GetModeStereoWidth();
|
||||
@ -929,7 +929,7 @@ void CVideoMode_Common::DrawStartupGraphic()
|
||||
slide = 0;
|
||||
|
||||
DrawScreenSpaceRectangle( pMaterial, 0, 0+slide, w, h-50, 0, 0, tw-1, th-1, tw, th, NULL,1,1,depth );
|
||||
if ( !IsSteamDeck() )
|
||||
if ( !IsGamepadUI() )
|
||||
DrawScreenSpaceRectangle( pLoadingMaterial, w-lw, h-lh+slide/2, lw, lh, 0, 0, lw-1, lh-1, lw, lh, NULL,1,1,depth-0.1 );
|
||||
else
|
||||
// TODO: Steam Deck
|
||||
@ -978,11 +978,15 @@ void CVideoMode_Common::DrawStartupGraphic()
|
||||
pRenderContext->ClearColor3ub( 0, 0, 0 );
|
||||
pRenderContext->ClearBuffers( true, true, true );
|
||||
DrawScreenSpaceRectangle( pMaterial, 0, 0, w, h, 0, 0, tw-1, th-1, tw, th, NULL,1,1,depth );
|
||||
DrawScreenSpaceRectangle( pLoadingMaterial, w-lw, h-lh, lw, lh, 0, 0, lw-1, lh-1, lw, lh, NULL,1,1,depth );
|
||||
if(!IsGamepadUI())
|
||||
DrawScreenSpaceRectangle( pLoadingMaterial, w-lw, h-lh, lw, lh, 0, 0, lw-1, lh-1, lw, lh, NULL,1,1,depth );
|
||||
|
||||
g_pMaterialSystem->SwapBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef DX_TO_GL_ABSTRACTION
|
||||
g_pMaterialSystem->DoStartupShaderPreloading();
|
||||
#endif
|
||||
|
@ -613,7 +613,7 @@ void CEngineVGui::Init()
|
||||
return;
|
||||
}
|
||||
|
||||
if ( IsX360() || IsSteamDeck() )
|
||||
if ( IsX360() || IsGamepadUI() )
|
||||
{
|
||||
CCommand ccommand;
|
||||
if ( CL_ShouldLoadBackgroundLevel( ccommand ) )
|
||||
@ -1273,12 +1273,18 @@ void CEngineVGui::OnLevelLoadingStarted()
|
||||
}
|
||||
}
|
||||
|
||||
if ( IsX360() || IsSteamDeck() )
|
||||
if ( IsX360() || !IsGamepadUI() )
|
||||
{
|
||||
// TCR requirement, always!!!
|
||||
m_bShowProgressDialog = true;
|
||||
}
|
||||
|
||||
// i dont want gamepadui menu while loading
|
||||
//if (IsGamepadUI())
|
||||
//{
|
||||
// m_bShowProgressDialog = false;
|
||||
//}
|
||||
|
||||
// we've starting loading a level/connecting to a server
|
||||
staticGameUIFuncs->OnLevelLoadingStarted( m_bShowProgressDialog );
|
||||
|
||||
|
@ -131,6 +131,11 @@
|
||||
#include "haptics/haptic_utils.h"
|
||||
#include "haptics/haptic_msgs.h"
|
||||
|
||||
#ifdef GAMEPADUI
|
||||
#include "../gamepadui/igamepadui.h"
|
||||
ConVar cl_gamepadui_mainmenu_draw("cl_gamepadui_mainmenu_draw", "0", FCVAR_DEVELOPMENTONLY);
|
||||
#endif // GAMEPADUI
|
||||
|
||||
#if defined( TF_CLIENT_DLL )
|
||||
#include "abuse_report.h"
|
||||
#endif
|
||||
@ -217,6 +222,10 @@ IEngineClientReplay *g_pEngineClientReplay = NULL;
|
||||
IReplaySystem *g_pReplay = NULL;
|
||||
#endif
|
||||
|
||||
#if defined(GAMEPADUI)
|
||||
IGamepadUI* g_pGamepadUI = nullptr;
|
||||
#endif // GAMEPADUI
|
||||
|
||||
IHaptics* haptics = NULL;// NVNT haptics system interface singleton
|
||||
|
||||
//=============================================================================
|
||||
@ -1156,6 +1165,54 @@ void CHLClient::PostInit()
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef PORTAL
|
||||
#if defined(GAMEPADUI)
|
||||
if (IsGamepadUI())
|
||||
{
|
||||
CSysModule* pGamepadUIModule = g_pFullFileSystem->LoadModule("gamepadui", "GAMEBIN", false);
|
||||
if (pGamepadUIModule != nullptr)
|
||||
{
|
||||
GamepadUI_Log("Loaded gamepadui module.\n");
|
||||
|
||||
CreateInterfaceFn gamepaduiFactory = Sys_GetFactory(pGamepadUIModule);
|
||||
if (gamepaduiFactory != nullptr)
|
||||
{
|
||||
g_pGamepadUI = (IGamepadUI*)gamepaduiFactory(GAMEPADUI_INTERFACE_VERSION, NULL);
|
||||
if (g_pGamepadUI != nullptr)
|
||||
{
|
||||
GamepadUI_Log("Initializing IGamepadUI interface...\n");
|
||||
|
||||
factorylist_t factories;
|
||||
FactoryList_Retrieve(factories);
|
||||
g_pGamepadUI->Initialize(factories.appSystemFactory);
|
||||
|
||||
#ifdef STEAM_INPUT
|
||||
g_pSteamInput->SetGamepadUI(true);
|
||||
g_pGamepadUI->SetSteamInput(g_pSteamInput);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
GamepadUI_Log("Unable to pull IGamepadUI interface.\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GamepadUI_Log("Unable to get gamepadui factory.\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GamepadUI_Log("Unable to load gamepadui module\n");
|
||||
}
|
||||
}
|
||||
#endif // GAMEPADUI
|
||||
#else
|
||||
if (IsGamepadUI())
|
||||
GamepadUI_Log("This version of GamepadUI doesnt work with portal 1. Idk why.");
|
||||
#endif // !PORTAL
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1196,6 +1253,11 @@ void CHLClient::Shutdown( void )
|
||||
UncacheAllMaterials();
|
||||
|
||||
IGameSystem::ShutdownAllSystems();
|
||||
|
||||
#if defined(GAMEPADUI)
|
||||
if (g_pGamepadUI != nullptr)
|
||||
g_pGamepadUI->Shutdown();
|
||||
#endif // GAMEPADUI
|
||||
|
||||
gHUD.Shutdown();
|
||||
VGui_Shutdown();
|
||||
@ -1243,6 +1305,11 @@ int CHLClient::HudVidInit( void )
|
||||
|
||||
GetClientVoiceMgr()->VidInit();
|
||||
|
||||
#if defined(GAMEPADUI)
|
||||
if (g_pGamepadUI != nullptr)
|
||||
g_pGamepadUI->VidInit();
|
||||
#endif // GAMEPADUI
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1293,6 +1360,11 @@ void CHLClient::HudUpdate( bool bActive )
|
||||
g_pSixenseInput->SixenseFrame( 0, NULL );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(GAMEPADUI)
|
||||
if (g_pGamepadUI != nullptr)
|
||||
g_pGamepadUI->OnUpdate(frametime);
|
||||
#endif // GAMEPADUI
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1301,6 +1373,7 @@ void CHLClient::HudUpdate( bool bActive )
|
||||
void CHLClient::HudReset( void )
|
||||
{
|
||||
gHUD.VidInit();
|
||||
|
||||
PhysicsReset();
|
||||
}
|
||||
|
||||
@ -1640,6 +1713,11 @@ void CHLClient::LevelInitPreEntity( char const* pMapName )
|
||||
CReplayRagdollRecorder::Instance().Init();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(GAMEPADUI)
|
||||
if (g_pGamepadUI != nullptr)
|
||||
g_pGamepadUI->OnLevelInitializePreEntity();
|
||||
#endif // GAMEPADUI
|
||||
}
|
||||
|
||||
|
||||
@ -1651,6 +1729,11 @@ void CHLClient::LevelInitPostEntity( )
|
||||
IGameSystem::LevelInitPostEntityAllSystems();
|
||||
C_PhysPropClientside::RecreateAll();
|
||||
internalCenterPrint->Clear();
|
||||
|
||||
#if defined(GAMEPADUI)
|
||||
if (g_pGamepadUI != nullptr)
|
||||
g_pGamepadUI->OnLevelInitializePostEntity();
|
||||
#endif // GAMEPADUI
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1717,6 +1800,11 @@ void CHLClient::LevelShutdown( void )
|
||||
|
||||
StopAllRumbleEffects();
|
||||
|
||||
#if defined(GAMEPADUI)
|
||||
if (g_pGamepadUI != nullptr)
|
||||
g_pGamepadUI->OnLevelShutdown();
|
||||
#endif // GAMEPADUI
|
||||
|
||||
gHUD.LevelShutdown();
|
||||
|
||||
internalCenterPrint->Clear();
|
||||
|
@ -55,6 +55,8 @@ $Configuration
|
||||
$PreprocessorDefinitions "$BASE;ENABLE_CHROMEHTMLWINDOW;fopen=dont_use_fopen" [$WIN32]
|
||||
$PreprocessorDefinitions "$BASE;ENABLE_CHROMEHTMLWINDOW;" [$OSXALL]
|
||||
$PreprocessorDefinitions "$BASE;ENABLE_CHROMEHTMLWINDOW;USE_WEBM_FOR_REPLAY;" [$LINUXALL]
|
||||
$PreprocessorDefinitions "$BASE;GAMEPADUI_DLL;"
|
||||
$PreprocessorDefinitions "$BASE;GAMEPADUI;"
|
||||
$PreprocessorDefinitions "$BASE;CURL_STATICLIB" [$WIN32 && $BUILD_REPLAY]
|
||||
$Create/UsePrecompiledHeader "Use Precompiled Header (/Yu)"
|
||||
$Create/UsePCHThroughFile "cbase.h"
|
||||
|
@ -13,7 +13,11 @@
|
||||
|
||||
// default FOV for HL1
|
||||
ConVar default_fov( "default_fov", "90", FCVAR_CHEAT );
|
||||
ConVar fov_desired( "fov_desired", "90", FCVAR_ARCHIVE | FCVAR_USERINFO, "Sets the base field-of-view.", true, 75.0, true, 110.0 );
|
||||
#ifdef GAMEPADUI
|
||||
ConVar fov_desired("fov_desired", "75", FCVAR_ARCHIVE | FCVAR_USERINFO, "Sets the base field-of-view.", true, 75.0, true, 120.0);
|
||||
#else
|
||||
ConVar fov_desired("fov_desired", "75", FCVAR_ARCHIVE | FCVAR_USERINFO, "Sets the base field-of-view.", true, 75.0, true, 110.0);
|
||||
#endif // GAMEPADUI
|
||||
|
||||
// The current client mode. Always ClientModeNormal in HL.
|
||||
IClientMode *g_pClientMode = NULL;
|
||||
|
@ -19,7 +19,11 @@
|
||||
|
||||
extern bool g_bRollingCredits;
|
||||
|
||||
#ifdef GAMEPADUI
|
||||
ConVar fov_desired("fov_desired", "75", FCVAR_ARCHIVE | FCVAR_USERINFO, "Sets the base field-of-view.", true, 75.0, true, 120.0);
|
||||
#else
|
||||
ConVar fov_desired( "fov_desired", "75", FCVAR_ARCHIVE | FCVAR_USERINFO, "Sets the base field-of-view.", true, 75.0, true, 110.0 );
|
||||
#endif // GAMEPADUI
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Globals
|
||||
|
@ -259,7 +259,7 @@ void CHudCrosshair::Paint( void )
|
||||
}
|
||||
|
||||
int iScreenDiv = 1600;
|
||||
if ( IsSteamDeck() )
|
||||
if ( IsGamepadUI() )
|
||||
iScreenDiv = 1440;
|
||||
|
||||
float flPlayerScale;
|
||||
|
@ -20,7 +20,11 @@
|
||||
|
||||
// default FOV for HL2
|
||||
ConVar default_fov( "default_fov", "75", FCVAR_CHEAT );
|
||||
ConVar fov_desired( "fov_desired", "75", FCVAR_ARCHIVE | FCVAR_USERINFO, "Sets the base field-of-view.", true, 75.0, true, 110.0 );
|
||||
#ifdef GAMEPADUI
|
||||
ConVar fov_desired("fov_desired", "75", FCVAR_ARCHIVE | FCVAR_USERINFO, "Sets the base field-of-view.", true, 75.0, true, 120.0);
|
||||
#else
|
||||
ConVar fov_desired("fov_desired", "75", FCVAR_ARCHIVE | FCVAR_USERINFO, "Sets the base field-of-view.", true, 75.0, true, 110.0);
|
||||
#endif // GAMEPADUI
|
||||
|
||||
// The current client mode. Always ClientModeNormal in HL.
|
||||
IClientMode *g_pClientMode = NULL;
|
||||
|
324
game/gamepadui/gamepadui_achievements.cpp
Normal file
324
game/gamepadui/gamepadui_achievements.cpp
Normal file
@ -0,0 +1,324 @@
|
||||
|
||||
#include "gamepadui_button.h"
|
||||
#include "gamepadui_frame.h"
|
||||
#include "gamepadui_scroll.h"
|
||||
#include "gamepadui_interface.h"
|
||||
#include "gamepadui_image.h"
|
||||
|
||||
#include "ienginevgui.h"
|
||||
#include "vgui/ILocalize.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "vgui/IVGui.h"
|
||||
#include "fmtstr.h"
|
||||
|
||||
#include "vgui_controls/ComboBox.h"
|
||||
#include "vgui_controls/ImagePanel.h"
|
||||
#include "vgui_controls/ScrollBar.h"
|
||||
|
||||
#include "KeyValues.h"
|
||||
#include "filesystem.h"
|
||||
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
class GamepadUIAchievement;
|
||||
|
||||
class GamepadUIAchievementsPanel : public GamepadUIFrame
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( GamepadUIAchievementsPanel, GamepadUIFrame );
|
||||
|
||||
public:
|
||||
GamepadUIAchievementsPanel( vgui::Panel *pParent, const char* pPanelName );
|
||||
|
||||
void UpdateGradients() OVERRIDE;
|
||||
|
||||
void OnThink() OVERRIDE;
|
||||
void OnCommand( char const* pCommand ) OVERRIDE;
|
||||
|
||||
MESSAGE_FUNC_HANDLE( OnGamepadUIButtonNavigatedTo, "OnGamepadUIButtonNavigatedTo", button );
|
||||
|
||||
void LayoutAchievementPanels();
|
||||
|
||||
void OnMouseWheeled( int nDelta ) OVERRIDE;
|
||||
|
||||
private:
|
||||
CUtlVector< GamepadUIAchievement* > m_pAchievementPanels;
|
||||
|
||||
GamepadUIScrollState m_ScrollState;
|
||||
|
||||
int m_nTotalAchievements = 0;
|
||||
int m_nUnlockedAchievements = 0;
|
||||
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_AchievementsFade, "Achievements.Fade", "0", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_AchievementsOffsetX, "Achievements.OffsetX", "0", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_AchievementsOffsetY, "Achievements.OffsetY", "0", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flAchievementsSpacing, "Achievements.Spacing", "0", SchemeValueTypes::ProportionalFloat );
|
||||
};
|
||||
|
||||
class GamepadUIAchievement : public GamepadUIButton
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS_SIMPLE( GamepadUIAchievement, GamepadUIButton );
|
||||
|
||||
GamepadUIAchievement( vgui::Panel* pParent, vgui::Panel* pActionSignalTarget, const char* pSchemeFile, const char* pCommand, const char* pText, const char* pDescription, const char *pChapterImage )
|
||||
: BaseClass( pParent, pActionSignalTarget, pSchemeFile, pCommand, pText, pDescription )
|
||||
, m_Image( pChapterImage )
|
||||
{
|
||||
}
|
||||
|
||||
GamepadUIAchievement( vgui::Panel* pParent, vgui::Panel* pActionSignalTarget, const char* pSchemeFile, const char* pCommand, const wchar* pText, const wchar* pDescription, const char *pChapterImage )
|
||||
: BaseClass( pParent, pActionSignalTarget, pSchemeFile, pCommand, pText, pDescription )
|
||||
, m_Image( pChapterImage )
|
||||
{
|
||||
}
|
||||
|
||||
void ApplySchemeSettings( vgui::IScheme* pScheme ) OVERRIDE
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
|
||||
m_hProgressFont = pScheme->GetFont( "Button.Progress.Font", true );
|
||||
}
|
||||
|
||||
void Paint() OVERRIDE
|
||||
{
|
||||
int x, y, w, t;
|
||||
GetBounds( x, y, w, t );
|
||||
|
||||
PaintButton();
|
||||
|
||||
vgui::surface()->DrawSetColor( m_colProgressColor );
|
||||
vgui::surface()->DrawFilledRect( 0, GetDrawHeight() - m_flProgressHeight, m_flWidth * m_flProgress, GetDrawHeight() );
|
||||
|
||||
if ( m_nGoal > 1 && m_flProgress > 0.0f )
|
||||
{
|
||||
vgui::surface()->DrawSetColor( m_colUnprogressColor );
|
||||
vgui::surface()->DrawFilledRect( m_flWidth * m_flProgress, GetDrawHeight() - m_flProgressHeight, m_flWidth, GetDrawHeight() );
|
||||
}
|
||||
|
||||
vgui::surface()->DrawSetColor( Color( 255, 255, 255, 255 ) );
|
||||
vgui::surface()->DrawSetTexture( m_Image );
|
||||
int nImageSize = m_flHeight - m_flIconInset * 2;
|
||||
vgui::surface()->DrawTexturedRect( m_flIconInset, m_flIconInset, m_flIconInset + nImageSize, m_flIconInset + nImageSize );
|
||||
vgui::surface()->DrawSetTexture( 0 );
|
||||
|
||||
PaintText();
|
||||
|
||||
if ( m_nGoal > 1 )
|
||||
{
|
||||
wchar_t wcsProgress[32];
|
||||
int nLength = V_swprintf_safe( wcsProgress, L"%d/%d", m_nCount, m_nGoal );
|
||||
vgui::surface()->DrawSetTextColor( m_colTextColor );
|
||||
vgui::surface()->DrawSetTextFont( m_hProgressFont );
|
||||
|
||||
int32 textSizeX = 0, textSizeY = 0;
|
||||
vgui::surface()->GetTextSize( m_hProgressFont, wcsProgress, textSizeX, textSizeY );
|
||||
int textPosX = m_flWidth - textSizeX - m_flProgressOffsetX;
|
||||
int textPosY = GetDrawHeight() / 2 - textSizeY / 2;
|
||||
|
||||
vgui::surface()->DrawSetTextPos( textPosX, textPosY );
|
||||
vgui::surface()->DrawPrintText( wcsProgress, nLength );
|
||||
}
|
||||
}
|
||||
|
||||
void SetProgress( bool bAchieved, int nCount, int nGoal )
|
||||
{
|
||||
m_nCount = nCount;
|
||||
m_nGoal = nGoal;
|
||||
|
||||
if (bAchieved)
|
||||
{
|
||||
m_flProgress = 1.0f;
|
||||
m_nCount = m_nGoal;
|
||||
}
|
||||
else
|
||||
m_flProgress = min( float( nCount ) / float( nGoal ), 1.0f );
|
||||
}
|
||||
|
||||
private:
|
||||
GamepadUIImage m_Image;
|
||||
|
||||
float m_flProgress = 0.0f;
|
||||
int m_nCount = 0;
|
||||
int m_nGoal = 0;
|
||||
|
||||
vgui::HFont m_hProgressFont = vgui::INVALID_FONT;
|
||||
|
||||
GAMEPADUI_PANEL_PROPERTY( Color, m_colProgressColor, "Button.Background.Progress", "255 0 0 255", SchemeValueTypes::Color );
|
||||
GAMEPADUI_PANEL_PROPERTY( Color, m_colUnprogressColor, "Button.Background.Unprogress", "255 0 0 255", SchemeValueTypes::Color );
|
||||
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flProgressHeight, "Button.Progress.Height", "1", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flIconInset, "Button.Icon.Inset", "0", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flProgressOffsetX, "Button.Progress.OffsetX", "0", SchemeValueTypes::ProportionalFloat );
|
||||
};
|
||||
|
||||
GamepadUIAchievementsPanel::GamepadUIAchievementsPanel( vgui::Panel *pParent, const char* pPanelName ) : BaseClass( pParent, pPanelName )
|
||||
{
|
||||
vgui::HScheme hScheme = vgui::scheme()->LoadSchemeFromFileEx( GamepadUI::GetInstance().GetSizingVPanel(), GAMEPADUI_DEFAULT_PANEL_SCHEME, "SchemePanel" );
|
||||
SetScheme( hScheme );
|
||||
|
||||
GetFrameTitle() = GamepadUIString( "#GameUI_Achievements_Title" );
|
||||
SetFooterButtons( FooterButtons::Back );
|
||||
|
||||
Activate();
|
||||
|
||||
GamepadUI::GetInstance().GetAchievementMgr()->EnsureGlobalStateLoaded();
|
||||
int nAllAchievements = GamepadUI::GetInstance().GetAchievementMgr()->GetAchievementCount();
|
||||
for ( int i = 0; i < nAllAchievements; i++ )
|
||||
{
|
||||
IAchievement *pCurAchievement = GamepadUI::GetInstance().GetAchievementMgr()->GetAchievementByIndex( i );
|
||||
if ( !pCurAchievement )
|
||||
continue;
|
||||
|
||||
if ( pCurAchievement->IsAchieved() )
|
||||
m_nUnlockedAchievements++;
|
||||
|
||||
// Don't show hidden achievements if not achieved.
|
||||
if ( pCurAchievement->ShouldHideUntilAchieved() && !pCurAchievement->IsAchieved() )
|
||||
continue;
|
||||
|
||||
char szIconName[MAX_PATH];
|
||||
V_sprintf_safe( szIconName, "gamepadui/achievements/%s%s.vmt", pCurAchievement->GetName(), pCurAchievement->IsAchieved() ? "" : "_bw" );
|
||||
|
||||
char szMaterialName[MAX_PATH];
|
||||
V_sprintf_safe( szMaterialName, "materials/%s", szIconName );
|
||||
if ( !g_pFullFileSystem->FileExists( szMaterialName ) )
|
||||
V_sprintf_safe( szIconName, "vgui/achievements/%s%s.vmt", pCurAchievement->GetName(), pCurAchievement->IsAchieved() ? "" : "_bw" );
|
||||
|
||||
V_sprintf_safe( szMaterialName, "materials/%s", szIconName );
|
||||
if ( !g_pFullFileSystem->FileExists( szMaterialName ) )
|
||||
V_strcpy_safe( szIconName, "vgui/hud/icon_locked.vmt" );
|
||||
|
||||
auto pAchievementPanel = new GamepadUIAchievement(
|
||||
this, this,
|
||||
GAMEPADUI_RESOURCE_FOLDER "schemeachievement.res",
|
||||
"",
|
||||
ACHIEVEMENT_LOCALIZED_NAME( pCurAchievement ),
|
||||
ACHIEVEMENT_LOCALIZED_DESC( pCurAchievement ),
|
||||
szIconName );
|
||||
pAchievementPanel->SetProgress( pCurAchievement->IsAchieved(), pCurAchievement->GetCount(), pCurAchievement->GetGoal() );
|
||||
pAchievementPanel->SetPriority( m_nTotalAchievements );
|
||||
m_pAchievementPanels.AddToTail( pAchievementPanel );
|
||||
|
||||
m_nTotalAchievements++;
|
||||
}
|
||||
|
||||
if ( m_pAchievementPanels.Count() )
|
||||
m_pAchievementPanels[0]->NavigateTo();
|
||||
|
||||
for ( int i = 1; i < m_pAchievementPanels.Count(); i++ )
|
||||
{
|
||||
m_pAchievementPanels[i]->SetNavUp( m_pAchievementPanels[i - 1] );
|
||||
m_pAchievementPanels[i - 1]->SetNavDown( m_pAchievementPanels[i] );
|
||||
}
|
||||
|
||||
UpdateGradients();
|
||||
}
|
||||
|
||||
void GamepadUIAchievementsPanel::UpdateGradients()
|
||||
{
|
||||
const float flTime = GamepadUI::GetInstance().GetTime();
|
||||
GamepadUI::GetInstance().GetGradientHelper()->ResetTargets( flTime );
|
||||
GamepadUI::GetInstance().GetGradientHelper()->SetTargetGradient( GradientSide::Up, { 1.0f, 1.0f }, flTime );
|
||||
GamepadUI::GetInstance().GetGradientHelper()->SetTargetGradient( GradientSide::Down, { 1.0f, 0.5f }, flTime );
|
||||
}
|
||||
|
||||
void GamepadUIAchievementsPanel::OnThink()
|
||||
{
|
||||
BaseClass::OnThink();
|
||||
|
||||
LayoutAchievementPanels();
|
||||
}
|
||||
|
||||
void GamepadUIAchievementsPanel::OnGamepadUIButtonNavigatedTo( vgui::VPANEL button )
|
||||
{
|
||||
GamepadUIButton *pButton = dynamic_cast< GamepadUIButton * >( vgui::ipanel()->GetPanel( button, GetModuleName() ) );
|
||||
if ( pButton )
|
||||
{
|
||||
if ( pButton->GetAlpha() != 255 )
|
||||
{
|
||||
int nParentW, nParentH;
|
||||
GetParent()->GetSize( nParentW, nParentH );
|
||||
|
||||
int nX, nY;
|
||||
pButton->GetPos( nX, nY );
|
||||
|
||||
int nTargetY = pButton->GetPriority() * (pButton->m_flHeightAnimationValue[ButtonStates::Out] + m_flAchievementsSpacing);
|
||||
|
||||
if ( nY < nParentH / 2 )
|
||||
{
|
||||
nTargetY += nParentH - m_AchievementsOffsetY;
|
||||
// Add a bit of spacing to make this more visually appealing :)
|
||||
nTargetY -= m_flAchievementsSpacing;
|
||||
}
|
||||
else
|
||||
{
|
||||
nTargetY += pButton->GetMaxHeight();
|
||||
// Add a bit of spacing to make this more visually appealing :)
|
||||
nTargetY += (pButton->GetMaxHeight() / 2) + 2 * m_flAchievementsSpacing;
|
||||
}
|
||||
|
||||
|
||||
m_ScrollState.SetScrollTarget( nTargetY - ( nParentH - m_AchievementsOffsetY ), GamepadUI::GetInstance().GetTime() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GamepadUIAchievementsPanel::LayoutAchievementPanels()
|
||||
{
|
||||
int nParentW, nParentH;
|
||||
GetParent()->GetSize( nParentW, nParentH );
|
||||
|
||||
float flScrollClamp = 0.0f;
|
||||
for ( int i = 0; i < m_pAchievementPanels.Count(); i++ )
|
||||
{
|
||||
int size = ( m_pAchievementPanels[i]->GetTall() + m_flAchievementsSpacing );
|
||||
|
||||
if ( i < m_pAchievementPanels.Count() - 2 )
|
||||
flScrollClamp += size;
|
||||
}
|
||||
|
||||
m_ScrollState.UpdateScrollBounds( 0.0f, flScrollClamp );
|
||||
|
||||
int previousSizes = 0;
|
||||
for ( int i = 0; i < m_pAchievementPanels.Count(); i++ )
|
||||
{
|
||||
int tall = m_pAchievementPanels[i]->GetTall();
|
||||
int size = ( tall + m_flAchievementsSpacing );
|
||||
|
||||
int y = m_AchievementsOffsetY + previousSizes - m_ScrollState.GetScrollProgress();
|
||||
int fade = 255;
|
||||
if ( y < m_AchievementsOffsetY )
|
||||
fade = ( 1.0f - clamp( -( y - m_AchievementsOffsetY ) / m_AchievementsFade, 0.0f, 1.0f ) ) * 255.0f;
|
||||
if ( y > nParentH - m_AchievementsFade )
|
||||
fade = ( 1.0f - clamp(( y - ( nParentH - m_AchievementsFade - size ) ) / m_AchievementsFade, 0.0f, 1.0f ) ) * 255.0f;
|
||||
if ( m_pAchievementPanels[i]->HasFocus() && fade != 0 )
|
||||
fade = 255;
|
||||
m_pAchievementPanels[i]->SetAlpha( fade );
|
||||
m_pAchievementPanels[i]->SetPos( m_AchievementsOffsetX, y );
|
||||
m_pAchievementPanels[i]->SetVisible( true );
|
||||
previousSizes += size;
|
||||
}
|
||||
|
||||
m_ScrollState.UpdateScrolling( 2.0f, GamepadUI::GetInstance().GetTime() );
|
||||
}
|
||||
|
||||
void GamepadUIAchievementsPanel::OnCommand( char const* pCommand )
|
||||
{
|
||||
if ( !V_strcmp( pCommand, "action_back" ) )
|
||||
{
|
||||
Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseClass::OnCommand( pCommand );
|
||||
}
|
||||
}
|
||||
|
||||
void GamepadUIAchievementsPanel::OnMouseWheeled( int nDelta )
|
||||
{
|
||||
m_ScrollState.OnMouseWheeled( nDelta * 160.0f, GamepadUI::GetInstance().GetTime() );
|
||||
}
|
||||
|
||||
CON_COMMAND( gamepadui_openachievementsdialog, "" )
|
||||
{
|
||||
new GamepadUIAchievementsPanel( GamepadUI::GetInstance().GetBasePanel(), "AchievementsPanel" );
|
||||
}
|
137
game/gamepadui/gamepadui_base.vpc
Normal file
137
game/gamepadui/gamepadui_base.vpc
Normal file
@ -0,0 +1,137 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// GAMEPADUI_BASE.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro OUTBINDIR "$SRCDIR\..\game\$GAMENAME\bin"
|
||||
|
||||
$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc"
|
||||
|
||||
$Configuration "Debug"
|
||||
{
|
||||
$General
|
||||
{
|
||||
$OutputDirectory ".\Debug_$GAMENAME" [$WINDOWS]
|
||||
$IntermediateDirectory ".\Debug_$GAMENAME" [$WINDOWS]
|
||||
}
|
||||
}
|
||||
|
||||
$Configuration "Release"
|
||||
{
|
||||
$General
|
||||
{
|
||||
$OutputDirectory ".\Release_$GAMENAME" [$WINDOWS]
|
||||
$IntermediateDirectory ".\Release_$GAMENAME" [$WINDOWS]
|
||||
}
|
||||
}
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$General
|
||||
{
|
||||
$OutputDirectory ".\$GAMENAME" [$OSXALL]
|
||||
}
|
||||
|
||||
$Compiler
|
||||
{
|
||||
$AdditionalIncludeDirectories "$BASE;.\;$SRCDIR\vgui2\include;$SRCDIR\vgui2\controls;$SRCDIR\game\gamepadui;..\..\public"
|
||||
$PreprocessorDefinitions "$BASE;GAMEPADUI_DLL;VERSION_SAFE_STEAM_API_INTERFACES;strncpy=use_Q_strncpy_instead;_snprintf=use_Q_snprintf_instead"
|
||||
}
|
||||
|
||||
$Linker
|
||||
{
|
||||
$SystemLibraries "iconv" [$OSXALL]
|
||||
$SystemFrameworks "Carbon" [$OSXALL]
|
||||
$SystemLibraries "rt" [$LINUXALL]
|
||||
$IgnoreImportLibrary "TRUE"
|
||||
$AdditionalDependencies "$BASE winmm.lib" [$WINDOWS]
|
||||
$AdditionalDependencies "$BASE wsock32.lib Ws2_32.lib" [$BUILD_REPLAY]
|
||||
}
|
||||
}
|
||||
|
||||
$Project
|
||||
{
|
||||
$Folder "Header Files"
|
||||
{
|
||||
$Folder "Public"
|
||||
{
|
||||
$File "igamepadui.h"
|
||||
}
|
||||
|
||||
$File "gamepadui_basepanel.h"
|
||||
$File "gamepadui_button.h"
|
||||
$File "gamepadui_frame.h"
|
||||
$File "gamepadui_genericconfirmation.h"
|
||||
$File "gamepadui_genericframes.h"
|
||||
$File "gamepadui_gradient_helper.h"
|
||||
$File "gamepadui_image.h"
|
||||
$File "gamepadui_interface.h"
|
||||
$File "gamepadui_mainmenu.h"
|
||||
$File "gamepadui_panel.h"
|
||||
$File "gamepadui_scroll.h"
|
||||
$File "gamepadui_string.h"
|
||||
$File "gamepadui_scrollbar.h"
|
||||
$File "gamepadui_util.h"
|
||||
}
|
||||
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$Folder "Common"
|
||||
{
|
||||
$File "$SRCDIR\public\vgui_controls\vgui_controls.cpp"
|
||||
$File "$SRCDIR\common\language.cpp"
|
||||
}
|
||||
|
||||
$File "gamepadui_achievements.cpp"
|
||||
$File "gamepadui_basepanel.cpp"
|
||||
$File "gamepadui_button.cpp"
|
||||
$File "gamepadui_frame.cpp"
|
||||
$File "gamepadui_genericconfirmation.cpp"
|
||||
$File "gamepadui_genericframes.cpp"
|
||||
$File "gamepadui_interface.cpp"
|
||||
$File "gamepadui_mainmenu.cpp"
|
||||
$File "gamepadui_newgame.cpp"
|
||||
$File "gamepadui_savegame.cpp"
|
||||
$File "gamepadui_options.cpp"
|
||||
$File "gamepadui_scrollbar.cpp"
|
||||
$File "gamepadui_util.cpp"
|
||||
}
|
||||
|
||||
$Folder "Link Libraries"
|
||||
{
|
||||
$Lib bitmap
|
||||
$Lib choreoobjects
|
||||
$Lib mathlib
|
||||
$Lib matsys_controls
|
||||
$Lib tier1
|
||||
$Lib tier2
|
||||
$Lib tier3
|
||||
$Lib vgui_controls
|
||||
$Lib vtf
|
||||
|
||||
$Lib expanded_steam [$STEAM_INPUT]
|
||||
$ImpLib steam_api [$STEAM_INPUT]
|
||||
$Lib "$LIBCOMMON\libpng" [$STEAM_INPUT]
|
||||
|
||||
// these are only necessary if HL2_RETAIL is enabled.
|
||||
$ImpLib steam_api [$HL2_RETAIl]
|
||||
$Lib "$LIBCOMMON/libjpeg" [$HL2_RETAIl]
|
||||
$Lib libpng [$HL2_RETAIl]
|
||||
|
||||
$Lib $LIBCOMMON/libcrypto [$POSIX]
|
||||
|
||||
$ImpLib "$LIBCOMMON\curl" [$OSXALL]
|
||||
|
||||
$Lib "$LIBCOMMON\libcurl" [$WIN32]
|
||||
$Lib "libz" [$WINDOWS]
|
||||
|
||||
$ImpLib "SDL2" [$SDL]
|
||||
|
||||
$Libexternal libz [$LINUXALL]
|
||||
$Libexternal "$LIBCOMMON/libcurl" [$LINUXALL]
|
||||
$Libexternal "$LIBCOMMON/libcurlssl" [$LINUXALL]
|
||||
$Libexternal "$LIBCOMMON/libssl" [$LINUXALL]
|
||||
}
|
||||
|
||||
}
|
243
game/gamepadui/gamepadui_basepanel.cpp
Normal file
243
game/gamepadui/gamepadui_basepanel.cpp
Normal file
@ -0,0 +1,243 @@
|
||||
#include "gamepadui_basepanel.h"
|
||||
#include "gamepadui_mainmenu.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef INVALID_HANDLE_VALUE
|
||||
#undef INVALID_HANDLE_VALUE
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include "icommandline.h"
|
||||
#include "filesystem.h"
|
||||
#include "gamepadui_interface.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
ConVar gamepadui_background_music_duck( "gamepadui_background_music_duck", "0.35", FCVAR_ARCHIVE );
|
||||
ConVar gamepadui_sizing_panel_width( "gamepadui_sizing_panel_width", "1280", FCVAR_ARCHIVE );
|
||||
ConVar gamepadui_sizing_panel_height( "gamepadui_sizing_panel_height", "800", FCVAR_ARCHIVE );
|
||||
|
||||
GamepadUIBasePanel::GamepadUIBasePanel( vgui::VPANEL parent ) : BaseClass( NULL, "GamepadUIBasePanel" )
|
||||
{
|
||||
SetParent( parent );
|
||||
MakePopup( false );
|
||||
|
||||
m_nBackgroundMusicGUID = 0;
|
||||
m_bBackgroundMusicEnabled = !CommandLine()->FindParm( "-nostartupsound" );
|
||||
|
||||
m_pSizingPanel = new GamepadUISizingPanel( this );
|
||||
|
||||
m_pMainMenu = new GamepadUIMainMenu( this );
|
||||
OnMenuStateChanged();
|
||||
}
|
||||
|
||||
void GamepadUIBasePanel::ApplySchemeSettings( vgui::IScheme* pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
|
||||
// Josh: Need to use GetVParent because this is across
|
||||
// a DLL boundary.
|
||||
int nVParentW, nVParentH;
|
||||
vgui::ipanel()->GetSize( GetVParent(), nVParentW, nVParentH );
|
||||
SetBounds( 0, 0, nVParentW, nVParentH );
|
||||
|
||||
// Josh:
|
||||
// Force the main menu to invalidate itself.
|
||||
// There is a weird ordering bug in VGUI we need to workaround.
|
||||
m_pMainMenu->InvalidateLayout( false, true );
|
||||
|
||||
m_pSizingPanel->InvalidateLayout( false, true );
|
||||
}
|
||||
|
||||
GamepadUISizingPanel *GamepadUIBasePanel::GetSizingPanel() const
|
||||
{
|
||||
return m_pSizingPanel;
|
||||
}
|
||||
|
||||
GamepadUIMainMenu* GamepadUIBasePanel::GetMainMenuPanel() const
|
||||
{
|
||||
return m_pMainMenu;
|
||||
}
|
||||
|
||||
GamepadUIFrame *GamepadUIBasePanel::GetCurrentFrame() const
|
||||
{
|
||||
return m_pCurrentFrame;
|
||||
}
|
||||
|
||||
void GamepadUIBasePanel::SetCurrentFrame( GamepadUIFrame *pFrame )
|
||||
{
|
||||
if (pFrame != NULL && m_pCurrentFrame != NULL)
|
||||
{
|
||||
// If there's already a frame, close it
|
||||
m_pCurrentFrame->Close();
|
||||
}
|
||||
|
||||
m_pCurrentFrame = pFrame;
|
||||
}
|
||||
|
||||
|
||||
void GamepadUIBasePanel::OnMenuStateChanged()
|
||||
{
|
||||
if ( m_bBackgroundMusicEnabled && GamepadUI::GetInstance().IsGamepadUIVisible() )
|
||||
{
|
||||
if ( !IsBackgroundMusicPlaying() )
|
||||
ActivateBackgroundEffects();
|
||||
}
|
||||
else
|
||||
ReleaseBackgroundMusic();
|
||||
|
||||
if (m_pCurrentFrame && m_pCurrentFrame != m_pMainMenu)
|
||||
{
|
||||
m_pCurrentFrame->Close();
|
||||
m_pCurrentFrame = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void GamepadUIBasePanel::ActivateBackgroundEffects()
|
||||
{
|
||||
StartBackgroundMusic( 1.0f );
|
||||
}
|
||||
|
||||
bool GamepadUIBasePanel::IsBackgroundMusicPlaying()
|
||||
{
|
||||
if ( !m_nBackgroundMusicGUID )
|
||||
return false;
|
||||
|
||||
return GamepadUI::GetInstance().GetEngineSound()->IsSoundStillPlaying( m_nBackgroundMusicGUID );
|
||||
}
|
||||
|
||||
bool GamepadUIBasePanel::StartBackgroundMusic( float flVolume )
|
||||
{
|
||||
if ( IsBackgroundMusicPlaying() )
|
||||
return true;
|
||||
|
||||
/* mostly from GameUI */
|
||||
char path[ 512 ];
|
||||
Q_snprintf( path, sizeof( path ), "sound/ui/gamestartup*.mp3" );
|
||||
Q_FixSlashes( path );
|
||||
CUtlVector<char*> fileNames;
|
||||
FileFindHandle_t fh;
|
||||
|
||||
char const *fn = g_pFullFileSystem->FindFirstEx( path, "MOD", &fh );
|
||||
if ( fn )
|
||||
{
|
||||
do
|
||||
{
|
||||
char ext[ 10 ];
|
||||
Q_ExtractFileExtension( fn, ext, sizeof( ext ) );
|
||||
|
||||
if ( !Q_stricmp( ext, "mp3" ) )
|
||||
{
|
||||
char temp[ 512 ];
|
||||
{
|
||||
Q_snprintf( temp, sizeof( temp ), "ui/%s", fn );
|
||||
}
|
||||
|
||||
char *found = new char[ strlen( temp ) + 1 ];
|
||||
Q_strncpy( found, temp, strlen( temp ) + 1 );
|
||||
|
||||
Q_FixSlashes( found );
|
||||
fileNames.AddToTail( found );
|
||||
}
|
||||
|
||||
fn = g_pFullFileSystem->FindNext( fh );
|
||||
|
||||
} while ( fn );
|
||||
|
||||
g_pFullFileSystem->FindClose( fh );
|
||||
}
|
||||
|
||||
if ( !fileNames.Count() )
|
||||
return false;
|
||||
|
||||
#ifdef WIN32
|
||||
SYSTEMTIME SystemTime;
|
||||
GetSystemTime( &SystemTime );
|
||||
int index = SystemTime.wMilliseconds % fileNames.Count();
|
||||
#else
|
||||
struct timeval tm;
|
||||
gettimeofday( &tm, NULL );
|
||||
int index = tm.tv_usec/1000 % fileNames.Count();
|
||||
#endif
|
||||
|
||||
const char* pSoundFile = NULL;
|
||||
|
||||
if ( fileNames.IsValidIndex(index) && fileNames[index] )
|
||||
pSoundFile = fileNames[ index ];
|
||||
|
||||
if ( !pSoundFile )
|
||||
return false;
|
||||
|
||||
// check and see if we have a background map loaded.
|
||||
// if not, this code path won't properly play the music.
|
||||
const bool bInGame = GamepadUI::GetInstance().GetEngineClient()->IsLevelMainMenuBackground();
|
||||
if ( bInGame )
|
||||
{
|
||||
// mixes too loud against soft ui sounds
|
||||
GamepadUI::GetInstance().GetEngineSound()->EmitAmbientSound( pSoundFile, gamepadui_background_music_duck.GetFloat() * flVolume );
|
||||
m_nBackgroundMusicGUID = GamepadUI::GetInstance().GetEngineSound()->GetGuidForLastSoundEmitted();
|
||||
}
|
||||
else
|
||||
{
|
||||
// old way, failsafe in case we don't have a background level.
|
||||
char found[ 512 ];
|
||||
Q_snprintf( found, sizeof( found ), "play *#%s\n", pSoundFile );
|
||||
GamepadUI::GetInstance().GetEngineClient()->ClientCmd_Unrestricted( found );
|
||||
}
|
||||
|
||||
fileNames.PurgeAndDeleteElements();
|
||||
|
||||
return m_nBackgroundMusicGUID != 0;
|
||||
}
|
||||
|
||||
void GamepadUIBasePanel::ReleaseBackgroundMusic()
|
||||
{
|
||||
if ( !m_nBackgroundMusicGUID )
|
||||
return;
|
||||
|
||||
// need to stop the sound now, do not queue the stop
|
||||
// we must release the 2-5MB held by this resource
|
||||
GamepadUI::GetInstance().GetEngineSound()->StopSoundByGuid( m_nBackgroundMusicGUID );
|
||||
m_nBackgroundMusicGUID = 0;
|
||||
}
|
||||
|
||||
GamepadUISizingPanel::GamepadUISizingPanel( vgui::Panel *pParent ) : BaseClass( pParent, "GamepadUISizingPanel" )
|
||||
{
|
||||
SetVisible( false );
|
||||
}
|
||||
|
||||
void GamepadUISizingPanel::ApplySchemeSettings( vgui::IScheme* pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
|
||||
int w = GetParent()->GetWide();
|
||||
int h = GetParent()->GetTall();
|
||||
|
||||
float flX, flY;
|
||||
GamepadUI::GetInstance().GetScreenRatio( flX, flY );
|
||||
|
||||
float targetW = gamepadui_sizing_panel_width.GetFloat() * flX;
|
||||
float targetH = gamepadui_sizing_panel_height.GetFloat() * flY;
|
||||
|
||||
w -= targetW;
|
||||
h -= targetH;
|
||||
if (w <= 0 || h <= 0)
|
||||
{
|
||||
GamepadUI_Log( "Setting sizing panel bounds to 0, 0, %i, %i (proportional)\n", GetParent()->GetWide(), GetParent()->GetTall() );
|
||||
SetBounds( 0, 0, GetParent()->GetWide(), GetParent()->GetTall() );
|
||||
|
||||
m_flScaleX = m_flScaleY = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
GamepadUI_Log( "Setting sizing panel bounds to %i, %i, %i, %i\n", w/2, h/2, (int)targetW, (int)targetH );
|
||||
SetBounds( w/2, h/2, targetW, targetH );
|
||||
|
||||
m_flScaleX = ((float)GetParent()->GetWide()) / targetW;
|
||||
m_flScaleY = ((float)GetParent()->GetTall()) / targetH;
|
||||
}
|
||||
}
|
60
game/gamepadui/gamepadui_basepanel.h
Normal file
60
game/gamepadui/gamepadui_basepanel.h
Normal file
@ -0,0 +1,60 @@
|
||||
#ifndef GAMEPADUI_BASEPANEL_H
|
||||
#define GAMEPADUI_BASEPANEL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "gamepadui_interface.h"
|
||||
|
||||
class GamepadUIMainMenu;
|
||||
class GamepadUIFrame;
|
||||
|
||||
class GamepadUIBasePanel : public vgui::Panel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( GamepadUIBasePanel, vgui::Panel );
|
||||
public:
|
||||
GamepadUIBasePanel( vgui::VPANEL parent );
|
||||
|
||||
void ApplySchemeSettings( vgui::IScheme* pScheme ) OVERRIDE;
|
||||
|
||||
GamepadUISizingPanel *GetSizingPanel() const;
|
||||
GamepadUIMainMenu *GetMainMenuPanel() const;
|
||||
|
||||
GamepadUIFrame *GetCurrentFrame() const;
|
||||
void SetCurrentFrame( GamepadUIFrame *pFrame );
|
||||
|
||||
void OnMenuStateChanged();
|
||||
|
||||
void ActivateBackgroundEffects();
|
||||
bool IsBackgroundMusicPlaying();
|
||||
bool StartBackgroundMusic( float flVolume );
|
||||
void ReleaseBackgroundMusic();
|
||||
|
||||
private:
|
||||
GamepadUISizingPanel *m_pSizingPanel = NULL;
|
||||
GamepadUIMainMenu *m_pMainMenu = NULL;
|
||||
|
||||
GamepadUIFrame *m_pCurrentFrame = NULL;
|
||||
|
||||
int m_nBackgroundMusicGUID;
|
||||
bool m_bBackgroundMusicEnabled;
|
||||
|
||||
};
|
||||
|
||||
class GamepadUISizingPanel : public vgui::Panel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( GamepadUISizingPanel, vgui::Panel );
|
||||
public:
|
||||
GamepadUISizingPanel( vgui::Panel *pParent );
|
||||
|
||||
void ApplySchemeSettings( vgui::IScheme* pScheme ) OVERRIDE;
|
||||
|
||||
void GetScale( float &flX, float &flY ) const { flX = m_flScaleX; flY = m_flScaleY; }
|
||||
|
||||
private:
|
||||
|
||||
float m_flScaleX;
|
||||
float m_flScaleY;
|
||||
};
|
||||
|
||||
#endif // GAMEPADUI_BASEPANEL_H
|
1375
game/gamepadui/gamepadui_bonusmaps.cpp
Normal file
1375
game/gamepadui/gamepadui_bonusmaps.cpp
Normal file
File diff suppressed because it is too large
Load Diff
419
game/gamepadui/gamepadui_button.cpp
Normal file
419
game/gamepadui/gamepadui_button.cpp
Normal file
@ -0,0 +1,419 @@
|
||||
#include "gamepadui_button.h"
|
||||
#include "gamepadui_interface.h"
|
||||
#include "gamepadui_util.h"
|
||||
|
||||
#include "vgui/IVGui.h"
|
||||
#include "vgui/ISurface.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#define DEFAULT_BTN_ARMED_SOUND "ui/buttonrollover.wav"
|
||||
#define DEFAULT_BTN_RELEASED_SOUND "ui/buttonclickrelease.wav"
|
||||
|
||||
ConVar gamepadui_center_footer_buttons( "gamepadui_center_footer_buttons", "1", FCVAR_NONE, "Centers footer buttons when not using gamepad" );
|
||||
|
||||
GamepadUIButton::GamepadUIButton( vgui::Panel *pParent, vgui::Panel* pActionSignalTarget, const char *pSchemeFile, const char *pCommand, const char *pText, const char *pDescription )
|
||||
: BaseClass( pParent, "", "", pActionSignalTarget, pCommand )
|
||||
, m_strButtonText( pText )
|
||||
, m_strButtonDescription( pDescription )
|
||||
{
|
||||
SetScheme( vgui::scheme()->LoadSchemeFromFileEx( GamepadUI::GetInstance().GetSizingVPanel(), pSchemeFile, "SchemePanel" ) );
|
||||
}
|
||||
|
||||
GamepadUIButton::GamepadUIButton( vgui::Panel *pParent, vgui::Panel* pActionSignalTarget, const char *pSchemeFile, const char *pCommand, const wchar_t *pText, const wchar_t *pDescription )
|
||||
: BaseClass( pParent, "", "", pActionSignalTarget, pCommand )
|
||||
, m_strButtonText( pText )
|
||||
, m_strButtonDescription( pDescription )
|
||||
{
|
||||
SetScheme( vgui::scheme()->LoadSchemeFromFileEx( GamepadUI::GetInstance().GetSizingVPanel(), pSchemeFile, "SchemePanel" ) );
|
||||
}
|
||||
|
||||
void GamepadUIButton::ApplySchemeSettings(vgui::IScheme* pScheme)
|
||||
{
|
||||
BaseClass::ApplySchemeSettings(pScheme);
|
||||
|
||||
const char *pButtonSound = pScheme->GetResourceString( "Button.Sound.Armed" );
|
||||
if (pButtonSound && *pButtonSound)
|
||||
SetArmedSound( pButtonSound );
|
||||
else
|
||||
SetArmedSound( DEFAULT_BTN_ARMED_SOUND );
|
||||
|
||||
pButtonSound = pScheme->GetResourceString( "Button.Sound.Released" );
|
||||
if (pButtonSound && *pButtonSound)
|
||||
SetReleasedSound( pButtonSound );
|
||||
else
|
||||
SetReleasedSound( DEFAULT_BTN_RELEASED_SOUND );
|
||||
|
||||
pButtonSound = pScheme->GetResourceString( "Button.Sound.Depressed" );
|
||||
if (pButtonSound && *pButtonSound)
|
||||
SetDepressedSound( pButtonSound );
|
||||
|
||||
SetPaintBorderEnabled( false );
|
||||
SetPaintBackgroundEnabled( false );
|
||||
SetConsoleStylePanel( true );
|
||||
|
||||
UpdateSchemeProperties( this, pScheme );
|
||||
|
||||
m_hTextFont = pScheme->GetFont( "Button.Text.Font", true );
|
||||
m_hTextFontOver = pScheme->GetFont( "Button.Text.Font.Over", true );
|
||||
if (m_hTextFontOver == vgui::INVALID_FONT )
|
||||
m_hTextFontOver = m_hTextFont;
|
||||
m_hDescriptionFont = pScheme->GetFont( "Button.Description.Font", true );
|
||||
|
||||
m_ePreviousState = ButtonStates::Out;
|
||||
|
||||
m_flCachedExtraHeight = 0.0f;
|
||||
if (!m_strButtonDescription.IsEmpty())
|
||||
{
|
||||
if ( m_bDescriptionWrap )
|
||||
m_flCachedExtraHeight = DrawPrintWrappedText(m_hDescriptionFont, 0, 0, m_strButtonDescription.String(), m_strButtonDescription.Length(), m_flWidthAnimationValue[ButtonStates::Over] - 2 * (m_flDescriptionOffsetX + m_flTextOffsetX), false);
|
||||
else
|
||||
m_flCachedExtraHeight = 0.0f;
|
||||
}
|
||||
|
||||
float flX, flY;
|
||||
if (GamepadUI::GetInstance().GetScreenRatio( flX, flY ))
|
||||
{
|
||||
if (flX != 1.0f)
|
||||
{
|
||||
m_flWidth *= flX;
|
||||
for (int i = 0; i < ButtonStates::Count; i++)
|
||||
m_flWidthAnimationValue[i] *= flX;
|
||||
}
|
||||
if (flY != 1.0f)
|
||||
{
|
||||
m_flHeight *= flY;
|
||||
for (int i = 0; i < ButtonStates::Count; i++)
|
||||
m_flHeightAnimationValue[i] *= flY;
|
||||
}
|
||||
}
|
||||
|
||||
SetSize( m_flWidth, m_flHeight + m_flExtraHeight );
|
||||
DoAnimations( true );
|
||||
}
|
||||
|
||||
void GamepadUIButton::RunAnimations( ButtonState state )
|
||||
{
|
||||
GAMEPADUI_RUN_ANIMATION_COMMAND( m_flWidth, vgui::AnimationController::INTERPOLATOR_LINEAR );
|
||||
GAMEPADUI_RUN_ANIMATION_COMMAND( m_flHeight, vgui::AnimationController::INTERPOLATOR_LINEAR );
|
||||
GAMEPADUI_RUN_ANIMATION_COMMAND( m_flTextOffsetX, vgui::AnimationController::INTERPOLATOR_LINEAR );
|
||||
GAMEPADUI_RUN_ANIMATION_COMMAND( m_flTextOffsetY, vgui::AnimationController::INTERPOLATOR_LINEAR );
|
||||
GAMEPADUI_RUN_ANIMATION_COMMAND( m_flDescriptionOffsetX, vgui::AnimationController::INTERPOLATOR_LINEAR );
|
||||
GAMEPADUI_RUN_ANIMATION_COMMAND( m_flDescriptionOffsetY, vgui::AnimationController::INTERPOLATOR_LINEAR );
|
||||
GAMEPADUI_RUN_ANIMATION_COMMAND( m_colBackgroundColor, vgui::AnimationController::INTERPOLATOR_LINEAR );
|
||||
GAMEPADUI_RUN_ANIMATION_COMMAND( m_colTextColor, vgui::AnimationController::INTERPOLATOR_LINEAR );
|
||||
GAMEPADUI_RUN_ANIMATION_COMMAND( m_colDescriptionColor, vgui::AnimationController::INTERPOLATOR_LINEAR );
|
||||
GAMEPADUI_RUN_ANIMATION_COMMAND( m_flGlyphFade, vgui::AnimationController::INTERPOLATOR_LINEAR );
|
||||
GAMEPADUI_RUN_ANIMATION_COMMAND( m_bDescriptionHide, vgui::AnimationController::INTERPOLATOR_LINEAR );
|
||||
GAMEPADUI_RUN_ANIMATION_COMMAND( m_flTextLeftBorder, vgui::AnimationController::INTERPOLATOR_LINEAR );
|
||||
GAMEPADUI_RUN_ANIMATION_COMMAND( m_colLeftBorder, vgui::AnimationController::INTERPOLATOR_LINEAR );
|
||||
GAMEPADUI_RUN_ANIMATION_COMMAND( m_flTextBottomBorder, vgui::AnimationController::INTERPOLATOR_LINEAR );
|
||||
GAMEPADUI_RUN_ANIMATION_COMMAND( m_colBottomBorder, vgui::AnimationController::INTERPOLATOR_LINEAR );
|
||||
}
|
||||
|
||||
void GamepadUIButton::DoAnimations( bool bForce )
|
||||
{
|
||||
ButtonState state = this->GetCurrentButtonState();
|
||||
if (m_ePreviousState != state || bForce)
|
||||
{
|
||||
this->RunAnimations( state );
|
||||
m_ePreviousState = state;
|
||||
}
|
||||
|
||||
SetSize(m_flWidth, m_flHeight + m_flExtraHeight);
|
||||
}
|
||||
|
||||
void GamepadUIButton::OnThink()
|
||||
{
|
||||
BaseClass::OnThink();
|
||||
DoAnimations();
|
||||
}
|
||||
|
||||
void GamepadUIButton::PaintButton()
|
||||
{
|
||||
vgui::surface()->DrawSetColor(m_colBackgroundColor);
|
||||
vgui::surface()->DrawFilledRect(0, 0, m_flWidth, m_flHeight + m_flExtraHeight);
|
||||
|
||||
PaintBorders();
|
||||
}
|
||||
|
||||
void GamepadUIButton::PaintBorders()
|
||||
{
|
||||
if ( m_flTextLeftBorder )
|
||||
{
|
||||
vgui::surface()->DrawSetColor(m_colLeftBorder);
|
||||
vgui::surface()->DrawFilledRect(0, 0, m_flTextLeftBorder, m_flHeight + m_flExtraHeight);
|
||||
}
|
||||
|
||||
if ( m_flTextBottomBorder )
|
||||
{
|
||||
vgui::surface()->DrawSetColor( m_colBottomBorder );
|
||||
vgui::surface()->DrawFilledRect( 0, m_flHeight + m_flExtraHeight - m_flTextBottomBorder, m_flWidth, m_flHeight + m_flExtraHeight );
|
||||
}
|
||||
}
|
||||
|
||||
int GamepadUIButton::PaintText()
|
||||
{
|
||||
ButtonState state = this->GetCurrentButtonState();
|
||||
int nTextPosX = 0, nTextPosY = 0;
|
||||
int nTextSizeX = 0, nTextSizeY = 0;
|
||||
|
||||
if (!m_strButtonText.IsEmpty())
|
||||
{
|
||||
vgui::surface()->DrawSetTextFont(state == ButtonStates::Out ? m_hTextFont : m_hTextFontOver);
|
||||
vgui::surface()->GetTextSize(state == ButtonStates::Out ? m_hTextFont : m_hTextFontOver, m_strButtonText.String(), nTextSizeX, nTextSizeY);
|
||||
|
||||
if (m_CenterX)
|
||||
nTextPosX = m_flWidth / 2 - nTextSizeX / 2 + m_flTextOffsetX;
|
||||
nTextPosX += m_flTextOffsetX;
|
||||
nTextPosY = m_flHeight / 2 - nTextSizeY / 2 + m_flTextOffsetY;
|
||||
}
|
||||
|
||||
#if defined(HL2_RETAIL) || defined(STEAM_INPUT)
|
||||
|
||||
#if defined(HL2_RETAIL) // Steam input and Steam Controller are not supported in SDK2013 (Madi)
|
||||
if ( g_pInputSystem->IsSteamControllerActive() )
|
||||
#else
|
||||
if (GamepadUI::GetInstance().GetSteamInput()->IsEnabled() && GamepadUI::GetInstance().GetSteamInput()->UseGlyphs())
|
||||
#endif
|
||||
{
|
||||
const int nGlyphSize = m_flHeight * 0.80f;
|
||||
if ( m_glyph.SetupGlyph( nGlyphSize, FooterButtons::GetButtonActionHandleString( m_eFooterButton ) ) )
|
||||
{
|
||||
int nGlyphPosX = m_flTextOffsetX;
|
||||
if (m_CenterX)
|
||||
{
|
||||
nGlyphPosX = nTextPosX - m_flHeight / 2;
|
||||
nTextPosX += m_flHeight / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
nTextPosX += nGlyphSize + (m_flTextOffsetX / 2);
|
||||
}
|
||||
int nGlyphPosY = m_flHeight / 2 - nGlyphSize / 2;
|
||||
|
||||
int nAlpha = 255 * (1.0f - m_flGlyphFade);
|
||||
|
||||
m_glyph.PaintGlyph( nGlyphPosX, nGlyphPosY, nGlyphSize, nAlpha );
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif // HL2_RETAIL
|
||||
if (GetFooterButton() != FooterButtons::None && gamepadui_center_footer_buttons.GetBool() && !m_CenterX)
|
||||
{
|
||||
nTextPosX = m_flWidth / 2 - nTextSizeX / 2;
|
||||
}
|
||||
|
||||
if (!m_strButtonText.IsEmpty())
|
||||
{
|
||||
vgui::surface()->DrawSetTextColor(m_colTextColor);
|
||||
vgui::surface()->DrawSetTextFont(state == ButtonStates::Out ? m_hTextFont : m_hTextFontOver);
|
||||
vgui::surface()->DrawSetTextPos(nTextPosX, nTextPosY);
|
||||
vgui::surface()->DrawPrintText(m_strButtonText.String(), m_strButtonText.Length());
|
||||
}
|
||||
|
||||
float flCurTime = GamepadUI::GetInstance().GetTime();
|
||||
const float flHeightTransTime = m_flHeightAnimationDuration;
|
||||
float flNewExtraHeight = 0.0f;
|
||||
if (!m_strButtonDescription.IsEmpty() && !m_bDescriptionHide)
|
||||
{
|
||||
vgui::surface()->DrawSetTextColor(m_colDescriptionColor);
|
||||
vgui::surface()->DrawSetTextFont(m_hDescriptionFont);
|
||||
if ( m_bDescriptionWrap )
|
||||
{
|
||||
flNewExtraHeight = DrawPrintWrappedText(m_hDescriptionFont, nTextPosX + m_flDescriptionOffsetX, nTextPosY + nTextSizeY + m_flDescriptionOffsetY, m_strButtonDescription.String(), m_strButtonDescription.Length(), m_flWidth - 2 * (m_flDescriptionOffsetX + m_flTextOffsetX), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
flNewExtraHeight = 0;
|
||||
vgui::surface()->DrawSetTextPos( nTextPosX + m_flDescriptionOffsetX, nTextPosY + nTextSizeY + m_flDescriptionOffsetY );
|
||||
vgui::surface()->DrawPrintText( m_strButtonDescription.String(), m_strButtonDescription.Length() );
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_flTargetExtraHeight != flNewExtraHeight)
|
||||
{
|
||||
m_flExtraHeightTime = flCurTime;
|
||||
m_flLastExtraHeight = m_flExtraHeight;
|
||||
m_flTargetExtraHeight = flNewExtraHeight;
|
||||
}
|
||||
|
||||
m_flExtraHeight = Lerp( Clamp( ( flCurTime - m_flExtraHeightTime ) / flHeightTransTime, 0.0f, 1.0f ), m_flLastExtraHeight, m_flTargetExtraHeight );
|
||||
|
||||
return nTextSizeX;
|
||||
}
|
||||
|
||||
void GamepadUIButton::Paint()
|
||||
{
|
||||
BaseClass::Paint();
|
||||
|
||||
PaintButton();
|
||||
PaintText();
|
||||
|
||||
m_bNavigateTo = false;
|
||||
}
|
||||
|
||||
|
||||
void GamepadUIButton::OnKeyCodePressed( vgui::KeyCode code )
|
||||
{
|
||||
ButtonCode_t buttonCode = GetBaseButtonCode( code );
|
||||
switch ( buttonCode )
|
||||
{
|
||||
#ifdef HL2_RETAIL // Steam input and Steam Controller are not supported in SDK2013 (Madi)
|
||||
case STEAMCONTROLLER_A:
|
||||
#endif
|
||||
|
||||
case KEY_XBUTTON_A:
|
||||
case KEY_ENTER:
|
||||
if ( IsEnabled() )
|
||||
{
|
||||
ForceDepressed( true );
|
||||
m_bControllerPressed = true;
|
||||
}
|
||||
BaseClass::OnKeyCodePressed( code );
|
||||
// Forward back up to parents for our buttons.
|
||||
if ( m_bForwardToParent )
|
||||
vgui::Panel::OnKeyCodePressed( code );
|
||||
break;
|
||||
default:
|
||||
if ( m_bControllerPressed )
|
||||
{
|
||||
ForceDepressed( false );
|
||||
m_bControllerPressed = false;
|
||||
}
|
||||
BaseClass::OnKeyCodePressed( code );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GamepadUIButton::OnKeyCodeReleased( vgui::KeyCode code )
|
||||
{
|
||||
ButtonCode_t buttonCode = GetBaseButtonCode(code);
|
||||
switch ( buttonCode )
|
||||
{
|
||||
#ifdef HL2_RETAIL // Steam input and Steam Controller are not supported in SDK2013 (Madi)
|
||||
case STEAMCONTROLLER_A:
|
||||
#endif
|
||||
|
||||
case KEY_XBUTTON_A:
|
||||
case KEY_ENTER:
|
||||
if ( IsEnabled() && IsDepressed() && m_bControllerPressed )
|
||||
{
|
||||
ForceDepressed( false );
|
||||
DoClick();
|
||||
m_bControllerPressed = false;
|
||||
}
|
||||
// Forward back up to parents for our buttons.
|
||||
if ( m_bForwardToParent )
|
||||
vgui::Panel::OnKeyCodeReleased( code );
|
||||
break;
|
||||
default:
|
||||
BaseClass::OnKeyCodeReleased( code );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GamepadUIButton::SetFooterButton( FooterButton button )
|
||||
{
|
||||
m_eFooterButton = button;
|
||||
m_glyph.Cleanup();
|
||||
}
|
||||
|
||||
FooterButton GamepadUIButton::GetFooterButton() const
|
||||
{
|
||||
return m_eFooterButton;
|
||||
}
|
||||
|
||||
void GamepadUIButton::SetForwardToParent( bool bForwardToParent )
|
||||
{
|
||||
m_bForwardToParent = bForwardToParent;
|
||||
}
|
||||
|
||||
bool GamepadUIButton::GetForwardToParent() const
|
||||
{
|
||||
return m_bForwardToParent;
|
||||
}
|
||||
|
||||
bool GamepadUIButton::IsFooterButton() const
|
||||
{
|
||||
return m_eFooterButton != FooterButtons::None;
|
||||
}
|
||||
|
||||
ButtonState GamepadUIButton::GetCurrentButtonState()
|
||||
{
|
||||
if ( IsDepressed() )
|
||||
return ButtonStates::Pressed;
|
||||
else if ( HasFocus() && IsEnabled() )
|
||||
return ButtonStates::Over;
|
||||
else if ( IsArmed() || m_bNavigateTo )
|
||||
{
|
||||
if ( IsArmed() )
|
||||
m_bNavigateTo = false;
|
||||
|
||||
return ButtonStates::Over;
|
||||
}
|
||||
else
|
||||
return ButtonStates::Out;
|
||||
}
|
||||
|
||||
void GamepadUIButton::NavigateTo()
|
||||
{
|
||||
BaseClass::NavigateTo();
|
||||
|
||||
if ( IsFooterButton() )
|
||||
return;
|
||||
|
||||
if ( GetVParent() )
|
||||
{
|
||||
KeyValues* msg = new KeyValues( "OnGamepadUIButtonNavigatedTo" );
|
||||
msg->SetInt( "button", ToHandle() );
|
||||
|
||||
vgui::ivgui()->PostMessage( GetVParent(), msg, GetVPanel() );
|
||||
}
|
||||
|
||||
m_bNavigateTo = true;
|
||||
RequestFocus( 0 );
|
||||
}
|
||||
|
||||
|
||||
void GamepadUIButton::NavigateFrom()
|
||||
{
|
||||
BaseClass::NavigateFrom();
|
||||
|
||||
m_bNavigateTo = false;
|
||||
}
|
||||
|
||||
void GamepadUIButton::OnCursorEntered()
|
||||
{
|
||||
#ifdef STEAM_INPUT
|
||||
if ( GamepadUI::GetInstance().GetSteamInput()->IsEnabled() || !IsEnabled() )
|
||||
#elif defined(HL2_RETAIL) // Steam input and Steam Controller are not supported in SDK2013 (Madi)
|
||||
if ( g_pInputSystem->IsSteamControllerActive() || !IsEnabled() )
|
||||
#else
|
||||
if ( !IsEnabled() )
|
||||
#endif
|
||||
return;
|
||||
|
||||
BaseClass::OnCursorEntered();
|
||||
|
||||
if ( IsFooterButton() || !m_bMouseNavigate )
|
||||
return;
|
||||
|
||||
if ( GetParent() )
|
||||
GetParent()->NavigateToChild( this );
|
||||
else
|
||||
NavigateTo();
|
||||
}
|
||||
|
||||
void GamepadUIButton::FireActionSignal()
|
||||
{
|
||||
BaseClass::FireActionSignal();
|
||||
|
||||
//PostMessageToAllSiblingsOfType< GamepadUIButton >( new KeyValues( "OnSiblingGamepadUIButtonOpened" ) );
|
||||
}
|
||||
|
||||
void GamepadUIButton::OnSiblingGamepadUIButtonOpened()
|
||||
{
|
||||
m_bNavigateTo = false;
|
||||
}
|
220
game/gamepadui/gamepadui_button.h
Normal file
220
game/gamepadui/gamepadui_button.h
Normal file
@ -0,0 +1,220 @@
|
||||
#ifndef GAMEPADUI_BUTTON_H
|
||||
#define GAMEPADUI_BUTTON_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "gamepadui_panel.h"
|
||||
#include "gamepadui_string.h"
|
||||
#include "gamepadui_glyph.h"
|
||||
#include "vgui_controls/Button.h"
|
||||
|
||||
namespace ButtonStates
|
||||
{
|
||||
enum ButtonState
|
||||
{
|
||||
Out,
|
||||
Over,
|
||||
Pressed,
|
||||
|
||||
Count,
|
||||
};
|
||||
}
|
||||
using ButtonState = ButtonStates::ButtonState;
|
||||
|
||||
namespace FooterButtons
|
||||
{
|
||||
enum FooterButton
|
||||
{
|
||||
None = 0,
|
||||
Back = ( 1 << 0 ),
|
||||
Cancel = ( 1 << 1 ),
|
||||
LeftSelect = ( 1 << 2 ),
|
||||
|
||||
// This button and any before are to the left.
|
||||
LeftMask = ( LeftSelect | Back | Cancel ),
|
||||
// Any buttons after here are to the right.
|
||||
DeclineMask = ( Back | Cancel ),
|
||||
|
||||
Select = ( 1 << 3 ),
|
||||
Apply = ( 1 << 4 ),
|
||||
Okay = ( 1 << 5 ),
|
||||
Commentary = ( 1 << 6 ),
|
||||
BonusMaps = ( 1 << 7 ),
|
||||
Challenge = ( 1 << 8 ),
|
||||
UseDefaults = ( 1 << 9 ),
|
||||
Delete = ( 1 << 10 ),
|
||||
|
||||
// Buttons that are 'confirmatory'
|
||||
ConfirmMask = ( LeftSelect | Select | Okay ),
|
||||
};
|
||||
static const int MaxFooterButtons = 11;
|
||||
|
||||
inline const char* GetButtonName( FooterButton button )
|
||||
{
|
||||
switch ( button )
|
||||
{
|
||||
case Back: return "#GameUI_Back";
|
||||
case Cancel: return "#GameUI_Cancel";
|
||||
case LeftSelect:
|
||||
case Select: return "#GameUI_Select";
|
||||
case Apply: return "#GameUI_Apply";
|
||||
case Okay: return "#GameUI_Ok";
|
||||
case Commentary: return "#GameUI_Commentary";
|
||||
case BonusMaps: return "#Deck_BonusMaps";
|
||||
case Challenge: return "#Deck_Challenges";
|
||||
case UseDefaults: return "#GameUI_UseDefaults";
|
||||
case Delete: return "#GameUI_Delete";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
inline const char* GetButtonAction( FooterButton button )
|
||||
{
|
||||
switch ( button )
|
||||
{
|
||||
case Back: return "action_back";
|
||||
case Cancel: return "action_cancel";
|
||||
case LeftSelect:
|
||||
case Select: return "action_select";
|
||||
case Apply: return "action_apply";
|
||||
case Okay: return "action_okay";
|
||||
case Commentary: return "action_commentary";
|
||||
case BonusMaps: return "action_bonus_maps";
|
||||
case Challenge: return "action_challenges";
|
||||
case UseDefaults: return "action_usedefaults";
|
||||
case Delete: return "action_delete";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
inline const char* GetButtonActionHandleString( FooterButton button )
|
||||
{
|
||||
switch ( button )
|
||||
{
|
||||
case Back: return "menu_cancel";
|
||||
case Cancel: return "menu_cancel";
|
||||
case LeftSelect:
|
||||
case Select: return "menu_select";
|
||||
case Apply: return "menu_y";
|
||||
case Okay: return "menu_select";
|
||||
case Commentary: return "menu_y";
|
||||
case BonusMaps: return "menu_x";
|
||||
case Challenge: return "menu_y";
|
||||
case UseDefaults: return "menu_x";
|
||||
case Delete: return "menu_x";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
inline FooterButton GetButtonByIdx( int i )
|
||||
{
|
||||
return static_cast< FooterButton >( 1 << i );
|
||||
}
|
||||
|
||||
using FooterButtonMask = unsigned int;
|
||||
}
|
||||
using FooterButton = FooterButtons::FooterButton;
|
||||
using FooterButtonMask = FooterButtons::FooterButtonMask;
|
||||
|
||||
class GamepadUIButton : public vgui::Button, public SchemeValueMap
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( GamepadUIButton, vgui::Button );
|
||||
public:
|
||||
GamepadUIButton( vgui::Panel *pParent, vgui::Panel* pActionSignalTarget, const char *pSchemeFile, const char *pCommand, const char *pText, const char *pDescription );
|
||||
GamepadUIButton( vgui::Panel *pParent, vgui::Panel* pActionSignalTarget, const char *pSchemeFile, const char *pCommand, const wchar_t *pText, const wchar_t *pDescription );
|
||||
|
||||
void ApplySchemeSettings( vgui::IScheme* pScheme ) OVERRIDE;
|
||||
void OnThink() OVERRIDE;
|
||||
void Paint() OVERRIDE;
|
||||
void OnKeyCodePressed( vgui::KeyCode code ) OVERRIDE;
|
||||
void OnKeyCodeReleased( vgui::KeyCode code ) OVERRIDE;
|
||||
void NavigateTo() OVERRIDE;
|
||||
void NavigateFrom() OVERRIDE;
|
||||
void OnCursorEntered() OVERRIDE;
|
||||
void FireActionSignal() OVERRIDE;
|
||||
|
||||
MESSAGE_FUNC( OnSiblingGamepadUIButtonOpened, "OnSiblingGamepadUIButtonOpened" );
|
||||
|
||||
virtual void RunAnimations( ButtonState state );
|
||||
void DoAnimations( bool bForce = false );
|
||||
void PaintButton();
|
||||
void PaintBorders();
|
||||
int PaintText();
|
||||
|
||||
void SetPriority( int nPriority ) { m_nPriority = nPriority; }
|
||||
int GetPriority() const { return m_nPriority; }
|
||||
|
||||
void SetFooterButton( FooterButton button );
|
||||
FooterButton GetFooterButton() const;
|
||||
|
||||
void SetForwardToParent( bool bForwardToParent );
|
||||
bool GetForwardToParent() const;
|
||||
|
||||
GamepadUIString& GetButtonText() { return m_strButtonText; }
|
||||
const GamepadUIString& GetButtonText() const { return m_strButtonText; }
|
||||
GamepadUIString& GetButtonDescription() { return m_strButtonDescription; }
|
||||
const GamepadUIString& GetButtonDescription() const { return m_strButtonDescription; }
|
||||
|
||||
virtual ButtonState GetCurrentButtonState();
|
||||
|
||||
bool IsFooterButton() const;
|
||||
|
||||
float GetDrawHeight() const { return m_flHeight + m_flExtraHeight; }
|
||||
float GetMaxHeight() const { return m_flHeightAnimationValue[ ButtonStates::Over ] + m_flCachedExtraHeight; }
|
||||
|
||||
void SetMouseNavigate( bool bMouseNavigate ) { m_bMouseNavigate = bMouseNavigate; }
|
||||
|
||||
protected:
|
||||
|
||||
ButtonState m_ePreviousState = ButtonStates::Out;
|
||||
|
||||
bool m_bCursorOver = false;
|
||||
bool m_bControllerPressed = false;
|
||||
bool m_bNavigateTo = false;
|
||||
bool m_bForwardToParent = false;
|
||||
bool m_bMouseNavigate = true;
|
||||
|
||||
float m_flExtraHeight = 0;
|
||||
float m_flCachedExtraHeight = 0;
|
||||
float m_flTargetExtraHeight = 0;
|
||||
float m_flLastExtraHeight = 0;
|
||||
float m_flExtraHeightTime = 0;
|
||||
|
||||
FooterButton m_eFooterButton = FooterButtons::None;
|
||||
|
||||
GamepadUIString m_strButtonText;
|
||||
GamepadUIString m_strButtonDescription;
|
||||
GamepadUIGlyph m_glyph;
|
||||
|
||||
public:
|
||||
|
||||
int m_nPriority = 0;
|
||||
|
||||
GAMEPADUI_BUTTON_ANIMATED_PROPERTY( float, m_flWidth, "Button.Width", "392", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_BUTTON_ANIMATED_PROPERTY( float, m_flHeight, "Button.Height", "40", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_BUTTON_ANIMATED_PROPERTY( float, m_flTextOffsetX, "Button.Text.OffsetX", "10", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_BUTTON_ANIMATED_PROPERTY( float, m_flTextOffsetY, "Button.Text.OffsetY", "0", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_BUTTON_ANIMATED_PROPERTY( float, m_flDescriptionOffsetX, "Button.Description.OffsetX", "0", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_BUTTON_ANIMATED_PROPERTY( float, m_flDescriptionOffsetY, "Button.Description.OffsetY", "0", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_BUTTON_ANIMATED_PROPERTY( Color, m_colBackgroundColor, "Button.Background", "0 0 0 0", SchemeValueTypes::Color );
|
||||
GAMEPADUI_BUTTON_ANIMATED_PROPERTY( Color, m_colTextColor, "Button.Text", "255 255 255 255", SchemeValueTypes::Color );
|
||||
GAMEPADUI_BUTTON_ANIMATED_PROPERTY( Color, m_colDescriptionColor, "Button.Description", "255 255 255 255", SchemeValueTypes::Color );
|
||||
GAMEPADUI_BUTTON_ANIMATED_PROPERTY( float, m_flGlyphFade, "Button.Glyphs.Fade", "0", SchemeValueTypes::Float );
|
||||
GAMEPADUI_BUTTON_ANIMATED_PROPERTY( bool, m_bDescriptionHide, "Button.Description.Hide", "0", SchemeValueTypes::Bool );
|
||||
|
||||
GAMEPADUI_BUTTON_ANIMATED_PROPERTY( float, m_flTextLeftBorder, "Button.Text.LeftBorder", "0", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_BUTTON_ANIMATED_PROPERTY( Color, m_colLeftBorder, "Button.Background.LeftBorder", "0 0 0 0", SchemeValueTypes::Color );
|
||||
|
||||
GAMEPADUI_BUTTON_ANIMATED_PROPERTY( float, m_flTextBottomBorder, "Button.Text.BottomBorder", "0", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_BUTTON_ANIMATED_PROPERTY( Color, m_colBottomBorder, "Button.Background.BottomBorder", "0 0 0 0", SchemeValueTypes::Color );
|
||||
|
||||
GAMEPADUI_PANEL_PROPERTY( bool, m_CenterX, "Button.Text.CenterX", "0", SchemeValueTypes::Bool );
|
||||
GAMEPADUI_PANEL_PROPERTY( bool, m_bDescriptionWrap, "Button.Description.Wrap", "1", SchemeValueTypes::Bool );
|
||||
|
||||
vgui::HFont m_hTextFont = vgui::INVALID_FONT;
|
||||
vgui::HFont m_hTextFontOver = vgui::INVALID_FONT;
|
||||
vgui::HFont m_hDescriptionFont = vgui::INVALID_FONT;
|
||||
};
|
||||
|
||||
#endif // GAMEPADUI_BUTTON_H
|
23
game/gamepadui/gamepadui_episodic.vpc
Normal file
23
game/gamepadui/gamepadui_episodic.vpc
Normal file
@ -0,0 +1,23 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// GAMEPADUI_EPISODIC.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro GAMENAME "mod_episodic" // Stock SDK2013, Modders should replace this line with their mod folder name if needed.
|
||||
$Macro OUTBINNAME "gamepadui"
|
||||
|
||||
$Include "$SRCDIR\game\gamepadui\gamepadui_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$PreprocessorDefinitions "$BASE;GAMEPADUI_GAME_HL2;GAMEPADUI_GAME_EPISODIC"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "GamepadUI (Episodic)"
|
||||
{
|
||||
}
|
414
game/gamepadui/gamepadui_frame.cpp
Normal file
414
game/gamepadui/gamepadui_frame.cpp
Normal file
@ -0,0 +1,414 @@
|
||||
// 🐸
|
||||
#include "gamepadui_frame.h"
|
||||
#include "gamepadui_button.h"
|
||||
#include "gamepadui_interface.h"
|
||||
#include "gamepadui_basepanel.h"
|
||||
|
||||
#include "inputsystem/iinputsystem.h"
|
||||
#include "vgui/ISurface.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
GamepadUIFrame::GamepadUIFrame( vgui::Panel *pParent, const char *pszPanelName, bool bShowTaskbarIcon, bool bPopup )
|
||||
: BaseClass( pParent, pszPanelName, bShowTaskbarIcon, bPopup )
|
||||
{
|
||||
SetConsoleStylePanel( true );
|
||||
// bodge to disable the frames title image and display our own
|
||||
// (the frames title has an invalid zpos and does not draw over the garnish)
|
||||
Frame::SetTitle( "", false );
|
||||
|
||||
if (pParent && pParent == GamepadUI::GetInstance().GetBasePanel())
|
||||
{
|
||||
GamepadUIBasePanel *pPanel = static_cast<GamepadUIBasePanel*>(pParent);
|
||||
pPanel->SetCurrentFrame( this );
|
||||
}
|
||||
|
||||
memset( &m_pFooterButtons, 0, sizeof( m_pFooterButtons ) );
|
||||
}
|
||||
|
||||
void GamepadUIFrame::ApplySchemeSettings( vgui::IScheme* pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
|
||||
// Josh: Big load of common default state for us
|
||||
MakeReadyForUse();
|
||||
SetMoveable( false );
|
||||
SetCloseButtonVisible( false );
|
||||
SetMinimizeButtonVisible( false );
|
||||
SetMaximizeButtonVisible( false );
|
||||
SetMenuButtonResponsive( false );
|
||||
SetMinimizeToSysTrayButtonVisible( false );
|
||||
SetSizeable( false );
|
||||
SetDeleteSelfOnClose( true );
|
||||
SetPaintBackgroundEnabled( false );
|
||||
SetPaintBorderEnabled( false );
|
||||
SetTitleBarVisible( false );
|
||||
|
||||
int nParentW, nParentH;
|
||||
GetParent()->GetSize( nParentW, nParentH );
|
||||
SetBounds( 0, 0, nParentW, nParentH );
|
||||
UpdateSchemeProperties( this, pScheme );
|
||||
|
||||
m_hTitleFont = pScheme->GetFont( "Title.Font", true );
|
||||
m_hGenericFont = pScheme->GetFont( "Generic.Text.Font", true );
|
||||
}
|
||||
|
||||
void GamepadUIFrame::OnThink()
|
||||
{
|
||||
BaseClass::OnThink();
|
||||
|
||||
LayoutFooterButtons();
|
||||
}
|
||||
|
||||
void GamepadUIFrame::Paint()
|
||||
{
|
||||
BaseClass::Paint();
|
||||
|
||||
PaintBackgroundGradients();
|
||||
PaintTitle();
|
||||
}
|
||||
|
||||
void GamepadUIFrame::UpdateGradients()
|
||||
{
|
||||
}
|
||||
|
||||
void GamepadUIFrame::PaintBackgroundGradients()
|
||||
{
|
||||
vgui::surface()->DrawSetColor( Color( 0, 0, 0, 255 ) );
|
||||
|
||||
GradientHelper* pGradients = GamepadUI::GetInstance().GetGradientHelper();
|
||||
const float flTime = GamepadUI::GetInstance().GetTime();
|
||||
GradientInfo gradients[ GradientSides::Count ] =
|
||||
{
|
||||
pGradients->GetGradient( GradientSides::Left, flTime ),
|
||||
pGradients->GetGradient( GradientSides::Right, flTime ),
|
||||
pGradients->GetGradient( GradientSides::Up, flTime ),
|
||||
pGradients->GetGradient( GradientSides::Down, flTime ),
|
||||
};
|
||||
|
||||
if ( gradients[ GradientSides::Left ].flExtent &&
|
||||
gradients[ GradientSides::Left ].flAmount )
|
||||
{
|
||||
vgui::surface()->DrawFilledRectFade(
|
||||
0,
|
||||
0,
|
||||
GetWide() * gradients[ GradientSides::Left ].flExtent,
|
||||
GetTall(),
|
||||
255.0f * gradients[ GradientSides::Left ].flAmount, 0,
|
||||
true);
|
||||
}
|
||||
|
||||
if ( gradients[ GradientSides::Right ].flExtent &&
|
||||
gradients[ GradientSides::Right ].flAmount )
|
||||
{
|
||||
vgui::surface()->DrawFilledRectFade(
|
||||
0,
|
||||
0,
|
||||
GetWide() * gradients[ GradientSides::Right ].flExtent,
|
||||
GetTall(),
|
||||
0, 255.0f * gradients[ GradientSides::Right ].flAmount,
|
||||
true);
|
||||
}
|
||||
|
||||
if ( gradients[ GradientSides::Down ].flExtent &&
|
||||
gradients[ GradientSides::Down ].flAmount )
|
||||
{
|
||||
vgui::surface()->DrawFilledRectFade(
|
||||
0,
|
||||
0,
|
||||
GetWide(),
|
||||
GetTall() * gradients[ GradientSides::Down ].flExtent,
|
||||
255.0f * gradients[ GradientSides::Down ].flAmount, 0,
|
||||
false);
|
||||
}
|
||||
|
||||
if ( gradients[ GradientSides::Up ].flExtent &&
|
||||
gradients[ GradientSides::Up ].flAmount )
|
||||
{
|
||||
vgui::surface()->DrawFilledRectFade(
|
||||
0,
|
||||
0,
|
||||
GetWide(),
|
||||
GetTall() * gradients[ GradientSides::Up ].flExtent,
|
||||
0, 255.0f * gradients[ GradientSides::Up ].flAmount,
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
void GamepadUIFrame::PaintTitle()
|
||||
{
|
||||
if ( m_strFrameTitle.IsEmpty() )
|
||||
return;
|
||||
|
||||
vgui::surface()->DrawSetTextColor( m_colTitleColor );
|
||||
vgui::surface()->DrawSetTextFont( m_hTitleFont );
|
||||
vgui::surface()->DrawSetTextPos( m_flTitleOffsetX, m_flTitleOffsetY );
|
||||
vgui::surface()->DrawPrintText( m_strFrameTitle.String(), m_strFrameTitle.Length() );
|
||||
}
|
||||
|
||||
void GamepadUIFrame::SetFooterButtons( FooterButtonMask mask, FooterButtonMask controllerOnlyMask )
|
||||
{
|
||||
for ( int i = 0; i < FooterButtons::MaxFooterButtons; i++ )
|
||||
{
|
||||
if ( m_pFooterButtons[i] )
|
||||
{
|
||||
delete m_pFooterButtons[i];
|
||||
m_pFooterButtons[i] = NULL;
|
||||
}
|
||||
|
||||
FooterButton button = FooterButtons::GetButtonByIdx( i );
|
||||
if ( mask & button )
|
||||
{
|
||||
m_pFooterButtons[i] = new GamepadUIButton(
|
||||
this, this,
|
||||
GAMEPADUI_DEFAULT_PANEL_SCHEME, FooterButtons::GetButtonAction( button ),
|
||||
FooterButtons::GetButtonName( button ), "" );
|
||||
m_pFooterButtons[i]->SetFooterButton( button );
|
||||
// Make footer buttons render over everything.
|
||||
m_pFooterButtons[i]->SetZPos( 100 );
|
||||
}
|
||||
}
|
||||
|
||||
m_ControllerOnlyFooterMask = controllerOnlyMask;
|
||||
}
|
||||
|
||||
void GamepadUIFrame::LayoutFooterButtons()
|
||||
{
|
||||
int nParentW, nParentH;
|
||||
GetParent()->GetSize( nParentW, nParentH );
|
||||
|
||||
int nLeftOffset = 0, nRightOffset = 0;
|
||||
for ( int i = 0; i < FooterButtons::MaxFooterButtons; i++ )
|
||||
{
|
||||
if ( !m_pFooterButtons[i] || !m_pFooterButtons[i]->IsVisible() )
|
||||
continue;
|
||||
|
||||
m_nFooterButtonWidth = m_pFooterButtons[i]->GetWide();
|
||||
m_nFooterButtonHeight = m_pFooterButtons[i]->GetTall();
|
||||
FooterButton button = FooterButtons::GetButtonByIdx( i );
|
||||
if ( m_bFooterButtonsStack )
|
||||
{
|
||||
if ( button & FooterButtons::LeftMask )
|
||||
{
|
||||
m_pFooterButtons[i]->SetPos( m_flFooterButtonsOffsetX, nParentH - m_flFooterButtonsOffsetY - m_nFooterButtonHeight - nLeftOffset );
|
||||
nLeftOffset += m_flFooterButtonsSpacing + m_pFooterButtons[i]->GetTall();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pFooterButtons[i]->SetPos( nParentW - m_pFooterButtons[i]->GetWide() - m_flFooterButtonsOffsetX, nParentH - m_flFooterButtonsOffsetY - m_nFooterButtonHeight - nRightOffset );
|
||||
nRightOffset += m_flFooterButtonsSpacing + m_pFooterButtons[i]->GetTall();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( button & FooterButtons::LeftMask )
|
||||
{
|
||||
m_pFooterButtons[i]->SetPos( m_flFooterButtonsOffsetX + nLeftOffset, nParentH - m_flFooterButtonsOffsetY - m_nFooterButtonHeight );
|
||||
nLeftOffset += m_flFooterButtonsSpacing + m_pFooterButtons[i]->GetWide();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pFooterButtons[i]->SetPos( nParentW - m_pFooterButtons[i]->GetWide() - nRightOffset - m_flFooterButtonsOffsetX, nParentH - m_flFooterButtonsOffsetY - m_nFooterButtonHeight );
|
||||
nRightOffset += m_flFooterButtonsSpacing + m_pFooterButtons[i]->GetWide();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef STEAM_INPUT
|
||||
const bool bController = GamepadUI::GetInstance().GetSteamInput()->IsEnabled();
|
||||
#elif defined(HL2_RETAIL) // Steam input and Steam Controller are not supported in SDK2013 (Madi)
|
||||
const bool bController = g_pInputSystem->IsSteamControllerActive();
|
||||
#else
|
||||
const bool bController = ( g_pInputSystem->GetJoystickCount() >= 1 );
|
||||
#endif
|
||||
|
||||
const bool bVisible = bController || !( m_ControllerOnlyFooterMask & button );
|
||||
m_pFooterButtons[i]->SetVisible( bVisible );
|
||||
}
|
||||
}
|
||||
|
||||
void GamepadUIFrame::OnClose()
|
||||
{
|
||||
BaseClass::OnClose();
|
||||
|
||||
if (GetParent() && GetParent() == GamepadUI::GetInstance().GetBasePanel())
|
||||
{
|
||||
GamepadUIBasePanel *pPanel = static_cast<GamepadUIBasePanel*>(GetParent());
|
||||
pPanel->SetCurrentFrame( NULL );
|
||||
}
|
||||
|
||||
GamepadUIFrame *pFrame = dynamic_cast<GamepadUIFrame *>( GetParent() );
|
||||
if ( pFrame )
|
||||
pFrame->UpdateGradients();
|
||||
else
|
||||
GamepadUI::GetInstance().ResetToMainMenuGradients();
|
||||
}
|
||||
|
||||
void GamepadUIFrame::OnKeyCodePressed( vgui::KeyCode code )
|
||||
{
|
||||
ButtonCode_t buttonCode = GetBaseButtonCode( code );
|
||||
switch (buttonCode)
|
||||
{
|
||||
#ifdef HL2_RETAIL // Steam input and Steam Controller are not supported in SDK2013 (Madi)
|
||||
case STEAMCONTROLLER_A:
|
||||
#endif
|
||||
|
||||
case KEY_XBUTTON_A:
|
||||
case KEY_ENTER:
|
||||
for ( int i = 0; i < FooterButtons::MaxFooterButtons; i++ )
|
||||
{
|
||||
if ( FooterButtons::GetButtonByIdx(i) & FooterButtons::ConfirmMask )
|
||||
{
|
||||
if ( m_pFooterButtons[i] )
|
||||
m_pFooterButtons[i]->ForceDepressed( true );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef HL2_RETAIL
|
||||
case STEAMCONTROLLER_Y:
|
||||
#endif
|
||||
|
||||
case KEY_XBUTTON_Y:
|
||||
for ( int i = 0; i < FooterButtons::MaxFooterButtons; i++ )
|
||||
{
|
||||
if ( FooterButtons::GetButtonByIdx(i) & ( FooterButtons::Apply | FooterButtons::Commentary | FooterButtons::Challenge ) )
|
||||
{
|
||||
if ( m_pFooterButtons[i] )
|
||||
m_pFooterButtons[i]->ForceDepressed( true );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef HL2_RETAIL
|
||||
case STEAMCONTROLLER_X:
|
||||
#endif
|
||||
|
||||
case KEY_XBUTTON_X:
|
||||
for ( int i = 0; i < FooterButtons::MaxFooterButtons; i++ )
|
||||
{
|
||||
if ( FooterButtons::GetButtonByIdx(i) & ( FooterButtons::BonusMaps | FooterButtons::UseDefaults | FooterButtons::Delete ) )
|
||||
{
|
||||
if ( m_pFooterButtons[i] )
|
||||
m_pFooterButtons[i]->ForceDepressed( true );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef HL2_RETAIL
|
||||
case STEAMCONTROLLER_B:
|
||||
#endif
|
||||
|
||||
case KEY_XBUTTON_B:
|
||||
case KEY_ESCAPE:
|
||||
for ( int i = 0; i < FooterButtons::MaxFooterButtons; i++ )
|
||||
{
|
||||
if ( FooterButtons::GetButtonByIdx(i) & FooterButtons::DeclineMask )
|
||||
{
|
||||
if ( m_pFooterButtons[i] )
|
||||
m_pFooterButtons[i]->ForceDepressed( true );
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BaseClass::OnKeyCodePressed( code );
|
||||
break;
|
||||
}
|
||||
}
|
||||
void GamepadUIFrame::OnKeyCodeReleased( vgui::KeyCode code )
|
||||
{
|
||||
ButtonCode_t buttonCode = GetBaseButtonCode( code );
|
||||
switch (buttonCode)
|
||||
{
|
||||
|
||||
#ifdef HL2_RETAIL
|
||||
case STEAMCONTROLLER_A:
|
||||
#endif
|
||||
|
||||
case KEY_XBUTTON_A:
|
||||
case KEY_ENTER:
|
||||
for ( int i = 0; i < FooterButtons::MaxFooterButtons; i++ )
|
||||
{
|
||||
if ( FooterButtons::GetButtonByIdx(i) & FooterButtons::ConfirmMask )
|
||||
{
|
||||
if ( m_pFooterButtons[i] )
|
||||
{
|
||||
if ( m_pFooterButtons[i]->IsDepressed() )
|
||||
{
|
||||
m_pFooterButtons[i]->ForceDepressed( false );
|
||||
m_pFooterButtons[i]->DoClick();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef HL2_RETAIL
|
||||
case STEAMCONTROLLER_Y:
|
||||
#endif
|
||||
|
||||
case KEY_XBUTTON_Y:
|
||||
for ( int i = 0; i < FooterButtons::MaxFooterButtons; i++ )
|
||||
{
|
||||
if ( FooterButtons::GetButtonByIdx(i) & ( FooterButtons::Apply | FooterButtons::Commentary | FooterButtons::Challenge ) )
|
||||
{
|
||||
if ( m_pFooterButtons[i] )
|
||||
{
|
||||
if ( m_pFooterButtons[i]->IsDepressed() )
|
||||
{
|
||||
m_pFooterButtons[i]->ForceDepressed( false );
|
||||
m_pFooterButtons[i]->DoClick();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef HL2_RETAIL
|
||||
case STEAMCONTROLLER_X:
|
||||
#endif
|
||||
|
||||
case KEY_XBUTTON_X:
|
||||
for ( int i = 0; i < FooterButtons::MaxFooterButtons; i++ )
|
||||
{
|
||||
if ( FooterButtons::GetButtonByIdx(i) & ( FooterButtons::BonusMaps | FooterButtons::UseDefaults | FooterButtons::Delete ) )
|
||||
{
|
||||
if ( m_pFooterButtons[i] )
|
||||
{
|
||||
if ( m_pFooterButtons[i]->IsDepressed() )
|
||||
{
|
||||
m_pFooterButtons[i]->ForceDepressed( false );
|
||||
m_pFooterButtons[i]->DoClick();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef HL2_RETAIL
|
||||
case STEAMCONTROLLER_B:
|
||||
#endif
|
||||
|
||||
case KEY_XBUTTON_B:
|
||||
case KEY_ESCAPE:
|
||||
for ( int i = 0; i < FooterButtons::MaxFooterButtons; i++ )
|
||||
{
|
||||
if ( FooterButtons::GetButtonByIdx(i) & FooterButtons::DeclineMask )
|
||||
{
|
||||
if ( m_pFooterButtons[i] )
|
||||
{
|
||||
if ( m_pFooterButtons[i]->IsDepressed() )
|
||||
{
|
||||
m_pFooterButtons[i]->ForceDepressed( false );
|
||||
m_pFooterButtons[i]->DoClick();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BaseClass::OnKeyCodeReleased( code );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
55
game/gamepadui/gamepadui_frame.h
Normal file
55
game/gamepadui/gamepadui_frame.h
Normal file
@ -0,0 +1,55 @@
|
||||
#ifndef GAMEPADUI_FRAME_H
|
||||
#define GAMEPADUI_FRAME_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
#include "gamepadui_panel.h"
|
||||
#include "gamepadui_button.h"
|
||||
#include "gamepadui_string.h"
|
||||
|
||||
#include "vgui_controls/Frame.h"
|
||||
|
||||
class GamepadUIFrame : public vgui::Frame, public SchemeValueMap
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( GamepadUIFrame, vgui::Frame );
|
||||
public:
|
||||
GamepadUIFrame( vgui::Panel *pParent, const char *pszPanelName, bool bShowTaskbarIcon = true, bool bPopup = true );
|
||||
void ApplySchemeSettings( vgui::IScheme* pScheme ) OVERRIDE;
|
||||
void OnThink() OVERRIDE;
|
||||
void Paint() OVERRIDE;
|
||||
void OnKeyCodePressed( vgui::KeyCode code ) OVERRIDE;
|
||||
void OnKeyCodeReleased( vgui::KeyCode code ) OVERRIDE;
|
||||
|
||||
GamepadUIString& GetFrameTitle() { return m_strFrameTitle; }
|
||||
const GamepadUIString& GetFrameTitle() const { return m_strFrameTitle; }
|
||||
|
||||
void PaintTitle();
|
||||
void SetFooterButtons( FooterButtonMask mask, FooterButtonMask controllerOnlyMask = 0 );
|
||||
void OnClose();
|
||||
|
||||
virtual void UpdateGradients();
|
||||
protected:
|
||||
void LayoutFooterButtons();
|
||||
void PaintBackgroundGradients();
|
||||
|
||||
GamepadUIString m_strFrameTitle;
|
||||
GamepadUIButton *m_pFooterButtons[ FooterButtons::MaxFooterButtons ];
|
||||
FooterButtonMask m_ControllerOnlyFooterMask = 0;
|
||||
|
||||
GAMEPADUI_PANEL_PROPERTY( Color, m_colTitleColor, "Title", "255 255 255 255", SchemeValueTypes::Color );
|
||||
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flTitleOffsetX, "Title.OffsetX", "0", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flTitleOffsetY, "Title.OffsetY", "0", SchemeValueTypes::ProportionalFloat );
|
||||
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flFooterButtonsOffsetX, "FooterButtons.OffsetX", "0", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flFooterButtonsOffsetY, "FooterButtons.OffsetY", "0", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flFooterButtonsSpacing, "FooterButtons.Spacing", "0", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_PANEL_PROPERTY( bool, m_bFooterButtonsStack, "FooterButtons.StackVertically", "0", SchemeValueTypes::Bool );
|
||||
|
||||
vgui::HFont m_hTitleFont = vgui::INVALID_FONT;
|
||||
vgui::HFont m_hGenericFont = vgui::INVALID_FONT;
|
||||
int m_nFooterButtonWidth = 0;
|
||||
int m_nFooterButtonHeight = 0;
|
||||
};
|
||||
|
||||
#endif // GAMEPADUI_FRAME_H
|
184
game/gamepadui/gamepadui_genericconfirmation.cpp
Normal file
184
game/gamepadui/gamepadui_genericconfirmation.cpp
Normal file
@ -0,0 +1,184 @@
|
||||
#include "gamepadui_interface.h"
|
||||
#include "gamepadui_genericconfirmation.h"
|
||||
#include "gamepadui_util.h"
|
||||
|
||||
#include "ienginevgui.h"
|
||||
#include "vgui/ILocalize.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "vgui/IVGui.h"
|
||||
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
ConVar gamepadui_center_confirmation_panels( "gamepadui_center_confirmation_panels", "1", FCVAR_NONE, "Centers confirmation panels" );
|
||||
|
||||
GamepadUIGenericConfirmationPanel::GamepadUIGenericConfirmationPanel( vgui::Panel *pParent, const char* pPanelName, const char* pTitle, const char* pText, std::function<void()> pCommand, bool bSmallFont, bool bShowCancel )
|
||||
: BaseClass( pParent, pPanelName )
|
||||
, m_pCommand( std::move( pCommand ) )
|
||||
, m_pszGenericConfirmationFontName( bSmallFont ? "Generic.Text.Font" : "GenericConfirmation.Font" )
|
||||
{
|
||||
vgui::HScheme hScheme = vgui::scheme()->LoadSchemeFromFileEx( GamepadUI::GetInstance().GetSizingVPanel(), GAMEPADUI_DEFAULT_PANEL_SCHEME, "SchemePanel" );
|
||||
SetScheme( hScheme );
|
||||
|
||||
GetFrameTitle() = GamepadUIString( pTitle );
|
||||
m_strText = GamepadUIString( pText );
|
||||
FooterButtonMask buttons = FooterButtons::Okay;
|
||||
if ( bShowCancel )
|
||||
buttons |= FooterButtons::Cancel;
|
||||
SetFooterButtons( buttons );
|
||||
|
||||
Activate();
|
||||
|
||||
UpdateGradients();
|
||||
}
|
||||
|
||||
GamepadUIGenericConfirmationPanel::GamepadUIGenericConfirmationPanel( vgui::Panel *pParent, const char* pPanelName, const wchar_t* pTitle, const wchar_t* pText, std::function<void()> pCommand, bool bSmallFont, bool bShowCancel )
|
||||
: BaseClass( pParent, pPanelName )
|
||||
, m_pCommand( std::move( pCommand ) )
|
||||
, m_pszGenericConfirmationFontName( bSmallFont ? "Generic.Text.Font" : "GenericConfirmation.Font" )
|
||||
{
|
||||
vgui::HScheme hScheme = vgui::scheme()->LoadSchemeFromFileEx( GamepadUI::GetInstance().GetSizingVPanel(), GAMEPADUI_DEFAULT_PANEL_SCHEME, "SchemePanel" );
|
||||
SetScheme( hScheme );
|
||||
|
||||
GetFrameTitle() = GamepadUIString( pTitle );
|
||||
m_strText = GamepadUIString( pText );
|
||||
FooterButtonMask buttons = FooterButtons::Okay;
|
||||
if ( bShowCancel )
|
||||
buttons |= FooterButtons::Cancel;
|
||||
SetFooterButtons( buttons );
|
||||
|
||||
Activate();
|
||||
|
||||
UpdateGradients();
|
||||
}
|
||||
|
||||
void GamepadUIGenericConfirmationPanel::ApplySchemeSettings( vgui::IScheme* pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
|
||||
m_hGenericConfirmationFont = pScheme->GetFont( m_pszGenericConfirmationFontName, true );
|
||||
|
||||
if ( !m_strText.IsEmpty() && gamepadui_center_confirmation_panels.GetBool() )
|
||||
{
|
||||
int nTall = DrawPrintWrappedText( m_hGenericConfirmationFont, m_flGenericConfirmationOffsetX, m_flGenericConfirmationOffsetY, m_strText.String(), m_strText.Length(), GetWide() - 2 * m_flGenericConfirmationOffsetX, false );
|
||||
|
||||
int nParentW, nParentH;
|
||||
GetParent()->GetSize( nParentW, nParentH );
|
||||
|
||||
int nYOffset = (nParentH / 2 - nTall / 2) - (m_flTitleOffsetY * 0.5f);
|
||||
|
||||
m_flFooterButtonsOffsetY = (nYOffset - m_flTitleOffsetY);
|
||||
m_flFooterButtonsOffsetX *= 3;
|
||||
|
||||
m_flTitleOffsetY = nYOffset - (m_flGenericConfirmationOffsetY - m_flTitleOffsetY);
|
||||
m_flGenericConfirmationOffsetY = nYOffset;
|
||||
}
|
||||
}
|
||||
|
||||
void GamepadUIGenericConfirmationPanel::PaintText()
|
||||
{
|
||||
if ( m_strText.IsEmpty() )
|
||||
return;
|
||||
|
||||
vgui::surface()->DrawSetTextColor( m_colGenericConfirmationColor );
|
||||
vgui::surface()->DrawSetTextFont( m_hGenericConfirmationFont );
|
||||
vgui::surface()->DrawSetTextPos( m_flGenericConfirmationOffsetX, m_flGenericConfirmationOffsetY );
|
||||
DrawPrintWrappedText( m_hGenericConfirmationFont, m_flGenericConfirmationOffsetX, m_flGenericConfirmationOffsetY, m_strText.String(), m_strText.Length(), GetWide() - 2 * m_flGenericConfirmationOffsetX, true );
|
||||
}
|
||||
|
||||
void GamepadUIGenericConfirmationPanel::UpdateGradients()
|
||||
{
|
||||
const float flTime = GamepadUI::GetInstance().GetTime();
|
||||
GamepadUI::GetInstance().GetGradientHelper()->ResetTargets( flTime );
|
||||
GamepadUI::GetInstance().GetGradientHelper()->SetTargetGradient( GradientSide::Up, { 1.0f, 1.0f }, flTime );
|
||||
GamepadUI::GetInstance().GetGradientHelper()->SetTargetGradient( GradientSide::Left, { 1.0f, 0.6667f }, flTime );
|
||||
GamepadUI::GetInstance().GetGradientHelper()->SetTargetGradient( GradientSide::Down, { 1.0f, 1.0f }, flTime );
|
||||
}
|
||||
|
||||
void GamepadUIGenericConfirmationPanel::Paint()
|
||||
{
|
||||
BaseClass::Paint();
|
||||
|
||||
PaintText();
|
||||
// Workaround focus shifting to main menu and getting the wrong gradients
|
||||
// causing us to not over paint everything leading to weird left over bits of text
|
||||
UpdateGradients();
|
||||
}
|
||||
|
||||
void GamepadUIGenericConfirmationPanel::OnCommand( const char* pCommand )
|
||||
{
|
||||
if ( !V_strcmp( pCommand, "action_cancel" ) )
|
||||
{
|
||||
Close();
|
||||
}
|
||||
else if ( !V_strcmp( pCommand, "action_okay" ) )
|
||||
{
|
||||
m_pCommand();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
CON_COMMAND( gamepadui_openquitgamedialog, "" )
|
||||
{
|
||||
new GamepadUIGenericConfirmationPanel( GamepadUI::GetInstance().GetBasePanel(), "QuitConfirmationPanel", "#GameUI_QuitConfirmationTitle", "#GameUI_QuitConfirmationText",
|
||||
[]()
|
||||
{
|
||||
GamepadUI::GetInstance().GetEngineClient()->ClientCmd_Unrestricted( "quit" );
|
||||
} );
|
||||
}
|
||||
|
||||
CON_COMMAND( gamepadui_opengenerictextdialog, "Opens a generic text dialog.\nFormat: gamepadui_opengenerictextdialog <title> <text> <small font (0 or 1)>" )
|
||||
{
|
||||
if (args.ArgC() < 4)
|
||||
{
|
||||
Msg("Format: gamepadui_opengenerictextdialog <title> <text> <small font (0 or 1)>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
vgui::Panel *pParent = GamepadUI::GetInstance().GetCurrentFrame();
|
||||
if (!pParent)
|
||||
pParent = GamepadUI::GetInstance().GetBasePanel();
|
||||
|
||||
new GamepadUIGenericConfirmationPanel( pParent, "GenericConfirmationPanel", args.Arg(1), args.Arg(2),
|
||||
[](){}, args.Arg(3)[0] != '0', false );
|
||||
}
|
||||
|
||||
CON_COMMAND( gamepadui_opengenericconfirmdialog, "Opens a generic confirmation dialog which executes a command.\nFormat: gamepadui_opengenericconfirmdialog <title> <text> <small font (0 or 1)> <command>\n<command> supports quotation marks as double apostrophes." )
|
||||
{
|
||||
if (args.ArgC() < 5)
|
||||
{
|
||||
Msg("Format: gamepadui_opengenericconfirmdialog <title> <text> <small font (0 or 1)> <command>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
vgui::Panel *pParent = GamepadUI::GetInstance().GetCurrentFrame();
|
||||
if (!pParent)
|
||||
pParent = GamepadUI::GetInstance().GetBasePanel();
|
||||
|
||||
// To get the command, we just use the remaining string after the small font parameter
|
||||
// This method is fairly dirty and relies a bit on guesswork, but it allows spaces and quotes to be used
|
||||
// without having to worry about how the initial dialog command handles it
|
||||
const char *pCmd = args.GetCommandString();
|
||||
char *pSmallFont = V_strstr( pCmd, args.Arg( 3 )[0] != '0' ? " 1 " : " 0 " );
|
||||
if (!pSmallFont)
|
||||
{
|
||||
// Look for quotes instead
|
||||
pSmallFont = V_strstr( pCmd, args.Arg( 3 )[0] != '0' ? " \"1\" " : " \"0\" " );
|
||||
if (pSmallFont)
|
||||
pCmd += (pSmallFont - pCmd) + 5;
|
||||
else
|
||||
{
|
||||
// Give up and use the 4th argument
|
||||
pCmd = args.Arg( 4 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pCmd += (pSmallFont - pCmd) + 3;
|
||||
}
|
||||
|
||||
new GamepadUIGenericConfirmationPanel( pParent, "GenericConfirmationPanel", args.Arg(1), args.Arg(2),
|
||||
[pCmd]()
|
||||
{
|
||||
GamepadUI::GetInstance().GetEngineClient()->ClientCmd_Unrestricted( pCmd );
|
||||
}, args.Arg(3)[0] != '0', true );
|
||||
}
|
42
game/gamepadui/gamepadui_genericconfirmation.h
Normal file
42
game/gamepadui/gamepadui_genericconfirmation.h
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef GAMEPADUI_GENERICCONFIRMATION_H
|
||||
#define GAMEPADUI_GENERICCONFIRMATION_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "gamepadui_frame.h"
|
||||
#include "tier0/valve_minmax_off.h"
|
||||
#include <functional>
|
||||
#include "tier0/valve_minmax_on.h"
|
||||
|
||||
class GamepadUIGenericConfirmationPanel : public GamepadUIFrame
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( GamepadUIGenericConfirmationPanel, GamepadUIFrame );
|
||||
|
||||
public:
|
||||
GamepadUIGenericConfirmationPanel( vgui::Panel *pParent, const char* pPanelName, const char *pTitle, const char *pText, std::function<void()> pCommand, bool bSmallFont = false, bool bShowCancel = true );
|
||||
GamepadUIGenericConfirmationPanel( vgui::Panel *pParent, const char* pPanelName, const wchar_t *pTitle, const wchar_t *pText, std::function<void()> pCommand, bool bSmallFont = false, bool bShowCancel = true );
|
||||
|
||||
void Paint() OVERRIDE;
|
||||
void OnCommand( const char *pCommand ) OVERRIDE;
|
||||
void ApplySchemeSettings( vgui::IScheme* pScheme ) OVERRIDE;
|
||||
void UpdateGradients() OVERRIDE;
|
||||
|
||||
|
||||
private:
|
||||
void PaintText();
|
||||
|
||||
GamepadUIString m_strText;
|
||||
|
||||
std::function<void()> m_pCommand;
|
||||
|
||||
GAMEPADUI_PANEL_PROPERTY( Color, m_colGenericConfirmationColor, "GenericConfirmation", "255 255 255 255", SchemeValueTypes::Color );
|
||||
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flGenericConfirmationOffsetX, "GenericConfirmation.OffsetX", "0", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flGenericConfirmationOffsetY, "GenericConfirmation.OffsetY", "0", SchemeValueTypes::ProportionalFloat );
|
||||
|
||||
vgui::HFont m_hGenericConfirmationFont;
|
||||
const char *m_pszGenericConfirmationFontName;
|
||||
};
|
||||
|
||||
#endif
|
187
game/gamepadui/gamepadui_genericframes.cpp
Normal file
187
game/gamepadui/gamepadui_genericframes.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
#include "gamepadui_interface.h"
|
||||
#include "gamepadui_genericframes.h"
|
||||
#include "gamepadui_util.h"
|
||||
|
||||
#include "ienginevgui.h"
|
||||
#include "vgui/ILocalize.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "vgui/IVGui.h"
|
||||
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
GamepadUIGenericBasePanel::GamepadUIGenericBasePanel( vgui::Panel *pParent, const char* pPanelName, const char* pTitle, std::function<void()> pCommand, bool bShowCancel )
|
||||
: BaseClass( pParent, pPanelName )
|
||||
, m_pCommand( std::move( pCommand ) )
|
||||
{
|
||||
vgui::HScheme hScheme = vgui::scheme()->LoadSchemeFromFileEx( GamepadUI::GetInstance().GetSizingVPanel(), GAMEPADUI_DEFAULT_PANEL_SCHEME, "SchemePanel" );
|
||||
SetScheme( hScheme );
|
||||
|
||||
GetFrameTitle() = GamepadUIString( pTitle );
|
||||
FooterButtonMask buttons = FooterButtons::Okay;
|
||||
if ( bShowCancel )
|
||||
buttons |= FooterButtons::Cancel;
|
||||
SetFooterButtons( buttons );
|
||||
|
||||
Activate();
|
||||
|
||||
UpdateGradients();
|
||||
}
|
||||
|
||||
GamepadUIGenericBasePanel::GamepadUIGenericBasePanel( vgui::Panel *pParent, const char* pPanelName, const wchar_t* pTitle, std::function<void()> pCommand, bool bShowCancel )
|
||||
: BaseClass( pParent, pPanelName )
|
||||
, m_pCommand( std::move( pCommand ) )
|
||||
{
|
||||
vgui::HScheme hScheme = vgui::scheme()->LoadSchemeFromFileEx( GamepadUI::GetInstance().GetSizingVPanel(), GAMEPADUI_DEFAULT_PANEL_SCHEME, "SchemePanel" );
|
||||
SetScheme( hScheme );
|
||||
|
||||
GetFrameTitle() = GamepadUIString( pTitle );
|
||||
FooterButtonMask buttons = FooterButtons::Okay;
|
||||
if ( bShowCancel )
|
||||
buttons |= FooterButtons::Cancel;
|
||||
SetFooterButtons( buttons );
|
||||
|
||||
Activate();
|
||||
|
||||
UpdateGradients();
|
||||
}
|
||||
|
||||
void GamepadUIGenericBasePanel::ApplySchemeSettings( vgui::IScheme* pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
|
||||
if ( CenterPanel() )
|
||||
{
|
||||
int nWide, nTall;
|
||||
ContentSize( nWide, nTall );
|
||||
|
||||
int nParentW, nParentH;
|
||||
GetParent()->GetSize( nParentW, nParentH );
|
||||
|
||||
int nYOffset = (nParentH / 2 - nTall / 2) - (m_flTitleOffsetY * 0.5f);
|
||||
|
||||
m_flFooterButtonsOffsetY = (nYOffset - m_flTitleOffsetY);
|
||||
m_flFooterButtonsOffsetX *= 3;
|
||||
|
||||
m_flTitleOffsetY = nYOffset - (m_flContentOffsetY - m_flTitleOffsetY);
|
||||
m_flContentOffsetY = nYOffset;
|
||||
}
|
||||
}
|
||||
|
||||
void GamepadUIGenericBasePanel::UpdateGradients()
|
||||
{
|
||||
const float flTime = GamepadUI::GetInstance().GetTime();
|
||||
GamepadUI::GetInstance().GetGradientHelper()->ResetTargets( flTime );
|
||||
GamepadUI::GetInstance().GetGradientHelper()->SetTargetGradient( GradientSide::Up, { 1.0f, 1.0f }, flTime );
|
||||
GamepadUI::GetInstance().GetGradientHelper()->SetTargetGradient( GradientSide::Left, { 1.0f, 0.6667f }, flTime );
|
||||
GamepadUI::GetInstance().GetGradientHelper()->SetTargetGradient( GradientSide::Down, { 1.0f, 1.0f }, flTime );
|
||||
}
|
||||
|
||||
void GamepadUIGenericBasePanel::Paint()
|
||||
{
|
||||
BaseClass::Paint();
|
||||
|
||||
PaintContent();
|
||||
// Workaround focus shifting to main menu and getting the wrong gradients
|
||||
// causing us to not over paint everything leading to weird left over bits of text
|
||||
UpdateGradients();
|
||||
}
|
||||
|
||||
void GamepadUIGenericBasePanel::OnCommand( const char* pCommand )
|
||||
{
|
||||
if ( !V_strcmp( pCommand, "action_cancel" ) )
|
||||
{
|
||||
Close();
|
||||
}
|
||||
else if ( !V_strcmp( pCommand, "action_okay" ) )
|
||||
{
|
||||
m_pCommand();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
GamepadUIGenericImagePanel::GamepadUIGenericImagePanel( vgui::Panel *pParent, const char* pPanelName, const char* pTitle, const char *pImage, float flImageWide, float flImageTall, std::function<void()> pCommand, bool bShowCancel )
|
||||
: BaseClass( pParent, pPanelName, pTitle, pCommand, bShowCancel )
|
||||
{
|
||||
const char *pszExt = V_GetFileExtension( pImage );
|
||||
if (pszExt && V_strncmp( pszExt, "tga", 4 ) == 0)
|
||||
{
|
||||
m_Image.SetTGAImage( pImage );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Image.SetImage( pImage );
|
||||
}
|
||||
|
||||
m_flBaseImageWide = flImageWide;
|
||||
m_flBaseImageTall = flImageTall;
|
||||
}
|
||||
|
||||
GamepadUIGenericImagePanel::GamepadUIGenericImagePanel( vgui::Panel *pParent, const char* pPanelName, const wchar_t* pTitle, const char *pImage, float flImageWide, float flImageTall, std::function<void()> pCommand, bool bShowCancel )
|
||||
: BaseClass( pParent, pPanelName, pTitle, pCommand, bShowCancel )
|
||||
{
|
||||
const char *pszExt = V_GetFileExtension( pImage );
|
||||
if (pszExt && V_strncmp( pszExt, "tga", 4 ) == 0)
|
||||
{
|
||||
m_Image.SetTGAImage( pImage );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Image.SetImage( pImage );
|
||||
}
|
||||
|
||||
m_flBaseImageWide = flImageWide;
|
||||
m_flBaseImageTall = flImageTall;
|
||||
}
|
||||
|
||||
void GamepadUIGenericImagePanel::ApplySchemeSettings( vgui::IScheme* pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
|
||||
m_flImageWide = float( vgui::scheme()->GetProportionalScaledValueEx( GetScheme(), int( m_flBaseImageWide ) ) );
|
||||
m_flImageTall = float( vgui::scheme()->GetProportionalScaledValueEx( GetScheme(), int( m_flBaseImageTall ) ) );
|
||||
|
||||
// For now, always center the image independent of the frame
|
||||
int nParentW, nParentH;
|
||||
GetParent()->GetSize( nParentW, nParentH );
|
||||
|
||||
m_flContentOffsetX = (nParentW / 2 - m_flImageWide / 2);
|
||||
m_flContentOffsetY = (nParentH / 2 - m_flImageTall / 2);
|
||||
}
|
||||
|
||||
void GamepadUIGenericImagePanel::PaintContent()
|
||||
{
|
||||
vgui::surface()->DrawSetTexture( m_Image );
|
||||
vgui::surface()->DrawSetColor( m_colContentColor );
|
||||
vgui::surface()->DrawTexturedRect( m_flContentOffsetX, m_flContentOffsetY, m_flContentOffsetX + m_flImageWide, m_flContentOffsetY + m_flImageTall );
|
||||
vgui::surface()->DrawSetTexture( 0 );
|
||||
}
|
||||
|
||||
CON_COMMAND( gamepadui_opengenericimagedialog, "Opens a generic image dialog.\nFormat: gamepadui_opengenericimagedialog <title> <image> <width> <height> <optional: command>" )
|
||||
{
|
||||
if (args.ArgC() < 5)
|
||||
{
|
||||
Msg("Format: gamepadui_opengenericimagedialog <title> <image> <width> <height> <optional: command>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Optional command
|
||||
const char *pCmd = NULL;
|
||||
if (args.ArgC() > 5)
|
||||
pCmd = args.Arg( 5 );
|
||||
|
||||
// TODO: Parent to current frame
|
||||
new GamepadUIGenericImagePanel( GamepadUI::GetInstance().GetBasePanel(), "GenericPanel", args.Arg(1), args.Arg(2), atof(args.Arg(3)), atof(args.Arg(4)),
|
||||
[pCmd]()
|
||||
{
|
||||
if (pCmd)
|
||||
{
|
||||
// Replace '' with quotes
|
||||
char szCmd[512];
|
||||
V_StrSubst( pCmd, "''", "\"", szCmd, sizeof(szCmd) );
|
||||
|
||||
GamepadUI::GetInstance().GetEngineClient()->ClientCmd_Unrestricted( szCmd );
|
||||
}
|
||||
}, false );
|
||||
}
|
62
game/gamepadui/gamepadui_genericframes.h
Normal file
62
game/gamepadui/gamepadui_genericframes.h
Normal file
@ -0,0 +1,62 @@
|
||||
#ifndef GAMEPADUI_GENERICFRAME_H
|
||||
#define GAMEPADUI_GENERICFRAME_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "gamepadui_frame.h"
|
||||
#include "gamepadui_image.h"
|
||||
#include "tier0/valve_minmax_off.h"
|
||||
#include <functional>
|
||||
#include "tier0/valve_minmax_on.h"
|
||||
|
||||
class GamepadUIGenericBasePanel : public GamepadUIFrame
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( GamepadUIGenericBasePanel, GamepadUIFrame );
|
||||
|
||||
public:
|
||||
GamepadUIGenericBasePanel( vgui::Panel *pParent, const char *pPanelName, const char *pTitle, std::function<void()> pCommand, bool bShowCancel = true );
|
||||
GamepadUIGenericBasePanel( vgui::Panel *pParent, const char *pPanelName, const wchar_t *pTitle, std::function<void()> pCommand, bool bShowCancel = true );
|
||||
|
||||
void Paint() OVERRIDE;
|
||||
void OnCommand( const char *pCommand ) OVERRIDE;
|
||||
void ApplySchemeSettings( vgui::IScheme* pScheme ) OVERRIDE;
|
||||
void UpdateGradients() OVERRIDE;
|
||||
|
||||
virtual void PaintContent() {}
|
||||
|
||||
virtual void ContentSize( int &nWide, int &nTall ) {}
|
||||
virtual bool CenterPanel() { return false; }
|
||||
|
||||
protected:
|
||||
|
||||
GAMEPADUI_PANEL_PROPERTY( Color, m_colContentColor, "Content", "255 255 255 255", SchemeValueTypes::Color );
|
||||
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flContentOffsetX, "Content.OffsetX", "64", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flContentOffsetY, "Content.OffsetY", "110", SchemeValueTypes::ProportionalFloat );
|
||||
|
||||
private:
|
||||
std::function<void()> m_pCommand;
|
||||
};
|
||||
|
||||
class GamepadUIGenericImagePanel : public GamepadUIGenericBasePanel
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( GamepadUIGenericImagePanel, GamepadUIGenericBasePanel );
|
||||
|
||||
public:
|
||||
GamepadUIGenericImagePanel( vgui::Panel *pParent, const char* pPanelName, const char *pTitle, const char *pImage, float flImageWide, float flImageTall, std::function<void()> pCommand, bool bShowCancel = false );
|
||||
GamepadUIGenericImagePanel( vgui::Panel *pParent, const char* pPanelName, const wchar_t *pTitle, const char *pImage, float flImageWide, float flImageTall, std::function<void()> pCommand, bool bShowCancel = false );
|
||||
|
||||
void ApplySchemeSettings( vgui::IScheme *pScheme ) OVERRIDE;
|
||||
void PaintContent() OVERRIDE;
|
||||
|
||||
private:
|
||||
GamepadUIImage m_Image;
|
||||
|
||||
float m_flBaseImageWide;
|
||||
float m_flBaseImageTall;
|
||||
float m_flImageWide; // Proportionally scaled
|
||||
float m_flImageTall; // Proportionally scaled
|
||||
};
|
||||
|
||||
#endif
|
236
game/gamepadui/gamepadui_glyph.h
Normal file
236
game/gamepadui/gamepadui_glyph.h
Normal file
@ -0,0 +1,236 @@
|
||||
#ifndef GAMEPADUI_GLYPH_H
|
||||
#define GAMEPADUI_GLYPH_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "gamepadui_interface.h"
|
||||
#include "gamepadui_util.h"
|
||||
|
||||
#ifdef STEAM_INPUT
|
||||
#include "img_png_loader.h"
|
||||
#elif defined(HL2_RETAIL) // Steam input and Steam Controller are not supported in SDK2013 (Madi)
|
||||
#include "steam/hl2/isteaminput.h"
|
||||
#include "imageutils.h"
|
||||
#endif // HL2_RETAIL
|
||||
|
||||
#include "inputsystem/iinputsystem.h"
|
||||
#include "bitmap/bitmap.h"
|
||||
|
||||
class GamepadUIGlyph
|
||||
{
|
||||
public:
|
||||
GamepadUIGlyph()
|
||||
{
|
||||
m_nOriginTextures[0] = -1;
|
||||
m_nOriginTextures[1] = -1;
|
||||
}
|
||||
|
||||
~GamepadUIGlyph()
|
||||
{
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
bool SetupGlyph( int nSize, const char *pszAction, bool bBaseLight = false )
|
||||
{
|
||||
#ifdef STEAM_INPUT
|
||||
|
||||
if (m_pszActionOrigin && !V_strcmp(pszAction, m_pszActionOrigin))
|
||||
return IsValid();
|
||||
|
||||
Cleanup();
|
||||
|
||||
m_pszActionOrigin = pszAction;
|
||||
|
||||
int iRealSize = nSize;
|
||||
|
||||
int kStyles[2] =
|
||||
{
|
||||
//bBaseLight ? ESteamInputGlyphStyle_Light : ESteamInputGlyphStyle_Knockout,
|
||||
//ESteamInputGlyphStyle_Dark,
|
||||
bBaseLight ? 1 : 0,
|
||||
2,
|
||||
};
|
||||
|
||||
for ( int i = 0; i < 2; i++ )
|
||||
{
|
||||
CUtlVector <const char *> szStringList;
|
||||
GamepadUI::GetInstance().GetSteamInput()->GetGlyphPNGsForCommand( szStringList, pszAction, iRealSize, kStyles[i] );
|
||||
if (szStringList.Count() == 0)
|
||||
{
|
||||
Cleanup();
|
||||
return false;
|
||||
}
|
||||
|
||||
CUtlMemory< byte > image;
|
||||
int w, h;
|
||||
if ( !PNGtoRGBA( g_pFullFileSystem, szStringList[0], image, w, h ) )
|
||||
{
|
||||
Cleanup();
|
||||
return false;
|
||||
}
|
||||
|
||||
DevMsg( "Loaded png %dx%d\n", w, h );
|
||||
|
||||
m_nOriginTextures[i] = vgui::surface()->CreateNewTextureID(true);
|
||||
if ( m_nOriginTextures[i] <= 0 )
|
||||
{
|
||||
Cleanup();
|
||||
return false;
|
||||
}
|
||||
g_pMatSystemSurface->DrawSetTextureRGBA( m_nOriginTextures[i], image.Base(), w, h, true, false );
|
||||
}
|
||||
#elif defined(HL2_RETAIL) // Steam input and Steam Controller are not supported in SDK2013 (Madi)
|
||||
uint64 nSteamInputHandles[STEAM_INPUT_MAX_COUNT];
|
||||
if ( !GamepadUI::GetInstance().GetSteamAPIContext() || !GamepadUI::GetInstance().GetSteamAPIContext()->SteamInput() )
|
||||
return false;
|
||||
|
||||
GamepadUI::GetInstance().GetSteamAPIContext()->SteamInput()->GetConnectedControllers( nSteamInputHandles );
|
||||
|
||||
uint64 nController = g_pInputSystem->GetActiveSteamInputHandle();
|
||||
if ( !nController )
|
||||
nController = nSteamInputHandles[0];
|
||||
|
||||
if ( !nController )
|
||||
return false;
|
||||
|
||||
InputActionSetHandle_t hActionSet = GamepadUI::GetInstance().GetSteamAPIContext()->SteamInput()->GetCurrentActionSet( nController );
|
||||
InputDigitalActionHandle_t hDigitalAction = GamepadUI::GetInstance().GetSteamAPIContext()->SteamInput()->GetDigitalActionHandle( pszAction );
|
||||
if ( !hDigitalAction )
|
||||
{
|
||||
Cleanup();
|
||||
return false;
|
||||
}
|
||||
|
||||
EInputActionOrigin eOrigins[STEAM_INPUT_MAX_ORIGINS] = {};
|
||||
int nOriginCount = GamepadUI::GetInstance().GetSteamAPIContext()->SteamInput()->GetDigitalActionOrigins( nController, hActionSet, hDigitalAction, eOrigins );
|
||||
EInputActionOrigin eOrigin = eOrigins[0];
|
||||
if ( !nOriginCount || eOrigin == k_EInputActionOrigin_None )
|
||||
{
|
||||
Cleanup();
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( m_eActionOrigin == eOrigin )
|
||||
return IsValid();
|
||||
|
||||
Cleanup();
|
||||
|
||||
m_eActionOrigin = eOrigin;
|
||||
|
||||
if ( !IsPowerOfTwo( nSize ) )
|
||||
nSize = NextPowerOfTwo( nSize );
|
||||
|
||||
int nGlyphSize = 256;
|
||||
ESteamInputGlyphSize eGlyphSize = k_ESteamInputGlyphSize_Large;
|
||||
if (nSize <= 32)
|
||||
{
|
||||
eGlyphSize = k_ESteamInputGlyphSize_Small;
|
||||
nGlyphSize = 32;
|
||||
}
|
||||
else if (nSize <= 128)
|
||||
{
|
||||
eGlyphSize = k_ESteamInputGlyphSize_Medium;
|
||||
nGlyphSize = 128;
|
||||
}
|
||||
else
|
||||
{
|
||||
eGlyphSize = k_ESteamInputGlyphSize_Large;
|
||||
nGlyphSize = 256;
|
||||
}
|
||||
|
||||
ESteamInputGlyphStyle kStyles[2] =
|
||||
{
|
||||
bBaseLight ? ESteamInputGlyphStyle_Light : ESteamInputGlyphStyle_Knockout,
|
||||
ESteamInputGlyphStyle_Dark,
|
||||
};
|
||||
|
||||
for ( int i = 0; i < 2; i++ )
|
||||
{
|
||||
const char* pszGlyph = GamepadUI::GetInstance().GetSteamAPIContext()->SteamInput()->GetGlyphPNGForActionOrigin( eOrigin, eGlyphSize, kStyles[i] );
|
||||
if (!pszGlyph)
|
||||
{
|
||||
Cleanup();
|
||||
return false;
|
||||
}
|
||||
|
||||
Bitmap_t bitmap;
|
||||
ConversionErrorType error = ImgUtl_LoadBitmap( pszGlyph, bitmap );
|
||||
if ( error != CE_SUCCESS )
|
||||
{
|
||||
Cleanup();
|
||||
return false;
|
||||
}
|
||||
|
||||
ImgUtl_ResizeBitmap( bitmap, nSize, nSize, &bitmap );
|
||||
|
||||
m_nOriginTextures[i] = vgui::surface()->CreateNewTextureID(true);
|
||||
if ( m_nOriginTextures[i] <= 0 )
|
||||
{
|
||||
Cleanup();
|
||||
return false;
|
||||
}
|
||||
g_pMatSystemSurface->DrawSetTextureRGBAEx2( m_nOriginTextures[i], bitmap.GetBits(), bitmap.Width(), bitmap.Height(), ImageFormat::IMAGE_FORMAT_RGBA8888, true, false );
|
||||
}
|
||||
#else
|
||||
return false;
|
||||
|
||||
#endif // HL2_RETAIL
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PaintGlyph( int nX, int nY, int nSize, int nBaseAlpha )
|
||||
{
|
||||
int nPressedAlpha = 255 - nBaseAlpha;
|
||||
|
||||
if ( nBaseAlpha )
|
||||
{
|
||||
vgui::surface()->DrawSetColor( Color( 255, 255, 255, nBaseAlpha ) );
|
||||
vgui::surface()->DrawSetTexture( m_nOriginTextures[0] );
|
||||
vgui::surface()->DrawTexturedRect( nX, nY, nX + nSize, nY + nSize );
|
||||
}
|
||||
|
||||
if ( nPressedAlpha )
|
||||
{
|
||||
vgui::surface()->DrawSetColor( Color( 255, 255, 255, nPressedAlpha ) );
|
||||
vgui::surface()->DrawSetTexture( m_nOriginTextures[1] );
|
||||
vgui::surface()->DrawTexturedRect( nX, nY, nX + nSize, nY + nSize );
|
||||
}
|
||||
|
||||
vgui::surface()->DrawSetTexture(0);
|
||||
}
|
||||
|
||||
bool IsValid()
|
||||
{
|
||||
return m_nOriginTextures[0] > 0 && m_nOriginTextures[1] > 0;
|
||||
}
|
||||
|
||||
void Cleanup()
|
||||
{
|
||||
for ( int i = 0; i < 2; i++ )
|
||||
{
|
||||
if ( m_nOriginTextures[ i ] > 0 )
|
||||
vgui::surface()->DestroyTextureID( m_nOriginTextures[ i ] );
|
||||
m_nOriginTextures[ i ] = -1;
|
||||
}
|
||||
|
||||
#ifdef STEAM_INPUT
|
||||
m_pszActionOrigin = NULL;
|
||||
#elif defined(HL2_RETAIL)
|
||||
m_eActionOrigin = k_EInputActionOrigin_None;
|
||||
#endif // HL2_RETAIL
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
#ifdef STEAM_INPUT
|
||||
const char *m_pszActionOrigin = NULL;
|
||||
#elif defined(HL2_RETAIL)
|
||||
EInputActionOrigin m_eActionOrigin = k_EInputActionOrigin_None;
|
||||
#endif // HL2_RETAIL
|
||||
|
||||
int m_nOriginTextures[2];
|
||||
};
|
||||
|
||||
#endif
|
77
game/gamepadui/gamepadui_gradient_helper.h
Normal file
77
game/gamepadui/gamepadui_gradient_helper.h
Normal file
@ -0,0 +1,77 @@
|
||||
#ifndef GAMEPADUI_GRADIENT_HELPER_H
|
||||
#define GAMEPADUI_GRADIENT_HELPER_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "igamepadui.h"
|
||||
#include "mathlib/mathlib.h"
|
||||
|
||||
namespace GradientSides
|
||||
{
|
||||
enum GradientSide
|
||||
{
|
||||
Left,
|
||||
Right,
|
||||
Up,
|
||||
Down,
|
||||
|
||||
Count
|
||||
};
|
||||
}
|
||||
using GradientSide = GradientSides::GradientSide;
|
||||
|
||||
struct GradientInfo
|
||||
{
|
||||
float flAmount;
|
||||
float flExtent;
|
||||
};
|
||||
|
||||
class GradientHelper
|
||||
{
|
||||
public:
|
||||
GradientHelper()
|
||||
{
|
||||
memset( &m_LastGradientChange, 0, sizeof( m_LastGradientChange ) );
|
||||
memset( &m_LastGradientInfo, 0, sizeof( m_LastGradientInfo ) );
|
||||
memset( &m_TargetGradientInfos, 0, sizeof( m_TargetGradientInfos ) );
|
||||
}
|
||||
|
||||
void ResetTargets( float flTime )
|
||||
{
|
||||
for ( int i = 0; i < GradientSides::Count; i++ )
|
||||
SetTargetGradient( GradientSide(i), GradientInfo{}, flTime );
|
||||
}
|
||||
|
||||
void SetTargetGradient( GradientSide side, GradientInfo info, float flTime )
|
||||
{
|
||||
m_LastGradientInfo[side] = GetGradient( side, flTime );
|
||||
m_TargetGradientInfos[side] = info;
|
||||
m_LastGradientChange[side] = flTime;
|
||||
}
|
||||
|
||||
GradientInfo GetGradient( GradientSide side, float flTime )
|
||||
{
|
||||
const GradientInfo& target = m_TargetGradientInfos[side];
|
||||
const GradientInfo& last = m_LastGradientInfo[side];
|
||||
|
||||
float flFadeTime = SimpleSpline(
|
||||
RemapValClamped( flTime, m_LastGradientChange[side], m_LastGradientChange[side] + 0.5f, 0.0f, 1.0f ));
|
||||
|
||||
return GradientInfo
|
||||
{
|
||||
Lerp( flFadeTime, last.flAmount, target.flAmount ),
|
||||
last.flAmount && target.flAmount && last.flExtent > target.flExtent
|
||||
? Lerp( flFadeTime, last.flExtent, target.flExtent )
|
||||
: target.flExtent
|
||||
};
|
||||
}
|
||||
|
||||
private:
|
||||
float m_LastGradientChange [ GradientSides::Count ];
|
||||
GradientInfo m_LastGradientInfo [ GradientSides::Count ];
|
||||
GradientInfo m_TargetGradientInfos[ GradientSides::Count ];
|
||||
};
|
||||
|
||||
|
||||
#endif // GAMEPADUI_GRADIENT_HELPER_H
|
23
game/gamepadui/gamepadui_hl2.vpc
Normal file
23
game/gamepadui/gamepadui_hl2.vpc
Normal file
@ -0,0 +1,23 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// GAMEPADUI_HL2.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro GAMENAME "mod_hl2" // Stock SDK2013, Modders should replace this line with their mod folder name if needed.
|
||||
$Macro OUTBINNAME "gamepadui"
|
||||
|
||||
$Include "$SRCDIR\game\gamepadui\gamepadui_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$PreprocessorDefinitions "$BASE;GAMEPADUI_GAME_HL2"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "GamepadUI (HL2)"
|
||||
{
|
||||
}
|
67
game/gamepadui/gamepadui_image.h
Normal file
67
game/gamepadui/gamepadui_image.h
Normal file
@ -0,0 +1,67 @@
|
||||
#ifndef GAMEPADUI_IMAGE_H
|
||||
#define GAMEPADUI_IMAGE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "vgui_controls/Panel.h"
|
||||
#include "bitmap/tgaloader.h"
|
||||
|
||||
class GamepadUIImage
|
||||
{
|
||||
public:
|
||||
GamepadUIImage()
|
||||
{
|
||||
}
|
||||
GamepadUIImage( const char* pName )
|
||||
{
|
||||
SetImage( pName );
|
||||
}
|
||||
~GamepadUIImage()
|
||||
{
|
||||
Cleanup();
|
||||
}
|
||||
void Cleanup()
|
||||
{
|
||||
if ( IsValid() )
|
||||
vgui::surface()->DestroyTextureID( m_nId );
|
||||
|
||||
m_nId = -1;
|
||||
}
|
||||
void SetImage( const char* pName )
|
||||
{
|
||||
Cleanup();
|
||||
|
||||
m_nId = vgui::surface()->CreateNewTextureID();
|
||||
vgui::surface()->DrawSetTextureFile( m_nId, pName, true, false );
|
||||
}
|
||||
void SetTGAImage( const char* pName )
|
||||
{
|
||||
Cleanup();
|
||||
|
||||
CUtlMemory< unsigned char > tga;
|
||||
int nWidth, nHeight;
|
||||
if ( !TGALoader::LoadRGBA8888( pName, tga, nWidth, nHeight ) )
|
||||
return;
|
||||
|
||||
m_nId = vgui::surface()->CreateNewTextureID( true );
|
||||
|
||||
#ifdef HL2_RETAIL // this crashes SDK2013 in the save/load menu (Madi)
|
||||
g_pMatSystemSurface->DrawSetTextureRGBAEx2( m_nId, tga.Base(), nWidth, nHeight, IMAGE_FORMAT_RGBA8888, true );
|
||||
#else
|
||||
g_pMatSystemSurface->DrawSetTextureRGBAEx( m_nId, tga.Base(), nWidth, nHeight, IMAGE_FORMAT_RGBA8888 );
|
||||
#endif
|
||||
}
|
||||
bool IsValid()
|
||||
{
|
||||
return m_nId > 0;
|
||||
}
|
||||
operator int()
|
||||
{
|
||||
return m_nId;
|
||||
}
|
||||
private:
|
||||
int m_nId = -1;
|
||||
};
|
||||
|
||||
#endif // GAMEPADUI_IMAGE_H
|
279
game/gamepadui/gamepadui_interface.cpp
Normal file
279
game/gamepadui/gamepadui_interface.cpp
Normal file
@ -0,0 +1,279 @@
|
||||
#include "gamepadui_interface.h"
|
||||
#include "gamepadui_basepanel.h"
|
||||
#include "gamepadui_mainmenu.h"
|
||||
|
||||
#include "vgui/ILocalize.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
static CDllDemandLoader s_GameUI( "GameUI" );
|
||||
|
||||
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( GamepadUI, IGamepadUI, GAMEPADUI_INTERFACE_VERSION, GamepadUI::GetInstance() );
|
||||
|
||||
GamepadUI *GamepadUI::s_pGamepadUI = NULL;
|
||||
|
||||
GamepadUI& GamepadUI::GetInstance()
|
||||
{
|
||||
if ( !s_pGamepadUI )
|
||||
s_pGamepadUI = new GamepadUI;
|
||||
|
||||
return *s_pGamepadUI;
|
||||
}
|
||||
|
||||
void GamepadUI::Initialize( CreateInterfaceFn factory )
|
||||
{
|
||||
ConnectTier1Libraries( &factory, 1 );
|
||||
ConnectTier2Libraries( &factory, 1 );
|
||||
ConVar_Register( FCVAR_CLIENTDLL );
|
||||
ConnectTier3Libraries( &factory, 1 );
|
||||
|
||||
m_pEngineClient = (IVEngineClient*) factory( VENGINE_CLIENT_INTERFACE_VERSION, NULL );
|
||||
m_pEngineSound = (IEngineSound*) factory( IENGINESOUND_CLIENT_INTERFACE_VERSION, NULL );
|
||||
m_pEngineVGui = (IEngineVGui*) factory( VENGINE_VGUI_VERSION, NULL );
|
||||
m_pGameUIFuncs = (IGameUIFuncs*) factory( VENGINE_GAMEUIFUNCS_VERSION, NULL );
|
||||
m_pMaterialSystem = (IMaterialSystem*) factory( MATERIAL_SYSTEM_INTERFACE_VERSION, NULL );
|
||||
m_pMaterialSystemSurface = (IMatSystemSurface*) factory( MAT_SYSTEM_SURFACE_INTERFACE_VERSION, NULL );
|
||||
m_pRenderView = (IVRenderView*) factory( VENGINE_RENDERVIEW_INTERFACE_VERSION, NULL );
|
||||
m_pSoundEmitterSystemBase = (ISoundEmitterSystemBase*)factory( SOUNDEMITTERSYSTEM_INTERFACE_VERSION, NULL );
|
||||
|
||||
CreateInterfaceFn gameuiFactory = s_GameUI.GetFactory();
|
||||
if ( gameuiFactory )
|
||||
m_pGameUI = (IGameUI*) gameuiFactory( GAMEUI_INTERFACE_VERSION, NULL );
|
||||
|
||||
m_pAchievementMgr = (IAchievementMgr*) m_pEngineClient->GetAchievementMgr();
|
||||
|
||||
bool bFailed = !m_pEngineClient ||
|
||||
!m_pEngineSound ||
|
||||
!m_pEngineVGui ||
|
||||
!m_pGameUIFuncs ||
|
||||
!m_pMaterialSystem ||
|
||||
!m_pMaterialSystemSurface ||
|
||||
!m_pRenderView ||
|
||||
!m_pSoundEmitterSystemBase ||
|
||||
!m_pGameUI ||
|
||||
!m_pAchievementMgr;
|
||||
if ( bFailed )
|
||||
{
|
||||
GamepadUI_Log( "GamepadUI::Initialize() failed to get necessary interfaces.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
g_pVGuiLocalize->AddFile( "resource/gameui_%language%.txt", "GAME", true );
|
||||
g_pVGuiLocalize->AddFile( "resource/deck_%language%.txt", "GAME", true );
|
||||
|
||||
#if defined(HL2_RETAIL) || defined(STEAM_INPUT)
|
||||
SteamAPI_InitSafe();
|
||||
SteamAPI_SetTryCatchCallbacks( false );
|
||||
m_SteamAPIContext.Init();
|
||||
#endif // HL2_RETAIL
|
||||
|
||||
m_pBasePanel = new GamepadUIBasePanel( GetRootVPanel() );
|
||||
if ( !m_pBasePanel )
|
||||
{
|
||||
GamepadUI_Log( "Failed to create BasePanel.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
GamepadUI_Log( "Overriding menu.\n" );
|
||||
|
||||
m_pGameUI->SetMainMenuOverride( GetBaseVPanel() );
|
||||
|
||||
m_pAnimationController = new vgui::AnimationController( m_pBasePanel );
|
||||
m_pAnimationController->SetProportional( false );
|
||||
|
||||
GetMainMenu()->Activate();
|
||||
}
|
||||
|
||||
void GamepadUI::Shutdown()
|
||||
{
|
||||
if ( m_pGameUI )
|
||||
m_pGameUI->SetMainMenuOverride( NULL );
|
||||
|
||||
if ( m_pBasePanel )
|
||||
m_pBasePanel->DeletePanel();
|
||||
|
||||
#if defined(HL2_RETAIL) || defined(STEAM_INPUT)
|
||||
m_SteamAPIContext.Clear();
|
||||
#endif
|
||||
|
||||
ConVar_Unregister();
|
||||
DisconnectTier3Libraries();
|
||||
DisconnectTier2Libraries();
|
||||
DisconnectTier1Libraries();
|
||||
}
|
||||
|
||||
|
||||
void GamepadUI::OnUpdate( float flFrametime )
|
||||
{
|
||||
if ( m_pAnimationController )
|
||||
m_pAnimationController->UpdateAnimations( GetTime() );
|
||||
}
|
||||
|
||||
void GamepadUI::OnLevelInitializePreEntity()
|
||||
{
|
||||
}
|
||||
|
||||
void GamepadUI::OnLevelInitializePostEntity()
|
||||
{
|
||||
m_pBasePanel->OnMenuStateChanged();
|
||||
GetMainMenu()->OnMenuStateChanged();
|
||||
}
|
||||
|
||||
void GamepadUI::OnLevelShutdown()
|
||||
{
|
||||
if ( m_pAnimationController )
|
||||
{
|
||||
m_pAnimationController->UpdateAnimations( GetTime() );
|
||||
m_pAnimationController->RunAllAnimationsToCompletion();
|
||||
}
|
||||
|
||||
m_pBasePanel->OnMenuStateChanged();
|
||||
GetMainMenu()->OnMenuStateChanged();
|
||||
}
|
||||
|
||||
void GamepadUI::VidInit()
|
||||
{
|
||||
int w, h;
|
||||
vgui::surface()->GetScreenSize( w, h );
|
||||
|
||||
Assert( w != 0 && h != 0 );
|
||||
|
||||
// Scale elements proportional to the aspect ratio's distance from 16:10
|
||||
const float flDefaultInvAspect = 0.625f;
|
||||
float flInvAspectRatio = ((float)h) / ((float)w);
|
||||
|
||||
if (flInvAspectRatio != flDefaultInvAspect)
|
||||
{
|
||||
m_flScreenXRatio = 1.0f - (flInvAspectRatio - flDefaultInvAspect);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flScreenXRatio = 1.0f;
|
||||
}
|
||||
|
||||
m_flScreenYRatio = 1.0f;
|
||||
|
||||
m_pBasePanel->InvalidateLayout( false, true );
|
||||
}
|
||||
|
||||
|
||||
bool GamepadUI::IsInLevel() const
|
||||
{
|
||||
const char *pLevelName = m_pEngineClient->GetLevelName();
|
||||
return pLevelName && *pLevelName && !m_pEngineClient->IsLevelMainMenuBackground();
|
||||
}
|
||||
|
||||
bool GamepadUI::IsInBackgroundLevel() const
|
||||
{
|
||||
const char *pLevelName = m_pEngineClient->GetLevelName();
|
||||
return pLevelName && *pLevelName && m_pEngineClient->IsLevelMainMenuBackground();
|
||||
}
|
||||
|
||||
bool GamepadUI::IsInMultiplayer() const
|
||||
{
|
||||
return IsInLevel() && m_pEngineClient->GetMaxClients() > 1;
|
||||
}
|
||||
|
||||
bool GamepadUI::IsGamepadUIVisible() const
|
||||
{
|
||||
return !IsInLevel() || IsInBackgroundLevel();
|
||||
}
|
||||
|
||||
|
||||
void GamepadUI::ResetToMainMenuGradients()
|
||||
{
|
||||
GetMainMenu()->UpdateGradients();
|
||||
}
|
||||
|
||||
vgui::VPANEL GamepadUI::GetRootVPanel() const
|
||||
{
|
||||
return m_pEngineVGui->GetPanel( PANEL_GAMEUIDLL );
|
||||
}
|
||||
|
||||
vgui::Panel *GamepadUI::GetBasePanel() const
|
||||
{
|
||||
return m_pBasePanel;
|
||||
}
|
||||
|
||||
vgui::VPANEL GamepadUI::GetBaseVPanel() const
|
||||
{
|
||||
return m_pBasePanel ? m_pBasePanel->GetVPanel() : 0;
|
||||
}
|
||||
|
||||
vgui::Panel *GamepadUI::GetSizingPanel() const
|
||||
{
|
||||
return m_pBasePanel ? m_pBasePanel->GetSizingPanel() : NULL;
|
||||
}
|
||||
|
||||
vgui::VPANEL GamepadUI::GetSizingVPanel() const
|
||||
{
|
||||
return GetSizingPanel() ? GetSizingPanel()->GetVPanel() : 0;
|
||||
}
|
||||
|
||||
vgui::Panel *GamepadUI::GetMainMenuPanel() const
|
||||
{
|
||||
return m_pBasePanel ? m_pBasePanel->GetMainMenuPanel() : NULL;
|
||||
}
|
||||
|
||||
vgui::VPANEL GamepadUI::GetMainMenuVPanel() const
|
||||
{
|
||||
return GetMainMenuPanel() ? GetMainMenuPanel()->GetVPanel() : 0;
|
||||
}
|
||||
|
||||
GamepadUIMainMenu* GamepadUI::GetMainMenu() const
|
||||
{
|
||||
return static_cast<GamepadUIMainMenu*>( GetMainMenuPanel() );
|
||||
}
|
||||
|
||||
void GamepadUI::GetSizingPanelScale( float &flX, float &flY ) const
|
||||
{
|
||||
vgui::Panel *pPanel = GetSizingPanel();
|
||||
if (!pPanel)
|
||||
return;
|
||||
static_cast<GamepadUISizingPanel*>(pPanel)->GetScale( flX, flY );
|
||||
}
|
||||
|
||||
void GamepadUI::GetSizingPanelOffset( int &nX, int &nY ) const
|
||||
{
|
||||
vgui::Panel *pPanel = GetSizingPanel();
|
||||
if (!pPanel)
|
||||
return;
|
||||
pPanel->GetPos( nX, nY );
|
||||
}
|
||||
|
||||
GamepadUIFrame *GamepadUI::GetCurrentFrame() const
|
||||
{
|
||||
return m_pBasePanel->GetCurrentFrame();
|
||||
}
|
||||
|
||||
vgui::VPANEL GamepadUI::GetCurrentFrameVPanel() const
|
||||
{
|
||||
return m_pBasePanel->GetCurrentFrame()->GetVPanel();
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
void GamepadUI::BonusMapChallengeNames( char *pchFileName, char *pchMapName, char *pchChallengeName )
|
||||
{
|
||||
Q_strncpy( pchFileName, m_szChallengeFileName, sizeof( m_szChallengeFileName ) );
|
||||
Q_strncpy( pchMapName, m_szChallengeMapName, sizeof( m_szChallengeMapName ) );
|
||||
Q_strncpy( pchChallengeName, m_szChallengeName, sizeof( m_szChallengeName ) );
|
||||
}
|
||||
|
||||
void GamepadUI::BonusMapChallengeObjectives( int &iBronze, int &iSilver, int &iGold )
|
||||
{
|
||||
iBronze = m_iBronze; iSilver = m_iSilver; iGold = m_iGold;
|
||||
}
|
||||
|
||||
void GamepadUI::SetCurrentChallengeObjectives( int iBronze, int iSilver, int iGold )
|
||||
{
|
||||
m_iBronze = iBronze; m_iSilver = iSilver; m_iGold = iGold;
|
||||
}
|
||||
|
||||
void GamepadUI::SetCurrentChallengeNames( const char *pszFileName, const char *pszMapName, const char *pszChallengeName )
|
||||
{
|
||||
Q_strncpy( m_szChallengeFileName, pszFileName, sizeof( m_szChallengeFileName ) );
|
||||
Q_strncpy( m_szChallengeMapName, pszMapName, sizeof( m_szChallengeMapName ) );
|
||||
Q_strncpy( m_szChallengeName, pszChallengeName, sizeof( m_szChallengeName ) );
|
||||
}
|
||||
#endif
|
152
game/gamepadui/gamepadui_interface.h
Normal file
152
game/gamepadui/gamepadui_interface.h
Normal file
@ -0,0 +1,152 @@
|
||||
#ifndef GAMEPADUI_INTERFACE_H
|
||||
#define GAMEPADUI_INTERFACE_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "igamepadui.h"
|
||||
|
||||
#include "cdll_int.h"
|
||||
#include "engine/IEngineSound.h"
|
||||
#include "gamepadui_gradient_helper.h"
|
||||
#include "GameUI/IGameUI.h"
|
||||
#include "iachievementmgr.h"
|
||||
#include "ienginevgui.h"
|
||||
#include "ivrenderview.h"
|
||||
#include "materialsystem/imaterialsystem.h"
|
||||
#include "SoundEmitterSystem/isoundemittersystembase.h"
|
||||
#include "tier1/interface.h"
|
||||
#include "tier1/strtools.h"
|
||||
#include "vgui_controls/AnimationController.h"
|
||||
#include "vgui_controls/Panel.h"
|
||||
#include "vgui/VGUI.h"
|
||||
#include "VGuiMatSurface/IMatSystemSurface.h"
|
||||
#include "view_shared.h"
|
||||
#include "IGameUIFuncs.h"
|
||||
#include "steam/steam_api.h"
|
||||
#ifdef STEAM_INPUT
|
||||
#include "expanded_steam/isteaminput.h"
|
||||
#endif
|
||||
|
||||
class GamepadUIBasePanel;
|
||||
class GamepadUIMainMenu;
|
||||
|
||||
#define GAMEPADUI_RESOURCE_FOLDER "gamepadui" CORRECT_PATH_SEPARATOR_S
|
||||
|
||||
class GamepadUIBasePanel;
|
||||
class GamepadUISizingPanel;
|
||||
class GamepadUIFrame;
|
||||
|
||||
class GamepadUI : public IGamepadUI
|
||||
{
|
||||
public:
|
||||
static GamepadUI& GetInstance();
|
||||
|
||||
void Initialize( CreateInterfaceFn factory ) OVERRIDE;
|
||||
void Shutdown() OVERRIDE;
|
||||
|
||||
void OnUpdate( float flFrametime ) OVERRIDE;
|
||||
void OnLevelInitializePreEntity() OVERRIDE;
|
||||
void OnLevelInitializePostEntity() OVERRIDE;
|
||||
void OnLevelShutdown() OVERRIDE;
|
||||
|
||||
void VidInit() OVERRIDE;
|
||||
|
||||
bool IsInLevel() const;
|
||||
bool IsInBackgroundLevel() const;
|
||||
bool IsInMultiplayer() const;
|
||||
|
||||
bool IsGamepadUIVisible() const;
|
||||
|
||||
vgui::VPANEL GetRootVPanel() const;
|
||||
vgui::Panel *GetBasePanel() const;
|
||||
vgui::VPANEL GetBaseVPanel() const;
|
||||
vgui::Panel *GetSizingPanel() const;
|
||||
vgui::VPANEL GetSizingVPanel() const;
|
||||
vgui::Panel *GetMainMenuPanel() const;
|
||||
vgui::VPANEL GetMainMenuVPanel() const;
|
||||
|
||||
IAchievementMgr *GetAchievementMgr() const { return m_pAchievementMgr; }
|
||||
IEngineSound *GetEngineSound() const { return m_pEngineSound; }
|
||||
IEngineVGui *GetEngineVGui() const { return m_pEngineVGui; }
|
||||
IGameUI *GetGameUI() const { return m_pGameUI; }
|
||||
IGameUIFuncs *GetGameUIFuncs() const { return m_pGameUIFuncs; }
|
||||
IMaterialSystem *GetMaterialSystem() const { return m_pMaterialSystem; }
|
||||
IMatSystemSurface *GetMaterialSystemSurface() const { return m_pMaterialSystemSurface; }
|
||||
ISoundEmitterSystemBase *GetSoundEmitterSystemBase() const { return m_pSoundEmitterSystemBase; }
|
||||
IVEngineClient *GetEngineClient() const { return m_pEngineClient; }
|
||||
IVRenderView *GetRenderView() const { return m_pRenderView; }
|
||||
#ifdef STEAM_INPUT
|
||||
ISource2013SteamInput *GetSteamInput() const { return m_pSteamInput; }
|
||||
#endif
|
||||
|
||||
vgui::AnimationController *GetAnimationController() const { return m_pAnimationController; }
|
||||
float GetTime() const { return Plat_FloatTime(); }
|
||||
GradientHelper *GetGradientHelper() { return &m_GradientHelper; }
|
||||
|
||||
void ResetToMainMenuGradients();
|
||||
|
||||
CSteamAPIContext* GetSteamAPIContext() { return &m_SteamAPIContext; }
|
||||
|
||||
bool GetScreenRatio( float &flX, float &flY ) const { flX = m_flScreenXRatio; flY = m_flScreenYRatio; return (flX != 1.0f || flY != 1.0f); }
|
||||
|
||||
void GetSizingPanelScale( float &flX, float &flY ) const;
|
||||
void GetSizingPanelOffset( int &nX, int &nY ) const;
|
||||
|
||||
GamepadUIFrame *GetCurrentFrame() const;
|
||||
vgui::VPANEL GetCurrentFrameVPanel() const;
|
||||
|
||||
#ifdef MAPBASE
|
||||
void BonusMapChallengeNames( char *pchFileName, char *pchMapName, char *pchChallengeName ) OVERRIDE;
|
||||
void BonusMapChallengeObjectives( int &iBronze, int &iSilver, int &iGold ) OVERRIDE;
|
||||
|
||||
void SetCurrentChallengeObjectives( int iBronze, int iSilver, int iGold );
|
||||
void SetCurrentChallengeNames( const char *pszFileName, const char *pszMapName, const char *pszChallengeName );
|
||||
#endif
|
||||
|
||||
#ifdef STEAM_INPUT
|
||||
// TODO: Replace with proper singleton interface in the future
|
||||
void SetSteamInput( ISource2013SteamInput *pSteamInput ) override { m_pSteamInput = pSteamInput; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
IEngineSound *m_pEngineSound = NULL;
|
||||
IEngineVGui *m_pEngineVGui = NULL;
|
||||
IGameUIFuncs *m_pGameUIFuncs = NULL;
|
||||
IMaterialSystem *m_pMaterialSystem = NULL;
|
||||
IMatSystemSurface *m_pMaterialSystemSurface = NULL;
|
||||
ISoundEmitterSystemBase *m_pSoundEmitterSystemBase = NULL;
|
||||
IVEngineClient *m_pEngineClient = NULL;
|
||||
IVRenderView *m_pRenderView = NULL;
|
||||
|
||||
IGameUI *m_pGameUI = NULL;
|
||||
IAchievementMgr *m_pAchievementMgr = NULL;
|
||||
|
||||
#ifdef STEAM_INPUT
|
||||
ISource2013SteamInput *m_pSteamInput = NULL;
|
||||
#endif
|
||||
|
||||
vgui::AnimationController *m_pAnimationController = NULL;
|
||||
GamepadUIBasePanel *m_pBasePanel = NULL;
|
||||
|
||||
GradientHelper m_GradientHelper;
|
||||
CSteamAPIContext m_SteamAPIContext;
|
||||
|
||||
GamepadUIMainMenu* GetMainMenu() const;
|
||||
|
||||
float m_flScreenXRatio = 1.0f;
|
||||
float m_flScreenYRatio = 1.0f;
|
||||
|
||||
#ifdef MAPBASE
|
||||
char m_szChallengeFileName[MAX_PATH];
|
||||
char m_szChallengeMapName[48];
|
||||
char m_szChallengeName[48];
|
||||
|
||||
int m_iBronze, m_iSilver, m_iGold;
|
||||
#endif
|
||||
|
||||
static GamepadUI *s_pGamepadUI;
|
||||
};
|
||||
|
||||
#endif // GAMEPADUI_INTERFACE_H
|
347
game/gamepadui/gamepadui_mainmenu.cpp
Normal file
347
game/gamepadui/gamepadui_mainmenu.cpp
Normal file
@ -0,0 +1,347 @@
|
||||
#include "gamepadui_interface.h"
|
||||
#include "gamepadui_basepanel.h"
|
||||
#include "gamepadui_mainmenu.h"
|
||||
|
||||
#include "vgui/ISurface.h"
|
||||
#include "vgui/ILocalize.h"
|
||||
#include "vgui/IVGui.h"
|
||||
|
||||
#include "KeyValues.h"
|
||||
#include "filesystem.h"
|
||||
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
#define GAMEPADUI_MAINMENU_SCHEME GAMEPADUI_RESOURCE_FOLDER "schememainmenu.res"
|
||||
#define GAMEPADUI_MAINMENU_FILE GAMEPADUI_RESOURCE_FOLDER "mainmenu.res"
|
||||
|
||||
#ifdef GAMEPADUI_GAME_EZ2
|
||||
ConVar gamepadui_show_ez2_version( "gamepadui_show_ez2_version", "1", FCVAR_NONE, "Show E:Z2 version in menu" );
|
||||
ConVar gamepadui_show_old_ui_button( "gamepadui_show_old_ui_button", "1", FCVAR_NONE, "Show button explaining how to switch to the old UI (Changes may not take effect until changing level)" );
|
||||
#endif
|
||||
|
||||
GamepadUIMainMenu::GamepadUIMainMenu( vgui::Panel* pParent )
|
||||
: BaseClass( pParent, "MainMenu" )
|
||||
{
|
||||
vgui::HScheme hScheme = vgui::scheme()->LoadSchemeFromFileEx( GamepadUI::GetInstance().GetSizingVPanel(), GAMEPADUI_MAINMENU_SCHEME, "SchemeMainMenu" );
|
||||
SetScheme( hScheme );
|
||||
|
||||
KeyValues* pModData = new KeyValues( "ModData" );
|
||||
if ( pModData )
|
||||
{
|
||||
if ( pModData->LoadFromFile( g_pFullFileSystem, "gameinfo.txt" ) )
|
||||
{
|
||||
m_LogoText[ 0 ] = pModData->GetString( "gamepadui_title", pModData->GetString( "title" ) );
|
||||
m_LogoText[ 1 ] = pModData->GetString( "gamepadui_title2", pModData->GetString( "title2" ) );
|
||||
}
|
||||
pModData->deleteThis();
|
||||
}
|
||||
|
||||
LoadMenuButtons();
|
||||
|
||||
SetFooterButtons( FooterButtons::Select, FooterButtons::Select );
|
||||
}
|
||||
|
||||
void GamepadUIMainMenu::UpdateGradients()
|
||||
{
|
||||
const float flTime = GamepadUI::GetInstance().GetTime();
|
||||
GamepadUI::GetInstance().GetGradientHelper()->ResetTargets( flTime );
|
||||
#ifdef GAMEPADUI_GAME_EZ2
|
||||
// E:Z2 reduces the gradient so that the background map can be more easily seen
|
||||
GamepadUI::GetInstance().GetGradientHelper()->SetTargetGradient( GradientSide::Left, { 1.0f, GamepadUI::GetInstance().IsInBackgroundLevel() ? 0.333f : 0.666f }, flTime );
|
||||
#else
|
||||
GamepadUI::GetInstance().GetGradientHelper()->SetTargetGradient( GradientSide::Left, { 1.0f, 0.666f }, flTime );
|
||||
#endif
|
||||
|
||||
// In case a controller is added mid-game
|
||||
SetFooterButtons( FooterButtons::Select, FooterButtons::Select );
|
||||
}
|
||||
|
||||
void GamepadUIMainMenu::LoadMenuButtons()
|
||||
{
|
||||
KeyValues* pDataFile = new KeyValues( "MainMenuScript" );
|
||||
if ( pDataFile )
|
||||
{
|
||||
if ( pDataFile->LoadFromFile( g_pFullFileSystem, GAMEPADUI_MAINMENU_FILE ) )
|
||||
{
|
||||
for ( KeyValues* pData = pDataFile->GetFirstSubKey(); pData != NULL; pData = pData->GetNextKey() )
|
||||
{
|
||||
GamepadUIButton* pButton = new GamepadUIButton(
|
||||
this, this,
|
||||
GAMEPADUI_MAINMENU_SCHEME,
|
||||
pData->GetString( "command" ),
|
||||
pData->GetString( "text", "Sample Text" ),
|
||||
pData->GetString( "description", "" ) );
|
||||
pButton->SetName( pData->GetName() );
|
||||
pButton->SetPriority( V_atoi( pData->GetString( "priority", "0" ) ) );
|
||||
pButton->SetVisible( true );
|
||||
|
||||
const char* pFamily = pData->GetString( "family", "all" );
|
||||
if ( !V_strcmp( pFamily, "ingame" ) || !V_strcmp( pFamily, "all" ) )
|
||||
m_Buttons[ GamepadUIMenuStates::InGame ].AddToTail( pButton );
|
||||
if ( !V_strcmp( pFamily, "mainmenu" ) || !V_strcmp( pFamily, "all" ) )
|
||||
m_Buttons[ GamepadUIMenuStates::MainMenu ].AddToTail( pButton );
|
||||
}
|
||||
}
|
||||
|
||||
pDataFile->deleteThis();
|
||||
}
|
||||
|
||||
#ifdef GAMEPADUI_GAME_EZ2
|
||||
{
|
||||
m_pSwitchToOldUIButton = new GamepadUIButton(
|
||||
this, this,
|
||||
GAMEPADUI_RESOURCE_FOLDER "schememainmenu_olduibutton.res",
|
||||
"cmd gamepadui_opengenerictextdialog #GameUI_SwitchToOldUI_Title #GameUI_SwitchToOldUI_Info 1",
|
||||
"#GameUI_GameMenu_SwitchToOldUI", "" );
|
||||
m_pSwitchToOldUIButton->SetPriority( 0 );
|
||||
m_pSwitchToOldUIButton->SetVisible( true );
|
||||
}
|
||||
#endif
|
||||
|
||||
UpdateButtonVisibility();
|
||||
}
|
||||
|
||||
void GamepadUIMainMenu::ApplySchemeSettings( vgui::IScheme* pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
|
||||
int nParentW, nParentH;
|
||||
GetParent()->GetSize( nParentW, nParentH );
|
||||
SetBounds( 0, 0, nParentW, nParentH );
|
||||
|
||||
const char *pImage = pScheme->GetResourceString( "Logo.Image" );
|
||||
if ( pImage && *pImage )
|
||||
m_LogoImage.SetImage( pImage );
|
||||
m_hLogoFont = pScheme->GetFont( "Logo.Font", true );
|
||||
|
||||
#ifdef GAMEPADUI_GAME_EZ2
|
||||
m_hVersionFont = pScheme->GetFont( "Version.Font", true );
|
||||
|
||||
ConVarRef ez2_version( "ez2_version" );
|
||||
m_strEZ2Version = ez2_version.GetString();
|
||||
#endif
|
||||
}
|
||||
|
||||
void GamepadUIMainMenu::LayoutMainMenu()
|
||||
{
|
||||
int nY = GetCurrentButtonOffset();
|
||||
CUtlVector<GamepadUIButton*>& currentButtons = GetCurrentButtons();
|
||||
for ( GamepadUIButton *pButton : currentButtons )
|
||||
{
|
||||
nY += pButton->GetTall();
|
||||
pButton->SetPos( m_flButtonsOffsetX, GetTall() - nY );
|
||||
nY += m_flButtonSpacing;
|
||||
}
|
||||
|
||||
#ifdef GAMEPADUI_GAME_EZ2
|
||||
if ( m_pSwitchToOldUIButton && m_pSwitchToOldUIButton->IsVisible() )
|
||||
{
|
||||
int nParentW, nParentH;
|
||||
GetParent()->GetSize( nParentW, nParentH );
|
||||
|
||||
m_pSwitchToOldUIButton->SetPos( m_flOldUIButtonOffsetX, nParentH - m_pSwitchToOldUIButton->m_flHeight - m_flOldUIButtonOffsetY );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void GamepadUIMainMenu::PaintLogo()
|
||||
{
|
||||
vgui::surface()->DrawSetTextColor( m_colLogoColor );
|
||||
vgui::surface()->DrawSetTextFont( m_hLogoFont );
|
||||
|
||||
int nMaxLogosW = 0, nTotalLogosH = 0;
|
||||
int nLogoW[ 2 ], nLogoH[ 2 ];
|
||||
for ( int i = 0; i < 2; i++ )
|
||||
{
|
||||
nLogoW[ i ] = 0;
|
||||
nLogoH[ i ] = 0;
|
||||
if ( !m_LogoText[ i ].IsEmpty() )
|
||||
vgui::surface()->GetTextSize( m_hLogoFont, m_LogoText[ i ].String(), nLogoW[ i ], nLogoH[ i ] );
|
||||
nMaxLogosW = Max( nLogoW[ i ], nMaxLogosW );
|
||||
nTotalLogosH += nLogoH[ i ];
|
||||
}
|
||||
|
||||
int nLogoY = GetTall() - ( GetCurrentLogoOffset() + nTotalLogosH );
|
||||
|
||||
if ( m_LogoImage.IsValid() )
|
||||
{
|
||||
int nY1 = nLogoY;
|
||||
int nY2 = nY1 + nLogoH[ 0 ];
|
||||
int nX1 = m_flLogoOffsetX;
|
||||
int nX2 = nX1 + ( nLogoH[ 0 ] * 3 );
|
||||
vgui::surface()->DrawSetColor( Color( 255, 255, 255, 255 ) );
|
||||
vgui::surface()->DrawSetTexture( m_LogoImage );
|
||||
vgui::surface()->DrawTexturedRect( nX1, nY1, nX2, nY2 );
|
||||
vgui::surface()->DrawSetTexture( 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( int i = 1; i >= 0; i-- )
|
||||
{
|
||||
vgui::surface()->DrawSetTextPos( m_flLogoOffsetX, nLogoY );
|
||||
vgui::surface()->DrawPrintText( m_LogoText[ i ].String(), m_LogoText[ i ].Length() );
|
||||
|
||||
nLogoY -= nLogoH[ i ];
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef GAMEPADUI_GAME_EZ2
|
||||
if (gamepadui_show_ez2_version.GetBool() && !m_strEZ2Version.IsEmpty())
|
||||
{
|
||||
int nVersionW, nVersionH;
|
||||
vgui::surface()->GetTextSize( m_hVersionFont, m_strEZ2Version.String(), nVersionW, nVersionH );
|
||||
|
||||
vgui::surface()->DrawSetTextColor( m_colVersionColor );
|
||||
vgui::surface()->DrawSetTextFont( m_hVersionFont );
|
||||
vgui::surface()->DrawSetTextPos( m_flLogoOffsetX + m_flVersionOffsetX + nLogoW[0], nLogoY + (nLogoH[0] * 2) - nVersionH);
|
||||
vgui::surface()->DrawPrintText( m_strEZ2Version.String(), m_strEZ2Version.Length() );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void GamepadUIMainMenu::OnThink()
|
||||
{
|
||||
BaseClass::OnThink();
|
||||
|
||||
LayoutMainMenu();
|
||||
}
|
||||
|
||||
void GamepadUIMainMenu::Paint()
|
||||
{
|
||||
BaseClass::Paint();
|
||||
|
||||
PaintLogo();
|
||||
}
|
||||
|
||||
void GamepadUIMainMenu::OnCommand( char const* pCommand )
|
||||
{
|
||||
if ( StringHasPrefixCaseSensitive( pCommand, "cmd " ) )
|
||||
{
|
||||
const char* pszClientCmd = &pCommand[ 4 ];
|
||||
if ( *pszClientCmd )
|
||||
GamepadUI::GetInstance().GetEngineClient()->ClientCmd_Unrestricted( pszClientCmd );
|
||||
|
||||
// This is a hack to reset bonus challenges in the event that the player disconnected before the map loaded.
|
||||
// We have no known way of detecting that event and differentiating between a bonus level and non-bonus level being loaded,
|
||||
// so for now, we just reset this when the player presses any menu button, as that indicates they are in the menu and no longer loading a bonus level
|
||||
// (note that this does not cover loading a map through other means, like through the console)
|
||||
ConVarRef sv_bonus_challenge( "sv_bonus_challenge" );
|
||||
if (sv_bonus_challenge.GetInt() != 0)
|
||||
{
|
||||
GamepadUI_Log( "Resetting sv_bonus_challenge\n" );
|
||||
sv_bonus_challenge.SetValue( 0 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseClass::OnCommand( pCommand );
|
||||
}
|
||||
}
|
||||
|
||||
void GamepadUIMainMenu::OnSetFocus()
|
||||
{
|
||||
BaseClass::OnSetFocus();
|
||||
OnMenuStateChanged();
|
||||
}
|
||||
|
||||
void GamepadUIMainMenu::OnMenuStateChanged()
|
||||
{
|
||||
UpdateGradients();
|
||||
UpdateButtonVisibility();
|
||||
}
|
||||
|
||||
void GamepadUIMainMenu::UpdateButtonVisibility()
|
||||
{
|
||||
for ( CUtlVector<GamepadUIButton*>& buttons : m_Buttons )
|
||||
{
|
||||
for ( GamepadUIButton* pButton : buttons )
|
||||
{
|
||||
pButton->NavigateFrom();
|
||||
pButton->SetVisible( false );
|
||||
}
|
||||
}
|
||||
|
||||
CUtlVector<GamepadUIButton*>& currentButtons = GetCurrentButtons();
|
||||
currentButtons.Sort( []( GamepadUIButton* const* a, GamepadUIButton* const* b ) -> int
|
||||
{
|
||||
return ( ( *a )->GetPriority() > ( *b )->GetPriority() );
|
||||
});
|
||||
|
||||
for ( int i = 1; i < currentButtons.Count(); i++ )
|
||||
{
|
||||
currentButtons[i]->SetNavDown( currentButtons[i - 1] );
|
||||
currentButtons[i - 1]->SetNavUp( currentButtons[i] );
|
||||
}
|
||||
|
||||
for ( GamepadUIButton* pButton : currentButtons )
|
||||
pButton->SetVisible( true );
|
||||
|
||||
if ( !currentButtons.IsEmpty() )
|
||||
currentButtons[ currentButtons.Count() - 1 ]->NavigateTo();
|
||||
|
||||
#ifdef GAMEPADUI_GAME_EZ2
|
||||
if ( m_pSwitchToOldUIButton )
|
||||
{
|
||||
if ( (!GamepadUI::GetInstance().GetSteamInput() || !GamepadUI::GetInstance().GetSteamInput()->IsSteamRunningOnSteamDeck()) && gamepadui_show_old_ui_button.GetBool() )
|
||||
{
|
||||
m_pSwitchToOldUIButton->SetVisible( true );
|
||||
|
||||
if (!currentButtons.IsEmpty())
|
||||
{
|
||||
currentButtons[ 0 ]->SetNavDown( m_pSwitchToOldUIButton );
|
||||
m_pSwitchToOldUIButton->SetNavUp( currentButtons[0] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pSwitchToOldUIButton->SetVisible( false );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void GamepadUIMainMenu::OnKeyCodeReleased( vgui::KeyCode code )
|
||||
{
|
||||
ButtonCode_t buttonCode = GetBaseButtonCode( code );
|
||||
switch (buttonCode)
|
||||
{
|
||||
#ifdef HL2_RETAIL // Steam input and Steam Controller are not supported in SDK2013 (Madi)
|
||||
case STEAMCONTROLLER_B:
|
||||
#endif
|
||||
|
||||
case KEY_XBUTTON_B:
|
||||
if ( GamepadUI::GetInstance().IsInLevel() )
|
||||
{
|
||||
GamepadUI::GetInstance().GetEngineClient()->ClientCmd_Unrestricted( "gamemenucommand resumegame" );
|
||||
// I tried it and didn't like it.
|
||||
// Oh well.
|
||||
//vgui::surface()->PlaySound( "UI/buttonclickrelease.wav" );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BaseClass::OnKeyCodeReleased( code );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GamepadUIMenuState GamepadUIMainMenu::GetCurrentMenuState() const
|
||||
{
|
||||
if ( GamepadUI::GetInstance().IsInLevel() )
|
||||
return GamepadUIMenuStates::InGame;
|
||||
return GamepadUIMenuStates::MainMenu;
|
||||
}
|
||||
|
||||
CUtlVector<GamepadUIButton*>& GamepadUIMainMenu::GetCurrentButtons()
|
||||
{
|
||||
return m_Buttons[ GetCurrentMenuState() ];
|
||||
}
|
||||
|
||||
float GamepadUIMainMenu::GetCurrentButtonOffset()
|
||||
{
|
||||
return GetCurrentMenuState() == GamepadUIMenuStates::InGame ? m_flButtonsOffsetYInGame : m_flButtonsOffsetYMenu;
|
||||
}
|
||||
|
||||
float GamepadUIMainMenu::GetCurrentLogoOffset()
|
||||
{
|
||||
return GetCurrentMenuState() == GamepadUIMenuStates::InGame ? m_flLogoOffsetYInGame : m_flLogoOffsetYMenu;
|
||||
}
|
88
game/gamepadui/gamepadui_mainmenu.h
Normal file
88
game/gamepadui/gamepadui_mainmenu.h
Normal file
@ -0,0 +1,88 @@
|
||||
#ifndef GAMEPADUI_MAINMENU_H
|
||||
#define GAMEPADUI_MAINMENU_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "gamepadui_frame.h"
|
||||
#include "gamepadui_button.h"
|
||||
#include "gamepadui_image.h"
|
||||
|
||||
namespace GamepadUIMenuStates
|
||||
{
|
||||
enum GamepadUIMenuState
|
||||
{
|
||||
InGame,
|
||||
MainMenu,
|
||||
|
||||
Count
|
||||
};
|
||||
}
|
||||
using GamepadUIMenuState = GamepadUIMenuStates::GamepadUIMenuState;
|
||||
|
||||
class GamepadUIMainMenu : public GamepadUIFrame
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( GamepadUIMainMenu, GamepadUIFrame );
|
||||
|
||||
public:
|
||||
GamepadUIMainMenu( vgui::Panel* pParent );
|
||||
|
||||
void ApplySchemeSettings( vgui::IScheme* pScheme ) OVERRIDE;
|
||||
void OnCommand( char const* pCommand ) OVERRIDE;
|
||||
void OnSetFocus() OVERRIDE;
|
||||
void UpdateGradients() OVERRIDE;
|
||||
|
||||
void OnThink() OVERRIDE;
|
||||
void Paint() OVERRIDE;
|
||||
|
||||
void LoadMenuButtons();
|
||||
void LayoutMainMenu();
|
||||
void PaintLogo();
|
||||
void OnMenuStateChanged();
|
||||
|
||||
void OnKeyCodeReleased( vgui::KeyCode code );
|
||||
|
||||
private:
|
||||
|
||||
void UpdateButtonVisibility();
|
||||
GamepadUIMenuState GetCurrentMenuState() const;
|
||||
CUtlVector<GamepadUIButton*>& GetCurrentButtons();
|
||||
float GetCurrentButtonOffset();
|
||||
float GetCurrentLogoOffset();
|
||||
|
||||
CUtlVector<GamepadUIButton*> m_Buttons[ GamepadUIMenuStates::Count ];
|
||||
|
||||
#ifdef GAMEPADUI_GAME_EZ2
|
||||
GamepadUIButton *m_pSwitchToOldUIButton;
|
||||
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flOldUIButtonOffsetX, "OldUIButton.OffsetX", "48", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flOldUIButtonOffsetY, "OldUIButton.OffsetY", "32", SchemeValueTypes::ProportionalFloat );
|
||||
#endif
|
||||
|
||||
GamepadUIString m_LogoText[ 2 ];
|
||||
GamepadUIImage m_LogoImage;
|
||||
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flButtonSpacing, "Buttons.Space", "0", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flButtonsOffsetX, "Buttons.OffsetX", "0", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flButtonsOffsetYMenu, "Buttons.OffsetY.MainMenu", "0", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flButtonsOffsetYInGame, "Buttons.OffsetY.InGame", "0", SchemeValueTypes::ProportionalFloat );
|
||||
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flLogoOffsetX, "Logo.OffsetX", "0", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flLogoOffsetYMenu, "Logo.OffsetY.MainMenu", "0", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flLogoOffsetYInGame, "Logo.OffsetY.InGame", "0", SchemeValueTypes::ProportionalFloat );
|
||||
|
||||
GAMEPADUI_PANEL_PROPERTY( Color, m_colLogoColor, "Logo", "255 255 255 255", SchemeValueTypes::Color );
|
||||
|
||||
vgui::HFont m_hLogoFont;
|
||||
|
||||
#ifdef GAMEPADUI_GAME_EZ2
|
||||
GAMEPADUI_PANEL_PROPERTY( Color, m_colVersionColor, "Version", "255 128 0 255", SchemeValueTypes::Color );
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flVersionOffsetX, "Version.OffsetX", "16", SchemeValueTypes::ProportionalFloat );
|
||||
|
||||
vgui::HFont m_hVersionFont;
|
||||
|
||||
GamepadUIString m_strEZ2Version;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
547
game/gamepadui/gamepadui_newgame.cpp
Normal file
547
game/gamepadui/gamepadui_newgame.cpp
Normal file
@ -0,0 +1,547 @@
|
||||
#include "gamepadui_interface.h"
|
||||
#include "gamepadui_image.h"
|
||||
#include "gamepadui_util.h"
|
||||
#include "gamepadui_frame.h"
|
||||
#include "gamepadui_scrollbar.h"
|
||||
#include "gamepadui_genericconfirmation.h"
|
||||
|
||||
#include "ienginevgui.h"
|
||||
#include "vgui/ILocalize.h"
|
||||
#include "vgui/ISurface.h"
|
||||
#include "vgui/IVGui.h"
|
||||
|
||||
#include "vgui_controls/ComboBox.h"
|
||||
#include "vgui_controls/ImagePanel.h"
|
||||
#include "vgui_controls/ScrollBar.h"
|
||||
|
||||
#include "KeyValues.h"
|
||||
#include "filesystem.h"
|
||||
|
||||
#include "icommandline.h"
|
||||
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
class GamepadUIChapterButton;
|
||||
struct chapter_t;
|
||||
|
||||
#define GAMEPADUI_CHAPTER_SCHEME GAMEPADUI_RESOURCE_FOLDER "schemechapterbutton.res"
|
||||
|
||||
ConVar gamepadui_newgame_commentary_toggle( "gamepadui_newgame_commentary_toggle", "1", FCVAR_NONE, "Makes the commentary button toggle commentary mode instead of going straight into the game" );
|
||||
|
||||
// Modders should override this if necessary. (Madi)
|
||||
// TODO - merge these into scheme config?
|
||||
bool GameHasCommentary()
|
||||
{
|
||||
#ifdef GAMEPADUI_GAME_EZ2
|
||||
// NOTE: Not all builds have commentary yet, so check for a file in the first map first
|
||||
static bool bHasCommentary = g_pFullFileSystem->FileExists( "maps/ez2_c0_1_commentary.txt" );
|
||||
return bHasCommentary;
|
||||
#else
|
||||
const char *pszGameDir = CommandLine()->ParmValue( "-game", CommandLine()->ParmValue( "-defaultgamedir", "hl2" ) );
|
||||
return !V_strcmp( pszGameDir, "episodic" ) ||
|
||||
!V_strcmp( pszGameDir, "ep2" ) ||
|
||||
!V_strcmp( pszGameDir, "portal" ) ||
|
||||
!V_strcmp( pszGameDir, "lostcoast" );
|
||||
#endif
|
||||
}
|
||||
|
||||
bool GameHasBonusMaps()
|
||||
{
|
||||
const char *pszGameDir = CommandLine()->ParmValue( "-game", CommandLine()->ParmValue( "-defaultgamedir", "hl2" ) );
|
||||
return !V_strcmp( pszGameDir, "portal" );
|
||||
}
|
||||
|
||||
class GamepadUINewGamePanel : public GamepadUIFrame
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( GamepadUINewGamePanel, GamepadUIFrame );
|
||||
|
||||
public:
|
||||
GamepadUINewGamePanel( vgui::Panel *pParent, const char* pPanelName );
|
||||
|
||||
void UpdateGradients();
|
||||
|
||||
void OnThink() OVERRIDE;
|
||||
void ApplySchemeSettings( vgui::IScheme *pScheme ) OVERRIDE;
|
||||
void OnCommand( char const* pCommand ) OVERRIDE;
|
||||
|
||||
MESSAGE_FUNC_HANDLE( OnGamepadUIButtonNavigatedTo, "OnGamepadUIButtonNavigatedTo", button );
|
||||
|
||||
void LayoutChapterButtons();
|
||||
|
||||
void OnMouseWheeled( int delta ) OVERRIDE;
|
||||
|
||||
void StartGame( int nChapter );
|
||||
|
||||
bool InCommentaryMode() const { return m_bCommentaryMode; }
|
||||
|
||||
GamepadUIImage *GetCommentaryThumb( float &flSize, float &flOffsetX, float &flOffsetY )
|
||||
{
|
||||
flSize = m_flCommentaryThumbSize; flOffsetX = m_flCommentaryThumbOffsetX; flOffsetY = m_flCommentaryThumbOffsetY;
|
||||
return &m_CommentaryThumb;
|
||||
}
|
||||
|
||||
private:
|
||||
CUtlVector< GamepadUIChapterButton* > m_pChapterButtons;
|
||||
CUtlVector< chapter_t > m_Chapters;
|
||||
|
||||
GamepadUIScrollState m_ScrollState;
|
||||
|
||||
GamepadUIScrollBar *m_pScrollBar;
|
||||
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_ChapterOffsetX, "Chapters.OffsetX", "0", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_ChapterOffsetY, "Chapters.OffsetY", "0", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_ChapterSpacing, "Chapters.Spacing", "0", SchemeValueTypes::ProportionalFloat );
|
||||
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flCommentaryThumbSize, "Chapters.CommentaryThumb.Size", "64", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flCommentaryThumbOffsetX, "Chapters.CommentaryThumb.OffsetX", "8", SchemeValueTypes::ProportionalFloat );
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flCommentaryThumbOffsetY, "Chapters.CommentaryThumb.OffsetY", "8", SchemeValueTypes::ProportionalFloat );
|
||||
|
||||
bool m_bCommentaryMode = false;
|
||||
GamepadUIImage m_CommentaryThumb;
|
||||
};
|
||||
|
||||
class GamepadUIChapterButton : public GamepadUIButton
|
||||
{
|
||||
public:
|
||||
DECLARE_CLASS_SIMPLE( GamepadUIChapterButton, GamepadUIButton );
|
||||
|
||||
GamepadUIChapterButton( vgui::Panel* pParent, vgui::Panel* pActionSignalTarget, const char* pSchemeFile, const char* pCommand, const char* pText, const char* pDescription, const char *pChapterImage )
|
||||
: BaseClass( pParent, pActionSignalTarget, pSchemeFile, pCommand, pText, pDescription )
|
||||
, m_Image( pChapterImage )
|
||||
{
|
||||
}
|
||||
|
||||
GamepadUIChapterButton( vgui::Panel* pParent, vgui::Panel* pActionSignalTarget, const char* pSchemeFile, const char* pCommand, const wchar* pText, const wchar* pDescription, const char *pChapterImage )
|
||||
: BaseClass( pParent, pActionSignalTarget, pSchemeFile, pCommand, pText, pDescription )
|
||||
, m_Image( pChapterImage )
|
||||
{
|
||||
}
|
||||
|
||||
~GamepadUIChapterButton()
|
||||
{
|
||||
if ( s_pLastNewGameButton == this )
|
||||
s_pLastNewGameButton = NULL;
|
||||
}
|
||||
|
||||
ButtonState GetCurrentButtonState() OVERRIDE
|
||||
{
|
||||
if ( s_pLastNewGameButton == this )
|
||||
return ButtonState::Over;
|
||||
return BaseClass::GetCurrentButtonState();
|
||||
}
|
||||
|
||||
void Paint() OVERRIDE
|
||||
{
|
||||
int x, y, w, t;
|
||||
GetBounds( x, y, w, t );
|
||||
|
||||
PaintButton();
|
||||
|
||||
vgui::surface()->DrawSetColor( Color( 255, 255, 255, 255 ) );
|
||||
vgui::surface()->DrawSetTexture( m_Image );
|
||||
int imgH = ( w * 9 ) / 16;
|
||||
//vgui::surface()->DrawTexturedRect( 0, 0, w, );
|
||||
float offset = m_flTextOffsetYAnimationValue[ButtonStates::Out] - m_flTextOffsetY;
|
||||
vgui::surface()->DrawTexturedSubRect( 0, 0, w, imgH - offset, 0.0f, 0.0f, 1.0f, ( imgH - offset ) / imgH );
|
||||
vgui::surface()->DrawSetTexture( 0 );
|
||||
if ( !IsEnabled() )
|
||||
{
|
||||
vgui::surface()->DrawSetColor( Color( 255, 255, 255, 16 ) );
|
||||
vgui::surface()->DrawFilledRect( 0, 0, w, imgH - offset );
|
||||
}
|
||||
|
||||
if ( GetParent() && gamepadui_newgame_commentary_toggle.GetBool() )
|
||||
{
|
||||
GamepadUINewGamePanel *pPanel = static_cast<GamepadUINewGamePanel*>( GetParent() );
|
||||
if (pPanel && pPanel->InCommentaryMode())
|
||||
{
|
||||
float flSize, flOffsetX, flOffsetY;
|
||||
vgui::surface()->DrawSetColor( Color( 255, 255, 255, 255 ) );
|
||||
vgui::surface()->DrawSetTexture( *pPanel->GetCommentaryThumb( flSize, flOffsetX, flOffsetY ) );
|
||||
vgui::surface()->DrawTexturedRect( flOffsetX, flOffsetY, flOffsetX + flSize, flOffsetY + flSize );
|
||||
vgui::surface()->DrawSetTexture( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
PaintText();
|
||||
}
|
||||
|
||||
void ApplySchemeSettings( vgui::IScheme* pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
|
||||
float flX, flY;
|
||||
if (GamepadUI::GetInstance().GetScreenRatio( flX, flY ))
|
||||
{
|
||||
if (flX != 1.0f)
|
||||
{
|
||||
m_flHeight *= flX;
|
||||
for (int i = 0; i < ButtonStates::Count; i++)
|
||||
m_flHeightAnimationValue[i] *= flX;
|
||||
|
||||
// Also change the text offset
|
||||
m_flTextOffsetY *= flX;
|
||||
for (int i = 0; i < ButtonStates::Count; i++)
|
||||
m_flTextOffsetYAnimationValue[i] *= flX;
|
||||
}
|
||||
|
||||
SetSize( m_flWidth, m_flHeight + m_flExtraHeight );
|
||||
DoAnimations( true );
|
||||
}
|
||||
}
|
||||
|
||||
void NavigateTo() OVERRIDE
|
||||
{
|
||||
BaseClass::NavigateTo();
|
||||
s_pLastNewGameButton = this;
|
||||
}
|
||||
|
||||
static GamepadUIChapterButton* GetLastNewGameButton() { return s_pLastNewGameButton; }
|
||||
|
||||
private:
|
||||
GamepadUIImage m_Image;
|
||||
|
||||
static GamepadUIChapterButton *s_pLastNewGameButton;
|
||||
};
|
||||
|
||||
GamepadUIChapterButton* GamepadUIChapterButton::s_pLastNewGameButton = NULL;
|
||||
|
||||
/* From GameUI: */
|
||||
// TODO: Modders may need to override this. (Madi)
|
||||
static const int MAX_CHAPTERS = 32;
|
||||
|
||||
struct chapter_t
|
||||
{
|
||||
char filename[32];
|
||||
};
|
||||
|
||||
static int __cdecl ChapterSortFunc( const void *elem1, const void *elem2 )
|
||||
{
|
||||
chapter_t *c1 = ( chapter_t * )elem1;
|
||||
chapter_t *c2 = ( chapter_t * )elem2;
|
||||
|
||||
// compare chapter number first
|
||||
static int chapterlen = strlen( "chapter" );
|
||||
if ( atoi( c1->filename + chapterlen ) > atoi( c2->filename + chapterlen ) )
|
||||
return 1;
|
||||
else if ( atoi( c1->filename + chapterlen ) < atoi( c2->filename + chapterlen ) )
|
||||
return -1;
|
||||
|
||||
// compare length second ( longer string show up later in the list, eg. chapter9 before chapter9a )
|
||||
if ( strlen( c1->filename ) > strlen( c2->filename ) )
|
||||
return 1;
|
||||
else if ( strlen( c1->filename ) < strlen( c2->filename ) )
|
||||
return -1;
|
||||
|
||||
// compare strings third
|
||||
return strcmp( c1->filename, c2->filename );
|
||||
}
|
||||
|
||||
static int FindChapters( chapter_t *pChapters )
|
||||
{
|
||||
int chapterIndex = 0;
|
||||
char szFullFileName[MAX_PATH];
|
||||
|
||||
FileFindHandle_t findHandle = FILESYSTEM_INVALID_FIND_HANDLE;
|
||||
const char *fileName = "cfg/chapter*.cfg";
|
||||
fileName = g_pFullFileSystem->FindFirst( fileName, &findHandle );
|
||||
while ( fileName && chapterIndex < MAX_CHAPTERS )
|
||||
{
|
||||
if ( fileName[0] )
|
||||
{
|
||||
// Only load chapter configs from the current mod's cfg dir
|
||||
// or else chapters appear that we don't want!
|
||||
Q_snprintf( szFullFileName, sizeof( szFullFileName ), "cfg/%s", fileName );
|
||||
FileHandle_t f = g_pFullFileSystem->Open( szFullFileName, "rb", "MOD" );
|
||||
if ( f )
|
||||
{
|
||||
// don't load chapter files that are empty, used in the demo
|
||||
if ( g_pFullFileSystem->Size( f ) > 0 )
|
||||
{
|
||||
Q_strncpy( pChapters[chapterIndex].filename, fileName, sizeof( pChapters[chapterIndex].filename ) );
|
||||
++chapterIndex;
|
||||
}
|
||||
g_pFullFileSystem->Close( f );
|
||||
}
|
||||
}
|
||||
fileName = g_pFullFileSystem->FindNext( findHandle );
|
||||
}
|
||||
|
||||
qsort( pChapters, chapterIndex, sizeof( chapter_t ), &ChapterSortFunc );
|
||||
return chapterIndex;
|
||||
}
|
||||
/* End from GameUI */
|
||||
|
||||
static int GetUnlockedChapters()
|
||||
{
|
||||
ConVarRef var( "sv_unlockedchapters" );
|
||||
|
||||
return var.IsValid() ? MAX( var.GetInt(), 1 ) : 1;
|
||||
}
|
||||
|
||||
GamepadUINewGamePanel::GamepadUINewGamePanel( vgui::Panel *pParent, const char* PanelName ) : BaseClass( pParent, PanelName )
|
||||
{
|
||||
vgui::HScheme hScheme = vgui::scheme()->LoadSchemeFromFileEx( GamepadUI::GetInstance().GetSizingVPanel(), GAMEPADUI_DEFAULT_PANEL_SCHEME, "SchemePanel" );
|
||||
SetScheme( hScheme );
|
||||
|
||||
GetFrameTitle() = GamepadUIString( "#GameUI_NewGame" );
|
||||
FooterButtonMask buttons = FooterButtons::Back | FooterButtons::Select;
|
||||
if ( GameHasCommentary() )
|
||||
buttons |= FooterButtons::Commentary;
|
||||
if ( GameHasBonusMaps() )
|
||||
buttons |= FooterButtons::BonusMaps;
|
||||
SetFooterButtons( buttons, FooterButtons::Select );
|
||||
|
||||
Activate();
|
||||
|
||||
chapter_t chapters[MAX_CHAPTERS];
|
||||
int nChapterCount = FindChapters( chapters );
|
||||
|
||||
for ( int i = 0; i < nChapterCount; i++ )
|
||||
{
|
||||
const char *fileName = chapters[i].filename;
|
||||
char chapterID[32] = { 0 };
|
||||
sscanf( fileName, "chapter%s", chapterID );
|
||||
// strip the extension
|
||||
char *ext = V_stristr( chapterID, ".cfg" );
|
||||
if ( ext )
|
||||
{
|
||||
*ext = 0;
|
||||
}
|
||||
const char* pGameDir = COM_GetModDirectory();
|
||||
|
||||
char chapterName[64];
|
||||
Q_snprintf( chapterName, sizeof( chapterName ), "#%s_Chapter%s_Title", pGameDir, chapterID );
|
||||
|
||||
char command[32];
|
||||
Q_snprintf( command, sizeof( command ), "chapter %d", i );
|
||||
|
||||
wchar_t text[32];
|
||||
wchar_t num[32];
|
||||
wchar_t* chapter = g_pVGuiLocalize->Find( "#GameUI_Chapter" );
|
||||
g_pVGuiLocalize->ConvertANSIToUnicode( chapterID, num, sizeof( num ) );
|
||||
_snwprintf( text, ARRAYSIZE( text ), L"%ls %ls", chapter ? chapter : L"CHAPTER", num );
|
||||
|
||||
GamepadUIString strChapterName( chapterName );
|
||||
|
||||
char chapterImage[64];
|
||||
Q_snprintf( chapterImage, sizeof( chapterImage ), "gamepadui/chapter%s.vmt", chapterID );
|
||||
GamepadUIChapterButton *pChapterButton = new GamepadUIChapterButton(
|
||||
this, this,
|
||||
GAMEPADUI_CHAPTER_SCHEME, command,
|
||||
strChapterName.String(), text, chapterImage);
|
||||
pChapterButton->SetEnabled( i < GetUnlockedChapters() );
|
||||
pChapterButton->SetPriority( i );
|
||||
pChapterButton->SetForwardToParent( true );
|
||||
|
||||
m_pChapterButtons.AddToTail( pChapterButton );
|
||||
m_Chapters.AddToTail( chapters[i] );
|
||||
}
|
||||
|
||||
if ( m_pChapterButtons.Count() > 0 )
|
||||
m_pChapterButtons[0]->NavigateTo();
|
||||
|
||||
for ( int i = 1; i < m_pChapterButtons.Count(); i++ )
|
||||
{
|
||||
m_pChapterButtons[i]->SetNavLeft( m_pChapterButtons[i - 1] );
|
||||
m_pChapterButtons[i - 1]->SetNavRight( m_pChapterButtons[i] );
|
||||
}
|
||||
|
||||
m_CommentaryThumb.SetImage( "vgui/hud/icon_commentary" );
|
||||
|
||||
UpdateGradients();
|
||||
|
||||
m_pScrollBar = new GamepadUIScrollBar(
|
||||
this, this,
|
||||
GAMEPADUI_RESOURCE_FOLDER "schemescrollbar.res",
|
||||
NULL, true );
|
||||
}
|
||||
|
||||
void GamepadUINewGamePanel::UpdateGradients()
|
||||
{
|
||||
const float flTime = GamepadUI::GetInstance().GetTime();
|
||||
GamepadUI::GetInstance().GetGradientHelper()->ResetTargets( flTime );
|
||||
GamepadUI::GetInstance().GetGradientHelper()->SetTargetGradient( GradientSide::Up, { 1.0f, 1.0f }, flTime );
|
||||
GamepadUI::GetInstance().GetGradientHelper()->SetTargetGradient( GradientSide::Down, { 1.0f, 0.5f }, flTime );
|
||||
}
|
||||
|
||||
void GamepadUINewGamePanel::OnThink()
|
||||
{
|
||||
BaseClass::OnThink();
|
||||
|
||||
LayoutChapterButtons();
|
||||
}
|
||||
|
||||
void GamepadUINewGamePanel::ApplySchemeSettings( vgui::IScheme* pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
|
||||
float flX, flY;
|
||||
if (GamepadUI::GetInstance().GetScreenRatio( flX, flY ))
|
||||
{
|
||||
m_ChapterOffsetX *= (flX*flX);
|
||||
m_ChapterOffsetX *= (flY*flY);
|
||||
}
|
||||
|
||||
if (m_pChapterButtons.Count() > 0)
|
||||
{
|
||||
m_pScrollBar->InitScrollBar( &m_ScrollState, m_ChapterOffsetX, m_ChapterOffsetY + m_pChapterButtons[0]->GetTall() + m_ChapterSpacing );
|
||||
}
|
||||
}
|
||||
|
||||
void GamepadUINewGamePanel::OnGamepadUIButtonNavigatedTo( vgui::VPANEL button )
|
||||
{
|
||||
GamepadUIButton *pButton = dynamic_cast< GamepadUIButton * >( vgui::ipanel()->GetPanel( button, GetModuleName() ) );
|
||||
if ( pButton )
|
||||
{
|
||||
int nParentW, nParentH;
|
||||
GetParent()->GetSize( nParentW, nParentH );
|
||||
|
||||
int nX, nY;
|
||||
pButton->GetPos( nX, nY );
|
||||
if ( nX + pButton->m_flWidth > nParentW || nX < 0 )
|
||||
{
|
||||
int nTargetX = pButton->GetPriority() * (pButton->m_flWidth + m_ChapterSpacing);
|
||||
|
||||
if ( nX < nParentW / 2 )
|
||||
{
|
||||
nTargetX += nParentW - m_ChapterOffsetX;
|
||||
// Add a bit of spacing to make this more visually appealing :)
|
||||
nTargetX -= m_ChapterSpacing;
|
||||
}
|
||||
else
|
||||
{
|
||||
nTargetX += pButton->m_flWidth;
|
||||
// Add a bit of spacing to make this more visually appealing :)
|
||||
nTargetX += (pButton->m_flWidth / 2) + m_ChapterSpacing;
|
||||
}
|
||||
|
||||
|
||||
m_ScrollState.SetScrollTarget( nTargetX - ( nParentW - m_ChapterOffsetX ), GamepadUI::GetInstance().GetTime() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GamepadUINewGamePanel::LayoutChapterButtons()
|
||||
{
|
||||
int nParentW, nParentH;
|
||||
GetParent()->GetSize( nParentW, nParentH );
|
||||
|
||||
float flScrollClamp = m_ChapterOffsetX;
|
||||
for ( int i = 0; i < m_pChapterButtons.Count(); i++ )
|
||||
{
|
||||
int nSize = ( m_pChapterButtons[0]->GetWide() + m_ChapterSpacing );
|
||||
|
||||
if ( i < m_pChapterButtons.Count() - 2 )
|
||||
flScrollClamp += nSize;
|
||||
}
|
||||
|
||||
m_ScrollState.UpdateScrollBounds( 0.0f, flScrollClamp );
|
||||
|
||||
if (m_pChapterButtons.Count() > 0)
|
||||
{
|
||||
m_pScrollBar->UpdateScrollBounds( 0.0f, flScrollClamp,
|
||||
( m_pChapterButtons[0]->GetWide() + m_ChapterSpacing ) * 2.0f, nParentW - (m_ChapterOffsetX*2.0f) );
|
||||
}
|
||||
|
||||
for ( int i = 0; i < m_pChapterButtons.Count(); i++ )
|
||||
{
|
||||
int size = ( m_pChapterButtons[0]->GetWide() + m_ChapterSpacing );
|
||||
|
||||
m_pChapterButtons[i]->SetPos( m_ChapterOffsetX + i * size - m_ScrollState.GetScrollProgress(), m_ChapterOffsetY );
|
||||
m_pChapterButtons[i]->SetVisible( true );
|
||||
}
|
||||
|
||||
m_ScrollState.UpdateScrolling( 2.0f, GamepadUI::GetInstance().GetTime() );
|
||||
}
|
||||
|
||||
void GamepadUINewGamePanel::OnCommand( char const* pCommand )
|
||||
{
|
||||
if ( !V_strcmp( pCommand, "action_back" ) )
|
||||
{
|
||||
Close();
|
||||
}
|
||||
else if ( !V_strcmp( pCommand, "action_commentary" ) )
|
||||
{
|
||||
GamepadUIChapterButton *pPanel = GamepadUIChapterButton::GetLastNewGameButton();
|
||||
if ( pPanel )
|
||||
{
|
||||
if ( gamepadui_newgame_commentary_toggle.GetBool() )
|
||||
{
|
||||
m_bCommentaryMode = !m_bCommentaryMode;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bCommentaryMode = true;
|
||||
pPanel->DoClick();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( !V_strcmp( pCommand, "action_bonus_maps" ) )
|
||||
{
|
||||
GamepadUI::GetInstance().GetEngineClient()->ClientCmd_Unrestricted( "gamepadui_openbonusmapsdialog\n" );
|
||||
}
|
||||
else if ( StringHasPrefixCaseSensitive( pCommand, "chapter " ) )
|
||||
{
|
||||
const char* pszEngineCommand = pCommand + 8;
|
||||
if ( *pszEngineCommand )
|
||||
StartGame( atoi( pszEngineCommand ) );
|
||||
|
||||
Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseClass::OnCommand( pCommand );
|
||||
}
|
||||
}
|
||||
|
||||
void GamepadUINewGamePanel::OnMouseWheeled( int nDelta )
|
||||
{
|
||||
m_ScrollState.OnMouseWheeled( nDelta * m_ChapterSpacing * 20.0f, GamepadUI::GetInstance().GetTime() );
|
||||
}
|
||||
|
||||
struct MapCommand_t
|
||||
{
|
||||
char szCommand[512];
|
||||
};
|
||||
|
||||
void GamepadUINewGamePanel::StartGame( int nChapter )
|
||||
{
|
||||
MapCommand_t cmd;
|
||||
cmd.szCommand[0] = 0;
|
||||
Q_snprintf( cmd.szCommand, sizeof( cmd.szCommand ), "disconnect\ndeathmatch 0\nprogress_enable\nexec %s\n", m_Chapters[nChapter].filename );
|
||||
|
||||
// Set commentary
|
||||
ConVarRef commentary( "commentary" );
|
||||
commentary.SetValue( m_bCommentaryMode );
|
||||
|
||||
ConVarRef sv_cheats( "sv_cheats" );
|
||||
sv_cheats.SetValue( m_bCommentaryMode );
|
||||
|
||||
// If commentary is on, we go to the explanation dialog ( but not for teaser trailers )
|
||||
if ( m_bCommentaryMode )//&& !m_ChapterPanels[m_iSelectedChapter]->IsTeaserChapter() )
|
||||
{
|
||||
// Check our current state and disconnect us from any multiplayer server we're connected to.
|
||||
// This fixes an exploit where players would click "start" on the commentary dialog to enable
|
||||
// sv_cheats on the client ( via the code above ) and then hit <esc> to get out of the explanation dialog.
|
||||
if ( GamepadUI::GetInstance().IsInMultiplayer() )
|
||||
{
|
||||
GamepadUI::GetInstance().GetEngineClient()->ExecuteClientCmd( "disconnect" );
|
||||
}
|
||||
|
||||
new GamepadUIGenericConfirmationPanel( GamepadUI::GetInstance().GetBasePanel(), "SaveOverwriteConfirmationPanel", "#GameUI_LoadCommentary", "#GAMEUI_Commentary_Console_Explanation",
|
||||
[cmd]()
|
||||
{
|
||||
GamepadUI::GetInstance().GetEngineClient()->ClientCmd_Unrestricted( cmd.szCommand );
|
||||
}, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
GamepadUI::GetInstance().GetEngineClient()->ClientCmd_Unrestricted( cmd.szCommand );
|
||||
}
|
||||
}
|
||||
|
||||
CON_COMMAND( gamepadui_opennewgamedialog, "" )
|
||||
{
|
||||
new GamepadUINewGamePanel( GamepadUI::GetInstance().GetBasePanel(), "" );
|
||||
}
|
2586
game/gamepadui/gamepadui_options.cpp
Normal file
2586
game/gamepadui/gamepadui_options.cpp
Normal file
File diff suppressed because it is too large
Load Diff
191
game/gamepadui/gamepadui_panel.h
Normal file
191
game/gamepadui/gamepadui_panel.h
Normal file
@ -0,0 +1,191 @@
|
||||
#ifndef GAMEPADUI_PANEL_H
|
||||
#define GAMEPADUI_PANEL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "gamepadui_interface.h"
|
||||
#include "vgui_controls/Panel.h"
|
||||
|
||||
// There are a lot of really sucky macros in here
|
||||
// solely because VGUI base class stuff completely
|
||||
// falls apart when you use it with template classes.
|
||||
// - Josh
|
||||
|
||||
#define GAMEPADUI_CONCAT_( x, y ) x ## y
|
||||
#define GAMEPADUI_CONCAT( x, y ) GAMEPADUI_CONCAT_( x, y )
|
||||
|
||||
#define GAMEPADUI_STRINGIFY_( x ) #x
|
||||
#define GAMEPADUI_STRINGIFY( x ) GAMEPADUI_STRINGIFY_( x )
|
||||
|
||||
#define GAMEPADUI_DEFAULT_PANEL_SCHEME GAMEPADUI_RESOURCE_FOLDER "schemepanel.res"
|
||||
|
||||
namespace SchemeValueTypes
|
||||
{
|
||||
enum SchemeValueType
|
||||
{
|
||||
Float,
|
||||
Bool,
|
||||
ProportionalFloat,
|
||||
Color
|
||||
};
|
||||
}
|
||||
using SchemeValueType = SchemeValueTypes::SchemeValueType;
|
||||
|
||||
class SchemeValueMap
|
||||
{
|
||||
public:
|
||||
struct SchemeValue
|
||||
{
|
||||
const char* pszName;
|
||||
const char *pszScriptName;
|
||||
SchemeValueType Type;
|
||||
const char *pszDefaultValue;
|
||||
PANELLOOKUPFUNC pfnFunc;
|
||||
};
|
||||
|
||||
void AddValueToSchemeMap( const char *pszName, const char *pszScriptName, SchemeValueType Type, char const *pszDefaultValue, PANELLOOKUPFUNC pfnFunc)
|
||||
{
|
||||
m_Values.AddToTail( SchemeValue{ pszName, pszScriptName, Type, pszDefaultValue, pfnFunc } );
|
||||
}
|
||||
|
||||
void UpdateSchemeProperties( vgui::Panel* pPanel, vgui::IScheme* pScheme )
|
||||
{
|
||||
for ( SchemeValue& value : m_Values )
|
||||
{
|
||||
const char *pszResourceStr = pScheme->GetResourceString( value.pszScriptName );
|
||||
switch ( value.Type )
|
||||
{
|
||||
case SchemeValueTypes::ProportionalFloat:
|
||||
case SchemeValueTypes::Float:
|
||||
{
|
||||
float flValue = 0.0f;
|
||||
if ( pszResourceStr && *pszResourceStr)
|
||||
flValue = atof( pszResourceStr );
|
||||
else if ( value.pszDefaultValue && *value.pszDefaultValue )
|
||||
flValue = atof( value.pszDefaultValue );
|
||||
if ( value.Type == SchemeValueTypes::ProportionalFloat )
|
||||
flValue = float( vgui::scheme()->GetProportionalScaledValueEx( pPanel->GetScheme(), int( flValue ) ) );
|
||||
|
||||
*static_cast< float* >( value.pfnFunc( pPanel ) ) = flValue;
|
||||
break;
|
||||
}
|
||||
case SchemeValueTypes::Bool:
|
||||
{
|
||||
int iVal = 0;
|
||||
if ( pszResourceStr && *pszResourceStr )
|
||||
iVal = atoi( pszResourceStr );
|
||||
else if ( value.pszDefaultValue && *value.pszDefaultValue )
|
||||
iVal = atoi( value.pszDefaultValue );
|
||||
*static_cast<bool*>( value.pfnFunc( pPanel ) ) = !!iVal;
|
||||
break;
|
||||
|
||||
}
|
||||
case SchemeValueType::Color:
|
||||
{
|
||||
Color cVal = Color( 0, 0, 0, 0 );
|
||||
if ( value.pszDefaultValue && *value.pszDefaultValue )
|
||||
{
|
||||
float r = 0.0f, g = 0.0f, b = 0.0f, a = 0.0f;
|
||||
sscanf( value.pszDefaultValue, "%f %f %f %f", &r, &g, &b, &a );
|
||||
cVal[ 0 ] = (unsigned char) r;
|
||||
cVal[ 1 ] = (unsigned char) g;
|
||||
cVal[ 2 ] = (unsigned char) b;
|
||||
cVal[ 3 ] = (unsigned char) a;
|
||||
}
|
||||
|
||||
cVal = pScheme->GetColor( value.pszScriptName, cVal );
|
||||
*static_cast<Color*>( value.pfnFunc( pPanel ) ) = cVal;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
CUtlVector< SchemeValue > m_Values;
|
||||
};
|
||||
|
||||
|
||||
// Josh: Multi-line macro
|
||||
#define GAMEPADUI_RUN_ANIMATION_COMMAND( name, interpolator ) \
|
||||
if ( GamepadUI::GetInstance().GetAnimationController() ) \
|
||||
GamepadUI::GetInstance().GetAnimationController()->RunAnimationCommand( this, #name , name##AnimationValue[state], 0.0f, name##AnimationDuration, interpolator )
|
||||
|
||||
|
||||
// Josh: Multi-line macro
|
||||
#define GAMEPADUI_PANEL_PROPERTY( type, name, scriptname, defaultvalue, typealias ) \
|
||||
class PanelAnimationVar_##name; \
|
||||
friend class PanelAnimationVar_##name; \
|
||||
static void *GetVar_##name( vgui::Panel *panel ) \
|
||||
{ \
|
||||
return &(( ThisClass *)panel)->name; \
|
||||
} \
|
||||
class PanelAnimationVar_##name \
|
||||
{ \
|
||||
public: \
|
||||
static void InitVar( SchemeValueMap *pMap ) \
|
||||
{ \
|
||||
pMap->AddValueToSchemeMap( #name, scriptname, typealias, defaultvalue, ThisClass::GetVar_##name ); \
|
||||
} \
|
||||
PanelAnimationVar_##name( SchemeValueMap *pMap ) \
|
||||
{ \
|
||||
PanelAnimationVar_##name::InitVar( pMap ); \
|
||||
} \
|
||||
}; \
|
||||
PanelAnimationVar_##name m_##name##_register = { this }; \
|
||||
type name;
|
||||
|
||||
|
||||
// Josh: Multi-line macro
|
||||
#define GAMEPADUI_BUTTON_ANIMATED_PROPERTY( type, name, scriptname, defaultvalue, typealias ) \
|
||||
class PanelAnimationVar_##name; \
|
||||
friend class PanelAnimationVar_##name; \
|
||||
static void *GetVar_##name( vgui::Panel *panel ) \
|
||||
{ \
|
||||
return &(( ThisClass *)panel)->name; \
|
||||
} \
|
||||
static void *GetVar_##name##_Out( vgui::Panel *panel ) \
|
||||
{ \
|
||||
return &(( ThisClass *)panel)->name##AnimationValue[ButtonStates::Out]; \
|
||||
} \
|
||||
static void *GetVar_##name##_Over( vgui::Panel *panel ) \
|
||||
{ \
|
||||
return &(( ThisClass *)panel)->name##AnimationValue[ButtonStates::Over]; \
|
||||
} \
|
||||
static void *GetVar_##name##_Pressed( vgui::Panel *panel ) \
|
||||
{ \
|
||||
return &(( ThisClass *)panel)->name##AnimationValue[ButtonStates::Pressed]; \
|
||||
} \
|
||||
static void *GetVar_##name##_AnimationDuration( vgui::Panel *panel ) \
|
||||
{ \
|
||||
return &(( ThisClass *)panel)->name##AnimationDuration; \
|
||||
} \
|
||||
class PanelAnimationVar_##name \
|
||||
{ \
|
||||
public: \
|
||||
static void InitVar( SchemeValueMap *pMap ) \
|
||||
{ \
|
||||
pMap->AddValueToSchemeMap( #name, scriptname ".Out", typealias, defaultvalue, ThisClass::GetVar_##name ); \
|
||||
pMap->AddValueToSchemeMap( #name, scriptname ".Out", typealias, defaultvalue, ThisClass::GetVar_##name##_Out ); \
|
||||
pMap->AddValueToSchemeMap( #name, scriptname ".Over", typealias, defaultvalue, ThisClass::GetVar_##name##_Over ); \
|
||||
pMap->AddValueToSchemeMap( #name, scriptname ".Pressed", typealias, defaultvalue, ThisClass::GetVar_##name##_Pressed ); \
|
||||
pMap->AddValueToSchemeMap( #name, scriptname ".Animation.Duration", SchemeValueTypes::Float, "0.2", ThisClass::GetVar_##name##_AnimationDuration ); \
|
||||
static bool bAdded = false; \
|
||||
if ( !bAdded ) \
|
||||
{ \
|
||||
bAdded = true; \
|
||||
AddToAnimationMap( #name, #type, #name, defaultvalue, false, ThisClass::GetVar_##name ); \
|
||||
} \
|
||||
} \
|
||||
PanelAnimationVar_##name( SchemeValueMap *pMap ) \
|
||||
{ \
|
||||
PanelAnimationVar_##name::InitVar( pMap ); \
|
||||
} \
|
||||
}; \
|
||||
PanelAnimationVar_##name m_##name##_register = { this }; \
|
||||
type name; \
|
||||
type name##AnimationValue[ButtonStates::Count]; \
|
||||
float name##AnimationDuration;
|
||||
|
||||
#endif // GAMEPADUI_PANEL_H
|
27
game/gamepadui/gamepadui_portal.vpc
Normal file
27
game/gamepadui/gamepadui_portal.vpc
Normal file
@ -0,0 +1,27 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// GAMEPADUI_PORTAL.VPC
|
||||
//
|
||||
// Project Script
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
$Macro SRCDIR "..\.."
|
||||
$Macro GAMENAME "portal"
|
||||
$Macro OUTBINNAME "gamepadui"
|
||||
|
||||
$Include "$SRCDIR\game\gamepadui\gamepadui_base.vpc"
|
||||
|
||||
$Configuration
|
||||
{
|
||||
$Compiler
|
||||
{
|
||||
$PreprocessorDefinitions "$BASE;GAMEPADUI_GAME_PORTAL"
|
||||
}
|
||||
}
|
||||
|
||||
$Project "GamepadUI (Portal)"
|
||||
{
|
||||
$Folder "Source Files"
|
||||
{
|
||||
$File "gamepadui_bonusmaps.cpp"
|
||||
}
|
||||
}
|
1235
game/gamepadui/gamepadui_savegame.cpp
Normal file
1235
game/gamepadui/gamepadui_savegame.cpp
Normal file
File diff suppressed because it is too large
Load Diff
55
game/gamepadui/gamepadui_scroll.h
Normal file
55
game/gamepadui/gamepadui_scroll.h
Normal file
@ -0,0 +1,55 @@
|
||||
#ifndef GAMEPADUI_SCROLL_H
|
||||
#define GAMEPADUI_SCROLL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
class GamepadUIScrollState
|
||||
{
|
||||
public:
|
||||
GamepadUIScrollState()
|
||||
{
|
||||
}
|
||||
|
||||
void UpdateScrollBounds( float flMin, float flMax )
|
||||
{
|
||||
m_flScrollTarget = clamp( m_flScrollTarget, flMin, flMax );
|
||||
}
|
||||
|
||||
void UpdateScrolling( float flScrollSpeed, float flTime )
|
||||
{
|
||||
float flLerpV = Min( ( flTime - m_flScrollLastScrolledTime ) * flScrollSpeed, 1.0f );
|
||||
flLerpV *= 2.0f - flLerpV;
|
||||
m_flScrollProgress = Lerp( flLerpV, m_flScrollLastScrolledValue, m_flScrollTarget );
|
||||
}
|
||||
|
||||
float GetScrollProgress()
|
||||
{
|
||||
return m_flScrollProgress;
|
||||
}
|
||||
|
||||
float GetScrollTarget() const
|
||||
{
|
||||
return m_flScrollTarget;
|
||||
}
|
||||
|
||||
void SetScrollTarget( float flScrollTarget, float flTime )
|
||||
{
|
||||
m_flScrollTarget = flScrollTarget;
|
||||
m_flScrollLastScrolledValue = m_flScrollProgress;
|
||||
m_flScrollLastScrolledTime = flTime;
|
||||
}
|
||||
|
||||
void OnMouseWheeled( int nDelta, float flTime )
|
||||
{
|
||||
SetScrollTarget( GetScrollTarget() - nDelta, flTime );
|
||||
}
|
||||
|
||||
private:
|
||||
float m_flScrollTarget = 0.0f;
|
||||
float m_flScrollProgress = 0.0f;
|
||||
float m_flScrollLastScrolledValue = 0.0f;
|
||||
float m_flScrollLastScrolledTime = 0.0f;
|
||||
};
|
||||
|
||||
#endif // GAMEPADUI_SCROLL_H
|
160
game/gamepadui/gamepadui_scrollbar.cpp
Normal file
160
game/gamepadui/gamepadui_scrollbar.cpp
Normal file
@ -0,0 +1,160 @@
|
||||
#include "gamepadui_scrollbar.h"
|
||||
#include "vgui/IInput.h"
|
||||
|
||||
void GamepadUIScrollBar::ApplySchemeSettings( vgui::IScheme *pScheme )
|
||||
{
|
||||
BaseClass::ApplySchemeSettings( pScheme );
|
||||
|
||||
GetPos( m_nStartX, m_nStartY );
|
||||
|
||||
if (m_bHorizontal)
|
||||
{
|
||||
m_flScrollSize = m_flWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flScrollSize = m_flHeight;
|
||||
}
|
||||
}
|
||||
|
||||
void GamepadUIScrollBar::OnThink()
|
||||
{
|
||||
BaseClass::OnThink();
|
||||
|
||||
if (!m_pScrollState)
|
||||
return;
|
||||
|
||||
if (m_nMouseOffset != -1)
|
||||
{
|
||||
int nMouseX, nMouseY;
|
||||
vgui::input()->GetCursorPos( nMouseX, nMouseY );
|
||||
|
||||
if (m_bHorizontal)
|
||||
{
|
||||
float flRatio = ((float)((nMouseX - m_nStartX) - m_nMouseOffset)) / m_flScrollSize;
|
||||
|
||||
m_pScrollState->SetScrollTarget( flRatio * m_flMax, GamepadUI::GetInstance().GetTime() );
|
||||
}
|
||||
else
|
||||
{
|
||||
float flRatio = ((float)((nMouseY - m_nStartY) - m_nMouseOffset)) / m_flScrollSize;
|
||||
|
||||
m_pScrollState->SetScrollTarget( flRatio * m_flMax, GamepadUI::GetInstance().GetTime() );
|
||||
}
|
||||
}
|
||||
else if (m_flKeyDir != 0)
|
||||
{
|
||||
m_pScrollState->SetScrollTarget( m_pScrollState->GetScrollProgress() + m_flKeyDir, GamepadUI::GetInstance().GetTime() );
|
||||
}
|
||||
|
||||
if (m_flMax > 0.0f)
|
||||
{
|
||||
if (m_bHorizontal)
|
||||
{
|
||||
int nX = m_nStartX + (m_flScrollSize * ((m_pScrollState->GetScrollProgress() - m_flMin) / m_flMax));
|
||||
SetPos( nX, m_nStartY );
|
||||
}
|
||||
else
|
||||
{
|
||||
int nY = m_nStartY + (m_flScrollSize * ((m_pScrollState->GetScrollProgress() - m_flMin) / m_flMax));
|
||||
SetPos( m_nStartX, nY );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GamepadUIScrollBar::InitScrollBar( GamepadUIScrollState *pScrollState, int nX, int nY )
|
||||
{
|
||||
m_pScrollState = pScrollState;
|
||||
|
||||
m_nStartX = nX;
|
||||
m_nStartY = nY;
|
||||
}
|
||||
|
||||
void GamepadUIScrollBar::UpdateScrollBounds( float flMin, float flMax, float flRegionSize, float flScrollSize )
|
||||
{
|
||||
if (flMin == 0.0f && flMax == 0.0f)
|
||||
{
|
||||
SetVisible( false );
|
||||
m_pScrollState = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
SetVisible( true );
|
||||
|
||||
m_flMin = flMin;
|
||||
m_flMax = flMax;
|
||||
m_flRegionSize = flRegionSize;
|
||||
|
||||
if (m_bHorizontal)
|
||||
{
|
||||
m_flWidth = flScrollSize * (m_flRegionSize / (m_flMax + m_flRegionSize));
|
||||
for (int i = 0; i < ButtonStates::Count; i++)
|
||||
m_flWidthAnimationValue[i] = m_flWidth;
|
||||
|
||||
m_flScrollSize = flScrollSize - m_flWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flHeight = flScrollSize * (m_flRegionSize / (m_flMax + m_flRegionSize));
|
||||
for (int i = 0; i < ButtonStates::Count; i++)
|
||||
m_flHeightAnimationValue[i] = m_flHeight;
|
||||
|
||||
m_flScrollSize = flScrollSize - m_flHeight;
|
||||
}
|
||||
}
|
||||
|
||||
void GamepadUIScrollBar::OnMousePressed( vgui::MouseCode code )
|
||||
{
|
||||
BaseClass::OnMousePressed( code );
|
||||
|
||||
int nX, nY;
|
||||
GetPos( nX, nY );
|
||||
|
||||
int nMouseX, nMouseY;
|
||||
vgui::input()->GetCursorPos( nMouseX, nMouseY );
|
||||
|
||||
m_nMouseOffset = (m_bHorizontal ? nMouseX - nX : nMouseY - nY);
|
||||
}
|
||||
|
||||
void GamepadUIScrollBar::OnMouseReleased( vgui::MouseCode code )
|
||||
{
|
||||
BaseClass::OnMouseReleased( code );
|
||||
|
||||
m_nMouseOffset = -1;
|
||||
}
|
||||
|
||||
void GamepadUIScrollBar::OnKeyCodePressed( vgui::KeyCode code )
|
||||
{
|
||||
ButtonCode_t buttonCode = GetBaseButtonCode( code );
|
||||
|
||||
switch ( buttonCode )
|
||||
{
|
||||
case KEY_UP:
|
||||
case KEY_XBUTTON_UP:
|
||||
m_flKeyDir = -m_flScrollSpeed;
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
case KEY_XBUTTON_DOWN:
|
||||
m_flKeyDir = m_flScrollSpeed;
|
||||
break;
|
||||
default:
|
||||
return BaseClass::OnKeyCodePressed( code );
|
||||
}
|
||||
}
|
||||
|
||||
void GamepadUIScrollBar::OnKeyCodeReleased( vgui::KeyCode code )
|
||||
{
|
||||
ButtonCode_t buttonCode = GetBaseButtonCode( code );
|
||||
|
||||
switch ( buttonCode )
|
||||
{
|
||||
case KEY_UP:
|
||||
case KEY_XBUTTON_UP:
|
||||
case KEY_DOWN:
|
||||
case KEY_XBUTTON_DOWN:
|
||||
m_flKeyDir = 0;
|
||||
break;
|
||||
default:
|
||||
return BaseClass::OnKeyCodeReleased( code );
|
||||
}
|
||||
}
|
53
game/gamepadui/gamepadui_scrollbar.h
Normal file
53
game/gamepadui/gamepadui_scrollbar.h
Normal file
@ -0,0 +1,53 @@
|
||||
#ifndef GAMEPADUI_SCROLLBAR_H
|
||||
#define GAMEPADUI_SCROLLBAR_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "gamepadui_button.h"
|
||||
#include "gamepadui_scroll.h"
|
||||
|
||||
class GamepadUIScrollBar : public GamepadUIButton
|
||||
{
|
||||
DECLARE_CLASS_SIMPLE( GamepadUIScrollBar, GamepadUIButton );
|
||||
public:
|
||||
GamepadUIScrollBar( vgui::Panel *pParent, vgui::Panel *pActionSignalTarget, const char *pSchemeFile, GamepadUIScrollState *pScrollState, bool bHorizontal )
|
||||
: BaseClass( pParent, pActionSignalTarget, pSchemeFile, "", "", "" )
|
||||
{
|
||||
m_pScrollState = pScrollState;
|
||||
m_bHorizontal = bHorizontal;
|
||||
|
||||
SetVisible( false );
|
||||
}
|
||||
|
||||
void ApplySchemeSettings( vgui::IScheme *pScheme ) OVERRIDE;
|
||||
void OnThink() OVERRIDE;
|
||||
|
||||
void InitScrollBar( GamepadUIScrollState *pScrollState, int nX, int nY );
|
||||
void UpdateScrollBounds( float flMin, float flMax, float flRegionSize, float flScrollSize );
|
||||
|
||||
void OnMousePressed( vgui::MouseCode code ) OVERRIDE;
|
||||
void OnMouseReleased( vgui::MouseCode code ) OVERRIDE;
|
||||
|
||||
void OnKeyCodePressed( vgui::KeyCode code ) OVERRIDE;
|
||||
void OnKeyCodeReleased( vgui::KeyCode code ) OVERRIDE;
|
||||
|
||||
private:
|
||||
int m_nStartX = 0;
|
||||
int m_nStartY = 0;
|
||||
|
||||
float m_flScrollSize = 0.0f;
|
||||
float m_flRegionSize = 0.0f;
|
||||
float m_flMin = 0;
|
||||
float m_flMax = 0;
|
||||
GamepadUIScrollState *m_pScrollState = NULL;
|
||||
|
||||
int m_nMouseOffset = -1;
|
||||
int m_flKeyDir = 0;
|
||||
|
||||
bool m_bHorizontal = false;
|
||||
|
||||
GAMEPADUI_PANEL_PROPERTY( float, m_flScrollSpeed, "ScrollBar.Speed", "64", SchemeValueTypes::ProportionalFloat );
|
||||
};
|
||||
|
||||
#endif // GAMEPADUI_SCROLLBAR_H
|
114
game/gamepadui/gamepadui_string.h
Normal file
114
game/gamepadui/gamepadui_string.h
Normal file
@ -0,0 +1,114 @@
|
||||
#ifndef GAMEPADUI_STRING_H
|
||||
#define GAMEPADUI_STRING_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "vgui/ILocalize.h"
|
||||
#include "tier1/utlvector.h"
|
||||
|
||||
extern vgui::ILocalize *g_pVGuiLocalize;
|
||||
|
||||
class GamepadUIString
|
||||
{
|
||||
public:
|
||||
GamepadUIString()
|
||||
{
|
||||
}
|
||||
|
||||
GamepadUIString( const char *pszText )
|
||||
{
|
||||
SetText( pszText );
|
||||
}
|
||||
|
||||
GamepadUIString( const wchar_t *pszText )
|
||||
{
|
||||
SetText( pszText );
|
||||
}
|
||||
|
||||
GamepadUIString( const wchar_t *pszText, int nLength )
|
||||
{
|
||||
SetText( pszText, nLength );
|
||||
}
|
||||
|
||||
const wchar_t *String() const
|
||||
{
|
||||
if ( m_ManagedText.Count() )
|
||||
return m_ManagedText.Base();
|
||||
|
||||
return L"";
|
||||
}
|
||||
|
||||
int Length() const
|
||||
{
|
||||
if ( m_ManagedText.Count() )
|
||||
return m_ManagedText.Count() - 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool IsEmpty() const
|
||||
{
|
||||
return Length() == 0;
|
||||
}
|
||||
|
||||
void SetText( const char *pszText )
|
||||
{
|
||||
m_ManagedText.Purge();
|
||||
|
||||
if ( !pszText || !*pszText )
|
||||
return;
|
||||
|
||||
const wchar_t *pszFoundText = g_pVGuiLocalize->Find( pszText );
|
||||
if ( !pszFoundText )
|
||||
{
|
||||
SetRawUTF8( pszText );
|
||||
}
|
||||
else
|
||||
{
|
||||
int nChars = V_wcslen( pszFoundText );
|
||||
SetText( pszFoundText, nChars );
|
||||
}
|
||||
}
|
||||
|
||||
void SetText( const wchar_t *pszText, int nLength )
|
||||
{
|
||||
m_ManagedText.Purge();
|
||||
|
||||
if ( !pszText || !nLength )
|
||||
return;
|
||||
|
||||
m_ManagedText.EnsureCapacity( nLength + 1 );
|
||||
for ( int i = 0; i < nLength; i++ )
|
||||
m_ManagedText.AddToTail( pszText[ i ] );
|
||||
m_ManagedText.AddToTail( L'\0' );
|
||||
}
|
||||
|
||||
void SetText( const wchar_t *pszText )
|
||||
{
|
||||
if ( !pszText )
|
||||
SetText( NULL, 0 );
|
||||
else
|
||||
SetText( pszText, V_wcslen( pszText ) );
|
||||
}
|
||||
|
||||
void SetRawUTF8( const char* pszText )
|
||||
{
|
||||
m_ManagedText.Purge();
|
||||
|
||||
if ( !pszText || !*pszText )
|
||||
return;
|
||||
|
||||
wchar_t szUnicode[ 4096 ];
|
||||
memset( szUnicode, 0, sizeof( wchar_t ) * 4096 );
|
||||
|
||||
V_UTF8ToUnicode( pszText, szUnicode, sizeof( szUnicode ) );
|
||||
int nChars = V_strlen(pszText);
|
||||
if ( nChars > 1 )
|
||||
SetText( szUnicode, nChars - 1 );
|
||||
}
|
||||
private:
|
||||
CCopyableUtlVector< wchar_t > m_ManagedText;
|
||||
};
|
||||
|
||||
#endif // GAMEPADUI_STRING_H
|
106
game/gamepadui/gamepadui_util.cpp
Normal file
106
game/gamepadui/gamepadui_util.cpp
Normal file
@ -0,0 +1,106 @@
|
||||
#include "gamepadui_util.h"
|
||||
#include "gamepadui_interface.h"
|
||||
|
||||
#include "tier0/icommandline.h"
|
||||
#include "tier1/strtools.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
// Josh: Unused, but referenced by imageutils.cpp
|
||||
// SDK2013: not necessary here (Madi)
|
||||
#ifdef HL2_RETAIL
|
||||
class IVEngineClient* engine = NULL;
|
||||
#endif
|
||||
|
||||
// Josh: Copied verbatim from basically every other module
|
||||
// we have on this planet.
|
||||
const char *COM_GetModDirectory()
|
||||
{
|
||||
static char szModDir[ MAX_PATH ] = {};
|
||||
if ( V_strlen( szModDir ) == 0 )
|
||||
{
|
||||
const char *pszGameDir = CommandLine()->ParmValue("-game", CommandLine()->ParmValue( "-defaultgamedir", "hl2" ) );
|
||||
V_strncpy( szModDir, pszGameDir, sizeof(szModDir) );
|
||||
if ( strchr( szModDir, '/' ) || strchr( szModDir, '\\' ) )
|
||||
{
|
||||
V_StripLastDir( szModDir, sizeof(szModDir) );
|
||||
int nDirLen = V_strlen( szModDir );
|
||||
V_strncpy( szModDir, pszGameDir + nDirLen, sizeof(szModDir) - nDirLen );
|
||||
}
|
||||
}
|
||||
|
||||
return szModDir;
|
||||
}
|
||||
|
||||
int DrawPrintWrappedText(vgui::HFont font, int pX, int pY, const wchar_t* pszText, int nLength, int nMaxWidth, bool bDraw)
|
||||
{
|
||||
float x = 0.0f;
|
||||
int extraY = 0;
|
||||
const int nFontTall = vgui::surface()->GetFontTall(font);
|
||||
const wchar_t* wszStrStart = pszText;
|
||||
const wchar_t* wszLastSpace = NULL;
|
||||
const wchar_t* wszEnd = pszText + nLength;
|
||||
|
||||
for (const wchar_t* wsz = pszText; *wsz; wsz++)
|
||||
{
|
||||
wchar_t ch = *wsz;
|
||||
|
||||
if (ch == L' ' || ch == L'\n')
|
||||
wszLastSpace = wsz;
|
||||
|
||||
#if USE_GETKERNEDCHARWIDTH
|
||||
wchar_t chBefore = 0;
|
||||
wchar_t chAfter = 0;
|
||||
if (wsz > pszText)
|
||||
chBefore = wsz[-1];
|
||||
chAfter = wsz[1];
|
||||
float flWide = 0.0f, flabcA = 0.0f;
|
||||
vgui::surface()->GetKernedCharWidth(font, ch, chBefore, chAfter, flWide, flabcA);
|
||||
if (ch == L' ')
|
||||
x = ceil(x);
|
||||
|
||||
surface()->DrawSetTextPos(x + px, y + py);
|
||||
surface()->DrawUnicodeChar(ch);
|
||||
x += floor(flWide + 0.6);
|
||||
#else
|
||||
x += vgui::surface()->GetCharacterWidth(font, ch);
|
||||
#endif
|
||||
|
||||
if (x >= nMaxWidth || ch == L'\n')
|
||||
{
|
||||
const wchar_t* wszNewStart = wszLastSpace ? wszLastSpace : wsz;
|
||||
if ( bDraw )
|
||||
{
|
||||
vgui::surface()->DrawSetTextPos(pX, pY);
|
||||
vgui::surface()->DrawPrintText(wszStrStart, (int)(intp)(wszNewStart - wszStrStart));
|
||||
}
|
||||
wszStrStart = wszNewStart + 1;
|
||||
wsz = wszStrStart;
|
||||
if ( ch == L'\n' )
|
||||
wsz--;
|
||||
x = 0;
|
||||
pY += nFontTall;
|
||||
extraY += nFontTall;
|
||||
}
|
||||
}
|
||||
|
||||
if (wszStrStart != wszEnd && bDraw)
|
||||
{
|
||||
vgui::surface()->DrawSetTextPos(pX, pY);
|
||||
vgui::surface()->DrawPrintText(wszStrStart, (int)(intp)(wszEnd - wszStrStart));
|
||||
}
|
||||
|
||||
return extraY;
|
||||
}
|
||||
|
||||
int NextPowerOfTwo( int v )
|
||||
{
|
||||
v--;
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
return ++v;
|
||||
}
|
15
game/gamepadui/gamepadui_util.h
Normal file
15
game/gamepadui/gamepadui_util.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef GAMEPADUI_UTIL_H
|
||||
#define GAMEPADUI_UTIL_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "vgui/ISurface.h"
|
||||
|
||||
const char *COM_GetModDirectory();
|
||||
|
||||
int DrawPrintWrappedText(vgui::HFont font, int pX, int pY, const wchar_t* pszText, int nLength, int nMaxWidth, bool bDraw);
|
||||
|
||||
int NextPowerOfTwo( int v );
|
||||
|
||||
#endif // GAMEPADUI_UTIL_H
|
47
game/gamepadui/igamepadui.h
Normal file
47
game/gamepadui/igamepadui.h
Normal file
@ -0,0 +1,47 @@
|
||||
#ifndef IGAMEPADUI_H
|
||||
#define IGAMEPADUI_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier1/interface.h"
|
||||
#include "vgui/VGUI.h"
|
||||
#include "mathlib/vector.h"
|
||||
#include "ivrenderview.h"
|
||||
|
||||
class ISource2013SteamInput;
|
||||
|
||||
abstract_class IGamepadUI : public IBaseInterface
|
||||
{
|
||||
public:
|
||||
virtual void Initialize( CreateInterfaceFn factory ) = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
|
||||
virtual void OnUpdate( float flFrametime ) = 0;
|
||||
virtual void OnLevelInitializePreEntity() = 0;
|
||||
virtual void OnLevelInitializePostEntity() = 0;
|
||||
virtual void OnLevelShutdown() = 0;
|
||||
|
||||
virtual void VidInit() = 0;
|
||||
|
||||
#ifdef STEAM_INPUT
|
||||
// TODO: Replace with proper singleton interface in the future
|
||||
virtual void SetSteamInput( ISource2013SteamInput *pSteamInput ) = 0;
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE
|
||||
virtual void BonusMapChallengeNames( char *pchFileName, char *pchMapName, char *pchChallengeName ) = 0;
|
||||
virtual void BonusMapChallengeObjectives( int &iBronze, int &iSilver, int &iGold ) = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define GAMEPADUI_INTERFACE_VERSION "GamepadUI001"
|
||||
|
||||
// Lil easter egg :-)
|
||||
#ifdef GAMEPADUI_GAME_PORTAL
|
||||
#define GamepadUI_Log(...) ConColorMsg( Color( 61, 189, 237, 255 ), "[GamepadUI] " __VA_ARGS__ )
|
||||
#else
|
||||
#define GamepadUI_Log(...) ConColorMsg( Color( 255, 134, 44, 255 ), "[GamepadUI] " __VA_ARGS__ )
|
||||
#endif
|
||||
|
||||
#endif // IGAMEPADUI_H
|
92
game/gamepadui/wscript
Normal file
92
game/gamepadui/wscript
Normal file
@ -0,0 +1,92 @@
|
||||
#! /usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
from waflib import Utils
|
||||
import os
|
||||
import vpc_parser
|
||||
|
||||
top = '.'
|
||||
PROJECT_NAME = 'gamepadui'
|
||||
|
||||
def options(opt):
|
||||
return
|
||||
|
||||
games = {
|
||||
'hl2': ['gamepadui_base.vpc', 'gamepadui_hl2.vpc'],
|
||||
'hl2mp': ['gamepadui_base.vpc', 'gamepadui_hl2.vpc'],
|
||||
'hl1': ['gamepadui_base.vpc', 'gamepadui_hl2.vpc'],
|
||||
'episodic': ['gamepadui_base.vpc', 'gamepadui_episodic.vpc'],
|
||||
'portal': ['gamepadui_base.vpc', 'gamepadui_portal.vpc'],
|
||||
'hl1mp': ['gamepadui_base.vpc', 'gamepadui_hl2.vpc'],
|
||||
'cstrike': ['gamepadui_base.vpc', 'gamepadui_hl2.vpc'],
|
||||
'dod': ['gamepadui_base.vpc', 'gamepadui_hl2.vpc']
|
||||
}
|
||||
|
||||
def configure(conf):
|
||||
game = conf.options.GAMES
|
||||
conf.env.GAMES = game
|
||||
|
||||
conf.env.append_unique('DEFINES', ['DISABLE_STEAM=1'])
|
||||
|
||||
if game not in games.keys():
|
||||
conf.fatal("Couldn't find game: ", game)
|
||||
|
||||
def build(bld):
|
||||
game = vpc_parser.parse_vpcs( bld.env, games[bld.env.GAMES], '../..' )
|
||||
|
||||
includes = [
|
||||
'.',
|
||||
'game_controls',
|
||||
'../../common',
|
||||
'../../public',
|
||||
'../../public/tier0',
|
||||
'../../public/tier1',
|
||||
'../../vgui2/vgui_controls',
|
||||
'../shared',
|
||||
'../game/gamepadui'
|
||||
]
|
||||
|
||||
libs = [
|
||||
'tier0',
|
||||
'particles',
|
||||
'dmxloader',
|
||||
'vgui_controls',
|
||||
'matsys_controls',
|
||||
'tier1',
|
||||
'tier2',
|
||||
'tier3',
|
||||
'mathlib',
|
||||
'vstdlib',
|
||||
'choreoobjects',
|
||||
'steam_api',
|
||||
'bitmap',
|
||||
'vtf',
|
||||
'RT',
|
||||
'ZLIB'
|
||||
]
|
||||
|
||||
install_path = bld.env.PREFIX
|
||||
if bld.env.DEST_OS != 'android':
|
||||
install_path += '/'+bld.env.GAMES+'/bin'
|
||||
|
||||
#source = [ 'in_touch.cpp' ]
|
||||
if bld.env.DEST_OS == 'win32':
|
||||
libs += ['USER32']
|
||||
|
||||
source = game["sources"] + ['../../public/tier0/memoverride.cpp']
|
||||
includes += game["includes"]
|
||||
defines = game["defines"]
|
||||
|
||||
bld.shlib(
|
||||
source = source,
|
||||
target = PROJECT_NAME,
|
||||
name = PROJECT_NAME,
|
||||
features = 'c cxx',
|
||||
includes = includes,
|
||||
defines = defines,
|
||||
use = libs,
|
||||
install_path = install_path,
|
||||
subsystem = bld.env.MSVC_SUBSYSTEM,
|
||||
idx = bld.get_taskgen_count()
|
||||
)
|
||||
|
@ -11,6 +11,13 @@
|
||||
#include "GameUI/IGameUI.h"
|
||||
#include "fmtstr.h"
|
||||
#include "igameevents.h"
|
||||
#ifdef MAPBASE
|
||||
#include "filesystem.h"
|
||||
#include "saverestore.h"
|
||||
#endif
|
||||
#ifdef GAMEPADUI
|
||||
#include "../gamepadui/igamepadui.h"
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
@ -18,6 +25,9 @@
|
||||
// See interface.h/.cpp for specifics: basically this ensures that we actually Sys_UnloadModule the dll and that we don't call Sys_LoadModule
|
||||
// over and over again.
|
||||
static CDllDemandLoader g_GameUI( "GameUI" );
|
||||
#if defined(GAMEPADUI) && defined(CLIENT_DLL)
|
||||
extern IGamepadUI *g_pGamepadUI;
|
||||
#endif
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
|
||||
@ -95,6 +105,14 @@ void CPointBonusMapsAccessor::InputSave( inputdata_t& inputdata )
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE
|
||||
void CustomBMSystem_UpdateChallenges( const char *pchFileName, const char *pchMapName, const char *pchChallengeName, int iBest );
|
||||
|
||||
bool CustomBMSystem_OverridingInterface();
|
||||
void CustomBMSystem_BonusMapChallengeNames( char *pchFileName, char *pchMapName, char *pchChallengeName );
|
||||
void CustomBMSystem_BonusMapChallengeObjectives( int &iBronze, int &iSilver, int &iGold );
|
||||
#endif
|
||||
|
||||
void BonusMapChallengeUpdate( const char *pchFileName, const char *pchMapName, const char *pchChallengeName, int iBest )
|
||||
{
|
||||
CreateInterfaceFn gameUIFactory = g_GameUI.GetFactory();
|
||||
@ -116,12 +134,25 @@ void BonusMapChallengeUpdate( const char *pchFileName, const char *pchMapName, c
|
||||
event->SetInt( "numgold", piNumMedals[ 2 ] );
|
||||
gameeventmanager->FireEvent( event );
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
CustomBMSystem_UpdateChallenges( pchFileName, pchMapName, pchChallengeName, iBest );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BonusMapChallengeNames( char *pchFileName, char *pchMapName, char *pchChallengeName )
|
||||
{
|
||||
#ifdef MAPBASE
|
||||
// This accounts for cases where challenges are "skipped", which causes the data from GameUI to get desynced
|
||||
if (CustomBMSystem_OverridingInterface())
|
||||
{
|
||||
CustomBMSystem_BonusMapChallengeNames( pchFileName, pchMapName, pchChallengeName );
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
CreateInterfaceFn gameUIFactory = g_GameUI.GetFactory();
|
||||
if ( gameUIFactory )
|
||||
{
|
||||
@ -135,6 +166,15 @@ void BonusMapChallengeNames( char *pchFileName, char *pchMapName, char *pchChall
|
||||
|
||||
void BonusMapChallengeObjectives( int &iBronze, int &iSilver, int &iGold )
|
||||
{
|
||||
#ifdef MAPBASE
|
||||
// This accounts for cases where challenges are "skipped", which causes the data from GameUI to get desynced
|
||||
if (CustomBMSystem_OverridingInterface())
|
||||
{
|
||||
CustomBMSystem_BonusMapChallengeObjectives( iBronze, iSilver, iGold );
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
CreateInterfaceFn gameUIFactory = g_GameUI.GetFactory();
|
||||
if ( gameUIFactory )
|
||||
{
|
||||
@ -145,3 +185,823 @@ void BonusMapChallengeObjectives( int &iBronze, int &iSilver, int &iGold )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MAPBASE
|
||||
#ifdef CLIENT_DLL
|
||||
// This is so that the client can access the bonus challenge before it's moved to the player without any complex networking.
|
||||
ConVar sv_bonus_challenge( "sv_bonus_challenge", "0", FCVAR_REPLICATED | FCVAR_HIDDEN );
|
||||
#else
|
||||
extern ConVar sv_bonus_challenge;
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: A wrapper-like system which tries to make up for the bonus maps framework being hardcoded into GameUI.
|
||||
// At the moment, this system mostly involves restoring bonus challenges and allowing them to be used in mods.
|
||||
//
|
||||
// This aims to resolve or work around the following specific issues:
|
||||
//
|
||||
// - A limitation where challenge types cannot go beyond the number of image boxes defined in the .res file.
|
||||
// - Not a complete workaround. They still have to occupy a valid image box, but different types can be used for one image.
|
||||
// - A bug where "skipped" challenge types in a level will cause a desync between the GameUI and the player/cvar's value.
|
||||
// - A bug where challenges with negative scores do not count as completed.
|
||||
// - Negative scores themselves are a workaround for allowing challenges which require the "most of" something rather than the "least of" something,
|
||||
// as the bonus maps framework normally only recognizes the latter.
|
||||
// - May not appear immediately since this fix can be overwritten by GameUI under some circumstances.
|
||||
// - A bug/limitation where challenge information didn't save/restore after restarting the game.
|
||||
//
|
||||
// The system also offers the following enhancements:
|
||||
//
|
||||
// - Two new game events for monitoring challenge progress for maps and challenge types in particular. They're useful
|
||||
// if you want to have achievements (or at least progress monitoring) for specific maps or challenge types, as the
|
||||
// existing events only covered all challenges in the game.
|
||||
// - VScript functions for accessing bonus map and challenge values.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
class CCustomBonusMapSystem : public CAutoGameSystem
|
||||
{
|
||||
public:
|
||||
DECLARE_DATADESC();
|
||||
|
||||
CCustomBonusMapSystem() : CAutoGameSystem( "CCustomBonusMapSystem" )
|
||||
{
|
||||
m_pKV_CurrentBonusData = NULL;
|
||||
m_pKV_SaveData = NULL;
|
||||
m_bUpdatedChallenges = false;
|
||||
}
|
||||
|
||||
virtual bool Init()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void Shutdown()
|
||||
{
|
||||
RefreshSaveAdjustments();
|
||||
}
|
||||
|
||||
virtual void LevelInitPreEntity()
|
||||
{
|
||||
CreateInterfaceFn gameUIFactory = g_GameUI.GetFactory();
|
||||
if ( gameUIFactory )
|
||||
{
|
||||
m_pGameUI = (IGameUI *) gameUIFactory(GAMEUI_INTERFACE_VERSION, NULL );
|
||||
}
|
||||
|
||||
#if defined(GAMEPADUI) && defined(CLIENT_DLL)
|
||||
if (g_pGamepadUI && sv_bonus_challenge.GetInt() != 0)
|
||||
{
|
||||
g_pGamepadUI->BonusMapChallengeNames( m_szChallengeFileName, m_szChallengeMapName, m_szChallengeName );
|
||||
g_pGamepadUI->BonusMapChallengeObjectives( m_iBronze, m_iSilver, m_iGold );
|
||||
LoadBonusDataKV( m_szChallengeFileName );
|
||||
m_bOverridingInterface = true;
|
||||
|
||||
//VerifyChallengeValues( sv_bonus_challenge.GetInt() );
|
||||
|
||||
// Get them onto the server
|
||||
engine->ClientCmd_Unrestricted( VarArgs( "_set_sv_bonus %i \"%s\" \"%s\" \"%s\" %i %i %i\n",
|
||||
sv_bonus_challenge.GetInt(), m_szChallengeFileName, m_szChallengeMapName, m_szChallengeName,
|
||||
m_iBronze, m_iSilver, m_iGold ) );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
// Get the GameUI's values to override its interface (covers cases where GameUI's challenge information has desynced)
|
||||
if (m_pGameUI)
|
||||
{
|
||||
m_pGameUI->BonusMapChallengeNames( m_szChallengeFileName, m_szChallengeMapName, m_szChallengeName );
|
||||
m_pGameUI->BonusMapChallengeObjectives( m_iBronze, m_iSilver, m_iGold );
|
||||
LoadBonusDataKV( m_szChallengeFileName );
|
||||
|
||||
//#ifndef CLIENT_DLL
|
||||
if (sv_bonus_challenge.GetInt() != 0)
|
||||
{
|
||||
VerifyChallengeValues( sv_bonus_challenge.GetInt() );
|
||||
}
|
||||
//#endif
|
||||
}
|
||||
}
|
||||
|
||||
virtual void LevelInitPostEntity()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void LevelShutdownPreEntity()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void LevelShutdownPostEntity()
|
||||
{
|
||||
// Destroy KV
|
||||
if (m_pKV_CurrentBonusData)
|
||||
{
|
||||
m_pKV_CurrentBonusData->deleteThis();
|
||||
m_pKV_CurrentBonusData = NULL;
|
||||
}
|
||||
|
||||
if (m_pKV_SaveData)
|
||||
{
|
||||
m_pKV_SaveData->deleteThis();
|
||||
m_pKV_SaveData = NULL;
|
||||
}
|
||||
|
||||
m_bUpdatedChallenges = false;
|
||||
m_bOverridingInterface = false;
|
||||
|
||||
RefreshSaveAdjustments();
|
||||
}
|
||||
|
||||
virtual void OnRestore()
|
||||
{
|
||||
// No longer necessary due to datadesc and save/restore handler
|
||||
/*
|
||||
#ifdef CLIENT_DLL
|
||||
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
#else
|
||||
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
|
||||
#endif
|
||||
if (pPlayer && pPlayer->GetBonusChallenge() != 0)
|
||||
{
|
||||
if (m_pGameUI)
|
||||
{
|
||||
m_pGameUI->BonusMapChallengeNames( m_szChallengeFileName, m_szChallengeMapName, m_szChallengeName );
|
||||
m_pGameUI->BonusMapChallengeObjectives( m_iBronze, m_iSilver, m_iGold );
|
||||
LoadBonusDataKV( m_szChallengeFileName );
|
||||
|
||||
VerifyChallengeValues( pPlayer->GetBonusChallenge() );
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
void LoadBonusDataKV( const char *pchFileName )
|
||||
{
|
||||
// Destroy KV if we have any
|
||||
if (m_pKV_CurrentBonusData)
|
||||
{
|
||||
m_pKV_CurrentBonusData->deleteThis();
|
||||
m_pKV_CurrentBonusData = NULL;
|
||||
}
|
||||
|
||||
// Reload the database
|
||||
m_pKV_CurrentBonusData = new KeyValues( "CurrentBonusMapData" );
|
||||
m_pKV_CurrentBonusData->LoadFromFile( g_pFullFileSystem, pchFileName, NULL );
|
||||
}
|
||||
|
||||
void LoadSaveDataKV( bool bRefreshData = false )
|
||||
{
|
||||
if (bRefreshData)
|
||||
{
|
||||
// Destroy KV if we have any
|
||||
if (m_pKV_SaveData)
|
||||
{
|
||||
m_pKV_SaveData->deleteThis();
|
||||
m_pKV_SaveData = NULL;
|
||||
}
|
||||
|
||||
// Save the database
|
||||
m_pGameUI->BonusMapDatabaseSave();
|
||||
}
|
||||
else if (m_pKV_SaveData)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Reload the database
|
||||
m_pKV_SaveData = new KeyValues( "SavedBonusMapData" );
|
||||
m_pKV_SaveData->LoadFromFile( g_pFullFileSystem, "save/bonus_maps_data.bmd", "MOD" );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
void UpdateChallenges( const char *pchFileName, const char *pchMapName, const char *pchChallengeName, int iBest )
|
||||
{
|
||||
if ( !m_pGameUI || m_bUpdatedChallenges )
|
||||
return;
|
||||
|
||||
LoadSaveDataKV( true );
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
Msg( "Updating challenges\n" );
|
||||
|
||||
KeyValues *pBonusFiles = m_pKV_SaveData->FindKey( "bonusfiles" );
|
||||
if (!pBonusFiles)
|
||||
{
|
||||
Warning( "Can't find bonus files\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// Can't use FindKey for file paths
|
||||
KeyValues *pFile = NULL;
|
||||
for (KeyValues *key = pBonusFiles->GetFirstSubKey(); key != NULL; key = key->GetNextKey())
|
||||
{
|
||||
if ( !Q_stricmp( key->GetName(), pchFileName ) )
|
||||
{
|
||||
pFile = key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Identify when all bonus challenges on this map are complete
|
||||
if (pFile)
|
||||
{
|
||||
// Since we have saved data, get a list of this map's challenges
|
||||
LoadBonusDataKV( pchFileName );
|
||||
|
||||
CUtlVector<int> iAllScores;
|
||||
|
||||
for (KeyValues *pBDMap = m_pKV_CurrentBonusData; pBDMap != NULL; pBDMap = pBDMap->GetNextKey())
|
||||
{
|
||||
KeyValues *pChallenges = pBDMap->FindKey( "challenges" );
|
||||
if (pChallenges)
|
||||
{
|
||||
KeyValues *pSaveMap = pFile->FindKey( pBDMap->GetName() );
|
||||
if (!pSaveMap)
|
||||
continue;
|
||||
|
||||
KeyValues *pThisChallenge = pChallenges->FindKey( pchChallengeName );
|
||||
if (pThisChallenge)
|
||||
{
|
||||
KeyValues *pSavedChallenge = pSaveMap->FindKey( pchChallengeName );
|
||||
if (!pSavedChallenge)
|
||||
{
|
||||
iAllScores.AddToTail( 0 );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add to progress vector
|
||||
if (pSavedChallenge->GetInt() < pThisChallenge->GetInt( "gold" ))
|
||||
iAllScores.AddToTail( 3 );
|
||||
else if (pSavedChallenge->GetInt() < pThisChallenge->GetInt( "silver" ))
|
||||
iAllScores.AddToTail( 2 );
|
||||
else if (pSavedChallenge->GetInt() < pThisChallenge->GetInt( "bronze" ))
|
||||
iAllScores.AddToTail( 1 );
|
||||
else
|
||||
iAllScores.AddToTail( 0 );
|
||||
}
|
||||
|
||||
// Only do the rest if it's the map we just completed
|
||||
if (!Q_stricmp( pBDMap->GetName(), pchMapName ))
|
||||
{
|
||||
CUtlDict<int> iScores;
|
||||
|
||||
// Compare all challenges to the saved data
|
||||
for (KeyValues *challenge = pChallenges->GetFirstSubKey(); challenge != NULL; challenge = challenge->GetNextKey())
|
||||
{
|
||||
KeyValues *pSavedChallenge = pSaveMap->FindKey( challenge->GetName() );
|
||||
if (!pSavedChallenge)
|
||||
{
|
||||
iScores.Insert( challenge->GetName(), 0 );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add to progress vector
|
||||
if (pSavedChallenge->GetInt() < challenge->GetInt("gold"))
|
||||
iScores.Insert( challenge->GetName(), 3 );
|
||||
else if (pSavedChallenge->GetInt() < challenge->GetInt("silver"))
|
||||
iScores.Insert( challenge->GetName(), 2 );
|
||||
else if (pSavedChallenge->GetInt() < challenge->GetInt("bronze"))
|
||||
iScores.Insert( challenge->GetName(), 1 );
|
||||
else
|
||||
iScores.Insert( challenge->GetName(), 0 );
|
||||
}
|
||||
|
||||
int iNumMedals[3] = { 0, 0, 0 };
|
||||
for (unsigned int i = 0; i < iScores.Count(); i++)
|
||||
{
|
||||
switch (iScores[i])
|
||||
{
|
||||
// These are supposed to fall through into each other
|
||||
case 3: iNumMedals[2]++; // Gold
|
||||
case 2: iNumMedals[1]++; // Silver
|
||||
case 1: iNumMedals[0]++; // Bronze
|
||||
}
|
||||
}
|
||||
|
||||
// Fire an expanded map update event with more map-specific values
|
||||
//
|
||||
// "challenge_map_update"
|
||||
// {
|
||||
// "challenge" "short"
|
||||
// "challengescore" "short"
|
||||
// "challengebest" "short"
|
||||
// "numbronze" "short"
|
||||
// "numsilver" "short"
|
||||
// "numgold" "short"
|
||||
// }
|
||||
//
|
||||
IGameEvent *event = gameeventmanager->CreateEvent( "challenge_map_update", true );
|
||||
if ( event )
|
||||
{
|
||||
|
||||
Msg("CHALLENGE MAP UPDATE:\n Map: %s, Challenge: %s\nChallenge Score: %i\n Ratio Bronze: %f, Ratio Silver: %f, Ratio Gold: %f\n",
|
||||
pchMapName, pchChallengeName, iScores.Find( pchChallengeName ),
|
||||
(float)iNumMedals[0] / (float)iScores.Count(), (float)iNumMedals[1] / (float)iScores.Count(), (float)iNumMedals[2] / (float)iScores.Count() );
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
#else
|
||||
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
|
||||
#endif
|
||||
|
||||
event->SetInt( "challenge", pPlayer ? pPlayer->GetBonusChallenge() : -1 );
|
||||
event->SetInt( "challengescore", iBest );
|
||||
event->SetInt( "challengebest", iScores.Find( pchChallengeName ) );
|
||||
event->SetInt( "numbronze", iNumMedals[0] );
|
||||
event->SetInt( "numsilver", iNumMedals[1] );
|
||||
event->SetInt( "numgold", iNumMedals[2] );
|
||||
#ifdef CLIENT_DLL
|
||||
gameeventmanager->FireEventClientSide( event );
|
||||
#else
|
||||
gameeventmanager->FireEvent( event );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//if (pSaveMap->FindKey( "complete", false ))
|
||||
}
|
||||
|
||||
// Fire an event for the challenge itself
|
||||
//
|
||||
// "challenge_update"
|
||||
// {
|
||||
// "challenge" "short"
|
||||
// "numbronze" "short"
|
||||
// "numsilver" "short"
|
||||
// "numgold" "short"
|
||||
// }
|
||||
//
|
||||
IGameEvent *event = gameeventmanager->CreateEvent( "challenge_update", true );
|
||||
if ( event )
|
||||
{
|
||||
int iNumMedals[3] = { 0, 0, 0 };
|
||||
for (int i = 0; i < iAllScores.Count(); i++)
|
||||
{
|
||||
switch (iAllScores[i])
|
||||
{
|
||||
// These are supposed to fall through into each other
|
||||
case 3: iNumMedals[2]++; // Gold
|
||||
case 2: iNumMedals[1]++; // Silver
|
||||
case 1: iNumMedals[0]++; // Bronze
|
||||
}
|
||||
}
|
||||
|
||||
Msg("CHALLENGE UPDATE:\n Ratio Bronze: %f, Ratio Silver: %f, Ratio Gold: %f\n",
|
||||
(float)iNumMedals[0] / (float)iAllScores.Count(), (float)iNumMedals[1] / (float)iAllScores.Count(), (float)iNumMedals[2] / (float)iAllScores.Count() );
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
#else
|
||||
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
|
||||
#endif
|
||||
|
||||
event->SetInt( "challenge", pPlayer ? pPlayer->GetBonusChallenge() : -1 );
|
||||
event->SetInt( "numbronze", iNumMedals[0] );
|
||||
event->SetInt( "numsilver", iNumMedals[1] );
|
||||
event->SetInt( "numgold", iNumMedals[2] );
|
||||
#ifdef CLIENT_DLL
|
||||
gameeventmanager->FireEventClientSide( event );
|
||||
#else
|
||||
gameeventmanager->FireEvent( event );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
m_bUpdatedChallenges = true;
|
||||
}
|
||||
|
||||
void RefreshSaveAdjustments()
|
||||
{
|
||||
if ( !m_pGameUI )
|
||||
return;
|
||||
|
||||
LoadSaveDataKV( true );
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
KeyValues *pBonusFiles = m_pKV_SaveData->FindKey( "bonusfiles" );
|
||||
if (!pBonusFiles)
|
||||
{
|
||||
Warning( "Can't find bonus files\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
bool bChanged = true;
|
||||
|
||||
// Go through all maps we have save data for
|
||||
for (KeyValues *pFile = pBonusFiles->GetFirstSubKey(); pFile != NULL; pFile = pFile->GetNextKey())
|
||||
{
|
||||
// Get a list of this map's challenges
|
||||
LoadBonusDataKV( pFile->GetName() );
|
||||
|
||||
CUtlVector<int> iAllScores;
|
||||
|
||||
for (KeyValues *pBDMap = m_pKV_CurrentBonusData; pBDMap != NULL; pBDMap = pBDMap->GetNextKey())
|
||||
{
|
||||
KeyValues *pChallenges = pBDMap->FindKey( "challenges" );
|
||||
if (pChallenges)
|
||||
{
|
||||
KeyValues *pSaveMap = pFile->FindKey( pBDMap->GetName() );
|
||||
if (!pSaveMap)
|
||||
continue;
|
||||
|
||||
CUtlDict<int> iScores;
|
||||
|
||||
// Compare all challenges to the saved data
|
||||
for (KeyValues *challenge = pChallenges->GetFirstSubKey(); challenge != NULL; challenge = challenge->GetNextKey())
|
||||
{
|
||||
KeyValues *pSavedChallenge = pSaveMap->FindKey( challenge->GetName() );
|
||||
if (!pSavedChallenge)
|
||||
{
|
||||
iScores.Insert( challenge->GetName(), 0 );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add to progress vector
|
||||
if (pSavedChallenge->GetInt() < challenge->GetInt("gold"))
|
||||
iScores.Insert( challenge->GetName(), 3 );
|
||||
else if (pSavedChallenge->GetInt() < challenge->GetInt("silver"))
|
||||
iScores.Insert( challenge->GetName(), 2 );
|
||||
else if (pSavedChallenge->GetInt() < challenge->GetInt("bronze"))
|
||||
iScores.Insert( challenge->GetName(), 1 );
|
||||
else
|
||||
iScores.Insert( challenge->GetName(), 0 );
|
||||
}
|
||||
|
||||
int iNumMedals[3] = { 0, 0, 0 };
|
||||
for (unsigned int i = 0; i < iScores.Count(); i++)
|
||||
{
|
||||
switch (iScores[i])
|
||||
{
|
||||
// These are supposed to fall through into each other
|
||||
case 3: iNumMedals[2]++; // Gold
|
||||
case 2: iNumMedals[1]++; // Silver
|
||||
case 1: iNumMedals[0]++; // Bronze
|
||||
}
|
||||
}
|
||||
|
||||
// Is the map completed?
|
||||
if (iNumMedals[2] >= (int)iScores.Count())
|
||||
{
|
||||
// Make sure the completion key is there. If it's not, there was a problem with the database code
|
||||
// (This typically happens when the scores are negative)
|
||||
if (pSaveMap && pSaveMap->FindKey( "complete" ) == NULL)
|
||||
{
|
||||
// Create the completion key and save
|
||||
pSaveMap->SetBool( "complete", true );
|
||||
bChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bChanged)
|
||||
m_pKV_SaveData->SaveToFile( g_pFullFileSystem, "save/bonus_maps_data.bmd", "MOD" );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
bool OverridingInterface() { return m_bOverridingInterface; }
|
||||
|
||||
void VerifyChallengeValues( int iTrueChallenge, bool bOverride = false )
|
||||
{
|
||||
// Use sv_bonus_challenge to find this map and challenge in the file
|
||||
for (KeyValues *pBDMap = m_pKV_CurrentBonusData; pBDMap != NULL; pBDMap = pBDMap->GetNextKey())
|
||||
{
|
||||
if (Q_stricmp( pBDMap->GetName(), m_szChallengeMapName ) != 0)
|
||||
continue;
|
||||
|
||||
KeyValues *pChallenges = pBDMap->FindKey( "challenges" );
|
||||
if (pChallenges)
|
||||
{
|
||||
KeyValues *pGameUIChallenge = pChallenges->FindKey( m_szChallengeName );
|
||||
KeyValues *pConVarChallenge = NULL;
|
||||
|
||||
for (KeyValues *challenge = pChallenges->GetFirstSubKey(); challenge != NULL; challenge = challenge->GetNextKey())
|
||||
{
|
||||
if (challenge->GetInt( "type", -1 )+1 == iTrueChallenge)
|
||||
{
|
||||
pConVarChallenge = challenge;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Begin overriding GameUI
|
||||
m_bOverridingInterface = true;
|
||||
|
||||
if ((pGameUIChallenge != pConVarChallenge || bOverride) && pConVarChallenge)
|
||||
{
|
||||
// This indicates there was a desync within GameUI
|
||||
|
||||
//Msg( "****************** OVERRIDING GAME UI BONUS MAP INFO ******************\n%i -> %i --- %s -> %s\n******************************************************\n",
|
||||
// pGameUIChallenge->GetInt( "type" ), iTrueChallenge,
|
||||
// m_szChallengeName, pConVarChallenge->GetName() );
|
||||
|
||||
Msg( "Overriding GameUI bonus map info!!! (%i -> %i) (%s -> %s)\n", pGameUIChallenge->GetInt( "type" ), iTrueChallenge, m_szChallengeName, pConVarChallenge->GetName() );
|
||||
|
||||
Q_strncpy( m_szChallengeName, pConVarChallenge->GetName(), sizeof( m_szChallengeName ) );
|
||||
|
||||
m_iBronze = pConVarChallenge->GetInt( "bronze", 0 );
|
||||
m_iSilver = pConVarChallenge->GetInt( "silver", 0 );
|
||||
m_iGold = pConVarChallenge->GetInt( "gold", 0 );
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetCustomBonusMapChallengeNames( const char *pchFileName, const char *pchMapName, const char *pchChallengeName )
|
||||
{
|
||||
Q_strncpy( m_szChallengeFileName, pchFileName, sizeof( m_szChallengeFileName ) );
|
||||
Q_strncpy( m_szChallengeMapName, pchMapName, sizeof( m_szChallengeMapName ) );
|
||||
Q_strncpy( m_szChallengeName, pchChallengeName, sizeof( m_szChallengeName ) );
|
||||
m_bOverridingInterface = true;
|
||||
}
|
||||
|
||||
void CustomBonusMapChallengeNames( char *pchFileName, char *pchMapName, char *pchChallengeName )
|
||||
{
|
||||
Q_strncpy( pchFileName, m_szChallengeFileName, sizeof( m_szChallengeFileName ) );
|
||||
Q_strncpy( pchMapName, m_szChallengeMapName, sizeof( m_szChallengeMapName ) );
|
||||
Q_strncpy( pchChallengeName, m_szChallengeName, sizeof( m_szChallengeName ) );
|
||||
}
|
||||
|
||||
void SetCustomBonusMapChallengeObjectives( int iBronze, int iSilver, int iGold )
|
||||
{
|
||||
m_iBronze = iBronze; m_iSilver = iSilver; m_iGold = iGold;
|
||||
m_bOverridingInterface = true;
|
||||
}
|
||||
|
||||
void CustomBonusMapChallengeObjectives( int &iBronze, int &iSilver, int &iGold )
|
||||
{
|
||||
iBronze = m_iBronze; iSilver = m_iSilver; iGold = m_iGold;
|
||||
}
|
||||
|
||||
#ifdef GAME_DLL
|
||||
// Allows a challenge to turn into another type in-game, allowing multiple challenges of the same "type" and
|
||||
// getting around issues connected to too many challenge types in the dialog
|
||||
void ResolveCustomBonusChallenge( CBasePlayer *pPlayer )
|
||||
{
|
||||
for (KeyValues *pBDMap = m_pKV_CurrentBonusData; pBDMap != NULL; pBDMap = pBDMap->GetNextKey())
|
||||
{
|
||||
//Msg( "Bonus map data has map %s\n", pBDMap->GetName() );
|
||||
|
||||
// Only do the rest if it's the map we just completed
|
||||
if (!Q_stricmp( pBDMap->GetName(), m_szChallengeMapName ))
|
||||
{
|
||||
KeyValues *pChallenges = pBDMap->FindKey( "challenges" );
|
||||
if (pChallenges)
|
||||
{
|
||||
KeyValues *pThisChallenge = pChallenges->FindKey( m_szChallengeName );
|
||||
if (pThisChallenge)
|
||||
{
|
||||
// Get the hacky "type_game"
|
||||
int iTypeGame = pThisChallenge->GetInt( "type_game", 0 );
|
||||
if (iTypeGame != 0)
|
||||
pPlayer->SetBonusChallenge( iTypeGame );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
virtual void RegisterVScript()
|
||||
{
|
||||
g_pScriptVM->RegisterInstance( this, "BonusMaps" );
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
const char *GetChallengeFileName()
|
||||
{
|
||||
return m_szChallengeFileName;
|
||||
}
|
||||
|
||||
const char *GetChallengeMapName()
|
||||
{
|
||||
return m_szChallengeMapName;
|
||||
}
|
||||
|
||||
const char *GetChallengeName()
|
||||
{
|
||||
return m_szChallengeName;
|
||||
}
|
||||
|
||||
int GetBronze()
|
||||
{
|
||||
return m_iBronze;
|
||||
}
|
||||
|
||||
int GetSilver()
|
||||
{
|
||||
return m_iSilver;
|
||||
}
|
||||
|
||||
int GetGold()
|
||||
{
|
||||
return m_iGold;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
inline bool BonusChallengesActive()
|
||||
{
|
||||
#ifdef CLIENT_DLL
|
||||
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
#else
|
||||
CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
|
||||
#endif
|
||||
if (pPlayer && pPlayer->GetBonusChallenge() != 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return sv_bonus_challenge.GetInt() != 0;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool m_bUpdatedChallenges;
|
||||
|
||||
//-------------------------------------------
|
||||
|
||||
bool m_bOverridingInterface;
|
||||
|
||||
char m_szChallengeFileName[MAX_PATH];
|
||||
char m_szChallengeMapName[48];
|
||||
char m_szChallengeName[48];
|
||||
|
||||
int m_iBronze, m_iSilver, m_iGold;
|
||||
|
||||
//-------------------------------------------
|
||||
|
||||
KeyValues *m_pKV_CurrentBonusData;
|
||||
KeyValues *m_pKV_SaveData;
|
||||
|
||||
IGameUI *m_pGameUI;
|
||||
#ifdef GAMEPADUI
|
||||
IGamepadUI *m_pGamepadUI;
|
||||
#endif
|
||||
};
|
||||
|
||||
CCustomBonusMapSystem g_CustomBonusMapSystem;
|
||||
|
||||
BEGIN_DATADESC_NO_BASE( CCustomBonusMapSystem )
|
||||
DEFINE_FIELD( m_bOverridingInterface, FIELD_BOOLEAN ),
|
||||
|
||||
DEFINE_AUTO_ARRAY( m_szChallengeFileName, FIELD_CHARACTER ),
|
||||
DEFINE_AUTO_ARRAY( m_szChallengeMapName, FIELD_CHARACTER ),
|
||||
DEFINE_AUTO_ARRAY( m_szChallengeName, FIELD_CHARACTER ),
|
||||
|
||||
DEFINE_FIELD( m_iBronze, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( m_iSilver, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( m_iGold, FIELD_INTEGER ),
|
||||
END_DATADESC()
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
BEGIN_SCRIPTDESC_ROOT( CCustomBonusMapSystem, SCRIPT_SINGLETON "A custom bonus map tracking system." )
|
||||
DEFINE_SCRIPTFUNC( OverridingInterface, "Returns true if the custom bonus map system is overriding the GameUI interface." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetChallengeFileName, "Gets the .bns file this bonus map originates from." )
|
||||
DEFINE_SCRIPTFUNC( GetChallengeMapName, "Gets the name of this bonus map from the .bns file. This is the literal name of the bonus map as it appears in the menu, which may be a user-friendly title and/or a localization token." )
|
||||
DEFINE_SCRIPTFUNC( GetChallengeName, "If a challenge is active, this gets its name. This is the literal name of the challenge as it appears in the menu, which may be a user-friendly title and/or a localization token." )
|
||||
|
||||
DEFINE_SCRIPTFUNC( GetBronze, "If a challenge is active, this gets its Bronze goal value." )
|
||||
DEFINE_SCRIPTFUNC( GetSilver, "If a challenge is active, this gets its Silver goal value." )
|
||||
DEFINE_SCRIPTFUNC( GetGold, "If a challenge is active, this gets its Gold goal value." )
|
||||
END_SCRIPTDESC();
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
inline void CustomBMSystem_UpdateChallenges( const char *pchFileName, const char *pchMapName, const char *pchChallengeName, int iBest )
|
||||
{
|
||||
g_CustomBonusMapSystem.UpdateChallenges( pchFileName, pchMapName, pchChallengeName, iBest );
|
||||
}
|
||||
|
||||
inline bool CustomBMSystem_OverridingInterface()
|
||||
{
|
||||
return g_CustomBonusMapSystem.OverridingInterface();
|
||||
}
|
||||
|
||||
inline void CustomBMSystem_BonusMapChallengeNames( char *pchFileName, char *pchMapName, char *pchChallengeName )
|
||||
{
|
||||
g_CustomBonusMapSystem.CustomBonusMapChallengeNames( pchFileName, pchMapName, pchChallengeName );
|
||||
}
|
||||
|
||||
void CustomBMSystem_BonusMapChallengeObjectives( int &iBronze, int &iSilver, int &iGold )
|
||||
{
|
||||
g_CustomBonusMapSystem.CustomBonusMapChallengeObjectives( iBronze, iSilver, iGold );
|
||||
}
|
||||
|
||||
#ifdef GAME_DLL
|
||||
void ResolveCustomBonusChallenge( CBasePlayer *pPlayer )
|
||||
{
|
||||
g_CustomBonusMapSystem.ResolveCustomBonusChallenge( pPlayer );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
void CC_SetSVBonus( const CCommand &args )
|
||||
{
|
||||
sv_bonus_challenge.SetValue( args.Arg( 1 ) );
|
||||
|
||||
// m_szChallengeFileName, m_szChallengeMapName, m_szChallengeName
|
||||
g_CustomBonusMapSystem.SetCustomBonusMapChallengeNames( args.Arg( 2 ), args.Arg( 3 ), args.Arg( 4 ) );
|
||||
g_CustomBonusMapSystem.SetCustomBonusMapChallengeObjectives( atoi( args.Arg( 5 ) ), atoi( args.Arg( 6 ) ), atoi( args.Arg( 7 ) ) );
|
||||
g_CustomBonusMapSystem.LoadBonusDataKV( args.Arg( 2 ) );
|
||||
|
||||
Msg( "Challenge: %s, file name: %s, map name: %s, challenge name: %s\n", args.Arg( 1 ), args.Arg( 2 ), args.Arg( 3 ), args.Arg( 4 ) );
|
||||
|
||||
//g_CustomBonusMapSystem.VerifyChallengeValues( sv_bonus_challenge.GetInt(), true );
|
||||
}
|
||||
static ConCommand _set_sv_bonus("_set_sv_bonus", CC_SetSVBonus, "", FCVAR_HIDDEN);
|
||||
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Custom Bonus System Save/Restore
|
||||
//-----------------------------------------------------------------------------
|
||||
static short CUSTOM_BONUS_SAVE_RESTORE_VERSION = 1;
|
||||
|
||||
class CCustomBonusSaveRestoreBlockHandler : public CDefSaveRestoreBlockHandler
|
||||
{
|
||||
public:
|
||||
const char *GetBlockName()
|
||||
{
|
||||
return "CustomBonusMapSystem";
|
||||
}
|
||||
|
||||
//---------------------------------
|
||||
|
||||
void Save( ISave *pSave )
|
||||
{
|
||||
// We only use this to save challenge info at the moment
|
||||
bool bDoSave = g_CustomBonusMapSystem.BonusChallengesActive();
|
||||
|
||||
pSave->WriteBool( &bDoSave );
|
||||
if ( bDoSave )
|
||||
{
|
||||
pSave->WriteAll( &g_CustomBonusMapSystem, g_CustomBonusMapSystem.GetDataDescMap() );
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------
|
||||
|
||||
void WriteSaveHeaders( ISave *pSave )
|
||||
{
|
||||
pSave->WriteShort( &CUSTOM_BONUS_SAVE_RESTORE_VERSION );
|
||||
}
|
||||
|
||||
//---------------------------------
|
||||
|
||||
void ReadRestoreHeaders( IRestore *pRestore )
|
||||
{
|
||||
// No reason why any future version shouldn't try to retain backward compatability. The default here is to not do so.
|
||||
short version;
|
||||
pRestore->ReadShort( &version );
|
||||
m_fDoLoad = ( version == CUSTOM_BONUS_SAVE_RESTORE_VERSION );
|
||||
}
|
||||
|
||||
//---------------------------------
|
||||
|
||||
void Restore( IRestore *pRestore, bool createPlayers )
|
||||
{
|
||||
if ( m_fDoLoad )
|
||||
{
|
||||
bool bDoRestore = false;
|
||||
|
||||
pRestore->ReadBool( &bDoRestore );
|
||||
if ( bDoRestore )
|
||||
{
|
||||
pRestore->ReadAll( &g_CustomBonusMapSystem, g_CustomBonusMapSystem.GetDataDescMap() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_fDoLoad;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CCustomBonusSaveRestoreBlockHandler g_CustomBonusSaveRestoreBlockHandler;
|
||||
|
||||
//-------------------------------------
|
||||
|
||||
ISaveRestoreBlockHandler *GetCustomBonusSaveRestoreBlockHandler()
|
||||
{
|
||||
return &g_CustomBonusSaveRestoreBlockHandler;
|
||||
}
|
||||
#endif
|
||||
|
@ -87,6 +87,9 @@ using namespace vgui;
|
||||
#include "tier1/utlstring.h"
|
||||
#include "steam/steam_api.h"
|
||||
|
||||
#include "materialsystem/imaterial.h"
|
||||
#include "tier2/renderutils.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <SDL_misc.h>
|
||||
#endif
|
||||
@ -732,10 +735,10 @@ public:
|
||||
|
||||
MESSAGE_FUNC_HANDLE( OnCursorEnteredMenuItem, "CursorEnteredMenuItem", menuItem);
|
||||
|
||||
vgui::VPANEL m_hMainMenuOverridePanel;
|
||||
private:
|
||||
CFooterPanel *m_pConsoleFooter;
|
||||
vgui::CKeyRepeatHandler m_KeyRepeat;
|
||||
vgui::VPANEL m_hMainMenuOverridePanel;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -811,6 +814,8 @@ CBasePanel::CBasePanel() : Panel(NULL, "BaseGameUIPanel")
|
||||
m_iBackgroundImageID = -1;
|
||||
m_iProductImageID = -1;
|
||||
m_iLoadingImageID = -1;
|
||||
m_iLoadingSpinnerImageID = -1;
|
||||
m_fLoadingSpinnerFrame = 0;
|
||||
|
||||
if ( GameUI().IsConsoleUI() )
|
||||
{
|
||||
@ -833,8 +838,11 @@ CBasePanel::CBasePanel() : Panel(NULL, "BaseGameUIPanel")
|
||||
#endif
|
||||
}
|
||||
|
||||
m_pGameMenuButtons.AddToTail( CreateMenuButton( this, "GameMenuButton", ModInfo().GetGameTitle() ) );
|
||||
m_pGameMenuButtons.AddToTail( CreateMenuButton( this, "GameMenuButton2", ModInfo().GetGameTitle2() ) );
|
||||
if (!IsGamepadUI())
|
||||
{
|
||||
m_pGameMenuButtons.AddToTail(CreateMenuButton(this, "GameMenuButton", ModInfo().GetGameTitle()));
|
||||
m_pGameMenuButtons.AddToTail(CreateMenuButton(this, "GameMenuButton2", ModInfo().GetGameTitle2()));
|
||||
}
|
||||
#ifdef CS_BETA
|
||||
if ( !ModInfo().NoCrosshair() ) // hack to not show the BETA for HL2 or HL1Port
|
||||
{
|
||||
@ -979,6 +987,12 @@ CBasePanel::~CBasePanel()
|
||||
vgui::surface()->DestroyTextureID( m_iLoadingImageID );
|
||||
m_iLoadingImageID = -1;
|
||||
}
|
||||
|
||||
if (m_iLoadingSpinnerImageID != -1 )
|
||||
{
|
||||
vgui::surface()->DestroyTextureID(m_iLoadingSpinnerImageID);
|
||||
m_iLoadingSpinnerImageID = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1301,7 +1315,14 @@ void CBasePanel::SetBackgroundRenderState(EBackgroundState state)
|
||||
// fade background into main menu
|
||||
m_bRenderingBackgroundTransition = true;
|
||||
m_flTransitionStartTime = frametime;
|
||||
m_flTransitionEndTime = frametime + 3.0f;
|
||||
if (IsGamepadUI())
|
||||
{
|
||||
m_flTransitionEndTime = frametime + 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_flTransitionEndTime = frametime + 3.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( state == BACKGROUND_LOADING )
|
||||
@ -1362,6 +1383,12 @@ void CBasePanel::OnLevelLoadingStarted()
|
||||
{
|
||||
m_bLevelLoading = true;
|
||||
|
||||
ConVarRef("cl_gamepadui_mainmenu_draw").SetValue(false);
|
||||
|
||||
//Msg("%d\n", GameUI().IsLoading());
|
||||
//GameUI().SetLoadingState(m_bLevelLoading);
|
||||
//Msg("%d\n", GameUI().IsLoading());
|
||||
|
||||
m_pGameMenu->ShowFooter( false );
|
||||
|
||||
if ( m_hMatchmakingBasePanel.Get() )
|
||||
@ -1384,6 +1411,8 @@ void CBasePanel::OnLevelLoadingFinished()
|
||||
{
|
||||
m_bLevelLoading = false;
|
||||
|
||||
ConVarRef("cl_gamepadui_mainmenu_draw").SetValue(true);
|
||||
|
||||
if ( m_hMatchmakingBasePanel.Get() )
|
||||
{
|
||||
m_hMatchmakingBasePanel->OnCommand( "LevelLoadingFinished" );
|
||||
@ -1475,7 +1504,29 @@ void CBasePanel::DrawBackgroundImage()
|
||||
surface()->DrawSetTexture(m_iLoadingImageID);
|
||||
int twide, ttall;
|
||||
surface()->DrawGetTextureSize(m_iLoadingImageID, twide, ttall);
|
||||
surface()->DrawTexturedRect(wide - twide, tall - ttall, wide, tall);
|
||||
if (IsGamepadUI())
|
||||
{
|
||||
surface()->DrawTexturedRect(wide - ((twide / 512.f) * twide) - 30, 30, wide - 30, (ttall / 512.f) * ttall + 30);
|
||||
|
||||
static unsigned int nFrameCache = 0;
|
||||
surface()->DrawGetTextureSize(m_iLoadingSpinnerImageID, twide, ttall); //now use twide and ttall for spinner
|
||||
IScheme* pScheme = vgui::scheme()->GetIScheme(vgui::scheme()->GetScheme("Scheme"));
|
||||
surface()->DrawSetColor(pScheme->GetColor("SteamDeckSpinner", { 201, 100, 0, alpha }));
|
||||
surface()->DrawSetTextureFrame(m_iLoadingSpinnerImageID, ((int)m_fLoadingSpinnerFrame) % surface()->GetTextureNumFrames(m_iLoadingSpinnerImageID), &nFrameCache);
|
||||
surface()->DrawSetTexture(m_iLoadingSpinnerImageID);
|
||||
|
||||
surface()->DrawTexturedRect(wide - ((twide / 512.f)* twide) - 30, 30, wide - 30, (ttall / 512.f) * ttall + 30);
|
||||
|
||||
static float SpinnerTimeDelta = 0;
|
||||
static float SpinnerTime = 0;
|
||||
SpinnerTimeDelta = engine->Time() - SpinnerTime;
|
||||
m_fLoadingSpinnerFrame += SpinnerTimeDelta * 100;
|
||||
SpinnerTime = engine->Time();
|
||||
}
|
||||
else
|
||||
{
|
||||
surface()->DrawTexturedRect(wide - twide, tall - ttall, wide, tall);
|
||||
}
|
||||
}
|
||||
|
||||
// update the menu alpha
|
||||
@ -1802,6 +1853,7 @@ void CBasePanel::PerformLayout()
|
||||
//-----------------------------------------------------------------------------
|
||||
void CBasePanel::ApplySchemeSettings(IScheme *pScheme)
|
||||
{
|
||||
|
||||
int i;
|
||||
BaseClass::ApplySchemeSettings(pScheme);
|
||||
|
||||
@ -1864,7 +1916,7 @@ void CBasePanel::ApplySchemeSettings(IScheme *pScheme)
|
||||
SetBgColor(Color(0, 0, 0, 0));
|
||||
|
||||
m_BackdropColor = pScheme->GetColor("mainmenu.backdrop", Color(0, 0, 0, 128));
|
||||
|
||||
|
||||
char filename[MAX_PATH];
|
||||
if ( IsX360() )
|
||||
{
|
||||
@ -1902,6 +1954,7 @@ void CBasePanel::ApplySchemeSettings(IScheme *pScheme)
|
||||
{
|
||||
m_iBackgroundImageID = surface()->CreateNewTextureID();
|
||||
}
|
||||
|
||||
surface()->DrawSetTextureFile( m_iBackgroundImageID, filename, false, false );
|
||||
|
||||
if ( IsX360() )
|
||||
@ -1915,19 +1968,40 @@ void CBasePanel::ApplySchemeSettings(IScheme *pScheme)
|
||||
}
|
||||
surface()->DrawSetTextureFile( m_iProductImageID, filename, false, false );
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ( IsPC() )
|
||||
{
|
||||
// load the loading icon
|
||||
if ( m_iLoadingImageID == -1 )
|
||||
{
|
||||
const char* loading = "console/startup_loading";
|
||||
if ( IsSteamDeck() )
|
||||
loading = "gamepadui/game_logo";
|
||||
m_iLoadingImageID = surface()->CreateNewTextureID();
|
||||
surface()->DrawSetTextureFile( m_iLoadingImageID, loading, false, false );
|
||||
if (IsGamepadUI())
|
||||
{
|
||||
const char* loading = "gamepadui/game_logo.vtf";
|
||||
m_iLoadingImageID = surface()->CreateNewTextureID();
|
||||
surface()->DrawSetTextureFile(m_iLoadingImageID, loading, true, false);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* loading = "console/startup_loading";
|
||||
m_iLoadingImageID = surface()->CreateNewTextureID();
|
||||
surface()->DrawSetTextureFile(m_iLoadingImageID, loading, false, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (IsGamepadUI())
|
||||
{
|
||||
if (m_iLoadingSpinnerImageID == -1)
|
||||
{
|
||||
const char* loadingCircle = "gamepadui/spinner";
|
||||
m_iLoadingSpinnerImageID = surface()->CreateNewTextureID();
|
||||
surface()->DrawSetTextureFile(m_iLoadingSpinnerImageID, loadingCircle, true, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -399,6 +399,7 @@ private:
|
||||
int m_iBackgroundImageID;
|
||||
int m_iRenderTargetImageID;
|
||||
int m_iLoadingImageID;
|
||||
int m_iLoadingSpinnerImageID; float m_fLoadingSpinnerFrame;
|
||||
int m_iProductImageID;
|
||||
bool m_bLevelLoading;
|
||||
bool m_bEverActivated;
|
||||
|
@ -428,7 +428,7 @@ inline bool KeyValues::IsEmpty( int keySymbol )
|
||||
return dat ? dat->IsEmpty( ) : true;
|
||||
}
|
||||
|
||||
bool IsSteamDeck();
|
||||
bool IsGamepadUI();
|
||||
|
||||
bool EvaluateConditional( const char *str );
|
||||
|
||||
|
@ -2179,32 +2179,28 @@ void KeyValues::RecursiveMergeKeyValues( KeyValues *baseKV )
|
||||
}
|
||||
}
|
||||
|
||||
static int s_nSteamDeckCached = -1;
|
||||
|
||||
bool IsSteamDeck()
|
||||
//Gamepadui
|
||||
bool IsGamepadUI()
|
||||
{
|
||||
if (s_nSteamDeckCached == -1) {
|
||||
if ( CommandLine()->CheckParm( "-nogamepadui" ) != 0 )
|
||||
{
|
||||
s_nSteamDeckCached = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( CommandLine()->CheckParm( "-gamepadui" ) != 0 )
|
||||
{
|
||||
s_nSteamDeckCached = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *deck = getenv("SteamDeck");
|
||||
if ( deck == 0 || *deck == 0 )
|
||||
s_nSteamDeckCached = 0;
|
||||
else
|
||||
s_nSteamDeckCached = atoi(deck) != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return s_nSteamDeckCached;
|
||||
//we dont want to use shader editor AND gamepadui at the same time
|
||||
if (CommandLine()->FindParm("-shaderedit"))
|
||||
return false;
|
||||
|
||||
//we dont want tools AND gamepadui at the same time
|
||||
if (CommandLine()->FindParm("-tools"))
|
||||
return false;
|
||||
|
||||
if (CommandLine()->FindParm("-nogamepadui"))
|
||||
return false;
|
||||
|
||||
if (CommandLine()->FindParm("-gamepadui"))
|
||||
return true;
|
||||
|
||||
const char* pszSteamDeckEnv = getenv("SteamDeck");
|
||||
if (pszSteamDeckEnv && *pszSteamDeckEnv)
|
||||
return atoi(pszSteamDeckEnv) != 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -2224,7 +2220,7 @@ bool EvaluateConditional( const char *str )
|
||||
bNot = true;
|
||||
|
||||
if ( Q_stristr( str, "$DECK" ) )
|
||||
return IsSteamDeck() ^ bNot;
|
||||
return IsGamepadUI() ^ bNot;
|
||||
|
||||
if ( Q_stristr( str, "$X360" ) )
|
||||
return IsX360() ^ bNot;
|
||||
|
Loading…
x
Reference in New Issue
Block a user