core/MenuStyle_Radio.cpp
author Scott Ehlert <ds@alliedmods.net>
Wed Aug 15 06:19:30 2007 +0000 (2007-08-15)
changeset 1330 ab94316bb52b
parent 1269 27397584df9c
child 1335 2047dc42d800
permissions -rw-r--r--
Updated license headers on virtually all files with extremely minor changes in the name of some sort of strange consistency.
All plugin and include file headers also have been changed to say about GPL3 instead of GPL2.

(This day shall henceforth be known as the Eighty Column Massacre of '07)
dvander@780
     1
/**
dvander@780
     2
 * vim: set ts=4 :
ds@1330
     3
 * =============================================================================
dvander@1231
     4
 * SourceMod
dvander@1231
     5
 * Copyright (C) 2004-2007 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@780
    35
#include "GameConfigs.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@780
    40
dvander@780
    41
extern const char *g_RadioNumTable[];
dvander@780
    42
CRadioStyle g_RadioMenuStyle;
dvander@780
    43
int g_ShowMenuId = -1;
dvander@785
    44
bool g_bRadioInit = false;
dvander@780
    45
dvander@780
    46
CRadioStyle::CRadioStyle() : m_players(new CBaseMenuPlayer[256+1])
dvander@780
    47
{
dvander@780
    48
}
dvander@780
    49
dvander@846
    50
void CRadioStyle::OnSourceModAllInitialized()
dvander@846
    51
{
dvander@846
    52
	g_Players.AddClientListener(this);
dvander@846
    53
}
dvander@846
    54
dvander@785
    55
void CRadioStyle::OnSourceModLevelChange(const char *mapName)
dvander@780
    56
{
dvander@785
    57
	if (g_bRadioInit)
dvander@785
    58
	{
dvander@785
    59
		return;
dvander@785
    60
	}
dvander@785
    61
dvander@785
    62
	g_bRadioInit = true;
dvander@780
    63
	const char *msg = g_pGameConf->GetKeyValue("HudRadioMenuMsg");
dvander@780
    64
	if (!msg || msg[0] == '\0')
dvander@780
    65
	{
dvander@780
    66
		return;
dvander@780
    67
	}
dvander@780
    68
dvander@780
    69
	g_ShowMenuId = g_UserMsgs.GetMessageIndex(msg);
dvander@780
    70
dvander@780
    71
	if (!IsSupported())
dvander@780
    72
	{
dvander@780
    73
		return;
dvander@780
    74
	}
dvander@780
    75
dvander@780
    76
	g_Menus.AddStyle(this);
dvander@780
    77
	g_Menus.SetDefaultStyle(this);
dvander@780
    78
dvander@780
    79
	g_UserMsgs.HookUserMessage(g_ShowMenuId, this, false);
dvander@780
    80
}
dvander@780
    81
dvander@780
    82
void CRadioStyle::OnSourceModShutdown()
dvander@780
    83
{
dvander@846
    84
	g_Players.RemoveClientListener(this);
dvander@780
    85
	g_UserMsgs.UnhookUserMessage(g_ShowMenuId, this, false);
dvander@790
    86
dvander@790
    87
	while (!m_FreeDisplays.empty())
dvander@790
    88
	{
dvander@790
    89
		delete m_FreeDisplays.front();
dvander@790
    90
		m_FreeDisplays.pop();
dvander@790
    91
	}
dvander@780
    92
}
dvander@780
    93
dvander@780
    94
bool CRadioStyle::IsSupported()
dvander@780
    95
{
dvander@780
    96
	return (g_ShowMenuId != -1);
dvander@780
    97
}
dvander@780
    98
dvander@780
    99
bool CRadioStyle::OnClientCommand(int client)
dvander@780
   100
{
dvander@780
   101
	const char *cmd = engine->Cmd_Argv(0);
dvander@780
   102
dvander@780
   103
	if (strcmp(cmd, "menuselect") == 0)
dvander@780
   104
	{
dvander@780
   105
		if (!m_players[client].bInMenu)
dvander@780
   106
		{
dvander@780
   107
			return false;
dvander@780
   108
		}
dvander@785
   109
dvander@780
   110
		int arg = atoi(engine->Cmd_Argv(1));
dvander@780
   111
		ClientPressedKey(client, arg);
dvander@785
   112
		return true;
dvander@780
   113
	}
dvander@780
   114
dvander@780
   115
	return false;
dvander@780
   116
}
dvander@780
   117
dvander@780
   118
static unsigned int g_last_holdtime = 0;
dvander@780
   119
static unsigned int g_last_client_count = 0;
dvander@780
   120
static int g_last_clients[256];
dvander@780
   121
dvander@780
   122
void CRadioStyle::OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter)
dvander@780
   123
{
dvander@780
   124
	int count = pFilter->GetRecipientCount();
dvander@780
   125
	bf_read br(bf->GetBasePointer(), 2);
dvander@780
   126
dvander@780
   127
	br.ReadWord();
dvander@780
   128
	int c = br.ReadChar();
dvander@780
   129
dvander@780
   130
	g_last_holdtime = (c == -1) ? 0 : (unsigned)c;
dvander@780
   131
dvander@780
   132
	for (int i=0; i<count; i++)
dvander@780
   133
	{
dvander@780
   134
		g_last_clients[g_last_client_count++] = pFilter->GetRecipientIndex(i);
dvander@780
   135
	}
dvander@780
   136
}
dvander@780
   137
dvander@780
   138
void CRadioStyle::OnUserMessageSent(int msg_id)
dvander@780
   139
{
dvander@780
   140
	for (unsigned int i=0; i<g_last_client_count; i++)
dvander@780
   141
	{
dvander@780
   142
		int client = g_last_clients[i];
dvander@970
   143
#if defined MENU_DEBUG
dvander@970
   144
		g_Logger.LogMessage("[SM_MENU] CRadioStyle got ShowMenu (client %d) (bInMenu %d)",
dvander@970
   145
			client,
dvander@970
   146
			m_players[client].bInExternMenu);
dvander@970
   147
#endif
dvander@780
   148
		if (m_players[client].bInMenu)
dvander@780
   149
		{
dvander@1005
   150
			_CancelClientMenu(client, MenuCancel_Interrupted, true);
dvander@780
   151
		}
dvander@780
   152
		m_players[client].bInExternMenu = true;
dvander@780
   153
		m_players[client].menuHoldTime = g_last_holdtime;
dvander@780
   154
	}
dvander@780
   155
	g_last_client_count = 0;
dvander@780
   156
}
dvander@780
   157
dvander@787
   158
void CRadioStyle::SendDisplay(int client, IMenuPanel *display)
dvander@780
   159
{
dvander@780
   160
	CRadioDisplay *rDisplay = (CRadioDisplay *)display;
dvander@780
   161
	rDisplay->SendRawDisplay(client, m_players[client].menuHoldTime);
dvander@780
   162
}
dvander@780
   163
dvander@787
   164
IMenuPanel *CRadioStyle::CreatePanel()
dvander@780
   165
{
dvander@790
   166
	return g_RadioMenuStyle.MakeRadioDisplay();
dvander@780
   167
}
dvander@780
   168
dvander@790
   169
IBaseMenu *CRadioStyle::CreateMenu(IMenuHandler *pHandler, IdentityToken_t *pOwner)
dvander@780
   170
{
dvander@790
   171
	return new CRadioMenu(pHandler, pOwner);
dvander@780
   172
}
dvander@780
   173
dvander@780
   174
unsigned int CRadioStyle::GetMaxPageItems()
dvander@780
   175
{
dvander@780
   176
	return 10;
dvander@780
   177
}
dvander@780
   178
dvander@780
   179
const char *CRadioStyle::GetStyleName()
dvander@780
   180
{
dvander@780
   181
	return "radio";
dvander@780
   182
}
dvander@780
   183
dvander@780
   184
CBaseMenuPlayer *CRadioStyle::GetMenuPlayer(int client)
dvander@780
   185
{
dvander@780
   186
	return &m_players[client];
dvander@780
   187
}
dvander@780
   188
dvander@790
   189
CRadioDisplay *CRadioStyle::MakeRadioDisplay(CRadioMenu *menu)
dvander@790
   190
{
dvander@790
   191
	CRadioDisplay *display;
dvander@790
   192
	if (m_FreeDisplays.empty())
dvander@790
   193
	{
dvander@790
   194
		display = new CRadioDisplay();
dvander@790
   195
	} else {
dvander@790
   196
		display = m_FreeDisplays.front();
dvander@790
   197
		m_FreeDisplays.pop();
dvander@790
   198
		display->Reset();
dvander@790
   199
	}
dvander@790
   200
	return display;
dvander@790
   201
}
dvander@790
   202
dvander@790
   203
void CRadioStyle::FreeRadioDisplay(CRadioDisplay *display)
dvander@790
   204
{
dvander@790
   205
	m_FreeDisplays.push(display);
dvander@790
   206
}
dvander@790
   207
dvander@780
   208
CRadioDisplay::CRadioDisplay()
dvander@780
   209
{
dvander@780
   210
	Reset();
dvander@780
   211
}
dvander@780
   212
dvander@780
   213
CRadioDisplay::CRadioDisplay(CRadioMenu *menu)
dvander@780
   214
{
dvander@780
   215
	Reset();
dvander@780
   216
}
dvander@780
   217
dvander@780
   218
bool CRadioDisplay::DrawRawLine(const char *rawline)
dvander@780
   219
{
dvander@780
   220
	m_BufferText.append(rawline);
dvander@780
   221
	m_BufferText.append("\n");
dvander@780
   222
	return true;
dvander@780
   223
}
dvander@780
   224
dvander@780
   225
void CRadioDisplay::Reset()
dvander@780
   226
{
dvander@780
   227
	m_BufferText.assign("");
dvander@780
   228
	m_Title.assign("");
dvander@780
   229
	m_NextPos = 1;
dvander@785
   230
	keys = 0;
dvander@780
   231
}
dvander@780
   232
dvander@840
   233
unsigned int CRadioDisplay::GetCurrentKey()
dvander@840
   234
{
dvander@840
   235
	return m_NextPos;
dvander@840
   236
}
dvander@840
   237
dvander@840
   238
bool CRadioDisplay::SetCurrentKey(unsigned int key)
dvander@840
   239
{
dvander@840
   240
	if (key < m_NextPos || m_NextPos > 10)
dvander@840
   241
	{
dvander@840
   242
		return false;
dvander@840
   243
	}
dvander@840
   244
dvander@840
   245
	m_NextPos = key;
dvander@840
   246
dvander@840
   247
	return true;
dvander@840
   248
}
dvander@840
   249
dvander@780
   250
bool CRadioDisplay::SendDisplay(int client, IMenuHandler *handler, unsigned int time)
dvander@780
   251
{
dvander@780
   252
	return g_RadioMenuStyle.DoClientMenu(client, this, handler, time);
dvander@780
   253
}
dvander@780
   254
dvander@780
   255
bool CRadioDisplay::SetExtOption(MenuOption option, const void *valuePtr)
dvander@780
   256
{
dvander@780
   257
	return false;
dvander@780
   258
}
dvander@780
   259
dvander@780
   260
IMenuStyle *CRadioDisplay::GetParentStyle()
dvander@780
   261
{
dvander@780
   262
	return &g_RadioMenuStyle;
dvander@780
   263
}
dvander@780
   264
dvander@780
   265
void CRadioDisplay::DrawTitle(const char *text, bool onlyIfEmpty/* =false */)
dvander@780
   266
{
dvander@780
   267
	if (m_Title.size() != 0 && onlyIfEmpty)
dvander@780
   268
	{
dvander@780
   269
		return;
dvander@780
   270
	}
dvander@780
   271
	m_Title.assign(text);
dvander@780
   272
}
dvander@780
   273
