core/MenuStyle_Radio.cpp
author Asher Baker <asherkin@gmail.com>
Thu May 16 14:58:14 2013 +0100 (2013-05-16)
changeset 3920 e4fa6b583893
parent 3855 d8ba5eddf543
child 4025 542dde661d5c
permissions -rw-r--r--
Fixed copy-paste error in 116256b519b5.
dvander@780
     1
/**
dvander@780
     2
 * vim: set ts=4 :
ds@1330
     3
 * =============================================================================
dvander@1231
     4
 * SourceMod
ds@1947
     5
 * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
ds@1330
     6
 * =============================================================================
dvander@780
     7
 *
ds@1330
     8
 * This program is free software; you can redistribute it and/or modify it under
ds@1330
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
ds@1330
    10
 * Free Software Foundation.
dvander@1231
    11
 * 
ds@1330
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
ds@1330
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
ds@1330
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
ds@1330
    15
 * details.
dvander@1231
    16
 *
ds@1330
    17
 * You should have received a copy of the GNU General Public License along with
ds@1330
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
dvander@1231
    19
 *
ds@1330
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
ds@1330
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
ds@1330
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
ds@1330
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
ds@1330
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
ds@1330
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
ds@1330
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
ds@1330
    27
 * or <http://www.sourcemod.net/license.php>.
dvander@780
    28
 *
dvander@780
    29
 * Version: $Id$
dvander@780
    30
 */
dvander@780
    31
dvander@780
    32
#include "MenuStyle_Radio.h"
dvander@780
    33
#include "sm_stringutil.h"
dvander@780
    34
#include "UserMessages.h"
dvander@3010
    35
#include <IGameConfigs.h>
dvander@846
    36
#include "PlayerManager.h"
dvander@970
    37
#if defined MENU_DEBUG
dvander@970
    38
#include "Logger.h"
dvander@970
    39
#endif
dvander@3010
    40
#include "logic_bridge.h"
dvander@780
    41
skamonkey@3743
    42
#ifdef USE_PROTOBUF_USERMESSAGES
skamonkey@3743
    43
#include <google/protobuf/descriptor.h>
skamonkey@3743
    44
#endif
skamonkey@3743
    45
skamonkey@3743
    46
#if SOURCE_ENGINE == SE_CSGO
skamonkey@3743
    47
#include <game/shared/csgo/protobuf/cstrike15_usermessages.pb.h>
skamonkey@3743
    48
#endif
skamonkey@3743
    49
dvander@780
    50
extern const char *g_RadioNumTable[];
dvander@780
    51
CRadioStyle g_RadioMenuStyle;
dvander@780
    52
int g_ShowMenuId = -1;
dvander@785
    53
bool g_bRadioInit = false;
dvander@1695
    54
unsigned int g_RadioMenuTimeout = 0;
dvander@780
    55
skamonkey@3570
    56
// back, next, exit
skamonkey@3570
    57
#define MAX_PAGINATION_OPTIONS 3
skamonkey@3570
    58
skamonkey@3570
    59
#define MAX_MENUSLOT_KEYS 10
skamonkey@3570
    60
skamonkey@3570
    61
static unsigned int s_RadioMaxPageItems = MAX_MENUSLOT_KEYS;
skamonkey@3570
    62
skamonkey@3570
    63
dvander@1695
    64
CRadioStyle::CRadioStyle()
dvander@780
    65
{
dvander@1695
    66
	m_players = new CRadioMenuPlayer[256+1];
dvander@1695
    67
	for (size_t i = 0; i < 256+1; i++)
dvander@1695
    68
	{
dvander@1695
    69
		m_players[i].Radio_SetIndex(i);
dvander@1695
    70
	}
dvander@780
    71
}
dvander@780
    72
dvander@846
    73
void CRadioStyle::OnSourceModAllInitialized()
dvander@846
    74
{
dvander@846
    75
	g_Players.AddClientListener(this);
dvander@846
    76
}
dvander@846
    77
dvander@785
    78
