hlsdk-xash3d/cl_dll/text_message.cpp

217 lines
6.0 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.
*
****/
//
// text_message.cpp
//
// implementation of CHudTextMessage class
//
// this class routes messages through titles.txt for localisation
//
#include "hud.h"
#include "cl_util.h"
#include <string.h>
#include <stdio.h>
#include "parsemsg.h"
#if USE_VGUI
#include "vgui_TeamFortressViewport.h"
#endif
2016-06-25 20:21:01 +02:00
DECLARE_MESSAGE( m_TextMessage, TextMsg )
2016-06-04 15:24:23 +02:00
2016-07-03 15:39:55 +02:00
int CHudTextMessage::Init( void )
2016-06-04 15:24:23 +02:00
{
HOOK_MESSAGE( TextMsg );
gHUD.AddHudElem( this );
Reset();
return 1;
2016-06-25 20:21:01 +02:00
}
2016-06-04 15:24:23 +02:00
// Searches through the string for any msg names (indicated by a '#')
// any found are looked up in titles.txt and the new message substituted
// the new value is pushed into dst_buffer
char *CHudTextMessage::LocaliseTextString( const char *msg, char *dst_buffer, int buffer_size )
{
char *dst = dst_buffer;
for( char *src = (char*)msg; *src != 0 && ( buffer_size - 1 ) > 0; buffer_size-- )
2016-06-04 15:24:23 +02:00
{
2016-07-03 15:39:55 +02:00
if( *src == '#' )
2016-06-04 15:24:23 +02:00
{
// cut msg name out of string
static char word_buf[255];
char *wdst = word_buf, *word_start = src;
int wordbuf_size = (int)sizeof(word_buf);
for( ++src; ( ( *src >= 'A' && *src <= 'z' ) || ( *src >= '0' && *src <= '9' ) ) && ( wordbuf_size - 1 ) > 0; wdst++, src++, wordbuf_size-- )
2016-06-04 15:24:23 +02:00
{
*wdst = *src;
}
*wdst = 0;
// lookup msg name in titles.txt
client_textmessage_t *clmsg = TextMessageGet( word_buf );
2016-07-03 15:39:55 +02:00
if( !clmsg || !( clmsg->pMessage ) )
2016-06-04 15:24:23 +02:00
{
src = word_start;
*dst = *src;
dst++, src++;
continue;
}
// copy string into message over the msg name
for( char *wsrc = (char*)clmsg->pMessage; *wsrc != 0 && ( buffer_size - 1 ) > 0; wsrc++, dst++, buffer_size-- )
2016-06-04 15:24:23 +02:00
{
*dst = *wsrc;
}
buffer_size++;
2016-06-04 15:24:23 +02:00
}
else
{
*dst = *src;
dst++, src++;
}
}
*dst = 0; // ensure null termination
2016-06-04 15:24:23 +02:00
return dst_buffer;
}
// As above, but with a local static buffer
char *CHudTextMessage::BufferedLocaliseTextString( const char *msg )
{
static char dst_buffer[1024];
2017-06-29 15:56:03 +02:00
LocaliseTextString( msg, dst_buffer, sizeof(dst_buffer) );
2016-06-04 15:24:23 +02:00
return dst_buffer;
}
// Simplified version of LocaliseTextString; assumes string is only one word
2017-06-29 15:56:03 +02:00
const char *CHudTextMessage::LookupString( const char *msg, int *msg_dest )
2016-06-04 15:24:23 +02:00
{
2016-07-03 15:39:55 +02:00
if( !msg )
2016-06-04 15:24:23 +02:00
return "";
// '#' character indicates this is a reference to a string in titles.txt, and not the string itself
2016-07-03 15:39:55 +02:00
if( msg[0] == '#' )
2016-06-04 15:24:23 +02:00
{
// this is a message name, so look up the real message
2016-07-03 15:39:55 +02:00
client_textmessage_t *clmsg = TextMessageGet( msg + 1 );
2016-06-04 15:24:23 +02:00
2016-07-03 15:39:55 +02:00
if( !clmsg || !(clmsg->pMessage) )
2017-06-29 15:56:03 +02:00
return msg; // lookup failed, so return the original string
2016-07-03 15:39:55 +02:00
if( msg_dest )
2016-06-04 15:24:23 +02:00
{
// check to see if titles.txt info overrides msg destination
// if clmsg->effect is less than 0, then clmsg->effect holds -1 * message_destination
2016-07-03 15:39:55 +02:00
if( clmsg->effect < 0 ) //
2016-06-04 15:24:23 +02:00
*msg_dest = -clmsg->effect;
}
2017-06-29 15:56:03 +02:00
return clmsg->pMessage;
2016-06-04 15:24:23 +02:00
}
else
2016-07-03 15:39:55 +02:00
{
// nothing special about this message, so just return the same string
2017-06-29 15:56:03 +02:00
return msg;
2016-06-04 15:24:23 +02:00
}
}
void StripEndNewlineFromString( char *str )
{
int s = strlen( str ) - 1;
2016-07-03 15:39:55 +02:00
if( str[s] == '\n' || str[s] == '\r' )
2016-06-04 15:24:23 +02:00
str[s] = 0;
}
// converts all '\r' characters to '\n', so that the engine can deal with the properly
// returns a pointer to str
char* ConvertCRtoNL( char *str )
{
2016-07-03 15:39:55 +02:00
for( char *ch = str; *ch != 0; ch++ )
if( *ch == '\r' )
2016-06-04 15:24:23 +02:00
*ch = '\n';
return str;
}
// Message handler for text messages
// displays a string, looking them up from the titles.txt file, which can be localised
// parameters:
// byte: message direction ( HUD_PRINTCONSOLE, HUD_PRINTNOTIFY, HUD_PRINTCENTER, HUD_PRINTTALK )
// string: message
// optional parameters:
// string: message parameter 1
// string: message parameter 2
// string: message parameter 3
// string: message parameter 4
// any string that starts with the character '#' is a message name, and is used to look up the real message in titles.txt
// the next (optional) one to four strings are parameters for that string (which can also be message names if they begin with '#')
int CHudTextMessage::MsgFunc_TextMsg( const char *pszName, int iSize, void *pbuf )
{
BEGIN_READ( pbuf, iSize );
int msg_dest = READ_BYTE();
2017-07-20 21:00:38 +02:00
#define MSG_BUF_SIZE 128
char szBuf[6][MSG_BUF_SIZE];
strncpy( szBuf[0], LookupString( READ_STRING(), &msg_dest ), MSG_BUF_SIZE - 1 );
szBuf[0][MSG_BUF_SIZE - 1] = '\0';
for( int i = 1; i <= 4; i++ )
{
// keep reading strings and using C format strings for subsituting the strings into the localised text string
strncpy( szBuf[i], LookupString( READ_STRING() ), MSG_BUF_SIZE - 1 );
szBuf[i][MSG_BUF_SIZE - 1] = '\0';
StripEndNewlineFromString( szBuf[i] ); // these strings are meant for subsitution into the main strings, so cull the automatic end newlines
}
2016-06-04 15:24:23 +02:00
char *psz = szBuf[5];
#if USE_VGUI
if( gViewPort && gViewPort->AllowedToPrintText() == FALSE )
return 1;
#endif
2016-07-03 15:39:55 +02:00
switch( msg_dest )
2016-06-04 15:24:23 +02:00
{
case HUD_PRINTCENTER:
_snprintf( psz, MSG_BUF_SIZE, szBuf[0], szBuf[1], szBuf[2], szBuf[3], szBuf[4] );
2020-04-01 10:14:14 +02:00
psz[MSG_BUF_SIZE - 1] = '\0';
2016-06-04 15:24:23 +02:00
CenterPrint( ConvertCRtoNL( psz ) );
break;
case HUD_PRINTNOTIFY:
psz[0] = 1; // mark this message to go into the notify buffer
_snprintf( psz + 1, MSG_BUF_SIZE - 1, szBuf[0], szBuf[1], szBuf[2], szBuf[3], szBuf[4] );
2020-04-01 10:14:14 +02:00
psz[MSG_BUF_SIZE - 2] = '\0';
2016-06-04 15:24:23 +02:00
ConsolePrint( ConvertCRtoNL( psz ) );
break;
case HUD_PRINTTALK:
_snprintf( psz, MSG_BUF_SIZE, szBuf[0], szBuf[1], szBuf[2], szBuf[3], szBuf[4] );
2020-04-01 10:14:14 +02:00
psz[MSG_BUF_SIZE - 1] = '\0';
2017-07-20 21:00:38 +02:00
gHUD.m_SayText.SayTextPrint( ConvertCRtoNL( psz ), MSG_BUF_SIZE );
2016-06-04 15:24:23 +02:00
break;
case HUD_PRINTCONSOLE:
_snprintf( psz, MSG_BUF_SIZE, szBuf[0], szBuf[1], szBuf[2], szBuf[3], szBuf[4] );
2020-04-01 10:14:14 +02:00
psz[MSG_BUF_SIZE - 1] = '\0';
2016-06-04 15:24:23 +02:00
ConsolePrint( ConvertCRtoNL( psz ) );
break;
}
return 1;
}