dvander@780
   274
unsigned int CRadioDisplay::DrawItem(const ItemDrawInfo &item)
dvander@780
   275
{
dvander@780
   276
	if (m_NextPos > 10 || !CanDrawItem(item.style))
dvander@780
   277
	{
dvander@780
   278
		return 0;
dvander@780
   279
	}
dvander@780
   280
dvander@780
   281
	if (item.style & ITEMDRAW_RAWLINE)
dvander@780
   282
	{
dvander@780
   283
		if (item.style & ITEMDRAW_SPACER)
dvander@780
   284
		{
dvander@785
   285
			m_BufferText.append(" \n");
dvander@780
   286
		} else {
dvander@780
   287
			m_BufferText.append(item.display);
dvander@780
   288
			m_BufferText.append("\n");
dvander@780
   289
		}
dvander@780
   290
		return 0;
dvander@780
   291
	} else if (item.style & ITEMDRAW_SPACER) {
dvander@785
   292
		m_BufferText.append(" \n");
dvander@785
   293
		return m_NextPos++;
dvander@785
   294
	} else if (item.style & ITEMDRAW_NOTEXT) {
dvander@780
   295
		return m_NextPos++;
dvander@780
   296
	}
dvander@780
   297
dvander@780
   298
	if (item.style & ITEMDRAW_DISABLED)
dvander@780
   299
	{
dvander@780
   300
		m_BufferText.append(g_RadioNumTable[m_NextPos]);
dvander@780
   301
		m_BufferText.append(item.display);
dvander@780
   302
		m_BufferText.append("\n");
dvander@780
   303
	} else {
dvander@785
   304
		m_BufferText.append("->");
dvander@785
   305
		m_BufferText.append(g_RadioNumTable[m_NextPos]);
dvander@780
   306
		m_BufferText.append(item.display);
dvander@780
   307
		m_BufferText.append("\n");
dvander@780
   308
		keys |= (1<<(m_NextPos-1));
dvander@780
   309
	}
dvander@780
   310
dvander@780
   311
	return m_NextPos++;
dvander@780
   312
}
dvander@780
   313
