Get VGUI back (optionally) (#194)

* Get VGUI back (optionally)

* Add some missing VGUI invocations

* Update CMakeLists.txt to build with vgui for Windows

* Move windows.h inclusions only to those places where it's really needed

* Try fix mingw build

* Update hud_spectator

* Merge nekonomicon's vgui branch

* Don't include vgui panel and app in cdll_int.cpp if vgui is real

* Deduplicate scoreboard global variables

* Add options to prefer non-vgui motd and scoreboard when vgui is enabled

* Add vgui-dev as a submodule. Add building vith vgui to CI

* Fix artifact uploading

* Don't use global variable when not necessary

* char* to const char* in CMenuHandler_StringCommand constructor

* Fix 'format string is not a literal string' warnings

* Fix 'always evaluate to true' warnings

* Team Fortress classes to const char*

* CreateCommandMenu accepts const char*

* Fix printf formats. Turn some unsigned longs into unsigned ints since they use only 32 bits anyway

* Explicit assignment result as condition

* Prevent memory leak on menu reading

* Localize button text

* Create FileInputStream on stack avoiding the leak

* Remove Servers Browser code

* Arrow file names to const char*

* Fix assignment to the wrong variable
This commit is contained in:
Roman Chistokhodov 2021-10-27 04:35:11 +03:00 committed by GitHub
parent 302e2d7a2a
commit ba2cab60df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
73 changed files with 12239 additions and 2762 deletions

View File

@ -23,6 +23,8 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v2
with:
submodules: true
- name: Checkout steam-runtime
if: startsWith(matrix.os, 'ubuntu')
@ -58,6 +60,13 @@ jobs:
schroot --chroot steamrt_scout_i386 -- cmake -B build -S . -DCMAKE_EXE_LINKER_FLAGS="-Wl,--no-undefined" -DGOLDSOURCE_SUPPORT=ON -DCMAKE_INSTALL_PREFIX="$PWD/dist"
schroot --chroot steamrt_scout_i386 -- cmake --build build --target all
schroot --chroot steamrt_scout_i386 -- cmake --build build --target install
- name: Build with goldsource input and vgui
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.cc, 'gcc')
run: |
schroot --chroot steamrt_scout_i386 -- cmake -B build-vgui -S . -DCMAKE_EXE_LINKER_FLAGS="-Wl,--no-undefined" -DGOLDSOURCE_SUPPORT=ON -DUSE_VGUI=ON -DCMAKE_INSTALL_PREFIX="$PWD/dist-vgui"
cp vgui-dev/lib/vgui.so build-vgui/cl_dll
schroot --chroot steamrt_scout_i386 -- cmake --build build-vgui --target all
schroot --chroot steamrt_scout_i386 -- cmake --build build-vgui --target install
- name: Build with mingw
if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.cc, 'gcc')
@ -74,6 +83,11 @@ jobs:
run: |
cmake -G "Visual Studio 15 2017" -B build -DGOLDSOURCE_SUPPORT=ON -DCMAKE_INSTALL_PREFIX="dist"
msbuild -verbosity:normal /property:Configuration=Release build/INSTALL.vcxproj
- name: Build with msvc and vgui
if: startsWith(matrix.os, 'windows')
run: |
cmake -G "Visual Studio 15 2017" -B build -DGOLDSOURCE_SUPPORT=ON -DUSE_VGUI=ON -DCMAKE_INSTALL_PREFIX="dist-vgui"
msbuild -verbosity:normal /property:Configuration=Release build/INSTALL.vcxproj
- name: Extract branch name
shell: bash
@ -89,10 +103,22 @@ jobs:
with:
name: hlsdk-${{ steps.extract_branch.outputs.branch }}-linux
path: dist/${{ steps.extract_gamedir.outputs.gamedir }}
- name: Upload linux artifact with vgui
if: startsWith(matrix.os, 'ubuntu') && matrix.cc == 'gcc'
uses: actions/upload-artifact@v2
with:
name: hlsdk-${{ steps.extract_branch.outputs.branch }}-linux-vgui
path: dist-vgui/${{ steps.extract_gamedir.outputs.gamedir }}
- name: Upload windows artifact
if: startsWith(matrix.os, 'windows')
uses: actions/upload-artifact@v2
with:
name: hlsdk-${{ steps.extract_branch.outputs.branch }}-windows
path: dist/${{ steps.extract_gamedir.outputs.gamedir }}
- name: Upload windows artifact with vgui
if: startsWith(matrix.os, 'windows')
uses: actions/upload-artifact@v2
with:
name: hlsdk-${{ steps.extract_branch.outputs.branch }}-windows-vgui
path: dist-vgui/${{ steps.extract_gamedir.outputs.gamedir }}

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "vgui-dev"]
path = vgui-dev
url = https://github.com/FWGS/vgui-dev

View File

@ -36,8 +36,10 @@ project (HLSDK-XASH3D)
#--------------
# USER DEFINES \
################\
option(USE_VGUI "Enable VGUI1. UNDONE" OFF)
option(USE_VGUI "Enable VGUI1." OFF)
option(USE_VGUI2 "Enable VGUI2. UNDONE" OFF)
option(USE_NOVGUI_MOTD "Prefer non-VGUI MOTD when USE_VGUI is enabled" OFF)
option(USE_NOVGUI_SCOREBOARD "Prefer non-VGUI Scoreboard when USE_VGUI is enabled" OFF)
option(USE_VOICEMGR "Enable VOICE MANAGER." OFF)
option(BUILD_CLIENT "Build client dll" ON)
option(BUILD_SERVER "Build server dll" ON)

View File

@ -50,6 +50,15 @@ if (GOLDSOURCE_SUPPORT)
add_definitions(-DGOLDSOURCE_SUPPORT)
endif()
if (USE_VGUI)
add_definitions(-DUSE_VGUI)
if (USE_NOVGUI_MOTD)
add_definitions(-DUSE_NOVGUI_MOTD)
endif()
if (USE_NOVGUI_SCOREBOARD)
add_definitions(-DUSE_NOVGUI_SCOREBOARD)
endif()
endif()
set (CLDLL_SOURCES
../dlls/crossbow.cpp
@ -112,11 +121,52 @@ set (CLDLL_SOURCES
train.cpp
tri.cpp
util.cpp
view.cpp
scoreboard.cpp
MOTD.cpp)
view.cpp)
include_directories (. hl/ ../dlls ../dlls/wpn_shared ../common ../engine ../pm_shared ../game_shared ../public ../utils/false_vgui/include)
if (USE_VGUI)
list(APPEND CLDLL_SOURCES
vgui_int.cpp
vgui_ClassMenu.cpp
vgui_ConsolePanel.cpp
vgui_ControlConfigPanel.cpp
vgui_CustomObjects.cpp
vgui_MOTDWindow.cpp
vgui_SchemeManager.cpp
vgui_ScorePanel.cpp
vgui_TeamFortressViewport.cpp
vgui_SpectatorPanel.cpp
vgui_teammenu.cpp
voice_status.cpp
../game_shared/vgui_checkbutton2.cpp
../game_shared/vgui_grid.cpp
../game_shared/vgui_helpers.cpp
../game_shared/vgui_listbox.cpp
../game_shared/vgui_loadtga.cpp
../game_shared/vgui_scrollbar2.cpp
../game_shared/vgui_slider2.cpp
../game_shared/voice_banmgr.cpp
)
if (USE_NOVGUI_MOTD)
list(APPEND CLDLL_SOURCES MOTD.cpp)
endif()
if (USE_NOVGUI_SCOREBOARD)
list(APPEND CLDLL_SOURCES scoreboard.cpp)
endif()
else()
list(APPEND CLDLL_SOURCES
MOTD.cpp
scoreboard.cpp)
endif()
include_directories (. hl/ ../dlls ../dlls/wpn_shared ../common ../engine ../pm_shared ../game_shared ../public)
if (USE_VGUI)
SET(CMAKE_SKIP_RPATH TRUE)
link_directories(${CMAKE_SOURCE_DIR}/vgui-dev/lib)
include_directories(../vgui-dev/include)
else()
include_directories(../utils/false_vgui/include)
endif()
if(USE_VOICEMGR)
#set(CLDLL_SOURCES
@ -126,10 +176,25 @@ if(USE_VOICEMGR)
endif()
add_library (${CLDLL_LIBRARY} SHARED ${CLDLL_SOURCES})
if (GOLDSOURCE_SUPPORT)
target_link_libraries( ${CLDLL_LIBRARY} ${CMAKE_DL_LIBS} )
endif()
if (USE_VGUI)
if (WIN32)
add_library(vgui SHARED IMPORTED)
set_property(TARGET vgui PROPERTY IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/vgui-dev/lib/win32_vc6/vgui.dll")
set_property(TARGET vgui PROPERTY IMPORTED_IMPLIB "${CMAKE_SOURCE_DIR}/vgui-dev/lib/win32_vc6/vgui.lib")
target_link_libraries(${CLDLL_LIBRARY} vgui)
target_link_libraries(${CLDLL_LIBRARY} ws2_32)
elseif(APPLE)
target_link_libraries(${CLDLL_LIBRARY} "-Wl,--no-undefined -L${CMAKE_SOURCE_DIR}/vgui-dev/lib vgui.dylib")
else()
target_link_libraries(${CLDLL_LIBRARY} :vgui.so)
endif()
endif()
if(WIN32)
target_link_libraries( ${CLDLL_LIBRARY} user32.lib )
if (GOLDSOURCE_SUPPORT)

View File

@ -26,13 +26,17 @@
#include <string.h>
#include <stdio.h>
#if !USE_VGUI || USE_NOVGUI_MOTD
DECLARE_MESSAGE( m_MOTD, MOTD )
#endif
int CHudMOTD::Init( void )
{
gHUD.AddHudElem( this );
#if !USE_VGUI || USE_NOVGUI_MOTD
HOOK_MESSAGE( MOTD );
#endif
m_bShow = false;

View File

@ -27,6 +27,9 @@
#include <stdio.h>
#include "ammohistory.h"
#if USE_VGUI
#include "vgui_TeamFortressViewport.h"
#endif
WEAPON *gpActiveSel; // NULL means off, 1 means just the menu bar, otherwise
// this points to the active weapon menu item
@ -673,10 +676,11 @@ int CHudAmmo::MsgFunc_WeaponList( const char *pszName, int iSize, void *pbuf )
// Slot button pressed
void CHudAmmo::SlotInput( int iSlot )
{
#if USE_VGUI
// Let the Viewport use it first, for menus
// if( gViewPort && gViewPort->SlotInput( iSlot ) )
// return;
if( gViewPort && gViewPort->SlotInput( iSlot ) )
return;
#endif
gWR.SelectSlot(iSlot, FALSE, 1);
}

View File

@ -23,11 +23,18 @@
#include "netadr.h"
#include "parsemsg.h"
#if USE_VGUI
#include "vgui_int.h"
#include "vgui_TeamFortressViewport.h"
#endif
#if GOLDSOURCE_SUPPORT && (_WIN32 || __linux__ || __APPLE__) && (__i386 || _M_IX86)
#define USE_VGUI_FOR_GOLDSOURCE_SUPPORT 1
#define USE_FAKE_VGUI !USE_VGUI
#if USE_FAKE_VGUI
#include "VGUI_Panel.h"
#include "VGUI_App.h"
#endif
#endif
extern "C"
{
@ -38,6 +45,9 @@ extern "C"
cl_enginefunc_t gEngfuncs;
CHud gHUD;
#if USE_VGUI
TeamFortressViewport *gViewPort = NULL;
#endif
mobile_engfuncs_t *gMobileEngfuncs = NULL;
extern "C" int g_bhopcap;
@ -183,7 +193,7 @@ int *HUD_GetRect( void )
return extent;
}
#if USE_VGUI_FOR_GOLDSOURCE_SUPPORT
#if USE_FAKE_VGUI
class TeamFortressViewport : public vgui::Panel
{
public:
@ -238,7 +248,7 @@ so the HUD can reinitialize itself.
int DLLEXPORT HUD_VidInit( void )
{
gHUD.VidInit();
#if USE_VGUI_FOR_GOLDSOURCE_SUPPORT
#if USE_FAKE_VGUI
vgui::Panel* root=(vgui::Panel*)gEngfuncs.VGui_GetPanel();
if (root) {
gEngfuncs.Con_Printf( "Root VGUI panel exists\n" );
@ -256,6 +266,8 @@ int DLLEXPORT HUD_VidInit( void )
} else {
gEngfuncs.Con_Printf( "Root VGUI panel does not exist\n" );
}
#elif USE_VGUI
VGui_Startup();
#endif
return 1;
}
@ -274,6 +286,9 @@ void DLLEXPORT HUD_Init( void )
{
InitInput();
gHUD.Init();
#if USE_VGUI
Scheme_Init();
#endif
gEngfuncs.pfnHookUserMsg( "Bhopcap", __MsgFunc_Bhopcap );
}
@ -337,7 +352,9 @@ Called by engine every frame that client .dll is loaded
void DLLEXPORT HUD_Frame( double time )
{
#if USE_VGUI_FOR_GOLDSOURCE_SUPPORT
#if USE_VGUI
GetClientVoiceMgr()->Frame(time);
#elif USE_FAKE_VGUI
if (!gViewPort)
gEngfuncs.VGui_ViewportPaintBackground(HUD_GetRect());
#else
@ -355,7 +372,9 @@ Called when a player starts or stops talking.
void DLLEXPORT HUD_VoiceStatus( int entindex, qboolean bTalking )
{
#if USE_VGUI
GetClientVoiceMgr()->UpdateSpeakerStatus(entindex, bTalking);
#endif
}
/*

View File

@ -23,6 +23,10 @@
#include <string.h>
#include <stdio.h>
#if USE_VGUI
#include "vgui_TeamFortressViewport.h"
#endif
DECLARE_MESSAGE( m_DeathNotice, DeathMsg )
struct DeathNoticeItem {
@ -110,7 +114,9 @@ int CHudDeathNotice::Draw( float flTime )
// Only draw if the viewport will let me
// vgui dropped out
//if( gViewPort && gViewPort->AllowedToPrintText() )
#if USE_VGUI
if( gViewPort && gViewPort->AllowedToPrintText() )
#endif
{
// Draw the death notice
y = YRES( DEATHNOTICE_TOP ) + 2 + ( 20 * i ); //!!!
@ -168,6 +174,11 @@ int CHudDeathNotice::MsgFunc_DeathMsg( const char *pszName, int iSize, void *pbu
strcpy( killedwith, "d_" );
strncat( killedwith, READ_STRING(), sizeof(killedwith) - strlen(killedwith) - 1 );
#if USE_VGUI
if (gViewPort)
gViewPort->DeathMsg( killer, victim );
#endif
gHUD.m_Spectator.DeathMessage( victim );
for( i = 0; i < MAX_DEATHNOTICES; i++ )
@ -182,9 +193,7 @@ int CHudDeathNotice::MsgFunc_DeathMsg( const char *pszName, int iSize, void *pbu
i = MAX_DEATHNOTICES - 1;
}
//if(gViewPort)
// gViewPort->GetAllPlayersInfo();
gHUD.m_Scoreboard.GetAllPlayersInfo();
gHUD.GetAllPlayersInfo();
// Get the Killer's name
const char *killer_name = "";

View File

@ -7,6 +7,8 @@
// Client side entity management functions
#include <memory.h>
#include "hud.h"
#include "cl_util.h"
#include "const.h"
@ -526,6 +528,10 @@ void DLLEXPORT HUD_CreateEntities( void )
#endif
// Add in any game specific objects
Game_AddObjects();
#if USE_VGUI
GetClientVoiceMgr()->CreateEntities();
#endif
}
/*

View File

@ -23,11 +23,72 @@
#include <string.h>
#include <stdio.h>
#include "parsemsg.h"
#include "hud_servers.h"
#if USE_VGUI
#include "vgui_int.h"
#include "vgui_TeamFortressViewport.h"
#endif
#include "demo.h"
#include "demo_api.h"
hud_player_info_t g_PlayerInfoList[MAX_PLAYERS+1]; // player info from the engine
extra_player_info_t g_PlayerExtraInfo[MAX_PLAYERS+1]; // additional player info sent directly to the client dll
team_info_t g_TeamInfo[MAX_TEAMS + 1];
int g_IsSpectator[MAX_PLAYERS+1];
int g_iPlayerClass;
int g_iTeamNumber;
int g_iUser1 = 0;
int g_iUser2 = 0;
int g_iUser3 = 0;
#if USE_VGUI
#include "vgui_ScorePanel.h"
class CHLVoiceStatusHelper : public IVoiceStatusHelper
{
public:
virtual void GetPlayerTextColor(int entindex, int color[3])
{
color[0] = color[1] = color[2] = 255;
if( entindex >= 0 && entindex < sizeof(g_PlayerExtraInfo)/sizeof(g_PlayerExtraInfo[0]) )
{
int iTeam = g_PlayerExtraInfo[entindex].teamnumber;
if ( iTeam < 0 )
{
iTeam = 0;
}
iTeam = iTeam % iNumberOfTeamColors;
color[0] = iTeamColors[iTeam][0];
color[1] = iTeamColors[iTeam][1];
color[2] = iTeamColors[iTeam][2];
}
}
virtual void UpdateCursorState()
{
gViewPort->UpdateCursorState();
}
virtual int GetAckIconHeight()
{
return ScreenHeight - gHUD.m_iFontHeight*3 - 6;
}
virtual bool CanShowSpeakerLabels()
{
if( gViewPort && gViewPort->m_pScoreBoard )
return !gViewPort->m_pScoreBoard->isVisible();
else
return false;
}
};
static CHLVoiceStatusHelper g_VoiceStatusHelper;
#endif
cvar_t *hud_textmode;
float g_hud_text_color[3];
@ -81,73 +142,182 @@ int __MsgFunc_GameMode( const char *pszName, int iSize, void *pbuf )
// TFFree Command Menu
void __CmdFunc_OpenCommandMenu( void )
{
#if USE_VGUI
if ( gViewPort )
{
gViewPort->ShowCommandMenu( gViewPort->m_StandardMenu );
}
#endif
}
// TFC "special" command
void __CmdFunc_InputPlayerSpecial( void )
{
#if USE_VGUI
if ( gViewPort )
{
gViewPort->InputPlayerSpecial();
}
#endif
}
void __CmdFunc_CloseCommandMenu( void )
{
#if USE_VGUI
if ( gViewPort )
{
gViewPort->InputSignalHideCommandMenu();
}
#endif
}
void __CmdFunc_ForceCloseCommandMenu( void )
{
}
void __CmdFunc_ToggleServerBrowser( void )
{
#if USE_VGUI
if ( gViewPort )
{
gViewPort->HideCommandMenu();
}
#endif
}
// TFFree Command Menu Message Handlers
int __MsgFunc_ValClass( const char *pszName, int iSize, void *pbuf )
{
#if USE_VGUI
if (gViewPort)
return gViewPort->MsgFunc_ValClass( pszName, iSize, pbuf );
#endif
return 0;
}
int __MsgFunc_TeamNames( const char *pszName, int iSize, void *pbuf )
{
#if USE_VGUI
if (gViewPort)
return gViewPort->MsgFunc_TeamNames( pszName, iSize, pbuf );
#endif
return 0;
}
int __MsgFunc_Feign( const char *pszName, int iSize, void *pbuf )
{
#if USE_VGUI
if (gViewPort)
return gViewPort->MsgFunc_Feign( pszName, iSize, pbuf );
#endif
return 0;
}
int __MsgFunc_Detpack( const char *pszName, int iSize, void *pbuf )
{
#if USE_VGUI
if (gViewPort)
return gViewPort->MsgFunc_Detpack( pszName, iSize, pbuf );
#endif
return 0;
}
int __MsgFunc_VGUIMenu( const char *pszName, int iSize, void *pbuf )
{
#if USE_VGUI
if (gViewPort)
return gViewPort->MsgFunc_VGUIMenu( pszName, iSize, pbuf );
#endif
return 0;
}
#if USE_VGUI && !USE_NOVGUI_MOTD
int __MsgFunc_MOTD(const char *pszName, int iSize, void *pbuf)
{
if (gViewPort)
return gViewPort->MsgFunc_MOTD( pszName, iSize, pbuf );
return 0;
}
#endif
int __MsgFunc_BuildSt( const char *pszName, int iSize, void *pbuf )
{
#if USE_VGUI
if (gViewPort)
return gViewPort->MsgFunc_BuildSt( pszName, iSize, pbuf );
#endif
return 0;
}
int __MsgFunc_RandomPC( const char *pszName, int iSize, void *pbuf )
{
#if USE_VGUI
if (gViewPort)
return gViewPort->MsgFunc_RandomPC( pszName, iSize, pbuf );
#endif
return 0;
}
int __MsgFunc_ServerName( const char *pszName, int iSize, void *pbuf )
{
#if USE_VGUI
if (gViewPort)
return gViewPort->MsgFunc_ServerName( pszName, iSize, pbuf );
#endif
return 0;
}
#if USE_VGUI && !USE_NOVGUI_SCOREBOARD
int __MsgFunc_ScoreInfo(const char *pszName, int iSize, void *pbuf)
{
if (gViewPort)
return gViewPort->MsgFunc_ScoreInfo( pszName, iSize, pbuf );
return 0;
}
int __MsgFunc_TeamScore(const char *pszName, int iSize, void *pbuf)
{
if (gViewPort)
return gViewPort->MsgFunc_TeamScore( pszName, iSize, pbuf );
return 0;
}
int __MsgFunc_TeamInfo(const char *pszName, int iSize, void *pbuf)
{
if (gViewPort)
return gViewPort->MsgFunc_TeamInfo( pszName, iSize, pbuf );
return 0;
}
#endif
int __MsgFunc_Spectator( const char *pszName, int iSize, void *pbuf )
{
#if USE_VGUI
if (gViewPort)
return gViewPort->MsgFunc_Spectator( pszName, iSize, pbuf );
#endif
return 0;
}
#if USE_VGUI
int __MsgFunc_SpecFade(const char *pszName, int iSize, void *pbuf)
{
if (gViewPort)
return gViewPort->MsgFunc_SpecFade( pszName, iSize, pbuf );
return 0;
}
int __MsgFunc_ResetFade(const char *pszName, int iSize, void *pbuf)
{
if (gViewPort)
return gViewPort->MsgFunc_ResetFade( pszName, iSize, pbuf );
return 0;
}
#endif
int __MsgFunc_AllowSpec( const char *pszName, int iSize, void *pbuf )
{
#if USE_VGUI
if (gViewPort)
return gViewPort->MsgFunc_AllowSpec( pszName, iSize, pbuf );
#endif
return 0;
}
@ -167,7 +337,6 @@ void CHud::Init( void )
HOOK_COMMAND( "-commandmenu", CloseCommandMenu );
HOOK_COMMAND( "ForceCloseCommandMenu", ForceCloseCommandMenu );
HOOK_COMMAND( "special", InputPlayerSpecial );
HOOK_COMMAND( "togglebrowser", ToggleServerBrowser );
HOOK_MESSAGE( ValClass );
HOOK_MESSAGE( TeamNames );
@ -177,9 +346,24 @@ void CHud::Init( void )
HOOK_MESSAGE( RandomPC );
HOOK_MESSAGE( ServerName );
#if USE_VGUI && !USE_NOVGUI_MOTD
HOOK_MESSAGE( MOTD );
#endif
#if USE_VGUI && !USE_NOVGUI_SCOREBOARD
HOOK_MESSAGE( ScoreInfo );
HOOK_MESSAGE( TeamScore );
HOOK_MESSAGE( TeamInfo );
#endif
HOOK_MESSAGE( Spectator );
HOOK_MESSAGE( AllowSpec );
#if USE_VGUI
HOOK_MESSAGE( SpecFade );
HOOK_MESSAGE( ResetFade );
#endif
// VGUI Menus
HOOK_MESSAGE( VGUIMenu );
@ -230,11 +414,19 @@ void CHud::Init( void )
m_AmmoSecondary.Init();
m_TextMessage.Init();
m_StatusIcons.Init();
#if USE_VGUI
GetClientVoiceMgr()->Init(&g_VoiceStatusHelper, (vgui::Panel**)&gViewPort);
#endif
#if !USE_VGUI || USE_NOVGUI_MOTD
m_MOTD.Init();
#endif
#if !USE_VGUI || USE_NOVGUI_SCOREBOARD
m_Scoreboard.Init();
#endif
m_Menu.Init();
MsgFunc_ResetHUD( 0, 0, NULL );
}
@ -411,8 +603,15 @@ void CHud::VidInit( void )
m_AmmoSecondary.VidInit();
m_TextMessage.VidInit();
m_StatusIcons.VidInit();
m_Scoreboard.VidInit();
#if USE_VGUI
GetClientVoiceMgr()->VidInit();
#endif
#if !USE_VGUI || USE_NOVGUI_MOTD
m_MOTD.VidInit();
#endif
#if !USE_VGUI || USE_NOVGUI_SCOREBOARD
m_Scoreboard.VidInit();
#endif
}
int CHud::MsgFunc_Logo( const char *pszName, int iSize, void *pbuf )
@ -588,3 +787,22 @@ float CHud::GetSensitivity( void )
{
return m_flMouseSensitivity;
}
void CHud::GetAllPlayersInfo()
{
for( int i = 1; i < MAX_PLAYERS; i++ )
{
GetPlayerInfo( i, &g_PlayerInfoList[i] );
if( g_PlayerInfoList[i].thisplayer )
{
#if USE_VGUI
if(gViewPort)
gViewPort->m_pScoreBoard->m_iPlayerNum = i;
#endif
#if !USE_VGUI || USE_NOVGUI_SCOREBOARD
m_Scoreboard.m_iPlayerNum = i; // !!!HACK: this should be initialized elsewhere... maybe gotten from the engine
#endif
}
}
}

View File

@ -63,6 +63,9 @@ typedef struct cvar_s cvar_t;
#define MAX_MOTD_LENGTH 1536
#define MAX_SERVERNAME_LENGTH 64
#define MAX_TEAMNAME_SIZE 32
//
//-----------------------------------------------------
//
@ -89,6 +92,9 @@ struct HUDLIST
//
//-----------------------------------------------------
#if USE_VGUI
#include "voice_status.h" // base voice handling class
#endif
#include "hud_spectator.h"
//
@ -196,11 +202,7 @@ private:
int m_iPos;
};
//
//-----------------------------------------------------
//
// REMOVED: Vgui has replaced this.
//
#if !USE_VGUI || USE_NOVGUI_MOTD
class CHudMOTD : public CHudBase
{
public:
@ -222,7 +224,9 @@ protected:
int m_iLines;
int m_iMaxLength;
};
#endif
#if !USE_VGUI || USE_NOVGUI_SCOREBOARD
class CHudScoreboard : public CHudBase
{
public:
@ -249,6 +253,7 @@ public:
void GetAllPlayersInfo( void );
};
#endif
//
//-----------------------------------------------------
@ -283,41 +288,6 @@ protected:
float *m_pflNameColors[MAX_STATUSBAR_LINES];
};
//
//-----------------------------------------------------
//
// REMOVED: Vgui has replaced this.
//
/*
class CHudScoreboard : public CHudBase
{
public:
int Init( void );
void InitHUDData( void );
int VidInit( void );
int Draw( float flTime );
int DrawPlayers( int xoffset, float listslot, int nameoffset = 0, char *team = NULL ); // returns the ypos where it finishes drawing
void UserCmd_ShowScores( void );
void UserCmd_HideScores( void );
int MsgFunc_ScoreInfo( const char *pszName, int iSize, void *pbuf );
int MsgFunc_TeamInfo( const char *pszName, int iSize, void *pbuf );
int MsgFunc_TeamScore( const char *pszName, int iSize, void *pbuf );
void DeathMsg( int killer, int victim );
int m_iNumTeams;
int m_iLastKilledBy;
int m_fLastKillTime;
int m_iPlayerNum;
int m_iShowscoresHeld;
void GetAllPlayersInfo( void );
private:
struct cvar_s *cl_showpacketloss;
};
*/
struct extra_player_info_t
{
short frags;
@ -633,8 +603,12 @@ public:
CHudAmmoSecondary m_AmmoSecondary;
CHudTextMessage m_TextMessage;
CHudStatusIcons m_StatusIcons;
#if !USE_VGUI || USE_NOVGUI_SCOREBOARD
CHudScoreboard m_Scoreboard;
#endif
#if !USE_VGUI || USE_NOVGUI_MOTD
CHudMOTD m_MOTD;
#endif
void Init( void );
void VidInit( void );
@ -670,6 +644,8 @@ public:
void AddHudElem( CHudBase *p );
float GetSensitivity();
void GetAllPlayersInfo( void );
};
extern CHud gHUD;

View File

@ -21,6 +21,10 @@
#include "cl_util.h"
//#include "triangleapi.h"
#if USE_VGUI
#include "vgui_TeamFortressViewport.h"
#endif
#define MAX_LOGO_FRAMES 56
int grgLogoFrame[MAX_LOGO_FRAMES] =
@ -39,6 +43,11 @@ extern cvar_t *sensitivity;
// Think
void CHud::Think( void )
{
#if USE_VGUI
m_scrinfo.iSize = sizeof(m_scrinfo);
GetScreenInfo(&m_scrinfo);
#endif
int newfov;
HUDLIST *pList = m_pHudList;
@ -94,13 +103,40 @@ int CHud::Redraw( float flTime, int intermission )
if( m_flTimeDelta < 0 )
m_flTimeDelta = 0;
#if USE_VGUI
// Bring up the scoreboard during intermission
if (gViewPort)
{
if( m_iIntermission && !intermission )
{
// Have to do this here so the scoreboard goes away
m_iIntermission = intermission;
gViewPort->HideCommandMenu();
gViewPort->HideScoreBoard();
gViewPort->UpdateSpectatorPanel();
}
else if( !m_iIntermission && intermission )
{
m_iIntermission = intermission;
gViewPort->HideCommandMenu();
gViewPort->HideVGUIMenu();
#if !USE_NOVGUI_SCOREBOARD
gViewPort->ShowScoreBoard();
#endif
gViewPort->UpdateSpectatorPanel();
// Take a screenshot if the client's got the cvar set
if( CVAR_GET_FLOAT( "hud_takesshots" ) != 0 )
m_flShotTime = flTime + 1.0; // Take a screenshot in a second
}
}
#else
if( !m_iIntermission && intermission )
{
// Take a screenshot if the client's got the cvar set
if( CVAR_GET_FLOAT( "hud_takesshots" ) != 0 )
m_flShotTime = flTime + 1.0f; // Take a screenshot in a second
}
#endif
if( m_flShotTime && m_flShotTime < flTime )
{
gEngfuncs.pfnClientCmd( "snapshot\n" );

File diff suppressed because it is too large Load Diff

View File

@ -1,40 +0,0 @@
//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#if !defined( HUD_SERVERSH )
#define HUD_SERVERSH
#pragma once
#define NET_CALLBACK /* */
// Dispatchers
void NET_CALLBACK ListResponse( struct net_response_s *response );
void NET_CALLBACK ServerResponse( struct net_response_s *response );
void NET_CALLBACK PingResponse( struct net_response_s *response );
void NET_CALLBACK RulesResponse( struct net_response_s *response );
void NET_CALLBACK PlayersResponse( struct net_response_s *response );
void ServersInit( void );
void ServersShutdown( void );
void ServersThink( double time );
void ServersCancel( void );
// Get list and get server info from each
void ServersList( void );
// Query for IP / IPX LAN servers
void BroadcastServersList( int clearpending );
void ServerPing( int server );
void ServerRules( int server );
void ServerPlayers( int server );
int ServersGetCount( void );
const char *ServersGetInfo( int server );
int ServersIsQuerying( void );
void SortServers( const char *fieldname );
#endif // HUD_SERVERSH

View File

@ -9,6 +9,10 @@
#include "cl_util.h"
#include "cl_entity.h"
#include "triangleapi.h"
#if USE_VGUI
#include "vgui_TeamFortressViewport.h"
#include "vgui_SpectatorPanel.h"
#endif
#include "hltv.h"
#include "pm_shared.h"
@ -76,8 +80,16 @@ void SpectatorSpray( void )
gEngfuncs.pfnServerCmd( string );
}
}
void SpectatorHelp( void )
{
#if USE_VGUI
if( gViewPort )
{
gViewPort->ShowVGUIMenu( MENU_SPECHELP );
}
else
#endif
{
char *text = CHudTextMessage::BufferedLocaliseTextString( "#Spec_Help_Text" );
@ -100,10 +112,33 @@ void SpectatorMenu( void )
gEngfuncs.Con_Printf( "usage: spec_menu <0|1>\n" );
return;
}
#if USE_VGUI
gViewPort->m_pSpectatorPanel->ShowMenu( atoi( gEngfuncs.Cmd_Argv( 1 ) ) != 0 );
#endif
}
void ToggleScores( void )
{
#if USE_VGUI && !USE_NOVGUI_SCOREBOARD
if( gViewPort )
{
if( gViewPort->IsScoreBoardVisible() )
{
gViewPort->HideScoreBoard();
}
else
{
gViewPort->ShowScoreBoard();
}
}
#else
if (gHUD.m_Scoreboard.m_iShowscoresHeld) {
gHUD.m_Scoreboard.UserCmd_HideScores();
} else {
gHUD.m_Scoreboard.UserCmd_ShowScores();
}
#endif
}
//-----------------------------------------------------------------------------
@ -392,8 +427,7 @@ int CHudSpectator::Draw( float flTime )
return 1;
// make sure we have player info
//gViewPort->GetAllPlayersInfo();
gHUD.m_Scoreboard.GetAllPlayersInfo();
gHUD.GetAllPlayersInfo();
// loop through all the players and draw additional infos to their sprites on the map
for( int i = 0; i < MAX_PLAYERS; i++ )
@ -529,9 +563,16 @@ void CHudSpectator::DirectorMessage( int iSize, void *pbuf )
READ_LONG(); // total number of spectator slots
m_iSpectatorNumber = READ_LONG(); // total number of spectator
READ_WORD(); // total number of relay proxies
#if USE_VGUI
gViewPort->UpdateSpectatorPanel();
#endif
break;
case DRC_CMD_BANNER:
// gEngfuncs.Con_DPrintf( "GUI: Banner %s\n",READ_STRING() ); // name of banner tga eg gfx/temp/7454562234563475.tga
#if USE_VGUI
gViewPort->m_pSpectatorPanel->m_TopBanner->LoadImage( READ_STRING() );
gViewPort->UpdateSpectatorPanel();
#endif
break;
case DRC_CMD_FADE:
break;
@ -573,8 +614,7 @@ void CHudSpectator::FindNextPlayer( bool bReverse )
int iDir = bReverse ? -1 : 1;
// make sure we have player info
//gViewPort->GetAllPlayersInfo();
gHUD.m_Scoreboard.GetAllPlayersInfo();
gHUD.GetAllPlayersInfo();
do
{
@ -611,6 +651,68 @@ void CHudSpectator::FindNextPlayer( bool bReverse )
VectorCopy( pEnt->angles, vJumpAngles );
}
iJumpSpectator = 1;
#if USE_VGUI
gViewPort->MsgFunc_ResetFade( NULL, 0, NULL );
#endif
}
void CHudSpectator::FindPlayer(const char *name)
{
// MOD AUTHORS: Modify the logic of this function if you want to restrict the observer to watching
// only a subset of the players. e.g. Make it check the target's team.
// if we are NOT in HLTV mode, spectator targets are set on server
if ( !gEngfuncs.IsSpectateOnly() )
{
char cmdstring[32];
// forward command to server
sprintf(cmdstring,"follow %s",name);
gEngfuncs.pfnServerCmd(cmdstring);
return;
}
g_iUser2 = 0;
// make sure we have player info
gHUD.GetAllPlayersInfo();
cl_entity_t * pEnt = NULL;
for (int i = 1; i < MAX_PLAYERS; i++ )
{
pEnt = gEngfuncs.GetEntityByIndex( i );
if ( !IsActivePlayer( pEnt ) )
continue;
if(!stricmp(g_PlayerInfoList[pEnt->index].name,name))
{
g_iUser2 = i;
break;
}
}
// Did we find a target?
if ( !g_iUser2 )
{
gEngfuncs.Con_DPrintf( "No observer targets.\n" );
// take save camera position
VectorCopy(m_cameraOrigin, vJumpOrigin);
VectorCopy(m_cameraAngles, vJumpAngles);
}
else
{
// use new entity position for roaming
VectorCopy ( pEnt->origin, vJumpOrigin );
VectorCopy ( pEnt->angles, vJumpAngles );
}
iJumpSpectator = 1;
#if USE_VGUI
gViewPort->MsgFunc_ResetFade( NULL, 0, NULL );
#endif
}
void CHudSpectator::HandleButtonsDown( int ButtonPressed )
@ -622,6 +724,11 @@ void CHudSpectator::HandleButtonsDown( int ButtonPressed )
// gEngfuncs.Con_Printf( " HandleButtons:%i\n", ButtonPressed );
#if USE_VGUI
if( !gViewPort )
return;
#endif
//Not in intermission.
if( gHUD.m_iIntermission )
return;
@ -637,8 +744,10 @@ void CHudSpectator::HandleButtonsDown( int ButtonPressed )
return;
// enable spectator screen
//if( ButtonPressed & IN_DUCK )
// gViewPort->m_pSpectatorPanel->ShowMenu( !gViewPort->m_pSpectatorPanel->m_menuVisible );
#if USE_VGUI
if( ButtonPressed & IN_DUCK )
gViewPort->m_pSpectatorPanel->ShowMenu( !gViewPort->m_pSpectatorPanel->m_menuVisible );
#endif
// 'Use' changes inset window mode
if( ButtonPressed & IN_USE )
@ -705,6 +814,14 @@ void CHudSpectator::HandleButtonsDown( int ButtonPressed )
void CHudSpectator::HandleButtonsUp( int ButtonPressed )
{
#if USE_VGUI
if( !gViewPort )
return;
if( !gViewPort->m_pSpectatorPanel->isVisible() )
return; // dont do anything if not in spectator mode
#endif
if( ButtonPressed & ( IN_FORWARD | IN_BACK ) )
m_zoomDelta = 0.0f;
@ -800,12 +917,19 @@ void CHudSpectator::SetModes( int iNewMainMode, int iNewInsetMode )
SetCrosshair( 0, m_crosshairRect, 0, 0, 0 );
}
#if USE_VGUI
gViewPort->MsgFunc_ResetFade( NULL, 0, NULL );
#endif
char string[128];
sprintf( string, "#Spec_Mode%d", g_iUser1 );
sprintf( string, "%c%s", HUD_PRINTCENTER, CHudTextMessage::BufferedLocaliseTextString( string ) );
gHUD.m_TextMessage.MsgFunc_TextMsg( NULL, strlen( string ) + 1, string );
}
#if USE_VGUI
gViewPort->UpdateSpectatorPanel();
#endif
}
bool CHudSpectator::IsActivePlayer( cl_entity_t *ent )
@ -1454,6 +1578,9 @@ void CHudSpectator::CheckSettings()
m_pip->value = INSET_OFF;
// draw small border around inset view, adjust upper black bar
#if USE_VGUI
gViewPort->m_pSpectatorPanel->EnableInsetView( m_pip->value != INSET_OFF );
#endif
}
int CHudSpectator::ToggleInset( bool allowOff )

View File

@ -73,6 +73,7 @@ public:
void HandleButtonsDown( int ButtonPressed );
void HandleButtonsUp( int ButtonPressed );
void FindNextPlayer( bool bReverse );
void FindPlayer(const char *name);
void DirectorMessage( int iSize, void *pbuf );
void SetSpectatorStartPosition();
int Init();

View File

@ -15,6 +15,22 @@
#include "camera.h"
#include "in_defs.h"
#if _WIN32
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#define WIN32_EXTRA_LEAN
#define HSPRITE WINDOWS_HSPRITE
#include <windows.h>
#undef HSPRITE
#else
typedef struct point_s
{
int x;
int y;
} POINT;
#define GetCursorPos(x)
#define SetCursorPos(x,y)
#endif
float CL_KeyState( kbutton_t *key );
extern "C"

View File

@ -16,17 +16,4 @@
// fall over
#define ROLL 2
#if _WIN32
#define HSPRITE HSPRITE_win32
#include <windows.h>
#undef HSPRITE
#else
typedef struct point_s
{
int x;
int y;
} POINT;
#define GetCursorPos(x)
#define SetCursorPos(x,y)
#endif
#endif

View File

@ -28,6 +28,10 @@ extern "C"
#include <string.h>
#include <ctype.h>
#if USE_VGUI
#include "vgui_TeamFortressViewport.h"
#endif
extern "C"
{
struct kbutton_s DLLEXPORT *KB_Find( const char *name );
@ -645,13 +649,27 @@ void IN_Impulse( void )
void IN_ScoreDown( void )
{
KeyDown( &in_score );
#if USE_VGUI && !USE_NOVGUI_SCOREBOARD
if ( gViewPort )
{
gViewPort->ShowScoreBoard();
}
#else
gHUD.m_Scoreboard.UserCmd_ShowScores();
#endif
}
void IN_ScoreUp( void )
{
KeyUp( &in_score );
#if USE_VGUI && !USE_NOVGUI_SCOREBOARD
if ( gViewPort )
{
gViewPort->HideScoreBoard();
}
#else
gHUD.m_Scoreboard.UserCmd_HideScores();
#endif
}
void IN_MLookUp( void )
@ -849,6 +867,12 @@ void DLLEXPORT CL_CreateMove( float frametime, struct usercmd_s *cmd, int active
//
cmd->buttons = CL_ButtonBits( 1 );
#if USE_VGUI
// If they're in a modal dialog, ignore the attack button.
if(GetClientVoiceMgr()->IsInSquelchMode())
cmd->buttons &= ~IN_ATTACK;
#endif
// Using joystick?
if( in_joystick->value )
{
@ -903,9 +927,11 @@ int CL_ButtonBits( int bResetState )
if( in_attack.state & 3 )
{
#if !USE_VGUI || USE_NOVGUI_MOTD
if( gHUD.m_MOTD.m_bShow )
gHUD.m_MOTD.Reset();
else
#endif
bits |= IN_ATTACK;
}

View File

@ -47,6 +47,21 @@ protected:
// No need for goldsource input support on the platforms that are not supported by GoldSource.
#if GOLDSOURCE_SUPPORT && (_WIN32 || __linux__ || __APPLE__) && (__i386 || _M_IX86)
#define SUPPORT_GOLDSOURCE_INPUT 1
#if _WIN32
#define HSPRITE WINDOWS_HSPRITE
#include <windows.h>
#undef HSPRITE
#else
typedef struct point_s
{
int x;
int y;
} POINT;
#define GetCursorPos(x)
#define SetCursorPos(x,y)
#endif
class GoldSourceInput : public AbstractInput
{
public:

View File

@ -187,9 +187,11 @@ void FWGSInput::IN_Move( float frametime, usercmd_t *cmd )
viewangles[YAW] -= ac_sidemove * 5;
ac_sidemove = 0;
}
#if !USE_VGUI || USE_NOVGUI_MOTD
if( gHUD.m_MOTD.m_bShow )
gHUD.m_MOTD.scroll += rel_pitch;
else
#endif
viewangles[PITCH] += rel_pitch;
if( viewangles[PITCH] > cl_pitchdown->value )

View File

@ -24,6 +24,10 @@
#include <string.h>
#include <stdio.h>
#if USE_VGUI
#include "vgui_TeamFortressViewport.h"
#endif
#define MAX_MENU_STRING 512
char g_szMenuString[MAX_MENU_STRING];
char g_szPrelocalisedMenuString[MAX_MENU_STRING];
@ -78,6 +82,11 @@ int CHudMenu::Draw( float flTime )
}
// don't draw the menu if the scoreboard is being shown
#if USE_VGUI
if( gViewPort && gViewPort->IsScoreBoardVisible() )
return 1;
#endif
// draw the menu, along the left-hand side of the screen
// count the number of newlines
int nlc = 0;

View File

@ -25,6 +25,10 @@
#include <string.h>
#include <stdio.h>
#if USE_VGUI
#include "vgui_TeamFortressViewport.h"
#endif
extern float *GetClientColor( int clientIndex );
#define MAX_LINES 5
@ -95,6 +99,12 @@ int CHudSayText::Draw( float flTime )
{
int y = Y_START;
#if USE_VGUI
if( ( gViewPort && gViewPort->AllowedToPrintText() == FALSE ) || !m_HUD_saytext->value )
return 1;
#endif
// make sure the scrolltime is within reasonable bounds, to guard against the clock being reset
flScrollTime = Q_min( flScrollTime, flTime + m_HUD_saytext_time->value );
@ -156,9 +166,18 @@ int CHudSayText::MsgFunc_SayText( const char *pszName, int iSize, void *pbuf )
void CHudSayText::SayTextPrint( const char *pszBuf, int iBufSize, int clientIndex )
{
int i;
#if USE_VGUI
if( gViewPort && gViewPort->AllowedToPrintText() == FALSE )
{
// Print it straight to the console
ConsolePrint( pszBuf );
return;
}
#else
ConsolePrint( pszBuf );
#endif
int i;
// find an empty string slot
for( i = 0; i < MAX_LINES; i++ )
{

View File

@ -28,23 +28,20 @@
cvar_t *cl_scoreboard_bg;
cvar_t *cl_showpacketloss;
hud_player_info_t g_PlayerInfoList[MAX_PLAYERS + 1]; // player info from the engine
extra_player_info_t g_PlayerExtraInfo[MAX_PLAYERS + 1]; // additional player info sent directly to the client dll
team_info_t g_TeamInfo[MAX_TEAMS + 1];
int g_iUser1;
int g_iUser2;
int g_iUser3;
int g_iTeamNumber;
int g_iPlayerClass;
//#include "vgui_TeamFortressViewport.h"
#if USE_VGUI
#include "vgui_TeamFortressViewport.h"
#endif
DECLARE_COMMAND( m_Scoreboard, ShowScores )
DECLARE_COMMAND( m_Scoreboard, HideScores )
#if !USE_VGUI || USE_NOVGUI_SCOREBOARD
DECLARE_MESSAGE( m_Scoreboard, ScoreInfo )
DECLARE_MESSAGE( m_Scoreboard, TeamInfo )
DECLARE_MESSAGE( m_Scoreboard, TeamScore )
#endif
int CHudScoreboard::Init( void )
{
@ -54,9 +51,11 @@ int CHudScoreboard::Init( void )
// HOOK_COMMAND( "+showscores", ShowScores );
// HOOK_COMMAND( "-showscores", HideScores );
#if !USE_VGUI || USE_NOVGUI_SCOREBOARD
HOOK_MESSAGE( ScoreInfo );
HOOK_MESSAGE( TeamScore );
HOOK_MESSAGE( TeamInfo );
#endif
InitHUDData();
@ -502,7 +501,9 @@ int CHudScoreboard::MsgFunc_ScoreInfo( const char *pszName, int iSize, void *pbu
g_PlayerExtraInfo[cl].playerclass = playerclass;
g_PlayerExtraInfo[cl].teamnumber = teamnumber;
//gViewPort->UpdateOnPlayerInfo();
#if USE_VGUI
gViewPort->UpdateOnPlayerInfo();
#endif
}
return 1;

View File

@ -26,6 +26,10 @@
#include <stdio.h>
#include "parsemsg.h"
#if USE_VGUI
#include "vgui_TeamFortressViewport.h"
#endif
DECLARE_MESSAGE( m_TextMessage, TextMsg )
int CHudTextMessage::Init( void )
@ -178,6 +182,11 @@ int CHudTextMessage::MsgFunc_TextMsg( const char *pszName, int iSize, void *pbuf
char *psz = szBuf[5];
#if USE_VGUI
if( gViewPort && gViewPort->AllowedToPrintText() == FALSE )
return 1;
#endif
switch( msg_dest )
{
case HUD_PRINTCENTER:

436
cl_dll/vgui_ClassMenu.cpp Normal file
View File

@ -0,0 +1,436 @@
//=========== (C) Copyright 1996-2002 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// Purpose: TFC Class Menu
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================
#include "VGUI_Font.h"
#include <VGUI_TextImage.h>
#include "hud.h"
#include "cl_util.h"
#include "camera.h"
#include "kbutton.h"
#include "cvardef.h"
#include "usercmd.h"
#include "const.h"
#include "camera.h"
#include "in_defs.h"
#include "parsemsg.h"
#include "vgui_int.h"
#include "vgui_TeamFortressViewport.h"
// Class Menu Dimensions
#define CLASSMENU_TITLE_X XRES(40)
#define CLASSMENU_TITLE_Y YRES(32)
#define CLASSMENU_TOPLEFT_BUTTON_X XRES(40)
#define CLASSMENU_TOPLEFT_BUTTON_Y YRES(80)
#define CLASSMENU_BUTTON_SIZE_X XRES(124)
#define CLASSMENU_BUTTON_SIZE_Y YRES(24)
#define CLASSMENU_BUTTON_SPACER_Y YRES(8)
#define CLASSMENU_WINDOW_X XRES(176)
#define CLASSMENU_WINDOW_Y YRES(80)
#define CLASSMENU_WINDOW_SIZE_X XRES(424)
#define CLASSMENU_WINDOW_SIZE_Y YRES(312)
#define CLASSMENU_WINDOW_TEXT_X XRES(150)
#define CLASSMENU_WINDOW_TEXT_Y YRES(80)
#define CLASSMENU_WINDOW_NAME_X XRES(150)
#define CLASSMENU_WINDOW_NAME_Y YRES(8)
#define CLASSMENU_WINDOW_PLAYERS_Y YRES(42)
// Creation
CClassMenuPanel::CClassMenuPanel( int iTrans, int iRemoveMe, int x, int y, int wide, int tall ) : CMenuPanel( iTrans, iRemoveMe, x, y, wide, tall )
{
// don't show class graphics at below 640x480 resolution
bool bShowClassGraphic = true;
if( ScreenWidth < 640 )
{
bShowClassGraphic = false;
}
memset( m_pClassImages, 0, sizeof(m_pClassImages) );
// Get the scheme used for the Titles
CSchemeManager *pSchemes = gViewPort->GetSchemeManager();
// schemes
SchemeHandle_t hTitleScheme = pSchemes->getSchemeHandle( "Title Font" );
SchemeHandle_t hClassWindowText = pSchemes->getSchemeHandle( "Briefing Text" );
// color schemes
int r, g, b, a;
// Create the title
Label *pLabel = new Label( "", CLASSMENU_TITLE_X, CLASSMENU_TITLE_Y );
pLabel->setParent( this );
pLabel->setFont( pSchemes->getFont( hTitleScheme ) );
pSchemes->getFgColor( hTitleScheme, r, g, b, a );
pLabel->setFgColor( r, g, b, a );
pSchemes->getBgColor( hTitleScheme, r, g, b, a );
pLabel->setBgColor( r, g, b, a );
pLabel->setContentAlignment( vgui::Label::a_west );
pLabel->setText(gHUD.m_TextMessage.BufferedLocaliseTextString( "#Title_SelectYourClass" ) );
// Create the Scroll panel
m_pScrollPanel = new CTFScrollPanel( CLASSMENU_WINDOW_X, CLASSMENU_WINDOW_Y, CLASSMENU_WINDOW_SIZE_X, CLASSMENU_WINDOW_SIZE_Y );
m_pScrollPanel->setParent( this );
//force the scrollbars on, so after the validate clientClip will be smaller
m_pScrollPanel->setScrollBarAutoVisible( false, false );
m_pScrollPanel->setScrollBarVisible( true, true );
m_pScrollPanel->setBorder( new LineBorder( Color( 255 * 0.7, 170 * 0.7, 0, 0 ) ) );
m_pScrollPanel->validate();
int clientWide=m_pScrollPanel->getClient()->getWide();
//turn scrollpanel back into auto show scrollbar mode and validate
m_pScrollPanel->setScrollBarAutoVisible( false, true );
m_pScrollPanel->setScrollBarVisible( false, false );
m_pScrollPanel->validate();
// Create the Class buttons
#ifdef _TFC
for( int i = 0; i <= PC_RANDOM; i++ )
{
char sz[256];
int iYPos = CLASSMENU_TOPLEFT_BUTTON_Y + ( ( CLASSMENU_BUTTON_SIZE_Y + CLASSMENU_BUTTON_SPACER_Y ) * i );
ActionSignal *pASignal = new CMenuHandler_StringCommandClassSelect( sTFClassSelection[i], true );
// Class button
sprintf( sz, "%s", CHudTextMessage::BufferedLocaliseTextString( sLocalisedClasses[i] ) );
m_pButtons[i] = new ClassButton( i, sz, CLASSMENU_TOPLEFT_BUTTON_X, iYPos, CLASSMENU_BUTTON_SIZE_X, CLASSMENU_BUTTON_SIZE_Y, true );
// RandomPC uses '0'
if( i >= 1 && i <= 9 )
{
sprintf( sz, "%d", i );
}
else
{
strcpy( sz, "0" );
}
m_pButtons[i]->setBoundKey( sz[0] );
m_pButtons[i]->setContentAlignment( vgui::Label::a_west );
m_pButtons[i]->addActionSignal( pASignal );
m_pButtons[i]->addInputSignal( new CHandler_MenuButtonOver(this, i) );
m_pButtons[i]->setParent( this );
// Create the Class Info Window
// m_pClassInfoPanel[i] = new CTransparentPanel( 255, CLASSMENU_WINDOW_X, CLASSMENU_WINDOW_Y, CLASSMENU_WINDOW_SIZE_X, CLASSMENU_WINDOW_SIZE_Y );
m_pClassInfoPanel[i] = new CTransparentPanel( 255, 0, 0, clientWide, CLASSMENU_WINDOW_SIZE_Y );
m_pClassInfoPanel[i]->setParent( m_pScrollPanel->getClient() );
// m_pClassInfoPanel[i]->setVisible( false );
// don't show class pic in lower resolutions
int textOffs = XRES( 8 );
if( bShowClassGraphic )
{
textOffs = CLASSMENU_WINDOW_NAME_X;
}
// Create the Class Name Label
sprintf( sz, "#Title_%s", sTFClassSelection[i] );
char *localName=CHudTextMessage::BufferedLocaliseTextString( sz );
Label *pNameLabel = new Label( "", textOffs, CLASSMENU_WINDOW_NAME_Y );
pNameLabel->setFont( pSchemes->getFont( hTitleScheme ) );
pNameLabel->setParent( m_pClassInfoPanel[i] );
pSchemes->getFgColor( hTitleScheme, r, g, b, a );
pNameLabel->setFgColor( r, g, b, a );
pSchemes->getBgColor( hTitleScheme, r, g, b, a );
pNameLabel->setBgColor( r, g, b, a );
pNameLabel->setContentAlignment( vgui::Label::a_west );
// pNameLabel->setBorder( new LineBorder() );
pNameLabel->setText( "%s", localName);
// Create the Class Image
if( bShowClassGraphic )
{
for( int team = 0; team < 2; team++ )
{
if( team == 1 )
{
sprintf( sz, "%sred", sTFClassSelection[i] );
}
else
{
sprintf( sz, "%sblue", sTFClassSelection[i] );
}
m_pClassImages[team][i] = new CImageLabel( sz, 0, 0, CLASSMENU_WINDOW_TEXT_X, CLASSMENU_WINDOW_TEXT_Y );
CImageLabel *pLabel = m_pClassImages[team][i];
pLabel->setParent( m_pClassInfoPanel[i] );
// pLabel->setBorder( new LineBorder() );
if( team != 1 )
{
pLabel->setVisible( false );
}
// Reposition it based upon it's size
int xOut, yOut;
pNameLabel->getTextSize( xOut, yOut );
pLabel->setPos( ( CLASSMENU_WINDOW_TEXT_X - pLabel->getWide() ) / 2, yOut / 2 );
}
}
// Create the Player count string
gHUD.m_TextMessage.LocaliseTextString( "#Title_CurrentlyOnYourTeam", m_sPlayersOnTeamString, STRLENMAX_PLAYERSONTEAM );
m_pPlayers[i] = new Label( "", textOffs, CLASSMENU_WINDOW_PLAYERS_Y );
m_pPlayers[i]->setParent( m_pClassInfoPanel[i] );
m_pPlayers[i]->setBgColor( 0, 0, 0, 255 );
m_pPlayers[i]->setContentAlignment( vgui::Label::a_west );
m_pPlayers[i]->setFont( pSchemes->getFont( hClassWindowText ) );
// Open up the Class Briefing File
sprintf(sz, "classes/short_%s.txt", sTFClassSelection[i]);
char *cText = "Class Description not available.";
char *pfile = (char *)gEngfuncs.COM_LoadFile( sz, 5, NULL );
if( pfile )
{
cText = pfile;
}
// Create the Text info window
TextPanel *pTextWindow = new TextPanel( cText, textOffs, CLASSMENU_WINDOW_TEXT_Y, ( CLASSMENU_WINDOW_SIZE_X - textOffs ) - 5, CLASSMENU_WINDOW_SIZE_Y - CLASSMENU_WINDOW_TEXT_Y );
pTextWindow->setParent( m_pClassInfoPanel[i] );
pTextWindow->setFont( pSchemes->getFont( hClassWindowText ) );
pSchemes->getFgColor( hClassWindowText, r, g, b, a );
pTextWindow->setFgColor( r, g, b, a );
pSchemes->getBgColor( hClassWindowText, r, g, b, a );
pTextWindow->setBgColor( r, g, b, a );
// Resize the Info panel to fit it all
int wide,tall;
pTextWindow->getTextImage()->getTextSizeWrapped( wide, tall );
pTextWindow->setSize( wide, tall );
int xx, yy;
pTextWindow->getPos( xx, yy );
int maxX = xx + wide;
int maxY = yy + tall;
//check to see if the image goes lower than the text
//just use the red teams [0] images
if( m_pClassImages[0][i] != null )
{
m_pClassImages[0][i]->getPos( xx, yy );
if( ( yy + m_pClassImages[0][i]->getTall() ) > maxY )
{
maxY = yy + m_pClassImages[0][i]->getTall();
}
}
m_pClassInfoPanel[i]->setSize( maxX , maxY );
if( pfile )
gEngfuncs.COM_FreeFile( pfile );
// m_pClassInfoPanel[i]->setBorder( new LineBorder() );
}
#endif
// Create the Cancel button
m_pCancelButton = new CommandButton( gHUD.m_TextMessage.BufferedLocaliseTextString( "#Menu_Cancel" ), CLASSMENU_TOPLEFT_BUTTON_X, 0, CLASSMENU_BUTTON_SIZE_X, CLASSMENU_BUTTON_SIZE_Y );
m_pCancelButton->setParent( this );
m_pCancelButton->addActionSignal( new CMenuHandler_TextWindow( HIDE_TEXTWINDOW ) );
m_iCurrentInfo = 0;
}
// Update
void CClassMenuPanel::Update()
{
// Don't allow the player to join a team if they're not in a team
if( !g_iTeamNumber )
return;
int iYPos = CLASSMENU_TOPLEFT_BUTTON_Y;
// Cycle through the rest of the buttons
#ifdef _TFC
for( int i = 0; i <= PC_RANDOM; i++ )
{
bool bCivilian = ( gViewPort->GetValidClasses( g_iTeamNumber ) == -1 );
if( bCivilian )
{
// If this team can only be civilians, only the civilian button's visible
if( i == 0 )
{
m_pButtons[0]->setVisible( true );
SetActiveInfo( 0 );
iYPos += CLASSMENU_BUTTON_SIZE_Y + CLASSMENU_BUTTON_SPACER_Y;
}
else
{
m_pButtons[i]->setVisible( false );
}
}
else
{
if( m_pButtons[i]->IsNotValid() || i == 0 )
{
m_pButtons[i]->setVisible( false );
}
else
{
m_pButtons[i]->setVisible( true );
m_pButtons[i]->setPos( CLASSMENU_TOPLEFT_BUTTON_X, iYPos );
iYPos += CLASSMENU_BUTTON_SIZE_Y + CLASSMENU_BUTTON_SPACER_Y;
// Start with the first option up
if( !m_iCurrentInfo )
SetActiveInfo( i );
}
}
// Now count the number of teammembers of this class
int iTotal = 0;
for( int j = 1; j < MAX_PLAYERS; j++ )
{
if( g_PlayerInfoList[j].name == 0 )
continue; // empty player slot, skip
if( g_PlayerExtraInfo[j].teamname[0] == 0 )
continue; // skip over players who are not in a team
if( g_PlayerInfoList[j].thisplayer )
continue; // skip this player
if( g_PlayerExtraInfo[j].teamnumber != g_iTeamNumber )
continue; // skip over players in other teams
// If this team is forced to be civilians, just count the number of teammates
if( g_PlayerExtraInfo[j].playerclass != i && !bCivilian )
continue;
iTotal++;
}
char sz[256];
sprintf( sz, m_sPlayersOnTeamString, iTotal );
m_pPlayers[i]->setText( "%s", sz );
// Set the text color to the teamcolor
m_pPlayers[i]->setFgColor( iTeamColors[g_iTeamNumber % iNumberOfTeamColors][0],
iTeamColors[g_iTeamNumber % iNumberOfTeamColors][1],
iTeamColors[g_iTeamNumber % iNumberOfTeamColors][2],
0 );
// set the graphic to be the team pick
for( int team = 0; team < MAX_TEAMS; team++ )
{
// unset all the other images
if( m_pClassImages[team][i] )
{
m_pClassImages[team][i]->setVisible( false );
}
// set the current team image
if( m_pClassImages[g_iTeamNumber - 1][i] != 0 )
{
m_pClassImages[g_iTeamNumber - 1][i]->setVisible( true );
}
else if( m_pClassImages[0][i] )
{
m_pClassImages[0][i]->setVisible( true );
}
}
}
#endif
// If the player already has a class, make the cancel button visible
if( g_iPlayerClass )
{
m_pCancelButton->setPos( CLASSMENU_TOPLEFT_BUTTON_X, iYPos );
m_pCancelButton->setVisible( true );
}
else
{
m_pCancelButton->setVisible( false );
}
}
//======================================
// Key inputs for the Class Menu
bool CClassMenuPanel::SlotInput( int iSlot )
{
if( ( iSlot < 0 ) || ( iSlot > 9 ) )
return false;
if( !m_pButtons[iSlot] )
return false;
// Is the button pushable? (0 is special case)
if( iSlot == 0 )
{
// Selects Civilian and RandomPC
if( gViewPort->GetValidClasses( g_iTeamNumber ) == -1 )
{
m_pButtons[0]->fireActionSignal();
return true;
}
// Select RandomPC
iSlot = 10;
}
if( !( m_pButtons[iSlot]->IsNotValid() ) )
{
m_pButtons[iSlot]->fireActionSignal();
return true;
}
return false;
}
//======================================
// Update the Class menu before opening it
void CClassMenuPanel::Open( void )
{
Update();
CMenuPanel::Open();
}
//-----------------------------------------------------------------------------
// Purpose: Called each time a new level is started.
//-----------------------------------------------------------------------------
void CClassMenuPanel::Initialize( void )
{
setVisible( false );
m_pScrollPanel->setScrollValue( 0, 0 );
}
//======================================
// Mouse is over a class button, bring up the class info
void CClassMenuPanel::SetActiveInfo( int iInput )
{
// Remove all the Info panels and bring up the specified one
#ifdef _TFC
for( int i = 0; i <= PC_RANDOM; i++ )
{
m_pButtons[i]->setArmed( false );
m_pClassInfoPanel[i]->setVisible( false );
}
if( iInput > PC_RANDOM || iInput < 0 )
#endif
iInput = 0;
m_pButtons[iInput]->setArmed( true );
m_pClassInfoPanel[iInput]->setVisible( true );
m_iCurrentInfo = iInput;
m_pScrollPanel->setScrollValue( 0, 0 );
m_pScrollPanel->validate();
}

View File

@ -0,0 +1,97 @@
//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "vgui_ConsolePanel.h"
#include "hud.h"
#include <VGUI_ActionSignal.h>
#include <VGUI_TextGrid.h>
#include <VGUI_TextEntry.h>
#include <VGUI_EtchedBorder.h>
#include <VGUI_LoweredBorder.h>
using namespace vgui;
namespace
{
class Handler : public ActionSignal
{
private:
ConsolePanel *_consolePanel;
public:
Handler( ConsolePanel *consolePanel )
{
_consolePanel = consolePanel;
}
public:
virtual void actionPerformed( Panel *panel )
{
_consolePanel->doExecCommand();
}
};
}
ConsolePanel::ConsolePanel( int x, int y, int wide, int tall ) : Panel( x, y, wide, tall )
{
setBorder( new EtchedBorder() );
_textGrid = new TextGrid( 80, 21, 5, 5, 200, 100 );
_textGrid->setBorder( new LoweredBorder() );
_textGrid->setParent( this );
_textEntry=new TextEntry( "", 5, 5, 200, 20 );
_textEntry->setParent( this );
_textEntry->addActionSignal( new Handler( this ) );
}
int ConsolePanel::print( const char *text )
{
return _textGrid->printf( "%s", text );
}
int ConsolePanel::vprintf( const char *format, va_list argList )
{
return _textGrid->vprintf( format, argList );
}
int ConsolePanel::printf( const char* format, ... )
{
va_list argList;
va_start( argList, format );
int ret = vprintf( format, argList );
va_end( argList );
return ret;
}
void ConsolePanel::doExecCommand()
{
char buf[2048];
_textEntry->getText( 0, buf, sizeof buf );
_textEntry->setText( null, 0 );
gEngfuncs.pfnClientCmd( buf );
}
void ConsolePanel::setSize( int wide, int tall )
{
Panel::setSize( wide, tall );
getPaintSize( wide, tall );
_textGrid->setBounds( 5, 5, wide - 10, tall - 35 );
_textEntry->setBounds( 5, tall - 25, wide - 10, 20 );
}

View File

@ -0,0 +1,37 @@
//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef CONSOLEPANEL_H
#define CONSOLEPANEL_H
#include <stdarg.h>
#include <VGUI_Panel.h>
namespace vgui
{
class TextGrid;
class TextEntry;
}
class ConsolePanel : public vgui::Panel
{
private:
vgui::TextGrid *_textGrid;
vgui::TextEntry *_textEntry;
public:
ConsolePanel( int x, int y, int wide, int tall );
public:
virtual void setSize( int wide, int tall );
virtual int print( const char *text );
virtual int vprintf( const char *format, va_list argList );
virtual int printf( const char *format, ... );
virtual void doExecCommand();
};
#endif

View File

@ -0,0 +1,216 @@
//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include <stdio.h>
#include "vgui_ControlConfigPanel.h"
#include <VGUI_HeaderPanel.h>
#include <VGUI_TablePanel.h>
#include <VGUI_Label.h>
#include <VGUI_ScrollPanel.h>
#include <VGUI_Scheme.h>
#include <VGUI_DataInputStream.h>
#include <VGUI.h>
#include <VGUI_TextEntry.h>
using namespace vgui;
namespace
{
class FooTablePanel : public TablePanel
{
private:
Label *_label;
TextEntry *_textEntry;
ControlConfigPanel *_controlConfigPanel;
public:
FooTablePanel( ControlConfigPanel *controlConfigPanel, int x, int y, int wide, int tall, int columnCount ) : TablePanel( x, y, wide, tall, columnCount )
{
_controlConfigPanel = controlConfigPanel;
_label = new Label( "You are a dumb monkey", 0, 0, 100, 20 );
_label->setBgColor( Scheme::sc_primary3 );
_label->setFgColor( Scheme::sc_primary1 );
_label->setFont( Scheme::sf_primary3 );
_textEntry=new TextEntry( "", 0, 0, 100, 20 );
// _textEntry->setFont( Scheme::sf_primary3 );
}
public:
virtual int getRowCount()
{
return _controlConfigPanel->GetCVarCount();
}
virtual int getCellTall( int row )
{
return 12;
}
virtual Panel *getCellRenderer( int column, int row,bool columnSelected, bool rowSelected, bool cellSelected )
{
char cvar[128], desc[128], bind[128], bindAlt[128];
_controlConfigPanel->GetCVar( row, cvar, 128, desc, 128 );
if( cellSelected )
{
_label->setBgColor( Scheme::sc_primary1 );
_label->setFgColor( Scheme::sc_primary3 );
}
else if( rowSelected )
{
_label->setBgColor( Scheme::sc_primary2 );
_label->setFgColor( Scheme::sc_primary1 );
}
else
{
_label->setBgColor( Scheme::sc_primary3 );
_label->setFgColor( Scheme::sc_primary1 );
}
switch( column )
{
case 0:
{
_label->setText( desc );
_label->setContentAlignment( Label::a_west );
break;
}
case 1:
{
_controlConfigPanel->GetCVarBind( cvar, bind, 128, bindAlt, 128 );
_label->setText( bind );
_label->setContentAlignment( Label::a_center );
break;
}
case 2:
{
_controlConfigPanel->GetCVarBind( cvar, bind, 128, bindAlt, 128 );
_label->setText( bindAlt );
_label->setContentAlignment( Label::a_center );
break;
}
default:
{
_label->setText( "" );
break;
}
}
return _label;
}
virtual Panel *startCellEditing( int column, int row )
{
_textEntry->setText( "Goat", strlen( "Goat" ) );
_textEntry->requestFocus();
return _textEntry;
}
};
}
ControlConfigPanel::ControlConfigPanel( int x, int y, int wide, int tall ) : Panel( x, y, wide, tall )
{
setPaintBorderEnabled( false );
setPaintBackgroundEnabled( false );
setPaintEnabled( false );
_actionLabel = new Label( "Action" );
_actionLabel->setBgColor( Scheme::sc_primary3 );
_actionLabel->setFgColor( Scheme::sc_primary3 );
_keyButtonLabel = new Label( "Key / Button" );
_keyButtonLabel->setBgColor( Scheme::sc_primary3 );
_keyButtonLabel->setFgColor( Scheme::sc_primary3 );
_alternateLabel = new Label( "Alternate" );
_alternateLabel->setBgColor( Scheme::sc_primary3 );
_alternateLabel->setFgColor( Scheme::sc_primary3 );
_headerPanel=new HeaderPanel( 0, 0, wide, 20 );
_headerPanel->setParent( this );
_headerPanel->addSectionPanel( _actionLabel );
_headerPanel->addSectionPanel( _keyButtonLabel );
_headerPanel->addSectionPanel( _alternateLabel );
_headerPanel->setSliderPos( 0, wide / 2 );
_headerPanel->setSliderPos( 1, ( wide / 2 ) + ( wide / 4 ) );
_headerPanel->setSliderPos( 2, wide );
_scrollPanel=new ScrollPanel( 0, 20, wide, tall - 20 );
_scrollPanel->setParent( this );
_scrollPanel->setPaintBorderEnabled( false );
_scrollPanel->setPaintBackgroundEnabled( false );
_scrollPanel->setPaintEnabled( false );
_scrollPanel->getClient()->setPaintBorderEnabled( false );
_scrollPanel->getClient()->setPaintBackgroundEnabled( false );
_scrollPanel->getClient()->setPaintEnabled( false );
_scrollPanel->setScrollBarVisible( false, true );
_tablePanel = new FooTablePanel( this, 0, 0, _scrollPanel->getClient()->getWide(), 800, 3 );
_tablePanel->setParent( _scrollPanel->getClient() );
_tablePanel->setHeaderPanel( _headerPanel );
_tablePanel->setBgColor( Color( 200, 0, 0, 255 ) );
_tablePanel->setFgColor( Color( Scheme::sc_primary2 ) );
_tablePanel->setGridVisible( true, true );
_tablePanel->setGridSize( 1, 1 );
}
void ControlConfigPanel::AddCVar( const char *cvar, const char *desc )
{
_cvarDar.addElement( vgui_strdup( cvar ) );
_descDar.addElement( vgui_strdup( desc ) );
}
int ControlConfigPanel::GetCVarCount()
{
return _cvarDar.getCount();
}
void ControlConfigPanel::GetCVar( int index, char *cvar, int cvarLen, char *desc, int descLen )
{
vgui_strcpy( cvar, cvarLen, _cvarDar[index] );
vgui_strcpy( desc, descLen, _descDar[index] );
}
void ControlConfigPanel::AddCVarFromInputStream( InputStream *is )
{
if( is == null )
{
return;
}
DataInputStream dis( is );
bool success;
while( 1 )
{
char buf[256], cvar[128], desc[128];
dis.readLine( buf, 256, success );
if( !success )
{
break;
}
if( sscanf( buf, "\"%[^\"]\" \"%[^\"]\"", cvar, desc ) == 2 )
{
AddCVar( cvar, desc );
}
}
}
void ControlConfigPanel::GetCVarBind( const char *cvar, char *bind, int bindLen, char *bindAlt, int bindAltLen )
{
sprintf( bind,"%s : Bind", cvar );
sprintf( bindAlt,"%s : BindAlt", cvar );
}
void ControlConfigPanel::SetCVarBind( const char *cvar, const char *bind, const char *bindAlt )
{
}

View File

@ -0,0 +1,43 @@
//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef CONTROLCONFIGPANEL_H
#define CONTROLCONFIGPANEL_H
#include <VGUI_Panel.h>
#include <VGUI_Dar.h>
namespace vgui
{
class HeaderPanel;
class TablePanel;
class ScrollPanel;
class InputStream;
class Label;
}
class ControlConfigPanel : public vgui::Panel
{
private:
vgui::HeaderPanel *_headerPanel;
vgui::TablePanel *_tablePanel;
vgui::ScrollPanel *_scrollPanel;
vgui::Dar<char*> _cvarDar;
vgui::Dar<char*> _descDar;
vgui::Label *_actionLabel;
vgui::Label *_keyButtonLabel;
vgui::Label *_alternateLabel;
public:
ControlConfigPanel( int x, int y, int wide, int tall );
void AddCVar( const char *cvar, const char *desc );
void AddCVarFromInputStream( vgui::InputStream *is );
int GetCVarCount();
void GetCVar( int index, char *cvar, int cvarLen, char *desc, int descLen );
void GetCVarBind( const char *cvar, char *bind, int bindLen, char *bindAlt, int bindAltLen );
void SetCVarBind( const char *cvar, const char *bind, const char *bindAlt );
};
#endif

View File

@ -0,0 +1,551 @@
//=========== (C) Copyright 1996-2002 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// Purpose: Contains implementation of various VGUI-derived objects
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================
#include "VGUI_Font.h"
#include "hud.h"
#include "cl_util.h"
#include "camera.h"
#include "kbutton.h"
#include "cvardef.h"
#include "usercmd.h"
#include "const.h"
#include "camera.h"
#include "in_defs.h"
#include "parsemsg.h"
#include "vgui_int.h"
#include "vgui_TeamFortressViewport.h"
#include "vgui_loadtga.h"
// Arrow filenames
const char *sArrowFilenames[] =
{
"arrowup",
"arrowdn",
"arrowlt",
"arrowrt",
};
// Get the name of TGA file, without a gamedir
char *GetTGANameForRes( const char *pszName )
{
int i;
char sz[256];
static char gd[256];
if( ScreenWidth < 640 )
i = 320;
else
i = 640;
sprintf( sz, pszName, i );
sprintf( gd, "gfx/vgui/%s.tga", sz );
return gd;
}
//-----------------------------------------------------------------------------
// Purpose: Loads a .tga file and returns a pointer to the VGUI tga object
//-----------------------------------------------------------------------------
BitmapTGA *LoadTGAForRes( const char* pImageName )
{
BitmapTGA *pTGA;
char sz[256];
sprintf( sz, "%%d_%s", pImageName );
pTGA = vgui_LoadTGA( GetTGANameForRes( sz ) );
return pTGA;
}
//===========================================================
// All TFC Hud buttons are derived from this one.
CommandButton::CommandButton( const char *text, int x, int y, int wide, int tall, bool bNoHighlight ) : Button( "", x, y, wide, tall )
{
m_iPlayerClass = 0;
m_bNoHighlight = bNoHighlight;
m_bFlat = false;
Init();
setText( text );
}
CommandButton::CommandButton( int iPlayerClass, const char *text, int x, int y, int wide, int tall, bool bFlat ) : Button( "", x, y, wide, tall )
{
m_iPlayerClass = iPlayerClass;
m_bNoHighlight = false;
m_bFlat = bFlat;
Init();
setText( text );
}
CommandButton::CommandButton( const char *text, int x, int y, int wide, int tall, bool bNoHighlight, bool bFlat ) : Button( "", x, y, wide, tall )
{
m_iPlayerClass = 0;
m_bFlat = bFlat;
m_bNoHighlight = bNoHighlight;
Init();
setText( text );
}
void CommandButton::Init( void )
{
m_pSubMenu = NULL;
m_pSubLabel = NULL;
m_pParentMenu = NULL;
// Set text color to orange
setFgColor( Scheme::sc_primary1 );
// left align
setContentAlignment( vgui::Label::a_west );
// Add the Highlight signal
if( !m_bNoHighlight )
addInputSignal( new CHandler_CommandButtonHighlight( this ) );
// not bound to any button yet
m_cBoundKey = 0;
}
//-----------------------------------------------------------------------------
// Purpose: Prepends the button text with the current bound key
// if no bound key, then a clear space ' ' instead
//-----------------------------------------------------------------------------
void CommandButton::RecalculateText( void )
{
char szBuf[128];
if( m_cBoundKey != 0 )
{
if( m_cBoundKey == (char)255 )
{
strcpy( szBuf, m_sMainText );
}
else
{
sprintf( szBuf, " %c %s", m_cBoundKey, m_sMainText );
}
szBuf[MAX_BUTTON_SIZE-1] = 0;
}
else
{
// just draw a space if no key bound
sprintf( szBuf, " %s", m_sMainText );
szBuf[MAX_BUTTON_SIZE - 1] = 0;
}
Button::setText( szBuf );
}
void CommandButton::setText( const char *text )
{
strncpy( m_sMainText, text, MAX_BUTTON_SIZE );
m_sMainText[MAX_BUTTON_SIZE - 1] = 0;
RecalculateText();
}
void CommandButton::setBoundKey( char boundKey )
{
m_cBoundKey = boundKey;
RecalculateText();
}
char CommandButton::getBoundKey( void )
{
return m_cBoundKey;
}
void CommandButton::AddSubMenu( CCommandMenu *pNewMenu )
{
m_pSubMenu = pNewMenu;
// Prevent this button from being pushed
setMouseClickEnabled( MOUSE_LEFT, false );
}
void CommandButton::UpdateSubMenus( int iAdjustment )
{
if( m_pSubMenu )
m_pSubMenu->RecalculatePositions( iAdjustment );
}
void CommandButton::paint()
{
// Make the sub label paint the same as the button
if( m_pSubLabel )
{
if( isSelected() )
m_pSubLabel->PushDown();
else
m_pSubLabel->PushUp();
}
// draw armed button text in white
if( isArmed() )
{
setFgColor( Scheme::sc_secondary2 );
}
else
{
setFgColor( Scheme::sc_primary1 );
}
Button::paint();
}
void CommandButton::paintBackground()
{
if( m_bFlat )
{
if( isArmed() )
{
// Orange Border
drawSetColor( Scheme::sc_secondary1 );
drawOutlinedRect( 0, 0, _size[0], _size[1] );
}
}
else
{
if( isArmed() )
{
// Orange highlight background
drawSetColor( Scheme::sc_primary2 );
drawFilledRect( 0, 0, _size[0], _size[1] );
}
// Orange Border
drawSetColor( Scheme::sc_secondary1 );
drawOutlinedRect( 0, 0, _size[0], _size[1] );
}
}
//-----------------------------------------------------------------------------
// Purpose: Highlights the current button, and all it's parent menus
//-----------------------------------------------------------------------------
void CommandButton::cursorEntered( void )
{
// unarm all the other buttons in this menu
CCommandMenu *containingMenu = getParentMenu();
if( containingMenu )
{
containingMenu->ClearButtonsOfArmedState();
// make all our higher buttons armed
CCommandMenu *pCParent = containingMenu->GetParentMenu();
if( pCParent )
{
CommandButton *pParentButton = pCParent->FindButtonWithSubmenu( containingMenu );
pParentButton->cursorEntered();
}
}
// arm ourselves
setArmed( true );
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CommandButton::cursorExited( void )
{
// only clear ourselves if we have do not have a containing menu
// only stay armed if we have a sub menu
// the buttons only unarm themselves when another button is armed instead
if( !getParentMenu() || !GetSubMenu() )
{
setArmed( false );
}
}
//-----------------------------------------------------------------------------
// Purpose: Returns the command menu that the button is part of, if any
// Output : CCommandMenu *
//-----------------------------------------------------------------------------
CCommandMenu *CommandButton::getParentMenu( void )
{
return m_pParentMenu;
}
//-----------------------------------------------------------------------------
// Purpose: Sets the menu that contains this button
// Input : *pParentMenu -
//-----------------------------------------------------------------------------
void CommandButton::setParentMenu( CCommandMenu *pParentMenu )
{
m_pParentMenu = pParentMenu;
}
//===========================================================
int ClassButton::IsNotValid()
{
// If this is the main ChangeClass button, remove it if the player's only able to be civilians
if( m_iPlayerClass == -1 )
{
if( gViewPort->GetValidClasses( g_iTeamNumber ) == -1 )
return true;
return false;
}
// Is it an illegal class?
#ifdef _TFC
if( ( gViewPort->GetValidClasses( 0 ) & sTFValidClassInts[m_iPlayerClass] ) || ( gViewPort->GetValidClasses( g_iTeamNumber ) & sTFValidClassInts[m_iPlayerClass] ) )
return true;
#endif
// Only check current class if they've got autokill on
bool bAutoKill = CVAR_GET_FLOAT( "hud_classautokill" ) != 0;
if( bAutoKill )
{
// Is it the player's current class?
if (
#ifdef _TFC
(gViewPort->IsRandomPC() && m_iPlayerClass == PC_RANDOM) ||
#endif
(!gViewPort->IsRandomPC() && (m_iPlayerClass == g_iPlayerClass)) )
return true;
}
return false;
}
//===========================================================
// Button with Class image beneath it
CImageLabel::CImageLabel( const char *pImageName,int x,int y ) : Label( "", x, y )
{
setContentFitted( true );
m_pTGA = LoadTGAForRes( pImageName );
setImage( m_pTGA );
}
CImageLabel::CImageLabel( const char *pImageName, int x, int y, int wide, int tall ) : Label( "", x, y, wide, tall )
{
setContentFitted( true );
m_pTGA = LoadTGAForRes( pImageName );
setImage( m_pTGA );
}
//===========================================================
// Image size
int CImageLabel::getImageWide( void )
{
if( m_pTGA )
{
int iXSize, iYSize;
m_pTGA->getSize( iXSize, iYSize );
return iXSize;
}
else
{
return 1;
}
}
int CImageLabel::getImageTall( void )
{
if( m_pTGA )
{
int iXSize, iYSize;
m_pTGA->getSize( iXSize, iYSize );
return iYSize;
}
else
{
return 1;
}
}
void CImageLabel::LoadImage( const char *pImageName )
{
if( m_pTGA )
delete m_pTGA;
// Load the Image
m_pTGA = LoadTGAForRes( pImageName );
if( m_pTGA == NULL )
{
// we didn't find a matching image file for this resolution
// try to load file resolution independent
char sz[256];
sprintf( sz, "%s/%s", gEngfuncs.pfnGetGameDirectory(), pImageName );
FileInputStream fis( sz, false );
m_pTGA = new BitmapTGA( &fis, true );
fis.close();
}
if( m_pTGA == NULL )
return; // unable to load image
int w,t;
m_pTGA->getSize( w, t );
setSize( XRES ( w ),YRES ( t) );
setImage( m_pTGA );
}
//===========================================================
// Various overloaded paint functions for Custom VGUI objects
void CCommandMenu::paintBackground()
{
// Transparent black background
if( m_iSpectCmdMenu )
drawSetColor( 0, 0, 0, 64 );
else
drawSetColor( Scheme::sc_primary3 );
drawFilledRect( 0, 0, _size[0], _size[1] );
}
//=================================================================================
// CUSTOM SCROLLPANEL
//=================================================================================
CTFScrollButton::CTFScrollButton( int iArrow, const char *text, int x, int y, int wide, int tall ) : CommandButton( text, x, y, wide, tall )
{
// Set text color to orange
setFgColor( Scheme::sc_primary1 );
// Load in the arrow
m_pTGA = LoadTGAForRes( sArrowFilenames[iArrow] );
setImage( m_pTGA );
// Highlight signal
InputSignal *pISignal = new CHandler_CommandButtonHighlight( this );
addInputSignal( pISignal );
}
void CTFScrollButton::paint( void )
{
if( !m_pTGA )
return;
// draw armed button text in white
if( isArmed() )
{
m_pTGA->setColor( Color( 255, 255, 255, 0 ) );
}
else
{
m_pTGA->setColor( Color( 255, 255, 255, 128 ) );
}
m_pTGA->doPaint( this );
}
void CTFScrollButton::paintBackground( void )
{
/*
if( isArmed() )
{
// Orange highlight background
drawSetColor( Scheme::sc_primary2 );
drawFilledRect( 0, 0, _size[0], _size[1] );
}
// Orange Border
drawSetColor( Scheme::sc_secondary1 );
drawOutlinedRect( 0, 0, _size[0] - 1, _size[1] );
*/
}
void CTFSlider::paintBackground( void )
{
int wide, tall, nobx, noby;
getPaintSize( wide, tall );
getNobPos( nobx, noby );
// Border
drawSetColor( Scheme::sc_secondary1 );
drawOutlinedRect( 0, 0, wide, tall );
if( isVertical() )
{
// Nob Fill
drawSetColor( Scheme::sc_primary2 );
drawFilledRect( 0, nobx, wide, noby );
// Nob Outline
drawSetColor( Scheme::sc_primary1 );
drawOutlinedRect( 0, nobx, wide, noby );
}
else
{
// Nob Fill
drawSetColor( Scheme::sc_primary2 );
drawFilledRect( nobx, 0, noby, tall );
// Nob Outline
drawSetColor( Scheme::sc_primary1 );
drawOutlinedRect( nobx, 0, noby, tall );
}
}
CTFScrollPanel::CTFScrollPanel( int x, int y, int wide, int tall ) : ScrollPanel( x, y, wide, tall )
{
ScrollBar *pScrollBar = getVerticalScrollBar();
pScrollBar->setButton( new CTFScrollButton( ARROW_UP, "", 0, 0, 16, 16 ), 0 );
pScrollBar->setButton( new CTFScrollButton( ARROW_DOWN, "", 0, 0, 16, 16 ), 1 );
pScrollBar->setSlider( new CTFSlider( 0, wide - 1, wide, ( tall - ( wide * 2 ) ) + 2, true ) );
pScrollBar->setPaintBorderEnabled( false );
pScrollBar->setPaintBackgroundEnabled( false );
pScrollBar->setPaintEnabled( false );
pScrollBar = getHorizontalScrollBar();
pScrollBar->setButton( new CTFScrollButton( ARROW_LEFT, "", 0, 0, 16, 16 ), 0 );
pScrollBar->setButton( new CTFScrollButton( ARROW_RIGHT, "", 0, 0, 16, 16 ), 1 );
pScrollBar->setSlider( new CTFSlider( tall, 0, wide - ( tall * 2 ), tall, false ) );
pScrollBar->setPaintBorderEnabled( false );
pScrollBar->setPaintBackgroundEnabled( false );
pScrollBar->setPaintEnabled( false );
}
//=================================================================================
// CUSTOM HANDLERS
//=================================================================================
void CHandler_MenuButtonOver::cursorEntered(Panel *panel)
{
if( gViewPort && m_pMenuPanel )
{
m_pMenuPanel->SetActiveInfo( m_iButton );
}
}
void CMenuHandler_StringCommandClassSelect::actionPerformed( Panel *panel )
{
CMenuHandler_StringCommand::actionPerformed( panel );
// THIS IS NOW BEING DONE ON THE TFC SERVER TO AVOID KILLING SOMEONE THEN
// HAVE THE SERVER SAY "SORRY...YOU CAN'T BE THAT CLASS".
#if !defined _TFC
bool bAutoKill = CVAR_GET_FLOAT( "hud_classautokill" ) != 0;
if( bAutoKill && g_iPlayerClass != 0 )
gEngfuncs.pfnClientCmd( "kill" );
#endif
}

151
cl_dll/vgui_MOTDWindow.cpp Normal file
View File

@ -0,0 +1,151 @@
//=========== (C) Copyright 1996-2002 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// Purpose:
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================
#include "VGUI_Font.h"
#include "VGUI_ScrollPanel.h"
#include "VGUI_TextImage.h"
#include <VGUI_StackLayout.h>
#include "hud.h"
#include "cl_util.h"
#include "camera.h"
#include "kbutton.h"
#include "const.h"
#include "vgui_int.h"
#include "vgui_TeamFortressViewport.h"
#define MOTD_TITLE_X XRES(16)
#define MOTD_TITLE_Y YRES(16)
#define MOTD_WINDOW_X XRES(112)
#define MOTD_WINDOW_Y YRES(80)
#define MOTD_WINDOW_SIZE_X XRES(424)
#define MOTD_WINDOW_SIZE_Y YRES(312)
//-----------------------------------------------------------------------------
// Purpose: Displays the MOTD and basic server information
//-----------------------------------------------------------------------------
class CMessageWindowPanel : public CMenuPanel
{
public:
CMessageWindowPanel( const char *szMOTD, const char *szTitle, int iShadeFullScreen, int iRemoveMe, int x, int y, int wide, int tall );
private:
CTransparentPanel *m_pBackgroundPanel;
};
//-----------------------------------------------------------------------------
// Purpose: Creates a new CMessageWindowPanel
// Output : CMenuPanel - interface to the panel
//-----------------------------------------------------------------------------
CMenuPanel *CMessageWindowPanel_Create( const char *szMOTD, const char *szTitle, int iShadeFullscreen, int iRemoveMe, int x, int y, int wide, int tall )
{
return new CMessageWindowPanel( szMOTD, szTitle, iShadeFullscreen, iRemoveMe, x, y, wide, tall );
}
//-----------------------------------------------------------------------------
// Purpose: Constructs a message panel
//-----------------------------------------------------------------------------
CMessageWindowPanel::CMessageWindowPanel( const char *szMOTD, const char *szTitle, int iShadeFullscreen, int iRemoveMe, int x, int y, int wide, int tall ) : CMenuPanel( iShadeFullscreen ? 100 : 255, iRemoveMe, x, y, wide, tall )
{
// Get the scheme used for the Titles
CSchemeManager *pSchemes = gViewPort->GetSchemeManager();
// schemes
SchemeHandle_t hTitleScheme = pSchemes->getSchemeHandle( "Title Font" );
SchemeHandle_t hMOTDText = pSchemes->getSchemeHandle( "Briefing Text" );
// color schemes
int r, g, b, a;
// Create the window
m_pBackgroundPanel = new CTransparentPanel( iShadeFullscreen ? 255 : 100, MOTD_WINDOW_X, MOTD_WINDOW_Y, MOTD_WINDOW_SIZE_X, MOTD_WINDOW_SIZE_Y );
m_pBackgroundPanel->setParent( this );
m_pBackgroundPanel->setBorder( new LineBorder( Color( 255 * 0.7, 170 * 0.7, 0, 0 ) ) );
m_pBackgroundPanel->setVisible( true );
int iXSize,iYSize,iXPos,iYPos;
m_pBackgroundPanel->getPos( iXPos, iYPos );
m_pBackgroundPanel->getSize( iXSize, iYSize );
// Create the title
Label *pLabel = new Label( "", iXPos + MOTD_TITLE_X, iYPos + MOTD_TITLE_Y );
pLabel->setParent( this );
pLabel->setFont( pSchemes->getFont( hTitleScheme ) );
pLabel->setFont( Scheme::sf_primary1 );
pSchemes->getFgColor( hTitleScheme, r, g, b, a );
pLabel->setFgColor( r, g, b, a );
pLabel->setFgColor( Scheme::sc_primary1 );
pSchemes->getBgColor( hTitleScheme, r, g, b, a );
pLabel->setBgColor( r, g, b, a );
pLabel->setContentAlignment( vgui::Label::a_west );
pLabel->setText( "%s", szTitle);
// Create the Scroll panel
ScrollPanel *pScrollPanel = new CTFScrollPanel( iXPos + XRES( 16 ), iYPos + MOTD_TITLE_Y * 2 + YRES( 16 ), iXSize - XRES( 32 ), iYSize - ( YRES( 48 ) + BUTTON_SIZE_Y * 2 ) );
pScrollPanel->setParent( this );
// force the scrollbars on so clientClip will take them in account after the validate
pScrollPanel->setScrollBarAutoVisible( false, false );
pScrollPanel->setScrollBarVisible( true, true );
pScrollPanel->validate();
// Create the text panel
TextPanel *pText = new TextPanel( "", 0, 0, 64, 64 );
pText->setParent( pScrollPanel->getClient() );
// get the font and colors from the scheme
pText->setFont( pSchemes->getFont( hMOTDText ) );
pSchemes->getFgColor( hMOTDText, r, g, b, a );
pText->setFgColor( r, g, b, a );
pSchemes->getBgColor( hMOTDText, r, g, b, a );
pText->setBgColor( r, g, b, a );
pText->setText( szMOTD );
// Get the total size of the MOTD text and resize the text panel
int iScrollSizeX, iScrollSizeY;
// First, set the size so that the client's wdith is correct at least because the
// width is critical for getting the "wrapped" size right.
// You'll see a horizontal scroll bar if there is a single word that won't wrap in the
// specified width.
pText->getTextImage()->setSize( pScrollPanel->getClientClip()->getWide(), pScrollPanel->getClientClip()->getTall() );
pText->getTextImage()->getTextSizeWrapped( iScrollSizeX, iScrollSizeY );
// Now resize the textpanel to fit the scrolled size
pText->setSize( iScrollSizeX, iScrollSizeY );
//turn the scrollbars back into automode
pScrollPanel->setScrollBarAutoVisible( true, true );
pScrollPanel->setScrollBarVisible( false, false );
pScrollPanel->validate();
CommandButton *pButton = new CommandButton( CHudTextMessage::BufferedLocaliseTextString( "#Menu_OK" ), iXPos + XRES( 16 ), iYPos + iYSize - YRES( 16 ) - BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y );
pButton->addActionSignal( new CMenuHandler_TextWindow( HIDE_TEXTWINDOW ) );
pButton->setParent( this );
}

View File

@ -0,0 +1,556 @@
//=========== (C) Copyright 1996-2002 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// Purpose:
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================
#include "hud.h"
#include "vgui_SchemeManager.h"
#include "cvardef.h"
#include <string.h>
cvar_t *g_CV_BitmapFonts;
void Scheme_Init()
{
g_CV_BitmapFonts = gEngfuncs.pfnRegisterVariable("bitmapfonts", "1", 0);
}
//-----------------------------------------------------------------------------
// Purpose: Scheme managers data container
//-----------------------------------------------------------------------------
class CSchemeManager::CScheme
{
public:
enum {
SCHEME_NAME_LENGTH = 32,
FONT_NAME_LENGTH = 48,
FONT_FILENAME_LENGTH = 64,
};
// name
char schemeName[SCHEME_NAME_LENGTH];
// font
char fontName[FONT_NAME_LENGTH];
int fontSize;
int fontWeight;
vgui::Font *font;
int ownFontPointer; // true if the font is ours to delete
// scheme
byte fgColor[4];
byte bgColor[4];
byte armedFgColor[4];
byte armedBgColor[4];
byte mousedownFgColor[4];
byte mousedownBgColor[4];
byte borderColor[4];
// construction/destruction
CScheme();
~CScheme();
};
CSchemeManager::CScheme::CScheme()
{
schemeName[0] = 0;
fontName[0] = 0;
fontSize = 0;
fontWeight = 0;
font = NULL;
ownFontPointer = false;
}
CSchemeManager::CScheme::~CScheme()
{
// only delete our font pointer if we own it
if ( ownFontPointer )
{
delete font;
}
}
//-----------------------------------------------------------------------------
// Purpose: resolution information
// !! needs to be shared out
//-----------------------------------------------------------------------------
static int g_ResArray[] =
{
320,
400,
512,
640,
800,
1024,
1152,
1280,
1600
};
static int g_NumReses = sizeof(g_ResArray) / sizeof(int);
static byte *LoadFileByResolution( const char *filePrefix, int xRes, const char *filePostfix )
{
// find our resolution in the res array
int resNum = g_NumReses - 1;
while ( g_ResArray[resNum] > xRes )
{
resNum--;
if ( resNum < 0 )
return NULL;
}
// try open the file
byte *pFile = NULL;
while ( 1 )
{
// try load
char fname[256];
sprintf( fname, "%s%d%s", filePrefix, g_ResArray[resNum], filePostfix );
pFile = gEngfuncs.COM_LoadFile( fname, 5, NULL );
if ( pFile )
break;
if ( resNum == 0 )
return NULL;
resNum--;
};
return pFile;
}
static void ParseRGBAFromString( byte colorArray[4], const char *colorVector )
{
int r, g, b, a;
sscanf( colorVector, "%d %d %d %d", &r, &g, &b, &a );
colorArray[0] = r;
colorArray[1] = g;
colorArray[2] = b;
colorArray[3] = a;
}
//-----------------------------------------------------------------------------
// Purpose: initializes the scheme manager
// loading the scheme files for the current resolution
// Input : xRes -
// yRes - dimensions of output window
//-----------------------------------------------------------------------------
CSchemeManager::CSchemeManager( int xRes, int yRes )
{
// basic setup
m_pSchemeList = NULL;
m_iNumSchemes = 0;
// find the closest matching scheme file to our resolution
char token[1024];
char *pFile = (char*)LoadFileByResolution( "", xRes, "_textscheme.txt" );
m_xRes = xRes;
char *pFileStart = pFile;
byte *pFontData;
int fontFileLength;
char fontFilename[512];
//
// Read the scheme descriptions from the text file, into a temporary array
// format is simply:
// <paramName name> = <paramValue>
//
// a <paramName name> of "SchemeName" signals a new scheme is being described
//
const static int numTmpSchemes = 64;
static CScheme tmpSchemes[numTmpSchemes];
memset( tmpSchemes, 0, sizeof(tmpSchemes) );
int currentScheme = -1;
CScheme *pScheme = NULL;
if ( !pFile )
{
gEngfuncs.Con_DPrintf( "Unable to find *_textscheme.txt\n");
goto buildDefaultFont;
}
// record what has been entered so we can create defaults from the different values
bool hasFgColor, hasBgColor, hasArmedFgColor, hasArmedBgColor, hasMouseDownFgColor, hasMouseDownBgColor;
pFile = gEngfuncs.COM_ParseFile( pFile, token );
while ( strlen(token) > 0 && (currentScheme < numTmpSchemes) )
{
// get the paramName name
static const int tokenSize = 64;
char paramName[tokenSize], paramValue[tokenSize];
strncpy( paramName, token, tokenSize );
paramName[tokenSize-1] = 0; // ensure null termination
// get the '=' character
pFile = gEngfuncs.COM_ParseFile( pFile, token );
if ( stricmp( token, "=" ) )
{
if ( currentScheme < 0 )
{
gEngfuncs.Con_Printf( "error parsing font scheme text file at file start - expected '=', found '%s''\n", token );
}
else
{
gEngfuncs.Con_Printf( "error parsing font scheme text file at scheme '%s' - expected '=', found '%s''\n", tmpSchemes[currentScheme].schemeName, token );
}
break;
}
// get paramValue
pFile = gEngfuncs.COM_ParseFile( pFile, token );
strncpy( paramValue, token, tokenSize );
paramValue[tokenSize-1] = 0; // ensure null termination
// is this a new scheme?
if ( !stricmp(paramName, "SchemeName") )
{
// setup the defaults for the current scheme
if ( pScheme )
{
// foreground color defaults (normal -> armed -> mouse down)
if ( !hasFgColor )
{
pScheme->fgColor[0] = pScheme->fgColor[1] = pScheme->fgColor[2] = pScheme->fgColor[3] = 255;
}
if ( !hasArmedFgColor )
{
memcpy( pScheme->armedFgColor, pScheme->fgColor, sizeof(pScheme->armedFgColor) );
}
if ( !hasMouseDownFgColor )
{
memcpy( pScheme->mousedownFgColor, pScheme->armedFgColor, sizeof(pScheme->mousedownFgColor) );
}
// background color (normal -> armed -> mouse down)
if ( !hasBgColor )
{
pScheme->bgColor[0] = pScheme->bgColor[1] = pScheme->bgColor[2] = pScheme->bgColor[3] = 0;
}
if ( !hasArmedBgColor )
{
memcpy( pScheme->armedBgColor, pScheme->bgColor, sizeof(pScheme->armedBgColor) );
}
if ( !hasMouseDownBgColor )
{
memcpy( pScheme->mousedownBgColor, pScheme->armedBgColor, sizeof(pScheme->mousedownBgColor) );
}
// font size
if ( !pScheme->fontSize )
{
pScheme->fontSize = 17;
}
if ( !pScheme->fontName[0] )
{
strcpy( pScheme->fontName, "Arial" );
}
}
// create the new scheme
currentScheme++;
pScheme = &tmpSchemes[currentScheme];
hasFgColor = hasBgColor = hasArmedFgColor = hasArmedBgColor = hasMouseDownFgColor = hasMouseDownBgColor = false;
strncpy( pScheme->schemeName, paramValue, CScheme::SCHEME_NAME_LENGTH );
pScheme->schemeName[CScheme::SCHEME_NAME_LENGTH-1] = '\0'; // ensure null termination of string
}
if ( !pScheme )
{
gEngfuncs.Con_Printf( "font scheme text file MUST start with a 'SchemeName'\n");
break;
}
// pull the data out into the scheme
if ( !stricmp(paramName, "FontName") )
{
strncpy( pScheme->fontName, paramValue, CScheme::FONT_NAME_LENGTH );
pScheme->fontName[CScheme::FONT_NAME_LENGTH-1] = 0;
}
else if ( !stricmp(paramName, "FontSize") )
{
pScheme->fontSize = atoi( paramValue );
}
else if ( !stricmp(paramName, "FontWeight") )
{
pScheme->fontWeight = atoi( paramValue );
}
else if ( !stricmp(paramName, "FgColor") )
{
ParseRGBAFromString( pScheme->fgColor, paramValue );
hasFgColor = true;
}
else if ( !stricmp(paramName, "BgColor") )
{
ParseRGBAFromString( pScheme->bgColor, paramValue );
hasBgColor = true;
}
else if ( !stricmp(paramName, "FgColorArmed") )
{
ParseRGBAFromString( pScheme->armedFgColor, paramValue );
hasArmedFgColor = true;
}
else if ( !stricmp(paramName, "BgColorArmed") )
{
ParseRGBAFromString( pScheme->armedBgColor, paramValue );
hasArmedBgColor = true;
}
else if ( !stricmp(paramName, "FgColorMousedown") )
{
ParseRGBAFromString( pScheme->mousedownFgColor, paramValue );
hasMouseDownFgColor = true;
}
else if ( !stricmp(paramName, "BgColorMousedown") )
{
ParseRGBAFromString( pScheme->mousedownBgColor, paramValue );
hasMouseDownBgColor = true;
}
else if ( !stricmp(paramName, "BorderColor") )
{
ParseRGBAFromString( pScheme->borderColor, paramValue );
hasMouseDownBgColor = true;
}
// get the new token last, so we now if the loop needs to be continued or not
pFile = gEngfuncs.COM_ParseFile( pFile, token );
}
// free the file
gEngfuncs.COM_FreeFile( pFileStart );
buildDefaultFont:
// make sure we have at least 1 valid font
if ( currentScheme < 0 )
{
currentScheme = 0;
strcpy( tmpSchemes[0].schemeName, "Default Scheme" );
strcpy( tmpSchemes[0].fontName, "Arial" );
tmpSchemes[0].fontSize = 0;
tmpSchemes[0].fgColor[0] = tmpSchemes[0].fgColor[1] = tmpSchemes[0].fgColor[2] = tmpSchemes[0].fgColor[3] = 255;
tmpSchemes[0].armedFgColor[0] = tmpSchemes[0].armedFgColor[1] = tmpSchemes[0].armedFgColor[2] = tmpSchemes[0].armedFgColor[3] = 255;
tmpSchemes[0].mousedownFgColor[0] = tmpSchemes[0].mousedownFgColor[1] = tmpSchemes[0].mousedownFgColor[2] = tmpSchemes[0].mousedownFgColor[3] = 255;
}
// we have the full list of schemes in the tmpSchemes array
// now allocate the correct sized list
m_iNumSchemes = currentScheme + 1; // 0-based index
m_pSchemeList = new CScheme[ m_iNumSchemes ];
// copy in the data
memcpy( m_pSchemeList, tmpSchemes, sizeof(CScheme) * m_iNumSchemes );
// create the fonts
for ( int i = 0; i < m_iNumSchemes; i++ )
{
m_pSchemeList[i].font = NULL;
// see if the current font values exist in a previously loaded font
for ( int j = 0; j < i; j++ )
{
// check if the font name, size, and weight are the same
if ( !stricmp(m_pSchemeList[i].fontName, m_pSchemeList[j].fontName)
&& m_pSchemeList[i].fontSize == m_pSchemeList[j].fontSize
&& m_pSchemeList[i].fontWeight == m_pSchemeList[j].fontWeight )
{
// copy the pointer, but mark i as not owning it
m_pSchemeList[i].font = m_pSchemeList[j].font;
m_pSchemeList[i].ownFontPointer = false;
}
}
// if we haven't found the font already, load it ourselves
if ( !m_pSchemeList[i].font )
{
fontFileLength = -1;
pFontData = NULL;
if(g_CV_BitmapFonts && g_CV_BitmapFonts->value)
{
int fontRes = 640;
if ( m_xRes >= 1600 )
fontRes = 1600;
else if ( m_xRes >= 1280 )
fontRes = 1280;
else if ( m_xRes >= 1152 )
fontRes = 1152;
else if ( m_xRes >= 1024 )
fontRes = 1024;
else if ( m_xRes >= 800 )
fontRes = 800;
sprintf(fontFilename, "gfx\\vgui\\fonts\\%d_%s.tga", fontRes, m_pSchemeList[i].schemeName);
pFontData = gEngfuncs.COM_LoadFile( fontFilename, 5, &fontFileLength );
if(!pFontData)
gEngfuncs.Con_Printf("Missing bitmap font: %s\n", fontFilename);
}
m_pSchemeList[i].font = new vgui::Font(
m_pSchemeList[i].fontName,
pFontData,
fontFileLength,
m_pSchemeList[i].fontSize,
0,
0,
m_pSchemeList[i].fontWeight,
false,
false,
false,
false);
m_pSchemeList[i].ownFontPointer = true;
}
// fix up alpha values; VGUI uses 1-A (A=0 being solid, A=255 transparent)
m_pSchemeList[i].fgColor[3] = 255 - m_pSchemeList[i].fgColor[3];
m_pSchemeList[i].bgColor[3] = 255 - m_pSchemeList[i].bgColor[3];
m_pSchemeList[i].armedFgColor[3] = 255 - m_pSchemeList[i].armedFgColor[3];
m_pSchemeList[i].armedBgColor[3] = 255 - m_pSchemeList[i].armedBgColor[3];
m_pSchemeList[i].mousedownFgColor[3] = 255 - m_pSchemeList[i].mousedownFgColor[3];
m_pSchemeList[i].mousedownBgColor[3] = 255 - m_pSchemeList[i].mousedownBgColor[3];
}
}
//-----------------------------------------------------------------------------
// Purpose: frees all the memory used by the scheme manager
//-----------------------------------------------------------------------------
CSchemeManager::~CSchemeManager()
{
delete [] m_pSchemeList;
m_iNumSchemes = 0;
}
//-----------------------------------------------------------------------------
// Purpose: Finds a scheme in the list, by name
// Input : char *schemeName - string name of the scheme
// Output : SchemeHandle_t handle to the scheme
//-----------------------------------------------------------------------------
SchemeHandle_t CSchemeManager::getSchemeHandle( const char *schemeName )
{
// iterate through the list
for ( int i = 0; i < m_iNumSchemes; i++ )
{
if ( !stricmp(schemeName, m_pSchemeList[i].schemeName) )
return i;
}
return 0;
}
//-----------------------------------------------------------------------------
// Purpose: always returns a valid scheme handle
// Input : schemeHandle -
// Output : CScheme
//-----------------------------------------------------------------------------
CSchemeManager::CScheme *CSchemeManager::getSafeScheme( SchemeHandle_t schemeHandle )
{
if ( schemeHandle < m_iNumSchemes )
return m_pSchemeList + schemeHandle;
return m_pSchemeList;
}
//-----------------------------------------------------------------------------
// Purpose: Returns the schemes pointer to a font
// Input : schemeHandle -
// Output : vgui::Font
//-----------------------------------------------------------------------------
vgui::Font *CSchemeManager::getFont( SchemeHandle_t schemeHandle )
{
return getSafeScheme( schemeHandle )->font;
}
void CSchemeManager::getFgColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a )
{
CScheme *pScheme = getSafeScheme( schemeHandle );
r = pScheme->fgColor[0];
g = pScheme->fgColor[1];
b = pScheme->fgColor[2];
a = pScheme->fgColor[3];
}
void CSchemeManager::getBgColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a )
{
CScheme *pScheme = getSafeScheme( schemeHandle );
r = pScheme->bgColor[0];
g = pScheme->bgColor[1];
b = pScheme->bgColor[2];
a = pScheme->bgColor[3];
}
void CSchemeManager::getFgArmedColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a )
{
CScheme *pScheme = getSafeScheme( schemeHandle );
r = pScheme->armedFgColor[0];
g = pScheme->armedFgColor[1];
b = pScheme->armedFgColor[2];
a = pScheme->armedFgColor[3];
}
void CSchemeManager::getBgArmedColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a )
{
CScheme *pScheme = getSafeScheme( schemeHandle );
r = pScheme->armedBgColor[0];
g = pScheme->armedBgColor[1];
b = pScheme->armedBgColor[2];
a = pScheme->armedBgColor[3];
}
void CSchemeManager::getFgMousedownColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a )
{
CScheme *pScheme = getSafeScheme( schemeHandle );
r = pScheme->mousedownFgColor[0];
g = pScheme->mousedownFgColor[1];
b = pScheme->mousedownFgColor[2];
a = pScheme->mousedownFgColor[3];
}
void CSchemeManager::getBgMousedownColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a )
{
CScheme *pScheme = getSafeScheme( schemeHandle );
r = pScheme->mousedownBgColor[0];
g = pScheme->mousedownBgColor[1];
b = pScheme->mousedownBgColor[2];
a = pScheme->mousedownBgColor[3];
}
void CSchemeManager::getBorderColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a )
{
CScheme *pScheme = getSafeScheme( schemeHandle );
r = pScheme->borderColor[0];
g = pScheme->borderColor[1];
b = pScheme->borderColor[2];
a = pScheme->borderColor[3];
}

View File

@ -0,0 +1,50 @@
//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include <VGUI_Font.h>
// handle to an individual scheme
typedef int SchemeHandle_t;
// Register console variables, etc..
void Scheme_Init();
//-----------------------------------------------------------------------------
// Purpose: Handles the loading of text scheme description from disk
// supports different font/color/size schemes at different resolutions
//-----------------------------------------------------------------------------
class CSchemeManager
{
public:
// initialization
CSchemeManager( int xRes, int yRes );
virtual ~CSchemeManager();
// scheme handling
SchemeHandle_t getSchemeHandle( const char *schemeName );
// getting info from schemes
vgui::Font *getFont( SchemeHandle_t schemeHandle );
void getFgColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a );
void getBgColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a );
void getFgArmedColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a );
void getBgArmedColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a );
void getFgMousedownColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a );
void getBgMousedownColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a );
void getBorderColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a );
private:
class CScheme;
CScheme *m_pSchemeList;
int m_iNumSchemes;
// Resolution we were initted at.
int m_xRes;
CScheme *getSafeScheme( SchemeHandle_t schemeHandle );
};

1147
cl_dll/vgui_ScorePanel.cpp Normal file

File diff suppressed because it is too large Load Diff

311
cl_dll/vgui_ScorePanel.h Normal file
View File

@ -0,0 +1,311 @@
//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef SCOREPANEL_H
#define SCOREPANEL_H
#include<VGUI_Panel.h>
#include<VGUI_TablePanel.h>
#include<VGUI_HeaderPanel.h>
#include<VGUI_TextGrid.h>
#include<VGUI_Label.h>
#include<VGUI_TextImage.h>
#include "../game_shared/vgui_listbox.h"
#include "cl_util.h"
#include <ctype.h>
#define MAX_SCORES 10
#define MAX_SCOREBOARD_TEAMS 5
// Scoreboard cells
#define COLUMN_TRACKER 0
#define COLUMN_NAME 1
#define COLUMN_CLASS 2
#define COLUMN_KILLS 3
#define COLUMN_DEATHS 4
#define COLUMN_LATENCY 5
#define COLUMN_VOICE 6
#define COLUMN_BLANK 7
#define NUM_COLUMNS 8
#define NUM_ROWS (MAX_PLAYERS + (MAX_SCOREBOARD_TEAMS * 2))
using namespace vgui;
class CTextImage2 : public Image
{
public:
CTextImage2()
{
_image[0] = new TextImage("");
_image[1] = new TextImage("");
}
~CTextImage2()
{
delete _image[0];
delete _image[1];
}
TextImage *GetImage(int image)
{
return _image[image];
}
void getSize(int &wide, int &tall)
{
int w1, w2, t1, t2;
_image[0]->getTextSize(w1, t1);
_image[1]->getTextSize(w2, t2);
wide = w1 + w2;
tall = Q_max(t1, t2);
setSize(wide, tall);
}
void doPaint(Panel *panel)
{
_image[0]->doPaint(panel);
_image[1]->doPaint(panel);
}
void setPos(int x, int y)
{
_image[0]->setPos(x, y);
int swide, stall;
_image[0]->getSize(swide, stall);
int wide, tall;
_image[1]->getSize(wide, tall);
_image[1]->setPos(x + wide, y + (stall * 0.9) - tall);
}
void setColor(Color color)
{
_image[0]->setColor(color);
}
void setColor2(Color color)
{
_image[1]->setColor(color);
}
private:
TextImage *_image[2];
};
//-----------------------------------------------------------------------------
// Purpose: Custom label for cells in the Scoreboard's Table Header
//-----------------------------------------------------------------------------
class CLabelHeader : public Label
{
public:
CLabelHeader() : Label("")
{
_dualImage = new CTextImage2();
_dualImage->setColor2(Color(255, 170, 0, 0));
_row = -2;
_useFgColorAsImageColor = true;
_offset[0] = 0;
_offset[1] = 0;
}
~CLabelHeader()
{
delete _dualImage;
}
void setRow(int row)
{
_row = row;
}
void setFgColorAsImageColor(bool state)
{
_useFgColorAsImageColor = state;
}
virtual void setText(int textBufferLen, const char* text)
{
_dualImage->GetImage(0)->setText(text);
// calculate the text size
Font *font = _dualImage->GetImage(0)->getFont();
_gap = 0;
for (const char *ch = text; *ch != 0; ch++)
{
int a, b, c;
font->getCharABCwide(*ch, a, b, c);
_gap += (a + b + c);
}
_gap += XRES(5);
}
virtual void setText(const char* text)
{
// strip any non-alnum characters from the end
char buf[512];
strcpy(buf, text);
int len = strlen(buf);
while (len && isspace(buf[--len]))
{
buf[len] = 0;
}
CLabelHeader::setText(0, buf);
}
void setText2(const char *text)
{
_dualImage->GetImage(1)->setText(text);
}
void getTextSize(int &wide, int &tall)
{
_dualImage->getSize(wide, tall);
}
void setFgColor(int r,int g,int b,int a)
{
Label::setFgColor(r,g,b,a);
Color color(r,g,b,a);
_dualImage->setColor(color);
_dualImage->setColor2(color);
repaint();
}
void setFgColor(Scheme::SchemeColor sc)
{
int r, g, b, a;
Label::setFgColor(sc);
Label::getFgColor( r, g, b, a );
// Call the r,g,b,a version so it sets the color in the dualImage..
setFgColor( r, g, b, a );
}
void setFont(Font *font)
{
_dualImage->GetImage(0)->setFont(font);
}
void setFont2(Font *font)
{
_dualImage->GetImage(1)->setFont(font);
}
// this adjust the absolute position of the text after alignment is calculated
void setTextOffset(int x, int y)
{
_offset[0] = x;
_offset[1] = y;
}
void paint();
void paintBackground();
void calcAlignment(int iwide, int itall, int &x, int &y);
private:
CTextImage2 *_dualImage;
int _row;
int _gap;
int _offset[2];
bool _useFgColorAsImageColor;
};
class ScoreTablePanel;
#include "../game_shared/vgui_grid.h"
#include "../game_shared/vgui_defaultinputsignal.h"
//-----------------------------------------------------------------------------
// Purpose: Scoreboard back panel
//-----------------------------------------------------------------------------
class ScorePanel : public Panel, public vgui::CDefaultInputSignal
{
private:
// Default panel implementation doesn't forward mouse messages when there is no cursor and we need them.
class HitTestPanel : public Panel
{
public:
virtual void internalMousePressed(MouseCode code);
};
private:
Label m_TitleLabel;
// Here is how these controls are arranged hierarchically.
// m_HeaderGrid
// m_HeaderLabels
// m_PlayerGridScroll
// m_PlayerGrid
// m_PlayerEntries
CGrid m_HeaderGrid;
CLabelHeader m_HeaderLabels[NUM_COLUMNS]; // Labels above the
CLabelHeader *m_pCurrentHighlightLabel;
int m_iHighlightRow;
vgui::CListBox m_PlayerList;
CGrid m_PlayerGrids[NUM_ROWS]; // The grid with player and team info.
CLabelHeader m_PlayerEntries[NUM_COLUMNS][NUM_ROWS]; // Labels for the grid entries.
ScorePanel::HitTestPanel m_HitTestPanel;
CommandButton *m_pCloseButton;
CLabelHeader* GetPlayerEntry(int x, int y) {return &m_PlayerEntries[x][y];}
public:
int m_iNumTeams;
int m_iPlayerNum;
int m_iShowscoresHeld;
int m_iRows;
int m_iSortedRows[NUM_ROWS];
int m_iIsATeam[NUM_ROWS];
bool m_bHasBeenSorted[MAX_PLAYERS];
int m_iLastKilledBy;
int m_fLastKillTime;
public:
ScorePanel(int x,int y,int wide,int tall);
void Update( void );
void SortTeams( void );
void SortPlayers( int iTeam, char *team );
void RebuildTeams( void );
void FillGrid();
void DeathMsg( int killer, int victim );
void Initialize( void );
void Open( void );
void MouseOverCell(int row, int col);
// InputSignal overrides.
public:
virtual void mousePressed(MouseCode code, Panel* panel);
virtual void cursorMoved(int x, int y, Panel *panel);
friend class CLabelHeader;
};
#endif

View File

@ -0,0 +1,420 @@
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
// vgui_SpectatorPanel.cpp: implementation of the SpectatorPanel class.
//
//////////////////////////////////////////////////////////////////////
#include "hud.h"
#include "cl_util.h"
#include "const.h"
#include "entity_state.h"
#include "cl_entity.h"
#include "pm_shared.h"
#include "vgui_TeamFortressViewport.h"
#include "vgui_SpectatorPanel.h"
#include "vgui_ScorePanel.h"
//#include "Exports.h"
/*
==========================
HUD_ChatInputPosition
Sets the location of the input for chat text
==========================
*/
void DLLEXPORT HUD_ChatInputPosition( int *x, int *y )
{
// RecClChatInputPosition( x, y );
if ( g_iUser1 != 0 || gEngfuncs.IsSpectateOnly() )
{
if ( gHUD.m_Spectator.m_pip->value == INSET_OFF )
{
*y = YRES( PANEL_HEIGHT );
}
else
{
*y = YRES( gHUD.m_Spectator.m_OverviewData.insetWindowHeight + 5 );
}
}
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
SpectatorPanel::SpectatorPanel( int x, int y, int wide, int tall ) : Panel( x, y, wide, tall )
{
}
SpectatorPanel::~SpectatorPanel()
{
}
void SpectatorPanel::ActionSignal( int cmd )
{
switch( cmd )
{
case SPECTATOR_PANEL_CMD_NONE : break;
case SPECTATOR_PANEL_CMD_OPTIONS : gViewPort->ShowCommandMenu( gViewPort->m_SpectatorOptionsMenu );
break;
case SPECTATOR_PANEL_CMD_NEXTPLAYER : gHUD.m_Spectator.FindNextPlayer(true);
break;
case SPECTATOR_PANEL_CMD_PREVPLAYER : gHUD.m_Spectator.FindNextPlayer(false);
break;
case SPECTATOR_PANEL_CMD_PLAYERS : gViewPort->ShowCommandMenu( gViewPort->m_PlayerMenu );
break;
case SPECTATOR_PANEL_CMD_HIDEMENU : ShowMenu(false);
break;
case SPECTATOR_PANEL_CMD_CAMERA : gViewPort->ShowCommandMenu( gViewPort->m_SpectatorCameraMenu );
break;
case SPECTATOR_PANEL_CMD_TOGGLE_INSET : gHUD.m_Spectator.SetModes( -1,
gHUD.m_Spectator.ToggleInset(false) );
break;
default : gEngfuncs.Con_DPrintf("Unknown SpectatorPanel ActionSingal %i.\n",cmd); break;
}
}
void SpectatorPanel::Initialize()
{
int x, y, wide, tall;
getBounds( x, y, wide, tall );
CSchemeManager *pSchemes = gViewPort->GetSchemeManager();
SchemeHandle_t hSmallScheme = pSchemes->getSchemeHandle( "Team Info Text" );
m_TopBorder = new CTransparentPanel( 64, 0, 0, ScreenWidth, YRES( PANEL_HEIGHT ) );
m_TopBorder->setParent( this );
m_BottomBorder = new CTransparentPanel( 64, 0, ScreenHeight - YRES( 32 ), ScreenWidth, YRES( PANEL_HEIGHT ) );
m_BottomBorder->setParent( this );
setPaintBackgroundEnabled( false );
m_ExtraInfo = new Label( "Extra Info", 0, 0, wide, YRES( PANEL_HEIGHT ) );
m_ExtraInfo->setParent( m_TopBorder );
m_ExtraInfo->setFont( pSchemes->getFont( hSmallScheme ) );
m_ExtraInfo->setPaintBackgroundEnabled( false );
m_ExtraInfo->setFgColor( 143, 143, 54, 0 );
m_ExtraInfo->setContentAlignment( vgui::Label::a_west );
m_TimerImage = new CImageLabel( "timer", 0, 0, 14, 14 );
m_TimerImage->setParent( m_TopBorder );
m_TopBanner = new CImageLabel( "banner", 0, 0, XRES( BANNER_WIDTH ), YRES( BANNER_HEIGHT ) );
m_TopBanner->setParent( this );
m_CurrentTime = new Label( "00:00", 0, 0, wide, YRES( PANEL_HEIGHT ) );
m_CurrentTime->setParent( m_TopBorder );
m_CurrentTime->setFont( pSchemes->getFont( hSmallScheme ) );
m_CurrentTime->setPaintBackgroundEnabled( false );
m_CurrentTime->setFgColor( 143, 143, 54, 0 );
m_CurrentTime->setContentAlignment( vgui::Label::a_west );
m_Separator = new Panel( 0, 0, XRES( 64 ), YRES( 96 ) );
m_Separator->setParent( m_TopBorder );
m_Separator->setFgColor( 59, 58, 34, 48 );
m_Separator->setBgColor( 59, 58, 34, 48 );
for( int j = 0; j < TEAM_NUMBER; j++ )
{
m_TeamScores[j] = new Label( " ", 0, 0, wide, YRES( PANEL_HEIGHT ) );
m_TeamScores[j]->setParent( m_TopBorder );
m_TeamScores[j]->setFont( pSchemes->getFont( hSmallScheme ) );
m_TeamScores[j]->setPaintBackgroundEnabled( false );
m_TeamScores[j]->setFgColor( 143, 143, 54, 0 );
m_TeamScores[j]->setContentAlignment( vgui::Label::a_west );
m_TeamScores[j]->setVisible( false );
}
// Initialize command buttons.
// m_OptionButton = new ColorButton( CHudTextMessage::BufferedLocaliseTextString( "#SPECT_OPTIONS" ), XRES(15), YRES(6), XRES(OPTIONS_BUTTON_X), YRES(20), false, false );
m_OptionButton = new DropDownButton( CHudTextMessage::BufferedLocaliseTextString( "#SPECT_OPTIONS" ), XRES(15), YRES(6), XRES(OPTIONS_BUTTON_X), YRES(20), false, false );
m_OptionButton->setParent( m_BottomBorder );
m_OptionButton->setContentAlignment( vgui::Label::a_center );
m_OptionButton->setBoundKey( (char)255 ); // special no bound to avoid leading spaces in name
m_OptionButton->addActionSignal( new CSpectatorHandler_Command( this, SPECTATOR_PANEL_CMD_OPTIONS ) );
m_OptionButton->setUnArmedBorderColor( 59, 58, 34, 48 );
m_OptionButton->setArmedBorderColor( 194, 202, 54, 0 );
m_OptionButton->setUnArmedColor( 143, 143, 54, 0 );
m_OptionButton->setArmedColor( 194, 202, 54, 0 );
m_CamButton = new DropDownButton( CHudTextMessage::BufferedLocaliseTextString( "#CAM_OPTIONS" ), ScreenWidth - ( XRES ( CAMOPTIONS_BUTTON_X ) + 15 ), YRES(6), XRES ( CAMOPTIONS_BUTTON_X ), YRES(20), false, false );
m_CamButton->setParent( m_BottomBorder );
m_CamButton->setContentAlignment( vgui::Label::a_center );
m_CamButton->setBoundKey( (char)255 ); // special no bound to avoid leading spaces in name
m_CamButton->addActionSignal( new CSpectatorHandler_Command( this, SPECTATOR_PANEL_CMD_CAMERA ) );
m_CamButton->setUnArmedBorderColor( 59, 58, 34, 48 );
m_CamButton->setArmedBorderColor( 194, 202, 54, 0 );
m_CamButton->setUnArmedColor( 143, 143, 54, 0 );
m_CamButton->setArmedColor( 194, 202, 54, 0 );
// m_PrevPlayerButton= new ColorButton("<", XRES( 15 + OPTIONS_BUTTON_X + 15 ), YRES(6), XRES(24), YRES(20), false, false );
m_PrevPlayerButton= new CImageButton("arrowleft", XRES( 15 + OPTIONS_BUTTON_X + 15 ), YRES(6), XRES(24), YRES(20), false, false );
m_PrevPlayerButton->setParent( m_BottomBorder );
m_PrevPlayerButton->setContentAlignment( vgui::Label::a_center );
m_PrevPlayerButton->setBoundKey( (char)255 ); // special no bound to avoid leading spaces in name
m_PrevPlayerButton->addActionSignal( new CSpectatorHandler_Command( this, SPECTATOR_PANEL_CMD_PREVPLAYER ) );
m_PrevPlayerButton->setUnArmedBorderColor( 59, 58, 34, 48 );
m_PrevPlayerButton->setArmedBorderColor( 194, 202, 54, 0 );
m_PrevPlayerButton->setUnArmedColor( 143, 143, 54, 0 );
m_PrevPlayerButton->setArmedColor( 194, 202, 54, 0 );
// m_NextPlayerButton= new ColorButton(">", (ScreenWidth - (XRES ( CAMOPTIONS_BUTTON_X ) + 15)) - XRES ( 24 + 15 ), YRES(6), XRES(24), YRES(20),false, false );
m_NextPlayerButton= new CImageButton("arrowright", (ScreenWidth - (XRES ( CAMOPTIONS_BUTTON_X ) + 15)) - XRES ( 24 + 15 ), YRES(6), XRES(24), YRES(20),false, false );
m_NextPlayerButton->setParent( m_BottomBorder );
m_NextPlayerButton->setContentAlignment( vgui::Label::a_center );
m_NextPlayerButton->setBoundKey( (char)255 ); // special no bound to avoid leading spaces in name
m_NextPlayerButton->addActionSignal( new CSpectatorHandler_Command( this, SPECTATOR_PANEL_CMD_NEXTPLAYER ) );
m_NextPlayerButton->setUnArmedBorderColor( 59, 58, 34, 48 );
m_NextPlayerButton->setArmedBorderColor( 194, 202, 54, 0 );
m_NextPlayerButton->setUnArmedColor( 143, 143, 54, 0 );
m_NextPlayerButton->setArmedColor( 194, 202, 54, 0 );
// Initialize the bottom title.
float flLabelSize = ( ( ScreenWidth - ( XRES ( CAMOPTIONS_BUTTON_X ) + 15 ) ) - XRES( 24 + 15 ) ) - XRES( ( 15 + OPTIONS_BUTTON_X + 15 ) + 38 );
m_BottomMainButton = new DropDownButton("Spectator Bottom",
XRES( ( 15 + OPTIONS_BUTTON_X + 15 ) + 31 ), YRES(6), flLabelSize, YRES(20),
false, false );
m_BottomMainButton->setParent(m_BottomBorder);
m_BottomMainButton->setPaintBackgroundEnabled(false);
m_BottomMainButton->setFgColor( Scheme::sc_primary1 );
m_BottomMainButton->setContentAlignment( vgui::Label::a_center );
m_BottomMainButton->setBorder( new LineBorder( Color( 59, 58, 34, 48 ) ) );
m_BottomMainButton->setBoundKey( (char)255 ); // special no bound to avoid leading spaces in name
m_BottomMainButton->addActionSignal( new CSpectatorHandler_Command(this,SPECTATOR_PANEL_CMD_PLAYERS) );
m_BottomMainButton->setUnArmedBorderColor ( 59, 58, 34, 48 );
m_BottomMainButton->setArmedBorderColor ( 194, 202, 54, 0 );
m_BottomMainButton->setUnArmedColor ( 143, 143, 54, 0 );
m_BottomMainButton->setArmedColor ( 194, 202, 54, 0 );
m_BottomMainLabel = new Label("Spectator Bottom",
XRES( ( 15 + OPTIONS_BUTTON_X + 15 ) + 31 ), YRES(6), flLabelSize, YRES(20));
m_BottomMainLabel->setParent( m_BottomBorder );
m_BottomMainLabel->setPaintBackgroundEnabled( false );
m_BottomMainLabel->setFgColor( Scheme::sc_primary1 );
m_BottomMainLabel->setContentAlignment( vgui::Label::a_center );
m_BottomMainLabel->setBorder( NULL );
m_BottomMainLabel->setVisible(false);
m_InsetViewButton = new ColorButton( "", XRES( 2 ), YRES( 2 ), XRES( 240 ), YRES( 180 ), false, false );
m_InsetViewButton->setParent( this );
m_InsetViewButton->setBoundKey( (char)255 );
m_InsetViewButton->addActionSignal( new CSpectatorHandler_Command( this, SPECTATOR_PANEL_CMD_TOGGLE_INSET ) );
m_InsetViewButton->setUnArmedBorderColor( 59, 58, 34, 48 );
m_InsetViewButton->setArmedBorderColor( 194, 202, 54, 0 );
m_InsetViewButton->setUnArmedColor( 143, 143, 54, 0 );
m_InsetViewButton->setArmedColor( 194, 202, 54, 0 );
m_menuVisible = false;
m_insetVisible = false;
// m_HideButton->setVisible( false );
m_CamButton->setVisible( false );
m_OptionButton->setVisible( false );
m_NextPlayerButton->setVisible( false );
m_PrevPlayerButton->setVisible( false );
m_TopBanner->setVisible( false );
m_ExtraInfo->setVisible( false );
m_Separator->setVisible( false );
m_TimerImage->setVisible( false );
}
void SpectatorPanel::ShowMenu( bool isVisible )
{
// m_HideButton->setVisible(isVisible); m_HideButton->setArmed( false );
m_OptionButton->setVisible(isVisible); m_OptionButton->setArmed( false );
m_CamButton->setVisible(isVisible); m_CamButton->setArmed( false );
m_NextPlayerButton->setVisible(isVisible); m_NextPlayerButton->setArmed( false );
m_PrevPlayerButton->setVisible(isVisible); m_PrevPlayerButton->setArmed( false );
if( !isVisible )
{
int iLabelSizeX, iLabelSizeY;
m_BottomMainLabel->setVisible(true);
m_BottomMainButton->setVisible(false);
m_BottomMainLabel->getSize( iLabelSizeX, iLabelSizeY );
m_BottomMainLabel->setPos( ( ScreenWidth / 2 ) - ( iLabelSizeX / 2 ), YRES( 6 ) );
}
else
{
m_BottomMainButton->setPos( XRES( ( 15 + OPTIONS_BUTTON_X + 15 ) + 31 ), YRES(6) );
m_BottomMainLabel->setVisible(false);
m_BottomMainButton->setVisible(true);
}
if( !isVisible )
{
gViewPort->HideCommandMenu();
// if switching from visible menu to invisible menu, show help text
if( m_menuVisible && this->isVisible() )
{
char string[64];
_snprintf( string, sizeof(string) - 1, "%c%s", HUD_PRINTCENTER, CHudTextMessage::BufferedLocaliseTextString( "#Spec_Duck" ) );
string[sizeof(string) - 1] = '\0';
gHUD.m_TextMessage.MsgFunc_TextMsg( NULL, strlen( string ) + 1, string );
}
}
m_menuVisible = isVisible;
gViewPort->UpdateCursorState();
}
const char *GetSpectatorLabel( int iMode )
{
switch( iMode )
{
case OBS_CHASE_LOCKED:
return "#OBS_CHASE_LOCKED";
case OBS_CHASE_FREE:
return "#OBS_CHASE_FREE";
case OBS_ROAMING:
return "#OBS_ROAMING";
case OBS_IN_EYE:
return "#OBS_IN_EYE";
case OBS_MAP_FREE:
return "#OBS_MAP_FREE";
case OBS_MAP_CHASE:
return "#OBS_MAP_CHASE";
case OBS_NONE:
default:
return "#OBS_NONE";
}
return "";
}
void SpectatorPanel::EnableInsetView(bool isEnabled)
{
int x = gHUD.m_Spectator.m_OverviewData.insetWindowX;
int y = gHUD.m_Spectator.m_OverviewData.insetWindowY;
int wide = gHUD.m_Spectator.m_OverviewData.insetWindowWidth;
int tall = gHUD.m_Spectator.m_OverviewData.insetWindowHeight;
int offset = x + wide + 2;
if( isEnabled )
{
// short black bar to see full inset
m_TopBorder->setBounds( XRES( offset ), 0, XRES(640 - offset ), YRES( PANEL_HEIGHT ) );
if( gEngfuncs.IsSpectateOnly() )
{
m_TopBanner->setVisible( true );
m_TopBanner->setPos( XRES( offset ), 0 );
}
else
m_TopBanner->setVisible( false );
m_InsetViewButton->setBounds( XRES( x -1 ), YRES( y ),
XRES( wide +2), YRES( tall ) );
m_InsetViewButton->setVisible( true );
}
else
{
// full black bar, no inset border
// show banner only in real HLTV mode
if( gEngfuncs.IsSpectateOnly() )
{
m_TopBanner->setVisible( true );
m_TopBanner->setPos( 0, 0 );
}
else
m_TopBanner->setVisible( false );
m_TopBorder->setBounds( 0, 0, ScreenWidth, YRES( PANEL_HEIGHT ) );
m_InsetViewButton->setVisible( false );
}
m_insetVisible = isEnabled;
Update();
m_CamButton->setText( CHudTextMessage::BufferedLocaliseTextString( GetSpectatorLabel( g_iUser1 ) ) );
}
void SpectatorPanel::Update()
{
int iTextWidth, iTextHeight;
int iTimeHeight, iTimeWidth;
int offset, j;
if( m_insetVisible )
offset = gHUD.m_Spectator.m_OverviewData.insetWindowX + gHUD.m_Spectator.m_OverviewData.insetWindowWidth + 2;
else
offset = 0;
bool visible = gHUD.m_Spectator.m_drawstatus->value != 0;
m_ExtraInfo->setVisible( visible );
m_TimerImage->setVisible( visible );
m_CurrentTime->setVisible( visible );
m_Separator->setVisible( visible );
for( j = 0; j < TEAM_NUMBER; j++ )
m_TeamScores[j]->setVisible( visible );
if( !visible )
return;
m_ExtraInfo->getTextSize( iTextWidth, iTextHeight );
m_CurrentTime->getTextSize( iTimeWidth, iTimeHeight );
iTimeWidth += XRES ( SEPERATOR_WIDTH*2 + 1 ); // +timer icon
iTimeWidth += ( SEPERATOR_WIDTH-(iTimeWidth%SEPERATOR_WIDTH) );
if( iTimeWidth > iTextWidth )
iTextWidth = iTimeWidth;
int xPos = ScreenWidth - ( iTextWidth + XRES ( SEPERATOR_WIDTH + offset ) );
m_ExtraInfo->setBounds( xPos, YRES( SEPERATOR_HEIGHT ), iTextWidth, iTextHeight );
m_TimerImage->setBounds( xPos, YRES( SEPERATOR_HEIGHT ) + iTextHeight , XRES(SEPERATOR_WIDTH*2 + 1), YRES(SEPERATOR_HEIGHT + 1) );
m_CurrentTime->setBounds( xPos + XRES ( SEPERATOR_WIDTH*2 + 1 ), YRES( SEPERATOR_HEIGHT ) + iTextHeight , iTimeWidth, iTimeHeight );
m_Separator->setPos( ScreenWidth - ( iTextWidth + XRES ( 2*SEPERATOR_WIDTH+SEPERATOR_WIDTH/2+offset ) ) , YRES( 5 ) );
m_Separator->setSize( XRES( 1 ), PANEL_HEIGHT - 10 );
for( j = 0; j < TEAM_NUMBER; j++ )
{
int iwidth, iheight;
m_TeamScores[j]->getTextSize( iwidth, iheight );
m_TeamScores[j]->setBounds( ScreenWidth - ( iTextWidth + XRES ( 2*SEPERATOR_WIDTH+2*SEPERATOR_WIDTH/2+offset ) + iwidth ), YRES( SEPERATOR_HEIGHT ) + ( iheight * j ), iwidth, iheight );
}
}

View File

@ -0,0 +1,111 @@
//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
// vgui_SpectatorPanel.h: interface for the SpectatorPanel class.
//
//////////////////////////////////////////////////////////////////////
#ifndef SPECTATORPANEL_H
#define SPECTATORPANEL_H
#include <VGUI_Panel.h>
#include <VGUI_Label.h>
#include <VGUI_Button.h>
using namespace vgui;
#define SPECTATOR_PANEL_CMD_NONE 0
#define SPECTATOR_PANEL_CMD_OPTIONS 1
#define SPECTATOR_PANEL_CMD_PREVPLAYER 2
#define SPECTATOR_PANEL_CMD_NEXTPLAYER 3
#define SPECTATOR_PANEL_CMD_HIDEMENU 4
#define SPECTATOR_PANEL_CMD_TOGGLE_INSET 5
#define SPECTATOR_PANEL_CMD_CAMERA 6
#define SPECTATOR_PANEL_CMD_PLAYERS 7
// spectator panel sizes
#define PANEL_HEIGHT 64
#define BANNER_WIDTH 256
#define BANNER_HEIGHT 64
#define OPTIONS_BUTTON_X 96
#define CAMOPTIONS_BUTTON_X 200
#define SEPERATOR_WIDTH 15
#define SEPERATOR_HEIGHT 15
#define TEAM_NUMBER 2
class SpectatorPanel : public Panel //, public vgui::CDefaultInputSignal
{
public:
SpectatorPanel( int x, int y, int wide, int tall );
virtual ~SpectatorPanel();
void ActionSignal( int cmd );
// InputSignal overrides.
public:
void Initialize();
void Update();
void EnableInsetView( bool isEnabled );
void ShowMenu( bool isVisible );
DropDownButton * m_OptionButton;
// CommandButton *m_HideButton;
//ColorButton * m_PrevPlayerButton;
//ColorButton * m_NextPlayerButton;
CImageButton * m_PrevPlayerButton;
CImageButton * m_NextPlayerButton;
DropDownButton * m_CamButton;
CTransparentPanel *m_TopBorder;
CTransparentPanel *m_BottomBorder;
ColorButton *m_InsetViewButton;
DropDownButton *m_BottomMainButton;
CImageLabel *m_TimerImage;
Label *m_BottomMainLabel;
Label *m_CurrentTime;
Label *m_ExtraInfo;
Panel *m_Separator;
Label *m_TeamScores[TEAM_NUMBER];
CImageLabel *m_TopBanner;
bool m_menuVisible;
bool m_insetVisible;
};
class CSpectatorHandler_Command : public ActionSignal
{
private:
SpectatorPanel *m_pFather;
int m_cmd;
public:
CSpectatorHandler_Command( SpectatorPanel *panel, int cmd )
{
m_pFather = panel;
m_cmd = cmd;
}
virtual void actionPerformed( Panel *panel )
{
m_pFather->ActionSignal( m_cmd );
}
};
#endif // !defined SPECTATORPANEL_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

127
cl_dll/vgui_int.cpp Normal file
View File

@ -0,0 +1,127 @@
//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "vgui_int.h"
#include <VGUI_Label.h>
#include <VGUI_BorderLayout.h>
#include <VGUI_LineBorder.h>
#include <VGUI_SurfaceBase.h>
#include <VGUI_TextEntry.h>
#include <VGUI_ActionSignal.h>
#include <string.h>
#include "hud.h"
#include "cl_util.h"
#include "camera.h"
#include "kbutton.h"
#include "cvardef.h"
#include "usercmd.h"
#include "const.h"
#include "camera.h"
#include "in_defs.h"
#include "vgui_TeamFortressViewport.h"
#include "vgui_ControlConfigPanel.h"
namespace
{
class TexturePanel : public Panel, public ActionSignal
{
private:
int _bindIndex;
TextEntry *_textEntry;
public:
TexturePanel() : Panel( 0, 0, 256, 276 )
{
_bindIndex = 2700;
_textEntry = new TextEntry( "2700", 0, 0, 128, 20 );
_textEntry->setParent( this );
_textEntry->addActionSignal( this );
}
virtual bool isWithin( int x, int y )
{
return _textEntry->isWithin( x, y );
}
virtual void actionPerformed( Panel *panel )
{
char buf[256];
_textEntry->getText( 0, buf, 256 );
sscanf( buf, "%d", &_bindIndex);
}
protected:
virtual void paintBackground()
{
Panel::paintBackground();
int wide, tall;
getPaintSize( wide, tall );
drawSetColor( 0, 0, 255, 0 );
drawSetTexture( _bindIndex );
drawTexturedRect( 0, 19, 257, 257 );
}
};
}
using namespace vgui;
void VGui_ViewportPaintBackground( int extents[4] )
{
gEngfuncs.VGui_ViewportPaintBackground( extents );
}
void* VGui_GetPanel()
{
return (Panel*)gEngfuncs.VGui_GetPanel();
}
void VGui_Startup()
{
Panel *root = (Panel*)VGui_GetPanel();
root->setBgColor( 128, 128, 0, 0 );
// root->setNonPainted( false );
// root->setBorder( new LineBorder() );
root->setLayout( new BorderLayout( 0 ) );
// root->getSurfaceBase()->setEmulatedCursorVisible( true );
if( gViewPort != NULL )
{
// root->removeChild( gViewPort );
// free the memory
// delete gViewPort;
// gViewPort = NULL;
gViewPort->Initialize();
}
else
{
gViewPort = new TeamFortressViewport( 0, 0, root->getWide(), root->getTall() );
gViewPort->setParent( root );
}
/*
TexturePanel *texturePanel = new TexturePanel();
texturePanel->setParent( gViewPort );
*/
}
void VGui_Shutdown()
{
delete gViewPort;
gViewPort = NULL;
}

21
cl_dll/vgui_int.h Normal file
View File

@ -0,0 +1,21 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef VGUI_INT_H
#define VGUI_INT_H
extern "C"
{
void VGui_Startup();
void VGui_Shutdown();
//Only safe to call from inside subclass of Panel::paintBackground
void VGui_ViewportPaintBackground(int extents[4]);
}
#endif

394
cl_dll/vgui_teammenu.cpp Normal file
View File

@ -0,0 +1,394 @@
//=========== (C) Copyright 1996-2002 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// Purpose: TFC Team Menu
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================
#include "vgui_int.h"
#include "VGUI_Font.h"
#include "VGUI_ScrollPanel.h"
#include "VGUI_TextImage.h"
#include "hud.h"
#include "cl_util.h"
#include "vgui_TeamFortressViewport.h"
// Team Menu Dimensions
#define TEAMMENU_TITLE_X XRES(40)
#define TEAMMENU_TITLE_Y YRES(32)
#define TEAMMENU_TOPLEFT_BUTTON_X XRES(40)
#define TEAMMENU_TOPLEFT_BUTTON_Y YRES(80)
#define TEAMMENU_BUTTON_SIZE_X XRES(124)
#define TEAMMENU_BUTTON_SIZE_Y YRES(24)
#define TEAMMENU_BUTTON_SPACER_Y YRES(8)
#define TEAMMENU_WINDOW_X XRES(176)
#define TEAMMENU_WINDOW_Y YRES(80)
#define TEAMMENU_WINDOW_SIZE_X XRES(424)
#define TEAMMENU_WINDOW_SIZE_Y YRES(312)
#define TEAMMENU_WINDOW_TITLE_X XRES(16)
#define TEAMMENU_WINDOW_TITLE_Y YRES(16)
#define TEAMMENU_WINDOW_TEXT_X XRES(16)
#define TEAMMENU_WINDOW_TEXT_Y YRES(48)
#define TEAMMENU_WINDOW_TEXT_SIZE_Y YRES(178)
#define TEAMMENU_WINDOW_INFO_X XRES(16)
#define TEAMMENU_WINDOW_INFO_Y YRES(234)
// Creation
CTeamMenuPanel::CTeamMenuPanel( int iTrans, int iRemoveMe, int x, int y, int wide, int tall ) : CMenuPanel( iTrans, iRemoveMe, x, y, wide, tall )
{
// Get the scheme used for the Titles
CSchemeManager *pSchemes = gViewPort->GetSchemeManager();
// schemes
SchemeHandle_t hTitleScheme = pSchemes->getSchemeHandle( "Title Font" );
SchemeHandle_t hTeamWindowText = pSchemes->getSchemeHandle( "Briefing Text" );
SchemeHandle_t hTeamInfoText = pSchemes->getSchemeHandle( "Team Info Text" );
// get the Font used for the Titles
Font *pTitleFont = pSchemes->getFont( hTitleScheme );
int r, g, b, a;
// Create the title
Label *pLabel = new Label( "", TEAMMENU_TITLE_X, TEAMMENU_TITLE_Y );
pLabel->setParent( this );
pLabel->setFont( pTitleFont );
pSchemes->getFgColor( hTitleScheme, r, g, b, a );
pLabel->setFgColor( r, g, b, a );
pSchemes->getBgColor( hTitleScheme, r, g, b, a );
pLabel->setBgColor( r, g, b, a );
pLabel->setContentAlignment( vgui::Label::a_west );
pLabel->setText( "%s", gHUD.m_TextMessage.BufferedLocaliseTextString("#Title_SelectYourTeam"));
// Create the Info Window
m_pTeamWindow = new CTransparentPanel( 255, TEAMMENU_WINDOW_X, TEAMMENU_WINDOW_Y, TEAMMENU_WINDOW_SIZE_X, TEAMMENU_WINDOW_SIZE_Y );
m_pTeamWindow->setParent( this );
m_pTeamWindow->setBorder( new LineBorder( Color( 255 * 0.7, 170 * 0.7 ,0 ,0 ) ) );
// Create the Map Name Label
m_pMapTitle = new Label( "", TEAMMENU_WINDOW_TITLE_X, TEAMMENU_WINDOW_TITLE_Y );
m_pMapTitle->setFont( pTitleFont );
m_pMapTitle->setParent( m_pTeamWindow );
pSchemes->getFgColor( hTitleScheme, r, g, b, a );
m_pMapTitle->setFgColor( r, g, b, a );
pSchemes->getBgColor( hTitleScheme, r, g, b, a );
m_pMapTitle->setBgColor( r, g, b, a );
m_pMapTitle->setContentAlignment( vgui::Label::a_west );
// Create the Scroll panel
m_pScrollPanel = new CTFScrollPanel( TEAMMENU_WINDOW_TEXT_X, TEAMMENU_WINDOW_TEXT_Y, TEAMMENU_WINDOW_SIZE_X - ( TEAMMENU_WINDOW_TEXT_X * 2 ), TEAMMENU_WINDOW_TEXT_SIZE_Y );
m_pScrollPanel->setParent( m_pTeamWindow );
m_pScrollPanel->setScrollBarVisible( false, false );
// Create the Map Briefing panel
m_pBriefing = new TextPanel("", 0, 0, TEAMMENU_WINDOW_SIZE_X - TEAMMENU_WINDOW_TEXT_X, TEAMMENU_WINDOW_TEXT_SIZE_Y );
m_pBriefing->setParent( m_pScrollPanel->getClient() );
m_pBriefing->setFont( pSchemes->getFont( hTeamWindowText ) );
pSchemes->getFgColor( hTeamWindowText, r, g, b, a );
m_pBriefing->setFgColor( r, g, b, a );
pSchemes->getBgColor( hTeamWindowText, r, g, b, a );
m_pBriefing->setBgColor( r, g, b, a );
m_pBriefing->setText( gHUD.m_TextMessage.BufferedLocaliseTextString( "#Map_Description_not_available" ) );
// Team Menu buttons
for( int i = 1; i <= 5; i++ )
{
char sz[256];
int iYPos = TEAMMENU_TOPLEFT_BUTTON_Y + ( ( TEAMMENU_BUTTON_SIZE_Y + TEAMMENU_BUTTON_SPACER_Y ) * i );
// Team button
m_pButtons[i] = new CommandButton( "", TEAMMENU_TOPLEFT_BUTTON_X, iYPos, TEAMMENU_BUTTON_SIZE_X, TEAMMENU_BUTTON_SIZE_Y, true );
m_pButtons[i]->setParent( this );
m_pButtons[i]->setContentAlignment( vgui::Label::a_west );
m_pButtons[i]->setVisible( false );
// AutoAssign button uses special case
if( i == 5 )
{
m_pButtons[5]->setBoundKey( '5' );
m_pButtons[5]->setText( gHUD.m_TextMessage.BufferedLocaliseTextString( "#Team_AutoAssign" ) );
m_pButtons[5]->setVisible( true );
}
// Create the Signals
sprintf( sz, "jointeam %d", i );
m_pButtons[i]->addActionSignal( new CMenuHandler_StringCommandWatch( sz, true ) );
m_pButtons[i]->addInputSignal( new CHandler_MenuButtonOver( this, i ) );
// Create the Team Info panel
m_pTeamInfoPanel[i] = new TextPanel( "", TEAMMENU_WINDOW_INFO_X, TEAMMENU_WINDOW_INFO_Y, TEAMMENU_WINDOW_SIZE_X - TEAMMENU_WINDOW_INFO_X, TEAMMENU_WINDOW_SIZE_X - TEAMMENU_WINDOW_INFO_Y );
m_pTeamInfoPanel[i]->setParent( m_pTeamWindow );
m_pTeamInfoPanel[i]->setFont( pSchemes->getFont( hTeamInfoText ) );
m_pTeamInfoPanel[i]->setFgColor( iTeamColors[i % iNumberOfTeamColors][0],
iTeamColors[i % iNumberOfTeamColors][1],
iTeamColors[i % iNumberOfTeamColors][2],
0 );
m_pTeamInfoPanel[i]->setBgColor( 0, 0, 0, 255 );
}
// Create the Cancel button
m_pCancelButton = new CommandButton( CHudTextMessage::BufferedLocaliseTextString( "#Menu_Cancel" ), TEAMMENU_TOPLEFT_BUTTON_X, 0, TEAMMENU_BUTTON_SIZE_X, TEAMMENU_BUTTON_SIZE_Y );
m_pCancelButton->setParent( this );
m_pCancelButton->addActionSignal( new CMenuHandler_TextWindow( HIDE_TEXTWINDOW ) );
// Create the Spectate button
m_pSpectateButton = new SpectateButton( CHudTextMessage::BufferedLocaliseTextString( "#Menu_Spectate" ), TEAMMENU_TOPLEFT_BUTTON_X, 0, TEAMMENU_BUTTON_SIZE_X, TEAMMENU_BUTTON_SIZE_Y, true );
m_pSpectateButton->setParent( this );
m_pSpectateButton->addActionSignal( new CMenuHandler_StringCommand( "spectate", true ) );
m_pSpectateButton->setBoundKey( '6' );
m_pSpectateButton->addInputSignal( new CHandler_MenuButtonOver( this, 6 ) );
Initialize();
}
//-----------------------------------------------------------------------------
// Purpose: Called each time a new level is started.
//-----------------------------------------------------------------------------
void CTeamMenuPanel::Initialize( void )
{
m_bUpdatedMapName = false;
m_iCurrentInfo = 0;
m_pScrollPanel->setScrollValue( 0, 0 );
}
//-----------------------------------------------------------------------------
// Purpose: Called everytime the Team Menu is displayed
//-----------------------------------------------------------------------------
void CTeamMenuPanel::Update( void )
{
int iYPos = TEAMMENU_TOPLEFT_BUTTON_Y;
// Set the team buttons
for( int i = 1; i <= 4; i++ )
{
if( m_pButtons[i] )
{
if( i <= gViewPort->GetNumberOfTeams() )
{
m_pButtons[i]->setText( gViewPort->GetTeamName( i ) );
// bound key replacement
char sz[32];
sprintf( sz, "%d", i );
m_pButtons[i]->setBoundKey( sz[0] );
m_pButtons[i]->setVisible( true );
m_pButtons[i]->setPos( TEAMMENU_TOPLEFT_BUTTON_X, iYPos );
iYPos += TEAMMENU_BUTTON_SIZE_Y + TEAMMENU_BUTTON_SPACER_Y;
// Start with the first option up
if( !m_iCurrentInfo )
SetActiveInfo( i );
char szPlayerList[( MAX_PLAYER_NAME_LENGTH + 3 ) * 31]; // name + ", "
strcpy(szPlayerList, "\n");
// Update the Team Info
// Now count the number of teammembers of this class
int iTotal = 0;
for( int j = 1; j < MAX_PLAYERS; j++ )
{
if( g_PlayerInfoList[j].name == NULL )
continue; // empty player slot, skip
if( g_PlayerInfoList[j].thisplayer )
continue; // skip this player
if( g_PlayerExtraInfo[j].teamnumber != i )
continue; // skip over players in other teams
iTotal++;
if( iTotal > 1 )
strncat( szPlayerList, ", ", sizeof(szPlayerList) - strlen( szPlayerList ) - 1 );
strncat( szPlayerList, g_PlayerInfoList[j].name, sizeof(szPlayerList) - strlen( szPlayerList ) - 1 );
szPlayerList[sizeof(szPlayerList) - 1] = '\0';
}
if( iTotal > 0 )
{
// Set the text of the info Panel
char szText[( ( MAX_PLAYER_NAME_LENGTH + 3 ) * 31 ) + 256];
if( iTotal == 1 )
sprintf( szText, "%s: %d Player (%d points)", gViewPort->GetTeamName( i ), iTotal, g_TeamInfo[i].frags );
else
sprintf( szText, "%s: %d Players (%d points)", gViewPort->GetTeamName( i ), iTotal, g_TeamInfo[i].frags );
strncat( szText, szPlayerList, sizeof(szText) - strlen( szText ) - 1 );
szText[sizeof(szText) - 1] = '\0';
m_pTeamInfoPanel[i]->setText( szText );
}
else
{
m_pTeamInfoPanel[i]->setText( "" );
}
}
else
{
// Hide the button (may be visible from previous maps)
m_pButtons[i]->setVisible( false );
}
}
}
// Move the AutoAssign button into place
m_pButtons[5]->setPos( TEAMMENU_TOPLEFT_BUTTON_X, iYPos );
iYPos += TEAMMENU_BUTTON_SIZE_Y + TEAMMENU_BUTTON_SPACER_Y;
// Spectate button
if( m_pSpectateButton->IsNotValid() )
{
m_pSpectateButton->setVisible( false );
}
else
{
m_pSpectateButton->setPos( TEAMMENU_TOPLEFT_BUTTON_X, iYPos );
m_pSpectateButton->setVisible( true );
iYPos += TEAMMENU_BUTTON_SIZE_Y + TEAMMENU_BUTTON_SPACER_Y;
}
// If the player is already in a team, make the cancel button visible
if( g_iTeamNumber )
{
m_pCancelButton->setPos( TEAMMENU_TOPLEFT_BUTTON_X, iYPos );
iYPos += TEAMMENU_BUTTON_SIZE_Y + TEAMMENU_BUTTON_SPACER_Y;
m_pCancelButton->setVisible( true );
}
else
{
m_pCancelButton->setVisible( false );
}
// Set the Map Title
if( !m_bUpdatedMapName )
{
const char *level = gEngfuncs.pfnGetLevelName();
if( level && level[0] )
{
char sz[256];
char szTitle[256];
char *ch;
// Update the level name
strcpy( sz, level );
ch = strchr( sz, '/' );
if( !ch )
ch = strchr( sz, '\\' );
strcpy( szTitle, ch + 1 );
ch = strchr( szTitle, '.' );
*ch = '\0';
m_pMapTitle->setText( "%s", szTitle );
*ch = '.';
// Update the map briefing
strcpy( sz, level );
ch = strchr( sz, '.' );
*ch = '\0';
strcat( sz, ".txt" );
char *pfile = (char*)gEngfuncs.COM_LoadFile( sz, 5, NULL );
if( pfile )
{
m_pBriefing->setText( pfile );
// Get the total size of the Briefing text and resize the text panel
int iXSize, iYSize;
m_pBriefing->getTextImage()->getTextSize( iXSize, iYSize );
m_pBriefing->setSize( iXSize, iYSize );
gEngfuncs.COM_FreeFile( pfile );
}
m_bUpdatedMapName = true;
}
}
m_pScrollPanel->validate();
}
//=====================================
// Key inputs
bool CTeamMenuPanel::SlotInput( int iSlot )
{
// Check for AutoAssign
if( iSlot == 5 )
{
m_pButtons[5]->fireActionSignal();
return true;
}
// Spectate
if( iSlot == 6 )
{
m_pSpectateButton->fireActionSignal();
return true;
}
// Otherwise, see if a particular team is selectable
if( ( iSlot < 1 ) || ( iSlot > gViewPort->GetNumberOfTeams() ) )
return false;
if( !m_pButtons[iSlot] )
return false;
// Is the button pushable?
if( m_pButtons[iSlot]->isVisible() )
{
m_pButtons[iSlot]->fireActionSignal();
return true;
}
return false;
}
//======================================
// Update the Team menu before opening it
void CTeamMenuPanel::Open( void )
{
Update();
CMenuPanel::Open();
}
void CTeamMenuPanel::paintBackground()
{
// make sure we get the map briefing up
if( !m_bUpdatedMapName )
Update();
CMenuPanel::paintBackground();
}
//======================================
// Mouse is over a team button, bring up the class info
void CTeamMenuPanel::SetActiveInfo( int iInput )
{
// Remove all the Info panels and bring up the specified one
m_pSpectateButton->setArmed( false );
for( int i = 1; i <= 5; i++ )
{
m_pButtons[i]->setArmed( false );
m_pTeamInfoPanel[i]->setVisible( false );
}
// 6 is Spectate
if( iInput == 6 )
{
m_pSpectateButton->setArmed( true );
}
else
{
m_pButtons[iInput]->setArmed( true );
m_pTeamInfoPanel[iInput]->setVisible( true );
}
m_iCurrentInfo = iInput;
m_pScrollPanel->validate();
}

884
cl_dll/voice_status.cpp Normal file
View File

@ -0,0 +1,884 @@
//========= Copyright <20> 1996-2001, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
// There are hud.h's coming out of the woodwork so this ensures that we get the right one.
#if defined(THREEWAVE) || defined(DMC_BUILD)
#include "../dmc/cl_dll/hud.h"
#elif defined(CSTRIKE)
#include "../cstrike/cl_dll/hud.h"
#elif defined(DOD)
#include "../dod/cl_dll/hud.h"
#else
#include "hud.h"
#endif
#include "cl_util.h"
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include "parsemsg.h"
#include "demo.h"
#include "demo_api.h"
#include "voice_status.h"
#include "r_efx.h"
#include "entity_types.h"
#include "VGUI_ActionSignal.h"
#include "VGUI_Scheme.h"
#include "VGUI_TextImage.h"
#include "vgui_loadtga.h"
#include "vgui_helpers.h"
#include "VGUI_MouseCode.h"
using namespace vgui;
extern int cam_thirdperson;
#define VOICE_MODEL_INTERVAL 0.3
#define SCOREBOARD_BLINK_FREQUENCY 0.3 // How often to blink the scoreboard icons.
#define SQUELCHOSCILLATE_PER_SECOND 2.0f
extern BitmapTGA *LoadTGA( const char* pImageName );
// ---------------------------------------------------------------------- //
// The voice manager for the client.
// ---------------------------------------------------------------------- //
CVoiceStatus g_VoiceStatus;
CVoiceStatus* GetClientVoiceMgr()
{
return &g_VoiceStatus;
}
// ---------------------------------------------------------------------- //
// CVoiceStatus.
// ---------------------------------------------------------------------- //
static CVoiceStatus *g_pInternalVoiceStatus = NULL;
int __MsgFunc_VoiceMask(const char *pszName, int iSize, void *pbuf)
{
if(g_pInternalVoiceStatus)
g_pInternalVoiceStatus->HandleVoiceMaskMsg(iSize, pbuf);
return 1;
}
int __MsgFunc_ReqState(const char *pszName, int iSize, void *pbuf)
{
if(g_pInternalVoiceStatus)
g_pInternalVoiceStatus->HandleReqStateMsg(iSize, pbuf);
return 1;
}
int g_BannedPlayerPrintCount;
void ForEachBannedPlayer(char id[16])
{
char str[256];
sprintf(str, "Ban %d: %2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x\n",
g_BannedPlayerPrintCount++,
id[0], id[1], id[2], id[3],
id[4], id[5], id[6], id[7],
id[8], id[9], id[10], id[11],
id[12], id[13], id[14], id[15]
);
#ifdef _WIN32
strupr(str);
#endif
gEngfuncs.pfnConsolePrint(str);
}
void ShowBannedCallback()
{
if(g_pInternalVoiceStatus)
{
g_BannedPlayerPrintCount = 0;
gEngfuncs.pfnConsolePrint("------- BANNED PLAYERS -------\n");
g_pInternalVoiceStatus->m_BanMgr.ForEachBannedPlayer(ForEachBannedPlayer);
gEngfuncs.pfnConsolePrint("------------------------------\n");
}
}
// ---------------------------------------------------------------------- //
// CVoiceStatus.
// ---------------------------------------------------------------------- //
CVoiceStatus::CVoiceStatus()
{
m_bBanMgrInitialized = false;
m_LastUpdateServerState = 0;
m_pSpeakerLabelIcon = NULL;
m_pScoreboardNeverSpoken = NULL;
m_pScoreboardNotSpeaking = NULL;
m_pScoreboardSpeaking = NULL;
m_pScoreboardSpeaking2 = NULL;
m_pScoreboardSquelch = NULL;
m_pScoreboardBanned = NULL;
m_pLocalBitmap = NULL;
m_pAckBitmap = NULL;
m_bTalking = m_bServerAcked = false;
memset(m_pBanButtons, 0, sizeof(m_pBanButtons));
m_pParentPanel = NULL;
m_bServerModEnable = -1;
m_pchGameDir = NULL;
}
CVoiceStatus::~CVoiceStatus()
{
g_pInternalVoiceStatus = NULL;
for(int i=0; i < MAX_VOICE_SPEAKERS; i++)
{
delete m_Labels[i].m_pLabel;
m_Labels[i].m_pLabel = NULL;
delete m_Labels[i].m_pIcon;
m_Labels[i].m_pIcon = NULL;
delete m_Labels[i].m_pBackground;
m_Labels[i].m_pBackground = NULL;
}
delete m_pLocalLabel;
m_pLocalLabel = NULL;
FreeBitmaps();
if(m_pchGameDir)
{
if(m_bBanMgrInitialized)
{
m_BanMgr.SaveState(m_pchGameDir);
}
free(m_pchGameDir);
}
}
int CVoiceStatus::Init(
IVoiceStatusHelper *pHelper,
Panel **pParentPanel)
{
// Setup the voice_modenable cvar.
gEngfuncs.pfnRegisterVariable("voice_modenable", "1", FCVAR_ARCHIVE);
gEngfuncs.pfnRegisterVariable("voice_clientdebug", "0", 0);
gEngfuncs.pfnAddCommand("voice_showbanned", ShowBannedCallback);
if(gEngfuncs.pfnGetGameDirectory())
{
m_BanMgr.Init(gEngfuncs.pfnGetGameDirectory());
m_bBanMgrInitialized = true;
}
assert(!g_pInternalVoiceStatus);
g_pInternalVoiceStatus = this;
m_BlinkTimer = 0;
m_VoiceHeadModel = 0;
memset(m_Labels, 0, sizeof(m_Labels));
for(int i=0; i < MAX_VOICE_SPEAKERS; i++)
{
CVoiceLabel *pLabel = &m_Labels[i];
pLabel->m_pBackground = new Label("");
if((pLabel->m_pLabel = new Label("")) != 0)
{
pLabel->m_pLabel->setVisible( true );
pLabel->m_pLabel->setFont( Scheme::sf_primary2 );
pLabel->m_pLabel->setTextAlignment( Label::a_east );
pLabel->m_pLabel->setContentAlignment( Label::a_east );
pLabel->m_pLabel->setParent( pLabel->m_pBackground );
}
if( (pLabel->m_pIcon = new ImagePanel( NULL )) != 0 )
{
pLabel->m_pIcon->setVisible( true );
pLabel->m_pIcon->setParent( pLabel->m_pBackground );
}
pLabel->m_clientindex = -1;
}
m_pLocalLabel = new ImagePanel(NULL);
m_bInSquelchMode = false;
m_pHelper = pHelper;
m_pParentPanel = pParentPanel;
gHUD.AddHudElem(this);
m_iFlags = HUD_ACTIVE;
HOOK_MESSAGE(VoiceMask);
HOOK_MESSAGE(ReqState);
// Cache the game directory for use when we shut down
const char *pchGameDirT = gEngfuncs.pfnGetGameDirectory();
m_pchGameDir = (char *)malloc(strlen(pchGameDirT) + 1);
strcpy(m_pchGameDir, pchGameDirT);
return 1;
}
int CVoiceStatus::VidInit()
{
FreeBitmaps();
if( (m_pLocalBitmap = vgui_LoadTGA("gfx/vgui/icntlk_pl.tga")) != 0 )
{
m_pLocalBitmap->setColor(Color(255,255,255,135));
}
if( (m_pAckBitmap = vgui_LoadTGA("gfx/vgui/icntlk_sv.tga")) != 0 )
{
m_pAckBitmap->setColor(Color(255,255,255,135)); // Give just a tiny bit of translucency so software draws correctly.
}
m_pLocalLabel->setImage( m_pLocalBitmap );
m_pLocalLabel->setVisible( false );
if( (m_pSpeakerLabelIcon = vgui_LoadTGANoInvertAlpha("gfx/vgui/speaker4.tga" )) != 0 )
m_pSpeakerLabelIcon->setColor( Color(255,255,255,1) ); // Give just a tiny bit of translucency so software draws correctly.
if ((m_pScoreboardNeverSpoken = vgui_LoadTGANoInvertAlpha("gfx/vgui/640_speaker1.tga")) != 0)
m_pScoreboardNeverSpoken->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly.
if((m_pScoreboardNotSpeaking = vgui_LoadTGANoInvertAlpha("gfx/vgui/640_speaker2.tga")) != 0)
m_pScoreboardNotSpeaking->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly.
if((m_pScoreboardSpeaking = vgui_LoadTGANoInvertAlpha("gfx/vgui/640_speaker3.tga")) != 0)
m_pScoreboardSpeaking->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly.
if((m_pScoreboardSpeaking2 = vgui_LoadTGANoInvertAlpha("gfx/vgui/640_speaker4.tga")) != 0)
m_pScoreboardSpeaking2->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly.
if((m_pScoreboardSquelch = vgui_LoadTGA("gfx/vgui/icntlk_squelch.tga")) != 0)
m_pScoreboardSquelch->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly.
if((m_pScoreboardBanned = vgui_LoadTGA("gfx/vgui/640_voiceblocked.tga")) != 0)
m_pScoreboardBanned->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly.
// Figure out the voice head model height.
m_VoiceHeadModelHeight = 45;
char *pFile = (char *)gEngfuncs.COM_LoadFile("scripts/voicemodel.txt", 5, NULL);
if(pFile)
{
char token[4096];
gEngfuncs.COM_ParseFile(pFile, token);
if(token[0] >= '0' && token[0] <= '9')
{
m_VoiceHeadModelHeight = (float)atof(token);
}
gEngfuncs.COM_FreeFile(pFile);
}
m_VoiceHeadModel = gEngfuncs.pfnSPR_Load("sprites/voiceicon.spr");
return TRUE;
}
void CVoiceStatus::Frame(double frametime)
{
// check server banned players once per second
if(gEngfuncs.GetClientTime() - m_LastUpdateServerState > 1)
{
UpdateServerState(false);
}
m_BlinkTimer += frametime;
// Update speaker labels.
if( m_pHelper->CanShowSpeakerLabels() )
{
for( int i=0; i < MAX_VOICE_SPEAKERS; i++ )
m_Labels[i].m_pBackground->setVisible( m_Labels[i].m_clientindex != -1 );
}
else
{
for( int i=0; i < MAX_VOICE_SPEAKERS; i++ )
m_Labels[i].m_pBackground->setVisible( false );
}
for(int i=0; i < VOICE_MAX_PLAYERS; i++)
UpdateBanButton(i);
}
void CVoiceStatus::CreateEntities()
{
if(!m_VoiceHeadModel)
return;
cl_entity_t *localPlayer = gEngfuncs.GetLocalPlayer();
int iOutModel = 0;
for(int i=0; i < VOICE_MAX_PLAYERS; i++)
{
if(!m_VoicePlayers[i])
continue;
cl_entity_s *pClient = gEngfuncs.GetEntityByIndex(i+1);
// Don't show an icon if the player is not in our PVS.
if(!pClient || pClient->curstate.messagenum < localPlayer->curstate.messagenum)
continue;
// Don't show an icon for dead or spectating players (ie: invisible entities).
if(pClient->curstate.effects & EF_NODRAW)
continue;
// Don't show an icon for the local player unless we're in thirdperson mode.
if(pClient == localPlayer && !cam_thirdperson)
continue;
cl_entity_s *pEnt = &m_VoiceHeadModels[iOutModel];
++iOutModel;
memset(pEnt, 0, sizeof(*pEnt));
pEnt->curstate.rendermode = kRenderTransAdd;
pEnt->curstate.renderamt = 255;
pEnt->baseline.renderamt = 255;
pEnt->curstate.renderfx = kRenderFxNoDissipation;
pEnt->curstate.framerate = 1;
pEnt->curstate.frame = 0;
pEnt->model = (struct model_s*)gEngfuncs.GetSpritePointer(m_VoiceHeadModel);
pEnt->angles[0] = pEnt->angles[1] = pEnt->angles[2] = 0;
pEnt->curstate.scale = 0.5f;
pEnt->origin[0] = pEnt->origin[1] = 0;
pEnt->origin[2] = 45;
VectorAdd(pEnt->origin, pClient->origin, pEnt->origin);
// Tell the engine.
gEngfuncs.CL_CreateVisibleEntity(ET_NORMAL, pEnt);
}
}
void CVoiceStatus::UpdateSpeakerStatus( int entindex, qboolean bTalking )
{
cvar_t *pVoiceLoopback = NULL;
if ( !m_pParentPanel || !*m_pParentPanel )
{
return;
}
if ( gEngfuncs.pfnGetCvarFloat( "voice_clientdebug" ) )
{
char msg[256];
_snprintf( msg, sizeof( msg ), "CVoiceStatus::UpdateSpeakerStatus: ent %d talking = %d\n", entindex, bTalking );
gEngfuncs.pfnConsolePrint( msg );
}
int iLocalPlayerIndex = gEngfuncs.GetLocalPlayer()->index;
// Is it the local player talking?
if ( entindex == -1 )
{
m_bTalking = !!bTalking;
if( bTalking )
{
// Enable voice for them automatically if they try to talk.
gEngfuncs.pfnClientCmd( "voice_modenable 1" );
}
// now set the player index to the correct index for the local player
// this will allow us to have the local player's icon flash in the scoreboard
entindex = iLocalPlayerIndex;
pVoiceLoopback = gEngfuncs.pfnGetCvarPointer( "voice_loopback" );
}
else if ( entindex == -2 )
{
m_bServerAcked = !!bTalking;
}
if ( entindex >= 0 && entindex <= VOICE_MAX_PLAYERS )
{
int iClient = entindex - 1;
if ( iClient < 0 )
{
return;
}
CVoiceLabel *pLabel = FindVoiceLabel( iClient );
if ( bTalking )
{
m_VoicePlayers[iClient] = true;
m_VoiceEnabledPlayers[iClient] = true;
// If we don't have a label for this guy yet, then create one.
if ( !pLabel )
{
// if this isn't the local player (unless they have voice_loopback on)
if ( ( entindex != iLocalPlayerIndex ) || ( pVoiceLoopback && pVoiceLoopback->value ) )
{
if ( (pLabel = GetFreeVoiceLabel()) != 0 )
{
// Get the name from the engine.
hud_player_info_t info;
memset( &info, 0, sizeof( info ) );
gEngfuncs.pfnGetPlayerInfo( entindex, &info );
char paddedName[512];
_snprintf( paddedName, sizeof( paddedName ), "%s ", info.name );
int color[3];
m_pHelper->GetPlayerTextColor( entindex, color );
if ( pLabel->m_pBackground )
{
pLabel->m_pBackground->setBgColor( color[0], color[1], color[2], 135 );
pLabel->m_pBackground->setParent( *m_pParentPanel );
pLabel->m_pBackground->setVisible( m_pHelper->CanShowSpeakerLabels() );
}
if ( pLabel->m_pLabel )
{
pLabel->m_pLabel->setFgColor( 255, 255, 255, 0 );
pLabel->m_pLabel->setBgColor( 0, 0, 0, 255 );
pLabel->m_pLabel->setText( "%s", paddedName );
}
pLabel->m_clientindex = iClient;
}
}
}
}
else
{
m_VoicePlayers[iClient] = false;
// If we have a label for this guy, kill it.
if ( pLabel )
{
pLabel->m_pBackground->setVisible( false );
pLabel->m_clientindex = -1;
}
}
}
RepositionLabels();
}
void CVoiceStatus::UpdateServerState(bool bForce)
{
// Can't do anything when we're not in a level.
char const *pLevelName = gEngfuncs.pfnGetLevelName();
if( pLevelName[0] == 0 )
{
if( gEngfuncs.pfnGetCvarFloat("voice_clientdebug") )
{
gEngfuncs.pfnConsolePrint( "CVoiceStatus::UpdateServerState: pLevelName[0]==0\n" );
}
return;
}
int bCVarModEnable = !!gEngfuncs.pfnGetCvarFloat("voice_modenable");
if(bForce || m_bServerModEnable != bCVarModEnable)
{
m_bServerModEnable = bCVarModEnable;
char str[256];
_snprintf(str, sizeof(str), "VModEnable %d", m_bServerModEnable);
ServerCmd(str);
if(gEngfuncs.pfnGetCvarFloat("voice_clientdebug"))
{
char msg[256];
sprintf(msg, "CVoiceStatus::UpdateServerState: Sending '%s'\n", str);
gEngfuncs.pfnConsolePrint(msg);
}
}
char str[2048];
sprintf(str, "vban");
bool bChange = false;
for(unsigned long dw=0; dw < VOICE_MAX_PLAYERS_DW; dw++)
{
unsigned int serverBanMask = 0;
unsigned int banMask = 0;
for(unsigned int i=0; i < 32; i++)
{
char playerID[16];
if(!gEngfuncs.GetPlayerUniqueID(i+1, playerID))
continue;
if(m_BanMgr.GetPlayerBan(playerID))
banMask |= 1 << i;
if(m_ServerBannedPlayers[dw*32 + i])
serverBanMask |= 1 << i;
}
if(serverBanMask != banMask)
bChange = true;
// Ok, the server needs to be updated.
char numStr[512];
sprintf(numStr, " %x", banMask);
strcat(str, numStr);
}
if(bChange || bForce)
{
if(gEngfuncs.pfnGetCvarFloat("voice_clientdebug"))
{
char msg[256];
sprintf(msg, "CVoiceStatus::UpdateServerState: Sending '%s'\n", str);
gEngfuncs.pfnConsolePrint(msg);
}
gEngfuncs.pfnServerCmdUnreliable(str); // Tell the server..
}
else
{
if (gEngfuncs.pfnGetCvarFloat("voice_clientdebug"))
{
gEngfuncs.pfnConsolePrint( "CVoiceStatus::UpdateServerState: no change\n" );
}
}
m_LastUpdateServerState = gEngfuncs.GetClientTime();
}
void CVoiceStatus::UpdateSpeakerImage(Label *pLabel, int iPlayer)
{
m_pBanButtons[iPlayer-1] = pLabel;
UpdateBanButton(iPlayer-1);
}
void CVoiceStatus::UpdateBanButton(int iClient)
{
Label *pPanel = m_pBanButtons[iClient];
if (!pPanel)
return;
char playerID[16];
extern bool HACK_GetPlayerUniqueID( int iPlayer, char playerID[16] );
if(!HACK_GetPlayerUniqueID(iClient+1, playerID))
return;
// Figure out if it's blinking or not.
bool bBlink = fmod(m_BlinkTimer, SCOREBOARD_BLINK_FREQUENCY*2) < SCOREBOARD_BLINK_FREQUENCY;
bool bTalking = !!m_VoicePlayers[iClient];
bool bBanned = m_BanMgr.GetPlayerBan(playerID);
bool bNeverSpoken = !m_VoiceEnabledPlayers[iClient];
// Get the appropriate image to display on the panel.
if (bBanned)
{
pPanel->setImage(m_pScoreboardBanned);
}
else if (bTalking)
{
if (bBlink)
{
pPanel->setImage(m_pScoreboardSpeaking2);
}
else
{
pPanel->setImage(m_pScoreboardSpeaking);
}
pPanel->setFgColor(255, 170, 0, 1);
}
else if (bNeverSpoken)
{
pPanel->setImage(m_pScoreboardNeverSpoken);
pPanel->setFgColor(100, 100, 100, 1);
}
else
{
pPanel->setImage(m_pScoreboardNotSpeaking);
}
}
void CVoiceStatus::HandleVoiceMaskMsg(int iSize, void *pbuf)
{
BEGIN_READ( pbuf, iSize );
unsigned int dw;
for(dw=0; dw < VOICE_MAX_PLAYERS_DW; dw++)
{
m_AudiblePlayers.SetDWord(dw, (unsigned long)READ_LONG());
m_ServerBannedPlayers.SetDWord(dw, (unsigned long)READ_LONG());
if(gEngfuncs.pfnGetCvarFloat("voice_clientdebug"))
{
char str[256];
gEngfuncs.pfnConsolePrint("CVoiceStatus::HandleVoiceMaskMsg\n");
sprintf(str, " - m_AudiblePlayers[%d] = %lu\n", dw, m_AudiblePlayers.GetDWord(dw));
gEngfuncs.pfnConsolePrint(str);
sprintf(str, " - m_ServerBannedPlayers[%d] = %lu\n", dw, m_ServerBannedPlayers.GetDWord(dw));
gEngfuncs.pfnConsolePrint(str);
}
}
m_bServerModEnable = READ_BYTE();
}
void CVoiceStatus::HandleReqStateMsg(int iSize, void *pbuf)
{
if(gEngfuncs.pfnGetCvarFloat("voice_clientdebug"))
{
gEngfuncs.pfnConsolePrint("CVoiceStatus::HandleReqStateMsg\n");
}
UpdateServerState(true);
}
void CVoiceStatus::StartSquelchMode()
{
if(m_bInSquelchMode)
return;
m_bInSquelchMode = true;
m_pHelper->UpdateCursorState();
}
void CVoiceStatus::StopSquelchMode()
{
m_bInSquelchMode = false;
m_pHelper->UpdateCursorState();
}
bool CVoiceStatus::IsInSquelchMode()
{
return m_bInSquelchMode;
}
CVoiceLabel* CVoiceStatus::FindVoiceLabel(int clientindex)
{
for(int i=0; i < MAX_VOICE_SPEAKERS; i++)
{
if(m_Labels[i].m_clientindex == clientindex)
return &m_Labels[i];
}
return NULL;
}
CVoiceLabel* CVoiceStatus::GetFreeVoiceLabel()
{
return FindVoiceLabel(-1);
}
void CVoiceStatus::RepositionLabels()
{
// find starting position to draw from, along right-hand side of screen
int y = ScreenHeight / 2;
int iconWide = 8, iconTall = 8;
if( m_pSpeakerLabelIcon )
{
m_pSpeakerLabelIcon->getSize( iconWide, iconTall );
}
// Reposition active labels.
for(int i = 0; i < MAX_VOICE_SPEAKERS; i++)
{
CVoiceLabel *pLabel = &m_Labels[i];
if( pLabel->m_clientindex == -1 || !pLabel->m_pLabel )
{
if( pLabel->m_pBackground )
pLabel->m_pBackground->setVisible( false );
continue;
}
int textWide, textTall;
pLabel->m_pLabel->getContentSize( textWide, textTall );
// Don't let it stretch too far across their screen.
if( textWide > (ScreenWidth*2)/3 )
textWide = (ScreenWidth*2)/3;
// Setup the background label to fit everything in.
int border = 2;
int bgWide = textWide + iconWide + border*3;
int bgTall = Q_max( textTall, iconTall ) + border*2;
pLabel->m_pBackground->setBounds( ScreenWidth - bgWide - 8, y, bgWide, bgTall );
// Put the text at the left.
pLabel->m_pLabel->setBounds( border, (bgTall - textTall) / 2, textWide, textTall );
// Put the icon at the right.
int iconLeft = border + textWide + border;
int iconTop = (bgTall - iconTall) / 2;
if( pLabel->m_pIcon )
{
pLabel->m_pIcon->setImage( m_pSpeakerLabelIcon );
pLabel->m_pIcon->setBounds( iconLeft, iconTop, iconWide, iconTall );
}
y += bgTall + 2;
}
if( m_pLocalBitmap && m_pAckBitmap && m_pLocalLabel && (m_bTalking || m_bServerAcked) )
{
m_pLocalLabel->setParent(*m_pParentPanel);
m_pLocalLabel->setVisible( true );
if( m_bServerAcked && !!gEngfuncs.pfnGetCvarFloat("voice_clientdebug") )
m_pLocalLabel->setImage( m_pAckBitmap );
else
m_pLocalLabel->setImage( m_pLocalBitmap );
int sizeX, sizeY;
m_pLocalBitmap->getSize(sizeX, sizeY);
int local_xPos = ScreenWidth - sizeX - 10;
int local_yPos = m_pHelper->GetAckIconHeight() - sizeY;
m_pLocalLabel->setPos( local_xPos, local_yPos );
}
else
{
m_pLocalLabel->setVisible( false );
}
}
void CVoiceStatus::FreeBitmaps()
{
// Delete all the images we have loaded.
delete m_pLocalBitmap;
m_pLocalBitmap = NULL;
delete m_pAckBitmap;
m_pAckBitmap = NULL;
delete m_pSpeakerLabelIcon;
m_pSpeakerLabelIcon = NULL;
delete m_pScoreboardNeverSpoken;
m_pScoreboardNeverSpoken = NULL;
delete m_pScoreboardNotSpeaking;
m_pScoreboardNotSpeaking = NULL;
delete m_pScoreboardSpeaking;
m_pScoreboardSpeaking = NULL;
delete m_pScoreboardSpeaking2;
m_pScoreboardSpeaking2 = NULL;
delete m_pScoreboardSquelch;
m_pScoreboardSquelch = NULL;
delete m_pScoreboardBanned;
m_pScoreboardBanned = NULL;
// Clear references to the images in panels.
for(int i=0; i < VOICE_MAX_PLAYERS; i++)
{
if (m_pBanButtons[i])
{
m_pBanButtons[i]->setImage(NULL);
}
}
if(m_pLocalLabel)
m_pLocalLabel->setImage(NULL);
}
//-----------------------------------------------------------------------------
// Purpose: returns true if the target client has been banned
// Input : playerID -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CVoiceStatus::IsPlayerBlocked(int iPlayer)
{
char playerID[16];
if (!gEngfuncs.GetPlayerUniqueID(iPlayer, playerID))
return false;
return m_BanMgr.GetPlayerBan(playerID);
}
//-----------------------------------------------------------------------------
// Purpose: returns true if the player can't hear the other client due to game rules (eg. the other team)
// Input : playerID -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CVoiceStatus::IsPlayerAudible(int iPlayer)
{
return !!m_AudiblePlayers[iPlayer-1];
}
//-----------------------------------------------------------------------------
// Purpose: blocks/unblocks the target client from being heard
// Input : playerID -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
void CVoiceStatus::SetPlayerBlockedState(int iPlayer, bool blocked)
{
if (gEngfuncs.pfnGetCvarFloat("voice_clientdebug"))
{
gEngfuncs.pfnConsolePrint( "CVoiceStatus::SetPlayerBlockedState part 1\n" );
}
char playerID[16];
if (!gEngfuncs.GetPlayerUniqueID(iPlayer, playerID))
return;
if (gEngfuncs.pfnGetCvarFloat("voice_clientdebug"))
{
gEngfuncs.pfnConsolePrint( "CVoiceStatus::SetPlayerBlockedState part 2\n" );
}
// Squelch or (try to) unsquelch this player.
if (gEngfuncs.pfnGetCvarFloat("voice_clientdebug"))
{
char str[256];
sprintf(str, "CVoiceStatus::SetPlayerBlockedState: setting player %d ban to %d\n", iPlayer, !m_BanMgr.GetPlayerBan(playerID));
gEngfuncs.pfnConsolePrint(str);
}
m_BanMgr.SetPlayerBan( playerID, blocked );
UpdateServerState(false);
}

228
cl_dll/voice_status.h Normal file
View File

@ -0,0 +1,228 @@
//========= Copyright (c) 1996-2001, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#ifndef VOICE_STATUS_H
#define VOICE_STATUS_H
#pragma once
#include "VGUI_Label.h"
#include "VGUI_LineBorder.h"
#include "VGUI_ImagePanel.h"
#include "VGUI_BitmapTGA.h"
#include "VGUI_InputSignal.h"
#include "VGUI_Button.h"
#include "voice_common.h"
#include "cl_entity.h"
#include "voice_banmgr.h"
#include "vgui_checkbutton2.h"
#include "vgui_defaultinputsignal.h"
class CVoiceStatus;
class CVoiceLabel
{
public:
vgui::Label *m_pLabel;
vgui::Label *m_pBackground;
vgui::ImagePanel *m_pIcon; // Voice icon next to player name.
int m_clientindex; // Client index of the speaker. -1 if this label isn't being used.
};
// This is provided by each mod to access data that may not be the same across mods.
class IVoiceStatusHelper
{
public:
virtual ~IVoiceStatusHelper() {}
// Get RGB color for voice status text about this player.
virtual void GetPlayerTextColor(int entindex, int color[3]) = 0;
// Force it to update the cursor state.
virtual void UpdateCursorState() = 0;
// Return the height above the bottom that the voice ack icons should be drawn at.
virtual int GetAckIconHeight() = 0;
// Return true if the voice manager is allowed to show speaker labels
// (mods usually return false when the scoreboard is up).
virtual bool CanShowSpeakerLabels() = 0;
};
//-----------------------------------------------------------------------------
// Purpose: Holds a color for the shared image
//-----------------------------------------------------------------------------
class VoiceImagePanel : public vgui::ImagePanel
{
virtual void paintBackground()
{
if (_image!=null)
{
vgui::Color col;
getFgColor(col);
_image->setColor(col);
_image->doPaint(this);
}
}
};
class CVoiceStatus : public CHudBase, public vgui::CDefaultInputSignal
{
public:
CVoiceStatus();
virtual ~CVoiceStatus();
// CHudBase overrides.
public:
// Initialize the cl_dll's voice manager.
virtual int Init(
IVoiceStatusHelper *m_pHelper,
vgui::Panel **pParentPanel);
// ackPosition is the bottom position of where CVoiceStatus will draw the voice acknowledgement labels.
virtual int VidInit();
public:
// Call from HUD_Frame each frame.
void Frame(double frametime);
// Called when a player starts or stops talking.
// entindex is -1 to represent the local client talking (before the data comes back from the server).
// When the server acknowledges that the local client is talking, then entindex will be gEngfuncs.GetLocalPlayer().
// entindex is -2 to represent the local client's voice being acked by the server.
void UpdateSpeakerStatus(int entindex, qboolean bTalking);
// sets the correct image in the label for the player
void UpdateSpeakerImage(vgui::Label *pLabel, int iPlayer);
// Call from the HUD_CreateEntities function so it can add sprites above player heads.
void CreateEntities();
// Called when the server registers a change to who this client can hear.
void HandleVoiceMaskMsg(int iSize, void *pbuf);
// The server sends this message initially to tell the client to send their state.
void HandleReqStateMsg(int iSize, void *pbuf);
// Squelch mode functions.
public:
// When you enter squelch mode, pass in
void StartSquelchMode();
void StopSquelchMode();
bool IsInSquelchMode();
// returns true if the target client has been banned
// playerIndex is of range 1..maxplayers
bool IsPlayerBlocked(int iPlayerIndex);
// returns false if the player can't hear the other client due to game rules (eg. the other team)
bool IsPlayerAudible(int iPlayerIndex);
// blocks the target client from being heard
void SetPlayerBlockedState(int iPlayerIndex, bool blocked);
public:
CVoiceLabel* FindVoiceLabel(int clientindex); // Find a CVoiceLabel representing the specified speaker.
// Returns NULL if none.
// entindex can be -1 if you want a currently-unused voice label.
CVoiceLabel* GetFreeVoiceLabel(); // Get an unused voice label. Returns NULL if none.
void RepositionLabels();
void FreeBitmaps();
void UpdateServerState(bool bForce);
// Update the button artwork to reflect the client's current state.
void UpdateBanButton(int iClient);
public:
enum {MAX_VOICE_SPEAKERS=7};
float m_LastUpdateServerState; // Last time we called this function.
int m_bServerModEnable; // What we've sent to the server about our "voice_modenable" cvar.
vgui::Panel **m_pParentPanel;
CPlayerBitVec m_VoicePlayers; // Who is currently talking. Indexed by client index.
// This is the gamerules-defined list of players that you can hear. It is based on what teams people are on
// and is totally separate from the ban list. Indexed by client index.
CPlayerBitVec m_AudiblePlayers;
// Players who have spoken at least once in the game so far
CPlayerBitVec m_VoiceEnabledPlayers;
// This is who the server THINKS we have banned (it can become incorrect when a new player arrives on the server).
// It is checked periodically, and the server is told to squelch or unsquelch the appropriate players.
CPlayerBitVec m_ServerBannedPlayers;
cl_entity_s m_VoiceHeadModels[VOICE_MAX_PLAYERS]; // These aren't necessarily in the order of players. They are just
// a place for it to put data in during CreateEntities.
IVoiceStatusHelper *m_pHelper; // Each mod provides an implementation of this.
// Scoreboard icons.
double m_BlinkTimer; // Blink scoreboard icons..
vgui::BitmapTGA *m_pScoreboardNeverSpoken;
vgui::BitmapTGA *m_pScoreboardNotSpeaking;
vgui::BitmapTGA *m_pScoreboardSpeaking;
vgui::BitmapTGA *m_pScoreboardSpeaking2;
vgui::BitmapTGA *m_pScoreboardSquelch;
vgui::BitmapTGA *m_pScoreboardBanned;
vgui::Label *m_pBanButtons[VOICE_MAX_PLAYERS]; // scoreboard buttons.
// Squelch mode stuff.
bool m_bInSquelchMode;
HSPRITE m_VoiceHeadModel; // Voice head model (goes above players who are speaking).
float m_VoiceHeadModelHeight; // Height above their head to place the model.
vgui::Image *m_pSpeakerLabelIcon; // Icon next to speaker labels.
// Lower-right icons telling when the local player is talking..
vgui::BitmapTGA *m_pLocalBitmap; // Represents the local client talking.
vgui::BitmapTGA *m_pAckBitmap; // Represents the server ack'ing the client talking.
vgui::ImagePanel *m_pLocalLabel; // Represents the local client talking.
bool m_bTalking; // Set to true when the client thinks it's talking.
bool m_bServerAcked; // Set to true when the server knows the client is talking.
public:
CVoiceBanMgr m_BanMgr; // Tracks which users we have squelched and don't want to hear.
public:
bool m_bBanMgrInitialized;
// Labels telling who is speaking.
CVoiceLabel m_Labels[MAX_VOICE_SPEAKERS];
// Cache the game directory for use when we shut down
char * m_pchGameDir;
};
// Get the (global) voice manager.
CVoiceStatus* GetClientVoiceMgr();
#endif // VOICE_STATUS_H

7
common/winsani_in.h Normal file
View File

@ -0,0 +1,7 @@
#if _MSC_VER >= 1500 // MSVC++ 9.0 (Visual Studio 2008)
#pragma push_macro("ARRAYSIZE")
#ifdef ARRAYSIZE
#undef ARRAYSIZE
#endif
#define HSPRITE WINDOWS_HSPRITE
#endif

4
common/winsani_out.h Normal file
View File

@ -0,0 +1,4 @@
#if _MSC_VER >= 1500 // MSVC++ 9.0 (Visual Studio 2008)
#undef HSPRITE
#pragma pop_macro("ARRAYSIZE")
#endif

View File

@ -1,10 +1,9 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//========= Copyright <EFBFBD> 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#pragma once
#if !defined(BITVEC_H)
#define BITVEC_H
@ -155,3 +154,4 @@ inline void CBitVec<NUM_BITS>::SetDWord( int i, unsigned long val )
m_DWords[i] = val;
}
#endif // BITVEC_H

View File

@ -10,57 +10,50 @@
#include "vgui_checkbutton2.h"
#include "vgui_loadtga.h"
#define EXTRA_X 5
using namespace vgui;
CCheckButton2::CCheckButton2() :
m_Label(""),
m_pChecked(NULL),
m_pUnchecked(NULL),
m_pHandler(NULL),
m_CheckboxPanel(NULL)
m_Label( "" ),
m_pChecked( NULL ),
m_pUnchecked( NULL ),
m_pHandler( NULL ),
m_CheckboxPanel( NULL )
{
m_bOwnImages = false;
m_bChecked = false;
m_pChecked = m_pUnchecked = NULL;
m_bCheckboxLeft = true;
m_Label.setParent(this);
m_Label.setFgColor(255,255,255,0);
m_Label.setBgColor(0,0,0,255); // background is not drawn and foreground is white
m_Label.addInputSignal(this);
m_Label.setParent( this );
m_Label.setFgColor( 255, 255, 255, 0 );
m_Label.setBgColor( 0, 0, 0, 255 ); // background is not drawn and foreground is white
m_Label.addInputSignal( this );
m_CheckboxPanel.setParent(this);
m_CheckboxPanel.addInputSignal(this);
m_CheckboxPanel.setParent( this );
m_CheckboxPanel.addInputSignal( this );
setPaintBackgroundEnabled(false);
setPaintBackgroundEnabled( false );
}
CCheckButton2::~CCheckButton2()
{
DeleteImages();
}
void CCheckButton2::SetImages(char const *pChecked, char const *pUnchecked)
void CCheckButton2::SetImages( char const *pChecked, char const *pUnchecked )
{
DeleteImages();
m_pChecked = vgui_LoadTGA(pChecked);
m_pUnchecked = vgui_LoadTGA(pUnchecked);
m_pChecked = vgui_LoadTGA( pChecked );
m_pUnchecked = vgui_LoadTGA( pUnchecked );
m_bOwnImages = true;
SetupControls();
}
void CCheckButton2::SetImages(Image *pChecked, Image *pUnchecked)
void CCheckButton2::SetImages( Image *pChecked, Image *pUnchecked )
{
DeleteImages();
@ -71,10 +64,9 @@ void CCheckButton2::SetImages(Image *pChecked, Image *pUnchecked)
SetupControls();
}
void CCheckButton2::DeleteImages()
{
if(m_bOwnImages)
if( m_bOwnImages )
{
delete m_pChecked;
delete m_pUnchecked;
@ -87,71 +79,62 @@ void CCheckButton2::DeleteImages()
SetupControls();
}
void CCheckButton2::SetCheckboxLeft(bool bLeftAlign)
void CCheckButton2::SetCheckboxLeft( bool bLeftAlign )
{
m_bCheckboxLeft = bLeftAlign;
SetupControls();
}
bool CCheckButton2::GetCheckboxLeft()
{
return m_bCheckboxLeft;
}
void CCheckButton2::SetText(char const *pText, ...)
void CCheckButton2::SetText( char const *pText, ... )
{
char str[512];
va_list marker;
va_start(marker, pText);
_vsnprintf(str, sizeof(str), pText, marker);
va_end(marker);
m_Label.setText(str);
va_list marker;
va_start( marker, pText );
_vsnprintf( str, sizeof( str ), pText, marker );
va_end( marker );
m_Label.setText( str );
SetupControls();
}
void CCheckButton2::SetTextColor(int r, int g, int b, int a)
void CCheckButton2::SetTextColor( int r, int g, int b, int a )
{
m_Label.setFgColor(r, g, b, a);
m_Label.setFgColor( r, g, b, a );
repaint();
}
void CCheckButton2::SetHandler(ICheckButton2Handler *pHandler)
void CCheckButton2::SetHandler( ICheckButton2Handler *pHandler )
{
m_pHandler = pHandler;
}
bool CCheckButton2::IsChecked()
{
return m_bChecked;
}
void CCheckButton2::SetChecked(bool bChecked)
void CCheckButton2::SetChecked( bool bChecked )
{
m_bChecked = bChecked;
SetupControls();
}
void CCheckButton2::internalMousePressed(MouseCode code)
void CCheckButton2::internalMousePressed( MouseCode code )
{
m_bChecked = !m_bChecked;
if(m_pHandler)
m_pHandler->StateChanged(this);
if( m_pHandler )
m_pHandler->StateChanged( this );
SetupControls();
}
void CCheckButton2::SetupControls()
{
// Initialize the checkbutton bitmap.
@ -161,37 +144,28 @@ void CCheckButton2::SetupControls()
int controlSizes[2][2];
controlSizes[0][0] = controlSizes[0][1] = 0;
if(pBitmap)
pBitmap->getSize(controlSizes[0][0], controlSizes[0][1]);
m_CheckboxPanel.setImage(pBitmap);
m_CheckboxPanel.setSize(controlSizes[0][0], controlSizes[0][1]);
if( pBitmap )
pBitmap->getSize( controlSizes[0][0], controlSizes[0][1] );
m_CheckboxPanel.setImage( pBitmap );
m_CheckboxPanel.setSize( controlSizes[0][0], controlSizes[0][1] );
// Get the label's size.
m_Label.getSize(controlSizes[1][0], controlSizes[1][1]);
m_Label.setContentAlignment(Label::a_west);
m_Label.getSize( controlSizes[1][0], controlSizes[1][1] );
m_Label.setContentAlignment( Label::a_west );
// Position the controls.
int iLeftControl = !m_bCheckboxLeft;
int iBiggestY = controlSizes[0][1] > controlSizes[1][0] ? 0 : 1;
controls[iLeftControl]->setPos(0, (controlSizes[iBiggestY][1] - controlSizes[iLeftControl][1]) / 2);
controls[!iLeftControl]->setPos(controlSizes[iLeftControl][0] + EXTRA_X, (controlSizes[iBiggestY][1] - controlSizes[!iLeftControl][1]) / 2);
controls[iLeftControl]->setPos( 0, ( controlSizes[iBiggestY][1] - controlSizes[iLeftControl][1] ) / 2 );
controls[!iLeftControl]->setPos( controlSizes[iLeftControl][0] + EXTRA_X, ( controlSizes[iBiggestY][1] - controlSizes[!iLeftControl][1]) / 2 );
// Fit this control to the sizes of the subcontrols.
setSize(controlSizes[0][0] + controlSizes[1][0] + EXTRA_X, (controlSizes[0][1] > controlSizes[1][1]) ? controlSizes[0][1] : controlSizes[1][1]);
setSize(controlSizes[0][0] + controlSizes[1][0] + EXTRA_X, ( controlSizes[0][1] > controlSizes[1][1]) ? controlSizes[0][1] : controlSizes[1][1] );
repaint();
}
void CCheckButton2::mousePressed(MouseCode code, Panel *panel)
void CCheckButton2::mousePressed( MouseCode code, Panel *panel )
{
internalMousePressed(code);
internalMousePressed( code );
}

View File

@ -1,32 +1,29 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//========= Copyright <EFBFBD> 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#pragma once
#if !defined(VGUI_CHECKBUTTON2_H)
#ifndef VGUI_CHECKBUTTON2_H
#define VGUI_CHECKBUTTON2_H
#ifdef _WIN32
#pragma once
#endif
#include "vgui_label.h"
#include "vgui_imagepanel.h"
#include "VGUI_Label.h"
#include "VGUI_ImagePanel.h"
#include "vgui_defaultinputsignal.h"
namespace vgui
{
class CCheckButton2;
class ICheckButton2Handler
{
public:
virtual void StateChanged(CCheckButton2 *pButton) = 0;
virtual void StateChanged( CCheckButton2 *pButton ) = 0;
};
// VGUI checkbox class.
// - Provides access to the checkbox images.
// - Provides an easy callback mechanism for state changes.
@ -34,47 +31,37 @@ public:
class CCheckButton2 : public Panel, public CDefaultInputSignal
{
public:
CCheckButton2();
~CCheckButton2();
CCheckButton2();
~CCheckButton2();
// Initialize the button with these.
void SetImages(char const *pChecked, char const *pUnchecked);
void SetImages(Image *pChecked, Image *pUnchecked); // If you use this, the button will never delete the images.
void SetImages( char const *pChecked, char const *pUnchecked );
void SetImages( Image *pChecked, Image *pUnchecked ); // If you use this, the button will never delete the images.
void DeleteImages();
// The checkbox can be to the left or the right of the text (default is left).
void SetCheckboxLeft(bool bLeftAlign);
void SetCheckboxLeft( bool bLeftAlign );
bool GetCheckboxLeft();
// Set the label text.
void SetText(char const *pText, ...);
void SetTextColor(int r, int g, int b, int a);
void SetText( char const *pText, ... );
void SetTextColor( int r, int g, int b, int a );
// You can register for change notification here.
void SetHandler(ICheckButton2Handler *pHandler);
void SetHandler( ICheckButton2Handler *pHandler );
// Get/set the check state.
bool IsChecked();
void SetChecked(bool bChecked);
void SetChecked( bool bChecked );
// Panel overrides.
public:
virtual void internalMousePressed(MouseCode code);
virtual void internalMousePressed( MouseCode code );
protected:
void SetupControls();
// InputSignal overrides.
protected:
virtual void mousePressed(MouseCode code,Panel* panel);
virtual void mousePressed( MouseCode code, Panel *panel );
public:
ICheckButton2Handler *m_pHandler;
@ -89,9 +76,5 @@ public:
bool m_bChecked;
};
}
#endif // VGUI_CHECKBUTTON2_H

View File

@ -1,14 +1,17 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//========= Copyright <EFBFBD> 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#pragma once
#if !defined(VGUI_DEFAULTINPUTSIGNAL_H)
#define VGUI_DEFAULTINPUTSIGNAL_H
#include "vgui_inputsignal.h"
#ifndef VGUI_DEFAULTINPUTSIGNAL_H
#define VGUI_DEFAULTINPUTSIGNAL_H
#ifdef _WIN32
#pragma once
#endif
#include "VGUI_InputSignal.h"
namespace vgui
{
@ -16,8 +19,8 @@ namespace vgui
class CDefaultInputSignal : public vgui::InputSignal
{
public:
virtual void cursorMoved(int x,int y,Panel* panel) {}
virtual void cursorEntered(Panel* panel) {}
virtual void cursorMoved( int x, int y, Panel *panel ) {}
virtual void cursorEntered( Panel *panel ) {}
virtual void cursorExited(Panel* panel) {}
virtual void mousePressed(MouseCode code,Panel* panel) {}
virtual void mouseDoublePressed(MouseCode code,Panel* panel) {}
@ -29,4 +32,6 @@ namespace vgui
virtual void keyFocusTicked(Panel* panel) {}
};
}
#endif // VGUI_DEFAULTINPUTSIGNAL_H

View File

@ -8,10 +8,8 @@
#include <assert.h>
#include "vgui_grid.h"
using namespace vgui;
#define AssertCheck(expr, msg) \
if(!(expr))\
{\
@ -19,12 +17,9 @@ using namespace vgui;
return 0;\
}
// ------------------------------------------------------------------------------ //
// CGrid::CGridEntry.
// ------------------------------------------------------------------------------ //
CGrid::CGridEntry::CGridEntry()
{
m_pPanel = NULL;
@ -35,47 +30,42 @@ CGrid::CGridEntry::~CGridEntry()
{
}
// ------------------------------------------------------------------------------ //
// CGrid.
// ------------------------------------------------------------------------------ //
CGrid::CGrid()
{
Clear();
}
CGrid::~CGrid()
{
Term();
}
bool CGrid::SetDimensions(int xCols, int yRows)
bool CGrid::SetDimensions( int xCols, int yRows )
{
Term();
m_GridEntries = new CGridEntry[xCols * yRows];
m_Widths = new int[xCols*2 + yRows*2];
m_Widths = new int[xCols * 2 + yRows * 2];
m_Heights = m_Widths + xCols;
m_ColOffsets = m_Heights + yRows;
m_RowOffsets = m_ColOffsets + xCols;
if(!m_GridEntries || !m_Widths)
if( !m_GridEntries || !m_Widths )
{
Term();
return false;
}
memset(m_Widths, 0, sizeof(int) * (xCols*2 + yRows*2));
memset( m_Widths, 0, sizeof(int) * ( xCols * 2 + yRows * 2 ) );
m_xCols = xCols;
m_yRows = yRows;
return true;
}
void CGrid::Term()
{
delete [] m_GridEntries;
@ -83,180 +73,164 @@ void CGrid::Term()
Clear();
}
Panel* CGrid::GetEntry(int x, int y)
Panel *CGrid::GetEntry( int x, int y )
{
return GridEntry(x, y)->m_pPanel;
return GridEntry( x, y )->m_pPanel;
}
bool CGrid::SetEntry(int x, int y, Panel *pPanel)
bool CGrid::SetEntry( int x, int y, Panel *pPanel )
{
CGridEntry *pEntry = GridEntry(x, y);
if(!pEntry)
CGridEntry *pEntry = GridEntry( x, y );
if( !pEntry )
return false;
if(pEntry->m_pPanel)
pEntry->m_pPanel->setParent(NULL);
if( pEntry->m_pPanel )
pEntry->m_pPanel->setParent( NULL );
pEntry->m_pPanel = pPanel;
if(pPanel)
pPanel->setParent(this);
if( pPanel )
pPanel->setParent( this );
m_bDirty = true;
return true;
}
int CGrid::GetXSpacing()
{
return m_xSpacing;
}
int CGrid::GetYSpacing()
{
return m_ySpacing;
}
void CGrid::SetSpacing(int xSpacing, int ySpacing)
void CGrid::SetSpacing( int xSpacing, int ySpacing )
{
if(xSpacing != m_xSpacing)
if( xSpacing != m_xSpacing )
{
m_xSpacing = xSpacing;
CalcColOffsets(0);
CalcColOffsets( 0 );
m_bDirty = true;
}
if(ySpacing != m_ySpacing)
if( ySpacing != m_ySpacing )
{
m_ySpacing = ySpacing;
CalcRowOffsets(0);
CalcRowOffsets( 0 );
m_bDirty = true;
}
}
bool CGrid::SetColumnWidth(int iColumn, int width)
{
AssertCheck(iColumn >= 0 && iColumn < m_xCols, "CGrid::SetColumnWidth : invalid location specified");
AssertCheck( iColumn >= 0 && iColumn < m_xCols, "CGrid::SetColumnWidth : invalid location specified" );
m_Widths[iColumn] = width;
CalcColOffsets(iColumn+1);
CalcColOffsets( iColumn + 1 );
m_bDirty = true;
return true;
}
bool CGrid::SetRowHeight(int iRow, int height)
bool CGrid::SetRowHeight( int iRow, int height )
{
AssertCheck(iRow >= 0 && iRow < m_yRows, "CGrid::SetColumnWidth : invalid location specified");
AssertCheck( iRow >= 0 && iRow < m_yRows, "CGrid::SetColumnWidth : invalid location specified" );
m_Heights[iRow] = height;
CalcRowOffsets(iRow+1);
CalcRowOffsets( iRow + 1 );
m_bDirty = true;
return true;
}
int CGrid::GetColumnWidth(int iColumn)
int CGrid::GetColumnWidth( int iColumn )
{
AssertCheck(iColumn >= 0 && iColumn < m_xCols, "CGrid::GetColumnWidth: invalid location specified");
AssertCheck( iColumn >= 0 && iColumn < m_xCols, "CGrid::GetColumnWidth: invalid location specified" );
return m_Widths[iColumn];
}
int CGrid::GetRowHeight(int iRow)
int CGrid::GetRowHeight( int iRow )
{
AssertCheck(iRow >= 0 && iRow < m_yRows, "CGrid::GetRowHeight: invalid location specified");
AssertCheck( iRow >= 0 && iRow < m_yRows, "CGrid::GetRowHeight: invalid location specified" );
return m_Heights[iRow];
}
int CGrid::CalcFitColumnWidth(int iColumn)
int CGrid::CalcFitColumnWidth( int iColumn )
{
AssertCheck(iColumn >= 0 && iColumn < m_xCols, "CGrid::CalcFitColumnWidth: invalid location specified");
AssertCheck( iColumn >= 0 && iColumn < m_xCols, "CGrid::CalcFitColumnWidth: invalid location specified" );
int maxSize = 0;
for(int i=0; i < m_yRows; i++)
for( int i = 0; i < m_yRows; i++ )
{
Panel *pPanel = GridEntry(iColumn, i)->m_pPanel;
if(!pPanel)
Panel *pPanel = GridEntry( iColumn, i )->m_pPanel;
if( !pPanel )
continue;
int w, h;
pPanel->getSize(w,h);
if(w > maxSize)
pPanel->getSize( w, h );
if( w > maxSize )
maxSize = w;
}
return maxSize;
}
int CGrid::CalcFitRowHeight(int iRow)
int CGrid::CalcFitRowHeight( int iRow )
{
AssertCheck(iRow >= 0 && iRow < m_yRows, "CGrid::CalcFitRowHeight: invalid location specified");
AssertCheck( iRow >= 0 && iRow < m_yRows, "CGrid::CalcFitRowHeight: invalid location specified" );
int maxSize = 0;
for(int i=0; i < m_xCols; i++)
for( int i = 0; i < m_xCols; i++ )
{
Panel *pPanel = GridEntry(i, iRow)->m_pPanel;
if(!pPanel)
Panel *pPanel = GridEntry( i, iRow )->m_pPanel;
if( !pPanel )
continue;
int w, h;
pPanel->getSize(w,h);
if(h > maxSize)
pPanel->getSize( w, h );
if( h > maxSize )
maxSize = h;
}
return maxSize;
}
void CGrid::AutoSetRowHeights()
{
for(int i=0; i < m_yRows; i++)
SetRowHeight(i, CalcFitRowHeight(i));
for( int i = 0; i < m_yRows; i++ )
SetRowHeight( i, CalcFitRowHeight( i ) );
}
bool CGrid::GetEntryBox(
int col, int row, int &x, int &y, int &w, int &h)
bool CGrid::GetEntryBox( int col, int row, int &x, int &y, int &w, int &h )
{
AssertCheck(col >= 0 && col < m_xCols && row >= 0 && row < m_yRows, "CGrid::GetEntryBox: invalid location specified");
AssertCheck( col >= 0 && col < m_xCols && row >= 0 && row < m_yRows, "CGrid::GetEntryBox: invalid location specified" );
x = m_ColOffsets[col];
w = m_Widths[col];
y = m_RowOffsets[row];
h = m_Heights[row];
return true;
return true;
}
bool CGrid::CopyColumnWidths(CGrid *pOther)
bool CGrid::CopyColumnWidths( CGrid *pOther )
{
if(!pOther || pOther->m_xCols != m_xCols)
if( !pOther || pOther->m_xCols != m_xCols )
return false;
for(int i=0; i < m_xCols; i++)
for( int i = 0; i < m_xCols; i++ )
m_Widths[i] = pOther->m_Widths[i];
CalcColOffsets(0);
CalcColOffsets( 0 );
m_bDirty = true;
return true;
}
void CGrid::RepositionContents()
{
for(int x=0; x < m_xCols; x++)
for( int x = 0; x < m_xCols; x++ )
{
for(int y=0; y < m_yRows; y++)
for( int y=0; y < m_yRows; y++ )
{
Panel *pPanel = GridEntry(x,y)->m_pPanel;
if(!pPanel)
Panel *pPanel = GridEntry( x, y )->m_pPanel;
if( !pPanel )
continue;
pPanel->setBounds(
@ -270,12 +244,11 @@ void CGrid::RepositionContents()
m_bDirty = false;
}
int CGrid::CalcDrawHeight()
{
if(m_yRows > 0)
if( m_yRows > 0 )
{
return m_RowOffsets[m_yRows-1] + m_Heights[m_yRows - 1] + m_ySpacing;
return m_RowOffsets[m_yRows - 1] + m_Heights[m_yRows - 1] + m_ySpacing;
}
else
{
@ -283,25 +256,24 @@ int CGrid::CalcDrawHeight()
}
}
void CGrid::paint()
{
if(m_bDirty)
if( m_bDirty )
RepositionContents();
Panel::paint();
// walk the grid looking for underlined rows
int x = 0, y = 0;
for (int row = 0; row < m_yRows; row++)
for( int row = 0; row < m_yRows; row++ )
{
CGridEntry *cell = GridEntry(0, row);
CGridEntry *cell = GridEntry( 0, row );
y += cell->m_pPanel->getTall() + m_ySpacing;
if (cell->m_bUnderline)
if( cell->m_bUnderline )
{
drawSetColor(cell->m_UnderlineColor[0], cell->m_UnderlineColor[1], cell->m_UnderlineColor[2], cell->m_UnderlineColor[3]);
drawFilledRect(0, y - (cell->m_iUnderlineOffset + 1), getWide(), y - cell->m_iUnderlineOffset);
drawSetColor( cell->m_UnderlineColor[0], cell->m_UnderlineColor[1], cell->m_UnderlineColor[2], cell->m_UnderlineColor[3] );
drawFilledRect( 0, y - (cell->m_iUnderlineOffset + 1 ), getWide(), y - cell->m_iUnderlineOffset );
}
}
}
@ -314,11 +286,11 @@ void CGrid::paintBackground()
//-----------------------------------------------------------------------------
// Purpose: sets underline color for a particular row
//-----------------------------------------------------------------------------
void CGrid::SetRowUnderline(int row, bool enabled, int offset, int r, int g, int b, int a)
void CGrid::SetRowUnderline( int row, bool enabled, int offset, int r, int g, int b, int a )
{
CGridEntry *cell = GridEntry(0, row);
CGridEntry *cell = GridEntry( 0, row );
cell->m_bUnderline = enabled;
if (enabled)
if( enabled )
{
cell->m_iUnderlineOffset = offset;
cell->m_UnderlineColor[0] = r;
@ -337,53 +309,51 @@ void CGrid::Clear()
m_bDirty = false;
}
CGrid::CGridEntry* CGrid::GridEntry(int x, int y)
{
AssertCheck(x >= 0 && x < m_xCols && y >= 0 && y < m_yRows, "CGrid::GridEntry: invalid location specified");
return &m_GridEntries[y*m_xCols + x];
AssertCheck( x >= 0 && x < m_xCols && y >= 0 && y < m_yRows, "CGrid::GridEntry: invalid location specified" );
return &m_GridEntries[y * m_xCols + x];
}
void CGrid::CalcColOffsets(int iStart)
void CGrid::CalcColOffsets( int iStart )
{
int cur = m_xSpacing;
if(iStart != 0)
cur += m_ColOffsets[iStart-1] + m_Widths[iStart-1];
if( iStart != 0 )
cur += m_ColOffsets[iStart - 1] + m_Widths[iStart - 1];
for(int i=iStart; i < m_xCols; i++)
for( int i = iStart; i < m_xCols; i++ )
{
m_ColOffsets[i] = cur;
cur += m_Widths[i] + m_xSpacing;
}
}
void CGrid::CalcRowOffsets(int iStart)
void CGrid::CalcRowOffsets( int iStart )
{
int cur = m_ySpacing;
if(iStart != 0)
cur += m_RowOffsets[iStart-1];
if( iStart != 0 )
cur += m_RowOffsets[iStart - 1];
for(int i=iStart; i < m_yRows; i++)
for( int i = iStart; i < m_yRows; i++ )
{
m_RowOffsets[i] = cur;
cur += m_Heights[i] + m_ySpacing;
}
}
bool CGrid::getCellAtPoint(int worldX, int worldY, int &row, int &col)
bool CGrid::getCellAtPoint( int worldX, int worldY, int &row, int &col )
{
row = -1; col = -1;
for(int x=0; x < m_xCols; x++)
for( int x = 0; x < m_xCols; x++ )
{
for(int y=0; y < m_yRows; y++)
for( int y = 0; y < m_yRows; y++ )
{
Panel *pPanel = GridEntry(x,y)->m_pPanel;
if (!pPanel)
Panel *pPanel = GridEntry( x, y )->m_pPanel;
if( !pPanel )
continue;
if (pPanel->isWithin(worldX, worldY))
if( pPanel->isWithin( worldX, worldY ) )
{
col = x;
row = y;
@ -395,4 +365,3 @@ bool CGrid::getCellAtPoint(int worldX, int worldY, int &row, int &col)
return false;
}

View File

@ -5,22 +5,20 @@
// $NoKeywords: $
//=============================================================================
#pragma once
#if !defined(VGUI_GRID_H)
#ifndef VGUI_GRID_H
#define VGUI_GRID_H
#include "vgui_panel.h"
#include "VGUI_Panel.h"
namespace vgui
{
// The grid control simply manages a grid of panels. You can adjust column sizes and spacings and
// configure and fill the panels however you want.
// To use this control, call SetDimensions, SetSpacing and fill the controls.
class CGrid : public Panel
{
public:
CGrid();
CGrid();
virtual ~CGrid();
bool SetDimensions(int xCols, int yRows); // Set how many columns and rows in the grid.
@ -66,8 +64,6 @@ public:
bool getCellAtPoint(int worldX, int worldY, int &row, int &col);
// Panel overrides.
public:
virtual void paint();
virtual void paintBackground();
@ -76,8 +72,8 @@ protected:
class CGridEntry
{
public:
CGridEntry();
~CGridEntry();
CGridEntry();
~CGridEntry();
Panel *m_pPanel;
@ -92,9 +88,6 @@ protected:
void CalcColOffsets(int iStart);
void CalcRowOffsets(int iStart);
protected:
bool m_bDirty; // Set when controls will need to be repositioned.
int m_xCols;
@ -108,9 +101,8 @@ protected:
int *m_ColOffsets;
int *m_RowOffsets;
CGridEntry *m_GridEntries;
};
CGridEntry *m_GridEntries;
};
}
#endif // VGUI_GRID_H

View File

@ -7,37 +7,36 @@
#include "vgui_helpers.h"
using namespace vgui;
void AlignPanel(Panel *pChild, Panel *pParent, int alignment)
void AlignPanel( Panel *pChild, Panel *pParent, int alignment )
{
int w, h, cw, ch;
pParent->getSize(w, h);
pChild->getSize(cw, ch);
int xCenter = (w - cw) / 2;
int yCenter = (h - ch) / 2;
pParent->getSize( w, h );
pChild->getSize( cw, ch );
if(alignment == Label::a_west)
pChild->setPos(0, yCenter);
else if(alignment == Label::a_northwest)
pChild->setPos(0,0);
else if(alignment == Label::a_north)
pChild->setPos(xCenter, 0);
else if(alignment == Label::a_northeast)
pChild->setPos(w - cw, 0);
else if(alignment == Label::a_east)
pChild->setPos(w - cw, yCenter);
else if(alignment == Label::a_southeast)
pChild->setPos(w - cw, h - ch);
else if(alignment == Label::a_south)
pChild->setPos(xCenter, h - ch);
else if(alignment == Label::a_southwest)
pChild->setPos(0, h - ch);
else if(alignment == Label::a_center)
pChild->setPos(xCenter, yCenter);
int xCenter = ( w - cw ) / 2;
int yCenter = ( h - ch ) / 2;
if( alignment == Label::a_west )
pChild->setPos( 0, yCenter );
else if( alignment == Label::a_northwest )
pChild->setPos( 0, 0 );
else if( alignment == Label::a_north )
pChild->setPos( xCenter, 0 );
else if( alignment == Label::a_northeast )
pChild->setPos( w - cw, 0 );
else if( alignment == Label::a_east )
pChild->setPos( w - cw, yCenter );
else if( alignment == Label::a_southeast )
pChild->setPos( w - cw, h - ch );
else if( alignment == Label::a_south )
pChild->setPos( xCenter, h - ch );
else if( alignment == Label::a_southwest )
pChild->setPos( 0, h - ch );
else if( alignment == Label::a_center )
pChild->setPos( xCenter, yCenter );
}

View File

@ -5,22 +5,68 @@
// $NoKeywords: $
//=============================================================================
#pragma once
#if !defined(VGUI_HELPERS_H)
#ifndef VGUI_HELPERS_H
#define VGUI_HELPERS_H
#include "VGUI_Panel.h"
#include "VGUI_Label.h"
#include "vgui_panel.h"
#include "vgui_label.h"
inline int PanelTop( vgui::Panel *pPanel )
{
int x, y, w, h;
pPanel->getBounds( x, y, w, h );
inline int PanelTop(vgui::Panel *pPanel) {int x,y,w,h; pPanel->getBounds(x,y,w,h); return y;}
inline int PanelLeft(vgui::Panel *pPanel) {int x,y,w,h; pPanel->getBounds(x,y,w,h); return x;}
inline int PanelRight(vgui::Panel *pPanel) {int x,y,w,h; pPanel->getBounds(x,y,w,h); return x+w;}
inline int PanelBottom(vgui::Panel *pPanel) {int x,y,w,h; pPanel->getBounds(x,y,w,h); return y+h;}
inline int PanelWidth(vgui::Panel *pPanel) {int x,y,w,h; pPanel->getBounds(x,y,w,h); return w;}
inline int PanelHeight(vgui::Panel *pPanel) {int x,y,w,h; pPanel->getBounds(x,y,w,h); return h;}
return y;
}
inline int PanelLeft( vgui::Panel *pPanel )
{
int x, y, w, h;
pPanel->getBounds( x, y, w, h );
return x;
}
inline int PanelRight( vgui::Panel *pPanel )
{
int x, y, w, h;
pPanel->getBounds( x, y, w, h );
return x + w;
}
inline int PanelBottom( vgui::Panel *pPanel )
{
int x, y, w, h;
pPanel->getBounds( x, y, w, h );
return y + h;
}
inline int PanelWidth( vgui::Panel *pPanel )
{
int x, y, w, h;
pPanel->getBounds( x, y, w, h );
return w;
}
inline int PanelHeight( vgui::Panel *pPanel )
{
int x, y, w, h;
pPanel->getBounds( x, y, w, h );
return h;
}
// Places child at the requested position inside pParent. iAlignment is from Label::Alignment.
void AlignPanel(vgui::Panel *pChild, vgui::Panel *pParent, int alignment);
void AlignPanel( vgui::Panel *pChild, vgui::Panel *pParent, int alignment );
#endif // VGUI_HELPERS_H

View File

@ -7,28 +7,25 @@
#include "vgui_listbox.h"
using namespace vgui;
CListBox::CListBox() : Panel(0, 0, 0, 0),
m_ItemsPanel(0,0,0,0),
m_ScrollBar(0, 0, 0, 0, true),
m_Slider(0, 0, 10, 40, true)
CListBox::CListBox() : Panel( 0, 0, 0, 0 ),
m_ItemsPanel( 0, 0, 0, 0 ),
m_ScrollBar( 0, 0, 0, 0, true ),
m_Slider( 0, 0, 10, 40, true )
{
m_Signal.m_pListBox = this;
m_ItemsPanel.setParent(this);
m_ItemsPanel.setBgColor(0,0,0,255);
m_Slider.setRangeWindow(50);
m_Slider.setRangeWindowEnabled(true);
m_ItemsPanel.setParent( this );
m_ItemsPanel.setBgColor( 0, 0, 0, 255 );
m_ScrollBar.setParent(this);
m_ScrollBar.addIntChangeSignal(&m_Signal);
m_ScrollBar.setSlider(&m_Slider);
m_ScrollBar.setButtonPressedScrollValue(1);
m_Slider.setRangeWindow( 50 );
m_Slider.setRangeWindowEnabled( true );
m_ScrollBar.setParent( this );
m_ScrollBar.addIntChangeSignal( &m_Signal );
m_ScrollBar.setSlider( &m_Slider );
m_ScrollBar.setButtonPressedScrollValue( 1 );
m_Items.m_pNext = m_Items.m_pPrev = &m_Items;
m_ItemOffset = 0;
@ -51,40 +48,42 @@ void CListBox::Term()
// Free the LBItems.
LBItem *pNext;
for(LBItem *pItem=m_Items.m_pNext; pItem != &m_Items; pItem=pNext)
for( LBItem *pItem =m_Items.m_pNext; pItem != &m_Items; pItem = pNext )
{
pItem->m_pPanel->setParent(NULL); // detach the panel from us
pItem->m_pPanel->setParent( NULL ); // detach the panel from us
pNext = pItem->m_pNext;
delete pItem;
}
m_Items.m_pPrev = m_Items.m_pNext = &m_Items;
}
void CListBox::AddItem(Panel* panel)
void CListBox::AddItem( Panel *panel )
{
// Add the item.
LBItem *pItem = new LBItem;
if(!pItem)
if( !pItem )
return;
pItem->m_pPanel = panel;
pItem->m_pPanel->setParent(&m_ItemsPanel);
pItem->m_pPanel->setParent( &m_ItemsPanel );
pItem->m_pPrev = m_Items.m_pPrev;
pItem->m_pNext = &m_Items;
pItem->m_pNext->m_pPrev = pItem->m_pPrev->m_pNext = pItem;
m_ScrollBar.setRange(0, GetScrollMax());
m_Slider.setRangeWindow(50);
m_Slider.setRangeWindowEnabled(true);
m_ScrollBar.setRange( 0, GetScrollMax() );
m_Slider.setRangeWindow( 50 );
m_Slider.setRangeWindowEnabled( true );
InternalLayout();
}
int CListBox::GetNumItems()
{
int count=0;
for(LBItem *pItem=m_Items.m_pNext; pItem != &m_Items; pItem=pItem->m_pNext)
int count = 0;
for( LBItem *pItem = m_Items.m_pNext; pItem != &m_Items; pItem = pItem->m_pNext )
++count;
return count;
@ -93,7 +92,9 @@ int CListBox::GetNumItems()
int CListBox::GetItemWidth()
{
int wide, tall;
m_ItemsPanel.getSize(wide, tall);
m_ItemsPanel.getSize( wide, tall );
return wide;
}
@ -102,29 +103,29 @@ int CListBox::GetScrollPos()
return m_ItemOffset;
}
void CListBox::SetScrollPos(int pos)
void CListBox::SetScrollPos( int pos )
{
int maxItems = GetScrollMax();
if(maxItems < 0)
if( maxItems < 0 )
return;
m_ItemOffset = (pos < 0) ? 0 : ((pos > maxItems) ? maxItems : pos);
m_ItemOffset = ( pos < 0 ) ? 0 : ( ( pos > maxItems ) ? maxItems : pos );
InternalLayout();
}
void CListBox::setPos(int x, int y)
void CListBox::setPos( int x, int y )
{
Panel::setPos(x, y);
Panel::setPos( x, y );
InternalLayout();
}
void CListBox::setSize(int wide,int tall)
void CListBox::setSize( int wide, int tall )
{
Panel::setSize(wide,tall);
Panel::setSize( wide, tall );
InternalLayout();
}
void CListBox::setPixelScroll(int value)
void CListBox::setPixelScroll( int value )
{
m_ItemOffset = m_ScrollBar.getValue();
InternalLayout();
@ -133,11 +134,11 @@ void CListBox::setPixelScroll(int value)
void CListBox::InternalLayout()
{
int x, y, wide, tall;
getBounds(x, y, wide, tall);
getBounds( x, y, wide, tall );
// Reposition the main panel and the scrollbar.
m_ItemsPanel.setBounds(0, 0, wide-15, tall);
m_ScrollBar.setBounds(wide-15, 0, 15, tall);
m_ItemsPanel.setBounds( 0, 0, wide - 15, tall );
m_ScrollBar.setBounds( wide - 15, 0, 15, tall );
bool bNeedScrollbar = false;
@ -145,31 +146,32 @@ void CListBox::InternalLayout()
int curItem = 0;
int curY = 0;
int maxItem = GetScrollMax();
for(LBItem *pItem=m_Items.m_pNext; pItem != &m_Items; pItem=pItem->m_pNext)
for( LBItem *pItem = m_Items.m_pNext; pItem != &m_Items; pItem = pItem->m_pNext )
{
if(curItem < m_ItemOffset)
if( curItem < m_ItemOffset )
{
pItem->m_pPanel->setVisible(false);
pItem->m_pPanel->setVisible( false );
bNeedScrollbar = true;
}
else if (curItem >= maxItem)
else if( curItem >= maxItem )
{
// item is past the end of the items we care about
pItem->m_pPanel->setVisible(false);
pItem->m_pPanel->setVisible( false );
}
else
{
pItem->m_pPanel->setVisible(true);
pItem->m_pPanel->setVisible( true );
int itemWidth, itemHeight;
pItem->m_pPanel->getSize(itemWidth, itemHeight);
pItem->m_pPanel->getSize( itemWidth, itemHeight );
// Don't change the item's height but change its width to fit the listbox.
pItem->m_pPanel->setBounds(0, curY, wide, itemHeight);
pItem->m_pPanel->setBounds( 0, curY, wide, itemHeight );
curY += itemHeight;
if (curY > tall)
if( curY > tall )
{
bNeedScrollbar = true;
}
@ -178,7 +180,7 @@ void CListBox::InternalLayout()
++curItem;
}
m_ScrollBar.setVisible(bNeedScrollbar);
m_ScrollBar.setVisible( bNeedScrollbar );
repaint();
}
@ -187,16 +189,16 @@ void CListBox::paintBackground()
{
}
void CListBox::SetScrollRange(int maxScroll)
void CListBox::SetScrollRange( int maxScroll )
{
m_iScrollMax = maxScroll;
m_ScrollBar.setRange(0, maxScroll);
m_ScrollBar.setRange( 0, maxScroll );
InternalLayout();
}
int CListBox::GetScrollMax()
int CListBox::GetScrollMax()
{
if (m_iScrollMax < 0)
if( m_iScrollMax < 0 )
{
return GetNumItems() - 1;
}
@ -204,4 +206,3 @@ int CListBox::GetScrollMax()
return m_iScrollMax;
}

View File

@ -5,19 +5,17 @@
// $NoKeywords: $
//=============================================================================
#pragma once
#if !defined(VOICE_LISTBOX_H)
#ifndef VOICE_LISTBOX_H
#define VOICE_LISTBOX_H
#include "VGUI_Panel.h"
#include "VGUI_IntChangeSignal.h"
#include "VGUI_Slider2.h"
#include "VGUI_ScrollBar2.h"
#include "vgui_slider2.h"
#include "vgui_scrollbar2.h"
namespace vgui
{
// Listbox class used by voice code. Based off of vgui's list panel but with some modifications:
// - This listbox clips its child items to its rectangle.
// - You can access things like the scrollbar and find out the item width.
@ -27,45 +25,39 @@ namespace vgui
class CListBox : public Panel
{
public:
CListBox();
~CListBox();
CListBox();
~CListBox();
void Init();
void Term();
void Init();
void Term();
// Add an item to the listbox. This automatically sets the item's parent to the listbox
// and resizes the item's width to fit within the listbox.
void AddItem(Panel *pPanel);
void AddItem( Panel *pPanel );
// Get the number of items currently in the listbox.
int GetNumItems();
int GetNumItems();
// Get the width that listbox items will be set to (this changes if you resize the listbox).
int GetItemWidth();
int GetItemWidth();
// Get/set the scrollbar position (position says which element is at the top of the listbox).
int GetScrollPos();
void SetScrollPos(int pos);
int GetScrollPos();
void SetScrollPos( int pos );
// sets the last item the listbox should scroll to
// scroll to GetNumItems() if not set
void SetScrollRange(int maxScroll);
void SetScrollRange( int maxScroll );
// returns the maximum value the scrollbar can scroll to
int GetScrollMax();
int GetScrollMax();
// vgui overrides.
public:
virtual void setPos(int x, int y);
virtual void setSize(int wide,int tall);
virtual void setPixelScroll(int value);
// vgui overrides.
virtual void setPos( int x, int y );
virtual void setSize( int wide, int tall );
virtual void setPixelScroll( int value );
virtual void paintBackground();
protected:
class LBItem
{
public:
@ -76,34 +68,29 @@ protected:
class ListBoxSignal : public IntChangeSignal
{
public:
void intChanged(int value,Panel* panel)
void intChanged( int value, Panel *panel )
{
m_pListBox->setPixelScroll(-value);
m_pListBox->setPixelScroll( -value );
}
vgui::CListBox *m_pListBox;
};
protected:
void InternalLayout();
protected:
void InternalLayout();
// All the items..
LBItem m_Items;
LBItem m_Items;
Panel m_ItemsPanel;
Panel m_ItemsPanel;
int m_ItemOffset; // where we're scrolled to
Slider2 m_Slider;
ScrollBar2 m_ScrollBar;
int m_ItemOffset; // where we're scrolled to
Slider2 m_Slider;
ScrollBar2 m_ScrollBar;
ListBoxSignal m_Signal;
int m_iScrollMax;
int m_iScrollMax;
};
}
#endif // VOICE_LISTBOX_H

View File

@ -7,10 +7,9 @@
#include "../cl_dll/wrect.h"
#include "../cl_dll/cl_dll.h"
#include "vgui.h"
#include "VGUI.h"
#include "vgui_loadtga.h"
#include "vgui_inputstream.h"
#include "VGUI_InputStream.h"
// ---------------------------------------------------------------------- //
// Helper class for loading tga files.
@ -18,76 +17,96 @@
class MemoryInputStream : public vgui::InputStream
{
public:
MemoryInputStream()
{
m_pData = NULL;
m_DataLen = m_ReadPos = 0;
}
virtual void seekStart(bool& success) {m_ReadPos=0; success=true;}
virtual void seekRelative(int count,bool& success) {m_ReadPos+=count; success=true;}
virtual void seekEnd(bool& success) {m_ReadPos=m_DataLen; success=true;}
virtual int getAvailable(bool& success) {success=false; return 0;} // This is what vgui does for files...
virtual uchar readUChar(bool& success)
MemoryInputStream()
{
if(m_ReadPos>=0 && m_ReadPos<m_DataLen)
m_pData = NULL;
m_DataLen = m_ReadPos = 0;
}
virtual void seekStart( bool &success )
{
m_ReadPos = 0;
success = true;
}
virtual void seekRelative( int count, bool &success )
{
m_ReadPos += count;
success = true;
}
virtual void seekEnd( bool &success )
{
m_ReadPos = m_DataLen;
success = true;
}
virtual int getAvailable( bool &success )
{
// This is what vgui does for files...
success = false;
return 0;
}
virtual uchar readUChar( bool & success )
{
if( m_ReadPos >= 0 && m_ReadPos < m_DataLen )
{
success=true;
success = true;
uchar ret = m_pData[m_ReadPos];
++m_ReadPos;
return ret;
}
else
{
success=false;
success = false;
return 0;
}
}
virtual void readUChar(uchar* buf,int count,bool& success)
virtual void readUChar( uchar *buf, int count, bool &success )
{
for(int i=0; i < count; i++)
buf[i] = readUChar(success);
for( int i = 0; i < count; i++)
buf[i] = readUChar( success );
}
virtual void close(bool& success)
virtual void close( bool &success)
{
m_pData = NULL;
m_DataLen = m_ReadPos = 0;
}
uchar *m_pData;
int m_DataLen;
int m_ReadPos;
uchar *m_pData;
int m_DataLen;
int m_ReadPos;
};
vgui::BitmapTGA* vgui_LoadTGA(char const *pFilename)
vgui::BitmapTGA *vgui_LoadTGA( char const *pFilename )
{
MemoryInputStream stream;
stream.m_pData = gEngfuncs.COM_LoadFile((char*)pFilename, 5, &stream.m_DataLen);
if(!stream.m_pData)
stream.m_pData = gEngfuncs.COM_LoadFile( (char*)pFilename, 5, &stream.m_DataLen );
if( !stream.m_pData )
return NULL;
stream.m_ReadPos = 0;
vgui::BitmapTGA *pRet = new vgui::BitmapTGA(&stream, true);
gEngfuncs.COM_FreeFile(stream.m_pData);
vgui::BitmapTGA *pRet = new vgui::BitmapTGA( &stream, true );
gEngfuncs.COM_FreeFile( stream.m_pData );
return pRet;
}
vgui::BitmapTGA* vgui_LoadTGANoInvertAlpha(char const *pFilename)
vgui::BitmapTGA *vgui_LoadTGANoInvertAlpha( char const *pFilename )
{
MemoryInputStream stream;
stream.m_pData = gEngfuncs.COM_LoadFile((char*)pFilename, 5, &stream.m_DataLen);
if(!stream.m_pData)
stream.m_pData = gEngfuncs.COM_LoadFile( (char*)pFilename, 5, &stream.m_DataLen );
if( !stream.m_pData )
return NULL;
stream.m_ReadPos = 0;
vgui::BitmapTGA *pRet = new vgui::BitmapTGA(&stream, false);
gEngfuncs.COM_FreeFile(stream.m_pData);
vgui::BitmapTGA *pRet = new vgui::BitmapTGA( &stream, false );
gEngfuncs.COM_FreeFile( stream.m_pData );
return pRet;
}

View File

@ -5,12 +5,12 @@
// $NoKeywords: $
//=============================================================================
#pragma once
#if !defined(VGUI_LOADTGA_H)
#ifndef VGUI_LOADTGA_H
#define VGUI_LOADTGA_H
#include "vgui_bitmaptga.h"
#include "VGUI_BitmapTGA.h"
vgui::BitmapTGA* vgui_LoadTGA(char const *pFilename);
vgui::BitmapTGA* vgui_LoadTGANoInvertAlpha(char const *pFilename);
vgui::BitmapTGA *vgui_LoadTGA( char const *pFilename );
vgui::BitmapTGA *vgui_LoadTGANoInvertAlpha( char const *pFilename );
#endif // VGUI_LOADTGA_H

View File

@ -1,58 +1,56 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//========= Copyright <EFBFBD> 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "VGUI_ScrollBar2.h"
#include "VGUI_Slider2.h"
#include "vgui_scrollbar2.h"
#include "vgui_slider2.h"
#include "vgui_loadtga.h"
#include<VGUI_IntChangeSignal.h>
#include<VGUI_Button.h>
#include<VGUI_ActionSignal.h>
#include<VGUI_LineBorder.h>
#include <VGUI_IntChangeSignal.h>
#include <VGUI_Button.h>
#include <VGUI_ActionSignal.h>
#include <VGUI_LineBorder.h>
using namespace vgui;
namespace
{
class FooDefaultScrollBarIntChangeSignal : public IntChangeSignal
{
public:
FooDefaultScrollBarIntChangeSignal(ScrollBar2* scrollBar)
FooDefaultScrollBarIntChangeSignal( ScrollBar2 *scrollBar )
{
_scrollBar=scrollBar;
_scrollBar = scrollBar;
}
virtual void intChanged(int value,Panel* panel)
virtual void intChanged( int value, Panel *panel )
{
_scrollBar->fireIntChangeSignal();
}
protected:
ScrollBar2* _scrollBar;
ScrollBar2 *_scrollBar;
};
class FooDefaultButtonSignal : public ActionSignal
{
public:
ScrollBar2* _scrollBar;
int _buttonIndex;
public:
FooDefaultButtonSignal(ScrollBar2* scrollBar,int buttonIndex)
ScrollBar2 *_scrollBar;
int _buttonIndex;
FooDefaultButtonSignal( ScrollBar2 *scrollBar, int buttonIndex )
{
_scrollBar=scrollBar;
_buttonIndex=buttonIndex;
_scrollBar = scrollBar;
_buttonIndex = buttonIndex;
}
public:
virtual void actionPerformed(Panel* panel)
virtual void actionPerformed( Panel *panel )
{
_scrollBar->doButtonPressed(_buttonIndex);
_scrollBar->doButtonPressed( _buttonIndex );
}
};
}
//-----------------------------------------------------------------------------
@ -65,32 +63,29 @@ private:
LineBorder m_Border;
public:
ScrollBarButton(const char *filename, int x, int y, int wide, int tall) : m_Border(Color(60, 60, 60, 0)), Button("", x, y, wide, tall)
ScrollBarButton( const char *filename, int x, int y, int wide, int tall ) : m_Border( Color( 60, 60, 60, 0 ) ), Button( "", x, y, wide, tall )
{
Image *image = vgui_LoadTGA(filename);
if (image)
Image *image = vgui_LoadTGA( filename );
if( image )
{
image->setColor(Color(140, 140, 140, 0));
setImage(image);
image->setColor( Color( 140, 140, 140, 0 ) );
setImage( image );
}
setBorder(&m_Border);
setBorder( &m_Border );
}
virtual void paintBackground()
{
int wide,tall;
getPaintSize(wide,tall);
int wide, tall;
getPaintSize( wide, tall );
// fill the background
drawSetColor(0, 0, 0, 0);
drawFilledRect(0, 0, wide, tall);
drawSetColor( 0, 0, 0, 0 );
drawFilledRect( 0, 0, wide, tall );
}
};
//-----------------------------------------------------------------------------
// Purpose: Constructor
// Input : x -
@ -99,68 +94,68 @@ public:
// tall -
// vertical -
//-----------------------------------------------------------------------------
ScrollBar2::ScrollBar2(int x,int y,int wide,int tall,bool vertical) : Panel(x,y,wide,tall)
ScrollBar2::ScrollBar2( int x, int y, int wide, int tall, bool vertical ) : Panel( x, y, wide, tall )
{
_slider=null;
_button[0]=null;
_button[1]=null;
_slider = null;
_button[0] = null;
_button[1] = null;
if(vertical)
if( vertical )
{
setSlider(new Slider2(0,wide-1,wide,(tall-(wide*2))+2,true));
setButton(new ScrollBarButton("gfx/vgui/arrowup.tga",0,0,wide,wide),0);
setButton(new ScrollBarButton("gfx/vgui/arrowdown.tga",0,tall-wide,wide,wide),1);
setSlider( new Slider2( 0, wide - 1, wide, ( tall - ( wide * 2 ) ) + 2, true ) );
setButton( new ScrollBarButton( "gfx/vgui/arrowup.tga", 0, 0, wide, wide ), 0 );
setButton( new ScrollBarButton( "gfx/vgui/arrowdown.tga", 0, tall - wide, wide, wide ), 1 );
}
else
{
// untested code
setSlider(new Slider2(tall,0,wide-(tall*2),tall,false));
setButton(new ScrollBarButton("gfx/vgui/320_arrowlt.tga",0,0,tall+1,tall+1),0);
setButton(new ScrollBarButton("gfx/vgui/320_arrowrt.tga",wide-tall,0,tall+1,tall+1),1);
setSlider( new Slider2( tall, 0, wide - ( tall * 2 ), tall, false ) );
setButton( new ScrollBarButton( "gfx/vgui/320_arrowlt.tga", 0, 0, tall + 1, tall + 1 ), 0 );
setButton( new ScrollBarButton( "gfx/vgui/320_arrowrt.tga", wide - tall, 0, tall + 1, tall + 1 ) , 1 );
}
setPaintBorderEnabled(true);
setPaintBackgroundEnabled(true);
setPaintEnabled(true);
setButtonPressedScrollValue(15);
setPaintBorderEnabled( true );
setPaintBackgroundEnabled( true );
setPaintEnabled( true );
setButtonPressedScrollValue( 15 );
validate();
}
}
void ScrollBar2::setSize(int wide,int tall)
void ScrollBar2::setSize( int wide, int tall )
{
Panel::setSize(wide,tall);
Panel::setSize( wide, tall );
if(_slider==null)
if( _slider == null )
{
return;
}
if(_button[0]==null)
if( _button[0] == null )
{
return;
}
if(_button[1]==null)
if( _button[1] == null )
{
return;
}
getPaintSize(wide,tall);
getPaintSize( wide, tall );
if(_slider->isVertical())
if( _slider->isVertical() )
{
_slider->setBounds(0,wide,wide,tall-(wide*2));
//_slider->setBounds(0,0,wide,tall);
_button[0]->setBounds(0,0,wide,wide);
_button[1]->setBounds(0,tall-wide,wide,wide);
_slider->setBounds( 0, wide, wide, tall - ( wide * 2 ) );
// _slider->setBounds( 0, 0, wide, tall );
_button[0]->setBounds( 0, 0, wide, wide );
_button[1]->setBounds( 0, tall - wide, wide, wide );
}
else
{
_slider->setBounds(tall,0,wide-(tall*2),tall);
//_slider->setBounds(0,0,wide,tall);
_button[0]->setBounds(0,0,tall,tall);
_button[1]->setBounds((wide-tall),0,tall,tall);
_slider->setBounds( tall, 0, wide - ( tall * 2 ), tall );
// _slider->setBounds( 0, 0, wide, tall );
_button[0]->setBounds( 0, 0, tall, tall );
_button[1]->setBounds( ( wide - tall ), 0, tall, tall);
}
}
@ -168,9 +163,9 @@ void ScrollBar2::performLayout()
{
}
void ScrollBar2::setValue(int value)
void ScrollBar2::setValue( int value )
{
_slider->setValue(value);
_slider->setValue( value );
}
int ScrollBar2::getValue()
@ -178,22 +173,22 @@ int ScrollBar2::getValue()
return _slider->getValue();
}
void ScrollBar2::addIntChangeSignal(IntChangeSignal* s)
void ScrollBar2::addIntChangeSignal( IntChangeSignal *s )
{
_intChangeSignalDar.putElement(s);
_slider->addIntChangeSignal(new FooDefaultScrollBarIntChangeSignal(this));
_intChangeSignalDar.putElement( s );
_slider->addIntChangeSignal( new FooDefaultScrollBarIntChangeSignal( this ) );
}
void ScrollBar2::setRange(int min,int max)
void ScrollBar2::setRange( int min, int max )
{
_slider->setRange(min,max);
_slider->setRange( min, max );
}
void ScrollBar2::fireIntChangeSignal()
{
for(int i=0;i<_intChangeSignalDar.getCount();i++)
for( int i = 0; i < _intChangeSignalDar.getCount(); i++ )
{
_intChangeSignalDar[i]->intChanged(_slider->getValue(),this);
_intChangeSignalDar[i]->intChanged( _slider->getValue(), this );
}
}
@ -207,39 +202,41 @@ bool ScrollBar2::hasFullRange()
return _slider->hasFullRange();
}
//LEAK: new and old slider will leak
void ScrollBar2::setButton(Button* button,int index)
// LEAK: new and old slider will leak
void ScrollBar2::setButton( Button *button, int index )
{
if(_button[index]!=null)
if( _button[index] != null )
{
removeChild(_button[index]);
removeChild( _button[index] );
}
_button[index]=button;
addChild(_button[index]);
_button[index]->addActionSignal(new FooDefaultButtonSignal(this,index));
_button[index] = button;
addChild( _button[index] );
_button[index]->addActionSignal( new FooDefaultButtonSignal( this, index ) );
validate();
//_button[index]->setVisible(false);
// _button[index]->setVisible( false );
}
Button* ScrollBar2::getButton(int index)
Button *ScrollBar2::getButton( int index )
{
return _button[index];
}
//LEAK: new and old slider will leak
void ScrollBar2::setSlider(Slider2 *slider)
// LEAK: new and old slider will leak
void ScrollBar2::setSlider( Slider2 *slider )
{
if(_slider!=null)
if( _slider != null )
{
removeChild(_slider);
removeChild( _slider );
}
_slider=slider;
addChild(_slider);
_slider->addIntChangeSignal(new FooDefaultScrollBarIntChangeSignal(this));
_slider = slider;
addChild( _slider );
_slider->addIntChangeSignal( new FooDefaultScrollBarIntChangeSignal( this ) );
validate();
}
@ -249,62 +246,62 @@ Slider2 *ScrollBar2::getSlider()
return _slider;
}
void ScrollBar2::doButtonPressed(int buttonIndex)
void ScrollBar2::doButtonPressed( int buttonIndex )
{
if(buttonIndex==0)
if( buttonIndex == 0 )
{
_slider->setValue(_slider->getValue()-_buttonPressedScrollValue);
_slider->setValue( _slider->getValue() - _buttonPressedScrollValue );
}
else
{
_slider->setValue(_slider->getValue()+_buttonPressedScrollValue);
_slider->setValue( _slider->getValue() + _buttonPressedScrollValue );
}
}
void ScrollBar2::setButtonPressedScrollValue(int value)
void ScrollBar2::setButtonPressedScrollValue( int value )
{
_buttonPressedScrollValue=value;
_buttonPressedScrollValue = value;
}
void ScrollBar2::setRangeWindow(int rangeWindow)
void ScrollBar2::setRangeWindow( int rangeWindow )
{
_slider->setRangeWindow(rangeWindow);
_slider->setRangeWindow( rangeWindow );
}
void ScrollBar2::setRangeWindowEnabled(bool state)
void ScrollBar2::setRangeWindowEnabled( bool state )
{
_slider->setRangeWindowEnabled(state);
_slider->setRangeWindowEnabled( state );
}
void ScrollBar2::validate()
{
if(_slider!=null)
if( _slider != null )
{
int buttonOffset=0;
int buttonOffset = 0;
for(int i=0;i<2;i++)
for( int i = 0; i < 2; i++ )
{
if(_button[i]!=null)
if( _button[i] != null )
{
if(_button[i]->isVisible())
if( _button[i]->isVisible() )
{
if(_slider->isVertical())
{
buttonOffset+=_button[i]->getTall();
if( _slider->isVertical() )
{
buttonOffset += _button[i]->getTall();
}
else
{
buttonOffset+=_button[i]->getWide();
buttonOffset += _button[i]->getWide();
}
}
}
}
_slider->setButtonOffset(buttonOffset);
_slider->setButtonOffset( buttonOffset );
}
int wide,tall;
getSize(wide,tall);
setSize(wide,tall);
int wide, tall;
getSize( wide, tall );
setSize( wide, tall );
}

View File

@ -5,16 +5,15 @@
// $NoKeywords: $
//=============================================================================
#pragma once
#if !defined(VGUI_SCROLLBAR2_H)
#ifndef VGUI_SCROLLBAR2_H
#define VGUI_SCROLLBAR2_H
#include<VGUI.h>
#include<VGUI_Panel.h>
#include<VGUI_Dar.h>
#include <VGUI.h>
#include <VGUI_Panel.h>
#include <VGUI_Dar.h>
namespace vgui
{
class IntChangeSignal;
class Button;
class Slider2;
@ -25,34 +24,34 @@ class Slider2;
class VGUIAPI ScrollBar2 : public Panel
{
public:
ScrollBar2(int x,int y,int wide,int tall,bool vertical);
public:
virtual void setValue(int value);
virtual int getValue();
virtual void addIntChangeSignal(IntChangeSignal* s);
virtual void setRange(int min,int max);
virtual void setRangeWindow(int rangeWindow);
virtual void setRangeWindowEnabled(bool state);
virtual void setSize(int wide,int tall);
virtual bool isVertical();
virtual bool hasFullRange();
virtual void setButton(Button *button,int index);
virtual Button* getButton(int index);
virtual void setSlider(Slider2 *slider);
virtual Slider2 *getSlider();
virtual void doButtonPressed(int buttonIndex);
virtual void setButtonPressedScrollValue(int value);
virtual void validate();
public: //bullshit public
virtual void fireIntChangeSignal();
protected:
virtual void performLayout();
protected:
Button* _button[2];
Slider2 *_slider;
Dar<IntChangeSignal*> _intChangeSignalDar;
int _buttonPressedScrollValue;
};
ScrollBar2( int x, int y, int wide, int tall, bool vertical );
virtual void setValue( int value );
virtual int getValue();
virtual void addIntChangeSignal( IntChangeSignal *s );
virtual void setRange(int min, int max );
virtual void setRangeWindow( int rangeWindow );
virtual void setRangeWindowEnabled( bool state );
virtual void setSize( int wide, int tall );
virtual bool isVertical();
virtual bool hasFullRange();
virtual void setButton( Button *button,int index );
virtual Button *getButton( int index );
virtual void setSlider( Slider2 *slider );
virtual Slider2 *getSlider();
virtual void doButtonPressed( int buttonIndex );
virtual void setButtonPressedScrollValue( int value );
virtual void validate();
// bullshit public
virtual void fireIntChangeSignal();
protected:
virtual void performLayout();
Button *_button[2];
Slider2 *_slider;
Dar<IntChangeSignal*> _intChangeSignalDar;
int _buttonPressedScrollValue;
};
}
#endif // VGUI_SCROLLBAR2_H

View File

@ -5,12 +5,12 @@
// $NoKeywords: $
//=============================================================================
#include "VGUI_Slider2.h"
#include "vgui_slider2.h"
#include<VGUI_InputSignal.h>
#include<VGUI_App.h>
#include<VGUI_IntChangeSignal.h>
#include<VGUI_MouseCode.h>
#include <VGUI_InputSignal.h>
#include <VGUI_App.h>
#include <VGUI_IntChangeSignal.h>
#include <VGUI_MouseCode.h>
using namespace vgui;
@ -18,54 +18,57 @@ namespace
{
class FooDefaultSliderSignal : public InputSignal
{
private:
Slider2* _slider;
Slider2 *_slider;
public:
FooDefaultSliderSignal(Slider2* slider)
FooDefaultSliderSignal( Slider2 *slider )
{
_slider=slider;
_slider = slider;
}
public:
void cursorMoved(int x,int y,Panel* panel)
void cursorMoved( int x, int y, Panel *panel )
{
_slider->privateCursorMoved(x,y,panel);
_slider->privateCursorMoved( x, y, panel );
}
void cursorEntered(Panel* panel){}
void cursorExited(Panel* panel){}
void mouseDoublePressed(MouseCode code,Panel* panel){}
void mousePressed(MouseCode code,Panel* panel)
void cursorEntered( Panel *panel ) {}
void cursorExited( Panel *panel ) {}
void mouseDoublePressed( MouseCode code, Panel *panel ) {}
void mousePressed( MouseCode code, Panel *panel )
{
_slider->privateMousePressed(code,panel);
_slider->privateMousePressed( code, panel );
}
void mouseReleased(MouseCode code,Panel* panel)
void mouseReleased( MouseCode code, Panel *panel )
{
_slider->privateMouseReleased(code,panel);
_slider->privateMouseReleased( code, panel );
}
void mouseWheeled(int delta,Panel* panel){}
void keyPressed(KeyCode code,Panel* panel){}
void keyTyped(KeyCode code,Panel* panel){}
void keyReleased(KeyCode code,Panel* panel){}
void keyFocusTicked(Panel* panel){}
void mouseWheeled( int delta, Panel *panel ) {}
void keyPressed( KeyCode code, Panel *panel ) {}
void keyTyped( KeyCode code, Panel *panel ) {}
void keyReleased( KeyCode code, Panel *panel ) {}
void keyFocusTicked( Panel *panel ) {}
};
}
Slider2::Slider2(int x,int y,int wide,int tall,bool vertical) : Panel(x,y,wide,tall)
Slider2::Slider2( int x, int y, int wide, int tall, bool vertical ) : Panel( x, y, wide, tall )
{
_vertical=vertical;
_dragging=false;
_value=0;
_range[0]=0;
_range[1]=299;
_rangeWindow=0;
_rangeWindowEnabled=false;
_buttonOffset=0;
_vertical = vertical;
_dragging = false;
_value = 0;
_range[0] = 0;
_range[1] = 299;
_rangeWindow = 0;
_rangeWindowEnabled = false;
_buttonOffset = 0;
recomputeNobPosFromValue();
addInputSignal(new FooDefaultSliderSignal(this));
addInputSignal( new FooDefaultSliderSignal( this ) );
}
void Slider2::setSize(int wide,int tall)
void Slider2::setSize( int wide, int tall )
{
Panel::setSize(wide,tall);
Panel::setSize( wide, tall );
recomputeNobPosFromValue();
}
@ -74,24 +77,24 @@ bool Slider2::isVertical()
return _vertical;
}
void Slider2::setValue(int value)
void Slider2::setValue( int value )
{
int oldValue=_value;
int oldValue = _value;
if(value<_range[0])
if( value < _range[0] )
{
value=_range[0];
value = _range[0];
}
if(value>_range[1])
if( value > _range[1] )
{
value=_range[1];
}
_value=value;
_value = value;
recomputeNobPosFromValue();
if(_value!=oldValue)
if( _value != oldValue )
{
fireIntChangeSignal();
}
@ -104,48 +107,48 @@ int Slider2::getValue()
void Slider2::recomputeNobPosFromValue()
{
int wide,tall;
int wide, tall;
getPaintSize(wide,tall);
getPaintSize( wide, tall );
float fwide=(float)wide;
float ftall=(float)tall;
float frange=(float)(_range[1]-_range[0]);
float fvalue=(float)(_value-_range[0]);
float fper=fvalue/frange;
float frangewindow=(float)(_rangeWindow);
float fwide = (float)wide;
float ftall = (float)tall;
float frange = (float)(_range[1] - _range[0]);
float fvalue = (float)(_value - _range[0]);
float fper = fvalue / frange;
float frangewindow = (float)_rangeWindow;
if(frangewindow<0)
if( frangewindow < 0 )
{
frangewindow=0;
frangewindow = 0;
}
if(!_rangeWindowEnabled)
if( !_rangeWindowEnabled )
{
frangewindow=frange;
frangewindow = frange;
}
if ( frangewindow > 0 )
if( frangewindow > 0 )
{
if(_vertical)
if( _vertical )
{
float fnobsize=frangewindow;
float freepixels = ftall - fnobsize;
float firstpixel = freepixels * fper;
_nobPos[0]=(int)( firstpixel );
_nobPos[1]=(int)( firstpixel + fnobsize );
_nobPos[0] = (int)( firstpixel );
_nobPos[1] = (int)( firstpixel + fnobsize );
if(_nobPos[1]>tall)
if( _nobPos[1] > tall )
{
_nobPos[0]=tall-((int)fnobsize);
_nobPos[1]=tall;
_nobPos[0] = tall - ((int)fnobsize);
_nobPos[1] = tall;
}
}
else
{
float fnobsize=frangewindow;
float fnobsize = frangewindow;
float freepixels = fwide - fnobsize;
float firstpixel = freepixels * fper;
@ -153,10 +156,10 @@ void Slider2::recomputeNobPosFromValue()
_nobPos[0]=(int)( firstpixel );
_nobPos[1]=(int)( firstpixel + fnobsize );
if(_nobPos[1]>wide)
if( _nobPos[1] > wide )
{
_nobPos[0]=wide-((int)fnobsize);
_nobPos[1]=wide;
_nobPos[0] = wide - ((int)fnobsize);
_nobPos[1] = wide;
}
}
}
@ -167,40 +170,41 @@ void Slider2::recomputeNobPosFromValue()
void Slider2::recomputeValueFromNobPos()
{
int wide,tall;
getPaintSize(wide,tall);
float fwide=(float)wide;
float ftall=(float)tall;
float frange=(float)(_range[1]-_range[0]);
float fvalue=(float)(_value-_range[0]);
float fnob=(float)_nobPos[0];
float frangewindow=(float)(_rangeWindow);
getPaintSize( wide, tall );
if(frangewindow<0)
float fwide = (float)wide;
float ftall = (float)tall;
float frange = (float)(_range[1] - _range[0]);
float fvalue = (float)(_value - _range[0]);
float fnob = (float)_nobPos[0];
float frangewindow = (float)(_rangeWindow);
if( frangewindow < 0 )
{
frangewindow=0;
frangewindow = 0;
}
if(!_rangeWindowEnabled)
if( !_rangeWindowEnabled )
{
frangewindow=frange;
frangewindow = frange;
}
if ( frangewindow > 0 )
if( frangewindow > 0 )
{
if(_vertical)
if( _vertical )
{
float fnobsize=frangewindow;
fvalue=frange*(fnob/(ftall-fnobsize));
float fnobsize = frangewindow;
fvalue = frange * ( fnob / ( ftall - fnobsize ) );
}
else
{
float fnobsize=frangewindow;
fvalue=frange*(fnob/(fwide-fnobsize));
float fnobsize = frangewindow;
fvalue = frange * ( fnob / ( fwide - fnobsize ) );
}
}
// Take care of rounding issues.
_value=(int)(fvalue+_range[0]+0.5);
_value = (int)( fvalue+_range[0] + 0.5 );
// Clamp final result
_value = ( _value < _range[1] ) ? _value : _range[1];
@ -208,27 +212,28 @@ void Slider2::recomputeValueFromNobPos()
bool Slider2::hasFullRange()
{
int wide,tall;
getPaintSize(wide,tall);
int wide, tall;
float fwide=(float)wide;
float ftall=(float)tall;
float frange=(float)(_range[1]-_range[0]);
float frangewindow=(float)(_rangeWindow);
getPaintSize( wide, tall );
if(frangewindow<0)
float fwide = (float)wide;
float ftall = (float)tall;
float frange = (float)( _range[1] - _range[0] );
float frangewindow = (float)( _rangeWindow );
if( frangewindow < 0 )
{
frangewindow=0;
frangewindow = 0;
}
if(!_rangeWindowEnabled)
if( !_rangeWindowEnabled )
{
frangewindow=frange;
frangewindow = frange;
}
if ( frangewindow > 0 )
if( frangewindow > 0 )
{
if(_vertical)
if( _vertical )
{
if( frangewindow <= ( ftall + _buttonOffset ) )
{
@ -247,126 +252,125 @@ bool Slider2::hasFullRange()
return false;
}
void Slider2::addIntChangeSignal(IntChangeSignal* s)
void Slider2::addIntChangeSignal( IntChangeSignal *s )
{
_intChangeSignalDar.putElement(s);
}
void Slider2::fireIntChangeSignal()
{
for(int i=0;i<_intChangeSignalDar.getCount();i++)
for( int i = 0; i < _intChangeSignalDar.getCount(); i++ )
{
_intChangeSignalDar[i]->intChanged(getValue(),this);
_intChangeSignalDar[i]->intChanged( getValue(), this );
}
}
void Slider2::paintBackground()
{
int wide,tall;
getPaintSize(wide,tall);
int wide, tall;
getPaintSize( wide, tall );
if (_vertical)
if( _vertical )
{
// background behind slider
drawSetColor(40, 40, 40, 0);
drawFilledRect(0, 0, wide, tall);
drawSetColor( 40, 40, 40, 0 );
drawFilledRect( 0, 0, wide, tall );
// slider front
drawSetColor(0, 0, 0, 0);
drawFilledRect(0,_nobPos[0],wide,_nobPos[1]);
drawSetColor( 0, 0, 0, 0 );
drawFilledRect( 0, _nobPos[0], wide, _nobPos[1] );
// slider border
drawSetColor(60, 60, 60, 0);
drawFilledRect(0,_nobPos[0],wide,_nobPos[0]+1); // top
drawFilledRect(0,_nobPos[1],wide,_nobPos[1]+1); // bottom
drawFilledRect(0,_nobPos[0]+1,1,_nobPos[1]); // left
drawFilledRect(wide-1,_nobPos[0]+1,wide,_nobPos[1]); // right
drawSetColor( 60, 60, 60, 0 );
drawFilledRect( 0, _nobPos[0], wide, _nobPos[0] + 1 ); // top
drawFilledRect( 0, _nobPos[1], wide, _nobPos[1] + 1 ); // bottom
drawFilledRect( 0, _nobPos[0] + 1, 1, _nobPos[1] ); // left
drawFilledRect( wide - 1, _nobPos[0] + 1, wide, _nobPos[1] ); // right
}
else
{
//!! doesn't work
drawSetColor( Scheme::sc_secondary3 );
drawFilledRect( 0, 0, wide, tall );
drawSetColor(Scheme::sc_secondary3);
drawFilledRect(0,0,wide,tall);
drawSetColor( Scheme::sc_black );
drawOutlinedRect( 0, 0, wide, tall );
drawSetColor(Scheme::sc_black);
drawOutlinedRect(0,0,wide,tall);
drawSetColor(Scheme::sc_primary2);
drawFilledRect(_nobPos[0],0,_nobPos[1],tall);
drawSetColor( Scheme::sc_primary2 );
drawFilledRect( _nobPos[0], 0, _nobPos[1], tall );
drawSetColor(Scheme::sc_black);
drawOutlinedRect(_nobPos[0],0,_nobPos[1],tall);
drawSetColor( Scheme::sc_black );
drawOutlinedRect( _nobPos[0], 0, _nobPos[1], tall );
}
}
void Slider2::setRange(int min,int max)
void Slider2::setRange( int min, int max )
{
if(max<min)
if( max < min )
{
max=min;
max =min;
}
if(min>max)
if( min > max )
{
min=max;
min = max;
}
_range[0]=min;
_range[1]=max;
_range[0] = min;
_range[1] = max;
}
void Slider2::getRange(int& min,int& max)
void Slider2::getRange( int &min, int &max )
{
min=_range[0];
max=_range[1];
min = _range[0];
max = _range[1];
}
void Slider2::privateCursorMoved(int x,int y,Panel* panel)
void Slider2::privateCursorMoved( int x, int y, Panel *panel )
{
if(!_dragging)
if( !_dragging )
{
return;
}
getApp()->getCursorPos(x,y);
screenToLocal(x,y);
getApp()->getCursorPos( x, y );
screenToLocal( x, y );
int wide,tall;
getPaintSize(wide,tall);
int wide, tall;
getPaintSize( wide, tall);
if(_vertical)
if( _vertical )
{
_nobPos[0]=_nobDragStartPos[0]+(y-_dragStartPos[1]);
_nobPos[1]=_nobDragStartPos[1]+(y-_dragStartPos[1]);
_nobPos[0] = _nobDragStartPos[0] + ( y - _dragStartPos[1] );
_nobPos[1] = _nobDragStartPos[1] + ( y - _dragStartPos[1] );
if(_nobPos[1]>tall)
if( _nobPos[1] > tall )
{
_nobPos[0]=tall-(_nobPos[1]-_nobPos[0]);
_nobPos[1]=tall;
_nobPos[0] = tall - ( _nobPos[1] - _nobPos[0] );
_nobPos[1] = tall;
}
if(_nobPos[0]<0)
if( _nobPos[0] < 0 )
{
_nobPos[1]=_nobPos[1]-_nobPos[0];
_nobPos[0]=0;
_nobPos[1] = _nobPos[1] - _nobPos[0];
_nobPos[0] = 0;
}
}
else
{
_nobPos[0]=_nobDragStartPos[0]+(x-_dragStartPos[0]);
_nobPos[1]=_nobDragStartPos[1]+(x-_dragStartPos[0]);
_nobPos[0] = _nobDragStartPos[0] + ( x - _dragStartPos[0] );
_nobPos[1] = _nobDragStartPos[1] + ( x - _dragStartPos[0] );
if(_nobPos[1]>wide)
if( _nobPos[1] > wide )
{
_nobPos[0]=wide-(_nobPos[1]-_nobPos[0]);
_nobPos[1]=wide;
_nobPos[0] = wide - ( _nobPos[1] - _nobPos[0] );
_nobPos[1] = wide;
}
if(_nobPos[0]<0)
if( _nobPos[0] < 0 )
{
_nobPos[1]=_nobPos[1]-_nobPos[0];
_nobPos[0]=0;
_nobPos[1] = _nobPos[1] - _nobPos[0];
_nobPos[0] = 0;
}
}
@ -375,62 +379,61 @@ void Slider2::privateCursorMoved(int x,int y,Panel* panel)
fireIntChangeSignal();
}
void Slider2::privateMousePressed(MouseCode code,Panel* panel)
void Slider2::privateMousePressed( MouseCode code, Panel *panel )
{
int x,y;
getApp()->getCursorPos(x,y);
screenToLocal(x,y);
getApp()->getCursorPos( x, y );
screenToLocal( x, y );
if(_vertical)
if( _vertical )
{
if((y>=_nobPos[0])&&(y<_nobPos[1]))
if( ( y >= _nobPos[0] ) && ( y < _nobPos[1] ) )
{
_dragging=true;
getApp()->setMouseCapture(this);
_nobDragStartPos[0]=_nobPos[0];
_nobDragStartPos[1]=_nobPos[1];
_dragStartPos[0]=x;
_dragStartPos[1]=y;
_dragging = true;
getApp()->setMouseCapture( this );
_nobDragStartPos[0] = _nobPos[0];
_nobDragStartPos[1] = _nobPos[1];
_dragStartPos[0] = x;
_dragStartPos[1] = y;
}
}
else
{
if((x>=_nobPos[0])&&(x<_nobPos[1]))
if( ( x >= _nobPos[0] ) && ( x < _nobPos[1] ) )
{
_dragging=true;
getApp()->setMouseCapture(this);
_nobDragStartPos[0]=_nobPos[0];
_nobDragStartPos[1]=_nobPos[1];
_dragStartPos[0]=x;
_dragStartPos[1]=y;
_dragging = true;
getApp()->setMouseCapture( this );
_nobDragStartPos[0] = _nobPos[0];
_nobDragStartPos[1] = _nobPos[1];
_dragStartPos[0] = x;
_dragStartPos[1] = y;
}
}
}
void Slider2::privateMouseReleased(MouseCode code,Panel* panel)
void Slider2::privateMouseReleased( MouseCode code, Panel *panel )
{
_dragging=false;
getApp()->setMouseCapture(null);
_dragging = false;
getApp()->setMouseCapture( null );
}
void Slider2::getNobPos(int& min, int& max)
void Slider2::getNobPos( int &min, int &max )
{
min=_nobPos[0];
max=_nobPos[1];
min = _nobPos[0];
max = _nobPos[1];
}
void Slider2::setRangeWindow(int rangeWindow)
void Slider2::setRangeWindow( int rangeWindow )
{
_rangeWindow=rangeWindow;
}
void Slider2::setRangeWindowEnabled(bool state)
void Slider2::setRangeWindowEnabled( bool state )
{
_rangeWindowEnabled=state;
}
void Slider2::setButtonOffset(int buttonOffset)
void Slider2::setButtonOffset( int buttonOffset )
{
_buttonOffset=buttonOffset;
}
}

View File

@ -5,22 +5,20 @@
// $NoKeywords: $
//=============================================================================
#pragma once
#if !defined(VGUI_SLIDER2_H)
#ifndef VGUI_SLIDER2_H
#define VGUI_SLIDER2_H
#include<VGUI.h>
#include<VGUI_Panel.h>
#include<VGUI_Dar.h>
#include <VGUI.h>
#include <VGUI_Panel.h>
#include <VGUI_Dar.h>
namespace vgui
{
enum MouseCode;
class IntChangeSignal;
class VGUIAPI Slider2 : public Panel
{
private:
bool _vertical;
bool _dragging;
int _nobPos[2];
@ -33,31 +31,31 @@ private:
bool _rangeWindowEnabled;
int _buttonOffset;
public:
Slider2(int x,int y,int wide,int tall,bool vertical);
public:
virtual void setValue(int value);
Slider2( int x, int y, int wide, int tall, bool vertical );
virtual void setValue( int value );
virtual int getValue();
virtual bool isVertical();
virtual void addIntChangeSignal(IntChangeSignal* s);
virtual void setRange(int min,int max);
virtual void getRange(int& min,int& max);
virtual void setRangeWindow(int rangeWindow);
virtual void setRangeWindowEnabled(bool state);
virtual void setSize(int wide,int tall);
virtual void getNobPos(int& min, int& max);
virtual void addIntChangeSignal( IntChangeSignal *s );
virtual void setRange( int min, int max );
virtual void getRange( int &min, int &max );
virtual void setRangeWindow( int rangeWindow );
virtual void setRangeWindowEnabled( bool state );
virtual void setSize( int wide, int tall );
virtual void getNobPos( int &min, int &max );
virtual bool hasFullRange();
virtual void setButtonOffset(int buttonOffset);
virtual void setButtonOffset( int buttonOffset );
private:
virtual void recomputeNobPosFromValue();
virtual void recomputeValueFromNobPos();
public: //bullshit public
virtual void privateCursorMoved(int x,int y,Panel* panel);
virtual void privateMousePressed(MouseCode code,Panel* panel);
virtual void privateMouseReleased(MouseCode code,Panel* panel);
public: // bullshit public
virtual void privateCursorMoved( int x, int y, Panel *panel );
virtual void privateMousePressed( MouseCode code, Panel *panel );
virtual void privateMouseReleased( MouseCode code, Panel *panel );
protected:
virtual void fireIntChangeSignal();
virtual void fireIntChangeSignal();
virtual void paintBackground();
};
}
#endif // VGUI_SLIDER2_H

View File

@ -9,79 +9,73 @@
#include <stdio.h>
#include "voice_banmgr.h"
#define BANMGR_FILEVERSION 1
char const *g_pBanMgrFilename = "voice_ban.dt";
// Hash a player ID to a byte.
unsigned char HashPlayerID(char const playerID[16])
unsigned char HashPlayerID( char const playerID[16] )
{
unsigned char curHash = 0;
for(int i=0; i < 16; i++)
for( int i = 0; i < 16; i++ )
curHash += (unsigned char)playerID[i];
return curHash;
}
CVoiceBanMgr::CVoiceBanMgr()
{
Clear();
}
CVoiceBanMgr::~CVoiceBanMgr()
{
Term();
}
bool CVoiceBanMgr::Init(char const *pGameDir)
bool CVoiceBanMgr::Init( char const *pGameDir )
{
Term();
char filename[512];
_snprintf(filename, sizeof(filename), "%s/%s", pGameDir, g_pBanMgrFilename);
sprintf( filename, "%s/%s", pGameDir, g_pBanMgrFilename );
// Load in the squelch file.
FILE *fp = fopen(filename, "rb");
if(fp)
FILE *fp = fopen( filename, "rb" );
if( fp )
{
int version;
fread(&version, 1, sizeof(version), fp);
if(version == BANMGR_FILEVERSION)
fread( &version, 1, sizeof(version), fp );
if( version == BANMGR_FILEVERSION )
{
fseek(fp, 0, SEEK_END);
int nIDs = (ftell(fp) - sizeof(version)) / 16;
fseek(fp, sizeof(version), SEEK_SET);
fseek( fp, 0, SEEK_END );
int nIDs = ( ftell( fp ) - sizeof(version) ) / 16;
fseek( fp, sizeof(version), SEEK_SET );
for(int i=0; i < nIDs; i++)
for( int i = 0; i < nIDs; i++ )
{
char playerID[16];
fread(playerID, 1, 16, fp);
AddBannedPlayer(playerID);
}
fread( playerID, 1, 16, fp );
AddBannedPlayer( playerID );
}
}
fclose(fp);
fclose( fp );
}
return true;
}
void CVoiceBanMgr::Term()
{
// Free all the player structures.
for(int i=0; i < 256; i++)
for( int i = 0; i < 256; i++ )
{
BannedPlayer *pListHead = &m_PlayerHash[i];
BannedPlayer *pNext;
for(BannedPlayer *pCur=pListHead->m_pNext; pCur != pListHead; pCur=pNext)
for( BannedPlayer *pCur=pListHead->m_pNext; pCur != pListHead; pCur = pNext )
{
pNext = pCur->m_pNext;
delete pCur;
@ -91,53 +85,51 @@ void CVoiceBanMgr::Term()
Clear();
}
void CVoiceBanMgr::SaveState(char const *pGameDir)
{
// Save the file out.
char filename[512];
_snprintf(filename, sizeof(filename), "%s/%s", pGameDir, g_pBanMgrFilename);
FILE *fp = fopen(filename, "wb");
if(fp)
sprintf( filename, "%s/%s", pGameDir, g_pBanMgrFilename );
FILE *fp = fopen( filename, "wb" );
if( fp )
{
int version = BANMGR_FILEVERSION;
fwrite(&version, 1, sizeof(version), fp);
fwrite( &version, 1, sizeof(version), fp );
for(int i=0; i < 256; i++)
for( int i = 0; i < 256; i++ )
{
BannedPlayer *pListHead = &m_PlayerHash[i];
for(BannedPlayer *pCur=pListHead->m_pNext; pCur != pListHead; pCur=pCur->m_pNext)
for( BannedPlayer *pCur = pListHead->m_pNext; pCur != pListHead; pCur = pCur->m_pNext )
{
fwrite(pCur->m_PlayerID, 1, 16, fp);
fwrite( pCur->m_PlayerID, 1, 16, fp );
}
}
fclose(fp);
fclose( fp );
}
}
bool CVoiceBanMgr::GetPlayerBan(char const playerID[16])
bool CVoiceBanMgr::GetPlayerBan( char const playerID[16] )
{
return !!InternalFindPlayerSquelch(playerID);
return !!InternalFindPlayerSquelch( playerID );
}
void CVoiceBanMgr::SetPlayerBan(char const playerID[16], bool bSquelch)
void CVoiceBanMgr::SetPlayerBan( char const playerID[16], bool bSquelch )
{
if(bSquelch)
if( bSquelch )
{
// Is this guy already squelched?
if(GetPlayerBan(playerID))
if( GetPlayerBan( playerID ) )
return;
AddBannedPlayer(playerID);
AddBannedPlayer( playerID );
}
else
{
BannedPlayer *pPlayer = InternalFindPlayerSquelch(playerID);
if(pPlayer)
BannedPlayer *pPlayer = InternalFindPlayerSquelch( playerID );
if( pPlayer )
{
pPlayer->m_pPrev->m_pNext = pPlayer->m_pNext;
pPlayer->m_pNext->m_pPrev = pPlayer->m_pPrev;
@ -146,52 +138,51 @@ void CVoiceBanMgr::SetPlayerBan(char const playerID[16], bool bSquelch)
}
}
void CVoiceBanMgr::ForEachBannedPlayer(void (*callback)(char id[16]))
void CVoiceBanMgr::ForEachBannedPlayer(void (*callback)( char id[16] ) )
{
for(int i=0; i < 256; i++)
for( int i = 0; i < 256; i++ )
{
for(BannedPlayer *pCur=m_PlayerHash[i].m_pNext; pCur != &m_PlayerHash[i]; pCur=pCur->m_pNext)
for( BannedPlayer *pCur = m_PlayerHash[i].m_pNext; pCur != &m_PlayerHash[i]; pCur = pCur->m_pNext )
{
callback(pCur->m_PlayerID);
callback( pCur->m_PlayerID );
}
}
}
void CVoiceBanMgr::Clear()
{
// Tie off the hash table entries.
for(int i=0; i < 256; i++)
for( int i = 0; i < 256; i++ )
m_PlayerHash[i].m_pNext = m_PlayerHash[i].m_pPrev = &m_PlayerHash[i];
}
CVoiceBanMgr::BannedPlayer* CVoiceBanMgr::InternalFindPlayerSquelch(char const playerID[16])
CVoiceBanMgr::BannedPlayer *CVoiceBanMgr::InternalFindPlayerSquelch( char const playerID[16] )
{
int index = HashPlayerID(playerID);
int index = HashPlayerID( playerID );
BannedPlayer *pListHead = &m_PlayerHash[index];
for(BannedPlayer *pCur=pListHead->m_pNext; pCur != pListHead; pCur=pCur->m_pNext)
for( BannedPlayer *pCur = pListHead->m_pNext; pCur != pListHead; pCur=pCur->m_pNext )
{
if(memcmp(playerID, pCur->m_PlayerID, 16) == 0)
if( memcmp( playerID, pCur->m_PlayerID, 16 ) == 0 )
return pCur;
}
return NULL;
}
CVoiceBanMgr::BannedPlayer* CVoiceBanMgr::AddBannedPlayer(char const playerID[16])
CVoiceBanMgr::BannedPlayer* CVoiceBanMgr::AddBannedPlayer( char const playerID[16] )
{
BannedPlayer *pNew = new BannedPlayer;
if(!pNew)
if( !pNew )
return NULL;
int index = HashPlayerID(playerID);
memcpy(pNew->m_PlayerID, playerID, 16);
int index = HashPlayerID( playerID );
memcpy( pNew->m_PlayerID, playerID, 16 );
pNew->m_pNext = &m_PlayerHash[index];
pNew->m_pPrev = m_PlayerHash[index].m_pPrev;
pNew->m_pPrev->m_pNext = pNew->m_pNext->m_pPrev = pNew;
return pNew;
}

View File

@ -5,47 +5,42 @@
// $NoKeywords: $
//=============================================================================
#pragma once
#if !defined(VOICE_BANMGR_H)
#ifndef VOICE_BANMGR_H
#define VOICE_BANMGR_H
// This class manages the (persistent) list of squelched players.
class CVoiceBanMgr
{
public:
CVoiceBanMgr();
~CVoiceBanMgr();
CVoiceBanMgr();
~CVoiceBanMgr();
// Init loads the list of squelched players from disk.
bool Init(char const *pGameDir);
bool Init( char const *pGameDir );
void Term();
// Saves the state into voice_squelch.dt.
void SaveState(char const *pGameDir);
void SaveState( char const *pGameDir );
bool GetPlayerBan(char const playerID[16]);
void SetPlayerBan(char const playerID[16], bool bSquelch);
bool GetPlayerBan( char const playerID[16] );
void SetPlayerBan( char const playerID[16], bool bSquelch );
// Call your callback for each banned player.
void ForEachBannedPlayer(void (*callback)(char id[16]));
void ForEachBannedPlayer( void (*callback)( char id[16] ) );
protected:
class BannedPlayer
{
public:
char m_PlayerID[16];
char m_PlayerID[16];
BannedPlayer *m_pPrev, *m_pNext;
};
void Clear();
BannedPlayer* InternalFindPlayerSquelch(char const playerID[16]);
BannedPlayer* AddBannedPlayer(char const playerID[16]);
protected:
void Clear();
BannedPlayer *InternalFindPlayerSquelch( char const playerID[16] );
BannedPlayer *AddBannedPlayer( char const playerID[16] );
BannedPlayer m_PlayerHash[256];
};
#endif // VOICE_BANMGR_H

View File

@ -5,14 +5,14 @@
// $NoKeywords: $
//=============================================================================
#pragma once
#if !defined(VOICE_COMMON_H)
#ifndef VOICE_COMMON_H
#define VOICE_COMMON_H
#include "bitvec.h"
#define VOICE_MAX_PLAYERS 32 // (todo: this should just be set to MAX_CLIENTS).
#define VOICE_MAX_PLAYERS_DW ((VOICE_MAX_PLAYERS / 32) + !!(VOICE_MAX_PLAYERS & 31))
#define VOICE_MAX_PLAYERS_DW ((VOICE_MAX_PLAYERS / 32) + !!(VOICE_MAX_PLAYERS & 31))
typedef CBitVec<VOICE_MAX_PLAYERS> CPlayerBitVec;
#endif // VOICE_COMMON_H

View File

@ -1,10 +1,11 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#include "archtypes.h" // DAL
#include "voice_gamemgr.h"
#include <string.h>
#include <assert.h>
@ -13,8 +14,11 @@
#include "cbase.h"
#include "player.h"
#define UPDATE_INTERVAL 0.3
// These are stored off as CVoiceGameMgr is created and deleted.
CPlayerBitVec g_PlayerModEnable; // Set to 1 for each player if the player wants to use voice in this mod.
// (If it's zero, then the server reports that the game rules are saying the
@ -32,24 +36,25 @@ cvar_t voice_serverdebug = {"voice_serverdebug", "0"};
// Set game rules to allow all clients to talk to each other.
// Muted players still can't talk to each other.
cvar_t sv_alltalk = {"sv_alltalk", "0"};
cvar_t sv_alltalk = {"sv_alltalk", "0", FCVAR_SERVER};
// ------------------------------------------------------------------------ //
// Static helpers.
// ------------------------------------------------------------------------ //
// Find a player with a case-insensitive name search.
static CBasePlayer* FindPlayerByName( const char *pTestName )
static CBasePlayer* FindPlayerByName(const char *pTestName)
{
for( int i = 1; i <= gpGlobals->maxClients; i++ )
for(int i=1; i <= gpGlobals->maxClients; i++)
{
edict_t *pEdict = g_engfuncs.pfnPEntityOfEntIndex( i );
if( pEdict )
edict_t *pEdict = g_engfuncs.pfnPEntityOfEntIndex(i);
if(pEdict)
{
CBaseEntity *pEnt = CBaseEntity::Instance( pEdict );
if( pEnt && pEnt->IsPlayer() )
{
const char *pNetName = STRING( pEnt->pev->netname );
if( stricmp( pNetName, pTestName ) == 0 )
CBaseEntity *pEnt = CBaseEntity::Instance(pEdict);
if(pEnt && pEnt->IsPlayer())
{
const char *pNetName = STRING(pEnt->pev->netname);
if(stricmp(pNetName, pTestName) == 0)
{
return (CBasePlayer*)pEnt;
}
@ -75,30 +80,37 @@ static void VoiceServerDebug( char const *pFmt, ... )
ALERT( at_console, "%s", msg );
}
// ------------------------------------------------------------------------ //
// CVoiceGameMgr.
// ------------------------------------------------------------------------ //
CVoiceGameMgr::CVoiceGameMgr()
{
m_UpdateInterval = 0;
m_nMaxPlayers = 0;
}
CVoiceGameMgr::~CVoiceGameMgr()
{
}
bool CVoiceGameMgr::Init( IVoiceGameMgrHelper *pHelper, int maxClients )
bool CVoiceGameMgr::Init(
IVoiceGameMgrHelper *pHelper,
int maxClients)
{
m_pHelper = pHelper;
m_nMaxPlayers = VOICE_MAX_PLAYERS < maxClients ? VOICE_MAX_PLAYERS : maxClients;
g_engfuncs.pfnPrecacheModel( "sprites/voiceicon.spr" );
g_engfuncs.pfnPrecacheModel("sprites/voiceicon.spr");
m_msgPlayerVoiceMask = REG_USER_MSG( "VoiceMask", VOICE_MAX_PLAYERS_DW * 4 * 2 );
m_msgPlayerVoiceMask = REG_USER_MSG( "VoiceMask", VOICE_MAX_PLAYERS_DW*4 * 2 );
m_msgRequestState = REG_USER_MSG( "ReqState", 0 );
// register voice_serverdebug if it hasn't been registered already
if( !CVAR_GET_POINTER( "voice_serverdebug" ) )
if ( !CVAR_GET_POINTER( "voice_serverdebug" ) )
CVAR_REGISTER( &voice_serverdebug );
if( !CVAR_GET_POINTER( "sv_alltalk" ) )
@ -107,70 +119,73 @@ bool CVoiceGameMgr::Init( IVoiceGameMgrHelper *pHelper, int maxClients )
return true;
}
void CVoiceGameMgr::SetHelper( IVoiceGameMgrHelper *pHelper )
void CVoiceGameMgr::SetHelper(IVoiceGameMgrHelper *pHelper)
{
m_pHelper = pHelper;
}
void CVoiceGameMgr::Update( double frametime )
void CVoiceGameMgr::Update(double frametime)
{
// Only update periodically.
m_UpdateInterval += frametime;
if( m_UpdateInterval < UPDATE_INTERVAL )
if(m_UpdateInterval < UPDATE_INTERVAL)
return;
UpdateMasks();
}
void CVoiceGameMgr::ClientConnected( edict_t *pEdict )
void CVoiceGameMgr::ClientConnected(edict_t *pEdict)
{
int index = ENTINDEX( pEdict ) - 1;
int index = ENTINDEX(pEdict) - 1;
// Clear out everything we use for deltas on this guy.
g_bWantModEnable[index] = true;
g_SentGameRulesMasks[index].Init( 0 );
g_SentBanMasks[index].Init( 0 );
g_SentGameRulesMasks[index].Init(0);
g_SentBanMasks[index].Init(0);
}
// Called to determine if the Receiver has muted (blocked) the Sender
// Returns true if the receiver has blocked the sender
bool CVoiceGameMgr::PlayerHasBlockedPlayer( CBasePlayer *pReceiver, CBasePlayer *pSender )
bool CVoiceGameMgr::PlayerHasBlockedPlayer(CBasePlayer *pReceiver, CBasePlayer *pSender)
{
int iReceiverIndex, iSenderIndex;
if( !pReceiver || !pSender )
if ( !pReceiver || !pSender )
return false;
iReceiverIndex = pReceiver->entindex() - 1;
iSenderIndex = pSender->entindex() - 1;
iSenderIndex = pSender->entindex() - 1;
if( iReceiverIndex < 0 || iReceiverIndex >= m_nMaxPlayers || iSenderIndex < 0 || iSenderIndex >= m_nMaxPlayers )
if ( iReceiverIndex < 0 || iReceiverIndex >= m_nMaxPlayers || iSenderIndex < 0 || iSenderIndex >= m_nMaxPlayers )
return false;
return ( g_BanMasks[iReceiverIndex][iSenderIndex] ? true : false );
}
bool CVoiceGameMgr::ClientCommand( CBasePlayer *pPlayer, const char *cmd )
bool CVoiceGameMgr::ClientCommand(CBasePlayer *pPlayer, const char *cmd)
{
int playerClientIndex = pPlayer->entindex() - 1;
if( playerClientIndex < 0 || playerClientIndex >= m_nMaxPlayers )
if(playerClientIndex < 0 || playerClientIndex >= m_nMaxPlayers)
{
VoiceServerDebug( "CVoiceGameMgr::ClientCommand: cmd %s from invalid client (%d)\n", cmd, playerClientIndex );
return true;
}
bool bBan = stricmp( cmd, "vban" ) == 0;
if( bBan && CMD_ARGC() >= 2 )
bool bBan = stricmp(cmd, "vban") == 0;
if(bBan && CMD_ARGC() >= 2)
{
for( int i = 1; i < CMD_ARGC(); i++ )
for(int i=1; i < CMD_ARGC(); i++)
{
unsigned long mask = 0;
sscanf( CMD_ARGV(i), "%lx", &mask );
uint32 mask = 0;
sscanf(CMD_ARGV(i), "%x", &mask);
if( i <= VOICE_MAX_PLAYERS_DW )
if(i <= VOICE_MAX_PLAYERS_DW)
{
VoiceServerDebug( "CVoiceGameMgr::ClientCommand: vban (0x%x) from %d\n", mask, playerClientIndex );
g_BanMasks[playerClientIndex].SetDWord( i - 1, mask );
g_BanMasks[playerClientIndex].SetDWord(i-1, mask);
}
else
{
@ -179,15 +194,15 @@ bool CVoiceGameMgr::ClientCommand( CBasePlayer *pPlayer, const char *cmd )
}
// Force it to update the masks now.
//UpdateMasks();
// UpdateMasks();
return true;
}
else if( stricmp( cmd, "VModEnable" ) == 0 && CMD_ARGC() >= 2 )
else if(stricmp(cmd, "VModEnable") == 0 && CMD_ARGC() >= 2)
{
VoiceServerDebug( "CVoiceGameMgr::ClientCommand: VModEnable (%d)\n", !!atoi( CMD_ARGV( 1 ) ) );
g_PlayerModEnable[playerClientIndex] = !!atoi( CMD_ARGV( 1 ) );
VoiceServerDebug( "CVoiceGameMgr::ClientCommand: VModEnable (%d)\n", !!atoi(CMD_ARGV(1)) );
g_PlayerModEnable[playerClientIndex] = !!atoi(CMD_ARGV(1));
g_bWantModEnable[playerClientIndex] = false;
//UpdateMasks();
// UpdateMasks();
return true;
}
else
@ -196,22 +211,23 @@ bool CVoiceGameMgr::ClientCommand( CBasePlayer *pPlayer, const char *cmd )
}
}
void CVoiceGameMgr::UpdateMasks()
{
m_UpdateInterval = 0;
bool bAllTalk = !!g_engfuncs.pfnCVarGetFloat( "sv_alltalk" );
bool bAllTalk = !!(sv_alltalk.value);
for( int iClient = 0; iClient < m_nMaxPlayers; iClient++ )
for(int iClient=0; iClient < m_nMaxPlayers; iClient++)
{
CBaseEntity *pEnt = UTIL_PlayerByIndex( iClient + 1 );
if( !pEnt || !pEnt->IsPlayer() )
CBaseEntity *pEnt = UTIL_PlayerByIndex(iClient+1);
if(!pEnt || !pEnt->IsPlayer())
continue;
// Request the state of their "VModEnable" cvar.
if( g_bWantModEnable[iClient] )
if(g_bWantModEnable[iClient])
{
MESSAGE_BEGIN( MSG_ONE, m_msgRequestState, NULL, pEnt->pev );
MESSAGE_BEGIN(MSG_ONE, m_msgRequestState, NULL, pEnt->pev);
MESSAGE_END();
}
@ -221,10 +237,10 @@ void CVoiceGameMgr::UpdateMasks()
if( g_PlayerModEnable[iClient] )
{
// Build a mask of who they can hear based on the game rules.
for( int iOtherClient = 0; iOtherClient < m_nMaxPlayers; iOtherClient++ )
for(int iOtherClient=0; iOtherClient < m_nMaxPlayers; iOtherClient++)
{
pEnt = UTIL_PlayerByIndex( iOtherClient + 1 );
if( pEnt && pEnt->IsPlayer() && ( bAllTalk || m_pHelper->CanPlayerHearPlayer( pPlayer, (CBasePlayer*)pEnt ) ) )
CBaseEntity *pEnt = UTIL_PlayerByIndex(iOtherClient+1);
if(pEnt && (bAllTalk || m_pHelper->CanPlayerHearPlayer(pPlayer, (CBasePlayer*)pEnt)) )
{
gameRulesMask[iOtherClient] = true;
}
@ -232,26 +248,27 @@ void CVoiceGameMgr::UpdateMasks()
}
// If this is different from what the client has, send an update.
if( gameRulesMask != g_SentGameRulesMasks[iClient] || g_BanMasks[iClient] != g_SentBanMasks[iClient] )
if(gameRulesMask != g_SentGameRulesMasks[iClient] ||
g_BanMasks[iClient] != g_SentBanMasks[iClient])
{
g_SentGameRulesMasks[iClient] = gameRulesMask;
g_SentBanMasks[iClient] = g_BanMasks[iClient];
MESSAGE_BEGIN( MSG_ONE, m_msgPlayerVoiceMask, NULL, pPlayer->pev );
MESSAGE_BEGIN(MSG_ONE, m_msgPlayerVoiceMask, NULL, pPlayer->pev);
int dw;
for( dw = 0; dw < VOICE_MAX_PLAYERS_DW; dw++ )
for(dw=0; dw < VOICE_MAX_PLAYERS_DW; dw++)
{
WRITE_LONG( gameRulesMask.GetDWord( dw ) );
WRITE_LONG( g_BanMasks[iClient].GetDWord( dw ) );
WRITE_LONG(gameRulesMask.GetDWord(dw));
WRITE_LONG(g_BanMasks[iClient].GetDWord(dw));
}
MESSAGE_END();
}
// Tell the engine.
for( int iOtherClient = 0; iOtherClient < m_nMaxPlayers; iOtherClient++ )
for(int iOtherClient=0; iOtherClient < m_nMaxPlayers; iOtherClient++)
{
bool bCanHear = gameRulesMask[iOtherClient] && !g_BanMasks[iClient][iOtherClient];
g_engfuncs.pfnVoice_SetClientListening( iClient + 1, iOtherClient + 1, bCanHear );
g_engfuncs.pfnVoice_SetClientListening(iClient+1, iOtherClient+1, bCanHear);
}
}
}

View File

@ -1,66 +1,80 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//========= Copyright <EFBFBD> 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#pragma once
#if !defined(VOICE_GAMEMGR_H)
#ifndef VOICE_GAMEMGR_H
#define VOICE_GAMEMGR_H
#ifdef _WIN32
#endif
#include "voice_common.h"
class CGameRules;
class CBasePlayer;
class IVoiceGameMgrHelper
{
public:
virtual ~IVoiceGameMgrHelper() {}
virtual ~IVoiceGameMgrHelper() {}
// Called each frame to determine which players are allowed to hear each other. This overrides
// whatever squelch settings players have.
virtual bool CanPlayerHearPlayer( CBasePlayer *pListener, CBasePlayer *pTalker ) = 0;
virtual bool CanPlayerHearPlayer(CBasePlayer *pListener, CBasePlayer *pTalker) = 0;
};
// CVoiceGameMgr manages which clients can hear which other clients.
class CVoiceGameMgr
{
public:
CVoiceGameMgr();
virtual ~CVoiceGameMgr();
CVoiceGameMgr();
virtual ~CVoiceGameMgr();
bool Init(
IVoiceGameMgrHelper *m_pHelper,
int maxClients
);
bool Init( IVoiceGameMgrHelper *m_pHelper, int maxClients );
void SetHelper( IVoiceGameMgrHelper *pHelper );
void SetHelper(IVoiceGameMgrHelper *pHelper);
// Updates which players can hear which other players.
// If gameplay mode is DM, then only players within the PVS can hear each other.
// If gameplay mode is teamplay, then only players on the same team can hear each other.
// Player masks are always applied.
void Update( double frametime );
void Update(double frametime);
// Called when a new client connects (unsquelches its entity for everyone).
void ClientConnected( struct edict_s *pEdict );
void ClientConnected(struct edict_s *pEdict);
// Called on ClientCommand. Checks for the squelch and unsquelch commands.
// Returns true if it handled the command.
bool ClientCommand( CBasePlayer *pPlayer, const char *cmd );
bool ClientCommand(CBasePlayer *pPlayer, const char *cmd);
// Called to determine if the Receiver has muted (blocked) the Sender
// Returns true if the receiver has blocked the sender
bool PlayerHasBlockedPlayer( CBasePlayer *pReceiver, CBasePlayer *pSender );
bool PlayerHasBlockedPlayer(CBasePlayer *pReceiver, CBasePlayer *pSender);
private:
// Force it to update the client masks.
void UpdateMasks();
void UpdateMasks();
private:
int m_msgPlayerVoiceMask;
int m_msgRequestState;
IVoiceGameMgrHelper *m_pHelper;
int m_nMaxPlayers;
double m_UpdateInterval; // How long since the last update.
int m_msgPlayerVoiceMask;
int m_msgRequestState;
IVoiceGameMgrHelper *m_pHelper;
int m_nMaxPlayers;
double m_UpdateInterval; // How long since the last update.
};
#endif // VOICE_GAMEMGR_H

View File

@ -6,34 +6,16 @@
//=============================================================================
// There are hud.h's coming out of the woodwork so this ensures that we get the right one.
#if defined( DMC_BUILD )
#include "../dmc/cl_dll/hud.h"
#include "../dmc/cl_dll/cl_util.h"
#elif defined( RICOCHET_BUILD )
#include "../ricochet/cl_dll/hud.h"
#include "../ricochet/cl_dll/cl_util.h"
#else
#include "../cl_dll/hud.h"
#include "../cl_dll/cl_util.h"
#endif
#include "../cl_dll/hud.h"
#include "../cl_dll/cl_util.h"
#include <assert.h>
#include <string.h>
#include <stdio.h>
#if defined( DMC_BUILD )
#include "../dmc/cl_dll/parsemsg.h"
#include "../dmc/cl_dll/hud_servers.h"
#include "../dmc/cl_dll/demo.h"
#elif defined( RICOCHET_BUILD )
#include "../ricochet/cl_dll/parsemsg.h"
#include "../ricochet/cl_dll/hud_servers.h"
#include "../ricochet/cl_dll/demo.h"
#else
#include "../cl_dll/parsemsg.h"
#include "../cl_dll/hud_servers.h"
#include "../cl_dll/demo.h"
#endif
#include "../cl_dll/parsemsg.h"
#include "../cl_dll/hud_servers.h"
#include "../cl_dll/demo.h"
#include "demo_api.h"
#include "voice_status.h"
@ -46,23 +28,16 @@
#include "vgui_helpers.h"
#include "vgui_mousecode.h"
using namespace vgui;
extern int cam_thirdperson;
#define VOICE_MODEL_INTERVAL 0.3
#define SCOREBOARD_BLINK_FREQUENCY 0.3 // How often to blink the scoreboard icons.
#define SQUELCHOSCILLATE_PER_SECOND 2.0f
extern BitmapTGA *LoadTGA( const char* pImageName );
// ---------------------------------------------------------------------- //
// The voice manager for the client.
// ---------------------------------------------------------------------- //
@ -73,63 +48,60 @@ CVoiceStatus* GetClientVoiceMgr()
return &g_VoiceStatus;
}
// ---------------------------------------------------------------------- //
// CVoiceStatus.
// ---------------------------------------------------------------------- //
static CVoiceStatus *g_pInternalVoiceStatus = NULL;
int __MsgFunc_VoiceMask(const char *pszName, int iSize, void *pbuf)
int __MsgFunc_VoiceMask( const char *pszName, int iSize, void *pbuf )
{
if(g_pInternalVoiceStatus)
g_pInternalVoiceStatus->HandleVoiceMaskMsg(iSize, pbuf);
if( g_pInternalVoiceStatus )
g_pInternalVoiceStatus->HandleVoiceMaskMsg( iSize, pbuf );
return 1;
}
int __MsgFunc_ReqState(const char *pszName, int iSize, void *pbuf)
int __MsgFunc_ReqState( const char *pszName, int iSize, void *pbuf )
{
if(g_pInternalVoiceStatus)
g_pInternalVoiceStatus->HandleReqStateMsg(iSize, pbuf);
if( g_pInternalVoiceStatus )
g_pInternalVoiceStatus->HandleReqStateMsg( iSize, pbuf );
return 1;
}
int g_BannedPlayerPrintCount;
void ForEachBannedPlayer(char id[16])
void ForEachBannedPlayer( char id[16] )
{
char str[256];
sprintf(str, "Ban %d: %2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x\n",
sprintf( str, "Ban %d: %2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x\n",
g_BannedPlayerPrintCount++,
id[0], id[1], id[2], id[3],
id[4], id[5], id[6], id[7],
id[8], id[9], id[10], id[11],
id[12], id[13], id[14], id[15]
);
strupr(str);
strupr( str );
gEngfuncs.pfnConsolePrint(str);
}
void ShowBannedCallback()
{
if(g_pInternalVoiceStatus)
if( g_pInternalVoiceStatus )
{
g_BannedPlayerPrintCount = 0;
gEngfuncs.pfnConsolePrint("------- BANNED PLAYERS -------\n");
g_pInternalVoiceStatus->m_BanMgr.ForEachBannedPlayer(ForEachBannedPlayer);
g_pInternalVoiceStatus->m_BanMgr.ForEachBannedPlayer( ForEachBannedPlayer );
gEngfuncs.pfnConsolePrint("------------------------------\n");
}
}
// ---------------------------------------------------------------------- //
// CVoiceStatus.
// ---------------------------------------------------------------------- //
CVoiceStatus::CVoiceStatus()
{
m_bBanMgrInitialized = false;
@ -142,84 +114,80 @@ CVoiceStatus::CVoiceStatus()
m_pScoreboardSpeaking2 = NULL;
m_pScoreboardSquelch = NULL;
m_pScoreboardBanned = NULL;
m_pLocalBitmap = NULL;
m_pAckBitmap = NULL;
m_bTalking = m_bServerAcked = false;
memset(m_pBanButtons, 0, sizeof(m_pBanButtons));
memset( m_pBanButtons, 0, sizeof(m_pBanButtons) );
m_bServerModEnable = -1;
m_pchGameDir = NULL;
}
CVoiceStatus::~CVoiceStatus()
{
g_pInternalVoiceStatus = NULL;
for(int i=0; i < MAX_VOICE_SPEAKERS; i++)
for( int i = 0; i < MAX_VOICE_SPEAKERS; i++ )
{
delete m_Labels[i].m_pLabel;
m_Labels[i].m_pLabel = NULL;
delete m_Labels[i].m_pIcon;
m_Labels[i].m_pIcon = NULL;
delete m_Labels[i].m_pBackground;
m_Labels[i].m_pBackground = NULL;
}
}
delete m_pLocalLabel;
m_pLocalLabel = NULL;
FreeBitmaps();
if(m_pchGameDir)
if( m_pchGameDir )
{
if(m_bBanMgrInitialized)
if( m_bBanMgrInitialized )
{
m_BanMgr.SaveState(m_pchGameDir);
m_BanMgr.SaveState( m_pchGameDir );
}
free(m_pchGameDir);
free( m_pchGameDir );
}
}
int CVoiceStatus::Init(
IVoiceStatusHelper *pHelper,
Panel **pParentPanel)
int CVoiceStatus::Init( IVoiceStatusHelper *pHelper, Panel **pParentPanel )
{
// Setup the voice_modenable cvar.
gEngfuncs.pfnRegisterVariable("voice_modenable", "1", FCVAR_ARCHIVE);
gEngfuncs.pfnRegisterVariable( "voice_modenable", "1", FCVAR_ARCHIVE );
gEngfuncs.pfnRegisterVariable("voice_clientdebug", "0", 0);
gEngfuncs.pfnRegisterVariable( "voice_clientdebug", "0", 0 );
gEngfuncs.pfnAddCommand("voice_showbanned", ShowBannedCallback);
gEngfuncs.pfnAddCommand( "voice_showbanned", ShowBannedCallback );
if(gEngfuncs.pfnGetGameDirectory())
if( gEngfuncs.pfnGetGameDirectory() )
{
m_BanMgr.Init(gEngfuncs.pfnGetGameDirectory());
m_BanMgr.Init( gEngfuncs.pfnGetGameDirectory() );
m_bBanMgrInitialized = true;
}
assert(!g_pInternalVoiceStatus);
assert( !g_pInternalVoiceStatus );
g_pInternalVoiceStatus = this;
m_BlinkTimer = 0;
m_VoiceHeadModel = NULL;
memset(m_Labels, 0, sizeof(m_Labels));
for(int i=0; i < MAX_VOICE_SPEAKERS; i++)
memset( m_Labels, 0, sizeof(m_Labels) );
for( int i = 0; i < MAX_VOICE_SPEAKERS; i++ )
{
CVoiceLabel *pLabel = &m_Labels[i];
pLabel->m_pBackground = new Label("");
pLabel->m_pBackground = new Label( "" );
if(pLabel->m_pLabel = new Label(""))
if( pLabel->m_pLabel = new Label( "" ) )
{
pLabel->m_pLabel->setVisible( true );
pLabel->m_pLabel->setFont( Scheme::sf_primary2 );
@ -237,92 +205,90 @@ int CVoiceStatus::Init(
pLabel->m_clientindex = -1;
}
m_pLocalLabel = new ImagePanel(NULL);
m_pLocalLabel = new ImagePanel( NULL );
m_bInSquelchMode = false;
m_pHelper = pHelper;
m_pParentPanel = pParentPanel;
gHUD.AddHudElem(this);
gHUD.AddHudElem( this );
m_iFlags = HUD_ACTIVE;
HOOK_MESSAGE(VoiceMask);
HOOK_MESSAGE(ReqState);
HOOK_MESSAGE( VoiceMask );
HOOK_MESSAGE( ReqState );
// Cache the game directory for use when we shut down
const char *pchGameDirT = gEngfuncs.pfnGetGameDirectory();
m_pchGameDir = (char *)malloc(strlen(pchGameDirT) + 1);
strcpy(m_pchGameDir, pchGameDirT);
m_pchGameDir = (char *)malloc( strlen( pchGameDirT ) + 1 );
strcpy( m_pchGameDir, pchGameDirT );
return 1;
}
int CVoiceStatus::VidInit()
{
FreeBitmaps();
if( m_pLocalBitmap = vgui_LoadTGA("gfx/vgui/icntlk_pl.tga") )
if( m_pLocalBitmap = vgui_LoadTGA( "gfx/vgui/icntlk_pl.tga" ) )
{
m_pLocalBitmap->setColor(Color(255,255,255,135));
m_pLocalBitmap->setColor( Color( 255, 255, 255, 135 ) );
}
if( m_pAckBitmap = vgui_LoadTGA("gfx/vgui/icntlk_sv.tga") )
if( m_pAckBitmap = vgui_LoadTGA( "gfx/vgui/icntlk_sv.tga" ) )
{
m_pAckBitmap->setColor(Color(255,255,255,135)); // Give just a tiny bit of translucency so software draws correctly.
m_pAckBitmap->setColor( Color( 255, 255, 255, 135 ) ); // Give just a tiny bit of translucency so software draws correctly.
}
m_pLocalLabel->setImage( m_pLocalBitmap );
m_pLocalLabel->setVisible( false );
if( m_pSpeakerLabelIcon = vgui_LoadTGANoInvertAlpha( "gfx/vgui/speaker4.tga" ) )
m_pSpeakerLabelIcon->setColor( Color( 255, 255, 255, 1 ) ); // Give just a tiny bit of translucency so software draws correctly.
if( m_pSpeakerLabelIcon = vgui_LoadTGANoInvertAlpha("gfx/vgui/speaker4.tga" ) )
m_pSpeakerLabelIcon->setColor( Color(255,255,255,1) ); // Give just a tiny bit of translucency so software draws correctly.
if( m_pScoreboardNeverSpoken = vgui_LoadTGANoInvertAlpha( "gfx/vgui/640_speaker1.tga" ) )
m_pScoreboardNeverSpoken->setColor( Color( 255, 255, 255, 1 ) ); // Give just a tiny bit of translucency so software draws correctly.
if (m_pScoreboardNeverSpoken = vgui_LoadTGANoInvertAlpha("gfx/vgui/640_speaker1.tga"))
m_pScoreboardNeverSpoken->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly.
if( m_pScoreboardNotSpeaking = vgui_LoadTGANoInvertAlpha( "gfx/vgui/640_speaker2.tga" ) )
m_pScoreboardNotSpeaking->setColor( Color( 255, 255, 255, 1 ) ); // Give just a tiny bit of translucency so software draws correctly.
if(m_pScoreboardNotSpeaking = vgui_LoadTGANoInvertAlpha("gfx/vgui/640_speaker2.tga"))
m_pScoreboardNotSpeaking->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly.
if(m_pScoreboardSpeaking = vgui_LoadTGANoInvertAlpha("gfx/vgui/640_speaker3.tga"))
m_pScoreboardSpeaking->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly.
if(m_pScoreboardSpeaking2 = vgui_LoadTGANoInvertAlpha("gfx/vgui/640_speaker4.tga"))
m_pScoreboardSpeaking2->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly.
if(m_pScoreboardSquelch = vgui_LoadTGA("gfx/vgui/icntlk_squelch.tga"))
m_pScoreboardSquelch->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly.
if( m_pScoreboardSpeaking = vgui_LoadTGANoInvertAlpha( "gfx/vgui/640_speaker3.tga" ) )
m_pScoreboardSpeaking->setColor( Color( 255, 255, 255, 1 ) ); // Give just a tiny bit of translucency so software draws correctly.
if(m_pScoreboardBanned = vgui_LoadTGA("gfx/vgui/640_voiceblocked.tga"))
m_pScoreboardBanned->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly.
if( m_pScoreboardSpeaking2 = vgui_LoadTGANoInvertAlpha( "gfx/vgui/640_speaker4.tga" ) )
m_pScoreboardSpeaking2->setColor( Color( 255, 255, 255, 1 ) ); // Give just a tiny bit of translucency so software draws correctly.
if( m_pScoreboardSquelch = vgui_LoadTGA( "gfx/vgui/icntlk_squelch.tga" ) )
m_pScoreboardSquelch->setColor( Color( 255, 255, 255, 1 ) ); // Give just a tiny bit of translucency so software draws correctly.
if( m_pScoreboardBanned = vgui_LoadTGA( "gfx/vgui/640_voiceblocked.tga" ) )
m_pScoreboardBanned->setColor( Color( 255, 255, 255, 1 ) ); // Give just a tiny bit of translucency so software draws correctly.
// Figure out the voice head model height.
m_VoiceHeadModelHeight = 45;
char *pFile = (char *)gEngfuncs.COM_LoadFile("scripts/voicemodel.txt", 5, NULL);
if(pFile)
char *pFile = (char *)gEngfuncs.COM_LoadFile( "scripts/voicemodel.txt", 5, NULL );
if( pFile )
{
char token[4096];
gEngfuncs.COM_ParseFile(pFile, token);
if(token[0] >= '0' && token[0] <= '9')
gEngfuncs.COM_ParseFile( pFile, token );
if( token[0] >= '0' && token[0] <= '9' )
{
m_VoiceHeadModelHeight = (float)atof(token);
m_VoiceHeadModelHeight = (float)atof( token );
}
gEngfuncs.COM_FreeFile(pFile);
gEngfuncs.COM_FreeFile( pFile );
}
m_VoiceHeadModel = gEngfuncs.pfnSPR_Load("sprites/voiceicon.spr");
m_VoiceHeadModel = gEngfuncs.pfnSPR_Load( "sprites/voiceicon.spr" );
return TRUE;
}
void CVoiceStatus::Frame(double frametime)
void CVoiceStatus::Frame( double frametime )
{
// check server banned players once per second
if(gEngfuncs.GetClientTime() - m_LastUpdateServerState > 1)
if( gEngfuncs.GetClientTime() - m_LastUpdateServerState > 1 )
{
UpdateServerState(false);
UpdateServerState( false );
}
m_BlinkTimer += frametime;
@ -330,51 +296,50 @@ void CVoiceStatus::Frame(double frametime)
// Update speaker labels.
if( m_pHelper->CanShowSpeakerLabels() )
{
for( int i=0; i < MAX_VOICE_SPEAKERS; i++ )
for( int i = 0; i < MAX_VOICE_SPEAKERS; i++ )
m_Labels[i].m_pBackground->setVisible( m_Labels[i].m_clientindex != -1 );
}
else
{
for( int i=0; i < MAX_VOICE_SPEAKERS; i++ )
for( int i = 0; i < MAX_VOICE_SPEAKERS; i++ )
m_Labels[i].m_pBackground->setVisible( false );
}
for(int i=0; i < VOICE_MAX_PLAYERS; i++)
for( int i = 0; i < VOICE_MAX_PLAYERS; i++ )
UpdateBanButton(i);
}
void CVoiceStatus::CreateEntities()
{
if(!m_VoiceHeadModel)
if( !m_VoiceHeadModel )
return;
cl_entity_t *localPlayer = gEngfuncs.GetLocalPlayer();
int iOutModel = 0;
for(int i=0; i < VOICE_MAX_PLAYERS; i++)
for( int i = 0; i < VOICE_MAX_PLAYERS; i++ )
{
if(!m_VoicePlayers[i])
if( !m_VoicePlayers[i] )
continue;
cl_entity_s *pClient = gEngfuncs.GetEntityByIndex(i+1);
cl_entity_s *pClient = gEngfuncs.GetEntityByIndex( i + 1 );
// Don't show an icon if the player is not in our PVS.
if(!pClient || pClient->curstate.messagenum < localPlayer->curstate.messagenum)
if( !pClient || pClient->curstate.messagenum < localPlayer->curstate.messagenum )
continue;
// Don't show an icon for dead or spectating players (ie: invisible entities).
if(pClient->curstate.effects & EF_NODRAW)
if( pClient->curstate.effects & EF_NODRAW )
continue;
// Don't show an icon for the local player unless we're in thirdperson mode.
if(pClient == localPlayer && !cam_thirdperson)
if( pClient == localPlayer && !cam_thirdperson )
continue;
cl_entity_s *pEnt = &m_VoiceHeadModels[iOutModel];
++iOutModel;
memset(pEnt, 0, sizeof(*pEnt));
memset( pEnt, 0, sizeof(*pEnt) );
pEnt->curstate.rendermode = kRenderTransAdd;
pEnt->curstate.renderamt = 255;
@ -382,30 +347,30 @@ void CVoiceStatus::CreateEntities()
pEnt->curstate.renderfx = kRenderFxNoDissipation;
pEnt->curstate.framerate = 1;
pEnt->curstate.frame = 0;
pEnt->model = (struct model_s*)gEngfuncs.GetSpritePointer(m_VoiceHeadModel);
pEnt->model = (struct model_s*)gEngfuncs.GetSpritePointer( m_VoiceHeadModel );
pEnt->angles[0] = pEnt->angles[1] = pEnt->angles[2] = 0;
pEnt->curstate.scale = 0.5f;
pEnt->origin[0] = pEnt->origin[1] = 0;
pEnt->origin[2] = 45;
VectorAdd(pEnt->origin, pClient->origin, pEnt->origin);
VectorAdd( pEnt->origin, pClient->origin, pEnt->origin );
// Tell the engine.
gEngfuncs.CL_CreateVisibleEntity(ET_NORMAL, pEnt);
gEngfuncs.CL_CreateVisibleEntity( ET_NORMAL, pEnt );
}
}
void CVoiceStatus::UpdateSpeakerStatus(int entindex, qboolean bTalking)
void CVoiceStatus::UpdateSpeakerStatus( int entindex, qboolean bTalking )
{
if(!*m_pParentPanel)
if( !*m_pParentPanel )
return;
if( gEngfuncs.pfnGetCvarFloat("voice_clientdebug") )
{
char msg[256];
_snprintf( msg, sizeof(msg), "CVoiceStatus::UpdateSpeakerStatus: ent %d talking = %d\n", entindex, bTalking );
sprintf( msg, "CVoiceStatus::UpdateSpeakerStatus: ent %d talking = %d\n", entindex, bTalking );
gEngfuncs.pfnConsolePrint( msg );
}
@ -423,30 +388,30 @@ void CVoiceStatus::UpdateSpeakerStatus(int entindex, qboolean bTalking)
{
m_bServerAcked = !!bTalking;
}
else if(entindex >= 0 && entindex <= VOICE_MAX_PLAYERS)
else if( entindex >= 0 && entindex <= VOICE_MAX_PLAYERS )
{
int iClient = entindex - 1;
if(iClient < 0)
if( iClient < 0 )
return;
CVoiceLabel *pLabel = FindVoiceLabel(iClient);
if(bTalking)
CVoiceLabel *pLabel = FindVoiceLabel( iClient );
if( bTalking )
{
m_VoicePlayers[iClient] = true;
m_VoiceEnabledPlayers[iClient] = true;
// If we don't have a label for this guy yet, then create one.
if(!pLabel)
if( !pLabel )
{
if(pLabel = GetFreeVoiceLabel())
if( pLabel = GetFreeVoiceLabel() )
{
// Get the name from the engine.
hud_player_info_t info;
memset(&info, 0, sizeof(info));
GetPlayerInfo(entindex, &info);
hud_player_info_t info = {0};
GetPlayerInfo( entindex, &info );
char paddedName[512];
_snprintf(paddedName, sizeof(paddedName), "%s ", info.name);
sprintf( paddedName, "%s ", info.name );
int color[3];
m_pHelper->GetPlayerTextColor( entindex, color );
@ -474,9 +439,9 @@ void CVoiceStatus::UpdateSpeakerStatus(int entindex, qboolean bTalking)
m_VoicePlayers[iClient] = false;
// If we have a label for this guy, kill it.
if(pLabel)
if( pLabel )
{
pLabel->m_pBackground->setVisible(false);
pLabel->m_pBackground->setVisible( false );
pLabel->m_clientindex = -1;
}
}
@ -485,14 +450,13 @@ void CVoiceStatus::UpdateSpeakerStatus(int entindex, qboolean bTalking)
RepositionLabels();
}
void CVoiceStatus::UpdateServerState(bool bForce)
void CVoiceStatus::UpdateServerState( bool bForce )
{
// Can't do anything when we're not in a level.
char const *pLevelName = gEngfuncs.pfnGetLevelName();
if( pLevelName[0] == 0 )
{
if( gEngfuncs.pfnGetCvarFloat("voice_clientdebug") )
if( gEngfuncs.pfnGetCvarFloat( "voice_clientdebug" ) )
{
gEngfuncs.pfnConsolePrint( "CVoiceStatus::UpdateServerState: pLevelName[0]==0\n" );
}
@ -500,167 +464,177 @@ void CVoiceStatus::UpdateServerState(bool bForce)
return;
}
int bCVarModEnable = !!gEngfuncs.pfnGetCvarFloat("voice_modenable");
if(bForce || m_bServerModEnable != bCVarModEnable)
int bCVarModEnable = !!gEngfuncs.pfnGetCvarFloat( "voice_modenable" );
if( bForce || m_bServerModEnable != bCVarModEnable )
{
m_bServerModEnable = bCVarModEnable;
char str[256];
_snprintf(str, sizeof(str), "VModEnable %d", m_bServerModEnable);
ServerCmd(str);
if(gEngfuncs.pfnGetCvarFloat("voice_clientdebug"))
sprintf( str, "VModEnable %d", m_bServerModEnable );
ServerCmd( str );
if( gEngfuncs.pfnGetCvarFloat( "voice_clientdebug" ) )
{
char msg[256];
sprintf(msg, "CVoiceStatus::UpdateServerState: Sending '%s'\n", str);
gEngfuncs.pfnConsolePrint(msg);
sprintf( msg, "CVoiceStatus::UpdateServerState: Sending '%s'\n", str );
gEngfuncs.pfnConsolePrint( msg );
}
}
char str[2048];
sprintf(str, "vban");
char str[2048] = "vban";
bool bChange = false;
for(unsigned long dw=0; dw < VOICE_MAX_PLAYERS_DW; dw++)
for( unsigned long dw = 0; dw < VOICE_MAX_PLAYERS_DW; dw++ )
{
unsigned long serverBanMask = 0;
unsigned long banMask = 0;
for(unsigned long i=0; i < 32; i++)
for( unsigned long i = 0; i < 32; i++ )
{
char playerID[16];
if(!gEngfuncs.GetPlayerUniqueID(i+1, playerID))
if( !gEngfuncs.GetPlayerUniqueID( i + 1, playerID ) )
continue;
if(m_BanMgr.GetPlayerBan(playerID))
if( m_BanMgr.GetPlayerBan( playerID ) )
banMask |= 1 << i;
if(m_ServerBannedPlayers[dw*32 + i])
if( m_ServerBannedPlayers[dw * 32 + i] )
serverBanMask |= 1 << i;
}
if(serverBanMask != banMask)
if( serverBanMask != banMask )
bChange = true;
// Ok, the server needs to be updated.
char numStr[512];
sprintf(numStr, " %x", banMask);
strcat(str, numStr);
}
if(bChange || bForce)
if( bChange || bForce )
{
if(gEngfuncs.pfnGetCvarFloat("voice_clientdebug"))
if( gEngfuncs.pfnGetCvarFloat( "voice_clientdebug" ) )
{
char msg[256];
sprintf(msg, "CVoiceStatus::UpdateServerState: Sending '%s'\n", str);
gEngfuncs.pfnConsolePrint(msg);
sprintf( msg, "CVoiceStatus::UpdateServerState: Sending '%s'\n", str );
gEngfuncs.pfnConsolePrint( msg );
}
gEngfuncs.pfnServerCmdUnreliable(str); // Tell the server..
gEngfuncs.pfnServerCmdUnreliable( str ); // Tell the server..
}
else
{
if (gEngfuncs.pfnGetCvarFloat("voice_clientdebug"))
if( gEngfuncs.pfnGetCvarFloat( "voice_clientdebug" ) )
{
gEngfuncs.pfnConsolePrint( "CVoiceStatus::UpdateServerState: no change\n" );
}
}
m_LastUpdateServerState = gEngfuncs.GetClientTime();
}
void CVoiceStatus::UpdateSpeakerImage(Label *pLabel, int iPlayer)
void CVoiceStatus::UpdateSpeakerImage( Label *pLabel, int iPlayer )
{
m_pBanButtons[iPlayer-1] = pLabel;
UpdateBanButton(iPlayer-1);
m_pBanButtons[iPlayer - 1] = pLabel;
UpdateBanButton(iPlayer - 1);
}
void CVoiceStatus::UpdateBanButton(int iClient)
void CVoiceStatus::UpdateBanButton( int iClient )
{
Label *pPanel = m_pBanButtons[iClient];
if (!pPanel)
if( !pPanel )
return;
char playerID[16];
extern bool HACK_GetPlayerUniqueID( int iPlayer, char playerID[16] );
if(!HACK_GetPlayerUniqueID(iClient+1, playerID))
if( !HACK_GetPlayerUniqueID( iClient + 1, playerID ) )
return;
// Figure out if it's blinking or not.
bool bBlink = fmod(m_BlinkTimer, SCOREBOARD_BLINK_FREQUENCY*2) < SCOREBOARD_BLINK_FREQUENCY;
bool bBlink = fmod( m_BlinkTimer, SCOREBOARD_BLINK_FREQUENCY * 2 ) < SCOREBOARD_BLINK_FREQUENCY;
bool bTalking = !!m_VoicePlayers[iClient];
bool bBanned = m_BanMgr.GetPlayerBan(playerID);
bool bBanned = m_BanMgr.GetPlayerBan( playerID );
bool bNeverSpoken = !m_VoiceEnabledPlayers[iClient];
// Get the appropriate image to display on the panel.
if (bBanned)
if( bBanned )
{
pPanel->setImage(m_pScoreboardBanned);
pPanel->setImage( m_pScoreboardBanned );
}
else if (bTalking)
else if( bTalking )
{
if (bBlink)
if( bBlink )
{
pPanel->setImage(m_pScoreboardSpeaking2);
pPanel->setImage( m_pScoreboardSpeaking2 );
}
else
{
pPanel->setImage(m_pScoreboardSpeaking);
pPanel->setImage( m_pScoreboardSpeaking );
}
pPanel->setFgColor(255, 170, 0, 1);
pPanel->setFgColor( 255, 170, 0, 1 );
}
else if (bNeverSpoken)
else if( bNeverSpoken )
{
pPanel->setImage(m_pScoreboardNeverSpoken);
pPanel->setFgColor(100, 100, 100, 1);
pPanel->setImage( m_pScoreboardNeverSpoken );
pPanel->setFgColor( 100, 100, 100, 1 );
}
else
{
pPanel->setImage(m_pScoreboardNotSpeaking);
pPanel->setImage( m_pScoreboardNotSpeaking );
}
}
void CVoiceStatus::HandleVoiceMaskMsg(int iSize, void *pbuf)
void CVoiceStatus::HandleVoiceMaskMsg( int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
unsigned long dw;
for(dw=0; dw < VOICE_MAX_PLAYERS_DW; dw++)
{
m_AudiblePlayers.SetDWord(dw, (unsigned long)READ_LONG());
m_ServerBannedPlayers.SetDWord(dw, (unsigned long)READ_LONG());
if(gEngfuncs.pfnGetCvarFloat("voice_clientdebug"))
for( dw = 0; dw < VOICE_MAX_PLAYERS_DW; dw++ )
{
m_AudiblePlayers.SetDWord( dw, (unsigned long)READ_LONG() );
m_ServerBannedPlayers.SetDWord( dw, (unsigned long)READ_LONG() );
if( gEngfuncs.pfnGetCvarFloat( "voice_clientdebug" ) )
{
char str[256];
gEngfuncs.pfnConsolePrint("CVoiceStatus::HandleVoiceMaskMsg\n");
sprintf(str, " - m_AudiblePlayers[%d] = %lu\n", dw, m_AudiblePlayers.GetDWord(dw));
gEngfuncs.pfnConsolePrint(str);
sprintf(str, " - m_ServerBannedPlayers[%d] = %lu\n", dw, m_ServerBannedPlayers.GetDWord(dw));
gEngfuncs.pfnConsolePrint(str);
gEngfuncs.pfnConsolePrint( "CVoiceStatus::HandleVoiceMaskMsg\n" );
sprintf( str, " - m_AudiblePlayers[%d] = %lu\n", dw, m_AudiblePlayers.GetDWord( dw ) );
gEngfuncs.pfnConsolePrint( str );
sprintf( str, " - m_ServerBannedPlayers[%d] = %lu\n", dw, m_ServerBannedPlayers.GetDWord( dw ) );
gEngfuncs.pfnConsolePrint( str );
}
}
m_bServerModEnable = READ_BYTE();
}
void CVoiceStatus::HandleReqStateMsg(int iSize, void *pbuf)
void CVoiceStatus::HandleReqStateMsg( int iSize, void *pbuf )
{
if(gEngfuncs.pfnGetCvarFloat("voice_clientdebug"))
if( gEngfuncs.pfnGetCvarFloat( "voice_clientdebug" ) )
{
gEngfuncs.pfnConsolePrint("CVoiceStatus::HandleReqStateMsg\n");
gEngfuncs.pfnConsolePrint( "CVoiceStatus::HandleReqStateMsg\n" );
}
UpdateServerState(true);
UpdateServerState( true );
}
void CVoiceStatus::StartSquelchMode()
{
if(m_bInSquelchMode)
if( m_bInSquelchMode )
return;
m_bInSquelchMode = true;
@ -678,37 +652,35 @@ bool CVoiceStatus::IsInSquelchMode()
return m_bInSquelchMode;
}
CVoiceLabel* CVoiceStatus::FindVoiceLabel(int clientindex)
CVoiceLabel *CVoiceStatus::FindVoiceLabel( int clientindex )
{
for(int i=0; i < MAX_VOICE_SPEAKERS; i++)
for( int i = 0; i < MAX_VOICE_SPEAKERS; i++ )
{
if(m_Labels[i].m_clientindex == clientindex)
if( m_Labels[i].m_clientindex == clientindex )
return &m_Labels[i];
}
return NULL;
}
CVoiceLabel* CVoiceStatus::GetFreeVoiceLabel()
CVoiceLabel *CVoiceStatus::GetFreeVoiceLabel()
{
return FindVoiceLabel(-1);
return FindVoiceLabel( -1 );
}
void CVoiceStatus::RepositionLabels()
{
// find starting position to draw from, along right-hand side of screen
int y = ScreenHeight / 2;
int iconWide = 8, iconTall = 8;
if( m_pSpeakerLabelIcon )
{
m_pSpeakerLabelIcon->getSize( iconWide, iconTall );
}
// Reposition active labels.
for(int i = 0; i < MAX_VOICE_SPEAKERS; i++)
for( int i = 0; i < MAX_VOICE_SPEAKERS; i++ )
{
CVoiceLabel *pLabel = &m_Labels[i];
@ -721,24 +693,25 @@ void CVoiceStatus::RepositionLabels()
}
int textWide, textTall;
pLabel->m_pLabel->getContentSize( textWide, textTall );
// Don't let it stretch too far across their screen.
if( textWide > (ScreenWidth*2)/3 )
textWide = (ScreenWidth*2)/3;
if( textWide > ( ScreenWidth * 2 ) / 3 )
textWide = ( ScreenWidth * 2 ) / 3;
// Setup the background label to fit everything in.
int border = 2;
int bgWide = textWide + iconWide + border*3;
int bgTall = max( textTall, iconTall ) + border*2;
int bgWide = textWide + iconWide + border * 3;
int bgTall = max( textTall, iconTall ) + border * 2;
pLabel->m_pBackground->setBounds( ScreenWidth - bgWide - 8, y, bgWide, bgTall );
// Put the text at the left.
pLabel->m_pLabel->setBounds( border, (bgTall - textTall) / 2, textWide, textTall );
pLabel->m_pLabel->setBounds( border, ( bgTall - textTall ) / 2, textWide, textTall );
// Put the icon at the right.
int iconLeft = border + textWide + border;
int iconTop = (bgTall - iconTall) / 2;
int iconTop = ( bgTall - iconTall ) / 2;
if( pLabel->m_pIcon )
{
pLabel->m_pIcon->setImage( m_pSpeakerLabelIcon );
@ -748,22 +721,23 @@ void CVoiceStatus::RepositionLabels()
y += bgTall + 2;
}
if( m_pLocalBitmap && m_pAckBitmap && m_pLocalLabel && (m_bTalking || m_bServerAcked) )
if( m_pLocalBitmap && m_pAckBitmap && m_pLocalLabel && ( m_bTalking || m_bServerAcked ) )
{
m_pLocalLabel->setParent(*m_pParentPanel);
m_pLocalLabel->setParent( *m_pParentPanel );
m_pLocalLabel->setVisible( true );
if( m_bServerAcked && !!gEngfuncs.pfnGetCvarFloat("voice_clientdebug") )
if( m_bServerAcked && !!gEngfuncs.pfnGetCvarFloat( "voice_clientdebug" ) )
m_pLocalLabel->setImage( m_pAckBitmap );
else
m_pLocalLabel->setImage( m_pLocalBitmap );
int sizeX, sizeY;
m_pLocalBitmap->getSize(sizeX, sizeY);
m_pLocalBitmap->getSize( sizeX, sizeY );
int local_xPos = ScreenWidth - sizeX - 10;
int local_yPos = m_pHelper->GetAckIconHeight() - sizeY;
m_pLocalLabel->setPos( local_xPos, local_yPos );
}
else
@ -772,7 +746,6 @@ void CVoiceStatus::RepositionLabels()
}
}
void CVoiceStatus::FreeBitmaps()
{
// Delete all the images we have loaded.
@ -804,16 +777,16 @@ void CVoiceStatus::FreeBitmaps()
m_pScoreboardBanned = NULL;
// Clear references to the images in panels.
for(int i=0; i < VOICE_MAX_PLAYERS; i++)
for( int i = 0; i < VOICE_MAX_PLAYERS; i++ )
{
if (m_pBanButtons[i])
if( m_pBanButtons[i] )
{
m_pBanButtons[i]->setImage(NULL);
m_pBanButtons[i]->setImage( NULL );
}
}
if(m_pLocalLabel)
m_pLocalLabel->setImage(NULL);
if( m_pLocalLabel )
m_pLocalLabel->setImage( NULL );
}
//-----------------------------------------------------------------------------
@ -821,13 +794,14 @@ void CVoiceStatus::FreeBitmaps()
// Input : playerID -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CVoiceStatus::IsPlayerBlocked(int iPlayer)
bool CVoiceStatus::IsPlayerBlocked( int iPlayer )
{
char playerID[16];
if (!gEngfuncs.GetPlayerUniqueID(iPlayer, playerID))
if( !gEngfuncs.GetPlayerUniqueID( iPlayer, playerID ) )
return false;
return m_BanMgr.GetPlayerBan(playerID);
return m_BanMgr.GetPlayerBan( playerID );
}
//-----------------------------------------------------------------------------
@ -835,9 +809,9 @@ bool CVoiceStatus::IsPlayerBlocked(int iPlayer)
// Input : playerID -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CVoiceStatus::IsPlayerAudible(int iPlayer)
bool CVoiceStatus::IsPlayerAudible( int iPlayer )
{
return !!m_AudiblePlayers[iPlayer-1];
return !!m_AudiblePlayers[iPlayer - 1];
}
//-----------------------------------------------------------------------------
@ -845,30 +819,32 @@ bool CVoiceStatus::IsPlayerAudible(int iPlayer)
// Input : playerID -
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
void CVoiceStatus::SetPlayerBlockedState(int iPlayer, bool blocked)
void CVoiceStatus::SetPlayerBlockedState( int iPlayer, bool blocked )
{
if (gEngfuncs.pfnGetCvarFloat("voice_clientdebug"))
if( gEngfuncs.pfnGetCvarFloat( "voice_clientdebug" ) )
{
gEngfuncs.pfnConsolePrint( "CVoiceStatus::SetPlayerBlockedState part 1\n" );
}
char playerID[16];
if (!gEngfuncs.GetPlayerUniqueID(iPlayer, playerID))
if( !gEngfuncs.GetPlayerUniqueID( iPlayer, playerID ) )
return;
if (gEngfuncs.pfnGetCvarFloat("voice_clientdebug"))
if( gEngfuncs.pfnGetCvarFloat( "voice_clientdebug" ) )
{
gEngfuncs.pfnConsolePrint( "CVoiceStatus::SetPlayerBlockedState part 2\n" );
}
// Squelch or (try to) unsquelch this player.
if (gEngfuncs.pfnGetCvarFloat("voice_clientdebug"))
if( gEngfuncs.pfnGetCvarFloat( "voice_clientdebug" ) )
{
char str[256];
sprintf(str, "CVoiceStatus::SetPlayerBlockedState: setting player %d ban to %d\n", iPlayer, !m_BanMgr.GetPlayerBan(playerID));
gEngfuncs.pfnConsolePrint(str);
sprintf( str, "CVoiceStatus::SetPlayerBlockedState: setting player %d ban to %d\n", iPlayer, !m_BanMgr.GetPlayerBan( playerID ) );
gEngfuncs.pfnConsolePrint( str );
}
m_BanMgr.SetPlayerBan( playerID, blocked );
UpdateServerState(false);
UpdateServerState( false );
}

View File

@ -1,10 +1,9 @@
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ============
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================
#pragma once
#if !defined(VOICE_STATUS_H)
#define VOICE_STATUS_H
@ -20,17 +19,15 @@
#include "vgui_checkbutton2.h"
#include "vgui_defaultinputsignal.h"
class CVoiceStatus;
class CVoiceLabel
{
public:
vgui::Label *m_pLabel;
vgui::Label *m_pBackground;
vgui::Label *m_pLabel;
vgui::Label *m_pBackground;
vgui::ImagePanel *m_pIcon; // Voice icon next to player name.
int m_clientindex; // Client index of the speaker. -1 if this label isn't being used.
int m_clientindex; // Client index of the speaker. -1 if this label isn't being used.
};
@ -38,7 +35,7 @@ public:
class IVoiceStatusHelper
{
public:
virtual ~IVoiceStatusHelper() {}
virtual ~IVoiceStatusHelper() {}
// Get RGB color for voice status text about this player.
virtual void GetPlayerTextColor(int entindex, int color[3]) = 0;
@ -47,7 +44,7 @@ public:
virtual void UpdateCursorState() = 0;
// Return the height above the bottom that the voice ack icons should be drawn at.
virtual int GetAckIconHeight() = 0;
virtual int GetAckIconHeight() = 0;
// Return true if the voice manager is allowed to show speaker labels
// (mods usually return false when the scoreboard is up).
@ -61,164 +58,148 @@ class VoiceImagePanel : public vgui::ImagePanel
{
virtual void paintBackground()
{
if (_image!=null)
if( _image != null )
{
vgui::Color col;
getFgColor(col);
_image->setColor(col);
_image->doPaint(this);
getFgColor( col );
_image->setColor( col );
_image->doPaint( this );
}
}
};
class CVoiceStatus : public CHudBase, public vgui::CDefaultInputSignal
{
public:
CVoiceStatus();
CVoiceStatus();
virtual ~CVoiceStatus();
// CHudBase overrides.
public:
// CHudBase overrides.
// Initialize the cl_dll's voice manager.
virtual int Init(
IVoiceStatusHelper *m_pHelper,
vgui::Panel **pParentPanel);
virtual int Init( IVoiceStatusHelper *m_pHelper, vgui::Panel **pParentPanel );
// ackPosition is the bottom position of where CVoiceStatus will draw the voice acknowledgement labels.
virtual int VidInit();
public:
virtual int VidInit();
// Call from HUD_Frame each frame.
void Frame(double frametime);
void Frame( double frametime );
// Called when a player starts or stops talking.
// entindex is -1 to represent the local client talking (before the data comes back from the server).
// When the server acknowledges that the local client is talking, then entindex will be gEngfuncs.GetLocalPlayer().
// entindex is -2 to represent the local client's voice being acked by the server.
void UpdateSpeakerStatus(int entindex, qboolean bTalking);
void UpdateSpeakerStatus( int entindex, qboolean bTalking );
// sets the correct image in the label for the player
void UpdateSpeakerImage(vgui::Label *pLabel, int iPlayer);
void UpdateSpeakerImage( vgui::Label *pLabel, int iPlayer );
// Call from the HUD_CreateEntities function so it can add sprites above player heads.
void CreateEntities();
void CreateEntities();
// Called when the server registers a change to who this client can hear.
void HandleVoiceMaskMsg(int iSize, void *pbuf);
void HandleVoiceMaskMsg( int iSize, void *pbuf );
// The server sends this message initially to tell the client to send their state.
void HandleReqStateMsg(int iSize, void *pbuf);
void HandleReqStateMsg( int iSize, void *pbuf );
// Squelch mode functions.
public:
// Squelch mode functions.
// When you enter squelch mode, pass in
void StartSquelchMode();
void StopSquelchMode();
bool IsInSquelchMode();
void StartSquelchMode();
void StopSquelchMode();
bool IsInSquelchMode();
// returns true if the target client has been banned
// playerIndex is of range 1..maxplayers
bool IsPlayerBlocked(int iPlayerIndex);
bool IsPlayerBlocked( int iPlayerIndex );
// returns false if the player can't hear the other client due to game rules (eg. the other team)
bool IsPlayerAudible(int iPlayerIndex);
bool IsPlayerAudible( int iPlayerIndex );
// blocks the target client from being heard
void SetPlayerBlockedState(int iPlayerIndex, bool blocked);
void SetPlayerBlockedState( int iPlayerIndex, bool blocked );
public:
CVoiceLabel* FindVoiceLabel(int clientindex); // Find a CVoiceLabel representing the specified speaker.
CVoiceLabel *FindVoiceLabel( int clientindex ); // Find a CVoiceLabel representing the specified speaker.
// Returns NULL if none.
// entindex can be -1 if you want a currently-unused voice label.
CVoiceLabel* GetFreeVoiceLabel(); // Get an unused voice label. Returns NULL if none.
CVoiceLabel *GetFreeVoiceLabel(); // Get an unused voice label. Returns NULL if none.
void RepositionLabels();
void FreeBitmaps();
void UpdateServerState(bool bForce);
void UpdateServerState( bool bForce );
// Update the button artwork to reflect the client's current state.
void UpdateBanButton(int iClient);
void UpdateBanButton( int iClient );
enum
{
MAX_VOICE_SPEAKERS = 7
};
public:
float m_LastUpdateServerState; // Last time we called this function.
int m_bServerModEnable; // What we've sent to the server about our "voice_modenable" cvar.
enum {MAX_VOICE_SPEAKERS=7};
float m_LastUpdateServerState; // Last time we called this function.
int m_bServerModEnable; // What we've sent to the server about our "voice_modenable" cvar.
vgui::Panel **m_pParentPanel;
CPlayerBitVec m_VoicePlayers; // Who is currently talking. Indexed by client index.
vgui::Panel **m_pParentPanel;
CPlayerBitVec m_VoicePlayers; // Who is currently talking. Indexed by client index.
// This is the gamerules-defined list of players that you can hear. It is based on what teams people are on
// and is totally separate from the ban list. Indexed by client index.
CPlayerBitVec m_AudiblePlayers;
CPlayerBitVec m_AudiblePlayers;
// Players who have spoken at least once in the game so far
CPlayerBitVec m_VoiceEnabledPlayers;
CPlayerBitVec m_VoiceEnabledPlayers;
// This is who the server THINKS we have banned (it can become incorrect when a new player arrives on the server).
// It is checked periodically, and the server is told to squelch or unsquelch the appropriate players.
CPlayerBitVec m_ServerBannedPlayers;
CPlayerBitVec m_ServerBannedPlayers;
cl_entity_s m_VoiceHeadModels[VOICE_MAX_PLAYERS]; // These aren't necessarily in the order of players. They are just
// a place for it to put data in during CreateEntities.
cl_entity_s m_VoiceHeadModels[VOICE_MAX_PLAYERS]; // These aren't necessarily in the order of players. They are just
// a place for it to put data in during CreateEntities.
IVoiceStatusHelper *m_pHelper; // Each mod provides an implementation of this.
IVoiceStatusHelper *m_pHelper; // Each mod provides an implementation of this.
// Scoreboard icons.
double m_BlinkTimer; // Blink scoreboard icons..
vgui::BitmapTGA *m_pScoreboardNeverSpoken;
vgui::BitmapTGA *m_pScoreboardNotSpeaking;
vgui::BitmapTGA *m_pScoreboardSpeaking;
vgui::BitmapTGA *m_pScoreboardSpeaking2;
vgui::BitmapTGA *m_pScoreboardSquelch;
vgui::BitmapTGA *m_pScoreboardBanned;
vgui::Label *m_pBanButtons[VOICE_MAX_PLAYERS]; // scoreboard buttons.
double m_BlinkTimer; // Blink scoreboard icons..
vgui::BitmapTGA *m_pScoreboardNeverSpoken;
vgui::BitmapTGA *m_pScoreboardNotSpeaking;
vgui::BitmapTGA *m_pScoreboardSpeaking;
vgui::BitmapTGA *m_pScoreboardSpeaking2;
vgui::BitmapTGA *m_pScoreboardSquelch;
vgui::BitmapTGA *m_pScoreboardBanned;
vgui::Label *m_pBanButtons[VOICE_MAX_PLAYERS]; // scoreboard buttons.
// Squelch mode stuff.
bool m_bInSquelchMode;
HSPRITE m_VoiceHeadModel; // Voice head model (goes above players who are speaking).
float m_VoiceHeadModelHeight; // Height above their head to place the model.
bool m_bInSquelchMode;
vgui::Image *m_pSpeakerLabelIcon; // Icon next to speaker labels.
HSPRITE m_VoiceHeadModel; // Voice head model (goes above players who are speaking).
float m_VoiceHeadModelHeight; // Height above their head to place the model.
vgui::Image *m_pSpeakerLabelIcon; // Icon next to speaker labels.
// Lower-right icons telling when the local player is talking..
vgui::BitmapTGA *m_pLocalBitmap; // Represents the local client talking.
vgui::BitmapTGA *m_pAckBitmap; // Represents the server ack'ing the client talking.
vgui::ImagePanel *m_pLocalLabel; // Represents the local client talking.
vgui::BitmapTGA *m_pLocalBitmap; // Represents the local client talking.
vgui::BitmapTGA *m_pAckBitmap; // Represents the server ack'ing the client talking.
vgui::ImagePanel *m_pLocalLabel; // Represents the local client talking.
bool m_bTalking; // Set to true when the client thinks it's talking.
bool m_bServerAcked; // Set to true when the server knows the client is talking.
bool m_bTalking; // Set to true when the client thinks it's talking.
bool m_bServerAcked; // Set to true when the server knows the client is talking.
public:
CVoiceBanMgr m_BanMgr; // Tracks which users we have squelched and don't want to hear.
CVoiceBanMgr m_BanMgr; // Tracks which users we have squelched and don't want to hear.
public:
bool m_bBanMgrInitialized;
bool m_bBanMgrInitialized;
// Labels telling who is speaking.
CVoiceLabel m_Labels[MAX_VOICE_SPEAKERS];
CVoiceLabel m_Labels[MAX_VOICE_SPEAKERS];
// Cache the game directory for use when we shut down
char * m_pchGameDir;
char *m_pchGameDir;
};
// Get the (global) voice manager.
// Get the (global) voice manager.
CVoiceStatus* GetClientVoiceMgr();
#endif // VOICE_STATUS_H

View File

@ -9,7 +9,6 @@
#include "../cl_dll/cl_util.h"
#include "../cl_dll/vgui_teamfortressviewport.h"
#include "vgui_actionsignal.h"
#include "voice_vgui_tweakdlg.h"
#include "voice_vgui_tweakdlg.h"
@ -21,20 +20,18 @@
#include "vgui_checkbutton2.h"
#include "vgui_helpers.h"
#define ITEM_BORDER 40 // Border between text and scrollbars on left and right.
#define ITEM_BORDER 40 // Border between text and scrollbars on left and right.
#define VOICETWEAK_TRANSPARENCY 150
class TweakScroller
{
public:
TweakScroller();
void Init(Panel *pParent, char *pText, int yPos);
TweakScroller();
void Init( Panel *pParent, char *pText, int yPos );
// Get/set value. Values are 0-1.
float GetValue();
void SetValue(float val);
void SetValue( float val );
public:
Label m_Label;
@ -46,48 +43,36 @@ public:
class CVoiceVGUITweakDlg : public CMenuPanel, public ICheckButton2Handler
{
typedef CMenuPanel BaseClass;
public:
CVoiceVGUITweakDlg();
~CVoiceVGUITweakDlg();
CVoiceVGUITweakDlg();
~CVoiceVGUITweakDlg();
// CMenuPanel overrides.
public:
// CMenuPanel overrides.
virtual void Open();
virtual void Close();
// ICheckButton2Handler overrides.
public:
// ICheckButton2Handler overrides.
virtual void StateChanged(CCheckButton2 *pButton);
// Panel overrides.
public:
// Panel overrides.
virtual void paintBackground();
private:
int m_DlgWidth;
int m_DlgHeight;
int m_DlgWidth;
int m_DlgHeight;
Label m_Label;
Label m_Label;
IVoiceTweak *m_pVoiceTweak; // Engine voice tweak API.
IVoiceTweak *m_pVoiceTweak; // Engine voice tweak API.
TweakScroller m_MicVolume;
TweakScroller m_SpeakerVolume;
TweakScroller m_MicVolume;
TweakScroller m_SpeakerVolume;
CCheckButton2 m_VoiceModEnable;
Button m_Button_OK;
CCheckButton2 m_VoiceModEnable;
Button m_Button_OK;
};
bool g_bTweakDlgOpen = false;
bool IsTweakDlgOpen()
@ -95,107 +80,97 @@ bool IsTweakDlgOpen()
return g_bTweakDlgOpen;
}
// ------------------------------------------------------------------------ //
// Global functions.
// ------------------------------------------------------------------------ //
static CVoiceVGUITweakDlg g_VoiceTweakDlg;
CMenuPanel* GetVoiceTweakDlg()
CMenuPanel *GetVoiceTweakDlg()
{
return &g_VoiceTweakDlg;
}
class CVoiceTweakOKButton : public ActionSignal
{
public:
virtual void actionPerformed(Panel *pPanel)
virtual void actionPerformed( Panel *pPanel )
{
gViewPort->HideVGUIMenu();
}
};
CVoiceTweakOKButton g_OKButtonSignal;
// ------------------------------------------------------------------------ //
// TweakScroller
// ------------------------------------------------------------------------ //
TweakScroller::TweakScroller() :
m_Label(""),
m_Scroll(0,0,0,0,false),
m_Slider(0,0,10,10,false)
m_Label( "" ),
m_Scroll( 0, 0, 0, 0, false ),
m_Slider( 0, 0, 10, 10, false )
{
}
void TweakScroller::Init(Panel *pParent, char *pText, int yPos)
void TweakScroller::Init( Panel *pParent, char *pText, int yPos )
{
int parentWidth, parentHeight;
pParent->getSize(parentWidth, parentHeight);
pParent->getSize( parentWidth, parentHeight );
// Setup the volume scroll bar.
m_Label.setParent(pParent);
m_Label.setFont(Scheme::sf_primary1);
m_Label.setContentAlignment(vgui::Label::a_northwest);
m_Label.setBgColor(0, 0, 0, 255);
m_Label.setFgColor(255,255,255,0);
m_Label.setPos(ITEM_BORDER, yPos);
m_Label.setSize(parentWidth/2-ITEM_BORDER, 20);
m_Label.setText(pText);
m_Label.setVisible(true);
m_Label.setParent( pParent );
m_Label.setFont( Scheme::sf_primary1 );
m_Label.setContentAlignment( vgui::Label::a_northwest );
m_Label.setBgColor( 0, 0, 0, 255 );
m_Label.setFgColor( 255, 255, 255, 0 );
m_Label.setPos( ITEM_BORDER, yPos );
m_Label.setSize( parentWidth / 2 - ITEM_BORDER, 20 );
m_Label.setText( pText );
m_Label.setVisible( true );
m_Slider.setRangeWindow(10);
m_Slider.setRangeWindowEnabled(true);
m_Scroll.setPos(parentWidth/2+ITEM_BORDER, yPos);
m_Scroll.setSize(parentWidth/2-ITEM_BORDER*2, 20);
m_Scroll.setSlider(&m_Slider);
m_Scroll.setParent(pParent);
m_Scroll.setRange(0, 100);
m_Scroll.setFgColor(255,255,255,0);
m_Scroll.setBgColor(255,255,255,0);
m_Slider.setRangeWindow( 10 );
m_Slider.setRangeWindowEnabled( true );
m_Scroll.setPos( parentWidth / 2 + ITEM_BORDER, yPos );
m_Scroll.setSize( parentWidth / 2 - ITEM_BORDER * 2, 20 );
m_Scroll.setSlider( &m_Slider );
m_Scroll.setParent( pParent );
m_Scroll.setRange( 0, 100 );
m_Scroll.setFgColor( 255, 255, 255, 0 );
m_Scroll.setBgColor( 255, 255, 255, 0 );
}
float TweakScroller::GetValue()
{
return m_Scroll.getValue() / 100.0f;
}
void TweakScroller::SetValue(float val)
void TweakScroller::SetValue( float val )
{
m_Scroll.setValue((int)(val * 100.0f));
m_Scroll.setValue( (int)( val * 100.0f ) );
}
// ------------------------------------------------------------------------ //
// CVoiceVGUITweakDlg implementation.
// ------------------------------------------------------------------------ //
CVoiceVGUITweakDlg::CVoiceVGUITweakDlg()
: CMenuPanel(VOICETWEAK_TRANSPARENCY, false, 0, 0, 0, 0),
m_Button_OK("",0,0),
m_Label("")
: CMenuPanel( VOICETWEAK_TRANSPARENCY, false, 0, 0, 0, 0 ),
m_Button_OK( "", 0, 0 ),
m_Label( "" )
{
m_pVoiceTweak = NULL;
m_Button_OK.addActionSignal(&g_OKButtonSignal);
m_Label.setBgColor(255,255,255,200);
m_Button_OK.addActionSignal( &g_OKButtonSignal );
m_Label.setBgColor( 255, 255, 255, 200 );
}
CVoiceVGUITweakDlg::~CVoiceVGUITweakDlg()
{
}
void CVoiceVGUITweakDlg::Open()
{
if(g_bTweakDlgOpen)
if( g_bTweakDlgOpen )
return;
g_bTweakDlgOpen = true;
@ -209,46 +184,48 @@ void CVoiceVGUITweakDlg::Open()
m_pVoiceTweak->StartVoiceTweakMode();
// Set our size.
setPos((ScreenWidth - m_DlgWidth) / 2, (ScreenHeight - m_DlgHeight) / 2);
setSize(m_DlgWidth, m_DlgHeight);
setPos( ( ScreenWidth - m_DlgWidth ) / 2, ( ScreenHeight - m_DlgHeight ) / 2 );
setSize( m_DlgWidth, m_DlgHeight );
int curY = ITEM_BORDER;
m_MicVolume.Init(this, gHUD.m_TextMessage.BufferedLocaliseTextString("#Mic_Volume"), curY);
m_MicVolume.SetValue(m_pVoiceTweak->GetControlFloat(MicrophoneVolume));
curY = PanelBottom(&m_MicVolume.m_Label);
m_MicVolume.Init( this, gHUD.m_TextMessage.BufferedLocaliseTextString( "#Mic_Volume" ), curY );
m_MicVolume.SetValue( m_pVoiceTweak->GetControlFloat( MicrophoneVolume ) );
curY = PanelBottom( &m_MicVolume.m_Label );
m_SpeakerVolume.Init(this, gHUD.m_TextMessage.BufferedLocaliseTextString("#Speaker_Volume"), curY);
m_SpeakerVolume.SetValue(m_pVoiceTweak->GetControlFloat(OtherSpeakerScale));
curY = PanelBottom(&m_SpeakerVolume.m_Label);
m_SpeakerVolume.Init( this, gHUD.m_TextMessage.BufferedLocaliseTextString( "#Speaker_Volume" ), curY );
m_SpeakerVolume.SetValue( m_pVoiceTweak->GetControlFloat( OtherSpeakerScale ) );
curY = PanelBottom( &m_SpeakerVolume.m_Label );
m_VoiceModEnable.setParent(this);
m_VoiceModEnable.SetImages("gfx/vgui/checked.tga", "gfx/vgui/unchecked.tga");
m_VoiceModEnable.SetText("Enable Voice In This Mod");
m_VoiceModEnable.setPos(ITEM_BORDER, curY);
m_VoiceModEnable.SetCheckboxLeft(false);
m_VoiceModEnable.SetChecked(!!gEngfuncs.pfnGetCvarFloat("voice_modenable"));
m_VoiceModEnable.SetHandler(this);
m_VoiceModEnable.setParent( this );
m_VoiceModEnable.SetImages( "gfx/vgui/checked.tga", "gfx/vgui/unchecked.tga" );
m_VoiceModEnable.SetText( "Enable Voice In This Mod" );
m_VoiceModEnable.setPos( ITEM_BORDER, curY );
m_VoiceModEnable.SetCheckboxLeft( false );
m_VoiceModEnable.SetChecked( !!gEngfuncs.pfnGetCvarFloat( "voice_modenable" ) );
m_VoiceModEnable.SetHandler( this );
// Setup the OK button.
int buttonWidth, buttonHeight;
m_Button_OK.setText(gHUD.m_TextMessage.BufferedLocaliseTextString("#Menu_OK"));
m_Button_OK.getSize(buttonWidth, buttonHeight);
m_Button_OK.setPos((m_DlgWidth - buttonWidth) / 2, m_DlgHeight - buttonHeight - 3);
m_Button_OK.setParent(this);
m_Button_OK.setText( gHUD.m_TextMessage.BufferedLocaliseTextString( "#Menu_OK" ) );
m_Button_OK.getSize( buttonWidth, buttonHeight );
m_Button_OK.setPos(( m_DlgWidth - buttonWidth ) / 2, m_DlgHeight - buttonHeight - 3 );
m_Button_OK.setParent( this );
// Put the label on the top.
m_Label.setBgColor(0, 0, 0, 255);
m_Label.setFgColor(255,255,255,0);
m_Label.setText(gHUD.m_TextMessage.BufferedLocaliseTextString("#Voice_Properties"));
m_Label.setBgColor( 0, 0, 0, 255 );
m_Label.setFgColor( 255, 255, 255, 0 );
m_Label.setText( gHUD.m_TextMessage.BufferedLocaliseTextString( "#Voice_Properties" ) );
int labelWidth, labelHeight;
m_Label.getSize(labelWidth, labelHeight);
m_Label.setPos((m_DlgWidth - labelWidth) / 2, 5);
m_Label.setParent(this);
m_Label.getSize( labelWidth, labelHeight );
m_Label.setPos( ( m_DlgWidth - labelWidth ) / 2, 5 );
m_Label.setParent( this );
BaseClass::Open();
}
void CVoiceVGUITweakDlg::Close()
{
m_pVoiceTweak->EndVoiceTweakMode();
@ -257,33 +234,33 @@ void CVoiceVGUITweakDlg::Close()
BaseClass::Close();
}
void CVoiceVGUITweakDlg::paintBackground()
{
BaseClass::paintBackground();
// Draw our border.
int w,h;
getSize(w,h);
int w, h;
drawSetColor(128,128,128,1);
drawOutlinedRect(0, 0, w, h);
getSize( w, h );
drawSetColor( 128, 128, 128, 1 );
drawOutlinedRect( 0, 0, w, h );
float volume = m_MicVolume.GetValue();
m_pVoiceTweak->SetControlFloat(MicrophoneVolume, volume);
m_pVoiceTweak->SetControlFloat( MicrophoneVolume, volume );
m_pVoiceTweak->SetControlFloat(OtherSpeakerScale, m_SpeakerVolume.GetValue());
m_pVoiceTweak->SetControlFloat( OtherSpeakerScale, m_SpeakerVolume.GetValue() );
}
void CVoiceVGUITweakDlg::StateChanged(CCheckButton2 *pButton)
void CVoiceVGUITweakDlg::StateChanged( CCheckButton2 *pButton )
{
if(pButton == &m_VoiceModEnable)
if( pButton == &m_VoiceModEnable )
{
if(pButton->IsChecked())
gEngfuncs.pfnClientCmd("voice_modenable 1");
if( pButton->IsChecked() )
gEngfuncs.pfnClientCmd( "voice_modenable 1" );
else
gEngfuncs.pfnClientCmd("voice_modenable 0");
gEngfuncs.pfnClientCmd( "voice_modenable 0" );
}
}

View File

@ -5,17 +5,16 @@
// $NoKeywords: $
//=============================================================================
#pragma once
#if !defined(VOICE_VGUI_TWEAKDLG_H)
#ifndef VOICE_VGUI_TWEAKDLG_H
#define VOICE_VGUI_TWEAKDLG_H
class CMenuPanel;
// Returns true if the tweak dialog is currently up.
bool IsTweakDlgOpen();
// Returns a global instance of the tweak dialog.
CMenuPanel* GetVoiceTweakDlg();
CMenuPanel *GetVoiceTweakDlg();
#endif // VOICE_VGUI_TWEAKDLG_H

1
vgui-dev Submodule

@ -0,0 +1 @@
Subproject commit 93573075afe885618ea15831e72d44bdacd65bfb