/*** * * Copyright (c) 1999, 2000 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. * ****/ // // menu.cpp // // generic menu handler // #include "hud.h" #include "cl_util.h" #include "parsemsg.h" #include #include #include "vgui_TeamFortressViewport.h" #define MAX_MENU_STRING 512 char g_szMenuString[MAX_MENU_STRING]; char g_szPrelocalisedMenuString[MAX_MENU_STRING]; int KB_ConvertString( char *in, char **ppout ); DECLARE_MESSAGE( m_Menu, ShowMenu ); int CHudMenu :: Init( void ) { gHUD.AddHudElem( this ); HOOK_MESSAGE( ShowMenu ); InitHUDData(); return 1; } void CHudMenu :: InitHUDData( void ) { m_fMenuDisplayed = 0; m_bitsValidSlots = 0; Reset(); } void CHudMenu :: Reset( void ) { g_szPrelocalisedMenuString[0] = 0; m_fWaitingForMore = FALSE; } int CHudMenu :: VidInit( void ) { return 1; } int CHudMenu :: Draw( float flTime ) { // check for if menu is set to disappear if ( m_flShutoffTime > 0 ) { if ( m_flShutoffTime <= gHUD.m_flTime ) { // times up, shutoff m_fMenuDisplayed = 0; m_iFlags &= ~HUD_ACTIVE; return 1; } } // don't draw the menu if the scoreboard is being shown if ( gViewPort && gViewPort->IsScoreBoardVisible() ) return 1; SCREENINFO screenInfo; screenInfo.iSize = sizeof(SCREENINFO); gEngfuncs.pfnGetScreenInfo(&screenInfo); // draw the menu, along the left-hand side of the screen // count the number of newlines int nlc = 0; int i; for ( i = 0; i < MAX_MENU_STRING && g_szMenuString[i] != '\0'; i++ ) { if ( g_szMenuString[i] == '\n' ) nlc++; } int nFontHeight = max(12, screenInfo.iCharHeight); // center it int y = (ScreenHeight / 2) - ((nlc / 2) * nFontHeight) - (3 * nFontHeight + nFontHeight / 3); // make sure it is above the say text int x = 20; i = 0; while ( i < MAX_MENU_STRING && g_szMenuString[i] != '\0' ) { gHUD.DrawHudString( x, y, 320, g_szMenuString + i, 255, 255, 255 ); y += nFontHeight; while ( i < MAX_MENU_STRING && g_szMenuString[i] != '\0' && g_szMenuString[i] != '\n' ) i++; if ( g_szMenuString[i] == '\n' ) i++; } return 1; } // selects an item from the menu void CHudMenu :: SelectMenuItem( int menu_item ) { // if menu_item is in a valid slot, send a menuselect command to the server if ( (menu_item > 0) && (m_bitsValidSlots & (1 << (menu_item-1))) ) { char szbuf[32]; sprintf( szbuf, "menuselect %d\n", menu_item ); ClientCmd( szbuf ); // remove the menu m_fMenuDisplayed = 0; m_iFlags &= ~HUD_ACTIVE; } } // Message handler for ShowMenu message // takes four values: // short: a bitfield of keys that are valid input // char : the duration, in seconds, the menu should stay up. -1 means is stays until something is chosen. // byte : a boolean, TRUE if there is more string yet to be received before displaying the menu, FALSE if it's the last string // string: menu string to display // if this message is never received, then scores will simply be the combined totals of the players. int CHudMenu :: MsgFunc_ShowMenu( const char *pszName, int iSize, void *pbuf ) { char *temp = NULL; BEGIN_READ( pbuf, iSize ); m_bitsValidSlots = READ_SHORT(); int DisplayTime = READ_CHAR(); int NeedMore = READ_BYTE(); if ( DisplayTime > 0 ) m_flShutoffTime = DisplayTime + gHUD.m_flTime; else m_flShutoffTime = -1; if ( m_bitsValidSlots ) { if ( !m_fWaitingForMore ) // this is the start of a new menu { strncpy( g_szPrelocalisedMenuString, READ_STRING(), MAX_MENU_STRING ); } else { // append to the current menu string strncat( g_szPrelocalisedMenuString, READ_STRING(), MAX_MENU_STRING - strlen(g_szPrelocalisedMenuString) ); } g_szPrelocalisedMenuString[MAX_MENU_STRING-1] = 0; // ensure null termination (strncat/strncpy does not) if ( !NeedMore ) { // we have the whole string, so we can localise it now strcpy( g_szMenuString, gHUD.m_TextMessage.BufferedLocaliseTextString( g_szPrelocalisedMenuString ) ); // Swap in characters if ( KB_ConvertString( g_szMenuString, &temp ) ) { strcpy( g_szMenuString, temp ); free( temp ); } } m_fMenuDisplayed = 1; m_iFlags |= HUD_ACTIVE; } else { m_fMenuDisplayed = 0; // no valid slots means that the menu should be turned off m_iFlags &= ~HUD_ACTIVE; } m_fWaitingForMore = NeedMore; return 1; }