void CRadioStyle::OnSourceModLevelChange(const char *mapName)
dvander@780
    79
{
dvander@785
    80
	if (g_bRadioInit)
dvander@785
    81
	{
dvander@785
    82
		return;
dvander@785
    83
	}
dvander@785
    84
dvander@785
    85
	g_bRadioInit = true;
dvander@780
    86
	const char *msg = g_pGameConf->GetKeyValue("HudRadioMenuMsg");
dvander@780
    87
	if (!msg || msg[0] == '\0')
dvander@780
    88
	{
dvander@780
    89
		return;
dvander@780
    90
	}
dvander@780
    91
dvander@780
    92
	g_ShowMenuId = g_UserMsgs.GetMessageIndex(msg);
dvander@780
    93
dvander@780
    94
	if (!IsSupported())
dvander@780
    95
	{
dvander@780
    96
		return;
dvander@780
    97
	}
dvander@780
    98
dvander@1695
    99
	const char *val = g_pGameConf->GetKeyValue("RadioMenuTimeout");
dvander@1695
   100
	if (val != NULL)
dvander@1695
   101
	{
dvander@1695
   102
		g_RadioMenuTimeout = atoi(val);
dvander@1695
   103
	}
dvander@1695
   104
	else
dvander@1695
   105
	{
dvander@1695
   106
		g_RadioMenuTimeout = 0;
dvander@1695
   107
	}
dvander@1695
   108
skamonkey@3570
   109
	const char *items = g_pGameConf->GetKeyValue("RadioMenuMaxPageItems");
skamonkey@3570
   110
	if (items != NULL)
skamonkey@3570
   111
	{
skamonkey@3570
   112
		int value = atoi(items);
skamonkey@3570
   113
skamonkey@3570
   114
		// Only override the mostly-safe default if it's a sane value
skamonkey@3570
   115
		if (value > MAX_PAGINATION_OPTIONS && value <= MAX_MENUSLOT_KEYS)
skamonkey@3570
   116
		{
skamonkey@3570
   117
			s_RadioMaxPageItems = value;
skamonkey@3570
   118
		}
skamonkey@3570
   119
	}
skamonkey@3570
   120
dvander@780
   121
	g_Menus.AddStyle(this);
dvander@780
   122
	g_Menus.SetDefaultStyle(this);
dvander@780
   123
dvander@780
   124
	g_UserMsgs.HookUserMessage(g_ShowMenuId, this, false);
dvander@780
   125
}
dvander@780
   126
dvander@780
   127
void CRadioStyle::OnSourceModShutdown()
dvander@780
   128
{
dvander@846
   129
	g_Players.RemoveClientListener(this);
dvander@780
   130
	g_UserMsgs.UnhookUserMessage(g_ShowMenuId, this, false);
dvander@790
   131
dvander@790
   132
	while (!m_FreeDisplays.empty())
dvander@790
   133
	{
dvander@790
   134
		delete m_FreeDisplays.front();
dvander@790
   135
		m_FreeDisplays.pop();
dvander@790
   136
	}
dvander@780
   137
}
dvander@780
   138
dvander@780
   139
bool CRadioStyle::IsSupported()
dvander@780
   140
{
skamonkey@3855
   141
#if SOURCE_ENGINE == SE_DOTA
skamonkey@3855
   142
	return false;
skamonkey@3855
   143
#else
dvander@780
   144
	return (g_ShowMenuId != -1);
skamonkey@3855
   145
#endif
dvander@780
   146
}
dvander@780
   147
faluco@1541
   148
bool CRadioStyle::OnClientCommand(int client, const char *cmdname, const CCommand &cmd)
dvander@780
   149
{
faluco@1541
   150
	if (strcmp(cmdname, "menuselect") == 0)
dvander@780
   151
	{
dvander@780
   152
		if (!m_players[client].bInMenu)
dvander@780
   153
		{
dvander@1838
   154
			m_players[client].bInExternMenu = false;
dvander@780
   155
			return false;
dvander@780
   156
		}
dvander@785
   157
faluco@1541
   158
		int arg = atoi(cmd.Arg(1));
dvander@780
   159
		ClientPressedKey(client, arg);
dvander@785
   160
		return true;
dvander@780
   161
	}
dvander@780
   162
dvander@780
   163
	return false;
dvander@780
   164
}
dvander@780
   165
