hlsdk-xash3d/cl_dll/statusbar.cpp

266 lines
6.9 KiB
C++
Raw Permalink Normal View History

2016-06-04 15:24:23 +02:00
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
//
// statusbar.cpp
//
// generic text status bar, set by game dll
// runs across bottom of screen
//
#include "hud.h"
#include "cl_util.h"
#include "parsemsg.h"
#include <string.h>
#include <stdio.h>
2016-06-25 20:21:01 +02:00
DECLARE_MESSAGE( m_StatusBar, StatusText )
DECLARE_MESSAGE( m_StatusBar, StatusValue )
2016-06-04 15:24:23 +02:00
#define STATUSBAR_ID_LINE 1
float *GetClientColor( int clientIndex );
extern float g_ColorYellow[3];
2016-07-03 15:39:55 +02:00
int CHudStatusBar::Init( void )
2016-06-04 15:24:23 +02:00
{
gHUD.AddHudElem( this );
HOOK_MESSAGE( StatusText );
HOOK_MESSAGE( StatusValue );
Reset();
CVAR_CREATE( "hud_centerid", "0", FCVAR_ARCHIVE );
return 1;
}
2016-07-03 15:39:55 +02:00
int CHudStatusBar::VidInit( void )
2016-06-04 15:24:23 +02:00
{
// Load sprites here
return 1;
}
2016-07-03 15:39:55 +02:00
void CHudStatusBar::Reset( void )
2016-06-04 15:24:23 +02:00
{
int i = 0;
m_iFlags &= ~HUD_ACTIVE; // start out inactive
2016-07-03 15:39:55 +02:00
for( i = 0; i < MAX_STATUSBAR_LINES; i++ )
2016-06-04 15:24:23 +02:00
m_szStatusText[i][0] = 0;
memset( m_iStatusValues, 0, sizeof m_iStatusValues );
m_iStatusValues[0] = 1; // 0 is the special index, which always returns true
// reset our colors for the status bar lines (yellow is default)
for ( i = 0; i < MAX_STATUSBAR_LINES; i++ )
m_pflNameColors[i] = g_ColorYellow;
}
2016-07-03 15:39:55 +02:00
void CHudStatusBar::ParseStatusString( int line_num )
2016-06-04 15:24:23 +02:00
{
// localise string first
2016-08-02 13:59:22 +02:00
char szBuffer[MAX_STATUSTEXT_LENGTH] = {0};
2016-06-04 15:24:23 +02:00
gHUD.m_TextMessage.LocaliseTextString( m_szStatusText[line_num], szBuffer, MAX_STATUSTEXT_LENGTH );
// parse m_szStatusText & m_iStatusValues into m_szStatusBar
memset( m_szStatusBar[line_num], 0, MAX_STATUSTEXT_LENGTH );
char *src = szBuffer;
char *dst = m_szStatusBar[line_num];
char *src_start = src, *dst_start = dst;
2016-07-03 15:39:55 +02:00
while( *src != 0 )
2016-06-04 15:24:23 +02:00
{
2016-07-03 15:39:55 +02:00
while( *src == '\n' )
2016-06-04 15:24:23 +02:00
src++; // skip over any newlines
2016-07-03 15:39:55 +02:00
if( ( ( src - src_start ) >= MAX_STATUSTEXT_LENGTH ) || ( ( dst - dst_start ) >= MAX_STATUSTEXT_LENGTH ) )
2016-06-04 15:24:23 +02:00
break;
int index = atoi( src );
// should we draw this line?
2016-07-03 15:39:55 +02:00
if( ( index >= 0 && index < MAX_STATUSBAR_VALUES ) && ( m_iStatusValues[index] != 0 ) )
{
// parse this line and append result to the status bar
2016-06-04 15:24:23 +02:00
while ( *src >= '0' && *src <= '9' )
src++;
2016-07-03 15:39:55 +02:00
if( *src == '\n' || *src == 0 )
2016-06-04 15:24:23 +02:00
continue; // no more left in this text line
// copy the text, char by char, until we hit a % or a \n
2016-07-03 15:39:55 +02:00
while( *src != '\n' && *src != 0 )
2016-06-04 15:24:23 +02:00
{
2016-07-03 15:39:55 +02:00
if( *src != '%' )
{
// just copy the character
2016-06-04 15:24:23 +02:00
*dst = *src;
dst++, src++;
}
else
{
// get the descriptor
char valtype = *(++src); // move over %
// if it's a %, draw a % sign
if ( valtype == '%' )
{
*dst = valtype;
dst++, src++;
continue;
}
// move over descriptor, then get and move over the index
index = atoi( ++src );
2016-07-03 15:39:55 +02:00
while( *src >= '0' && *src <= '9' )
2016-06-04 15:24:23 +02:00
src++;
2016-07-03 15:39:55 +02:00
if( index >= 0 && index < MAX_STATUSBAR_VALUES )
2016-06-04 15:24:23 +02:00
{
int indexval = m_iStatusValues[index];
// get the string to substitute in place of the %XX
char szRepString[MAX_PLAYER_NAME_LENGTH];
2016-07-03 15:39:55 +02:00
switch( valtype )
2016-06-04 15:24:23 +02:00
{
case 'p': // player name
GetPlayerInfo( indexval, &g_PlayerInfoList[indexval] );
2016-07-03 15:39:55 +02:00
if( g_PlayerInfoList[indexval].name != NULL )
2016-06-04 15:24:23 +02:00
{
2022-11-14 04:47:47 +01:00
strncpy( szRepString, g_PlayerInfoList[indexval].name, MAX_PLAYER_NAME_LENGTH - 1 );
szRepString[MAX_PLAYER_NAME_LENGTH - 1] = '\0';
2016-06-04 15:24:23 +02:00
m_pflNameColors[line_num] = GetClientColor( indexval );
}
else
{
strcpy( szRepString, "******" );
}
break;
case 'i': // number
sprintf( szRepString, "%d", indexval );
break;
default:
szRepString[0] = 0;
}
2016-07-03 15:39:55 +02:00
for( char *cp = szRepString; *cp != 0 && ( ( dst - dst_start ) < MAX_STATUSTEXT_LENGTH ); cp++, dst++ )
2016-06-04 15:24:23 +02:00
*dst = *cp;
}
}
}
}
else
{
// skip to next line of text
2016-07-03 15:39:55 +02:00
while( *src != 0 && *src != '\n' )
2016-06-04 15:24:23 +02:00
src++;
}
}
}
2016-07-03 15:39:55 +02:00
int CHudStatusBar::Draw( float fTime )
2016-06-04 15:24:23 +02:00
{
2016-07-03 15:39:55 +02:00
if( m_bReparseString )
2016-06-04 15:24:23 +02:00
{
2016-07-03 15:39:55 +02:00
for( int i = 0; i < MAX_STATUSBAR_LINES; i++ )
2016-06-04 15:24:23 +02:00
{
m_pflNameColors[i] = g_ColorYellow;
ParseStatusString( i );
}
m_bReparseString = FALSE;
}
2016-07-03 15:39:55 +02:00
int Y_START = ScreenHeight - YRES( 32 + 4 );
2016-06-04 15:24:23 +02:00
// Draw the status bar lines
2016-07-03 15:39:55 +02:00
for( int i = 0; i < MAX_STATUSBAR_LINES; i++ )
2016-06-04 15:24:23 +02:00
{
int TextHeight, TextWidth;
GetConsoleStringSize( m_szStatusBar[i], &TextWidth, &TextHeight );
int x = 4;
int y = Y_START - ( 4 + TextHeight * i ); // draw along bottom of screen
// let user set status ID bar centering
2016-07-03 15:39:55 +02:00
if( ( i == STATUSBAR_ID_LINE ) && CVAR_GET_FLOAT( "hud_centerid" ) )
2016-06-04 15:24:23 +02:00
{
2019-08-11 23:25:50 +02:00
x = Q_max( 0, Q_max( 2, ( ScreenWidth - TextWidth ) ) / 2 );
2016-07-03 15:39:55 +02:00
y = ( ScreenHeight / 2 ) + ( TextHeight * CVAR_GET_FLOAT( "hud_centerid" ) );
2016-06-04 15:24:23 +02:00
}
2016-07-03 15:39:55 +02:00
if( m_pflNameColors[i] )
2016-06-04 15:24:23 +02:00
DrawSetTextColor( m_pflNameColors[i][0], m_pflNameColors[i][1], m_pflNameColors[i][2] );
DrawConsoleString( x, y, m_szStatusBar[i] );
}
return 1;
}
// Message handler for StatusText message
// accepts two values:
// byte: line number of status bar text
// string: status bar text
// this string describes how the status bar should be drawn
// a semi-regular expression:
// ( slotnum ([a..z] [%pX] [%iX])*)*
// where slotnum is an index into the Value table (see below)
// if slotnum is 0, the string is always drawn
// if StatusValue[slotnum] != 0, the following string is drawn, upto the next newline - otherwise the text is skipped upto next newline
// %pX, where X is an integer, will substitute a player name here, getting the player index from StatusValue[X]
// %iX, where X is an integer, will substitute a number here, getting the number from StatusValue[X]
2016-07-03 15:39:55 +02:00
int CHudStatusBar::MsgFunc_StatusText( const char *pszName, int iSize, void *pbuf )
2016-06-04 15:24:23 +02:00
{
BEGIN_READ( pbuf, iSize );
int line = READ_BYTE();
2016-07-03 15:39:55 +02:00
if( line < 0 || line >= MAX_STATUSBAR_LINES )
2016-06-04 15:24:23 +02:00
return 1;
2022-11-14 04:47:47 +01:00
strncpy( m_szStatusText[line], READ_STRING(), MAX_STATUSTEXT_LENGTH - 1 );
2016-07-03 15:39:55 +02:00
m_szStatusText[line][MAX_STATUSTEXT_LENGTH - 1] = 0; // ensure it's null terminated ( strncpy() won't null terminate if read string too long)
2016-06-04 15:24:23 +02:00
2016-07-03 15:39:55 +02:00
if( m_szStatusText[0] == 0 )
2016-06-04 15:24:23 +02:00
m_iFlags &= ~HUD_ACTIVE;
else
m_iFlags |= HUD_ACTIVE; // we have status text, so turn on the status bar
m_bReparseString = TRUE;
return 1;
}
// Message handler for StatusText message
// accepts two values:
// byte: index into the status value array
// short: value to store
2016-07-03 15:39:55 +02:00
int CHudStatusBar::MsgFunc_StatusValue( const char *pszName, int iSize, void *pbuf )
2016-06-04 15:24:23 +02:00
{
BEGIN_READ( pbuf, iSize );
int index = READ_BYTE();
2016-07-03 15:39:55 +02:00
if( index < 1 || index >= MAX_STATUSBAR_VALUES )
2016-06-04 15:24:23 +02:00
return 1; // index out of range
m_iStatusValues[index] = READ_SHORT();
m_bReparseString = TRUE;
2016-07-03 15:39:55 +02:00
2016-06-04 15:24:23 +02:00
return 1;
}