dvander@780
   314
bool CRadioDisplay::CanDrawItem(unsigned int drawFlags)
dvander@780
   315
{
dvander@780
   316
	if ((drawFlags & ITEMDRAW_IGNORE) == ITEMDRAW_IGNORE)
dvander@780
   317
	{
dvander@780
   318
		return false;
dvander@780
   319
	}
dvander@780
   320
dvander@785
   321
	if ((drawFlags & ITEMDRAW_DISABLED) && (drawFlags & ITEMDRAW_CONTROL))
dvander@785
   322
	{
dvander@785
   323
		return false;
dvander@785
   324
	}
dvander@785
   325
dvander@780
   326
	return true;
dvander@780
   327
}
dvander@780
   328
dvander@780
   329
void CRadioDisplay::SendRawDisplay(int client, unsigned int time)
dvander@780
   330
{
dvander@780
   331
	char buffer[4096];
dvander@780
   332
	size_t len;
dvander@780
   333
dvander@780
   334
	len = UTIL_Format(buffer, sizeof(buffer), "%s\n%s", m_Title.c_str(), m_BufferText.c_str());
dvander@780
   335
dvander@780
   336
	cell_t players[1] = {client};
dvander@780
   337
dvander@819
   338
	int _sel_keys = (keys == 0) ? (1<<9) : keys;
dvander@819
   339
dvander@780
   340
	char *ptr = buffer;
dvander@780
   341
	char save = 0;
dvander@780
   342
	while (true)
dvander@780
   343
	{
dvander@780
   344
		if (len > 240)
dvander@780
   345
		{
dvander@780
   346
			save = ptr[240];
dvander@780
   347
			ptr[240] = '\0';
dvander@780
   348
		}
dvander@1251
   349
		bf_write *buffer = g_UserMsgs.StartMessage(g_ShowMenuId, players, 1, USERMSG_BLOCKHOOKS);
dvander@819
   350
		buffer->WriteWord(_sel_keys);
dvander@780
   351
		buffer->WriteChar(time ? time : -1);
dvander@780
   352
		buffer->WriteByte( (len > 240) ? 1 : 0 );
dvander@780
   353
		buffer->WriteString(ptr);
dvander@780
   354
		g_UserMsgs.EndMessage();
dvander@780
   355
		if (len > 240)
dvander@780
   356
		{
dvander@780
   357
			ptr[240] = save;
dvander@780
   358
			ptr = &ptr[240];
dvander@780
   359
			len -= 240;
dvander@780
   360
		} else {
dvander@780
   361
			break;
dvander@780
   362
		}
dvander@780
   363
	}
dvander@780
   364
}
dvander@780
   365