dvander@780
   166
static unsigned int g_last_holdtime = 0;
dvander@780
   167
static unsigned int g_last_client_count = 0;
dvander@780
   168
static int g_last_clients[256];
dvander@780
   169
skamonkey@3743
   170
#ifdef USE_PROTOBUF_USERMESSAGES
skamonkey@3743
   171
void CRadioStyle::OnUserMessage(int msg_id, protobuf::Message &msg, IRecipientFilter *pFilter)
skamonkey@3743
   172
#else
dvander@780
   173
void CRadioStyle::OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter)
skamonkey@3743
   174
#endif
dvander@780
   175
{
skamonkey@3855
   176
#if SOURCE_ENGINE != SE_DOTA
dvander@780
   177
	int count = pFilter->GetRecipientCount();
skamonkey@3743
   178
skamonkey@3743
   179
#ifdef USE_PROTOBUF_USERMESSAGES
skamonkey@3743
   180
	int c = ((CCSUsrMsg_ShowMenu &)msg).display_time();
skamonkey@3743
   181
#else
dvander@1838
   182
	bf_read br(bf->GetBasePointer(), 3);
dvander@780
   183
dvander@780
   184
	br.ReadWord();
dvander@780
   185
	int c = br.ReadChar();
skamonkey@3743
   186
#endif
dvander@780
   187
dvander@780
   188
	g_last_holdtime = (c == -1) ? 0 : (unsigned)c;
dvander@780
   189
dvander@780
   190
	for (int i=0; i<count; i++)
dvander@780
   191
	{
dvander@780
   192
		g_last_clients[g_last_client_count++] = pFilter->GetRecipientIndex(i);
dvander@780
   193
	}
skamonkey@3855
   194
#endif
dvander@780
   195
}
dvander@780
   196
dvander@780
   197
void CRadioStyle::OnUserMessageSent(int msg_id)
dvander@780
   198
{
dvander@780
   199
	for (unsigned int i=0; i<g_last_client_count; i++)
dvander@780
   200
	{
dvander@780
   201
		int client = g_last_clients[i];
dvander@970
   202
#if defined MENU_DEBUG
dvander@970
   203
		g_Logger.LogMessage("[SM_MENU] CRadioStyle got ShowMenu (client %d) (bInMenu %d)",
dvander@970
   204
			client,
dvander@970
   205
			m_players[client].bInExternMenu);
dvander@970
   206
#endif
dvander@780
   207
		if (m_players[client].bInMenu)
dvander@780
   208
		{
dvander@1005
   209
			_CancelClientMenu(client, MenuCancel_Interrupted, true);
dvander@780
   210
		}
dvander@780
   211
		m_players[client].bInExternMenu = true;
dvander@780
   212
		m_players[client].menuHoldTime = g_last_holdtime;
dvander@780
   213
	}
dvander@780
   214
	g_last_client_count = 0;
dvander@780
   215
}
dvander@780
   216
dvander@787
   217
void CRadioStyle::SendDisplay(int client, IMenuPanel *display)
dvander@780
   218
{
dvander@780
   219
	CRadioDisplay *rDisplay = (CRadioDisplay *)display;
dvander@780
   220
	rDisplay->SendRawDisplay(client, m_players[client].menuHoldTime);
dvander@780
   221
}
dvander@780
   222
dvander@787
   223
IMenuPanel *CRadioStyle::CreatePanel()
dvander@780
   224
{
dvander@790
   225
	return g_RadioMenuStyle.MakeRadioDisplay();
dvander@780
   226
}
dvander@780
   227
dvander@790
   228
IBaseMenu *CRadioStyle::CreateMenu(IMenuHandler *pHandler, IdentityToken_t *pOwner)
dvander@780
   229
{
dvander@790
   230
	return new CRadioMenu(pHandler, pOwner);
dvander@780
   231
}
dvander@780
   232
dvander@780
   233
unsigned int CRadioStyle::GetMaxPageItems()
dvander@780
   234
{
skamonkey@3570
   235
	return s_RadioMaxPageItems;
dvander@780
   236
}
dvander@780
   237
