📄 hud_numeric.cpp
字号:
}
surface()->DrawSetTextPos( xnext, y );
// Paint from 0.5 to frac of next char
if ( surface()->DrawGetUnicodeCharRenderInfo( nextchar, info ) )
{
// Shift tex coord and y position half way up glyph
vgui::Vertex_t save[2];
save[0] = info.verts[0];
save[1] = info.verts[1];
info.verts[0].m_Position.y = Lerp( 0.5f, save[0].m_Position.y, save[1].m_Position.y );
info.verts[0].m_TexCoord.y = Lerp( 0.5f, save[0].m_TexCoord.y, save[1].m_TexCoord.y );
info.verts[1].m_Position.y = Lerp( frac, save[0].m_Position.y, save[1].m_Position.y );
//info.verts[1].m_TexCoord.y = Lerp( frac, save[0].m_TexCoord.y, save[1].m_TexCoord.y );
surface()->DrawRenderCharFromInfo( info );
}
}
x += cellwidth;
surface()->DrawSetTextPos( x, y );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *prev -
// *next -
// Output : float
//-----------------------------------------------------------------------------
float CHudNumeric::MaxCharacterDiff( const char *prev, const char *next )
{
float maxdiff = 0.0f;
int textlen = Q_strlen( next );
int prevlen = Q_strlen( prev );
int ch;
for ( ch = 0; ch < textlen; ch++ )
{
int charfromend = textlen - ch;
char c = next[ ch ];
char prevc = prev[ max( 0, prevlen - charfromend ) ];
if ( prevc == 0 )
{
int tempindex = FindPrintableIndex( c );
if ( tempindex != m_Printables.InvalidIndex() )
{
tempindex = max( 0, tempindex - 3 );
prevc = m_Printables[ tempindex ];
}
else
{
prevc = c;
}
}
float diff = (float)fabs( FindPrintableIndex( c ) - FindPrintableIndex( prevc ) );
if ( diff > maxdiff )
{
maxdiff = diff;
}
}
float maxdelta = maxdiff;
if ( m_nRotaryMaxDelta != 0 )
{
maxdelta = min( (float)m_nRotaryMaxDelta, maxdelta );
}
return maxdelta;
}
int CHudNumeric::ComputePixelsRequired( vgui::HFont& font, const char *text, int textlen )
{
int pixels = 0;
for ( int ch = 0; ch < textlen; ch++ )
{
char c = text[ ch ];
pixels += surface()->GetCharacterWidth( font, c );
}
return pixels;
}
void CHudNumeric::DrawCharacterBackground( const char *text, int textlen, HFont& font, int x, int y )
{
int abcA, abcB, abcC;
int fontTall = surface()->GetFontTall( font );
int ch;
int curx = x - ComputePixelsRequired( font, text, textlen );
for ( ch = 0; ch < textlen; ch++ )
{
char c = text[ ch ];
surface()->GetCharABCwide( font, c, abcA, abcB, abcC );
curx += abcA;
surface()->DrawSetColor( m_CharBg );
surface()->DrawFilledRect( curx - abcA, y + 2, curx + abcB + abcC, y + fontTall - 2 );
if ( m_bDrawCharacterBackgroundBorder )
{
surface()->DrawSetColor( m_CharBgBorder );
surface()->DrawOutlinedRect( curx - abcA, y + 2, curx + abcB + abcC, y + fontTall - 2 );
}
curx += ( abcB + abcC );
}
}
void CHudNumeric::DrawCharacterForeground( const char *text, int textlen, HFont& font, int x, int y )
{
if ( m_nRotaryEffect == ROTARY_EFFECT_NONE ||
m_nRotaryEffect == ROTARY_EFFECT_SPEEDOMETER )
return;
int abcA, abcB, abcC;
int fontTall = surface()->GetFontTall( font );
int ch;
int curx = x - ComputePixelsRequired( font, text, textlen );
for ( ch = 0; ch < textlen; ch++ )
{
char c = text[ ch ];
surface()->GetCharABCwide( font, c, abcA, abcB, abcC );
curx += abcA;
switch ( m_nRotaryEffect )
{
default:
case ROTARY_EFFECT_VERTICAL_ALARM:
{
surface()->DrawSetColor( m_CharFg );
surface()->DrawLine( curx - abcA + 1, y + fontTall / 2, curx + abcB + abcC - 1, y + fontTall / 2 );
}
break;
case ROTARY_EFFECT_HORIZONTAL_ALARM:
{
surface()->DrawSetColor( m_CharFg );
int avex = curx + ( - abcA + abcB + abcC ) / 2;
surface()->DrawLine( avex, y + 2, avex, y + fontTall - 2 );
}
break;
}
curx += ( abcB + abcC );
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *text -
// textlen -
// font -
// x -
// y -
//-----------------------------------------------------------------------------
void CHudNumeric::PaintStringRotary( float t, const char *text, int textlen, HFont& font, int x, int y )
{
surface()->DrawSetTextFont( font );
int ch;
int prevlen = Q_strlen( m_szLatchedValue );
// Compute pixels actually required
int pixels = 0;
for ( ch = 0; ch < textlen; ch++ )
{
int charfromend = textlen - ch;
char c = text[ ch ];
char prevc = m_szLatchedValue[ max( 0, prevlen - charfromend ) ];
if ( prevc == 0 )
{
int tempindex = FindPrintableIndex( c );
if ( tempindex != m_Printables.InvalidIndex() )
{
tempindex = max( 0, tempindex - 3 );
prevc = m_Printables[ tempindex ];
}
else
{
prevc = c;
}
}
float diff = (float)fabs( FindPrintableIndex( c ) - FindPrintableIndex( prevc ) );
if ( m_nRotaryMaxDelta != 0 )
{
diff = min( (float)m_nRotaryMaxDelta, diff );
}
float dt = diff / m_flActualCharactersPerSecond;
float frac = 1.0f;
if ( dt > 0.0f )
{
frac = t / min( dt, m_flRotaryTime );
}
frac = clamp( frac, 0.0f, 1.0f );
float s;
char chstart, chend;
GetRotatedChar( frac, prevc, c, chstart, chend, s );
int w0 = surface()->GetCharacterWidth( font, chstart );
int w1 = surface()->GetCharacterWidth( font, chend );
pixels += max( w0, w1 );
}
surface()->DrawSetTextPos( x - pixels, y );
// Now render
for ( ch = 0; ch < textlen; ch++ )
{
int charfromend = textlen - ch;
char c = text[ ch ];
char prevc = m_szLatchedValue[ max( 0, prevlen - charfromend ) ];
if ( prevc == 0 )
{
int tempindex = FindPrintableIndex( c );
if ( tempindex != m_Printables.InvalidIndex() )
{
tempindex = max( 0, tempindex - 3 );
prevc = m_Printables[ tempindex ];
}
else
{
prevc = c;
}
}
float diff = (float)fabs( FindPrintableIndex( c ) - FindPrintableIndex( prevc ) );
if ( m_nRotaryMaxDelta != 0 )
{
diff = min( (float)m_nRotaryMaxDelta, diff );
}
float dt = diff / m_flActualCharactersPerSecond;
float frac = 1.0f;
if ( dt > 0.0f )
{
frac = t / min( dt, m_flRotaryTime );
}
frac = clamp( frac, 0.0f, 1.0f );
float s;
char chstart, chend;
GetRotatedChar( frac, prevc, c, chstart, chend, s );
int outx, outy;
surface()->DrawGetTextPos( outx, outy );
switch ( m_nRotaryEffect )
{
default:
case ROTARY_EFFECT_VERTICAL_ALARM:
{
PaintRotatedCharacter( outx, outy, font, chstart, chend, s );
}
break;
case ROTARY_EFFECT_HORIZONTAL_ALARM:
{
PaintRotatedCharacterHoriz( outx, outy, font, chstart, chend, s );
}
break;
case ROTARY_EFFECT_SPEEDOMETER:
{
PaintRotatedCharacterSpeedomter( outx, outy, font, chstart, chend, s );
}
break;
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *text -
// textlen -
// font -
// x -
// y -
//-----------------------------------------------------------------------------
void CHudNumeric::PaintString( const char *text, int textlen, HFont& font, int x, int y )
{
if ( m_nRotaryEffect != ROTARY_EFFECT_NONE &&
IsRotating() &&
m_flRotaryTime > 0.0f )
{
float rotation_time = gpGlobals->curtime - m_flRotaryStartTime;
PaintStringRotary( rotation_time, text, textlen, font, x, y );
return;
}
PaintStringNormal( text, textlen, font, x, y );
}
void CHudNumeric::PaintStringNormal( const char *text, int textlen, vgui::HFont& font, int x, int y )
{
surface()->DrawSetTextFont( font );
int ch;
surface()->DrawSetTextPos( x - ComputePixelsRequired( font, text, textlen ), y );
for ( ch = 0; ch < textlen; ch++ )
{
char c = text[ ch ];
surface()->DrawUnicodeChar( c );
}
}
void CHudNumeric::PaintBackground( void )
{
char value[ MAX_VALUE_LENGTH ];
if ( !GetValue( value, sizeof( value ) ) )
return;
float alpha = m_flAlphaOverride / 255.0f;
Color boxColor = GetBoxColor();
boxColor[3] *= alpha;
SetBgColor( boxColor );
BaseClass::PaintBackground();
if ( !m_bUseIcon )
return;
CHudTexture *tex = m_hIcon;
if ( !tex )
return;
Color iconColor = m_IconColor;
iconColor[3] *= alpha;
tex->DrawSelf( m_flIconXPos, m_flIconYPos, m_flIconWidth, m_flIconHeight, iconColor );
}
void CHudNumeric::PaintValue( const char *value, int textlen, int wide, int tall, Color& clr )
{
float alpha = m_flAlphaOverride / 255.0f;
Color boxColor = GetBoxColor();
boxColor[3] *= alpha;
SetBgColor( boxColor );
Color useColor = clr;
useColor[3] *= alpha;
surface()->DrawSetTextColor( useColor );
int x = wide - label_xpos_right;
int y = label_ypos;
if ( m_bDrawLabel )
{
// Label
PaintStringNormal( GetLabelText(), Q_strlen( GetLabelText() ), m_hLabelFont, x, y );
}
x = wide - value_xpos_right;
y = value_ypos;
if ( m_nRotaryEffect != ROTARY_EFFECT_NONE &&
(bool)m_bDrawCharacterBackground )
{
DrawCharacterBackground( value, textlen, m_hTextFont, x, y );
}
PaintString( value, textlen, m_hTextFont, x, y );
if ( m_nRotaryEffect != ROTARY_EFFECT_NONE &&
(bool)m_bDrawCharacterForeground )
{
DrawCharacterForeground( value, textlen, m_hTextFont, x, y );
}
// draw the overbright blur
for (float fl = m_flBlur; fl > 0.0f; fl -= 1.0f)
{
if (fl >= 1.0f)
{
PaintString( value, textlen, m_hTextFontPulsing, x, y );
}
else
{
// draw a percentage of the last one
Color col = useColor;
col[3] *= fl;
surface()->DrawSetTextColor(col);
PaintString( value, textlen, m_hTextFontPulsing, x, y );
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : vgui::Color
//-----------------------------------------------------------------------------
Color CHudNumeric::GetColor()
{
return m_TextColor;
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : vgui::Color
//-----------------------------------------------------------------------------
Color CHudNumeric::GetBoxColor()
{
return m_BoxColor;
}
//-----------------------------------------------------------------------------
// Purpose: Redraw
//-----------------------------------------------------------------------------
void CHudNumeric::Paint( void )
{
char value[ MAX_VALUE_LENGTH ];
if ( !GetValue( value, sizeof( value ) ) )
return;
int w, h;
GetSize( w, h );
bool dopulse = ( Q_strcmp( value, m_szPreviousValue ) != 0 ) || ( m_bPulseForced );
bool increment = false;
if ( dopulse )
{
if ( atof( m_szPreviousValue ) <= atof( value ) )
{
increment = true;
}
Q_strncpy( m_szLatchedValue, m_szPreviousValue, sizeof( m_szLatchedValue ) );
m_nTextLen = Q_strlen( value );
m_flRotaryStartTime = gpGlobals->curtime;
float maxdiff = MaxCharacterDiff( m_szLatchedValue, value );
float timerequired = maxdiff / m_flDesiredCharactersPerSecond;
m_flActualCharactersPerSecond = (float)m_flDesiredCharactersPerSecond;
m_flRotaryTime = min( m_flRotaryTimeMax, timerequired );
if ( m_flRotaryTime < timerequired )
{
// Speed up rotation since we're moving so far
m_flActualCharactersPerSecond = ( timerequired / m_flRotaryTime ) * m_flDesiredCharactersPerSecond;
}
}
Q_strncpy( m_szPreviousValue, value, sizeof( m_szPreviousValue ) );
Color clr = GetColor();
PaintValue( value, m_nTextLen, w, h, clr );
if ( dopulse && m_bSendPulses )
{
// Start with a short pulse
g_pClientMode->GetViewportAnimationController()->StartAnimationSequence( GetPulseEvent( increment ) );
m_bPulseForced = false;
}
}
//-----------------------------------------------------------------------------
// Purpose: Derived class has forced a pulse
//-----------------------------------------------------------------------------
void CHudNumeric::ForcePulse( void )
{
m_bPulseForced = true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -