Skip to content

Commit 723d7f7

Browse files
committed
client: updated menu.cpp to current hlsdk-portable state
1 parent 1a1ef30 commit 723d7f7

File tree

1 file changed

+143
-55
lines changed

1 file changed

+143
-55
lines changed

client/menu.cpp

Lines changed: 143 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
/***
22
*
33
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
4-
*
5-
* This product contains software technology licensed from Id
6-
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
4+
*
5+
* This product contains software technology licensed from Id
6+
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
77
* All Rights Reserved.
88
*
99
* Use, distribution, and modification of this source code and/or resulting
@@ -17,53 +17,122 @@
1717
//
1818
// generic menu handler
1919
//
20+
2021
#include "hud.h"
2122
#include "utils.h"
2223
#include "parsemsg.h"
24+
#include <string.h>
25+
#include <stdio.h>
2326

2427
#define MAX_MENU_STRING 512
25-
2628
char g_szMenuString[MAX_MENU_STRING];
2729
char g_szPrelocalisedMenuString[MAX_MENU_STRING];
2830

29-
DECLARE_MESSAGE( m_Menu, ShowMenu );
31+
int KB_ConvertString(char *in, char **ppout);
3032

31-
int CHudMenu :: Init( void )
33+
DECLARE_MESSAGE(m_Menu, ShowMenu)
34+
35+
int CHudMenu::Init(void)
3236
{
33-
gHUD.AddHudElem( this );
37+
gHUD.AddHudElem(this);
3438

35-
HOOK_MESSAGE( ShowMenu );
39+
HOOK_MESSAGE(ShowMenu);
3640

3741
InitHUDData();
3842

3943
return 1;
4044
}
4145

42-
void CHudMenu :: InitHUDData( void )
46+
void CHudMenu::InitHUDData(void)
4347
{
4448
m_fMenuDisplayed = 0;
4549
m_bitsValidSlots = 0;
50+
m_iFlags &= ~HUD_ACTIVE;
4651
Reset();
4752
}
4853

49-
void CHudMenu :: Reset( void )
54+
void CHudMenu::Reset(void)
5055
{
5156
g_szPrelocalisedMenuString[0] = 0;
5257
m_fWaitingForMore = FALSE;
5358
}
5459

55-
int CHudMenu :: VidInit( void )
60+
int CHudMenu::VidInit(void)
5661
{
5762
return 1;
5863
}
5964

60-
int CHudMenu :: Draw( float flTime )
65+
/*
66+
=================================
67+
ParseEscapeToken
68+
69+
Interprets the given escape token (backslash followed by a letter). The
70+
first character of the token must be a backslash. The second character
71+
specifies the operation to perform:
72+
73+
\w : White text (this is the default)
74+
\d : Dim (gray) text
75+
\y : Yellow text
76+
\r : Red text
77+
\R : Right-align (just for the remainder of the current line)
78+
=================================
79+
*/
80+
81+
static int menu_r, menu_g, menu_b, menu_x, menu_ralign;
82+
83+
static inline const char* ParseEscapeToken(const char* token)
84+
{
85+
if (*token != '\\')
86+
return token;
87+
88+
token++;
89+
90+
switch (*token)
91+
{
92+
case '\0':
93+
return token;
94+
95+
case 'w':
96+
menu_r = 255;
97+
menu_g = 255;
98+
menu_b = 255;
99+
break;
100+
101+
case 'd':
102+
menu_r = 100;
103+
menu_g = 100;
104+
menu_b = 100;
105+
break;
106+
107+
case 'y':
108+
menu_r = 255;
109+
menu_g = 210;
110+
menu_b = 64;
111+
break;
112+
113+
case 'r':
114+
menu_r = 210;
115+
menu_g = 24;
116+
menu_b = 0;
117+
break;
118+
119+
case 'R':
120+
menu_x = ScreenWidth / 2;
121+
menu_ralign = TRUE;
122+
break;
123+
}
124+
125+
return ++token;
126+
}
127+
128+
int CHudMenu::Draw(float flTime)
61129
{
62130
int i;
131+
63132
// check for if menu is set to disappear
64-
if( m_flShutoffTime > 0 )
133+
if (m_flShutoffTime > 0)
65134
{
66-
if( m_flShutoffTime <= gHUD.m_flTime )
135+
if (m_flShutoffTime <= gHUD.m_flTime)
67136
{
68137
// times up, shutoff
69138
m_fMenuDisplayed = 0;
@@ -76,99 +145,119 @@ int CHudMenu :: Draw( float flTime )
76145
if( gHUD.m_Scoreboard.m_iShowscoresHeld )
77146
return 1;
78147

79-
// draw the menu, along the left-hand side of the screen
148+
SCREENINFO screenInfo;
149+
150+
screenInfo.iSize = sizeof(SCREENINFO);
151+
gEngfuncs.pfnGetScreenInfo(&screenInfo);
80152

153+
// draw the menu, along the left-hand side of the screen
81154
// count the number of newlines
82155
int nlc = 0;
83-
for( i = 0; i < MAX_MENU_STRING && g_szMenuString[i] != '\0'; i++ )
84-
{
85-
if( g_szMenuString[i] == '\n' )
156+
for (i = 0; i < MAX_MENU_STRING && g_szMenuString[i] != '\0'; i++)
157+
if (g_szMenuString[i] == '\n')
86158
nlc++;
87-
}
159+
160+
int nFontHeight = Q_max(12, screenInfo.iCharHeight);
88161

89162
// center it
90-
int y = (ScreenHeight / 2) - ((nlc / 2) * 12) - 40; // make sure it is above the say text
91-
int x = 20;
163+
int y = (ScreenHeight / 2) - ((nlc / 2) * nFontHeight) - (3 * nFontHeight + nFontHeight / 3); // make sure it is above the say text
92164

93-
i = 0;
94-
while( i < MAX_MENU_STRING && g_szMenuString[i] != '\0' )
95-
{
96-
gHUD.DrawHudString( x, y, 320, g_szMenuString + i, 255, 255, 255 );
97-
y += 12;
165+
menu_r = 255;
166+
menu_g = 255;
167+
menu_b = 255;
168+
menu_x = 20;
169+
menu_ralign = FALSE;
98170

99-
while( i < MAX_MENU_STRING && g_szMenuString[i] != '\0' && g_szMenuString[i] != '\n' )
100-
i++;
171+
const char* sptr = g_szMenuString;
101172

102-
if( g_szMenuString[i] == '\n' )
103-
i++;
173+
while (*sptr != '\0')
174+
{
175+
if (*sptr == '\\')
176+
sptr = ParseEscapeToken(sptr);
177+
else if (*sptr == '\n')
178+
{
179+
menu_ralign = FALSE;
180+
menu_x = 20;
181+
y += nFontHeight;
182+
sptr++;
183+
}
184+
else
185+
{
186+
char menubuf[80] = "";
187+
const char *ptr = sptr;
188+
while (*sptr != '\0' && *sptr != '\n' && *sptr != '\\')
189+
sptr++;
190+
strlcpy(menubuf, ptr, Q_min((sptr - ptr + 1), (int)sizeof(menubuf)));
191+
if (menu_ralign)
192+
// IMPORTANT: Right-to-left rendered text does not parse escape tokens!
193+
menu_x = gHUD.DrawHudStringReverse(menu_x, y, 0, menubuf, menu_r, menu_g, menu_b);
194+
else menu_x = gHUD.DrawHudString(menu_x, y, 320, menubuf, menu_r, menu_g, menu_b);
195+
}
104196
}
105-
197+
106198
return 1;
107199
}
108200

109201
// selects an item from the menu
110-
void CHudMenu :: SelectMenuItem( int menu_item )
202+
void CHudMenu::SelectMenuItem(int menu_item)
111203
{
112204
// if menu_item is in a valid slot, send a menuselect command to the server
113-
if(( menu_item > 0 ) && ( m_bitsValidSlots & (1 << ( menu_item - 1 ))))
205+
if ((menu_item > 0) && (m_bitsValidSlots & (1 << (menu_item - 1))))
114206
{
115207
char szbuf[32];
116-
sprintf( szbuf, "menuselect %d\n", menu_item );
117-
ClientCmd( szbuf );
208+
sprintf(szbuf, "menuselect %d\n", menu_item);
209+
ClientCmd(szbuf);
118210

119211
// remove the menu
120212
m_fMenuDisplayed = 0;
121213
m_iFlags &= ~HUD_ACTIVE;
122214
}
123215
}
124216

125-
126217
// Message handler for ShowMenu message
127218
// takes four values:
128-
// short: a bitfield of keys that are valid input
129-
// char : the duration, in seconds, the menu should stay up. -1 means is stays until something is chosen.
130-
// byte : a boolean, TRUE if there is more string yet to be received before displaying the menu, FALSE if it's the last string
131-
// string: menu string to display
219+
// short: a bitfield of keys that are valid input
220+
// char : the duration, in seconds, the menu should stay up. -1 means is stays until something is chosen.
221+
// byte : a boolean, TRUE if there is more string yet to be received before displaying the menu, FALSE if it's the last string
222+
// string: menu string to display
132223
// if this message is never received, then scores will simply be the combined totals of the players.
133-
int CHudMenu :: MsgFunc_ShowMenu( const char *pszName, int iSize, void *pbuf )
224+
int CHudMenu::MsgFunc_ShowMenu(const char *pszName, int iSize, void *pbuf)
134225
{
135226
char *temp = NULL;
136227

137-
BEGIN_READ( pszName, pbuf, iSize );
228+
BEGIN_READ(pszName, pbuf, iSize);
138229

139230
m_bitsValidSlots = READ_SHORT();
140231
int DisplayTime = READ_CHAR();
141232
int NeedMore = READ_BYTE();
142233

143-
if( DisplayTime > 0 )
234+
if (DisplayTime > 0)
144235
m_flShutoffTime = DisplayTime + gHUD.m_flTime;
145236
else
146237
m_flShutoffTime = -1;
147238

148-
if( m_bitsValidSlots )
239+
if (m_bitsValidSlots)
149240
{
150-
if( !m_fWaitingForMore )
241+
if (!m_fWaitingForMore) // this is the start of a new menu
151242
{
152-
// this is the start of a new menu
153-
Q_strncpy( g_szPrelocalisedMenuString, READ_STRING(), MAX_MENU_STRING );
243+
strlcpy(g_szPrelocalisedMenuString, READ_STRING(), MAX_MENU_STRING);
154244
}
155245
else
156246
{
157247
// append to the current menu string
158-
Q_strncat( g_szPrelocalisedMenuString, READ_STRING(), MAX_MENU_STRING - Q_strlen( g_szPrelocalisedMenuString ));
248+
strlcat(g_szPrelocalisedMenuString, READ_STRING(), MAX_MENU_STRING);
159249
}
160-
g_szPrelocalisedMenuString[MAX_MENU_STRING-1] = 0; // ensure null termination (strncat/strncpy does not)
161250

162-
if( !NeedMore )
251+
if (!NeedMore)
163252
{
164253
// we have the whole string, so we can localise it now
165-
Q_strcpy( g_szMenuString, gHUD.m_TextMessage.BufferedLocaliseTextString( g_szPrelocalisedMenuString ));
254+
strlcpy(g_szMenuString, gHUD.m_TextMessage.BufferedLocaliseTextString(g_szPrelocalisedMenuString), MAX_MENU_STRING);
166255

167256
// Swap in characters
168-
if( KB_ConvertString( g_szMenuString, &temp ))
257+
if (KB_ConvertString(g_szMenuString, &temp))
169258
{
170-
Q_strcpy( g_szMenuString, temp );
171-
free( temp );
259+
strlcpy(g_szMenuString, temp, MAX_MENU_STRING);
260+
free(temp);
172261
}
173262
}
174263

@@ -187,4 +276,3 @@ int CHudMenu :: MsgFunc_ShowMenu( const char *pszName, int iSize, void *pbuf )
187276

188277
return 1;
189278
}
190-

0 commit comments

Comments
 (0)