dvander@780
   238
const char *CRadioStyle::GetStyleName()
dvander@780
   239
{
dvander@780
   240
	return "radio";
dvander@780
   241
}
dvander@780
   242
dvander@780
   243
CBaseMenuPlayer *CRadioStyle::GetMenuPlayer(int client)
dvander@780
   244
{
dvander@780
   245
	return &m_players[client];
dvander@780
   246
}
dvander@780
   247
dvander@790
   248
CRadioDisplay *CRadioStyle::MakeRadioDisplay(CRadioMenu *menu)
dvander@790
   249
{
dvander@790
   250
	CRadioDisplay *display;
dvander@790
   251
	if (m_FreeDisplays.empty())
dvander@790
   252
	{
dvander@790
   253
		display = new CRadioDisplay();
dvander@1705
   254
	}
dvander@1705
   255
	else
dvander@1705
   256
	{
dvander@790
   257
		display = m_FreeDisplays.front();
dvander@790
   258
		m_FreeDisplays.pop();
dvander@790
   259
		display->Reset();
dvander@790
   260
	}
dvander@790
   261
	return display;
dvander@790
   262
}
dvander@790
   263
dvander@1705
   264
IMenuPanel *CRadioStyle::MakeRadioDisplay(const char *str, int keys)
dvander@1705
   265
{
dvander@1705
   266
	CRadioDisplay *pPanel = MakeRadioDisplay(NULL);
dvander@1705
   267
dvander@1705
   268
	pPanel->DirectSet(str, keys);
dvander@1705
   269
dvander@1705
   270
	return pPanel;
dvander@1705
   271
}
dvander@1705
   272
dvander@790
   273
void CRadioStyle::FreeRadioDisplay(CRadioDisplay *display)
dvander@790
   274
{
dvander@790
   275
	m_FreeDisplays.push(display);
dvander@790
   276
}
dvander@790
   277
dvander@1695
   278
CRadioMenuPlayer *CRadioStyle::GetRadioMenuPlayer(int client)
dvander@1695
   279
{
dvander@1695
   280
	return &m_players[client];
dvander@1695
   281
}
dvander@1695
   282
dvander@1695
   283
void CRadioStyle::ProcessWatchList()
dvander@1695
   284
{
dvander@1695
   285
	if (!g_RadioMenuTimeout)
dvander@1695
   286
	{
dvander@1695
   287
		BaseMenuStyle::ProcessWatchList();
dvander@1695
   288
		return;
dvander@1695
   289
	}
dvander@1695
   290
dvander@1695
   291
	BaseMenuStyle::ProcessWatchList();
dvander@1695
   292
dvander@1695
   293
	CRadioMenuPlayer *pPlayer;
dvander@1695
   294
	unsigned int max_clients = g_Players.GetMaxClients();
dvander@1695
   295
	for (unsigned int i = 1; i <= max_clients; i++)
dvander@1695
   296
	{
dvander@1695
   297
		pPlayer = GetRadioMenuPlayer(i);
dvander@1695
   298
		if (!pPlayer->bInMenu || pPlayer->bInExternMenu)
dvander@1695
   299
		{
dvander@1695
   300
			continue;
dvander@1695
   301
		}
dvander@1695
   302
		if (pPlayer->Radio_NeedsRefresh())
dvander@1695
   303
		{
dvander@1695
   304
			pPlayer->Radio_Refresh();
dvander@1695
   305
		}
dvander@1695
   306
	}
dvander@1695
   307
}
dvander@1695
   308
dvander@1766
   309
unsigned int CRadioStyle::GetApproxMemUsage()
dvander@1766
   310
{
dvander@1766
   311
	return sizeof(CRadioStyle) + (sizeof(CRadioMenuPlayer) * 257);
dvander@1766
   312
}
dvander@1766
   313
dvander@780
   314
CRadioDisplay::CRadioDisplay()
dvander@780
   315
{
dvander@780
   316
	Reset();
dvander@780
   317
}
dvander@780
   318
dvander@780
   319