dvander@780
   366
void CRadioDisplay::DeleteThis()
dvander@780
   367
{
dvander@780
   368
	delete this;
dvander@780
   369
}
dvander@780
   370
dvander@819
   371
bool CRadioDisplay::SetSelectableKeys(unsigned int keymap)
dvander@819
   372
{
dvander@819
   373
	keys = (signed)keymap;
dvander@820
   374
	return true;
dvander@819
   375
}
dvander@819
   376
dvander@790
   377
CRadioMenu::CRadioMenu(IMenuHandler *pHandler, IdentityToken_t *pOwner) : 
dvander@790
   378
CBaseMenu(pHandler, &g_RadioMenuStyle, pOwner)
dvander@780
   379
{
dvander@780
   380
}
dvander@780
   381
dvander@780
   382
bool CRadioMenu::SetExtOption(MenuOption option, const void *valuePtr)
dvander@780
   383
{
dvander@780
   384
	return false;
dvander@780
   385
}
dvander@780
   386
dvander@787
   387
IMenuPanel *CRadioMenu::CreatePanel()
dvander@780
   388
{
dvander@790
   389
	return g_RadioMenuStyle.MakeRadioDisplay(this);
dvander@780
   390
}
dvander@780
   391
dvander@1269
   392
bool CRadioMenu::Display(int client, unsigned int time, IMenuHandler *alt_handler)
dvander@780
   393
{
dvander@970
   394
#if defined MENU_DEBUG
dvander@970
   395
	g_Logger.LogMessage("[SM_MENU] CRadioMenu::Display(%p) (client %d) (time %d)",
dvander@970
   396
		this,
dvander@970
   397
		client,
dvander@970
   398
		time);
dvander@970
   399
#endif
dvander@877
   400
	if (m_bCancelling)
dvander@877
   401
	{
dvander@877
   402
		return false;
dvander@877
   403
	}
dvander@877
   404
dvander@1269
   405
	return g_RadioMenuStyle.DoClientMenu(client, this, alt_handler ? alt_handler : m_pHandler, time);
dvander@877
   406
}
dvander@877
   407
dvander@780
   408
void CRadioMenu::Cancel_Finally()
dvander@780
   409
{
dvander@780
   410
	g_RadioMenuStyle.CancelMenu(this);
dvander@780
   411
}
dvander@780
   412
dvander@780
   413
const char *g_RadioNumTable[11] = 
dvander@780
   414
{
dvander@785
   415
	"0. ", "1. ", "2. ", "3. ", "4. ", "5. ", "6. ", "7. ", "8. ", "9. ", "0. "
dvander@780
   416
};