Moved modified HL SDK to trunk
This commit is contained in:
181
hlsdk/game_shared/bitvec.h
Normal file
181
hlsdk/game_shared/bitvec.h
Normal file
@ -0,0 +1,181 @@
|
||||
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef BITVEC_H
|
||||
#define BITVEC_H
|
||||
#ifdef _WIN32
|
||||
#ifndef __MINGW32__
|
||||
#pragma once
|
||||
#endif /* not __MINGW32__ */
|
||||
#endif
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
class CBitVecAccessor
|
||||
{
|
||||
public:
|
||||
CBitVecAccessor(unsigned long *pDWords, int iBit);
|
||||
|
||||
void operator=(int val);
|
||||
operator unsigned long();
|
||||
|
||||
private:
|
||||
unsigned long *m_pDWords;
|
||||
int m_iBit;
|
||||
};
|
||||
|
||||
|
||||
// CBitVec allows you to store a list of bits and do operations on them like they were
|
||||
// an atomic type.
|
||||
template<int NUM_BITS>
|
||||
class CBitVec
|
||||
{
|
||||
public:
|
||||
|
||||
CBitVec();
|
||||
|
||||
// Set all values to the specified value (0 or 1..)
|
||||
void Init(int val = 0);
|
||||
|
||||
// Access the bits like an array.
|
||||
CBitVecAccessor operator[](int i);
|
||||
|
||||
// Operations on other bit vectors.
|
||||
CBitVec& operator=(CBitVec<NUM_BITS> const &other);
|
||||
bool operator==(CBitVec<NUM_BITS> const &other);
|
||||
bool operator!=(CBitVec<NUM_BITS> const &other);
|
||||
|
||||
// Get underlying dword representations of the bits.
|
||||
int GetNumDWords();
|
||||
unsigned long GetDWord(int i);
|
||||
void SetDWord(int i, unsigned long val);
|
||||
|
||||
int GetNumBits();
|
||||
|
||||
private:
|
||||
|
||||
enum {NUM_DWORDS = NUM_BITS/32 + !!(NUM_BITS & 31)};
|
||||
unsigned long m_DWords[NUM_DWORDS];
|
||||
};
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------ //
|
||||
// CBitVecAccessor inlines.
|
||||
// ------------------------------------------------------------------------ //
|
||||
|
||||
inline CBitVecAccessor::CBitVecAccessor(unsigned long *pDWords, int iBit)
|
||||
{
|
||||
m_pDWords = pDWords;
|
||||
m_iBit = iBit;
|
||||
}
|
||||
|
||||
|
||||
inline void CBitVecAccessor::operator=(int val)
|
||||
{
|
||||
if(val)
|
||||
m_pDWords[m_iBit >> 5] |= (1 << (m_iBit & 31));
|
||||
else
|
||||
m_pDWords[m_iBit >> 5] &= ~(unsigned long)(1 << (m_iBit & 31));
|
||||
}
|
||||
|
||||
inline CBitVecAccessor::operator unsigned long()
|
||||
{
|
||||
return m_pDWords[m_iBit >> 5] & (1 << (m_iBit & 31));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------ //
|
||||
// CBitVec inlines.
|
||||
// ------------------------------------------------------------------------ //
|
||||
|
||||
template<int NUM_BITS>
|
||||
inline int CBitVec<NUM_BITS>::GetNumBits()
|
||||
{
|
||||
return NUM_BITS;
|
||||
}
|
||||
|
||||
|
||||
template<int NUM_BITS>
|
||||
inline CBitVec<NUM_BITS>::CBitVec()
|
||||
{
|
||||
for(int i=0; i < NUM_DWORDS; i++)
|
||||
m_DWords[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
template<int NUM_BITS>
|
||||
inline void CBitVec<NUM_BITS>::Init(int val)
|
||||
{
|
||||
for(int i=0; i < GetNumBits(); i++)
|
||||
{
|
||||
(*this)[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<int NUM_BITS>
|
||||
inline CBitVec<NUM_BITS>& CBitVec<NUM_BITS>::operator=(CBitVec<NUM_BITS> const &other)
|
||||
{
|
||||
memcpy(m_DWords, other.m_DWords, sizeof(m_DWords));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template<int NUM_BITS>
|
||||
inline CBitVecAccessor CBitVec<NUM_BITS>::operator[](int i)
|
||||
{
|
||||
assert(i >= 0 && i < GetNumBits());
|
||||
return CBitVecAccessor(m_DWords, i);
|
||||
}
|
||||
|
||||
|
||||
template<int NUM_BITS>
|
||||
inline bool CBitVec<NUM_BITS>::operator==(CBitVec<NUM_BITS> const &other)
|
||||
{
|
||||
for(int i=0; i < NUM_DWORDS; i++)
|
||||
if(m_DWords[i] != other.m_DWords[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<int NUM_BITS>
|
||||
inline bool CBitVec<NUM_BITS>::operator!=(CBitVec<NUM_BITS> const &other)
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
|
||||
template<int NUM_BITS>
|
||||
inline int CBitVec<NUM_BITS>::GetNumDWords()
|
||||
{
|
||||
return NUM_DWORDS;
|
||||
}
|
||||
|
||||
template<int NUM_BITS>
|
||||
inline unsigned long CBitVec<NUM_BITS>::GetDWord(int i)
|
||||
{
|
||||
assert(i >= 0 && i < NUM_DWORDS);
|
||||
return m_DWords[i];
|
||||
}
|
||||
|
||||
|
||||
template<int NUM_BITS>
|
||||
inline void CBitVec<NUM_BITS>::SetDWord(int i, unsigned long val)
|
||||
{
|
||||
assert(i >= 0 && i < NUM_DWORDS);
|
||||
m_DWords[i] = val;
|
||||
}
|
||||
|
||||
|
||||
#endif // BITVEC_H
|
||||
|
197
hlsdk/game_shared/vgui_checkbutton2.cpp
Normal file
197
hlsdk/game_shared/vgui_checkbutton2.cpp
Normal file
@ -0,0 +1,197 @@
|
||||
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#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_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_CheckboxPanel.setParent(this);
|
||||
m_CheckboxPanel.addInputSignal(this);
|
||||
|
||||
setPaintBackgroundEnabled(false);
|
||||
}
|
||||
|
||||
|
||||
CCheckButton2::~CCheckButton2()
|
||||
{
|
||||
DeleteImages();
|
||||
}
|
||||
|
||||
|
||||
void CCheckButton2::SetImages(char const *pChecked, char const *pUnchecked)
|
||||
{
|
||||
DeleteImages();
|
||||
|
||||
m_pChecked = vgui_LoadTGA(pChecked);
|
||||
m_pUnchecked = vgui_LoadTGA(pUnchecked);
|
||||
m_bOwnImages = true;
|
||||
|
||||
SetupControls();
|
||||
}
|
||||
|
||||
|
||||
void CCheckButton2::SetImages(Image *pChecked, Image *pUnchecked)
|
||||
{
|
||||
DeleteImages();
|
||||
|
||||
m_pChecked = pChecked;
|
||||
m_pUnchecked = pUnchecked;
|
||||
m_bOwnImages = false;
|
||||
|
||||
SetupControls();
|
||||
}
|
||||
|
||||
|
||||
void CCheckButton2::DeleteImages()
|
||||
{
|
||||
if(m_bOwnImages)
|
||||
{
|
||||
delete m_pChecked;
|
||||
delete m_pUnchecked;
|
||||
}
|
||||
|
||||
m_pChecked = NULL;
|
||||
m_pUnchecked = NULL;
|
||||
m_bOwnImages = false;
|
||||
|
||||
SetupControls();
|
||||
}
|
||||
|
||||
|
||||
void CCheckButton2::SetCheckboxLeft(bool bLeftAlign)
|
||||
{
|
||||
m_bCheckboxLeft = bLeftAlign;
|
||||
SetupControls();
|
||||
}
|
||||
|
||||
|
||||
bool CCheckButton2::GetCheckboxLeft()
|
||||
{
|
||||
return m_bCheckboxLeft;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
SetupControls();
|
||||
}
|
||||
|
||||
|
||||
void CCheckButton2::SetTextColor(int r, int g, int b, int a)
|
||||
{
|
||||
m_Label.setFgColor(r, g, b, a);
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
||||
void CCheckButton2::SetHandler(ICheckButton2Handler *pHandler)
|
||||
{
|
||||
m_pHandler = pHandler;
|
||||
}
|
||||
|
||||
|
||||
bool CCheckButton2::IsChecked()
|
||||
{
|
||||
return m_bChecked;
|
||||
}
|
||||
|
||||
|
||||
void CCheckButton2::SetChecked(bool bChecked)
|
||||
{
|
||||
m_bChecked = bChecked;
|
||||
SetupControls();
|
||||
}
|
||||
|
||||
|
||||
void CCheckButton2::internalMousePressed(MouseCode code)
|
||||
{
|
||||
m_bChecked = !m_bChecked;
|
||||
|
||||
if(m_pHandler)
|
||||
m_pHandler->StateChanged(this);
|
||||
|
||||
SetupControls();
|
||||
}
|
||||
|
||||
|
||||
void CCheckButton2::SetupControls()
|
||||
{
|
||||
// Initialize the checkbutton bitmap.
|
||||
Image *pBitmap = m_bChecked ? m_pChecked : m_pUnchecked;
|
||||
|
||||
Panel *controls[2] = {&m_CheckboxPanel, &m_Label};
|
||||
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]);
|
||||
|
||||
|
||||
// Get the label's size.
|
||||
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);
|
||||
|
||||
|
||||
// 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]);
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
||||
void CCheckButton2::mousePressed(MouseCode code, Panel *panel)
|
||||
{
|
||||
internalMousePressed(code);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
103
hlsdk/game_shared/vgui_checkbutton2.h
Normal file
103
hlsdk/game_shared/vgui_checkbutton2.h
Normal file
@ -0,0 +1,103 @@
|
||||
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef VGUI_CHECKBUTTON2_H
|
||||
#define VGUI_CHECKBUTTON2_H
|
||||
#ifdef _WIN32
|
||||
#ifndef __MINGW32__
|
||||
#pragma once
|
||||
#endif /* not __MINGW32__ */
|
||||
#endif
|
||||
|
||||
|
||||
#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;
|
||||
};
|
||||
|
||||
|
||||
// VGUI checkbox class.
|
||||
// - Provides access to the checkbox images.
|
||||
// - Provides an easy callback mechanism for state changes.
|
||||
// - Default background is invisible, and default text color is white.
|
||||
class CCheckButton2 : public Panel, public CDefaultInputSignal
|
||||
{
|
||||
public:
|
||||
|
||||
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 DeleteImages();
|
||||
|
||||
// The checkbox can be to the left or the right of the text (default is left).
|
||||
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);
|
||||
|
||||
// You can register for change notification here.
|
||||
void SetHandler(ICheckButton2Handler *pHandler);
|
||||
|
||||
// Get/set the check state.
|
||||
bool IsChecked();
|
||||
void SetChecked(bool bChecked);
|
||||
|
||||
|
||||
|
||||
// Panel overrides.
|
||||
public:
|
||||
|
||||
virtual void internalMousePressed(MouseCode code);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
void SetupControls();
|
||||
|
||||
|
||||
// InputSignal overrides.
|
||||
protected:
|
||||
virtual void mousePressed(MouseCode code,Panel* panel);
|
||||
|
||||
|
||||
public:
|
||||
ICheckButton2Handler *m_pHandler;
|
||||
|
||||
bool m_bCheckboxLeft;
|
||||
Label m_Label;
|
||||
ImagePanel m_CheckboxPanel;
|
||||
|
||||
Image *m_pChecked;
|
||||
Image *m_pUnchecked;
|
||||
bool m_bOwnImages;
|
||||
|
||||
bool m_bChecked;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // VGUI_CHECKBUTTON2_H
|
41
hlsdk/game_shared/vgui_defaultinputsignal.h
Normal file
41
hlsdk/game_shared/vgui_defaultinputsignal.h
Normal file
@ -0,0 +1,41 @@
|
||||
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef VGUI_DEFAULTINPUTSIGNAL_H
|
||||
#define VGUI_DEFAULTINPUTSIGNAL_H
|
||||
#ifdef _WIN32
|
||||
#ifndef __MINGW32__
|
||||
#pragma once
|
||||
#endif /* not __MINGW32__ */
|
||||
#endif
|
||||
|
||||
|
||||
#include "vgui_inputsignal.h"
|
||||
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
// This class derives from vgui::InputSignal and implements empty defaults for all of its functions.
|
||||
class CDefaultInputSignal : public vgui::InputSignal
|
||||
{
|
||||
public:
|
||||
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) {}
|
||||
virtual void mouseReleased(MouseCode code,Panel* panel) {}
|
||||
virtual void mouseWheeled(int delta,Panel* panel) {}
|
||||
virtual void keyPressed(KeyCode code,Panel* panel) {}
|
||||
virtual void keyTyped(KeyCode code,Panel* panel) {}
|
||||
virtual void keyReleased(KeyCode code,Panel* panel) {}
|
||||
virtual void keyFocusTicked(Panel* panel) {}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif // VGUI_DEFAULTINPUTSIGNAL_H
|
398
hlsdk/game_shared/vgui_grid.cpp
Normal file
398
hlsdk/game_shared/vgui_grid.cpp
Normal file
@ -0,0 +1,398 @@
|
||||
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include <assert.h>
|
||||
#include "vgui_grid.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
#define AssertCheck(expr, msg) \
|
||||
if(!(expr))\
|
||||
{\
|
||||
assert(!msg);\
|
||||
return 0;\
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------ //
|
||||
// CGrid::CGridEntry.
|
||||
// ------------------------------------------------------------------------------ //
|
||||
|
||||
CGrid::CGridEntry::CGridEntry()
|
||||
{
|
||||
m_pPanel = NULL;
|
||||
m_bUnderline = false;
|
||||
}
|
||||
|
||||
CGrid::CGridEntry::~CGridEntry()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------ //
|
||||
// CGrid.
|
||||
// ------------------------------------------------------------------------------ //
|
||||
|
||||
CGrid::CGrid()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
|
||||
CGrid::~CGrid()
|
||||
{
|
||||
Term();
|
||||
}
|
||||
|
||||
|
||||
bool CGrid::SetDimensions(int xCols, int yRows)
|
||||
{
|
||||
Term();
|
||||
|
||||
m_GridEntries = new CGridEntry[xCols * yRows];
|
||||
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)
|
||||
{
|
||||
Term();
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(m_Widths, 0, sizeof(int) * (xCols*2 + yRows*2));
|
||||
|
||||
m_xCols = xCols;
|
||||
m_yRows = yRows;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CGrid::Term()
|
||||
{
|
||||
delete [] m_GridEntries;
|
||||
delete [] m_Widths;
|
||||
Clear();
|
||||
}
|
||||
|
||||
|
||||
Panel* CGrid::GetEntry(int x, int y)
|
||||
{
|
||||
return GridEntry(x, y)->m_pPanel;
|
||||
}
|
||||
|
||||
|
||||
bool CGrid::SetEntry(int x, int y, Panel *pPanel)
|
||||
{
|
||||
CGridEntry *pEntry = GridEntry(x, y);
|
||||
if(!pEntry)
|
||||
return false;
|
||||
|
||||
if(pEntry->m_pPanel)
|
||||
pEntry->m_pPanel->setParent(NULL);
|
||||
|
||||
pEntry->m_pPanel = pPanel;
|
||||
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)
|
||||
{
|
||||
if(xSpacing != m_xSpacing)
|
||||
{
|
||||
m_xSpacing = xSpacing;
|
||||
CalcColOffsets(0);
|
||||
m_bDirty = true;
|
||||
}
|
||||
|
||||
if(ySpacing != m_ySpacing)
|
||||
{
|
||||
m_ySpacing = ySpacing;
|
||||
CalcRowOffsets(0);
|
||||
m_bDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CGrid::SetColumnWidth(int iColumn, int width)
|
||||
{
|
||||
AssertCheck(iColumn >= 0 && iColumn < m_xCols, "CGrid::SetColumnWidth : invalid location specified");
|
||||
m_Widths[iColumn] = width;
|
||||
CalcColOffsets(iColumn+1);
|
||||
m_bDirty = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CGrid::SetRowHeight(int iRow, int height)
|
||||
{
|
||||
AssertCheck(iRow >= 0 && iRow < m_yRows, "CGrid::SetColumnWidth : invalid location specified");
|
||||
m_Heights[iRow] = height;
|
||||
CalcRowOffsets(iRow+1);
|
||||
m_bDirty = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int CGrid::GetColumnWidth(int iColumn)
|
||||
{
|
||||
AssertCheck(iColumn >= 0 && iColumn < m_xCols, "CGrid::GetColumnWidth: invalid location specified");
|
||||
return m_Widths[iColumn];
|
||||
}
|
||||
|
||||
|
||||
int CGrid::GetRowHeight(int iRow)
|
||||
{
|
||||
AssertCheck(iRow >= 0 && iRow < m_yRows, "CGrid::GetRowHeight: invalid location specified");
|
||||
return m_Heights[iRow];
|
||||
}
|
||||
|
||||
|
||||
int CGrid::CalcFitColumnWidth(int iColumn)
|
||||
{
|
||||
AssertCheck(iColumn >= 0 && iColumn < m_xCols, "CGrid::CalcFitColumnWidth: invalid location specified");
|
||||
|
||||
int maxSize = 0;
|
||||
for(int i=0; i < m_yRows; i++)
|
||||
{
|
||||
Panel *pPanel = GridEntry(iColumn, i)->m_pPanel;
|
||||
if(!pPanel)
|
||||
continue;
|
||||
|
||||
int w, h;
|
||||
pPanel->getSize(w,h);
|
||||
if(w > maxSize)
|
||||
maxSize = w;
|
||||
}
|
||||
|
||||
return maxSize;
|
||||
}
|
||||
|
||||
|
||||
int CGrid::CalcFitRowHeight(int iRow)
|
||||
{
|
||||
AssertCheck(iRow >= 0 && iRow < m_yRows, "CGrid::CalcFitRowHeight: invalid location specified");
|
||||
|
||||
int maxSize = 0;
|
||||
for(int i=0; i < m_xCols; i++)
|
||||
{
|
||||
Panel *pPanel = GridEntry(i, iRow)->m_pPanel;
|
||||
if(!pPanel)
|
||||
continue;
|
||||
|
||||
int w, h;
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
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");
|
||||
|
||||
x = m_ColOffsets[col];
|
||||
w = m_Widths[col];
|
||||
|
||||
y = m_RowOffsets[row];
|
||||
h = m_Heights[row];
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CGrid::CopyColumnWidths(CGrid *pOther)
|
||||
{
|
||||
if(!pOther || pOther->m_xCols != m_xCols)
|
||||
return false;
|
||||
|
||||
for(int i=0; i < m_xCols; i++)
|
||||
m_Widths[i] = pOther->m_Widths[i];
|
||||
|
||||
CalcColOffsets(0);
|
||||
m_bDirty = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CGrid::RepositionContents()
|
||||
{
|
||||
for(int x=0; x < m_xCols; x++)
|
||||
{
|
||||
for(int y=0; y < m_yRows; y++)
|
||||
{
|
||||
Panel *pPanel = GridEntry(x,y)->m_pPanel;
|
||||
if(!pPanel)
|
||||
continue;
|
||||
|
||||
pPanel->setBounds(
|
||||
m_ColOffsets[x],
|
||||
m_RowOffsets[y],
|
||||
m_Widths[x],
|
||||
m_Heights[y]);
|
||||
}
|
||||
}
|
||||
|
||||
m_bDirty = false;
|
||||
}
|
||||
|
||||
|
||||
int CGrid::CalcDrawHeight()
|
||||
{
|
||||
if(m_yRows > 0)
|
||||
{
|
||||
return m_RowOffsets[m_yRows-1] + m_Heights[m_yRows - 1] + m_ySpacing;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CGrid::paint()
|
||||
{
|
||||
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++)
|
||||
{
|
||||
CGridEntry *cell = GridEntry(0, row);
|
||||
|
||||
y += cell->m_pPanel->getTall() + m_ySpacing;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGrid::paintBackground()
|
||||
{
|
||||
Panel::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)
|
||||
{
|
||||
CGridEntry *cell = GridEntry(0, row);
|
||||
cell->m_bUnderline = enabled;
|
||||
if (enabled)
|
||||
{
|
||||
cell->m_iUnderlineOffset = offset;
|
||||
cell->m_UnderlineColor[0] = r;
|
||||
cell->m_UnderlineColor[1] = g;
|
||||
cell->m_UnderlineColor[2] = b;
|
||||
cell->m_UnderlineColor[3] = a;
|
||||
}
|
||||
}
|
||||
|
||||
void CGrid::Clear()
|
||||
{
|
||||
m_xCols = m_yRows = 0;
|
||||
m_Widths = NULL;
|
||||
m_GridEntries = NULL;
|
||||
m_xSpacing = m_ySpacing = 0;
|
||||
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];
|
||||
}
|
||||
|
||||
|
||||
void CGrid::CalcColOffsets(int iStart)
|
||||
{
|
||||
int cur = m_xSpacing;
|
||||
if(iStart != 0)
|
||||
cur += m_ColOffsets[iStart-1] + m_Widths[iStart-1];
|
||||
|
||||
for(int i=iStart; i < m_xCols; i++)
|
||||
{
|
||||
m_ColOffsets[i] = cur;
|
||||
cur += m_Widths[i] + m_xSpacing;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CGrid::CalcRowOffsets(int iStart)
|
||||
{
|
||||
int cur = m_ySpacing;
|
||||
if(iStart != 0)
|
||||
cur += m_RowOffsets[iStart-1];
|
||||
|
||||
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)
|
||||
{
|
||||
row = -1; col = -1;
|
||||
for(int x=0; x < m_xCols; x++)
|
||||
{
|
||||
for(int y=0; y < m_yRows; y++)
|
||||
{
|
||||
Panel *pPanel = GridEntry(x,y)->m_pPanel;
|
||||
if (!pPanel)
|
||||
continue;
|
||||
|
||||
if (pPanel->isWithin(worldX, worldY))
|
||||
{
|
||||
col = x;
|
||||
row = y;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
124
hlsdk/game_shared/vgui_grid.h
Normal file
124
hlsdk/game_shared/vgui_grid.h
Normal file
@ -0,0 +1,124 @@
|
||||
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef VGUI_GRID_H
|
||||
#define VGUI_GRID_H
|
||||
#ifdef _WIN32
|
||||
#ifndef __MINGW32__
|
||||
#pragma once
|
||||
#endif /* not __MINGW32__ */
|
||||
#endif
|
||||
|
||||
|
||||
#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();
|
||||
virtual ~CGrid();
|
||||
|
||||
bool SetDimensions(int xCols, int yRows); // Set how many columns and rows in the grid.
|
||||
void Term();
|
||||
|
||||
Panel* GetEntry(int x, int y); // Get the panel associated with a grid entry.
|
||||
bool SetEntry(int x, int y, Panel *pPanel);
|
||||
|
||||
int GetXSpacing();
|
||||
int GetYSpacing();
|
||||
void SetSpacing(int xSpacing, int ySpacing); // Set spacing between rows and columns.
|
||||
|
||||
bool SetColumnWidth(int iColumn, int width); // Set a column's width.
|
||||
bool SetRowHeight(int iRow, int height); // Set a row's height.
|
||||
|
||||
int GetColumnWidth(int iColumn);
|
||||
int GetRowHeight(int iRow);
|
||||
|
||||
int CalcFitColumnWidth(int iColumn); // Returns the maximum width of all panels in the column.
|
||||
int CalcFitRowHeight(int iRow); // Returns the maximum height of all panels in the row.
|
||||
|
||||
int CalcDrawHeight(); // Returns how many pixels high the grid control should be
|
||||
// for all of its contents to be visible (based on its row heights
|
||||
// and y spacing).
|
||||
|
||||
void AutoSetRowHeights(); // Just does SetRowHeight(iRow, CalcFitRowHeight(iRow)) for all rows.
|
||||
|
||||
bool GetEntryBox( // Returns the bounding box for the specified entry.
|
||||
int col, int row, int &x, int &y, int &w, int &h);
|
||||
|
||||
bool CopyColumnWidths(CGrid *pOther); // Copy the column widths from the other grid. Fails if the
|
||||
// column count is different.
|
||||
|
||||
void RepositionContents(); // Sets the size and position of all the grid entries based
|
||||
// on current spacings and row/column widths.
|
||||
// You usually only want to call this while setting up the control
|
||||
// if you want to get the position or dimensions of the child
|
||||
// controls. This will set them.
|
||||
|
||||
void SetRowUnderline(int row, bool enabled, int offset, int r, int g, int b, int a); // sets underline color for a particular row
|
||||
|
||||
// returns the true if found, false otherwise
|
||||
bool getCellAtPoint(int worldX, int worldY, int &row, int &col);
|
||||
|
||||
// Panel overrides.
|
||||
public:
|
||||
|
||||
virtual void paint();
|
||||
virtual void paintBackground();
|
||||
|
||||
protected:
|
||||
|
||||
class CGridEntry
|
||||
{
|
||||
public:
|
||||
CGridEntry();
|
||||
~CGridEntry();
|
||||
|
||||
Panel *m_pPanel;
|
||||
|
||||
bool m_bUnderline;
|
||||
short m_UnderlineColor[4];
|
||||
int m_iUnderlineOffset;
|
||||
};
|
||||
|
||||
void Clear();
|
||||
CGridEntry* GridEntry(int x, int y);
|
||||
|
||||
void CalcColOffsets(int iStart);
|
||||
void CalcRowOffsets(int iStart);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
bool m_bDirty; // Set when controls will need to be repositioned.
|
||||
|
||||
int m_xCols;
|
||||
int m_yRows;
|
||||
|
||||
int m_xSpacing;
|
||||
int m_ySpacing;
|
||||
|
||||
int *m_Widths;
|
||||
int *m_Heights;
|
||||
int *m_ColOffsets;
|
||||
int *m_RowOffsets;
|
||||
|
||||
CGridEntry *m_GridEntries;
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // VGUI_GRID_H
|
45
hlsdk/game_shared/vgui_helpers.cpp
Normal file
45
hlsdk/game_shared/vgui_helpers.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "vgui_helpers.h"
|
||||
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
33
hlsdk/game_shared/vgui_helpers.h
Normal file
33
hlsdk/game_shared/vgui_helpers.h
Normal file
@ -0,0 +1,33 @@
|
||||
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef VGUI_HELPERS_H
|
||||
#define VGUI_HELPERS_H
|
||||
#ifdef _WIN32
|
||||
#ifndef __MINGW32__
|
||||
#pragma once
|
||||
#endif /* not __MINGW32__ */
|
||||
#endif
|
||||
|
||||
|
||||
#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); 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);
|
||||
|
||||
|
||||
#endif // VGUI_HELPERS_H
|
||||
|
207
hlsdk/game_shared/vgui_listbox.cpp
Normal file
207
hlsdk/game_shared/vgui_listbox.cpp
Normal file
@ -0,0 +1,207 @@
|
||||
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#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)
|
||||
{
|
||||
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_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;
|
||||
m_iScrollMax = -1;
|
||||
}
|
||||
|
||||
CListBox::~CListBox()
|
||||
{
|
||||
Term();
|
||||
}
|
||||
|
||||
void CListBox::Init()
|
||||
{
|
||||
Term();
|
||||
}
|
||||
|
||||
void CListBox::Term()
|
||||
{
|
||||
m_ItemOffset = 0;
|
||||
|
||||
// Free the LBItems.
|
||||
LBItem *pNext;
|
||||
for(LBItem *pItem=m_Items.m_pNext; pItem != &m_Items; pItem=pNext)
|
||||
{
|
||||
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)
|
||||
{
|
||||
// Add the item.
|
||||
LBItem *pItem = new LBItem;
|
||||
if(!pItem)
|
||||
return;
|
||||
|
||||
pItem->m_pPanel = panel;
|
||||
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);
|
||||
|
||||
InternalLayout();
|
||||
}
|
||||
|
||||
int CListBox::GetNumItems()
|
||||
{
|
||||
int count=0;
|
||||
for(LBItem *pItem=m_Items.m_pNext; pItem != &m_Items; pItem=pItem->m_pNext)
|
||||
++count;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int CListBox::GetItemWidth()
|
||||
{
|
||||
int wide, tall;
|
||||
m_ItemsPanel.getSize(wide, tall);
|
||||
return wide;
|
||||
}
|
||||
|
||||
int CListBox::GetScrollPos()
|
||||
{
|
||||
return m_ItemOffset;
|
||||
}
|
||||
|
||||
void CListBox::SetScrollPos(int pos)
|
||||
{
|
||||
int maxItems = GetScrollMax();
|
||||
if(maxItems < 0)
|
||||
return;
|
||||
|
||||
m_ItemOffset = (pos < 0) ? 0 : ((pos > maxItems) ? maxItems : pos);
|
||||
InternalLayout();
|
||||
}
|
||||
|
||||
void CListBox::setPos(int x, int y)
|
||||
{
|
||||
Panel::setPos(x, y);
|
||||
InternalLayout();
|
||||
}
|
||||
|
||||
void CListBox::setSize(int wide,int tall)
|
||||
{
|
||||
Panel::setSize(wide,tall);
|
||||
InternalLayout();
|
||||
}
|
||||
|
||||
void CListBox::setPixelScroll(int value)
|
||||
{
|
||||
m_ItemOffset = m_ScrollBar.getValue();
|
||||
InternalLayout();
|
||||
}
|
||||
|
||||
void CListBox::InternalLayout()
|
||||
{
|
||||
int 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);
|
||||
|
||||
bool bNeedScrollbar = false;
|
||||
|
||||
// Reposition the items.
|
||||
int curItem = 0;
|
||||
int curY = 0;
|
||||
int maxItem = GetScrollMax();
|
||||
for(LBItem *pItem=m_Items.m_pNext; pItem != &m_Items; pItem=pItem->m_pNext)
|
||||
{
|
||||
if(curItem < m_ItemOffset)
|
||||
{
|
||||
pItem->m_pPanel->setVisible(false);
|
||||
bNeedScrollbar = true;
|
||||
}
|
||||
else if (curItem >= maxItem)
|
||||
{
|
||||
// item is past the end of the items we care about
|
||||
pItem->m_pPanel->setVisible(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
pItem->m_pPanel->setVisible(true);
|
||||
|
||||
int 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);
|
||||
|
||||
curY += itemHeight;
|
||||
|
||||
if (curY > tall)
|
||||
{
|
||||
bNeedScrollbar = true;
|
||||
}
|
||||
}
|
||||
|
||||
++curItem;
|
||||
}
|
||||
|
||||
m_ScrollBar.setVisible(bNeedScrollbar);
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
void CListBox::paintBackground()
|
||||
{
|
||||
}
|
||||
|
||||
void CListBox::SetScrollRange(int maxScroll)
|
||||
{
|
||||
m_iScrollMax = maxScroll;
|
||||
m_ScrollBar.setRange(0, maxScroll);
|
||||
InternalLayout();
|
||||
}
|
||||
|
||||
int CListBox::GetScrollMax()
|
||||
{
|
||||
if (m_iScrollMax < 0)
|
||||
{
|
||||
return GetNumItems() - 1;
|
||||
}
|
||||
|
||||
return m_iScrollMax;
|
||||
}
|
||||
|
||||
|
117
hlsdk/game_shared/vgui_listbox.h
Normal file
117
hlsdk/game_shared/vgui_listbox.h
Normal file
@ -0,0 +1,117 @@
|
||||
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef VOICE_LISTBOX_H
|
||||
#define VOICE_LISTBOX_H
|
||||
#ifdef _WIN32
|
||||
#ifndef __MINGW32__
|
||||
#pragma once
|
||||
#endif /* not __MINGW32__ */
|
||||
#endif
|
||||
|
||||
|
||||
#include "VGUI_Panel.h"
|
||||
#include "VGUI_IntChangeSignal.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.
|
||||
// - The scrollbar scrolls one element at a time and the range is correct.
|
||||
|
||||
// Note: this listbox does not provide notification when items are
|
||||
class CListBox : public Panel
|
||||
{
|
||||
public:
|
||||
|
||||
CListBox();
|
||||
~CListBox();
|
||||
|
||||
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);
|
||||
|
||||
// Get the number of items currently in the listbox.
|
||||
int GetNumItems();
|
||||
|
||||
// Get the width that listbox items will be set to (this changes if you resize the listbox).
|
||||
int GetItemWidth();
|
||||
|
||||
// Get/set the scrollbar position (position says which element is at the top of the listbox).
|
||||
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);
|
||||
|
||||
// returns the maximum value the scrollbar can scroll to
|
||||
int GetScrollMax();
|
||||
|
||||
// vgui overrides.
|
||||
public:
|
||||
|
||||
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:
|
||||
Panel *m_pPanel;
|
||||
LBItem *m_pPrev, *m_pNext;
|
||||
};
|
||||
|
||||
class ListBoxSignal : public IntChangeSignal
|
||||
{
|
||||
public:
|
||||
void intChanged(int value,Panel* panel)
|
||||
{
|
||||
m_pListBox->setPixelScroll(-value);
|
||||
}
|
||||
|
||||
vgui::CListBox *m_pListBox;
|
||||
};
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
void InternalLayout();
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// All the items..
|
||||
LBItem m_Items;
|
||||
|
||||
Panel m_ItemsPanel;
|
||||
|
||||
int m_ItemOffset; // where we're scrolled to
|
||||
Slider2 m_Slider;
|
||||
ScrollBar2 m_ScrollBar;
|
||||
ListBoxSignal m_Signal;
|
||||
|
||||
int m_iScrollMax;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // VOICE_LISTBOX_H
|
93
hlsdk/game_shared/vgui_loadtga.cpp
Normal file
93
hlsdk/game_shared/vgui_loadtga.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "../cl_dll/wrect.h"
|
||||
#include "../cl_dll/cl_dll.h"
|
||||
#include "vgui.h"
|
||||
#include "vgui_loadtga.h"
|
||||
#include "vgui_inputstream.h"
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------- //
|
||||
// Helper class for loading tga files.
|
||||
// ---------------------------------------------------------------------- //
|
||||
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)
|
||||
{
|
||||
if(m_ReadPos>=0 && m_ReadPos<m_DataLen)
|
||||
{
|
||||
success=true;
|
||||
uchar ret = m_pData[m_ReadPos];
|
||||
++m_ReadPos;
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
success=false;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void readUChar(uchar* buf,int count,bool& success)
|
||||
{
|
||||
for(int i=0; i < count; i++)
|
||||
buf[i] = readUChar(success);
|
||||
}
|
||||
|
||||
virtual void close(bool& success)
|
||||
{
|
||||
m_pData = NULL;
|
||||
m_DataLen = m_ReadPos = 0;
|
||||
}
|
||||
|
||||
uchar *m_pData;
|
||||
int m_DataLen;
|
||||
int m_ReadPos;
|
||||
};
|
||||
|
||||
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)
|
||||
return NULL;
|
||||
|
||||
stream.m_ReadPos = 0;
|
||||
vgui::BitmapTGA *pRet = new vgui::BitmapTGA(&stream, true);
|
||||
gEngfuncs.COM_FreeFile(stream.m_pData);
|
||||
|
||||
return pRet;
|
||||
}
|
||||
|
||||
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)
|
||||
return NULL;
|
||||
|
||||
stream.m_ReadPos = 0;
|
||||
vgui::BitmapTGA *pRet = new vgui::BitmapTGA(&stream, false);
|
||||
gEngfuncs.COM_FreeFile(stream.m_pData);
|
||||
|
||||
return pRet;
|
||||
}
|
24
hlsdk/game_shared/vgui_loadtga.h
Normal file
24
hlsdk/game_shared/vgui_loadtga.h
Normal file
@ -0,0 +1,24 @@
|
||||
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef VGUI_LOADTGA_H
|
||||
#define VGUI_LOADTGA_H
|
||||
#ifdef _WIN32
|
||||
#ifndef __MINGW32__
|
||||
#pragma once
|
||||
#endif /* not __MINGW32__ */
|
||||
#endif
|
||||
|
||||
|
||||
#include "vgui_bitmaptga.h"
|
||||
|
||||
|
||||
vgui::BitmapTGA* vgui_LoadTGA(char const *pFilename);
|
||||
vgui::BitmapTGA* vgui_LoadTGANoInvertAlpha(char const *pFilename);
|
||||
|
||||
|
||||
#endif // VGUI_LOADTGA_H
|
310
hlsdk/game_shared/vgui_scrollbar2.cpp
Normal file
310
hlsdk/game_shared/vgui_scrollbar2.cpp
Normal file
@ -0,0 +1,310 @@
|
||||
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#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>
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
class FooDefaultScrollBarIntChangeSignal : public IntChangeSignal
|
||||
{
|
||||
public:
|
||||
FooDefaultScrollBarIntChangeSignal(ScrollBar2* scrollBar)
|
||||
{
|
||||
_scrollBar=scrollBar;
|
||||
}
|
||||
virtual void intChanged(int value,Panel* panel)
|
||||
{
|
||||
_scrollBar->fireIntChangeSignal();
|
||||
}
|
||||
protected:
|
||||
ScrollBar2* _scrollBar;
|
||||
};
|
||||
|
||||
class FooDefaultButtonSignal : public ActionSignal
|
||||
{
|
||||
public:
|
||||
ScrollBar2* _scrollBar;
|
||||
int _buttonIndex;
|
||||
public:
|
||||
FooDefaultButtonSignal(ScrollBar2* scrollBar,int buttonIndex)
|
||||
{
|
||||
_scrollBar=scrollBar;
|
||||
_buttonIndex=buttonIndex;
|
||||
}
|
||||
public:
|
||||
virtual void actionPerformed(Panel* panel)
|
||||
{
|
||||
_scrollBar->doButtonPressed(_buttonIndex);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Default scrollbar button
|
||||
// Draws in new scoreboard style
|
||||
//-----------------------------------------------------------------------------
|
||||
class ScrollBarButton : public Button
|
||||
{
|
||||
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)
|
||||
{
|
||||
Image *image = vgui_LoadTGA(filename);
|
||||
if (image)
|
||||
{
|
||||
image->setColor(Color(140, 140, 140, 0));
|
||||
setImage(image);
|
||||
}
|
||||
|
||||
setBorder(&m_Border);
|
||||
}
|
||||
|
||||
virtual void paintBackground()
|
||||
{
|
||||
int wide,tall;
|
||||
getPaintSize(wide,tall);
|
||||
|
||||
// fill the background
|
||||
drawSetColor(0, 0, 0, 0);
|
||||
drawFilledRect(0, 0, wide, tall);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Constructor
|
||||
// Input : x -
|
||||
// y -
|
||||
// wide -
|
||||
// tall -
|
||||
// vertical -
|
||||
//-----------------------------------------------------------------------------
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
setPaintBorderEnabled(true);
|
||||
setPaintBackgroundEnabled(true);
|
||||
setPaintEnabled(true);
|
||||
setButtonPressedScrollValue(15);
|
||||
|
||||
validate();
|
||||
}
|
||||
|
||||
void ScrollBar2::setSize(int wide,int tall)
|
||||
{
|
||||
Panel::setSize(wide,tall);
|
||||
|
||||
if(_slider==null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(_button[0]==null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(_button[1]==null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
getPaintSize(wide,tall);
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollBar2::performLayout()
|
||||
{
|
||||
}
|
||||
|
||||
void ScrollBar2::setValue(int value)
|
||||
{
|
||||
_slider->setValue(value);
|
||||
}
|
||||
|
||||
int ScrollBar2::getValue()
|
||||
{
|
||||
return _slider->getValue();
|
||||
}
|
||||
|
||||
void ScrollBar2::addIntChangeSignal(IntChangeSignal* s)
|
||||
{
|
||||
_intChangeSignalDar.putElement(s);
|
||||
_slider->addIntChangeSignal(new FooDefaultScrollBarIntChangeSignal(this));
|
||||
}
|
||||
|
||||
void ScrollBar2::setRange(int min,int max)
|
||||
{
|
||||
_slider->setRange(min,max);
|
||||
}
|
||||
|
||||
void ScrollBar2::fireIntChangeSignal()
|
||||
{
|
||||
for(int i=0;i<_intChangeSignalDar.getCount();i++)
|
||||
{
|
||||
_intChangeSignalDar[i]->intChanged(_slider->getValue(),this);
|
||||
}
|
||||
}
|
||||
|
||||
bool ScrollBar2::isVertical()
|
||||
{
|
||||
return _slider->isVertical();
|
||||
}
|
||||
|
||||
bool ScrollBar2::hasFullRange()
|
||||
{
|
||||
return _slider->hasFullRange();
|
||||
}
|
||||
|
||||
//LEAK: new and old slider will leak
|
||||
void ScrollBar2::setButton(Button* button,int index)
|
||||
{
|
||||
if(_button[index]!=null)
|
||||
{
|
||||
removeChild(_button[index]);
|
||||
}
|
||||
_button[index]=button;
|
||||
addChild(_button[index]);
|
||||
|
||||
_button[index]->addActionSignal(new FooDefaultButtonSignal(this,index));
|
||||
|
||||
validate();
|
||||
|
||||
//_button[index]->setVisible(false);
|
||||
}
|
||||
|
||||
Button* ScrollBar2::getButton(int index)
|
||||
{
|
||||
return _button[index];
|
||||
}
|
||||
|
||||
//LEAK: new and old slider will leak
|
||||
void ScrollBar2::setSlider(Slider2 *slider)
|
||||
{
|
||||
if(_slider!=null)
|
||||
{
|
||||
removeChild(_slider);
|
||||
}
|
||||
_slider=slider;
|
||||
addChild(_slider);
|
||||
|
||||
_slider->addIntChangeSignal(new FooDefaultScrollBarIntChangeSignal(this));
|
||||
|
||||
validate();
|
||||
}
|
||||
|
||||
Slider2 *ScrollBar2::getSlider()
|
||||
{
|
||||
return _slider;
|
||||
}
|
||||
|
||||
void ScrollBar2::doButtonPressed(int buttonIndex)
|
||||
{
|
||||
if(buttonIndex==0)
|
||||
{
|
||||
_slider->setValue(_slider->getValue()-_buttonPressedScrollValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
_slider->setValue(_slider->getValue()+_buttonPressedScrollValue);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ScrollBar2::setButtonPressedScrollValue(int value)
|
||||
{
|
||||
_buttonPressedScrollValue=value;
|
||||
}
|
||||
|
||||
void ScrollBar2::setRangeWindow(int rangeWindow)
|
||||
{
|
||||
_slider->setRangeWindow(rangeWindow);
|
||||
}
|
||||
|
||||
void ScrollBar2::setRangeWindowEnabled(bool state)
|
||||
{
|
||||
_slider->setRangeWindowEnabled(state);
|
||||
}
|
||||
|
||||
void ScrollBar2::validate()
|
||||
{
|
||||
if(_slider!=null)
|
||||
{
|
||||
int buttonOffset=0;
|
||||
|
||||
for(int i=0;i<2;i++)
|
||||
{
|
||||
if(_button[i]!=null)
|
||||
{
|
||||
if(_button[i]->isVisible())
|
||||
{
|
||||
if(_slider->isVertical())
|
||||
{
|
||||
buttonOffset+=_button[i]->getTall();
|
||||
}
|
||||
else
|
||||
{
|
||||
buttonOffset+=_button[i]->getWide();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_slider->setButtonOffset(buttonOffset);
|
||||
}
|
||||
|
||||
int wide,tall;
|
||||
getSize(wide,tall);
|
||||
setSize(wide,tall);
|
||||
}
|
64
hlsdk/game_shared/vgui_scrollbar2.h
Normal file
64
hlsdk/game_shared/vgui_scrollbar2.h
Normal file
@ -0,0 +1,64 @@
|
||||
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef VGUI_SCROLLBAR2_H
|
||||
#define VGUI_SCROLLBAR2_H
|
||||
#ifdef _WIN32
|
||||
#ifndef __MINGW32__
|
||||
#pragma once
|
||||
#endif /* not __MINGW32__ */
|
||||
#endif
|
||||
|
||||
#include<VGUI.h>
|
||||
#include<VGUI_Panel.h>
|
||||
#include<VGUI_Dar.h>
|
||||
|
||||
namespace vgui
|
||||
{
|
||||
|
||||
class IntChangeSignal;
|
||||
class Button;
|
||||
class Slider2;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Hacked up version of the vgui scrollbar
|
||||
//-----------------------------------------------------------------------------
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // VGUI_SCROLLBAR2_H
|
436
hlsdk/game_shared/vgui_slider2.cpp
Normal file
436
hlsdk/game_shared/vgui_slider2.cpp
Normal file
@ -0,0 +1,436 @@
|
||||
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose: New version of the slider bar
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "VGUI_Slider2.h"
|
||||
|
||||
#include<VGUI_InputSignal.h>
|
||||
#include<VGUI_App.h>
|
||||
#include<VGUI_IntChangeSignal.h>
|
||||
#include<VGUI_MouseCode.h>
|
||||
|
||||
using namespace vgui;
|
||||
|
||||
namespace
|
||||
{
|
||||
class FooDefaultSliderSignal : public InputSignal
|
||||
{
|
||||
private:
|
||||
Slider2* _slider;
|
||||
public:
|
||||
FooDefaultSliderSignal(Slider2* slider)
|
||||
{
|
||||
_slider=slider;
|
||||
}
|
||||
public:
|
||||
void cursorMoved(int x,int y,Panel* 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)
|
||||
{
|
||||
_slider->privateMousePressed(code,panel);
|
||||
}
|
||||
void mouseReleased(MouseCode code,Panel* 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){}
|
||||
};
|
||||
}
|
||||
|
||||
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;
|
||||
recomputeNobPosFromValue();
|
||||
addInputSignal(new FooDefaultSliderSignal(this));
|
||||
}
|
||||
|
||||
void Slider2::setSize(int wide,int tall)
|
||||
{
|
||||
Panel::setSize(wide,tall);
|
||||
recomputeNobPosFromValue();
|
||||
}
|
||||
|
||||
bool Slider2::isVertical()
|
||||
{
|
||||
return _vertical;
|
||||
}
|
||||
|
||||
void Slider2::setValue(int value)
|
||||
{
|
||||
int oldValue=_value;
|
||||
|
||||
if(value<_range[0])
|
||||
{
|
||||
value=_range[0];
|
||||
}
|
||||
|
||||
if(value>_range[1])
|
||||
{
|
||||
value=_range[1];
|
||||
}
|
||||
|
||||
_value=value;
|
||||
recomputeNobPosFromValue();
|
||||
|
||||
if(_value!=oldValue)
|
||||
{
|
||||
fireIntChangeSignal();
|
||||
}
|
||||
}
|
||||
|
||||
int Slider2::getValue()
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
void Slider2::recomputeNobPosFromValue()
|
||||
{
|
||||
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 fper=fvalue/frange;
|
||||
float frangewindow=(float)(_rangeWindow);
|
||||
|
||||
if(frangewindow<0)
|
||||
{
|
||||
frangewindow=0;
|
||||
}
|
||||
|
||||
if(!_rangeWindowEnabled)
|
||||
{
|
||||
frangewindow=frange;
|
||||
}
|
||||
|
||||
if ( frangewindow > 0 )
|
||||
{
|
||||
if(_vertical)
|
||||
{
|
||||
float fnobsize=frangewindow;
|
||||
float freepixels = ftall - fnobsize;
|
||||
|
||||
float firstpixel = freepixels * fper;
|
||||
|
||||
_nobPos[0]=(int)( firstpixel );
|
||||
_nobPos[1]=(int)( firstpixel + fnobsize );
|
||||
|
||||
if(_nobPos[1]>tall)
|
||||
{
|
||||
_nobPos[0]=tall-((int)fnobsize);
|
||||
_nobPos[1]=tall;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float fnobsize=frangewindow;
|
||||
float freepixels = fwide - fnobsize;
|
||||
|
||||
float firstpixel = freepixels * fper;
|
||||
|
||||
_nobPos[0]=(int)( firstpixel );
|
||||
_nobPos[1]=(int)( firstpixel + fnobsize );
|
||||
|
||||
if(_nobPos[1]>wide)
|
||||
{
|
||||
_nobPos[0]=wide-((int)fnobsize);
|
||||
_nobPos[1]=wide;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repaint();
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if(frangewindow<0)
|
||||
{
|
||||
frangewindow=0;
|
||||
}
|
||||
|
||||
if(!_rangeWindowEnabled)
|
||||
{
|
||||
frangewindow=frange;
|
||||
}
|
||||
|
||||
if ( frangewindow > 0 )
|
||||
{
|
||||
if(_vertical)
|
||||
{
|
||||
float fnobsize=frangewindow;
|
||||
fvalue=frange*(fnob/(ftall-fnobsize));
|
||||
}
|
||||
else
|
||||
{
|
||||
float fnobsize=frangewindow;
|
||||
fvalue=frange*(fnob/(fwide-fnobsize));
|
||||
}
|
||||
}
|
||||
// Take care of rounding issues.
|
||||
_value=(int)(fvalue+_range[0]+0.5);
|
||||
|
||||
// Clamp final result
|
||||
_value = ( _value < _range[1] ) ? _value : _range[1];
|
||||
}
|
||||
|
||||
bool Slider2::hasFullRange()
|
||||
{
|
||||
int wide,tall;
|
||||
getPaintSize(wide,tall);
|
||||
|
||||
float fwide=(float)wide;
|
||||
float ftall=(float)tall;
|
||||
float frange=(float)(_range[1]-_range[0]);
|
||||
float frangewindow=(float)(_rangeWindow);
|
||||
|
||||
if(frangewindow<0)
|
||||
{
|
||||
frangewindow=0;
|
||||
}
|
||||
|
||||
if(!_rangeWindowEnabled)
|
||||
{
|
||||
frangewindow=frange;
|
||||
}
|
||||
|
||||
if ( frangewindow > 0 )
|
||||
{
|
||||
if(_vertical)
|
||||
{
|
||||
if( frangewindow <= ( ftall + _buttonOffset ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( frangewindow <= ( fwide + _buttonOffset ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Slider2::addIntChangeSignal(IntChangeSignal* s)
|
||||
{
|
||||
_intChangeSignalDar.putElement(s);
|
||||
}
|
||||
|
||||
void Slider2::fireIntChangeSignal()
|
||||
{
|
||||
for(int i=0;i<_intChangeSignalDar.getCount();i++)
|
||||
{
|
||||
_intChangeSignalDar[i]->intChanged(getValue(),this);
|
||||
}
|
||||
}
|
||||
|
||||
void Slider2::paintBackground()
|
||||
{
|
||||
int wide,tall;
|
||||
getPaintSize(wide,tall);
|
||||
|
||||
if (_vertical)
|
||||
{
|
||||
// background behind slider
|
||||
drawSetColor(40, 40, 40, 0);
|
||||
drawFilledRect(0, 0, wide, tall);
|
||||
|
||||
// slider front
|
||||
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
|
||||
}
|
||||
else
|
||||
{
|
||||
//!! doesn't work
|
||||
|
||||
drawSetColor(Scheme::sc_secondary3);
|
||||
drawFilledRect(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_black);
|
||||
drawOutlinedRect(_nobPos[0],0,_nobPos[1],tall);
|
||||
}
|
||||
}
|
||||
|
||||
void Slider2::setRange(int min,int max)
|
||||
{
|
||||
if(max<min)
|
||||
{
|
||||
max=min;
|
||||
}
|
||||
|
||||
if(min>max)
|
||||
{
|
||||
min=max;
|
||||
}
|
||||
|
||||
_range[0]=min;
|
||||
_range[1]=max;
|
||||
}
|
||||
|
||||
void Slider2::getRange(int& min,int& max)
|
||||
{
|
||||
min=_range[0];
|
||||
max=_range[1];
|
||||
}
|
||||
|
||||
void Slider2::privateCursorMoved(int x,int y,Panel* panel)
|
||||
{
|
||||
if(!_dragging)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
getApp()->getCursorPos(x,y);
|
||||
screenToLocal(x,y);
|
||||
|
||||
int wide,tall;
|
||||
getPaintSize(wide,tall);
|
||||
|
||||
if(_vertical)
|
||||
{
|
||||
_nobPos[0]=_nobDragStartPos[0]+(y-_dragStartPos[1]);
|
||||
_nobPos[1]=_nobDragStartPos[1]+(y-_dragStartPos[1]);
|
||||
|
||||
if(_nobPos[1]>tall)
|
||||
{
|
||||
_nobPos[0]=tall-(_nobPos[1]-_nobPos[0]);
|
||||
_nobPos[1]=tall;
|
||||
}
|
||||
|
||||
if(_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]);
|
||||
|
||||
if(_nobPos[1]>wide)
|
||||
{
|
||||
_nobPos[0]=wide-(_nobPos[1]-_nobPos[0]);
|
||||
_nobPos[1]=wide;
|
||||
}
|
||||
|
||||
if(_nobPos[0]<0)
|
||||
{
|
||||
_nobPos[1]=_nobPos[1]-_nobPos[0];
|
||||
_nobPos[0]=0;
|
||||
}
|
||||
}
|
||||
|
||||
recomputeValueFromNobPos();
|
||||
repaint();
|
||||
fireIntChangeSignal();
|
||||
}
|
||||
|
||||
void Slider2::privateMousePressed(MouseCode code,Panel* panel)
|
||||
{
|
||||
int x,y;
|
||||
getApp()->getCursorPos(x,y);
|
||||
screenToLocal(x,y);
|
||||
|
||||
if(_vertical)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Slider2::privateMouseReleased(MouseCode code,Panel* panel)
|
||||
{
|
||||
_dragging=false;
|
||||
getApp()->setMouseCapture(null);
|
||||
}
|
||||
|
||||
void Slider2::getNobPos(int& min, int& max)
|
||||
{
|
||||
min=_nobPos[0];
|
||||
max=_nobPos[1];
|
||||
}
|
||||
|
||||
void Slider2::setRangeWindow(int rangeWindow)
|
||||
{
|
||||
_rangeWindow=rangeWindow;
|
||||
}
|
||||
|
||||
void Slider2::setRangeWindowEnabled(bool state)
|
||||
{
|
||||
_rangeWindowEnabled=state;
|
||||
}
|
||||
|
||||
void Slider2::setButtonOffset(int buttonOffset)
|
||||
{
|
||||
_buttonOffset=buttonOffset;
|
||||
}
|
69
hlsdk/game_shared/vgui_slider2.h
Normal file
69
hlsdk/game_shared/vgui_slider2.h
Normal file
@ -0,0 +1,69 @@
|
||||
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef VGUI_SLIDER2_H
|
||||
#define VGUI_SLIDER2_H
|
||||
#ifdef _WIN32
|
||||
#ifndef __MINGW32__
|
||||
#pragma once
|
||||
#endif /* not __MINGW32__ */
|
||||
#endif
|
||||
|
||||
#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];
|
||||
int _nobDragStartPos[2];
|
||||
int _dragStartPos[2];
|
||||
Dar<IntChangeSignal*> _intChangeSignalDar;
|
||||
int _range[2];
|
||||
int _value;
|
||||
int _rangeWindow;
|
||||
bool _rangeWindowEnabled;
|
||||
int _buttonOffset;
|
||||
public:
|
||||
Slider2(int x,int y,int wide,int tall,bool vertical);
|
||||
public:
|
||||
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 bool hasFullRange();
|
||||
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);
|
||||
protected:
|
||||
virtual void fireIntChangeSignal();
|
||||
virtual void paintBackground();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // VGUI_SLIDER2_H
|
205
hlsdk/game_shared/voice_banmgr.cpp
Normal file
205
hlsdk/game_shared/voice_banmgr.cpp
Normal file
@ -0,0 +1,205 @@
|
||||
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "voice_banmgr.h"
|
||||
|
||||
#if defined _MSC_VER && _MSC_VER >= 1400
|
||||
#ifndef _CRT_SECURE_NO_DEPRECATE
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#endif
|
||||
|
||||
#pragma warning(disable: 4996) // deprecated functions
|
||||
#endif
|
||||
|
||||
|
||||
#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 curHash = 0;
|
||||
|
||||
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)
|
||||
{
|
||||
Term();
|
||||
|
||||
char filename[512];
|
||||
_snprintf(filename, sizeof(filename), "%s/%s", pGameDir, g_pBanMgrFilename);
|
||||
|
||||
// Load in the squelch file.
|
||||
FILE *fp = fopen(filename, "rb");
|
||||
if(fp)
|
||||
{
|
||||
int version;
|
||||
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);
|
||||
|
||||
for(int i=0; i < nIDs; i++)
|
||||
{
|
||||
char playerID[16];
|
||||
fread(playerID, 1, 16, fp);
|
||||
AddBannedPlayer(playerID);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CVoiceBanMgr::Term()
|
||||
{
|
||||
// Free all the player structures.
|
||||
for(int i=0; i < 256; i++)
|
||||
{
|
||||
BannedPlayer *pListHead = &m_PlayerHash[i];
|
||||
BannedPlayer *pNext;
|
||||
for(BannedPlayer *pCur=pListHead->m_pNext; pCur != pListHead; pCur=pNext)
|
||||
{
|
||||
pNext = pCur->m_pNext;
|
||||
delete pCur;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int version = BANMGR_FILEVERSION;
|
||||
fwrite(&version, 1, sizeof(version), fp);
|
||||
|
||||
for(int i=0; i < 256; i++)
|
||||
{
|
||||
BannedPlayer *pListHead = &m_PlayerHash[i];
|
||||
for(BannedPlayer *pCur=pListHead->m_pNext; pCur != pListHead; pCur=pCur->m_pNext)
|
||||
{
|
||||
fwrite(pCur->m_PlayerID, 1, 16, fp);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CVoiceBanMgr::GetPlayerBan(char const playerID[16])
|
||||
{
|
||||
return !!InternalFindPlayerSquelch(playerID);
|
||||
}
|
||||
|
||||
|
||||
void CVoiceBanMgr::SetPlayerBan(char const playerID[16], bool bSquelch)
|
||||
{
|
||||
if(bSquelch)
|
||||
{
|
||||
// Is this guy already squelched?
|
||||
if(GetPlayerBan(playerID))
|
||||
return;
|
||||
|
||||
AddBannedPlayer(playerID);
|
||||
}
|
||||
else
|
||||
{
|
||||
BannedPlayer *pPlayer = InternalFindPlayerSquelch(playerID);
|
||||
if(pPlayer)
|
||||
{
|
||||
pPlayer->m_pPrev->m_pNext = pPlayer->m_pNext;
|
||||
pPlayer->m_pNext->m_pPrev = pPlayer->m_pPrev;
|
||||
delete pPlayer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CVoiceBanMgr::ForEachBannedPlayer(void (*callback)(char id[16]))
|
||||
{
|
||||
for(int i=0; i < 256; i++)
|
||||
{
|
||||
for(BannedPlayer *pCur=m_PlayerHash[i].m_pNext; pCur != &m_PlayerHash[i]; pCur=pCur->m_pNext)
|
||||
{
|
||||
callback(pCur->m_PlayerID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CVoiceBanMgr::Clear()
|
||||
{
|
||||
// Tie off the hash table entries.
|
||||
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])
|
||||
{
|
||||
int index = HashPlayerID(playerID);
|
||||
BannedPlayer *pListHead = &m_PlayerHash[index];
|
||||
for(BannedPlayer *pCur=pListHead->m_pNext; pCur != pListHead; pCur=pCur->m_pNext)
|
||||
{
|
||||
if(memcmp(playerID, pCur->m_PlayerID, 16) == 0)
|
||||
return pCur;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
CVoiceBanMgr::BannedPlayer* CVoiceBanMgr::AddBannedPlayer(char const playerID[16])
|
||||
{
|
||||
BannedPlayer *pNew = new BannedPlayer;
|
||||
if(!pNew)
|
||||
return NULL;
|
||||
|
||||
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;
|
||||
}
|
||||
|
59
hlsdk/game_shared/voice_banmgr.h
Normal file
59
hlsdk/game_shared/voice_banmgr.h
Normal file
@ -0,0 +1,59 @@
|
||||
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef VOICE_BANMGR_H
|
||||
#define VOICE_BANMGR_H
|
||||
#ifdef _WIN32
|
||||
#ifndef __MINGW32__
|
||||
#pragma once
|
||||
#endif /* not __MINGW32__ */
|
||||
#endif
|
||||
|
||||
|
||||
// This class manages the (persistent) list of squelched players.
|
||||
class CVoiceBanMgr
|
||||
{
|
||||
public:
|
||||
|
||||
CVoiceBanMgr();
|
||||
~CVoiceBanMgr();
|
||||
|
||||
// Init loads the list of squelched players from disk.
|
||||
bool Init(char const *pGameDir);
|
||||
void Term();
|
||||
|
||||
// Saves the state into voice_squelch.dt.
|
||||
void SaveState(char const *pGameDir);
|
||||
|
||||
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]));
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
class BannedPlayer
|
||||
{
|
||||
public:
|
||||
char m_PlayerID[16];
|
||||
BannedPlayer *m_pPrev, *m_pNext;
|
||||
};
|
||||
|
||||
void Clear();
|
||||
BannedPlayer* InternalFindPlayerSquelch(char const playerID[16]);
|
||||
BannedPlayer* AddBannedPlayer(char const playerID[16]);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
BannedPlayer m_PlayerHash[256];
|
||||
};
|
||||
|
||||
|
||||
#endif // VOICE_BANMGR_H
|
26
hlsdk/game_shared/voice_common.h
Normal file
26
hlsdk/game_shared/voice_common.h
Normal file
@ -0,0 +1,26 @@
|
||||
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef VOICE_COMMON_H
|
||||
#define VOICE_COMMON_H
|
||||
#ifdef _WIN32
|
||||
#ifndef __MINGW32__
|
||||
#pragma once
|
||||
#endif /* not __MINGW32__ */
|
||||
#endif
|
||||
|
||||
|
||||
#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))
|
||||
|
||||
typedef CBitVec<VOICE_MAX_PLAYERS> CPlayerBitVec;
|
||||
|
||||
|
||||
#endif // VOICE_COMMON_H
|
274
hlsdk/game_shared/voice_gamemgr.cpp
Normal file
274
hlsdk/game_shared/voice_gamemgr.cpp
Normal file
@ -0,0 +1,274 @@
|
||||
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "voice_gamemgr.h"
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "extdll.h"
|
||||
#include "util.h"
|
||||
#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
|
||||
// player can't hear anyone).
|
||||
|
||||
CPlayerBitVec g_BanMasks[VOICE_MAX_PLAYERS]; // Tells which players don't want to hear each other.
|
||||
// These are indexed as clients and each bit represents a client
|
||||
// (so player entity is bit+1).
|
||||
|
||||
CPlayerBitVec g_SentGameRulesMasks[VOICE_MAX_PLAYERS]; // These store the masks we last sent to each client so we can determine if
|
||||
CPlayerBitVec g_SentBanMasks[VOICE_MAX_PLAYERS]; // we need to resend them.
|
||||
CPlayerBitVec g_bWantModEnable;
|
||||
|
||||
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"};
|
||||
|
||||
// ------------------------------------------------------------------------ //
|
||||
// Static helpers.
|
||||
// ------------------------------------------------------------------------ //
|
||||
|
||||
// Find a player with a case-insensitive name search.
|
||||
/*static CBasePlayer* FindPlayerByName(const char *pTestName)
|
||||
{
|
||||
for(int i=1; i <= gpGlobals->maxClients; i++)
|
||||
{
|
||||
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)
|
||||
{
|
||||
return (CBasePlayer*)pEnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}*/
|
||||
|
||||
static void VoiceServerDebug( char const *pFmt, ... )
|
||||
{
|
||||
char msg[4096];
|
||||
va_list marker;
|
||||
|
||||
if( !voice_serverdebug.value )
|
||||
return;
|
||||
|
||||
va_start( marker, pFmt );
|
||||
_vsnprintf( msg, sizeof(msg), pFmt, marker );
|
||||
va_end( marker );
|
||||
|
||||
ALERT( at_console, "%s", msg );
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------ //
|
||||
// CVoiceGameMgr.
|
||||
// ------------------------------------------------------------------------ //
|
||||
|
||||
CVoiceGameMgr::CVoiceGameMgr()
|
||||
{
|
||||
m_UpdateInterval = 0;
|
||||
m_nMaxPlayers = 0;
|
||||
}
|
||||
|
||||
|
||||
CVoiceGameMgr::~CVoiceGameMgr()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
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");
|
||||
|
||||
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" ) )
|
||||
CVAR_REGISTER( &voice_serverdebug );
|
||||
|
||||
if( !CVAR_GET_POINTER( "sv_alltalk" ) )
|
||||
CVAR_REGISTER( &sv_alltalk );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CVoiceGameMgr::SetHelper(IVoiceGameMgrHelper *pHelper)
|
||||
{
|
||||
m_pHelper = pHelper;
|
||||
}
|
||||
|
||||
|
||||
void CVoiceGameMgr::Update(double frametime)
|
||||
{
|
||||
// Only update periodically.
|
||||
m_UpdateInterval += frametime;
|
||||
if(m_UpdateInterval < UPDATE_INTERVAL)
|
||||
return;
|
||||
|
||||
UpdateMasks();
|
||||
}
|
||||
|
||||
|
||||
void CVoiceGameMgr::ClientConnected(edict_t *pEdict)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
int iReceiverIndex, iSenderIndex;
|
||||
|
||||
if ( !pReceiver || !pSender )
|
||||
return false;
|
||||
|
||||
iReceiverIndex = pReceiver->entindex() - 1;
|
||||
iSenderIndex = pSender->entindex() - 1;
|
||||
|
||||
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)
|
||||
{
|
||||
int playerClientIndex = pPlayer->entindex() - 1;
|
||||
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)
|
||||
{
|
||||
for(int i=1; i < CMD_ARGC(); i++)
|
||||
{
|
||||
unsigned long mask = 0;
|
||||
sscanf(CMD_ARGV(i), "%lx", &mask);
|
||||
|
||||
if(i <= VOICE_MAX_PLAYERS_DW)
|
||||
{
|
||||
VoiceServerDebug( "CVoiceGameMgr::ClientCommand: vban (0x%x) from %d\n", mask, playerClientIndex );
|
||||
g_BanMasks[playerClientIndex].SetDWord(i-1, mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
VoiceServerDebug( "CVoiceGameMgr::ClientCommand: invalid index (%d)\n", i );
|
||||
}
|
||||
}
|
||||
|
||||
// Force it to update the masks now.
|
||||
//UpdateMasks();
|
||||
return true;
|
||||
}
|
||||
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));
|
||||
g_bWantModEnable[playerClientIndex] = false;
|
||||
//UpdateMasks();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CVoiceGameMgr::UpdateMasks()
|
||||
{
|
||||
m_UpdateInterval = 0;
|
||||
|
||||
bool bAllTalk = !!g_engfuncs.pfnCVarGetFloat( "sv_alltalk" );
|
||||
|
||||
for(int iClient=0; iClient < m_nMaxPlayers; iClient++)
|
||||
{
|
||||
CBaseEntity *pEnt = UTIL_PlayerByIndex(iClient+1);
|
||||
if(!pEnt || !pEnt->IsPlayer())
|
||||
continue;
|
||||
|
||||
// Request the state of their "VModEnable" cvar.
|
||||
if(g_bWantModEnable[iClient])
|
||||
{
|
||||
MESSAGE_BEGIN(MSG_ONE, m_msgRequestState, NULL, pEnt->pev);
|
||||
MESSAGE_END();
|
||||
}
|
||||
|
||||
CBasePlayer *pPlayer = (CBasePlayer*)pEnt;
|
||||
|
||||
CPlayerBitVec gameRulesMask;
|
||||
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++)
|
||||
{
|
||||
CBaseEntity *pEnt = UTIL_PlayerByIndex(iOtherClient+1);
|
||||
if(pEnt && pEnt->IsPlayer() &&
|
||||
(bAllTalk || m_pHelper->CanPlayerHearPlayer(pPlayer, (CBasePlayer*)pEnt)) )
|
||||
{
|
||||
gameRulesMask[iOtherClient] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If this is different from what the client has, send an update.
|
||||
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);
|
||||
int dw;
|
||||
for(dw=0; dw < VOICE_MAX_PLAYERS_DW; 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++)
|
||||
{
|
||||
bool bCanHear = gameRulesMask[iOtherClient] && !g_BanMasks[iClient][iOtherClient];
|
||||
g_engfuncs.pfnVoice_SetClientListening(iClient+1, iOtherClient+1, bCanHear);
|
||||
}
|
||||
}
|
||||
}
|
83
hlsdk/game_shared/voice_gamemgr.h
Normal file
83
hlsdk/game_shared/voice_gamemgr.h
Normal file
@ -0,0 +1,83 @@
|
||||
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef VOICE_GAMEMGR_H
|
||||
#define VOICE_GAMEMGR_H
|
||||
#ifdef _WIN32
|
||||
#ifndef __MINGW32__
|
||||
#pragma once
|
||||
#endif /* not __MINGW32__ */
|
||||
#endif
|
||||
|
||||
|
||||
#include "voice_common.h"
|
||||
|
||||
|
||||
class CGameRules;
|
||||
class CBasePlayer;
|
||||
|
||||
|
||||
class IVoiceGameMgrHelper
|
||||
{
|
||||
public:
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
// CVoiceGameMgr manages which clients can hear which other clients.
|
||||
class CVoiceGameMgr
|
||||
{
|
||||
public:
|
||||
CVoiceGameMgr();
|
||||
virtual ~CVoiceGameMgr();
|
||||
|
||||
bool Init(
|
||||
IVoiceGameMgrHelper *m_pHelper,
|
||||
int maxClients
|
||||
);
|
||||
|
||||
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);
|
||||
|
||||
// Called when a new client connects (unsquelches its entity for everyone).
|
||||
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);
|
||||
|
||||
// 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);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Force it to update the client masks.
|
||||
void UpdateMasks();
|
||||
|
||||
|
||||
private:
|
||||
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
|
874
hlsdk/game_shared/voice_status.cpp
Normal file
874
hlsdk/game_shared/voice_status.cpp
Normal file
@ -0,0 +1,874 @@
|
||||
//========= Copyright <20> 1996-2002, 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( 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 <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 "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]
|
||||
);
|
||||
strupr(str);
|
||||
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_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 = NULL;
|
||||
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(""))
|
||||
{
|
||||
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 ) )
|
||||
{
|
||||
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") )
|
||||
{
|
||||
m_pLocalBitmap->setColor(Color(255,255,255,135));
|
||||
}
|
||||
|
||||
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_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_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_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_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 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)
|
||||
{
|
||||
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 );
|
||||
gEngfuncs.pfnConsolePrint( msg );
|
||||
}
|
||||
|
||||
// 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" );
|
||||
}
|
||||
}
|
||||
else if( entindex == -2 )
|
||||
{
|
||||
m_bServerAcked = !!bTalking;
|
||||
}
|
||||
else 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(pLabel = GetFreeVoiceLabel())
|
||||
{
|
||||
// Get the name from the engine.
|
||||
hud_player_info_t info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
GetPlayerInfo(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( 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 long serverBanMask = 0;
|
||||
unsigned long banMask = 0;
|
||||
for(unsigned long 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 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"))
|
||||
{
|
||||
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 = 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);
|
||||
}
|
232
hlsdk/game_shared/voice_status.h
Normal file
232
hlsdk/game_shared/voice_status.h
Normal file
@ -0,0 +1,232 @@
|
||||
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef VOICE_STATUS_H
|
||||
#define VOICE_STATUS_H
|
||||
#ifdef _WIN32
|
||||
#ifndef __MINGW32__
|
||||
#pragma once
|
||||
#endif /* not __MINGW32__ */
|
||||
#endif
|
||||
|
||||
|
||||
#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
|
289
hlsdk/game_shared/voice_vgui_tweakdlg.cpp
Normal file
289
hlsdk/game_shared/voice_vgui_tweakdlg.cpp
Normal file
@ -0,0 +1,289 @@
|
||||
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#include "../cl_dll/hud.h"
|
||||
#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"
|
||||
#include "vgui_panel.h"
|
||||
#include "vgui_scrollbar.h"
|
||||
#include "vgui_slider.h"
|
||||
#include "ivoicetweak.h"
|
||||
#include "vgui_button.h"
|
||||
#include "vgui_checkbutton2.h"
|
||||
#include "vgui_helpers.h"
|
||||
|
||||
|
||||
#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);
|
||||
|
||||
// Get/set value. Values are 0-1.
|
||||
float GetValue();
|
||||
void SetValue(float val);
|
||||
|
||||
public:
|
||||
Label m_Label;
|
||||
ScrollBar m_Scroll;
|
||||
Slider m_Slider;
|
||||
};
|
||||
|
||||
|
||||
class CVoiceVGUITweakDlg : public CMenuPanel, public ICheckButton2Handler
|
||||
{
|
||||
typedef CMenuPanel BaseClass;
|
||||
|
||||
public:
|
||||
CVoiceVGUITweakDlg();
|
||||
~CVoiceVGUITweakDlg();
|
||||
|
||||
// CMenuPanel overrides.
|
||||
public:
|
||||
virtual void Open();
|
||||
virtual void Close();
|
||||
|
||||
|
||||
// ICheckButton2Handler overrides.
|
||||
public:
|
||||
|
||||
virtual void StateChanged(CCheckButton2 *pButton);
|
||||
|
||||
|
||||
|
||||
// Panel overrides.
|
||||
public:
|
||||
virtual void paintBackground();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
int m_DlgWidth;
|
||||
int m_DlgHeight;
|
||||
|
||||
Label m_Label;
|
||||
|
||||
IVoiceTweak *m_pVoiceTweak; // Engine voice tweak API.
|
||||
|
||||
TweakScroller m_MicVolume;
|
||||
TweakScroller m_SpeakerVolume;
|
||||
|
||||
CCheckButton2 m_VoiceModEnable;
|
||||
|
||||
Button m_Button_OK;
|
||||
};
|
||||
|
||||
|
||||
|
||||
bool g_bTweakDlgOpen = false;
|
||||
|
||||
bool IsTweakDlgOpen()
|
||||
{
|
||||
return g_bTweakDlgOpen;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------ //
|
||||
// Global functions.
|
||||
// ------------------------------------------------------------------------ //
|
||||
|
||||
static CVoiceVGUITweakDlg g_VoiceTweakDlg;
|
||||
CMenuPanel* GetVoiceTweakDlg()
|
||||
{
|
||||
return &g_VoiceTweakDlg;
|
||||
}
|
||||
|
||||
|
||||
class CVoiceTweakOKButton : public ActionSignal
|
||||
{
|
||||
public:
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void TweakScroller::Init(Panel *pParent, char *pText, int yPos)
|
||||
{
|
||||
int 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_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)
|
||||
{
|
||||
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("")
|
||||
{
|
||||
m_pVoiceTweak = NULL;
|
||||
m_Button_OK.addActionSignal(&g_OKButtonSignal);
|
||||
m_Label.setBgColor(255,255,255,200);
|
||||
}
|
||||
|
||||
|
||||
CVoiceVGUITweakDlg::~CVoiceVGUITweakDlg()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void CVoiceVGUITweakDlg::Open()
|
||||
{
|
||||
if(g_bTweakDlgOpen)
|
||||
return;
|
||||
|
||||
g_bTweakDlgOpen = true;
|
||||
|
||||
m_DlgWidth = ScreenWidth;
|
||||
m_DlgHeight = ScreenHeight;
|
||||
|
||||
m_pVoiceTweak = gEngfuncs.pVoiceTweak;
|
||||
|
||||
// Tell the engine to start voice tweak mode (pipe voice output right to speakers).
|
||||
m_pVoiceTweak->StartVoiceTweakMode();
|
||||
|
||||
// Set our size.
|
||||
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_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);
|
||||
|
||||
// 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);
|
||||
|
||||
// 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"));
|
||||
int labelWidth, labelHeight;
|
||||
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();
|
||||
g_bTweakDlgOpen = false;
|
||||
|
||||
BaseClass::Close();
|
||||
}
|
||||
|
||||
|
||||
void CVoiceVGUITweakDlg::paintBackground()
|
||||
{
|
||||
BaseClass::paintBackground();
|
||||
|
||||
// Draw our border.
|
||||
int 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(OtherSpeakerScale, m_SpeakerVolume.GetValue());
|
||||
}
|
||||
|
||||
|
||||
void CVoiceVGUITweakDlg::StateChanged(CCheckButton2 *pButton)
|
||||
{
|
||||
if(pButton == &m_VoiceModEnable)
|
||||
{
|
||||
if(pButton->IsChecked())
|
||||
gEngfuncs.pfnClientCmd("voice_modenable 1");
|
||||
else
|
||||
gEngfuncs.pfnClientCmd("voice_modenable 0");
|
||||
}
|
||||
}
|
||||
|
27
hlsdk/game_shared/voice_vgui_tweakdlg.h
Normal file
27
hlsdk/game_shared/voice_vgui_tweakdlg.h
Normal file
@ -0,0 +1,27 @@
|
||||
//========= Copyright <20> 1996-2002, Valve LLC, All rights reserved. ============
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================
|
||||
|
||||
#ifndef VOICE_VGUI_TWEAKDLG_H
|
||||
#define VOICE_VGUI_TWEAKDLG_H
|
||||
#ifdef _WIN32
|
||||
#ifndef __MINGW32__
|
||||
#pragma once
|
||||
#endif /* not __MINGW32__ */
|
||||
#endif
|
||||
|
||||
|
||||
class CMenuPanel;
|
||||
|
||||
|
||||
// Returns true if the tweak dialog is currently up.
|
||||
bool IsTweakDlgOpen();
|
||||
|
||||
// Returns a global instance of the tweak dialog.
|
||||
CMenuPanel* GetVoiceTweakDlg();
|
||||
|
||||
|
||||
#endif // VOICE_VGUI_TWEAKDLG_H
|
Reference in New Issue
Block a user