CRadioDisplay::CRadioDisplay(CRadioMenu *menu)
dvander@780
   320
{
dvander@780
   321
	Reset();
dvander@780
   322
}
dvander@780
   323
dvander@780
   324
bool CRadioDisplay::DrawRawLine(const char *rawline)
dvander@780
   325
{
dvander@780
   326
	m_BufferText.append(rawline);
dvander@780
   327
	m_BufferText.append("\n");
dvander@780
   328
	return true;
dvander@780
   329
}
dvander@780
   330
dvander@780
   331
void CRadioDisplay::Reset()
dvander@780
   332
{
dvander@780
   333
	m_BufferText.assign("");
dvander@780
   334
	m_Title.assign("");
dvander@780
   335
	m_NextPos = 1;
dvander@785
   336
	keys = 0;
dvander@780
   337
}
dvander@780
   338
dvander@1705
   339
void CRadioDisplay::DirectSet(const char *str, int keymap)
dvander@1705
   340
{
dvander@1705
   341
	m_Title.clear();
dvander@1705
   342
	m_BufferText.assign(str);
dvander@1705
   343
	keys = keymap;
dvander@1705
   344
}
dvander@1705
   345
dvander@840
   346
unsigned int CRadioDisplay::GetCurrentKey()
dvander@840
   347
{
dvander@840
   348
	return m_NextPos;
dvander@840
   349
}
dvander@840
   350
dvander@840
   351
bool CRadioDisplay::SetCurrentKey(unsigned int key)
dvander@840
   352
{
skamonkey@3570
   353
	if (key < m_NextPos || m_NextPos > s_RadioMaxPageItems)
dvander@840
   354
	{
dvander@840
   355
		return false;
dvander@840
   356
	}
dvander@840
   357
dvander@840
   358
	m_NextPos = key;
dvander@840
   359
dvander@840
   360
	return true;
dvander@840
   361
}
dvander@840
   362
dvander@780
   363
bool CRadioDisplay::SendDisplay(int client, IMenuHandler *handler, unsigned int time)
dvander@780
   364
{
dvander@780
   365
	return g_RadioMenuStyle.DoClientMenu(client, this, handler, time);
dvander@780
   366
}
dvander@780
   367
dvander@780
   368
bool CRadioDisplay::SetExtOption(MenuOption option, const void *valuePtr)
dvander@780
   369
{
dvander@780
   370
	return false;
dvander@780
   371
}
dvander@780
   372
dvander@780
   373
IMenuStyle *CRadioDisplay::GetParentStyle()
dvander@780
   374
{
dvander@780
   375
	return &g_RadioMenuStyle;
dvander@780
   376
}
dvander@780
   377
dvander@780
   378
void CRadioDisplay::DrawTitle(const char *text, bool onlyIfEmpty/* =false */)
dvander@780
   379
{
dvander@780
   380
	if (m_Title.size() != 0 && onlyIfEmpty)
dvander@780
   381
	{
dvander@780
   382
		return;
dvander@780
   383
	}
dvander@780
   384
	m_Title.assign(text);
dvander@780
   385
}
dvander@780
   386
dvander@780
   387
