1.1 --- a/core/MenuStyle_Radio.cpp Fri Jul 11 06:51:21 2008 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,566 +0,0 @@
1.4 -/**
1.5 - * vim: set ts=4 :
1.6 - * =============================================================================
1.7 - * SourceMod
1.8 - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
1.9 - * =============================================================================
1.10 - *
1.11 - * This program is free software; you can redistribute it and/or modify it under
1.12 - * the terms of the GNU General Public License, version 3.0, as published by the
1.13 - * Free Software Foundation.
1.14 - *
1.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
1.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.18 - * details.
1.19 - *
1.20 - * You should have received a copy of the GNU General Public License along with
1.21 - * this program. If not, see <http://www.gnu.org/licenses/>.
1.22 - *
1.23 - * As a special exception, AlliedModders LLC gives you permission to link the
1.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
1.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
1.26 - * by the Valve Corporation. You must obey the GNU General Public License in
1.27 - * all respects for all other code used. Additionally, AlliedModders LLC grants
1.28 - * this exception to all derivative works. AlliedModders LLC defines further
1.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
1.30 - * or <http://www.sourcemod.net/license.php>.
1.31 - *
1.32 - * Version: $Id$
1.33 - */
1.34 -
1.35 -#include "MenuStyle_Radio.h"
1.36 -#include "sm_stringutil.h"
1.37 -#include "UserMessages.h"
1.38 -#include "GameConfigs.h"
1.39 -#include "PlayerManager.h"
1.40 -#if defined MENU_DEBUG
1.41 -#include "Logger.h"
1.42 -#endif
1.43 -
1.44 -extern const char *g_RadioNumTable[];
1.45 -CRadioStyle g_RadioMenuStyle;
1.46 -int g_ShowMenuId = -1;
1.47 -bool g_bRadioInit = false;
1.48 -unsigned int g_RadioMenuTimeout = 0;
1.49 -
1.50 -CRadioStyle::CRadioStyle()
1.51 -{
1.52 - m_players = new CRadioMenuPlayer[256+1];
1.53 - for (size_t i = 0; i < 256+1; i++)
1.54 - {
1.55 - m_players[i].Radio_SetIndex(i);
1.56 - }
1.57 -}
1.58 -
1.59 -void CRadioStyle::OnSourceModAllInitialized()
1.60 -{
1.61 - g_Players.AddClientListener(this);
1.62 -}
1.63 -
1.64 -void CRadioStyle::OnSourceModLevelChange(const char *mapName)
1.65 -{
1.66 - if (g_bRadioInit)
1.67 - {
1.68 - return;
1.69 - }
1.70 -
1.71 - g_bRadioInit = true;
1.72 - const char *msg = g_pGameConf->GetKeyValue("HudRadioMenuMsg");
1.73 - if (!msg || msg[0] == '\0')
1.74 - {
1.75 - return;
1.76 - }
1.77 -
1.78 - g_ShowMenuId = g_UserMsgs.GetMessageIndex(msg);
1.79 -
1.80 - if (!IsSupported())
1.81 - {
1.82 - return;
1.83 - }
1.84 -
1.85 - const char *val = g_pGameConf->GetKeyValue("RadioMenuTimeout");
1.86 - if (val != NULL)
1.87 - {
1.88 - g_RadioMenuTimeout = atoi(val);
1.89 - }
1.90 - else
1.91 - {
1.92 - g_RadioMenuTimeout = 0;
1.93 - }
1.94 -
1.95 - g_Menus.AddStyle(this);
1.96 - g_Menus.SetDefaultStyle(this);
1.97 -
1.98 - g_UserMsgs.HookUserMessage(g_ShowMenuId, this, false);
1.99 -}
1.100 -
1.101 -void CRadioStyle::OnSourceModShutdown()
1.102 -{
1.103 - g_Players.RemoveClientListener(this);
1.104 - g_UserMsgs.UnhookUserMessage(g_ShowMenuId, this, false);
1.105 -
1.106 - while (!m_FreeDisplays.empty())
1.107 - {
1.108 - delete m_FreeDisplays.front();
1.109 - m_FreeDisplays.pop();
1.110 - }
1.111 -}
1.112 -
1.113 -bool CRadioStyle::IsSupported()
1.114 -{
1.115 - return (g_ShowMenuId != -1);
1.116 -}
1.117 -
1.118 -bool CRadioStyle::OnClientCommand(int client, const char *cmdname, const CCommand &cmd)
1.119 -{
1.120 - if (strcmp(cmdname, "menuselect") == 0)
1.121 - {
1.122 - if (!m_players[client].bInMenu)
1.123 - {
1.124 - m_players[client].bInExternMenu = false;
1.125 - return false;
1.126 - }
1.127 -
1.128 - int arg = atoi(cmd.Arg(1));
1.129 - ClientPressedKey(client, arg);
1.130 - return true;
1.131 - }
1.132 -
1.133 - return false;
1.134 -}
1.135 -
1.136 -static unsigned int g_last_holdtime = 0;
1.137 -static unsigned int g_last_client_count = 0;
1.138 -static int g_last_clients[256];
1.139 -
1.140 -void CRadioStyle::OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter)
1.141 -{
1.142 - int count = pFilter->GetRecipientCount();
1.143 - bf_read br(bf->GetBasePointer(), 3);
1.144 -
1.145 - br.ReadWord();
1.146 - int c = br.ReadChar();
1.147 -
1.148 - g_last_holdtime = (c == -1) ? 0 : (unsigned)c;
1.149 -
1.150 - for (int i=0; i<count; i++)
1.151 - {
1.152 - g_last_clients[g_last_client_count++] = pFilter->GetRecipientIndex(i);
1.153 - }
1.154 -}
1.155 -
1.156 -void CRadioStyle::OnUserMessageSent(int msg_id)
1.157 -{
1.158 - for (unsigned int i=0; i<g_last_client_count; i++)
1.159 - {
1.160 - int client = g_last_clients[i];
1.161 -#if defined MENU_DEBUG
1.162 - g_Logger.LogMessage("[SM_MENU] CRadioStyle got ShowMenu (client %d) (bInMenu %d)",
1.163 - client,
1.164 - m_players[client].bInExternMenu);
1.165 -#endif
1.166 - if (m_players[client].bInMenu)
1.167 - {
1.168 - _CancelClientMenu(client, MenuCancel_Interrupted, true);
1.169 - }
1.170 - m_players[client].bInExternMenu = true;
1.171 - m_players[client].menuHoldTime = g_last_holdtime;
1.172 - }
1.173 - g_last_client_count = 0;
1.174 -}
1.175 -
1.176 -void CRadioStyle::SendDisplay(int client, IMenuPanel *display)
1.177 -{
1.178 - CRadioDisplay *rDisplay = (CRadioDisplay *)display;
1.179 - rDisplay->SendRawDisplay(client, m_players[client].menuHoldTime);
1.180 -}
1.181 -
1.182 -IMenuPanel *CRadioStyle::CreatePanel()
1.183 -{
1.184 - return g_RadioMenuStyle.MakeRadioDisplay();
1.185 -}
1.186 -
1.187 -IBaseMenu *CRadioStyle::CreateMenu(IMenuHandler *pHandler, IdentityToken_t *pOwner)
1.188 -{
1.189 - return new CRadioMenu(pHandler, pOwner);
1.190 -}
1.191 -
1.192 -unsigned int CRadioStyle::GetMaxPageItems()
1.193 -{
1.194 - return 10;
1.195 -}
1.196 -
1.197 -const char *CRadioStyle::GetStyleName()
1.198 -{
1.199 - return "radio";
1.200 -}
1.201 -
1.202 -CBaseMenuPlayer *CRadioStyle::GetMenuPlayer(int client)
1.203 -{
1.204 - return &m_players[client];
1.205 -}
1.206 -
1.207 -CRadioDisplay *CRadioStyle::MakeRadioDisplay(CRadioMenu *menu)
1.208 -{
1.209 - CRadioDisplay *display;
1.210 - if (m_FreeDisplays.empty())
1.211 - {
1.212 - display = new CRadioDisplay();
1.213 - }
1.214 - else
1.215 - {
1.216 - display = m_FreeDisplays.front();
1.217 - m_FreeDisplays.pop();
1.218 - display->Reset();
1.219 - }
1.220 - return display;
1.221 -}
1.222 -
1.223 -IMenuPanel *CRadioStyle::MakeRadioDisplay(const char *str, int keys)
1.224 -{
1.225 - CRadioDisplay *pPanel = MakeRadioDisplay(NULL);
1.226 -
1.227 - pPanel->DirectSet(str, keys);
1.228 -
1.229 - return pPanel;
1.230 -}
1.231 -
1.232 -void CRadioStyle::FreeRadioDisplay(CRadioDisplay *display)
1.233 -{
1.234 - m_FreeDisplays.push(display);
1.235 -}
1.236 -
1.237 -CRadioMenuPlayer *CRadioStyle::GetRadioMenuPlayer(int client)
1.238 -{
1.239 - return &m_players[client];
1.240 -}
1.241 -
1.242 -void CRadioStyle::ProcessWatchList()
1.243 -{
1.244 - if (!g_RadioMenuTimeout)
1.245 - {
1.246 - BaseMenuStyle::ProcessWatchList();
1.247 - return;
1.248 - }
1.249 -
1.250 - BaseMenuStyle::ProcessWatchList();
1.251 -
1.252 - CRadioMenuPlayer *pPlayer;
1.253 - unsigned int max_clients = g_Players.GetMaxClients();
1.254 - for (unsigned int i = 1; i <= max_clients; i++)
1.255 - {
1.256 - pPlayer = GetRadioMenuPlayer(i);
1.257 - if (!pPlayer->bInMenu || pPlayer->bInExternMenu)
1.258 - {
1.259 - continue;
1.260 - }
1.261 - if (pPlayer->Radio_NeedsRefresh())
1.262 - {
1.263 - pPlayer->Radio_Refresh();
1.264 - }
1.265 - }
1.266 -}
1.267 -
1.268 -unsigned int CRadioStyle::GetApproxMemUsage()
1.269 -{
1.270 - return sizeof(CRadioStyle) + (sizeof(CRadioMenuPlayer) * 257);
1.271 -}
1.272 -
1.273 -CRadioDisplay::CRadioDisplay()
1.274 -{
1.275 - Reset();
1.276 -}
1.277 -
1.278 -CRadioDisplay::CRadioDisplay(CRadioMenu *menu)
1.279 -{
1.280 - Reset();
1.281 -}
1.282 -
1.283 -bool CRadioDisplay::DrawRawLine(const char *rawline)
1.284 -{
1.285 - m_BufferText.append(rawline);
1.286 - m_BufferText.append("\n");
1.287 - return true;
1.288 -}
1.289 -
1.290 -void CRadioDisplay::Reset()
1.291 -{
1.292 - m_BufferText.assign("");
1.293 - m_Title.assign("");
1.294 - m_NextPos = 1;
1.295 - keys = 0;
1.296 -}
1.297 -
1.298 -void CRadioDisplay::DirectSet(const char *str, int keymap)
1.299 -{
1.300 - m_Title.clear();
1.301 - m_BufferText.assign(str);
1.302 - keys = keymap;
1.303 -}
1.304 -
1.305 -unsigned int CRadioDisplay::GetCurrentKey()
1.306 -{
1.307 - return m_NextPos;
1.308 -}
1.309 -
1.310 -bool CRadioDisplay::SetCurrentKey(unsigned int key)
1.311 -{
1.312 - if (key < m_NextPos || m_NextPos > 10)
1.313 - {
1.314 - return false;
1.315 - }
1.316 -
1.317 - m_NextPos = key;
1.318 -
1.319 - return true;
1.320 -}
1.321 -
1.322 -bool CRadioDisplay::SendDisplay(int client, IMenuHandler *handler, unsigned int time)
1.323 -{
1.324 - return g_RadioMenuStyle.DoClientMenu(client, this, handler, time);
1.325 -}
1.326 -
1.327 -bool CRadioDisplay::SetExtOption(MenuOption option, const void *valuePtr)
1.328 -{
1.329 - return false;
1.330 -}
1.331 -
1.332 -IMenuStyle *CRadioDisplay::GetParentStyle()
1.333 -{
1.334 - return &g_RadioMenuStyle;
1.335 -}
1.336 -
1.337 -void CRadioDisplay::DrawTitle(const char *text, bool onlyIfEmpty/* =false */)
1.338 -{
1.339 - if (m_Title.size() != 0 && onlyIfEmpty)
1.340 - {
1.341 - return;
1.342 - }
1.343 - m_Title.assign(text);
1.344 -}
1.345 -
1.346 -unsigned int CRadioDisplay::DrawItem(const ItemDrawInfo &item)
1.347 -{
1.348 - if (m_NextPos > 10 || !CanDrawItem(item.style))
1.349 - {
1.350 - return 0;
1.351 - }
1.352 -
1.353 - if (item.style & ITEMDRAW_RAWLINE)
1.354 - {
1.355 - if (item.style & ITEMDRAW_SPACER)
1.356 - {
1.357 - m_BufferText.append(" \n");
1.358 - } else {
1.359 - m_BufferText.append(item.display);
1.360 - m_BufferText.append("\n");
1.361 - }
1.362 - return 0;
1.363 - } else if (item.style & ITEMDRAW_SPACER) {
1.364 - m_BufferText.append(" \n");
1.365 - return m_NextPos++;
1.366 - } else if (item.style & ITEMDRAW_NOTEXT) {
1.367 - return m_NextPos++;
1.368 - }
1.369 -
1.370 - if (item.style & ITEMDRAW_DISABLED)
1.371 - {
1.372 - m_BufferText.append(g_RadioNumTable[m_NextPos]);
1.373 - m_BufferText.append(item.display);
1.374 - m_BufferText.append("\n");
1.375 - } else {
1.376 - m_BufferText.append("->");
1.377 - m_BufferText.append(g_RadioNumTable[m_NextPos]);
1.378 - m_BufferText.append(item.display);
1.379 - m_BufferText.append("\n");
1.380 - keys |= (1<<(m_NextPos-1));
1.381 - }
1.382 -
1.383 - return m_NextPos++;
1.384 -}
1.385 -
1.386 -bool CRadioDisplay::CanDrawItem(unsigned int drawFlags)
1.387 -{
1.388 - if ((drawFlags & ITEMDRAW_IGNORE) == ITEMDRAW_IGNORE)
1.389 - {
1.390 - return false;
1.391 - }
1.392 -
1.393 - if ((drawFlags & ITEMDRAW_DISABLED) && (drawFlags & ITEMDRAW_CONTROL))
1.394 - {
1.395 - return false;
1.396 - }
1.397 -
1.398 - return true;
1.399 -}
1.400 -
1.401 -void CRadioDisplay::SendRawDisplay(int client, unsigned int time)
1.402 -{
1.403 - int _sel_keys = (keys == 0) ? (1<<9) : keys;
1.404 - CRadioMenuPlayer *pPlayer = g_RadioMenuStyle.GetRadioMenuPlayer(client);
1.405 - pPlayer->Radio_Init(_sel_keys, m_Title.c_str(), m_BufferText.c_str());
1.406 - pPlayer->Radio_Refresh();
1.407 -}
1.408 -
1.409 -void CRadioMenuPlayer::Radio_SetIndex(unsigned int index)
1.410 -{
1.411 - m_index = index;
1.412 -}
1.413 -
1.414 -bool CRadioMenuPlayer::Radio_NeedsRefresh()
1.415 -{
1.416 - return (gpGlobals->curtime - display_last_refresh >= g_RadioMenuTimeout);
1.417 -}
1.418 -
1.419 -void CRadioMenuPlayer::Radio_Init(int keys, const char *title, const char *text)
1.420 -{
1.421 - if (title[0] != '\0')
1.422 - {
1.423 - display_len = UTIL_Format(display_pkt,
1.424 - sizeof(display_pkt),
1.425 - "%s\n%s",
1.426 - title,
1.427 - text);
1.428 - }
1.429 - else
1.430 - {
1.431 - display_len = UTIL_Format(display_pkt,
1.432 - sizeof(display_pkt),
1.433 - "%s",
1.434 - text);
1.435 - }
1.436 - display_keys = keys;
1.437 -}
1.438 -
1.439 -void CRadioMenuPlayer::Radio_Refresh()
1.440 -{
1.441 - cell_t players[1] = {m_index};
1.442 - char *ptr = display_pkt;
1.443 - char save = 0;
1.444 - size_t len = display_len;
1.445 - unsigned int time;
1.446 -
1.447 - /* Compute the new time */
1.448 - if (menuHoldTime == 0)
1.449 - {
1.450 - time = 0;
1.451 - }
1.452 - else
1.453 - {
1.454 - time = menuHoldTime - (unsigned int)(gpGlobals->curtime - menuStartTime);
1.455 - }
1.456 -
1.457 - while (true)
1.458 - {
1.459 - if (len > 240)
1.460 - {
1.461 - save = ptr[240];
1.462 - ptr[240] = '\0';
1.463 - }
1.464 - bf_write *buffer = g_UserMsgs.StartMessage(g_ShowMenuId, players, 1, USERMSG_BLOCKHOOKS);
1.465 - buffer->WriteWord(display_keys);
1.466 - buffer->WriteChar(time ? time : -1);
1.467 - buffer->WriteByte( (len > 240) ? 1 : 0 );
1.468 - buffer->WriteString(ptr);
1.469 - g_UserMsgs.EndMessage();
1.470 - if (len > 240)
1.471 - {
1.472 - ptr[240] = save;
1.473 - ptr = &ptr[240];
1.474 - len -= 240;
1.475 - }
1.476 - else
1.477 - {
1.478 - break;
1.479 - }
1.480 - }
1.481 -
1.482 - display_last_refresh = gpGlobals->curtime;
1.483 -}
1.484 -
1.485 -int CRadioDisplay::GetAmountRemaining()
1.486 -{
1.487 - size_t amt = m_Title.size() + 1 + m_BufferText.size();
1.488 - if (amt >= 511)
1.489 - {
1.490 - return 0;
1.491 - }
1.492 - return (int)(511 - amt);
1.493 -}
1.494 -
1.495 -void CRadioDisplay::DeleteThis()
1.496 -{
1.497 - delete this;
1.498 -}
1.499 -
1.500 -bool CRadioDisplay::SetSelectableKeys(unsigned int keymap)
1.501 -{
1.502 - keys = (signed)keymap;
1.503 - return true;
1.504 -}
1.505 -
1.506 -unsigned int CRadioDisplay::GetApproxMemUsage()
1.507 -{
1.508 - return sizeof(CRadioDisplay)
1.509 - + m_BufferText.size()
1.510 - + m_Title.size();
1.511 -}
1.512 -
1.513 -CRadioMenu::CRadioMenu(IMenuHandler *pHandler, IdentityToken_t *pOwner) :
1.514 -CBaseMenu(pHandler, &g_RadioMenuStyle, pOwner)
1.515 -{
1.516 -}
1.517 -
1.518 -bool CRadioMenu::SetExtOption(MenuOption option, const void *valuePtr)
1.519 -{
1.520 - return false;
1.521 -}
1.522 -
1.523 -IMenuPanel *CRadioMenu::CreatePanel()
1.524 -{
1.525 - return g_RadioMenuStyle.MakeRadioDisplay(this);
1.526 -}
1.527 -
1.528 -bool CRadioMenu::Display(int client, unsigned int time, IMenuHandler *alt_handler)
1.529 -{
1.530 - return DisplayAtItem(client, time, 0, alt_handler);
1.531 -}
1.532 -
1.533 -bool CRadioMenu::DisplayAtItem(int client,
1.534 - unsigned int time,
1.535 - unsigned int start_item,
1.536 - IMenuHandler *alt_handler)
1.537 -{
1.538 -#if defined MENU_DEBUG
1.539 - g_Logger.LogMessage("[SM_MENU] CRadioMenu::Display(%p) (client %d) (time %d)",
1.540 - this,
1.541 - client,
1.542 - time);
1.543 -#endif
1.544 - if (m_bCancelling)
1.545 - {
1.546 - return false;
1.547 - }
1.548 -
1.549 - return g_RadioMenuStyle.DoClientMenu(client,
1.550 - this,
1.551 - start_item,
1.552 - alt_handler ? alt_handler : m_pHandler,
1.553 - time);
1.554 -}
1.555 -
1.556 -void CRadioMenu::Cancel_Finally()
1.557 -{
1.558 - g_RadioMenuStyle.CancelMenu(this);
1.559 -}
1.560 -
1.561 -unsigned int CRadioMenu::GetApproxMemUsage()
1.562 -{
1.563 - return sizeof(CRadioMenu) + GetBaseMemUsage();
1.564 -}
1.565 -
1.566 -const char *g_RadioNumTable[11] =
1.567 -{
1.568 - "0. ", "1. ", "2. ", "3. ", "4. ", "5. ", "6. ", "7. ", "8. ", "9. ", "0. "
1.569 -};