unsigned int CRadioDisplay::DrawItem(const ItemDrawInfo &item)
dvander@780
   388
{
skamonkey@3570
   389
	if (m_NextPos > s_RadioMaxPageItems || !CanDrawItem(item.style))
dvander@780
   390
	{
dvander@780
   391
		return 0;
dvander@780
   392
	}
dvander@780
   393
dvander@780
   394
	if (item.style & ITEMDRAW_RAWLINE)
dvander@780
   395
	{
dvander@780
   396
		if (item.style & ITEMDRAW_SPACER)
dvander@780
   397
		{
dvander@785
   398
			m_BufferText.append(" \n");
dvander@780
   399
		} else {
dvander@780
   400
			m_BufferText.append(item.display);
dvander@780
   401
			m_BufferText.append("\n");
dvander@780
   402
		}
dvander@780
   403
		return 0;
dvander@780
   404
	} else if (item.style & ITEMDRAW_SPACER) {
dvander@785
   405
		m_BufferText.append(" \n");
dvander@785
   406
		return m_NextPos++;
dvander@785
   407
	} else if (item.style & ITEMDRAW_NOTEXT) {
dvander@780
   408
		return m_NextPos++;
dvander@780
   409
	}
dvander@780
   410
dvander@780
   411
	if (item.style & ITEMDRAW_DISABLED)
dvander@780
   412
	{
dvander@780
   413
		m_BufferText.append(g_RadioNumTable[m_NextPos]);
dvander@780
   414
		m_BufferText.append(item.display);
dvander@780
   415
		m_BufferText.append("\n");
dvander@780
   416
	} else {
dvander@785
   417
		m_BufferText.append("->");
dvander@785
   418
		m_BufferText.append(g_RadioNumTable[m_NextPos]);
dvander@780
   419
		m_BufferText.append(item.display);
dvander@780
   420
		m_BufferText.append("\n");
dvander@780
   421
		keys |= (1<<(m_NextPos-1));
dvander@780
   422
	}
dvander@780
   423
dvander@780
   424
	return m_NextPos++;
dvander@780
   425
}
dvander@780
   426
dvander@780
   427
bool CRadioDisplay::CanDrawItem(unsigned int drawFlags)
dvander@780
   428
{
dvander@780
   429
	if ((drawFlags & ITEMDRAW_IGNORE) == ITEMDRAW_IGNORE)
dvander@780
   430
	{
dvander@780
   431
		return false;
dvander@780
   432
	}
dvander@780
   433
dvander@785
   434
	if ((drawFlags & ITEMDRAW_DISABLED) && (drawFlags & ITEMDRAW_CONTROL))
dvander@785
   435
	{
dvander@785
   436
		return false;
dvander@785
   437
	}
dvander@785
   438
dvander@780
   439
	return true;
dvander@780
   440
}
dvander@780
   441
dvander@780
   442
void CRadioDisplay::SendRawDisplay(int client, unsigned int time)
dvander@780
   443
{
dvander@1695
   444
	int _sel_keys = (keys == 0) ? (1<<9) : keys;
dvander@1695
   445
	CRadioMenuPlayer *pPlayer = g_RadioMenuStyle.GetRadioMenuPlayer(client);
dvander@1695
   446
	pPlayer->Radio_Init(_sel_keys, m_Title.c_str(), m_BufferText.c_str());
dvander@1695
   447
	pPlayer->Radio_Refresh();
dvander@1695
   448
}
dvander@780
   449
dvander@1695
   450
void CRadioMenuPlayer::Radio_SetIndex(unsigned int index)
dvander@1695
   451
{
dvander@1695
   452
	m_index = index;
dvander@1695
   453
}
dvander@1695
   454
dvander@1695
   455
bool CRadioMenuPlayer::Radio_NeedsRefresh()
dvander@1695
   456
{
dvander@1695
   457
	return (gpGlobals->curtime - display_last_refresh >= g_RadioMenuTimeout);
dvander@1695
   458
}
dvander@780
   459
dvander@1695
   460
void CRadioMenuPlayer::Radio_Init(int keys, const char *title, const char *text)
dvander@1695
   461
{
dvander@1705
   462
	if (title[0] != '\0')
dvander@1705
   463
	{
dvander@1705
   464
		display_len = UTIL_Format(display_pkt, 
dvander@1705
   465
			sizeof(display_pkt), 
dvander@1705
   466
			"%s\n%s", 
dvander@1705
   467
			title,
dvander@1705
   468
			text);
dvander@1705
   469
	}
dvander@1705
   470
	else
dvander@1705
   471
	{
dvander@1705
   472
		display_len = UTIL_Format(display_pkt, 
dvander@1705
   473
			sizeof(display_pkt), 
dvander@1705
   474
			"%s", 
dvander@1705
   475
			text);
dvander@1705
   476
	}
dvander@1695
   477
	display_keys = keys;
dvander@1695
   478
}
dvander@780
   479
dvander@1695
   480
void CRadioMenuPlayer::Radio_Refresh()
dvander@1695
   481
{
skamonkey@3855
   482
#if SOURCE_ENGINE != SE_DOTA
dvander@1695
   483
	cell_t players[1] = {m_index};
dvander@1695
   484
	char *ptr = display_pkt;
dvander@1695
   485
	char save = 0;
dvander@1695
   486
	size_t len = display_len;
dvander@1695
   487
	unsigned int time;
dvander@819
   488
dvander@1695
   489
	/* Compute the new time */
dvander@1695
   490
	if (menuHoldTime == 0)
dvander@1695
   491
	{
dvander@1695
   492
		time = 0;
dvander@1695
   493
	}
dvander@1695
   494
	else
dvander@1695
   495
	{
dvander@1695
   496
		time = menuHoldTime - (unsigned int)(gpGlobals->curtime - menuStartTime);
dvander@1695
   497
	}
dvander@1695
   498
skamonkey@3743
   499
#ifdef USE_PROTOBUF_USERMESSAGES
skamonkey@3743
   500
	// If or when we need to support multiple games per engine with this, we can switch to reflection
skamonkey@3743
   501
	// TODO: find what happens past 240 on CS:GO
skamonkey@3743
   502
	CCSUsrMsg_ShowMenu *msg = (CCSUsrMsg_ShowMenu *)g_UserMsgs.StartProtobufMessage(g_ShowMenuId, players, 1, USERMSG_BLOCKHOOKS);
skamonkey@3743
   503
	msg->set_bits_valid_slots(display_keys);
skamonkey@3743
   504
	msg->set_display_time(time);
skamonkey@3743
   505
	msg->set_menu_string(ptr);
skamonkey@3743
   506
	g_UserMsgs.EndMessage();
skamonkey@3743
   507
#else
dvander@780
   508
	while (true)
dvander@780
   509
	{
dvander@780
   510
		if (len > 240)
dvander@780
   511
		{
dvander@780
   512
			save = ptr[240];
dvander@780
   513
			ptr[240] = '\0';
dvander@780
   514
		}
skamonkey@3743
   515
skamonkey@3743
   516
		bf_write *buffer = g_UserMsgs.StartBitBufMessage(g_ShowMenuId, players, 1, USERMSG_BLOCKHOOKS);
dvander@1695
   517
		buffer->WriteWord(display_keys);
dvander@780
   518
		buffer->WriteChar(time ? time : -1);
dvander@780
   519
		buffer->WriteByte( (len > 240) ? 1 : 0 );
dvander@780
   520
		buffer->WriteString(ptr);
dvander@780
   521
		g_UserMsgs.EndMessage();
dvander@780
   522
		if (len > 240)
dvander@780
   523
		{
dvander@780
   524
			ptr[240] = save;
dvander@780
   525
			ptr = &ptr[240];
dvander@780
   526
			len -= 240;
dvander@1695
   527
		}
dvander@1695
   528
		else
dvander@1695
   529
		{
dvander@780
   530
			break;
dvander@780
   531
		}
dvander@780
   532
	}
skamonkey@3743
   533
#endif
dvander@1695
   534
dvander@1695
   535
	display_last_refresh = gpGlobals->curtime;
skamonkey@3855
   536
#endif // !DOTA
dvander@780
   537
}
dvander@780
   538
dvander@1361
   539
int CRadioDisplay::GetAmountRemaining()
dvander@1361
   540
{
dvander@1361
   541
	size_t amt = m_Title.size() + 1 + m_BufferText.size();
dvander@1361
   542
	if (amt >= 511)
dvander@1361
   543
	{
dvander@1361
   544
		return 0;
dvander@1361
   545
	}
dvander@1361
   546
	return (int)(511 - amt);
dvander@1361
   547
}
dvander@1361
   548
dvander@780
   549
void CRadioDisplay::DeleteThis()
dvander@780
   550
{
dvander@780
   551
	delete this;
dvander@780
   552
}
dvander@780
   553
dvander@819
   554
bool CRadioDisplay::SetSelectableKeys(unsigned int keymap)
dvander@819
   555
{
dvander@819
   556
	keys = (signed)keymap;
dvander@820
   557
	return true;
dvander@819
   558
}
dvander@819
   559
dvander@1766
   560
unsigned int CRadioDisplay::GetApproxMemUsage()
dvander@1766
   561
{
dvander@1766
   562
	return sizeof(CRadioDisplay)
dvander@1766
   563
		+ m_BufferText.size()
dvander@1766
   564
		+ m_Title.size();
dvander@1766
   565
}
dvander@1766
   566
dvander@790
   567
CRadioMenu::CRadioMenu(IMenuHandler *pHandler, IdentityToken_t *pOwner) : 
dvander@790
   568
CBaseMenu(pHandler, &g_RadioMenuStyle, pOwner)
dvander@780
   569
{
skamonkey@3570
   570
	m_Pagination = s_RadioMaxPageItems - MAX_PAGINATION_OPTIONS;
dvander@780
   571
}
dvander@780
   572
dvander@780
   573
bool CRadioMenu::SetExtOption(MenuOption option, const void *valuePtr)
dvander@780
   574
{
dvander@780
   575
	return false;
dvander@780
   576
}
dvander@780
   577
dvander@787
   578
IMenuPanel *CRadioMenu::CreatePanel()
dvander@780
   579
{
dvander@790
   580
	return g_RadioMenuStyle.MakeRadioDisplay(this);
dvander@780
   581
}
dvander@780
   582
dvander@1269
   583
bool CRadioMenu::Display(int client, unsigned int time, IMenuHandler *alt_handler)
dvander@780
   584
{
dvander@1474
   585
	return DisplayAtItem(client, time, 0, alt_handler);
dvander@1474
   586
}
dvander@1474
   587
dvander@1474
   588
bool CRadioMenu::DisplayAtItem(int client,
dvander@1474
   589
							   unsigned int time,
dvander@1474
   590
							   unsigned int start_item,
dvander@1474
   591
							   IMenuHandler *alt_handler)
dvander@1474
   592
{
dvander@970
   593
#if defined MENU_DEBUG
dvander@970
   594
	g_Logger.LogMessage("[SM_MENU] CRadioMenu::Display(%p) (client %d) (time %d)",
dvander@970
   595
		this,
dvander@970
   596
		client,
dvander@970
   597
		time);
dvander@970
   598
#endif
dvander@877
   599
	if (m_bCancelling)
dvander@877
   600
	{
dvander@877
   601
		return false;
dvander@877
   602
	}
dvander@877
   603
dvander@1474
   604
	return g_RadioMenuStyle.DoClientMenu(client,
dvander@1474
   605
		this,
dvander@1474
   606
		start_item,
dvander@1474
   607
		alt_handler ? alt_handler : m_pHandler, 
dvander@1474
   608
		time);
dvander@877
   609
}
dvander@877
   610
skamonkey@3570
   611
bool CRadioMenu::SetPagination(unsigned int itemsPerPage)
skamonkey@3570
   612
{
skamonkey@3570
   613
	const unsigned int maxPerPage = s_RadioMaxPageItems - MAX_PAGINATION_OPTIONS;
skamonkey@3570
   614
	if (itemsPerPage > maxPerPage)
skamonkey@3570
   615
	{
skamonkey@3570
   616
		return false;
skamonkey@3570
   617
	}
skamonkey@3570
   618
skamonkey@3570
   619
	return CBaseMenu::SetPagination(itemsPerPage);
skamonkey@3570
   620
}
skamonkey@3570
   621
dvander@780
   622
void CRadioMenu::Cancel_Finally()
dvander@780
   623
{
dvander@780
   624
	g_RadioMenuStyle.CancelMenu(this);
dvander@780
   625
}
dvander@780
   626
dvander@1766
   627
unsigned int CRadioMenu::GetApproxMemUsage()
dvander@1766
   628
{
dvander@1766
   629
	return sizeof(CRadioMenu) + GetBaseMemUsage();
dvander@1766
   630
}
dvander@1766
   631
dvander@780
   632
const char *g_RadioNumTable[11] = 
dvander@780
   633
{
dvander@785
   634
	"0. ", "1. ", "2. ", "3. ", "4. ", "5. ", "6. ", "7. ", "8. ", "9. ", "0. "
dvander@780
   635
};