/* =========================================================================== Copyright (C) 2023 the OpenMoHAA team This file is part of OpenMoHAA source code. OpenMoHAA source code is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. OpenMoHAA source code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenMoHAA source code; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ #include "client.h" #include "../server/server.h" #include "../renderercommon/tr_public.h" #include "../qcommon/tiki.h" #include "../qcommon/localization.h" #include "../qcommon/q_version.h" #include "cl_ui.h" #include typedef struct { float fadetime; float starttime; float endtime; float alpha_start; float alpha_end; UIReggedMaterial *material; } intro_stage_t; static qboolean ui_hud; static class UIFont *globalFont; static UIFloatingConsole *fakk_console; static UIFloatingDMConsole *dm_console; static UIFloatingConsole *developer_console; static FakkMiniconsole *mini_console; static UIGMBox *gmbox; static UIDMBox *dmbox; static View3D *view3d; static Menu *mainmenu; static Menu *hud_weapons; static Menu *hud_items; static Menu *hud_health; static Menu *hud_ammo; static Menu *hud_compass; static Menu *hud_boss; static Menu *crosshairhud; static Menu *missionLog; qboolean server_loading; static qboolean server_loading_waiting; static str *s_intermediateconsole; static int ui_lastWeapHudState_Owned; static int ui_lastWeapHudState_Equipped = 0xFFFF; static int ui_weapHudTime; static int ui_itemHudTime; Menu *ui_pLoadingMenu; static Menu *ui_pConnectingMenu; static_media_t ui_static_materials; cvar_t *cl_greenfps; cvar_t *ui_GunneryEvaluation; cvar_t *ui_GroinShots; cvar_t *ui_RightArmShots; cvar_t *ui_LeftArmShots; cvar_t *ui_RightLegShots; cvar_t *ui_LeftLegShots; cvar_t *ui_TorsoShots; cvar_t *ui_HeadShots; cvar_t *ui_NumEnemysKilled; cvar_t *ui_NumObjectsDestroyed; cvar_t *ui_NumHitsTaken; cvar_t *ui_PreferredWeapon; cvar_t *ui_Accuracy; cvar_t *ui_NumObjectives; cvar_t *ui_NumComplete; cvar_t *ui_NumHits; cvar_t *ui_NumShotsFired; cvar_t *ui_gotmedal; cvar_t *ui_success; cvar_t *ui_failed; cvar_t *ui_returnmenu; cvar_t *ui_skip_eamovie; cvar_t *ui_skip_titlescreen; cvar_t *ui_skip_legalscreen; cvar_t *ui_titlescreen_fadein; cvar_t *ui_titlescreen_fadeout; cvar_t *ui_titlescreen_stay; cvar_t *ui_legalscreen_fadein; cvar_t *ui_legalscreen_fadeout; cvar_t *ui_legalscreen_stay; cvar_t *ui_drawcoords; cvar_t *ui_minicon; cvar_t *ui_gmbox; cvar_t *ui_consoleposition; cvar_t *ui_inventoryfile; cvar_t *ui_console; cvar_t *ui_newvidmode; cvar_t *ui_crosshair; cvar_t *ui_compass; cvar_t *ui_weaponsbar; cvar_t *ui_weaponsbartime; cvar_t *ui_itemsbar; cvar_t *ui_health_start; cvar_t *ui_health_end; cvar_t *ui_gmboxspam; cvar_t *ui_debugload; cvar_t *sound_overlay; cvar_t *ui_compass_scale; static intro_stage_t intro_stage; static char server_mapname[64]; static UIListCtrl *scoreboardlist; static Menu *scoreboard_menu; static float scoreboard_x; static float scoreboard_y; static float scoreboard_w; static float scoreboard_h; static qboolean scoreboard_header; cvar_t *cl_playintro; cvar_t *cl_movieaudio; static unsigned int startCountLow; static unsigned int startCountHigh; static unsigned int loadCountLow; static unsigned int loadCountHigh; static unsigned int loadCount; static unsigned int lastTime = 0; static unsigned int updateTime = 0; static unsigned int loadNumber; static unsigned int totalLoadTime; static unsigned int currentLoadTime; unsigned char UIListCtrlItem[8]; inventory_t client_inv; bind_t client_bind; static str scoreboard_menuname; static str ui_sCurrentLoadingMenu; static Container hudList; void UI_MultiplayerMenuWidgetsUpdate(void); void UI_MultiplayerMainMenuWidgetsUpdate(void); void UI_MainMenuWidgetsUpdate(void); static UIRect2D getDefaultGMBoxRectangle(void); static UIRect2D getDefaultDMBoxRectangle(void); class ConsoleHider : public Listener { public: CLASS_PROTOTYPE(ConsoleHider); void HideConsole(Event *ev); void DeadConsole(Event *ev); }; CLASS_DECLARATION(Listener, ConsoleHider, NULL) { {&UIFloatingWindow::W_ClosePressed, &ConsoleHider::HideConsole}, {&W_Destroyed, &ConsoleHider::DeadConsole}, {NULL, NULL } }; void ConsoleHider::HideConsole(Event *ev) { UI_CloseConsole(); } void ConsoleHider::DeadConsole(Event *ev) { if (fakk_console && !fakk_console->IsDying()) { delete fakk_console; fakk_console = NULL; } } static ConsoleHider s_consolehider; /* ==================== ConsoleCommandHandler ==================== */ static void ConsoleCommandHandler(const char *txt) { Cbuf_AddText(txt); } /* ==================== getDefaultConsoleRectangle ==================== */ static UIRect2D getDefaultConsoleRectangle(void) { float f[4]; int i; UIRect2D rect; if (sscanf(ui_consoleposition->string, "%f %f %f %f", &f[0], &f[1], &f[2], &f[3]) == 4) { for (i = 0; i < 4; i++) { f[i] = floor(f[i]); } rect.pos.x = f[0] - cls.glconfig.vidWidth; rect.pos.y = f[1] - cls.glconfig.vidHeight; rect.size.width = f[2] + 50.0; rect.size.height = f[3] + 50.0; } else { rect.pos.x = 25.0; rect.pos.y = 25.0; rect.size.width = (cls.glconfig.vidWidth - 50); rect.size.height = (cls.glconfig.vidHeight / 2); } return rect; } class DMConsoleHider : public Listener { public: CLASS_PROTOTYPE(DMConsoleHider); void HideDMConsole(Event *ev); void DeadDMConsole(Event *ev); }; CLASS_DECLARATION(Listener, DMConsoleHider, NULL) { {&UIFloatingWindow::W_ClosePressed, &DMConsoleHider::HideDMConsole}, {&W_Deactivated, &DMConsoleHider::HideDMConsole}, {&W_Destroyed, &DMConsoleHider::DeadDMConsole}, {NULL, NULL } }; void DMConsoleHider::HideDMConsole(Event *ev) { UI_CloseDMConsole(); } void DMConsoleHider::DeadDMConsole(Event *ev) { if (dm_console && !dm_console->IsDying()) { delete dm_console; dm_console = NULL; } } static DMConsoleHider s_dmconsolehider; /* ==================== GetClientState ==================== */ static void GetClientState(uiClientState_t *state) { state->connectPacketCount = clc.connectPacketCount; state->connState = clc.state; Q_strncpyz(state->servername, clc.servername, sizeof(state->servername)); Q_strncpyz(state->updateInfoString, cls.updateInfoString, sizeof(state->updateInfoString)); Q_strncpyz(state->messageString, clc.serverMessage, sizeof(state->messageString)); state->clientNum = cl.snap.ps.clientNum; } /* ==================== LAN_LoadCachedServers ==================== */ void LAN_LoadCachedServers(void) { int size; fileHandle_t fileIn; cls.numglobalservers = cls.nummplayerservers = cls.numfavoriteservers = 0; cls.numGlobalServerAddresses = 0; if (FS_SV_FOpenFileRead("servercache.dat", &fileIn)) { FS_Read(&cls.numglobalservers, sizeof(int), fileIn); FS_Read(&cls.nummplayerservers, sizeof(int), fileIn); FS_Read(&cls.numfavoriteservers, sizeof(int), fileIn); FS_Read(&size, sizeof(int), fileIn); if (size == sizeof(cls.globalServers) + sizeof(cls.favoriteServers) + sizeof(cls.mplayerServers)) { FS_Read(&cls.globalServers, sizeof(cls.globalServers), fileIn); FS_Read(&cls.mplayerServers, sizeof(cls.mplayerServers), fileIn); FS_Read(&cls.favoriteServers, sizeof(cls.favoriteServers), fileIn); } else { cls.numglobalservers = cls.nummplayerservers = cls.numfavoriteservers = 0; cls.numGlobalServerAddresses = 0; } FS_FCloseFile(fileIn); } } /* ==================== LAN_SaveServersToCache ==================== */ void LAN_SaveServersToCache(void) { int size; fileHandle_t fileOut = FS_SV_FOpenFileWrite("servercache.dat"); FS_Write(&cls.numglobalservers, sizeof(int), fileOut); FS_Write(&cls.nummplayerservers, sizeof(int), fileOut); FS_Write(&cls.numfavoriteservers, sizeof(int), fileOut); size = sizeof(cls.globalServers) + sizeof(cls.favoriteServers) + sizeof(cls.mplayerServers); FS_Write(&size, sizeof(int), fileOut); FS_Write(&cls.globalServers, sizeof(cls.globalServers), fileOut); FS_Write(&cls.mplayerServers, sizeof(cls.mplayerServers), fileOut); FS_Write(&cls.favoriteServers, sizeof(cls.favoriteServers), fileOut); FS_FCloseFile(fileOut); } /* ==================== LAN_ResetPings ==================== */ static void LAN_ResetPings(int source) { int count, i; serverInfo_t *servers = NULL; count = 0; switch (source) { case AS_LOCAL: servers = &cls.localServers[0]; count = MAX_OTHER_SERVERS; break; case AS_MPLAYER: servers = &cls.mplayerServers[0]; count = MAX_OTHER_SERVERS; break; case AS_GLOBAL: servers = &cls.globalServers[0]; count = MAX_GLOBAL_SERVERS; break; case AS_FAVORITES: servers = &cls.favoriteServers[0]; count = MAX_OTHER_SERVERS; break; } if (servers) { for (i = 0; i < count; i++) { servers[i].ping = -1; } } } /* ==================== LAN_AddServer ==================== */ static int LAN_AddServer(int source, const char *name, const char *address) { int max, *count, i; netadr_t adr; serverInfo_t *servers = NULL; max = MAX_OTHER_SERVERS; count = NULL; switch (source) { case AS_LOCAL: count = &cls.numlocalservers; servers = &cls.localServers[0]; break; case AS_MPLAYER: count = &cls.nummplayerservers; servers = &cls.mplayerServers[0]; break; case AS_GLOBAL: max = MAX_GLOBAL_SERVERS; count = &cls.numglobalservers; servers = &cls.globalServers[0]; break; case AS_FAVORITES: count = &cls.numfavoriteservers; servers = &cls.favoriteServers[0]; break; } if (servers && *count < max) { NET_StringToAdr(address, &adr, NA_IP); for (i = 0; i < *count; i++) { if (NET_CompareAdr(servers[i].adr, adr)) { break; } } if (i >= *count) { servers[*count].adr = adr; Q_strncpyz(servers[*count].hostName, name, sizeof(servers[*count].hostName)); servers[*count].visible = qtrue; (*count)++; return 1; } return 0; } return -1; } /* ==================== LAN_RemoveServer ==================== */ static void LAN_RemoveServer(int source, const char *addr) { int *count, i; serverInfo_t *servers = NULL; count = NULL; switch (source) { case AS_LOCAL: count = &cls.numlocalservers; servers = &cls.localServers[0]; break; case AS_MPLAYER: count = &cls.nummplayerservers; servers = &cls.mplayerServers[0]; break; case AS_GLOBAL: count = &cls.numglobalservers; servers = &cls.globalServers[0]; break; case AS_FAVORITES: count = &cls.numfavoriteservers; servers = &cls.favoriteServers[0]; break; } if (servers) { netadr_t comp; NET_StringToAdr(addr, &comp, NA_IP); for (i = 0; i < *count; i++) { if (NET_CompareAdr(comp, servers[i].adr)) { int j = i; while (j < *count - 1) { Com_Memcpy(&servers[j], &servers[j + 1], sizeof(servers[j])); j++; } (*count)--; break; } } } } /* ==================== LAN_GetServerCount ==================== */ static int LAN_GetServerCount(int source) { switch (source) { case AS_LOCAL: return cls.numlocalservers; break; case AS_MPLAYER: return cls.nummplayerservers; break; case AS_GLOBAL: return cls.numglobalservers; break; case AS_FAVORITES: return cls.numfavoriteservers; break; } return 0; } /* ==================== LAN_GetLocalServerAddressString ==================== */ static void LAN_GetServerAddressString(int source, int n, char *buf, int buflen) { switch (source) { case AS_LOCAL: if (n >= 0 && n < MAX_OTHER_SERVERS) { Q_strncpyz(buf, NET_AdrToString(cls.localServers[n].adr), buflen); return; } break; case AS_MPLAYER: if (n >= 0 && n < MAX_OTHER_SERVERS) { Q_strncpyz(buf, NET_AdrToString(cls.mplayerServers[n].adr), buflen); return; } break; case AS_GLOBAL: if (n >= 0 && n < MAX_GLOBAL_SERVERS) { Q_strncpyz(buf, NET_AdrToString(cls.globalServers[n].adr), buflen); return; } break; case AS_FAVORITES: if (n >= 0 && n < MAX_OTHER_SERVERS) { Q_strncpyz(buf, NET_AdrToString(cls.favoriteServers[n].adr), buflen); return; } break; } buf[0] = '\0'; } /* ==================== LAN_GetServerInfo ==================== */ static void LAN_GetServerInfo(int source, int n, char *buf, int buflen) { char info[MAX_STRING_CHARS]; serverInfo_t *server = NULL; info[0] = '\0'; switch (source) { case AS_LOCAL: if (n >= 0 && n < MAX_OTHER_SERVERS) { server = &cls.localServers[n]; } break; case AS_MPLAYER: if (n >= 0 && n < MAX_OTHER_SERVERS) { server = &cls.mplayerServers[n]; } break; case AS_GLOBAL: if (n >= 0 && n < MAX_GLOBAL_SERVERS) { server = &cls.globalServers[n]; } break; case AS_FAVORITES: if (n >= 0 && n < MAX_OTHER_SERVERS) { server = &cls.favoriteServers[n]; } break; } if (server && buf) { buf[0] = '\0'; Info_SetValueForKey(info, "hostname", server->hostName); Info_SetValueForKey(info, "mapname", server->mapName); Info_SetValueForKey(info, "clients", va("%i", server->clients)); Info_SetValueForKey(info, "sv_maxclients", va("%i", server->maxClients)); Info_SetValueForKey(info, "ping", va("%i", server->ping)); Info_SetValueForKey(info, "minping", va("%i", server->minPing)); Info_SetValueForKey(info, "maxping", va("%i", server->maxPing)); Info_SetValueForKey(info, "game", server->game); Info_SetValueForKey(info, "gametype", va("%i", server->gameType)); Info_SetValueForKey(info, "nettype", va("%i", server->netType)); Info_SetValueForKey(info, "addr", NET_AdrToString(server->adr)); Q_strncpyz(buf, info, buflen); } else { if (buf) { buf[0] = '\0'; } } } /* ==================== LAN_GetServerPing ==================== */ static int LAN_GetServerPing(int source, int n) { serverInfo_t *server = NULL; switch (source) { case AS_LOCAL: if (n >= 0 && n < MAX_OTHER_SERVERS) { server = &cls.localServers[n]; } break; case AS_MPLAYER: if (n >= 0 && n < MAX_OTHER_SERVERS) { server = &cls.mplayerServers[n]; } break; case AS_GLOBAL: if (n >= 0 && n < MAX_GLOBAL_SERVERS) { server = &cls.globalServers[n]; } break; case AS_FAVORITES: if (n >= 0 && n < MAX_OTHER_SERVERS) { server = &cls.favoriteServers[n]; } break; } if (server) { return server->ping; } return -1; } /* ==================== LAN_GetServerPtr ==================== */ static serverInfo_t *LAN_GetServerPtr(int source, int n) { switch (source) { case AS_LOCAL: if (n >= 0 && n < MAX_OTHER_SERVERS) { return &cls.localServers[n]; } break; case AS_MPLAYER: if (n >= 0 && n < MAX_OTHER_SERVERS) { return &cls.mplayerServers[n]; } break; case AS_GLOBAL: if (n >= 0 && n < MAX_GLOBAL_SERVERS) { return &cls.globalServers[n]; } break; case AS_FAVORITES: if (n >= 0 && n < MAX_OTHER_SERVERS) { return &cls.favoriteServers[n]; } break; } return NULL; } /* ==================== LAN_CompareServers ==================== */ static int LAN_CompareServers(int source, int sortKey, int sortDir, int s1, int s2) { int res; serverInfo_t *server1, *server2; server1 = LAN_GetServerPtr(source, s1); server2 = LAN_GetServerPtr(source, s2); if (!server1 || !server2) { return 0; } res = 0; switch (sortKey) { case SORT_HOST: res = Q_stricmp(server1->hostName, server2->hostName); break; case SORT_MAP: res = Q_stricmp(server1->mapName, server2->mapName); break; case SORT_CLIENTS: if (server1->clients < server2->clients) { res = -1; } else if (server1->clients > server2->clients) { res = 1; } else { res = 0; } break; case SORT_GAME: if (server1->gameType < server2->gameType) { res = -1; } else if (server1->gameType > server2->gameType) { res = 1; } else { res = 0; } break; case SORT_PING: if (server1->ping < server2->ping) { res = -1; } else if (server1->ping > server2->ping) { res = 1; } else { res = 0; } break; } if (sortDir) { if (res < 0) { return 1; } if (res > 0) { return -1; } return 0; } return res; } /* ==================== LAN_GetPingQueueCount ==================== */ static int LAN_GetPingQueueCount(void) { return (CL_GetPingQueueCount()); } /* ==================== LAN_ClearPing ==================== */ static void LAN_ClearPing(int n) { CL_ClearPing(n); } /* ==================== LAN_GetPing ==================== */ static void LAN_GetPing(int n, char *buf, int buflen, int *pingtime) { CL_GetPing(n, buf, buflen, pingtime); } /* ==================== LAN_GetPingInfo ==================== */ static void LAN_GetPingInfo(int n, char *buf, int buflen) { CL_GetPingInfo(n, buf, buflen); } /* ==================== LAN_MarkServerVisible ==================== */ static void LAN_MarkServerVisible(int source, int n, qboolean visible) { if (n == -1) { int count = MAX_OTHER_SERVERS; serverInfo_t *server = NULL; switch (source) { case AS_LOCAL: server = &cls.localServers[0]; break; case AS_MPLAYER: server = &cls.mplayerServers[0]; break; case AS_GLOBAL: server = &cls.globalServers[0]; count = MAX_GLOBAL_SERVERS; break; case AS_FAVORITES: server = &cls.favoriteServers[0]; break; } if (server) { for (n = 0; n < count; n++) { server[n].visible = visible; } } } else { switch (source) { case AS_LOCAL: if (n >= 0 && n < MAX_OTHER_SERVERS) { cls.localServers[n].visible = visible; } break; case AS_MPLAYER: if (n >= 0 && n < MAX_OTHER_SERVERS) { cls.mplayerServers[n].visible = visible; } break; case AS_GLOBAL: if (n >= 0 && n < MAX_GLOBAL_SERVERS) { cls.globalServers[n].visible = visible; } break; case AS_FAVORITES: if (n >= 0 && n < MAX_OTHER_SERVERS) { cls.favoriteServers[n].visible = visible; } break; } } } /* ======================= LAN_ServerIsVisible ======================= */ static int LAN_ServerIsVisible(int source, int n) { switch (source) { case AS_LOCAL: if (n >= 0 && n < MAX_OTHER_SERVERS) { return cls.localServers[n].visible; } break; case AS_MPLAYER: if (n >= 0 && n < MAX_OTHER_SERVERS) { return cls.mplayerServers[n].visible; } break; case AS_GLOBAL: if (n >= 0 && n < MAX_GLOBAL_SERVERS) { return cls.globalServers[n].visible; } break; case AS_FAVORITES: if (n >= 0 && n < MAX_OTHER_SERVERS) { return cls.favoriteServers[n].visible; } break; } return qfalse; } /* ======================= LAN_UpdateVisiblePings ======================= */ qboolean LAN_UpdateVisiblePings(int source) { return CL_UpdateVisiblePings_f(source); } /* ==================== LAN_GetServerStatus ==================== */ int LAN_GetServerStatus(const char *serverAddress, char *serverStatus, int maxLen) { return CL_ServerStatus(serverAddress, serverStatus, maxLen); } /* ==================== CL_GetGlConfig ==================== */ static void CL_GetGlconfig(glconfig_t *config) { *config = cls.glconfig; } /* ==================== CL_GetClipboardData ==================== */ static void CL_GetClipboardData(char *buf, int buflen) { char *cbd; cbd = Sys_GetClipboardData(); if (!cbd) { *buf = 0; return; } Q_strncpyz(buf, cbd, buflen); Z_Free(cbd); } /* ==================== Key_KeynumToStringBuf ==================== */ static void Key_KeynumToStringBuf(int keynum, char *buf, int buflen) { Q_strncpyz(buf, Key_KeynumToString(keynum), buflen); } /* ==================== Key_GetBindingBuf ==================== */ static void Key_GetBindingBuf(int keynum, char *buf, int buflen) { const char *value; value = Key_GetBinding(keynum); if (value) { Q_strncpyz(buf, value, buflen); } else { *buf = 0; } } /* ==================== GetConfigString ==================== */ static int GetConfigString(int index, char *buf, int size) { int offset; if (index < 0 || index >= MAX_CONFIGSTRINGS) { return qfalse; } offset = cl.gameState.stringOffsets[index]; if (!offset) { if (size) { buf[0] = 0; } return qfalse; } Q_strncpyz(buf, cl.gameState.stringData + offset, size); return qtrue; } /* ==================== FloatAsInt ==================== */ static int FloatAsInt(float f) { int temp; *(float *)&temp = f; return temp; } qboolean UI_usesUniqueCDKey(void) { return qfalse; } /* ==================== getDefaultConsoleRectangle ==================== */ static UIRect2D getDefaultDMConsoleRectangle(void) { float f[4]; int i; UIRect2D rect; if (sscanf(ui_consoleposition->string, "%f %f %f %f", &f[0], &f[1], &f[2], &f[3]) == 4) { for (i = 0; i < 4; i++) { f[i] = floor(f[i]); } rect.pos.x = f[0] - cls.glconfig.vidWidth; rect.pos.y = f[1] - cls.glconfig.vidHeight; rect.size.width = f[2] + 50.0; rect.size.height = f[3] + 50.0; } else { rect.pos.x = 0; rect.pos.y = cls.glconfig.vidHeight * 0.58; rect.size.width = cls.glconfig.vidWidth; rect.size.height = cls.glconfig.vidHeight * 0.415; } return rect; } /* ==================== getDefaultConsoleRectangle ==================== */ static UIRect2D getQuickMessageDMConsoleRectangle(void) { float f[4]; int i; UIRect2D rect; if (sscanf(ui_consoleposition->string, "%f %f %f %f", &f[0], &f[1], &f[2], &f[3]) == 4) { for (i = 0; i < 4; i++) { f[i] = floor(f[i]); } rect.pos.x = f[0] - cls.glconfig.vidWidth; rect.pos.y = f[1] - cls.glconfig.vidHeight; rect.size.width = f[2] + 50.0; rect.size.height = f[3] + 50.0; } else { rect.pos.x = 0; rect.pos.y = cls.glconfig.vidHeight * 0.66; rect.size.width = cls.glconfig.vidWidth; // Fixed in 2.0 // Was 38.0 in 1.11 and below // This prevents characters to be seen from the DM console // in the quick message console rect.size.height = 36.0; } return rect; } /* ==================== UI_DMMessageModesMatch ==================== */ static qboolean UI_DMMessageModesMatch(int iMode) { qboolean bQuickMessage = qfalse; if (iMode && (iMode != 300 || dm_console->GetQuickMessageMode())) { if (iMode < 0) { bQuickMessage = qtrue; iMode = -iMode; } if (dm_console->GetQuickMessageMode() == bQuickMessage) { return dm_console->GetMessageMode() == iMode; } else { return qfalse; } } else { return qtrue; } } /* ==================== UI_SetDMConsoleMode ==================== */ static void UI_SetDMConsoleMode(int iMode) { qboolean bQuickMessage; if (UI_DMMessageModesMatch(iMode)) { return; } bQuickMessage = qfalse; if (iMode < 0) { bQuickMessage = qtrue; iMode = -iMode; } if (iMode == 300) { iMode = dm_console->GetMessageMode(); } if (dm_console->GetQuickMessageMode()) { if (!bQuickMessage) { dm_console->setFrame(getDefaultDMConsoleRectangle()); dm_console->SetQuickMessageMode(qfalse); } } else { if (bQuickMessage) { dm_console->setFrame(getQuickMessageDMConsoleRectangle()); dm_console->SetQuickMessageMode(bQuickMessage); } } dm_console->SetMessageMode(iMode); if (bQuickMessage) { if (iMode == 100) { dm_console->setTitle(Sys_LV_CL_ConvertString("Quick Chat (Press Enter to send) : Messaging to All")); } else if (iMode == 200) { dm_console->setTitle(Sys_LV_CL_ConvertString("Quick Chat (Press Enter to send) : Messaging to Team")); } else { dm_console->setTitle( va("%s %i", Sys_LV_CL_ConvertString("Quick Chat (Press Enter to send) : Messaging to Client"), iMode) ); } } else { if (iMode == 100) { dm_console->setTitle(Sys_LV_CL_ConvertString( "Chat Window (Enter to send/close) (all|team|private to change mode) : Messaging to All" )); } else if (iMode == 200) { dm_console->setTitle(Sys_LV_CL_ConvertString( "Chat Window (Enter to send/close) (all|team|private to change mode) : Messaging to Team" )); } else { dm_console->setTitle( va("%s %i", Sys_LV_CL_ConvertString( "Chat Window (Enter to send/close) (all|team|private to change mode) : Messaging to Client" ), iMode) ); } } } static void DMConsoleCommandHandler(const char *txt) { int iMode; char szStringOut[1024]; iMode = 0; if (dm_console->GetMessageMode() != 100) { if (dm_console->GetMessageMode() == 200) { iMode = -1; } else { iMode = dm_console->GetMessageMode(); } } Com_sprintf(szStringOut, sizeof(szStringOut), "dmmessage %i %s\n", iMode, txt); CL_AddReliableCommand(szStringOut, qfalse); } /* ==================== getNewConsole ==================== */ UIFloatingConsole *getNewConsole() { const char *consoleName = va("%s console version %s", PRODUCT_NAME, PRODUCT_VERSION); UIFloatingConsole *console = new UIFloatingConsole; console->Create(NULL, getDefaultConsoleRectangle(), consoleName, UWindowColor, UHudColor); console->setConsoleHandler(ConsoleCommandHandler); console->setConsoleBackground(UBlack, 0.8f); console->setShow(false); console->Connect(&s_consolehider, UIFloatingWindow::W_ClosePressed, UIFloatingWindow::W_ClosePressed); console->Connect(&s_consolehider, W_Destroyed, W_Destroyed); return console; } /* ==================== getNewDMConsole ==================== */ UIFloatingDMConsole *getNewDMConsole() { UIFloatingDMConsole *console = new UIFloatingDMConsole; Event *event; console->Create( NULL, getDefaultDMConsoleRectangle(), "Chat Window (Enter to send/close) (all|team|private to change message mode) : Messaging to All", UWindowColor, UHudColor ); console->setConsoleHandler(DMConsoleCommandHandler); console->setConsoleBackground(UBlack, 0.8f); console->setShow(false); console->Connect(&s_dmconsolehider, UIFloatingWindow::W_ClosePressed, UIFloatingWindow::W_ClosePressed); console->Connect(&s_dmconsolehider, W_Destroyed, W_Destroyed); event = new Event(EV_Widget_Disable); console->PassEventToWidget("closebutton", event); event = new Event(EV_Widget_Disable); console->PassEventToWidget("minimizebutton", event); return console; } /* ==================== getDefaultGMBoxRectangle ==================== */ static UIRect2D getDefaultGMBoxRectangle(void) { UIRect2D dmRect = getDefaultDMBoxRectangle(); float height = cls.glconfig.vidHeight * ui_compass_scale->value * 0.25f; float y = dmRect.size.height + dmRect.pos.y; if (height < y) { height = y; } return UIRect2D(20.0f, height, cls.glconfig.vidWidth - 20, 128.0f); } /* ==================== getDefaultDMBoxRectangle ==================== */ static UIRect2D getDefaultDMBoxRectangle(void) { float width = cls.glconfig.vidWidth * ui_compass_scale->value * 0.2f; return UIRect2D(width, 0, cls.glconfig.vidWidth - (width + 192.0f), 120.0f); } /* ==================== UI_ShowHudList ==================== */ void UI_ShowHudList(void) { for (int i = 1; i <= hudList.NumObjects(); i++) { hudList.ObjectAt(i)->ForceShow(); } } /* ==================== UI_HideHudList ==================== */ void UI_HideHudList(void) { for (int i = 1; i <= hudList.NumObjects(); i++) { hudList.ObjectAt(i)->ForceHide(); } } /* ==================== UI_DisplayHudList ==================== */ void UI_DisplayHudList(void) { for (int i = 1; i <= hudList.NumObjects(); i++) { Menu *pMenu = hudList.ObjectAt(i); UIWidget *pWidget = pMenu->GetContainerWidget(); pMenu->ForceShow(); pWidget->Display(uWinMan.getFrame(), 1.0); } } /* ==================== UI_PrintConsole ==================== */ void UI_PrintConsole(const char *msg) { UColor *pColor = NULL; const char *pszString; char szString[1024]; char szBlah[1024]; qboolean bPrintedDMBox = qfalse; pszString = msg; strncpy(szString, msg, 1024); if (*pszString < MESSAGE_MAX) { qboolean bNormalMessage = qfalse; qboolean bDMMessage = qfalse; qboolean bBold = qfalse; qboolean bDeathMessage = qfalse; switch (*pszString) { case MESSAGE_YELLOW: bNormalMessage = qtrue; pColor = &UHudColor; break; case MESSAGE_CHAT_WHITE: bDMMessage = qtrue; pColor = &UGrey; break; case MESSAGE_WHITE: bBold = qtrue; pColor = &UWhite; break; case MESSAGE_CHAT_RED: bDeathMessage = MESSAGE_CHAT_RED; pColor = &ULightRed; break; case MESSAGE_CHAT_GREEN: bDeathMessage = MESSAGE_CHAT_GREEN; pColor = &UGreen; break; } if (*pszString != 0) { pszString++; } // // print to the deathmatch console // if (dm_console && !bNormalMessage) { if (bDMMessage) { dm_console->AddDMMessageText(szString + 1, pColor); } else { dm_console->AddText(szString + 1, pColor); } } // // print to the deathmatch message box // if (dmbox) { if (bDMMessage) { *szString = MESSAGE_CHAT_WHITE; dmbox->Print(szString); pszString = msg + 1; bPrintedDMBox = qtrue; } else if (bDeathMessage) { dmbox->Print(szString); *szString = bDeathMessage; bPrintedDMBox = qtrue; } } // // print to the game message box // if (gmbox && !bPrintedDMBox) { if (bBold) { *szString = MESSAGE_WHITE; gmbox->Print(szString); uii.Snd_PlaySound("objective_text"); pszString = msg + 1; } else { gmbox->Print(szString + 1); } if (!ui_gmboxspam->integer) { return; } if (!bDMMessage) { memcpy(szBlah, "Game Message: ", 15); Q_strcat(szBlah, sizeof(szBlah), pszString); pszString = szBlah; } } } if (*pszString == '\a') { pszString++; if (mini_console) { mini_console->Print(pszString); return; } } if (fakk_console) { if (s_intermediateconsole) { fakk_console->AddText(*s_intermediateconsole, NULL); delete s_intermediateconsole; s_intermediateconsole = NULL; } fakk_console->AddText(pszString, pColor); if (mini_console) { mini_console->Print(pszString); } } else { if (!s_intermediateconsole) { s_intermediateconsole = new str; } *s_intermediateconsole = msg; } } /* ==================== UI_PrintDeveloperConsole ==================== */ void UI_PrintDeveloperConsole(const char *msg) { if (!developer_console) { return; } developer_console->AddText(msg, NULL); } /* ==================== UI_UpdateContinueGame ==================== */ void UI_UpdateContinueGame(void) { cvar_t *var; const char *name; const char *archive_name; int length; Event *event; var = Cvar_Get("g_lastsave", "", 0); name = var->string; if (*name) { archive_name = Com_GetArchiveFileName(name, "sav"); length = FS_ReadFileEx(archive_name, NULL, qtrue); if (length != -1) { event = new Event(EV_Widget_Enable); menuManager.PassEventToWidget("continue game", event); event = new Event(EV_Widget_Disable); menuManager.PassEventToWidget("new game", event); return; } Cvar_Set("g_lastsave", ""); } event = new Event(EV_Widget_Disable); menuManager.PassEventToWidget("continue game", event); event = new Event(EV_Widget_Enable); menuManager.PassEventToWidget("new game", event); } /* ==================== UI_MenuActive ==================== */ qboolean UI_MenuActive(void) { return menuManager.CurrentMenu() != NULL; } /* ==================== UI_FocusMenuIfExists ==================== */ void UI_FocusMenuIfExists(void) { Menu *currentMenu; int r_mode; currentMenu = menuManager.CurrentMenu(); r_mode = Cvar_VariableValue("r_mode"); if (currentMenu) { IN_MouseOn(); if (view3d->IsActive()) { uWinMan.DeactivateCurrentControl(); } currentMenu->ActivateMenu(); if (ui_newvidmode->integer == -1) { Cvar_Get("ui_newvidmode", va("%d", r_mode), CVAR_SERVER_CREATED); Cvar_SetValue("ui_newvidmode", r_mode); } } else { UI_ActivateView3D(); IN_MouseOff(); Cvar_SetValue("ui_newvidmode", -1); } } /* ==================== UI_OpenConsole ==================== */ void UI_OpenConsole(void) { if (!fakk_console) { return; } fakk_console->setShow(true); uWinMan.ActivateControl(fakk_console); IN_MouseOn(); } /* ==================== UI_OpenConsole ==================== */ qboolean UI_ConsoleIsVisible(void) { return fakk_console && fakk_console->IsVisible(); } /* ==================== UI_ConsoleIsOpen ==================== */ qboolean UI_ConsoleIsOpen(void) { return fakk_console && fakk_console->IsVisible() && fakk_console->IsActive(); } /* ==================== UI_CloseConsole ==================== */ void UI_CloseConsole(void) { if (fakk_console && fakk_console->getShow()) { fakk_console->setShow(false); } UI_FocusMenuIfExists(); } /* ==================== UI_ToggleConsole ==================== */ void UI_ToggleConsole(void) { if (!fakk_console) { return; } if (fakk_console->IsVisible()) { UI_CloseConsole(); } else { UI_OpenConsole(); } } /* ==================== UI_OpenDMConsole ==================== */ void UI_OpenDMConsole(int iMode) { if (!dm_console) { return; } UI_SetDMConsoleMode(iMode); dm_console->setShow(true); uWinMan.ActivateControl(dm_console); IN_MouseOff(); } /* ==================== UI_CloseDMConsole ==================== */ void UI_CloseDMConsole(void) { if (dm_console && dm_console->getShow()) { dm_console->setShow(false); } UI_FocusMenuIfExists(); } /* ==================== UI_ToggleDMConsole ==================== */ void UI_ToggleDMConsole(int iMode) { if (!dm_console) { return; } if (dm_console->IsVisible()) { if (UI_DMMessageModesMatch(iMode)) { UI_CloseDMConsole(); } else { UI_OpenDMConsole(iMode); } } else { UI_OpenDMConsole(iMode); } } /* ==================== UI_OpenDeveloperConsole ==================== */ void UI_OpenDeveloperConsole(void) { if (!developer_console) { return; } developer_console->setShow(true); uWinMan.ActivateControl(developer_console); IN_MouseOn(); } /* ==================== UI_CloseDeveloperConsole ==================== */ void UI_CloseDeveloperConsole(void) { if (developer_console && developer_console->getShow()) { developer_console->setShow(false); } UI_FocusMenuIfExists(); } /* ==================== UI_ToggleDeveloperConsole_f ==================== */ void UI_ToggleDeveloperConsole_f(void) { if (!developer_console) { return; } if (developer_console->IsThisOrChildActive()) { UI_CloseDeveloperConsole(); } else { UI_OpenDeveloperConsole(); } } /* ==================== UI_KeyEvent ==================== */ void UI_KeyEvent(int key, unsigned int time) { uWinMan.KeyEvent(key, time); } /* ==================== UI_CharEvent ==================== */ void UI_CharEvent(int ch) { uWinMan.CharEvent(ch); } /* ==================== UI_ClearBackground ==================== */ void UI_ClearBackground(void) { re.Set2DWindow( 0, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight, 0, -1, 1 ); re.Scissor(0, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight); re.SetColor(g_color_table[0]); re.DrawBox(0, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight); re.SetColor(NULL); } /* ==================== UI_ActivateView3D ==================== */ void UI_ActivateView3D(void) { if (!view3d) { return; } view3d->setShow(true); uWinMan.ActivateControl(view3d); } /* ==================== UI_DrawIntro ==================== */ void UI_DrawIntro(void) { if (clc.state == CA_CINEMATIC) { view3d->setShow(true); return; } view3d->setShow(false); UI_ClearBackground(); if (cls.startStage < 3 || cls.startStage >= 12) { return; } if (intro_stage.material->GetMaterial()) { float swidth; float sheight; vec4_t color; VectorSet4(color, 1, 1, 1, 1); if (intro_stage.fadetime) { float frac; frac = Q_clamp_float((cls.realtime - intro_stage.starttime) / intro_stage.fadetime, 0, 1); color[0] = color[1] = color[2] = intro_stage.alpha_start + frac * (intro_stage.alpha_end - intro_stage.alpha_start); } swidth = view3d->getFrame().getMaxX(); sheight = view3d->getFrame().getMaxY(); re.SetColor(color); re.DrawStretchPic(0.0, 0.0, swidth, sheight, 0.0, 0.0, 1.0, 1.0, intro_stage.material->GetMaterial()); re.SetColor(NULL); } if (cls.realtime >= intro_stage.endtime) { CL_FinishedStartStage(); } } /* ==================== UI_MenuUp ==================== */ qboolean UI_MenuUp() { return menuManager.CurrentMenu() != NULL; } /* ==================== UI_FullscreenMenuUp ==================== */ qboolean UI_FullscreenMenuUp() { Menu *currentMenu = menuManager.CurrentMenu(); if (currentMenu) { return currentMenu->isFullscreen(); } return qfalse; } /* ==================== UI_Update Updates the UI. ==================== */ void UI_Update(void) { Menu *currentMenu; UIRect2D frame; re.SetRenderTime(cls.realtime); CL_FillUIDef(); uWinMan.ServiceEvents(); // // draw the base HUD when in-game // if (cls.no_menus && clc.state == CA_ACTIVE) { view3d->setShow(true); frame = uWinMan.getFrame(); view3d->Display(frame, 1.0); if (ui_hud && !view3d->LetterboxActive()) { // draw the health hud if (hud_health) { hud_health->ForceShow(); frame = uWinMan.getFrame(); hud_health->GetContainerWidget()->Display(frame, 1.0); } // draw the ammo hud if (hud_ammo) { hud_ammo->ForceShow(); frame = uWinMan.getFrame(); hud_ammo->GetContainerWidget()->Display(frame, 1.0); } // draw the compass hud if (hud_compass) { hud_compass->ForceShow(); frame = uWinMan.getFrame(); hud_compass->GetContainerWidget()->Display(frame, 1.0); } } return; } if (fakk_console) { if (ui_minicon->integer) { // toggle the mini-console if (mini_console) { mini_console->setRealShow(fakk_console->getShow() ^ 1); } } else if (mini_console) { mini_console->setRealShow(false); } } if (gmbox) { gmbox->setRealShow(true); } if (dmbox) { dmbox->setRealShow(true); } currentMenu = menuManager.CurrentMenu(); if (currentMenu == menuManager.FindMenu("main")) { UI_MainMenuWidgetsUpdate(); } else if (currentMenu == menuManager.FindMenu("dm_main")) { UI_MultiplayerMainMenuWidgetsUpdate(); } // don't care about the intro if (!CL_FinishedIntro()) { UI_DrawIntro(); } else if (!server_loading && (clc.state == CA_CONNECTING || clc.state == CA_CHALLENGING) && ui_pConnectingMenu) { view3d->setShow(false); UI_ClearBackground(); if (UI_BindActive()) { Menu *bindMenu = menuManager.FindMenu("controls"); if (bindMenu) { Event *event = new Event(EV_UIFakkBindList_StopBind); bindMenu->PassEventToWidget("bindlist", event); } else { uWinMan.SetBindActive(NULL); } } if (clc.connectStartTime >= cls.realtime - 1000 * cl_connect_timeout->integer) { if (currentMenu != ui_pConnectingMenu) { UI_ForceMenuOff(true); UI_DeactiveFloatingWindows(); UI_ForceMenu("connecting"); uWinMan.showCursor(true); } } else { Com_Printf("\nConnect to server timed out\n"); UI_ForceMenuOff(true); Cbuf_AddText("disconnect;pushmenu servertimeout"); } } else { if (currentMenu && currentMenu->isFullscreen() && (!server_loading || !ui_pLoadingMenu)) { if (com_sv_running->integer && clc.state == CA_ACTIVE) { Com_FakePause(); } view3d->setShow(false); } else if (!server_loading) { if (clc.state <= CA_PRIMED) { view3d->setShow(false); UI_ClearBackground(); } else if (clc.state == CA_ACTIVE || clc.state == CA_CINEMATIC) { Com_FakeUnpause(); view3d->setShow(true); } else { UI_ClearBackground(); view3d->setShow(false); } } else { view3d->setShow(false); UI_ClearBackground(); if (UI_BindActive()) { Menu *bindMenu = menuManager.FindMenu("controls"); if (bindMenu) { Event *event = new Event(EV_UIFakkBindList_StopBind); bindMenu->PassEventToWidget("bindlist", event); } } else { uWinMan.SetBindActive(NULL); } if (ui_pLoadingMenu) { if (currentMenu != ui_pLoadingMenu) { UI_ForceMenuOff(true); UI_DeactiveFloatingWindows(); UI_ForceMenu(ui_sCurrentLoadingMenu); uWinMan.showCursor(false); } if (!developer->integer && UI_ConsoleIsVisible()) { UI_CloseConsole(); } } else if (ui_static_materials.loading) { ui_static_materials.loading->GetMaterial(); } } } // Hide the HUD when necessary if (!ui_hud || clc.state != CA_ACTIVE || view3d->LetterboxActive() || (currentMenu && currentMenu->isFullscreen()) || server_loading || ((cl.snap.ps.pm_flags & PMF_NO_HUD) || (cl.snap.ps.pm_flags & PMF_INTERMISSION))) { if (crosshairhud) { crosshairhud->ForceHide(); } if (hud_weapons) { hud_weapons->ForceHide(); ui_weapHudTime = 0; } if (hud_items) { hud_items->ForceHide(); ui_itemHudTime = 0; } if (hud_health) { hud_health->ForceHide(); } if (hud_ammo) { hud_ammo->ForceHide(); } if (hud_compass) { hud_compass->ForceHide(); } if (hud_boss) { hud_boss->ForceHide(); } UI_HideHudList(); } else { if (crosshairhud) { if (ui_crosshair->integer && cl.snap.ps.stats[STAT_CROSSHAIR]) { crosshairhud->ForceShow(); } else { crosshairhud->ForceHide(); } } // // show and highlight all weapons that the player holds // // // try to show the weapons bar // if (hud_weapons) { if (ui_weaponsbar->integer) { int iEquippedDiff = 0; int iOwnedDiff = 0; if (ui_weaponsbar->integer == 2) { ui_weapHudTime = cls.realtime + ui_weaponsbartime->value; } else if (ui_weaponsbar->integer != 3 && ui_itemHudTime && hud_items->isVisible()) { ui_weapHudTime = 0; } if (ui_lastWeapHudState_Owned != cl.snap.ps.stats[STAT_WEAPONS] || ui_lastWeapHudState_Equipped != cl.snap.ps.stats[STAT_EQUIPPED_WEAPON]) { iOwnedDiff = cl.snap.ps.stats[STAT_WEAPONS] ^ ui_lastWeapHudState_Owned & 0x3F; iEquippedDiff = (ui_lastWeapHudState_Equipped ^ cl.snap.ps.stats[STAT_EQUIPPED_WEAPON]) & 0x3F; // if we have different equipment, reset the weapons hud time if (iOwnedDiff || iEquippedDiff) { ui_weapHudTime = cls.realtime + ui_weaponsbartime->integer; } } // // show weapons that the player holds // if (iOwnedDiff) { if (iOwnedDiff & 1) { if (cl.snap.ps.stats[STAT_WEAPONS] & 1) { Event *event = new Event(EV_Widget_Disable); hud_weapons->PassEventToWidget("pistol_empty", event); } else { Event *event = new Event(EV_Widget_Enable); hud_weapons->PassEventToWidget("pistol_empty", event); } } if (iOwnedDiff & 2) { if (cl.snap.ps.stats[STAT_WEAPONS] & 2) { Event *event = new Event(EV_Widget_Disable); hud_weapons->PassEventToWidget("rifle_empty", event); } else { Event *event = new Event(EV_Widget_Enable); hud_weapons->PassEventToWidget("rifle_empty", event); } } if (iOwnedDiff & 4) { if (cl.snap.ps.stats[STAT_WEAPONS] & 4) { Event *event = new Event(EV_Widget_Disable); hud_weapons->PassEventToWidget("smg_empty", event); } else { Event *event = new Event(EV_Widget_Enable); hud_weapons->PassEventToWidget("smg_empty", event); } } if (iOwnedDiff & 8) { if (cl.snap.ps.stats[STAT_WEAPONS] & 8) { Event *event = new Event(EV_Widget_Disable); hud_weapons->PassEventToWidget("mg_empty", event); } else { Event *event = new Event(EV_Widget_Enable); hud_weapons->PassEventToWidget("mg_empty", event); } } if (iOwnedDiff & 16) { if (cl.snap.ps.stats[STAT_WEAPONS] & 16) { Event *event = new Event(EV_Widget_Disable); hud_weapons->PassEventToWidget("grenade_empty", event); } else { Event *event = new Event(EV_Widget_Enable); hud_weapons->PassEventToWidget("grenade_empty", event); } } if (iOwnedDiff & 32) { if (cl.snap.ps.stats[STAT_WEAPONS] & 32) { Event *event = new Event(EV_Widget_Disable); hud_weapons->PassEventToWidget("heavy_empty", event); } else { Event *event = new Event(EV_Widget_Enable); hud_weapons->PassEventToWidget("heavy_empty", event); } } ui_lastWeapHudState_Owned = cl.snap.ps.stats[STAT_WEAPONS] & 0x3F | ui_lastWeapHudState_Owned & ~0x3F; } // // highlight currently equipped weapons // if (iEquippedDiff) { if (iEquippedDiff & 1) { if (cl.snap.ps.stats[STAT_EQUIPPED_WEAPON] & 1) { Event *event = new Event(EV_Widget_Enable); hud_weapons->PassEventToWidget("pistol_equipped", event); } else { Event *event = new Event(EV_Widget_Disable); hud_weapons->PassEventToWidget("pistol_equipped", event); } } if (iEquippedDiff & 2) { if (cl.snap.ps.stats[STAT_EQUIPPED_WEAPON] & 2) { Event *event = new Event(EV_Widget_Enable); hud_weapons->PassEventToWidget("rifle_equipped", event); } else { Event *event = new Event(EV_Widget_Disable); hud_weapons->PassEventToWidget("rifle_equipped", event); } } if (iEquippedDiff & 4) { if (cl.snap.ps.stats[STAT_EQUIPPED_WEAPON] & 4) { Event *event = new Event(EV_Widget_Enable); hud_weapons->PassEventToWidget("smg_equipped", event); } else { Event *event = new Event(EV_Widget_Disable); hud_weapons->PassEventToWidget("smg_equipped", event); } } if (iEquippedDiff & 8) { if (cl.snap.ps.stats[STAT_EQUIPPED_WEAPON] & 8) { Event *event = new Event(EV_Widget_Enable); hud_weapons->PassEventToWidget("mg_equipped", event); } else { Event *event = new Event(EV_Widget_Disable); hud_weapons->PassEventToWidget("mg_equipped", event); } } if (iEquippedDiff & 16) { if (cl.snap.ps.stats[STAT_EQUIPPED_WEAPON] & 16) { Event *event = new Event(EV_Widget_Enable); hud_weapons->PassEventToWidget("grenade_equipped", event); } else { Event *event = new Event(EV_Widget_Disable); hud_weapons->PassEventToWidget("grenade_equipped", event); } } if (iEquippedDiff & 32) { if (cl.snap.ps.stats[STAT_EQUIPPED_WEAPON] & 32) { Event *event = new Event(EV_Widget_Enable); hud_weapons->PassEventToWidget("heavy_equipped", event); } else { Event *event = new Event(EV_Widget_Disable); hud_weapons->PassEventToWidget("heavy_equipped", event); } } ui_lastWeapHudState_Equipped = cl.snap.ps.stats[STAT_EQUIPPED_WEAPON] & 0x3F | ui_lastWeapHudState_Equipped & ~0x3F; } if (!ui_weapHudTime) { if (hud_weapons->isVisible()) { hud_weapons->ProcessEvent(EV_HideMenu); } } else if (ui_weapHudTime < cls.realtime || ui_itemHudTime > ui_weapHudTime) { ui_weapHudTime = 0; if (hud_weapons->isVisible()) { hud_weapons->ProcessEvent(EV_HideMenu); } } else if (!hud_weapons->isVisible()) { Event *event = new Event(EV_ShowMenu); event->AddInteger(false); hud_weapons->ProcessEvent(event); if (hud_items->isVisible()) { hud_items->ProcessEvent(EV_HideMenu); } } } else { hud_weapons->ForceHide(); ui_weapHudTime = 0; } } // // try to show the item bar // if (hud_items) { if (ui_weaponsbar->integer && ui_itemsbar->integer) { int iEquippedDiff = 0; int iOwnedDiff = 0; if (ui_weaponsbar->integer == 3) { ui_itemHudTime = cls.realtime + ui_weaponsbartime->integer; if (ui_weapHudTime && hud_weapons->isVisible()) { ui_itemHudTime = 0; } } if (ui_lastWeapHudState_Owned != cl.snap.ps.stats[STAT_WEAPONS] || ui_lastWeapHudState_Equipped != cl.snap.ps.stats[STAT_EQUIPPED_WEAPON]) { iOwnedDiff = cl.snap.ps.stats[STAT_WEAPONS] ^ ui_lastWeapHudState_Owned & 0xF00; iEquippedDiff = (ui_lastWeapHudState_Equipped ^ cl.snap.ps.stats[STAT_EQUIPPED_WEAPON]) & 0xF00; // if we have different equipment, reset the weapons hud time if (iOwnedDiff || iEquippedDiff) { ui_weapHudTime = cls.realtime + ui_weaponsbartime->integer; } } // // show items that the player holds // if (iOwnedDiff) { if (iOwnedDiff & 0x100) { if (cl.snap.ps.stats[STAT_WEAPONS] & 1) { Event *event = new Event(EV_Widget_Disable); hud_weapons->PassEventToWidget("slot1_icon", event); } else { Event *event = new Event(EV_Widget_Enable); hud_weapons->PassEventToWidget("slot1_icon", event); } } if (iOwnedDiff & 0x200) { if (cl.snap.ps.stats[STAT_WEAPONS] & 2) { Event *event = new Event(EV_Widget_Disable); hud_weapons->PassEventToWidget("slot2_icon", event); } else { Event *event = new Event(EV_Widget_Enable); hud_weapons->PassEventToWidget("slot2_icon", event); } } if (iOwnedDiff & 0x400) { if (cl.snap.ps.stats[STAT_WEAPONS] & 4) { Event *event = new Event(EV_Widget_Disable); hud_weapons->PassEventToWidget("slot3_icon", event); } else { Event *event = new Event(EV_Widget_Enable); hud_weapons->PassEventToWidget("slot3_icon", event); } } if (iOwnedDiff & 0x800) { if (cl.snap.ps.stats[STAT_WEAPONS] & 8) { Event *event = new Event(EV_Widget_Disable); hud_weapons->PassEventToWidget("slot4_icon", event); } else { Event *event = new Event(EV_Widget_Enable); hud_weapons->PassEventToWidget("slot4_icon", event); } } ui_lastWeapHudState_Owned = cl.snap.ps.stats[STAT_WEAPONS] & 0xF00 | (ui_lastWeapHudState_Owned & 0xF0); } // // highlight currently equipped weapons // else if (iEquippedDiff) { if (iEquippedDiff & 0x100) { if (cl.snap.ps.stats[STAT_EQUIPPED_WEAPON] & 1) { Event *event = new Event(EV_Widget_Disable); hud_weapons->PassEventToWidget("slot1_highlight", event); } else { Event *event = new Event(EV_Widget_Enable); hud_weapons->PassEventToWidget("slot1_highlight", event); } } else if (iEquippedDiff & 0x200) { if (cl.snap.ps.stats[STAT_EQUIPPED_WEAPON] & 2) { Event *event = new Event(EV_Widget_Disable); hud_weapons->PassEventToWidget("slot2_highlight", event); } else { Event *event = new Event(EV_Widget_Enable); hud_weapons->PassEventToWidget("slot2_highlight", event); } } else if (iEquippedDiff & 0x400) { if (cl.snap.ps.stats[STAT_EQUIPPED_WEAPON] & 4) { Event *event = new Event(EV_Widget_Disable); hud_weapons->PassEventToWidget("slot3_highlight", event); } else { Event *event = new Event(EV_Widget_Enable); hud_weapons->PassEventToWidget("slot3_highlight", event); } } else if (iEquippedDiff & 0x800) { if (cl.snap.ps.stats[STAT_EQUIPPED_WEAPON] & 8) { Event *event = new Event(EV_Widget_Disable); hud_weapons->PassEventToWidget("slot4_highlight", event); } else { Event *event = new Event(EV_Widget_Enable); hud_weapons->PassEventToWidget("slot4_highlight", event); } } else { ui_lastWeapHudState_Equipped = cl.snap.ps.stats[STAT_EQUIPPED_WEAPON] & 0xF00 | (ui_lastWeapHudState_Equipped & 0xF0); } } if (!ui_itemHudTime) { if (hud_items->isVisible()) { hud_items->ProcessEvent(EV_HideMenu); } } else if (ui_itemHudTime < cls.realtime || ui_weapHudTime > ui_itemHudTime) { ui_itemHudTime = 0; if (hud_items->isVisible()) { hud_items->ProcessEvent(EV_HideMenu); } } else if (!hud_items->isVisible()) { Event *event = new Event(EV_ShowMenu); event->AddInteger(false); hud_items->ProcessEvent(event); if (hud_weapons->isVisible()) { hud_weapons->ProcessEvent(EV_HideMenu); } } } else { hud_items->ForceHide(); ui_itemHudTime = 0; } } if (hud_health) { hud_health->ForceShow(); } // // show the ammo hud // str ammo = "hud_ammo_"; ammo += CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[ITEM_WEAPON]); if (!hud_ammo || hud_ammo->m_name.icmp(ammo)) { Menu *ammoMenu = menuManager.FindMenu(ammo); if (ammoMenu) { if (ammoMenu != hud_ammo) { if (hud_ammo) { hud_ammo->ForceHide(); } hud_ammo = ammoMenu; } } else { ammoMenu = menuManager.FindMenu("hud_ammo_"); if (ammoMenu) { if (ammoMenu != hud_ammo) { if (hud_ammo) { hud_ammo->ForceHide(); } hud_ammo = ammoMenu; } } } } if (hud_ammo) { hud_ammo->ForceShow(); } // // show the compass // if (hud_compass) { if (ui_compass->integer) { hud_compass->ForceShow(); } else { hud_compass->ForceHide(); } } // // show the boss health // if (hud_boss) { if (cl.snap.ps.stats[STAT_BOSSHEALTH] > 0 && !hud_boss->isVisible()) { Event *event = new Event(EV_ShowMenu); event->AddInteger(false); hud_boss->ProcessEvent(event); } else if (hud_boss->isVisible()) { hud_boss->ProcessEvent(EV_HideMenu); } } UI_ShowHudList(); } // // show the scoreboard // if (scoreboard_menu) { if (scoreboardlist && scoreboardlist->IsVisible()) { scoreboard_menu->ForceShow(); } else { scoreboard_menu->ForceHide(); } } uWinMan.UpdateViews(); } /* ==================== UI_MultiplayerMenuWidgetsUpdate ==================== */ void UI_MultiplayerMenuWidgetsUpdate(void) { Event *event; // allow the map change widget when running in-game if (com_sv_running->integer) { event = new Event(EV_Widget_Disable); menuManager.PassEventToWidget("startnew", event); if (clc.state > CA_PRIMED && !cg_gametype->integer) { event = new Event(EV_Widget_Disable); menuManager.PassEventToWidget("changemap", event); } else { event = new Event(EV_Widget_Enable); menuManager.PassEventToWidget("changemap", event); } } else { event = new Event(EV_Widget_Disable); menuManager.PassEventToWidget("changemap", event); event = new Event(EV_Widget_Enable); menuManager.PassEventToWidget("startnew", event); } // allow the disconnect widget when in-game if (clc.state > CA_PRIMED) { event = new Event(EV_Widget_Enable); menuManager.PassEventToWidget("disconnect", event); } else { event = new Event(EV_Widget_Disable); menuManager.PassEventToWidget("disconnect", event); } // allow the join widget when in-game if (com_sv_running->integer || clc.state > CA_PRIMED) { event = new Event(EV_Widget_Disable); menuManager.PassEventToWidget("joinlan", event); event = new Event(EV_Widget_Disable); menuManager.PassEventToWidget("joininternet", event); } else { event = new Event(EV_Widget_Enable); menuManager.PassEventToWidget("joinlan", event); event = new Event(EV_Widget_Enable); menuManager.PassEventToWidget("joininternet", event); } } /* ==================== UI_MainMenuWidgetsUpdate ==================== */ void UI_MainMenuWidgetsUpdate(void) { if (clc.state > CA_PRIMED) { Event *event = new Event(EV_Widget_Enable); menuManager.PassEventToWidget("backtogame", event); } else { Event *event = new Event(EV_Widget_Disable); menuManager.PassEventToWidget("backtogame", event); } UI_UpdateContinueGame(); } /* ==================== UI_MultiplayerMainMenuWidgetsUpdate ==================== */ // Added in 2.0 void UI_MultiplayerMainMenuWidgetsUpdate(void) { static const cvar_t *cg_allowvote = Cvar_Get("cg_allowvote", "1", 0); if (cg_allowvote->integer) { menuManager.PassEventToWidget("cantvote", new Event(EV_Widget_Disable)); if (atoi(CL_ConfigString(CS_VOTE_TIME))) { menuManager.PassEventToWidget("callvotebutton", new Event(EV_Widget_Disable)); if (cl.snap.ps.voted) { menuManager.PassEventToWidget("votebutton", new Event(EV_Widget_Disable)); menuManager.PassEventToWidget("alreadyvoted", new Event(EV_Widget_Enable)); } else { menuManager.PassEventToWidget("votebutton", new Event(EV_Widget_Enable)); menuManager.PassEventToWidget("alreadyvoted", new Event(EV_Widget_Disable)); } } else { menuManager.PassEventToWidget("callvotebutton", new Event(EV_Widget_Enable)); menuManager.PassEventToWidget("votebutton", new Event(EV_Widget_Disable)); menuManager.PassEventToWidget("alreadyvoted", new Event(EV_Widget_Disable)); } } else { menuManager.PassEventToWidget("callvotebutton", new Event(EV_Widget_Disable)); menuManager.PassEventToWidget("votebutton", new Event(EV_Widget_Disable)); menuManager.PassEventToWidget("alreadyvoted", new Event(EV_Widget_Disable)); menuManager.PassEventToWidget("cantvote", new Event(EV_Widget_Enable)); } UI_UpdateContinueGame(); } /* ==================== UI_ToggleMenu Toggle a menu ==================== */ void UI_ToggleMenu(str name) { Menu *menu; menu = menuManager.CurrentMenu(); if (menu) { UI_ForceMenuOff(false); if (menu->m_name != name) { UI_PushMenu(name); } } else { UI_PushMenu(name); } UI_FocusMenuIfExists(); } /* ==================== UI_ToggleMenu_f ==================== */ void UI_ToggleMenu_f() { if (Cmd_Argc() <= 1) { Com_Printf("Usage: togglemenu \n"); return; } UI_ToggleMenu(Cmd_Argv(1)); } /* ==================== UI_PopMenu ==================== */ void UI_PopMenu(qboolean restore_cvars) { Menu *menu; if (uWinMan.DialogExists()) { uWinMan.RemoveAllDialogBoxes(); return; } if (menuManager.CurrentMenu()) { menuManager.PopMenu(restore_cvars); } UI_FocusMenuIfExists(); menu = menuManager.CurrentMenu(); if (menu) { if (!str::cmp(menu->m_name, "main")) { UI_MainMenuWidgetsUpdate(); } else if (!str::cmp(menu->m_name, "dm_main")) { UI_MultiplayerMainMenuWidgetsUpdate(); } else if (!str::cmp(menu->m_name, "multiplayer")) { UI_MultiplayerMenuWidgetsUpdate(); } } } /* ==================== UI_DeactiveFloatingWindows ==================== */ void UI_DeactiveFloatingWindows(void) { uWinMan.DeactiveFloatingWindows(); } /* ==================== UI_PushMenu ==================== */ void UI_PushMenu(const char *name) { Menu *menu = menuManager.CurrentMenu(); qboolean bDiff = qfalse; if (menu) { bDiff = strcmp(menu->m_name, name) != 0; } if (!bDiff || !ui_pLoadingMenu || menu != ui_pLoadingMenu) { menuManager.PushMenu(name); } UI_FocusMenuIfExists(); if (!str::cmp(name, "main")) { UI_MainMenuWidgetsUpdate(); } else if (!str::cmp(name, "dm_main")) { UI_MultiplayerMainMenuWidgetsUpdate(); } else if (!str::cmp(name, "multiplayer")) { UI_MultiplayerMenuWidgetsUpdate(); } } /* ==================== UI_ForceMenu ==================== */ void UI_ForceMenu(const char *name) { Menu *menu = menuManager.CurrentMenu(); qboolean bDiff = qfalse; if (menu) { bDiff = strcmp(menu->m_name, name) != 0; } if (!menu || bDiff) { menuManager.ForceMenu(name); } UI_FocusMenuIfExists(); } /* ==================== UI_ShowMenu ==================== */ void UI_ShowMenu(const char *name, qboolean bForce) { Menu *pMenu; pMenu = menuManager.FindMenu(name); if (pMenu) { if (bForce) { pMenu->ForceShow(); } else if (!pMenu->isVisible()) { Event *event = new Event(EV_ShowMenu); event->AddInteger(false); pMenu->ProcessEvent(event); } } } /* ==================== UI_HideMenu ==================== */ void UI_HideMenu(const char *name, qboolean bForce) { Menu *pMenu; pMenu = menuManager.FindMenu(name); if (pMenu) { if (bForce) { pMenu->ForceHide(); } else if (pMenu->isVisible()) { pMenu->ProcessEvent(EV_HideMenu); } } } /* ==================== UI_PushMenu_f ==================== */ void UI_PushMenu_f(void) { if (Cmd_Argc() <= 1) { Com_Printf("Usage: pushmenu \n"); return; } UI_PushMenu(Cmd_Argv(1)); } /* ==================== UI_PushMenuSP_f ==================== */ void UI_PushMenuSP_f(void) { if (Cmd_Argc() <= 1) { Com_Printf("Usage: pushmenu_sp \n"); return; } if ((!com_cl_running || !com_cl_running->integer || clc.state == CA_DISCONNECTED || !cg_gametype->integer) && (!com_sv_running || !com_sv_running->integer || !g_gametype->integer)) { UI_PushMenu(Cmd_Argv(1)); } } /* ==================== UI_PushMenuMP_f ==================== */ void UI_PushMenuMP_f(void) { const char *cmd; if (Cmd_Argc() <= 1) { Com_Printf("Usage: pushmenu_mp \n"); return; } if (com_cl_running && com_cl_running->integer && clc.state != CA_DISCONNECTED && cg_gametype->integer && com_sv_running && com_sv_running->integer && g_gametype->integer) { cmd = Cmd_Argv(1); // // Push the right menu depending on the gametype // if (!Q_stricmp(cmd, "SelectTeam")) { switch (cg_gametype->integer) { case GT_FFA: UI_PushMenu("SelectFFAModel"); break; case GT_OBJECTIVE: UI_PushMenu("ObjSelectTeam"); break; default: UI_PushMenu("SelectTeam"); } } else { UI_PushMenu(cmd); } } } /* ==================== UI_ForceMenu_f ==================== */ void UI_ForceMenu_f(void) { if (Cmd_Argc() <= 1) { Com_Printf("Usage: forcemenu \n"); return; } UI_ForceMenu(Cmd_Argv(1)); } /* ==================== UI_PopMenu_f ==================== */ void UI_PopMenu_f(void) { if (Cmd_Argc() <= 1) { Com_Printf("Usage: popmenu "); return; } UI_PopMenu(atoi(Cmd_Argv(1))); } /* ==================== UI_ShowMenu_f ==================== */ void UI_ShowMenu_f(void) { qboolean bForce; const char *name; if (Cmd_Argc() <= 1) { Com_Printf("Usage: showmenu \n"); return; } name = Cmd_Argv(1); if (Cmd_Argc() > 2) { bForce = atoi(Cmd_Argv(2)); } else { bForce = qfalse; } UI_ShowMenu(name, bForce); } /* ==================== UI_HideMenu_f ==================== */ void UI_HideMenu_f(void) { qboolean bForce; const char *name; if (Cmd_Argc() <= 1) { Com_Printf("Usage: hidemenu \n"); return; } name = Cmd_Argv(1); if (Cmd_Argc() > 2) { bForce = atoi(Cmd_Argv(2)); } else { bForce = qfalse; } UI_HideMenu(name, bForce); } /* ==================== UI_WidgetCommand_f ==================== */ void UI_WidgetCommand_f(void) { str name; str commandstring; if (Cmd_Argc() <= 2) { Com_Printf("Usage: widgetcommand \n"); return; } name = Cmd_Argv(1); commandstring = Cmd_Argv(2); Event *event = new Event(commandstring); for (int i = 3; i < Cmd_Argc(); i++) { event->AddToken(Cmd_Argv(i)); } menuManager.PassEventToWidget(name, event); } /* ==================== UI_GlobalWidgetCommand_f ==================== */ void UI_GlobalWidgetCommand_f(void) { str name; str commandstring; if (Cmd_Argc() <= 2) { Com_Printf("Usage: globalwidgetcommand \n"); return; } name = Cmd_Argv(1); commandstring = Cmd_Argv(2); Event *event = new Event(commandstring); for (int i = 3; i < Cmd_Argc(); i++) { event->AddToken(Cmd_Argv(i)); } uWinMan.PassEventToWidget(name, event); } /* ==================== UI_ListMenus_f ==================== */ void UI_ListMenus_f() { menuManager.ListMenus(); } /* ==================== UI_BindActive ==================== */ qboolean UI_BindActive(void) { return uWinMan.BindActive() != NULL; } /* ==================== UI_SetReturnMenuToCurrent ==================== */ void UI_SetReturnMenuToCurrent(void) { Menu *currentMenu = menuManager.CurrentMenu(); if (currentMenu) { Cvar_Set("ui_returnmenu", currentMenu->m_name); } else { Cvar_Set("ui_returnmenu", ""); } } /* ==================== UI_PushReturnMenu ==================== */ qboolean UI_PushReturnMenu() { str sMenuName; if (!ui_returnmenu->string || !*ui_returnmenu->string) { return qfalse; } sMenuName = ui_returnmenu->string; UI_PushMenu(sMenuName); Cvar_Set("ui_returnmenu", ""); UI_FocusMenuIfExists(); if (!menuManager.CurrentMenu()) { return qfalse; } if (!str::cmp(sMenuName, "main")) { UI_MainMenuWidgetsUpdate(); } else if (!str::cmp(sMenuName, "dm_main")) { UI_MultiplayerMainMenuWidgetsUpdate(); } else if (!str::cmp(sMenuName, "multiplayer")) { UI_MultiplayerMenuWidgetsUpdate(); } return qtrue; } /* ==================== UI_PushReturnMenu_f ==================== */ void UI_PushReturnMenu_f(void) { UI_PushReturnMenu(); } /* ==================== UI_MenuEscape ==================== */ void UI_MenuEscape(const char *name) { if (server_loading) { return; } if (uWinMan.BindActive()) { UI_KeyEvent(K_ESCAPE, qfalse); return; } if (menuManager.CurrentMenu() == mainmenu && clc.state == CA_DISCONNECTED) { if (developer->integer) { if (UI_ConsoleIsVisible()) { UI_CloseConsole(); } else { UI_OpenConsole(); } } return; } if (uWinMan.DialogExists()) { uWinMan.RemoveAllDialogBoxes(); return; } if (menuManager.CurrentMenu()) { menuManager.PopMenu(qtrue); } else if (!Q_stricmp(name, "main") && clc.state > CA_PRIMED && cg_gametype->integer > 0) { // multiplayer UI_PushMenu("dm_main"); } else { // single-player UI_PushMenu(name); } UI_FocusMenuIfExists(); if (menuManager.CurrentMenu()) { if (!str::cmp(name, "main")) { UI_MainMenuWidgetsUpdate(); } else if (!str::cmp(name, "dm_main")) { UI_MultiplayerMainMenuWidgetsUpdate(); } else if (!str::cmp(name, "multiplayer")) { UI_MultiplayerMenuWidgetsUpdate(); } } } /* ==================== UI_ForceMenuOff ==================== */ void UI_ForceMenuOff(bool force) { menuManager.ClearMenus(force); UI_FocusMenuIfExists(); } /* ==================== UI_UpdateConnectionString ==================== */ void UI_UpdateConnectionString(void) {} /* ==================== UI_ParseServerInfoMessage ==================== */ void UI_ParseServerInfoMessage(msg_t *msg) {} /* ==================== UI_DrawConnectText ==================== */ void UI_DrawConnectText(void) {} /* ==================== UI_DrawConnect ==================== */ void UI_DrawConnect(void) { Com_Printf("UI_DrawConnect called\n"); } /* ==================== CL_PingServers_f ==================== */ void CL_PingServers_f(void) { int i; netadr_t adr; char name[32]; const char *adrstring; cvar_t *noudp; cvar_t *noipx; Com_Printf("pinging broadcast...\n"); noudp = Cvar_Get("noudp", "0", CVAR_INIT); if (!noudp->integer) { adr.type = NA_BROADCAST; adr.port = BigShort(12203); NET_OutOfBandPrint(NS_SERVER, adr, "info %i", 8); } noipx = Cvar_Get("noipx", "0", CVAR_INIT); if (!noipx->integer) { adr.type = NA_BROADCAST_IPX; adr.port = BigShort(12203); NET_OutOfBandPrint(NS_SERVER, adr, "info %i", 8); } for (i = 0; i < 16; i++) { Com_sprintf(name, sizeof(name), "adr%i", i); adrstring = Cvar_VariableString(name); if (adrstring && *adrstring) { Com_Printf("pinging %s...\n", adrstring); if (NET_StringToAdr(adrstring, &adr, NA_IP)) { if (!adr.port) { adr.port = BigShort(12203); } NET_OutOfBandPrint(NS_SERVER, adr, "info %i", 8); } else { Com_Printf("Bad address: %s\n", adrstring); } } } } /* ==================== UI_MapList_f ==================== */ void UI_MapList_f(void) { str mappath = "maps"; if (Cmd_Argc() == 2) { mappath += "/"; mappath += Cmd_Argv(1); } MapRunnerClass *map = new MapRunnerClass; map->Setup("maps", mappath, ".bsp", "_sml"); CL_SetMousePos(cls.glconfig.vidWidth / 2, cls.glconfig.vidHeight / 2); } /* ==================== UI_DMMapSelect_f ==================== */ void UI_DMMapSelect_f(void) { str basepath = "maps"; str mappath; str gametype; if (Cmd_Argc() > 1) { const char *path; path = Cmd_Argv(1); if (strcmp(path, ".")) { basepath += "/"; basepath += path; } if (Cmd_Argc() > 2) { path = Cmd_Argv(2); if (strcmp(path, ".")) { mappath += "maps/"; mappath += path; } } if (Cmd_Argc() > 3) { gametype = Cmd_Argv(3); } } MpMapPickerClass *map = new MpMapPickerClass; map->Setup(basepath, mappath, gametype); CL_SetMousePos(cls.glconfig.vidWidth / 2, cls.glconfig.vidHeight / 2); } /* ==================== UI_StartDMMap_f ==================== */ void UI_StartDMMap_f(void) { int iDedicated; int iMaxClients; int iUseGameSpy; int iGameType = GT_FFA; int iFragLimit; int iTimeLimit; int iTeamDamage; int iInactiveSpectate; int iInactiveKick; const char *pszTemp; const char *pszGameTypeString = "Free-For-All"; const char *pszMapName; const char *pszMapListCvar = "sv_maplist"; const char *pszMapListString; char szHostName[32]; if (Cmd_Argc() > 1) { iGameType = atoi(Cmd_Argv(1)); if (Cmd_Argc() > 2) { pszGameTypeString = Cmd_Argv(2); if (Cmd_Argc() > 3) { pszMapListCvar = Cmd_Argv(3); } } } pszMapName = CvarGetForUI("ui_dmmap", ""); if (!*pszMapName) { return; } iDedicated = atoi(CvarGetForUI("ui_dedicated", "0")); if (iDedicated < 0) { iDedicated = 0; } else if (iDedicated > 1) { iDedicated = 1; } Cvar_SetValue("ui_dedicated", iDedicated); iMaxClients = atoi(CvarGetForUI("ui_maxclients", "0")); if (iMaxClients < 1) { iMaxClients = 1; } else if (iMaxClients > MAX_CLIENTS) { iMaxClients = MAX_CLIENTS; } Cvar_SetValue("ui_maxclients", iMaxClients); iUseGameSpy = atoi(CvarGetForUI("ui_gamespy", "0")); if (iUseGameSpy < 0) { iUseGameSpy = 0; } else if (iUseGameSpy > 1) { iUseGameSpy = 1; } Cvar_SetValue("ui_gamespy", iUseGameSpy); iFragLimit = atoi(CvarGetForUI("ui_fraglimit", "0")); if (iFragLimit < 0) { iFragLimit = 0; } Cvar_SetValue("ui_fraglimit", iFragLimit); iTimeLimit = atoi(CvarGetForUI("ui_timelimit", "0")); if (iTimeLimit < 0) { iTimeLimit = 0; } Cvar_SetValue("ui_timelimit", iTimeLimit); iTeamDamage = atoi(CvarGetForUI("ui_teamdamage", "0")); if (iTeamDamage < 0) { iTeamDamage = 0; } else if (iTeamDamage > 1) { iTeamDamage = 1; } Cvar_SetValue("ui_teamdamage", iTeamDamage); iInactiveSpectate = atoi(CvarGetForUI("ui_inactivespectate", "0")); if (iInactiveSpectate < 0) { iInactiveSpectate = 0; } Cvar_SetValue("ui_inactivespectate", iInactiveSpectate); iInactiveKick = atoi(CvarGetForUI("ui_inactivekick", "0")); if (iInactiveKick < 0) { iInactiveKick = 0; } Cvar_SetValue("ui_inactivekick", iInactiveKick); pszMapListString = CvarGetForUI(pszMapListCvar, ""); pszTemp = CvarGetForUI("ui_hostname", "Nameless Battle"); Q_strncpyz(szHostName, pszTemp, sizeof(szHostName)); for (int i = 0; i < sizeof(szHostName); i++) { if (szHostName[i] == ';' || szHostName[i] == '"' || szHostName[i] == '\\') { szHostName[i] = '_'; } } Cvar_Set("ui_hostname", szHostName); Cbuf_AddText( va("set dedicated %i;" "set sv_maxclients %i;" "set sv_gamespy %i;" "set g_gametype %i;" "set g_gametypestring \"%s\";" "set fraglimit %i;" "set timelimit %i;" "set g_teamdamage %i;" "set g_inactivespectate %i;" "set g_inactivekick %i;" "set sv_maplist \"%s\";" "set sv_hostname \"%s\";" "set cheats 0;" "wait;" "map \"%s\"\n", iDedicated, iMaxClients, iUseGameSpy, iGameType, pszGameTypeString, iFragLimit, iTimeLimit, iTeamDamage, iInactiveSpectate, iInactiveKick, pszMapListString, szHostName, pszMapName) ); } /* ==================== UI_PlayerModel_f ==================== */ void UI_PlayerModel_f(void) { qboolean bGermanModel; str modelpath = "models/player"; bGermanModel = qfalse; if (Cmd_Argc() > 1) { bGermanModel = atoi(Cmd_Argv(1)) ? qtrue : qfalse; if (Cmd_Argc() == 3) { modelpath += "/"; modelpath += Cmd_Argv(2); } } PlayerModelPickerClass *picker = new PlayerModelPickerClass; picker->Setup("models/player", modelpath, bGermanModel); CL_SetMousePos(cls.glconfig.vidWidth / 2, cls.glconfig.vidHeight / 2); } /* ==================== UI_ApplyPlayerModel_f ==================== */ void UI_ApplyPlayerModel_f(void) { const char *pszUIPlayerModel; char donotshowssindeorfr[64]; pszUIPlayerModel = CvarGetForUI("ui_dm_playermodel_set", "american_army"); Cvar_Set("dm_playermodel", pszUIPlayerModel); pszUIPlayerModel = CvarGetForUI("ui_dm_playergermanmodel_set", "german_wehrmacht_soldier"); if (!Q_stricmpn(pszUIPlayerModel, "german_waffen", 14)) { Q_strcat(donotshowssindeorfr, sizeof(donotshowssindeorfr), pszUIPlayerModel + 14); Cvar_Set("dm_playergermanmodel", donotshowssindeorfr); } else { Cvar_Set("dm_playergermanmodel", pszUIPlayerModel); } Cvar_Set("name", CvarGetForUI("ui_name", "UnnamedSoldier")); } /* ==================== UI_GetPlayerModel_f ==================== */ void UI_GetPlayerModel_f(void) { const char *pszUIPlayerModel; char donotshowssindeorfr[64]; // // Allies // pszUIPlayerModel = CvarGetForUI("dm_playermodel", "american_army"); Cvar_Set("ui_dm_playermodel", PM_FilenameToDisplayname(pszUIPlayerModel)); Cvar_Set("ui_dm_playermodel_set", pszUIPlayerModel); Cvar_Set("ui_disp_playermodel", va("models/player/%s.tik", pszUIPlayerModel)); // // Axis // pszUIPlayerModel = CvarGetForUI("dm_playergermanmodel", "german_wehrmacht_soldier"); Cvar_Set("ui_dm_playergermanmodel", PM_FilenameToDisplayname(pszUIPlayerModel)); Cvar_Set("ui_dm_playergermanmodel_set", pszUIPlayerModel); if (!strncmp(pszUIPlayerModel, "german_waffen_", 14)) { Q_strncpyz(donotshowssindeorfr, "german_waffenss_", sizeof(donotshowssindeorfr)); Q_strcat(donotshowssindeorfr, sizeof(donotshowssindeorfr), pszUIPlayerModel + 14); Cvar_Set("ui_disp_playergermanmodel", va("models/player/%s.tik", donotshowssindeorfr)); } else { Cvar_Set("ui_disp_playergermanmodel", va("models/player/%s.tik", pszUIPlayerModel)); } Cvar_Set("ui_name", CvarGetForUI("name", "UnnamedSoldier")); } /* ==================== UI_SoundPicker_f ==================== */ void UI_SoundPicker_f(void) { new SoundPickerClass; } /* ==================== UI_ViewSpawnList_f ==================== */ void UI_ViewSpawnList_f(void) { str modelpath = "models"; ViewSpawnerClass *picker = new ViewSpawnerClass; picker->Setup("models", modelpath, ".tik"); } /* ==================== UI_LODSpawnList_f ==================== */ void UI_LODSpawnList_f(void) { str modelpath = "models"; LODSpawnerClass *picker = new LODSpawnerClass; picker->Setup("models", modelpath, ".tik"); } /* ==================== UI_Notepad_f ==================== */ void UI_Notepad_f(void) { if (Cmd_Argc() > 1) { UI_LoadNotepadFile(Cmd_Argv(1)); } else { UI_LoadNotepadFile(NULL); } } /* ==================== UI_EditScript_f ==================== */ void UI_EditScript_f(void) { const char *info; const char *mname; str mapname; str mappath; // editscript only works in-game if (clc.state != CA_ACTIVE) { Com_Printf("You need to load a map to edit its script\n"); return; } mname = Info_ValueForKey(&cl.gameState.stringData[cl.gameState.stringOffsets[CS_SERVERINFO]], "mapname"); mapname = mname; // remove the spawnpoint name if (strchr(mname, '$')) { info = strchr(mname, '$'); mapname[info - mname] = 0; } // make sure the map is loaded if (!strcmp(mapname, "")) { Com_Printf("No map loaded?\n"); return; } mappath = "maps/" + mapname + ".scr"; if (!UI_LoadNotepadFile(mappath)) { Com_Printf("Couldn't load/find script file for %s\n", mappath.c_str()); } } /* ==================== UI_EditShader_f ==================== */ void UI_EditShader_f(void) { str shaderpath; if (Cmd_Argc() != 2) { Com_Printf("Usage: Editshader \n"); return; } shaderpath = "scripts/" + str(Cmd_Argv(1)) + ".shader"; if (!UI_LoadNotepadFile(shaderpath)) { Com_Printf("Couldn't open shader named %s\n", shaderpath.c_str()); } } /* ==================== UI_EditSpecificShader_f ==================== */ void UI_EditSpecificShader_f(void) {} /* ==================== UI_LoadMenu ==================== */ void UI_LoadMenu(const char *name) { char buffer[256]; Com_sprintf(buffer, sizeof(buffer), "ui/%s", name); COM_StripExtension(buffer, buffer, sizeof(buffer)); Q_strcat(buffer, 256, ".urc"); new UILayout(buffer); uWinMan.CreateMenus(); UI_FocusMenuIfExists(); } /* ==================== UI_LoadMenu_f ==================== */ void UI_LoadMenu_f(void) { UI_LoadMenu(Cmd_Argv(1)); } /* ==================== CvarGetForUI ==================== */ const char *CvarGetForUI(const char *name, const char *defval) { cvar_t *cvar = Cvar_FindVar(name); if (cvar) { if (cvar->latchedString && *cvar->latchedString) { return cvar->latchedString; } else { return cvar->string; } } else { return defval; } } /* ==================== ListFilesForUI ==================== */ void ListFilesForUI(const char *filespec) { int nfiles; char **filenames; filenames = FS_ListFiles("", filespec, qfalse, &nfiles); for (int i = 0; i < nfiles; i++) { uie.AddFileToList(filenames[i]); } FS_FreeFileList(filenames); } /* ==================== IsKeyDown ==================== */ int IsKeyDown(int key) { return keys[key].down; } /* ==================== UI_WantsKeyboard ==================== */ void UI_WantsKeyboard() { Key_SetCatcher(Key_GetCatcher() | KEYCATCH_UI); } struct widgettrans_s { const char *src; const char *dst; }; static widgettrans_s s_widgettrans[2] = { {"Label", "FakkLabel"}, {NULL, NULL } }; /* ==================== TranslateWidgetName ==================== */ const char *TranslateWidgetName(const char *widget) { widgettrans_s *trans = &s_widgettrans[0]; for (int i = 0; trans->src != NULL; i++, trans++) { if (!strcmp(trans->src, widget)) { return trans->dst; } } return NULL; } /* ==================== UI_Cvar_Set ==================== */ void UI_Cvar_Set(const char *var_name, const char *value) { Cvar_Set2(var_name, value, qfalse); } /* ==================== CL_FillUIDef ==================== */ void CL_FillUIDef(void) { CL_GetMouseState(&uid.mouseX, &uid.mouseY, &uid.mouseFlags); uid.time = cls.realtime; uid.vidHeight = cls.glconfig.vidHeight; uid.vidWidth = cls.glconfig.vidWidth; uid.uiHasMouse = in_guimouse != qfalse; } /* ==================== UI_RegisterSound ==================== */ sfxHandle_t UI_RegisterSound(const char *sample, qboolean streamed) { return S_RegisterSound(sample, streamed, qfalse); } /* ==================== UI_FadeSound ==================== */ void UI_FadeSound(float fTime) { S_FadeSound(fTime); } /* ==================== UI_StopAll ==================== */ void UI_StopAll() { S_StopAllSounds2(qtrue); } /* ==================== UI_StartLocalSound ==================== */ void UI_StartLocalSound(const char *sound_name) { S_StartLocalSound(sound_name, qtrue); } /* ==================== UI_StartLocalSoundDialog ==================== */ void UI_StartLocalSoundDialog(const char *sound_name) { S_StartLocalSoundChannel(sound_name, qtrue, CHAN_DIALOG); } /* ==================== CL_FillUIImports ==================== */ void CL_FillUIImports(void) { uii.Rend_DrawBox = re.DrawBox; uii.Rend_DrawPicStretched = re.DrawStretchPic; uii.Rend_DrawPicStretched2 = re.DrawStretchPic2; uii.Rend_DrawPicTiled = re.DrawTilePic; uii.Rend_GetShaderHeight = re.GetShaderHeight; uii.Rend_GetShaderWidth = re.GetShaderWidth; uii.Rend_DrawString = re.DrawString; uii.Rend_LoadFont = re.LoadFont; uii.Rend_RegisterMaterial = re.RegisterShaderNoMip; uii.Rend_RefreshMaterial = re.RefreshShaderNoMip; uii.Rend_Scissor = re.Scissor; uii.Rend_Set2D = re.Set2DWindow; uii.Rend_SetColor = re.SetColor; uii.Cmd_Stuff = Cbuf_AddText; uii.Cvar_GetString = CvarGetForUI; uii.Cvar_Reset = Cvar_Reset; uii.Cvar_Find = Cvar_FindVar; uii.Cvar_Set = UI_Cvar_Set; uii.File_PickFile = PickFile; uii.File_FreeFile = FS_FreeFile; uii.File_ListFiles = ListFilesForUI; uii.File_OpenFile = FS_ReadFile; uii.File_WriteFile = FS_WriteTextFile; uii.Snd_PlaySound = UI_StartLocalSound; uii.Snd_PlaySoundDialog = UI_StartLocalSoundDialog; uii.Snd_RegisterSound = UI_RegisterSound; uii.Snd_FadeSound = UI_FadeSound; uii.Snd_StopAllSound = UI_StopAll; uii.Alias_Add = Alias_Add; uii.Alias_FindRandom = Alias_FindRandom; uii.Sys_Error = Com_Error; uii.Sys_IsKeyDown = IsKeyDown; uii.Sys_Milliseconds = Sys_Milliseconds; uii.Sys_Printf = Com_Printf; uii.Sys_DPrintf = Com_DPrintf; uii.Sys_GetClipboard = Sys_GetWholeClipboard; uii.Sys_SetClipboard = Sys_SetClipboard; uii.Cmd_CompleteCommandByNumber = Cmd_CompleteCommandByNumber; uii.Cvar_CompleteCvarByNumber = Cvar_CompleteVariableByNumber; uii.UI_WantsKeyboard = UI_WantsKeyboard; uii.Client_TranslateWidgetName = TranslateWidgetName; uii.Connect = CL_Connect; uii.Key_GetKeynameForCommand = Key_GetKeynameForCommand; uii.Key_GetCommandForKey = Key_GetBinding; uii.Key_SetBinding = Key_SetBinding; uii.Key_GetKeysForCommand = Key_GetKeysForCommand; uii.Key_KeynumToString = Key_KeynumToBindString; uii.GetConfigstring = CL_ConfigString; uii.UI_CloseDMConsole = UI_CloseDMConsole; } /* ==================== CL_BeginRegistration ==================== */ void CL_BeginRegistration(void) { // init console stuff re.BeginRegistration(&cls.glconfig); uWinMan.CleanupShadersFromList(); } /* ==================== CL_EndRegistration ==================== */ void CL_EndRegistration(void) { int start, end; start = Sys_Milliseconds(); S_EndRegistration(); re.EndRegistration(); if (!Sys_LowPhysicalMemory()) { Com_TouchMemory(); } end = Sys_Milliseconds(); Com_Printf("CL_EndRegistration: %5.2f seconds\n", (float)(start - end) / 1000.0); } /* ==================== UI_CreateDialog ==================== */ void UI_CreateDialog( const char *title, char *cvarname, const char *command, const char *cancelCommand, int width, int height, const char *shader, const char *okshader, const char *cancelshader ) { UIDialog *dlg = new UIDialog; UIRect2D rect = UIRect2D((cls.glconfig.vidWidth - width) >> 1, (cls.glconfig.vidHeight - height) >> 1, width, height); UColor bgColor = UWindowColor; dlg->Create(NULL, rect, title, bgColor, UHudColor); dlg->LinkCvar(cvarname); dlg->SetOKCommand(command); dlg->SetCancelCommand(cancelCommand); dlg->SetLabelMaterial(uWinMan.RegisterShader(shader)); dlg->SetOkMaterial(uWinMan.RegisterShader(okshader)); if (cancelshader) { dlg->SetCancelMaterial(uWinMan.RegisterShader(cancelshader)); } uWinMan.ActivateControl(dlg); } /* ==================== UI_ResolutionChange ==================== */ void UI_ResolutionChange(void) { UIRect2D frame; ui_compass_scale = Cvar_Get("ui_compass_scale", "0.75", CVAR_ARCHIVE | CVAR_LATCH); CL_FillUIImports(); CL_FillUIDef(); if (!uie.ResolutionChange) { return; } if (fakk_console) { frame = getDefaultConsoleRectangle(); fakk_console->setFrame(frame); } if (dm_console) { if (dm_console->GetQuickMessageMode()) { frame = getQuickMessageDMConsoleRectangle(); } else { frame = getDefaultDMConsoleRectangle(); } dm_console->setFrame(frame); } if (developer_console) { frame = getDefaultConsoleRectangle(); developer_console->setFrame(frame); } if (scoreboardlist) { delete scoreboardlist; scoreboardlist = NULL; UI_CreateScoreboard(); } uie.ResolutionChange(); menuManager.RealignMenus(); if (view3d) { frame = UIRect2D(0, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight); view3d->setFrame(frame); } if (gmbox) { frame = getDefaultGMBoxRectangle(); gmbox->setFrame(frame); } if (dmbox) { frame = getDefaultDMBoxRectangle(); dmbox->setFrame(frame); } } /* ==================== UI_FinishLoadingScreen_f ==================== */ void UI_FinishLoadingScreen_f(void) { Com_Unpause(); UI_ForceMenuOff(qtrue); ui_pLoadingMenu = NULL; ui_sCurrentLoadingMenu = ""; server_loading = qfalse; server_loading_waiting = qfalse; UI_ActivateView3D(); } /* ==================== S_ServerLoaded ==================== */ void S_ServerLoaded(void) { if (!svs.soundsNeedLoad) { return; } svs.soundsNeedLoad = qfalse; Com_DPrintf("Loading Previous Sound State.\n"); S_StopAllSounds2(qfalse); S_TriggeredMusic_Stop(); s_bSoundPaused = qtrue; S_ReLoad(&svs.soundSystem); if (svs.tm_filename[0]) { S_TriggeredMusic_SetupHandle(svs.tm_filename, svs.tm_loopcount, svs.tm_offset, 0); } } /* ==================== UI_ServerLoaded ==================== */ void UI_ServerLoaded(void) { Menu *pCurrentMenu; cvar_t *pMaxClients; Event *event; CL_UpdateSnapFlags(); SV_ServerLoaded(); S_FadeSound(0); S_ServerLoaded(); if (!server_loading) { return; } UI_EndLoad(); pMaxClients = Cvar_Get("sv_maxclients", "1", 0); if (com_sv_running->integer && pMaxClients->integer > 1) { SV_Heartbeat_f(); } uWinMan.showCursor(true); if (!ui_pLoadingMenu) { UI_FinishLoadingScreen_f(); return; } pCurrentMenu = menuManager.CurrentMenu(); if (pCurrentMenu != ui_pLoadingMenu || !pCurrentMenu->GetNamedWidget("continuebutton") || !com_sv_running->integer || pMaxClients->integer > 1) { UI_FinishLoadingScreen_f(); return; } if (ui_sCurrentLoadingMenu == "loading_default") { UI_FinishLoadingScreen_f(); return; } server_loading_waiting = qtrue; event = new Event(EV_Widget_Enable); ui_pLoadingMenu->PassEventToWidget("continuebutton", event); event = new Event(EV_Widget_Disable); ui_pLoadingMenu->PassEventToWidget("loadingflasher", event); event = new Event(EV_Widget_Disable); ui_pLoadingMenu->PassEventToWidget("loadingbar", event); event = new Event(EV_Widget_Disable); ui_pLoadingMenu->PassEventToWidget("loadingbar_border", event); event = new Event(EV_Widget_Activate); ui_pLoadingMenu->PassEventToWidget("continuebutton", event); Com_FakePause(); } /* ==================== UI_ClearCenterPrint ==================== */ void UI_ClearCenterPrint(void) { if (view3d) { view3d->ClearCenterPrint(); } } /* ==================== UI_UpdateCenterPrint ==================== */ void UI_UpdateCenterPrint(const char *s, float alpha) { view3d->UpdateCenterPrint(s, alpha); } /* ==================== UI_UpdateLocationPrint ==================== */ void UI_UpdateLocationPrint(int x, int y, const char *s, float alpha) { view3d->UpdateLocationPrint(x, y, s, alpha); } /* ==================== UI_CenterPrint_f ==================== */ void UI_CenterPrint_f(void) { const char *s; float alpha; if (Cmd_Argc() <= 1) { Com_Printf("Usage: centerprintf string [alpha]\n"); return; } s = Cmd_Argv(1); if (Cmd_Argc() > 2) { alpha = atof(Cmd_Argv(2)); } else { alpha = 1.0; } UI_UpdateCenterPrint(s, alpha); } /* ==================== UI_LocationPrint_f ==================== */ void UI_LocationPrint_f(void) { int x, y; const char *s; float alpha; if (Cmd_Argc() <= 3) { Com_Printf("Usage: locatinprint x y string [alpha]\n"); return; } x = atoi(Cmd_Argv(1)); y = atoi(Cmd_Argv(2)); s = Cmd_Argv(3); if (Cmd_Argc() > 4) { alpha = atof(Cmd_Argv(4)); } else { alpha = 1.0; } UI_UpdateLocationPrint(x, y, s, alpha); } /* ==================== UI_LoadInventory_f ==================== */ void UI_LoadInventory_f(void) { UI_CloseInventory(); CL_LoadInventory(ui_inventoryfile->string, &client_inv); } /* ==================== UI_ClearState ==================== */ void UI_ClearState(void) { S_FadeSound(0.0); UI_ClearCenterPrint(); if (gmbox) { gmbox->Clear(); } if (dmbox) { dmbox->Clear(); } } /* ==================== UI_CheckRestart ==================== */ void UI_CheckRestart(void) { if (ui_console->integer && !fakk_console) { fakk_console = getNewConsole(); } if (!dm_console) { dm_console = getNewDMConsole(); } if (!ui_console->integer && fakk_console) { fakk_console->SendSignal(W_Destroyed); } if (ui_minicon->integer) { if (!mini_console) { UISize2D size; UColor back = UColor(0.0, 0.5, 1.0, 1.0); size.width = 500; size.height = 100; mini_console = new FakkMiniconsole; mini_console->Create(size, UHudColor, back, 0.3f); mini_console->setAlwaysOnBottom(true); mini_console->setBorderStyle(border_none); } } else if (mini_console) { delete mini_console; mini_console = NULL; } if (ui_gmbox->integer) { if (!gmbox) { UIRect2D frame; gmbox = new UIGMBox; frame = getDefaultGMBoxRectangle(); gmbox->Create(frame, UHudColor, UHudColor, 0); gmbox->setAlwaysOnBottom(true); gmbox->setBorderStyle(border_none); } } else if (gmbox) { delete gmbox; gmbox = NULL; } if (!dmbox) { UIRect2D frame; dmbox = new UIDMBox; frame = getDefaultDMBoxRectangle(); dmbox->Create(frame, UHudColor, UHudColor, 0); dmbox->setAlwaysOnBottom(true); dmbox->setBorderStyle(border_outline); } menuManager.CheckRestart(); } /* ==================== UI_ResetCvars ==================== */ void UI_ResetCvars(void) { menuManager.ResetCVars(); } /* ==================== UI_ShowMouse_f ==================== */ void UI_ShowMouse_f(void) { if (view3d->IsActive()) { uWinMan.DeactivateCurrentControl(); } } /* ==================== UI_HideMouse_f ==================== */ void UI_HideMouse_f(void) { if (!view3d->IsActive()) { uWinMan.ActivateControl(view3d); IN_MouseOff(); } } class TestListItem : public UIListCtrlItem { str strings[3]; public: virtual griditemtype_t getListItemType(int which) const; virtual str getListItemString(int i) const; virtual int getListItemValue(int which) const; virtual void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont); virtual qboolean IsHeaderEntry(void) const; }; /* ==================== UI_TestListCtrl_f ==================== */ void UI_TestListCtrl_f(void) { UIFloatingWindow *wnd = new UIFloatingWindow; UIListCtrl *control; UIRect2D frame = UIRect2D(20, 20, 400, 300); TestListItem *i1, *i2, *i3; wnd->Create(NULL, frame, "Test list control", UWindowColor, UHudColor); control = new UIListCtrl; control->InitFrame( wnd->getChildSpace(), frame.pos.x, frame.pos.y, frame.size.width, frame.size.height, border_none, "verdana-12" ); control->setBackgroundColor(UWhite, true); control->AddColumn("name", 0, 100, false, false); control->AddColumn("ping", 1, 64, false, false); control->AddColumn("IP", 2, 64, false, false); for (int i = 0; i < 100; i++) { i1 = new TestListItem; control->AddItem(i1); i2 = new TestListItem; control->AddItem(i2); i3 = new TestListItem; control->AddItem(i3); } } class StatsUpdater : public Listener { public: CLASS_PROTOTYPE(StatsUpdater); void UpdateStats(Event *ev); }; Event EV_StatsUpdater_UpdateStats("updatestats", EV_DEFAULT, NULL, NULL, "Update the stats on the missionLog"); CLASS_DECLARATION(Listener, StatsUpdater, NULL) { {NULL, NULL} }; static StatsUpdater statsUpdater; static str loadName; void StatsUpdater::UpdateStats(Event *ev) { cvar_t *pMaxClients = Cvar_Get("sv_maxclients", "1", 0); if (!com_sv_running->integer || pMaxClients->integer > 1) { return; } if (paused && !paused->integer) { CL_AddReliableCommand("stats", qfalse); } Event *event = new Event(EV_StatsUpdater_UpdateStats); PostEvent(event, 2.0); } static int statsRequestTime; static bool intermission_stats_up; static bool isMissionLogVisible; /* ==================== UI_ShowScoreboard_f ==================== */ void UI_ShowScoreboard_f(const char *pszMenuName) { if (pszMenuName) { if (scoreboard_menuname.length()) { if (str::icmp(scoreboard_menuname, pszMenuName)) { scoreboard_menu->ForceHide(); } } scoreboard_menuname = pszMenuName; } if (UI_MenuActive()) { if (scoreboard_menuname.length()) { scoreboard_menu = menuManager.FindMenu(scoreboard_menuname); if (scoreboard_menu) { scoreboard_menu->ForceHide(); } } if (scoreboardlist && scoreboardlist->IsVisible()) { scoreboardlist->setShow(false); } } else { if (scoreboard_menuname.length()) { scoreboard_menu = menuManager.FindMenu(scoreboard_menuname); if (scoreboard_menu) { UIWidget *widget = scoreboard_menu->GetContainerWidget(); if (widget) { widget->BringToFrontPropogated(); } scoreboard_menu->ForceShow(); } } if (scoreboardlist && !scoreboardlist->IsVisible()) { scoreboardlist->setShow(true); } } } /* ==================== UI_HideScoreboard_f ==================== */ void UI_HideScoreboard_f(void) { if (scoreboardlist) { scoreboardlist->setShow(false); } if (scoreboard_menuname.length()) { scoreboard_menu->ForceHide(); } } class ScoreboardListItem : public UIListCtrlItem { str strings[8]; qboolean bColorSet; UColor backColor; UColor textColor; qboolean bTitleItem; public: ScoreboardListItem(); void SetListItemStrings( const char *string1, const char *string2, const char *string3, const char *string4, const char *string5, const char *string6, const char *string7, const char *string8 ); virtual griditemtype_t getListItemType(int which) const; virtual str getListItemString(int i) const; virtual int getListItemValue(int which) const; virtual void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont); void SetColors(const UColor& newTextColor, const UColor& newBackColor); void ClearColors(void); void SetTitleItem(qboolean bSet); virtual qboolean IsHeaderEntry(void) const; }; ScoreboardListItem::ScoreboardListItem() { bColorSet = false; bTitleItem = false; } void ScoreboardListItem::DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) { DrawBox(drawRect, backColor, 1.0); pFont->setColor(textColor); pFont->Print(drawRect.pos.x + 1, drawRect.pos.y, Sys_LV_CL_ConvertString(getListItemString(iColumn)), -1, qfalse); if (bTitleItem) { UIRect2D lineRect; UColor lineColor = backColor; lineRect = drawRect; lineRect.pos.y += lineRect.size.height - 2.0; lineRect.size.height = 2.0; DrawBox(lineRect, lineColor, 1.0); } } void ScoreboardListItem::SetColors(const UColor& newTextColor, const UColor& newBackColor) { textColor = newTextColor; backColor = newBackColor; bColorSet = true; } void ScoreboardListItem::ClearColors(void) { bColorSet = false; } /* ==================== UI_CreateScoreboard ==================== */ void UI_CreateScoreboard(void) { int i; int iColumnWidth; float w, h, x, y; float fColumnScale; float fR, fG, fB, fA; float fFontR, fFontG, fFontB, fFontA; const char *pszColumnName; if (!cge) { return; } scoreboardlist = new UIListCtrl; cge->CG_GetScoreBoardPosition(&x, &y, &w, &h); scoreboard_x = x; scoreboard_y = y; scoreboard_w = w; scoreboard_h = h; SCR_AdjustFrom640(&x, &y, &w, &h); fColumnScale = cls.glconfig.vidWidth / 640.0; cge->CG_GetScoreBoardColor(&fR, &fG, &fB, &fA); cge->CG_GetScoreBoardFontColor(&fFontR, &fFontG, &fFontB, &fFontA); scoreboardlist->InitFrame(NULL, x, y, w, h, -1, "verdana-12"); scoreboardlist->setBackgroundColor(UColor(fR, fG, fB, fA), true); scoreboardlist->setForegroundColor(UColor(fFontR, fFontG, fFontB, fFontA)); for (i = 0; i < 8; i++) { pszColumnName = cge->CG_GetColumnName(i, &iColumnWidth); if (!pszColumnName) { break; } scoreboardlist->AddColumn(pszColumnName, i, iColumnWidth * fColumnScale + 0.5, false, false); } scoreboard_header = cge->CG_GetScoreBoardDrawHeader(); scoreboardlist->setShow(false); scoreboardlist->AllowActivate(false); scoreboardlist->setAlwaysOnBottom(true); scoreboardlist->SetUseScrollBar(false); scoreboardlist->SetDrawHeader(scoreboard_header); scoreboardlist->setHeaderFont("facfont-20"); } /* ==================== UI_SetScoreBoardItem ==================== */ void UI_SetScoreBoardItem( int iItemNumber, const char *pszData1, const char *pszData2, const char *pszData3, const char *pszData4, const char *pszData5, const char *pszData6, const char *pszData7, const char *pszData8, const vec4_t pTextColor, const vec4_t pBackColor, qboolean bIsHeader ) { int i; float x, y, w, h; ScoreboardListItem *pItem; if (iItemNumber >= 64) { return; } if (scoreboardlist) { cge->CG_GetScoreBoardPosition(&x, &y, &w, &h); // Recreate the scoreboard if it has different rect if (scoreboard_x != x || scoreboard_y != y || scoreboard_w != w || scoreboard_h != h || scoreboard_header != cge->CG_GetScoreBoardDrawHeader()) { delete scoreboardlist; scoreboardlist = NULL; UI_CreateScoreboard(); } } else { UI_CreateScoreboard(); } if (scoreboardlist) { if (iItemNumber + 1 > scoreboardlist->getNumItems()) { pItem = new ScoreboardListItem; scoreboardlist->AddItem(pItem); } else { pItem = (ScoreboardListItem *)scoreboardlist->GetItem(iItemNumber + 1); } if (pItem) { if (!pszData1) { pszData1 = ""; } if (!pszData2) { pszData2 = ""; } if (!pszData3) { pszData3 = ""; } if (!pszData4) { pszData4 = ""; } if (!pszData5) { pszData5 = ""; } if (!pszData6) { pszData6 = ""; } if (!pszData7) { pszData7 = ""; } if (!pszData8) { pszData8 = ""; } pItem->SetListItemStrings(pszData1, pszData2, pszData3, pszData4, pszData5, pszData6, pszData7, pszData8); if (pTextColor && pBackColor) { UColor textColor, backColor; textColor = UColor(pTextColor[0], pTextColor[1], pTextColor[2], pTextColor[3]); backColor = UColor(pBackColor[0], pBackColor[1], pBackColor[2], pBackColor[3]); pItem->SetColors(textColor, backColor); } else { pItem->ClearColors(); } for (i = 0; i < 8; i++) { pItem->getListItemString(i); } pItem->SetTitleItem(bIsHeader); } } } /* ==================== UI_DeleteScoreBoardItems ==================== */ void UI_DeleteScoreBoardItems(int iMaxIndex) { while (iMaxIndex + 1 <= scoreboardlist->getNumItems()) { scoreboardlist->DeleteItem(scoreboardlist->getNumItems()); } } /* ==================== UI_Hud_f ==================== */ void UI_Hud_f(void) { qboolean hide; if (Cmd_Argc() != 2) { Com_Printf("Usage: ui_hud [1|0]"); return; } ui_hud = atoi(Cmd_Argv(1)); hide = !ui_hud; if (hud_weapons && hide) { hud_weapons->ForceHide(); ui_weapHudTime = 0; } if (hud_items && hide) { hud_items->ForceHide(); ui_itemHudTime = 0; } if (hud_health) { if (hide) { hud_health->ForceHide(); } else { hud_health->ForceShow(); } } if (hud_ammo) { if (hide) { hud_ammo->ForceHide(); } else { hud_ammo->ForceShow(); } } if (hud_compass) { if (hide) { hud_compass->ForceHide(); } else { hud_compass->ForceShow(); } } if (hide) { UI_HideHudList(); } else { UI_ShowHudList(); } if (ui_hud) { Cvar_Set("cg_hud", "1"); } else { Cvar_Set("cg_hud", "0"); } } /* ==================== UI_ClearConsole_f ==================== */ void UI_ClearConsole_f(void) { if (fakk_console) { fakk_console->Clear(); } if (dm_console) { dm_console->Clear(); } if (developer_console) { developer_console->Clear(); } } /* ==================== CL_FinishedIntro ==================== */ qboolean CL_FinishedIntro(void) { return cls.startStage == 0; } /* ==================== CL_FinishedStartStage ==================== */ void CL_FinishedStartStage(void) { int wait; switch (cls.startStage++) { case 1: Cbuf_ExecuteText(EXEC_NOW, "cinematic EAlogo.RoQ\n"); break; case 2: intro_stage.alpha_start = 0.0; intro_stage.alpha_end = 1.0; wait = ui_titlescreen_fadein->value * 1000.0; intro_stage.fadetime = wait; intro_stage.starttime = cls.realtime; intro_stage.endtime = cls.realtime + wait; intro_stage.material = uWinMan.RegisterShader("mohaa_title"); break; case 3: intro_stage.alpha_start = 1.0; intro_stage.alpha_end = 1.0; wait = ui_legalscreen_stay->value * 1000.0; intro_stage.fadetime = 0.0; intro_stage.starttime = cls.realtime; intro_stage.endtime = cls.realtime + wait; break; case 4: intro_stage.alpha_start = 1.0; intro_stage.alpha_end = 0.0; wait = ui_titlescreen_fadeout->value * 1000.0; intro_stage.fadetime = wait; intro_stage.starttime = cls.realtime; intro_stage.endtime = cls.realtime + wait; break; case 5: intro_stage.alpha_start = 0.0; intro_stage.alpha_end = 1.0; wait = ui_legalscreen_fadein->value * 1000.0; intro_stage.fadetime = wait; intro_stage.starttime = cls.realtime; intro_stage.endtime = cls.realtime + wait; intro_stage.material = uWinMan.RegisterShader("legal"); break; case 6: intro_stage.alpha_start = 1.0; intro_stage.alpha_end = 1.0; wait = ui_legalscreen_stay->value * 1000.0; intro_stage.fadetime = 0.0; intro_stage.starttime = cls.realtime; intro_stage.endtime = cls.realtime + wait; break; case 7: intro_stage.alpha_start = 1.0; intro_stage.alpha_end = 0.0; wait = ui_legalscreen_fadeout->value * 1000.0; intro_stage.fadetime = wait; intro_stage.starttime = cls.realtime; intro_stage.endtime = cls.realtime + wait; break; case 8: if (com_target_game->integer >= target_game_e::TG_MOHTA) { cls.startStage = 0; return; } Cbuf_ExecuteText(EXEC_NOW, "cinematic 2015intro.RoQ\n"); break; case 9: Cbuf_ExecuteText(EXEC_NOW, "cinematic intro.RoQ\n"); break; case 10: cls.startStage = 0; break; default: break; } } /* ==================== UI_StartStageKeyEvent ==================== */ void UI_StartStageKeyEvent(void) { switch (cls.startStage) { case 2: if (ui_skip_eamovie->integer) { SCR_StopCinematic(); } break; case 3: case 4: case 5: if (ui_skip_titlescreen->integer) { cls.startStage = 5; CL_FinishedStartStage(); } break; case 6: case 7: case 8: if (ui_skip_legalscreen->integer) { cls.startStage = 8; CL_FinishedStartStage(); } break; case 9: case 10: SCR_StopCinematic(); break; default: break; } } /* ==================== UI_StartIntro_f ==================== */ void UI_StartIntro_f(void) { cls.startStage = 1; IN_MouseOff(); CL_FinishedStartStage(); } /* ==================== CL_TryStartIntro ==================== */ void CL_TryStartIntro(void) { if (developer->integer || !cl_playintro->integer) { UI_ToggleConsole(); } else { // FIXME: no intro from now Cvar_Set(cl_playintro->name, "0"); UI_StartIntro_f(); } } /* ==================== SaveConsoleRectangle ==================== */ static void SaveConsoleRectangle(void) { bool wasMinimized; UIRect2D r; if (!fakk_console) { return; } wasMinimized = fakk_console->IsMinimized(); if (wasMinimized) { fakk_console->ProcessEvent(UIFloatingWindow::W_MinimizePressed); } if (!fakk_console->IsMinimized()) { r = fakk_console->getFrame(); Cvar_Set( "ui_consoleposition", va("%d %d %d %d", (int)r.pos.x, (int)r.pos.y, (int)r.size.width, (int)r.size.height) ); if (wasMinimized) { fakk_console->ProcessEvent(UIFloatingWindow::W_MinimizePressed); } } } /* ==================== LoadConsoleRectangle ==================== */ static void LoadConsoleRectangle(void) { bool wasMinimized; if (!fakk_console) { return; } wasMinimized = fakk_console->IsMinimized(); if (wasMinimized) { fakk_console->ProcessEvent(UIFloatingWindow::W_MinimizePressed); } if (!fakk_console->IsMinimized() && wasMinimized) { fakk_console->ProcessEvent(UIFloatingWindow::W_MinimizePressed); } } /* ==================== UI_AddHud_f ==================== */ void UI_AddHud_f(void) { Menu *hud = menuManager.FindMenu(Cmd_Argv(1)); if (hud) { if (!hudList.ObjectInList(hud)) { hudList.AddObject(hud); } hud->ShowMenu(NULL); } else { Com_DPrintf("Hud %s not found in menu system.\n", Cmd_Argv(1)); } } /* ==================== UI_RemoveHud_f ==================== */ void UI_RemoveHud_f(void) { Menu *hud = menuManager.FindMenu(Cmd_Argv(1)); if (hud && hudList.ObjectInList(hud)) { hud->ForceHide(); hudList.RemoveObject(hud); } } /* ==================== UI_StartServer_f ==================== */ void UI_StartServer_f(void) { const char *map = Cmd_Argv(1); if (strlen(map)) { Cbuf_AddText(va("map %s\n", map)); } } /* ==================== UI_ShowStatistics_f ==================== */ void UI_ShowStatistics_f() { cvar_t *pMaxClients = Cvar_Get("sv_maxclients", "1", 0); if (!com_sv_running->integer || pMaxClients->integer > 1) { return; } if (missionLog && !isMissionLogVisible) { isMissionLogVisible = true; missionLog->ShowMenu(NULL); IN_MouseOn(); } if (statsRequestTime + 2000 <= cls.realtime) { if (paused && !paused->integer) { statsRequestTime = cls.realtime; CL_AddReliableCommand("stats", qfalse); Event *event = new Event(EV_StatsUpdater_UpdateStats); statsUpdater.PostEvent(event, 2.0); } } } /* ==================== UI_HideStatistics_f ==================== */ void UI_HideStatistics_f() { cvar_t *pMaxClients = Cvar_Get("sv_maxclients", "1", 0); if (!com_sv_running->integer || pMaxClients->integer > 1) { return; } if (missionLog) { isMissionLogVisible = false; missionLog->HideMenu(&EV_HideMenu); IN_MouseOff(); } statsUpdater.CancelEventsOfType(EV_StatsUpdater_UpdateStats); } /* ==================== CL_ShutdownUI ==================== */ void CL_ShutdownUI(void) { if (!cls.uiStarted) { return; } if (s_intermediateconsole) { delete s_intermediateconsole; s_intermediateconsole = NULL; } // remove all UI commands Cmd_RemoveCommand("pushmenu"); Cmd_RemoveCommand("forcemenu"); Cmd_RemoveCommand("popmenu"); Cmd_RemoveCommand("showmenu"); Cmd_RemoveCommand("widgetcommand"); Cmd_RemoveCommand("listmenus"); Cmd_RemoveCommand("togglemenu"); Cmd_RemoveCommand("loadmenu"); Cmd_RemoveCommand("maplist"); Cmd_RemoveCommand("dmmapselect"); Cmd_RemoveCommand("ui_startdmmap"); Cmd_RemoveCommand("viewspawnlist"); Cmd_RemoveCommand("lod_spawnlist"); Cmd_RemoveCommand("soundpicker"); Cmd_RemoveCommand("notepad"); Cmd_RemoveCommand("editscript"); Cmd_RemoveCommand("editshader"); Cmd_RemoveCommand("inv_restart"); Cmd_RemoveCommand("ui_showmouse"); Cmd_RemoveCommand("ui_hidemouse"); Cmd_RemoveCommand("ui_saveconsolepos"); Cmd_RemoveCommand("ui_loadconsolepos"); Cmd_RemoveCommand("ui_testlist"); Cmd_RemoveCommand("clear"); Cmd_RemoveCommand("ui_hud"); Cmd_RemoveCommand("ui_resetcvars"); Cmd_RemoveCommand("ui_checkrestart"); Cmd_RemoveCommand("ui_addhud"); Cmd_RemoveCommand("ui_removehud"); Cmd_RemoveCommand("centerprint"); Cmd_RemoveCommand("locationprint"); Cmd_RemoveCommand("startserver"); Cmd_RemoveCommand("finishloadingscreen"); Cmd_RemoveCommand("playermodel"); Cmd_RemoveCommand("ui_applyplayermodel"); Cmd_RemoveCommand("ui_getplayermodel"); Cmd_RemoveCommand("devcon"); Cmd_RemoveCommand("+statistics"); Cmd_RemoveCommand("-statistics"); for (int i = 0; i < hudList.NumObjects(); i++) { hudList.RemoveObjectAt(i); } // Removed in 2.0 // Crosshair is now handled by the cgame module //crosshairhud = menuManager.FindMenu("crosshair"); hud_weapons = menuManager.FindMenu("hud_weapons"); hud_items = menuManager.FindMenu("hud_items"); hud_health = menuManager.FindMenu("hud_health"); hud_compass = menuManager.FindMenu("hud_compass"); hud_boss = menuManager.FindMenu("hud_boss"); ui_pConnectingMenu = menuManager.FindMenu("connecting"); // delete base hud if (view3d) { delete view3d; view3d = NULL; } if (fakk_console) { delete fakk_console; fakk_console = NULL; } if (dm_console) { delete dm_console; dm_console = NULL; } if (developer_console) { delete developer_console; developer_console = NULL; } if (mini_console) { delete mini_console; mini_console = NULL; } // delete game hud if (crosshairhud) { crosshairhud = NULL; } if (hud_weapons) { hud_weapons = NULL; } if (hud_items) { hud_items = NULL; } if (hud_health) { hud_health = NULL; } if (hud_ammo) { hud_ammo = NULL; } if (hud_compass) { hud_compass = NULL; } if (hud_boss) { hud_boss = NULL; } // delete informations hud if (scoreboardlist) { delete scoreboardlist; scoreboardlist = NULL; } if (gmbox) { delete gmbox; gmbox = NULL; } if (dmbox) { delete dmbox; dmbox = NULL; } // clear inventory client_inv.Clear(); // shutdown the UI uie.Shutdown(); // delete all menus menuManager.DeleteAllMenus(); cls.uiStarted = false; } /* ==================== CL_InitUI ==================== */ #define UI_OLD_API_VERSION 4 void CL_InitializeUI(void) { int nfiles; char **filenames; int i; // Register all variables ui_minicon = Cvar_Get("ui_minicon", "0", 1); ui_gmbox = Cvar_Get("ui_gmbox", "1", 1); ui_consoleposition = Cvar_Get("ui_consoleposition", "", 1); ui_console = Cvar_Get("ui_console", "0", 1); ui_crosshair = Cvar_Get("ui_crosshair", "1", 1); ui_weaponsbar = Cvar_Get("ui_weaponsbar", "1", 1); ui_weaponsbartime = Cvar_Get("ui_weaponsbartime", "2500", 1); ui_itemsbar = Cvar_Get("ui_itemsbar", "0", 1); sound_overlay = Cvar_Get("soundoverlay", "0", 0); ui_debugload = Cvar_Get("ui_debugload", "0", 0); Cvar_Get("ui_signshader", "", 0); ui_compass = Cvar_Get("ui_compass", "1", 0); ui_newvidmode = Cvar_Get("ui_newvidmode", "-1", 0); ui_inventoryfile = Cvar_Get("ui_inventoryfile", "global/inventory.txt", 0); ui_drawcoords = Cvar_Get("ui_drawcoords", "0", 0); ui_health_start = Cvar_Get("ui_health_start", "0", 0); ui_health_end = Cvar_Get("ui_health_end", "0", 0); ui_GunneryEvaluation = Cvar_Get("ui_GunneryEvaluation", "0", 0); ui_GroinShots = Cvar_Get("ui_GroinShots", "0", 0); ui_RightArmShots = Cvar_Get("ui_RightArmShots", "0", 0); ui_LeftArmShots = Cvar_Get("ui_LeftArmShots", "0", 0); ui_RightLegShots = Cvar_Get("ui_RightLegShots", "0", 0); ui_LeftLegShots = Cvar_Get("ui_LeftLegShots", "0", 0); ui_TorsoShots = Cvar_Get("ui_TorsoShots", "0", 0); ui_HeadShots = Cvar_Get("ui_HeadShots", "0", 0); ui_NumEnemysKilled = Cvar_Get("ui_NumEnemysKilled", "0", 0); ui_NumObjectsDestroyed = Cvar_Get("ui_NumObjectsDestroyed", "0", 0); ui_NumHitsTaken = Cvar_Get("ui_NumHitsTaken", "0", 0); ui_PreferredWeapon = Cvar_Get("ui_PreferredWeapon", "none", 0); ui_Accuracy = Cvar_Get("ui_Accuracy", "0", 0); ui_NumObjectives = Cvar_Get("ui_NumObjectives", "0", 0); ui_NumComplete = Cvar_Get("ui_NumComplete", "0", 0); ui_NumHits = Cvar_Get("ui_NumHits", "0", 0); ui_NumShotsFired = Cvar_Get("ui_NumShotsFired", "0", 0); ui_gmboxspam = Cvar_Get("ui_gmboxspam", "1", 0); ui_gotmedal = Cvar_Get("ui_gotmedal", "0", 0); ui_success = Cvar_Get("ui_success", "0", 0); ui_failed = Cvar_Get("ui_failed", "0", 0); ui_returnmenu = Cvar_Get("ui_returnmenu", "0", 0); ui_skip_eamovie = Cvar_Get("ui_skip_eamovie", "1", 0); ui_skip_titlescreen = Cvar_Get("ui_skip_titlescreen", "1", 0); ui_skip_legalscreen = Cvar_Get("ui_skip_legalscreen", "1", 0); ui_titlescreen_fadein = Cvar_Get("ui_titlescreen_fadein", "1", 0); ui_titlescreen_fadeout = Cvar_Get("ui_titlescreen_fadeout", "1", 0); ui_titlescreen_stay = Cvar_Get("ui_titlescreen_stay", "3", 0); ui_legalscreen_fadein = Cvar_Get("ui_legalscreen_fadein", "1", 0); ui_legalscreen_fadeout = Cvar_Get("ui_legalscreen_fadeout", "1", 0); ui_legalscreen_stay = Cvar_Get("ui_legalscreen_stay", "3", 0); cl_greenfps = Cvar_Get("cl_greenfps", "0", 1); cl_playintro = Cvar_Get("cl_playintro", "1", 0); cl_movieaudio = Cvar_Get("cl_movieaudio", "1", 0); Cvar_Get("ui_startmap", "", 1); Cvar_Get("dlg_badsave", "This save game is invalid", 0); Cvar_Set("cg_hud", ui_hud ? "1" : "0"); CL_FillUIDef(); CL_FillUIImports(); UI_InitExports(); uie.Init(); UI_LoadInventory_f(); UI_CreateScoreboard(); // New since mohta // Version number Cvar_Set("game_version", va("v%s", com_target_version->string)); // Add all commands Cmd_AddCommand("pushmenu", UI_PushMenu_f); Cmd_AddCommand("pushmenu_sp", UI_PushMenuSP_f); Cmd_AddCommand("pushmenu_dm", UI_PushMenuMP_f); Cmd_AddCommand("forcemenu", UI_ForceMenu_f); Cmd_AddCommand("popmenu", UI_PopMenu_f); Cmd_AddCommand("showmenu", UI_ShowMenu_f); Cmd_AddCommand("hidemenu", UI_HideMenu_f); Cmd_AddCommand("widgetcommand", UI_WidgetCommand_f); Cmd_AddCommand("globalwidgetcommand", UI_GlobalWidgetCommand_f); Cmd_AddCommand("listmenus", UI_ListMenus_f); Cmd_AddCommand("togglemenu", UI_ToggleMenu_f); Cmd_AddCommand("loadmenu", UI_LoadMenu_f); Cmd_AddCommand("maplist", UI_MapList_f); Cmd_AddCommand("dmmapselect", UI_DMMapSelect_f); Cmd_AddCommand("ui_startdmmap", UI_StartDMMap_f); Cmd_AddCommand("viewspawnlist", UI_ViewSpawnList_f); Cmd_AddCommand("lod_spawnlist", UI_LODSpawnList_f); Cmd_AddCommand("soundpicker", UI_SoundPicker_f); Cmd_AddCommand("notepad", UI_Notepad_f); Cmd_AddCommand("editscript", UI_EditScript_f); Cmd_AddCommand("editshader", UI_EditShader_f); Cmd_AddCommand("editspecificshader", UI_EditSpecificShader_f); Cmd_AddCommand("inv_restart", UI_LoadInventory_f); Cmd_AddCommand("ui_showmouse", UI_ShowMouse_f); Cmd_AddCommand("ui_hidemouse", UI_HideMouse_f); Cmd_AddCommand("ui_saveconsolepos", SaveConsoleRectangle); Cmd_AddCommand("ui_loadconsolepos", LoadConsoleRectangle); Cmd_AddCommand("ui_testlist", UI_TestListCtrl_f); Cmd_AddCommand("clear", UI_ClearConsole_f); Cmd_AddCommand("ui_hud", UI_Hud_f); Cmd_AddCommand("ui_resetcvars", UI_ResetCvars); Cmd_AddCommand("ui_checkrestart", UI_CheckRestart); Cmd_AddCommand("centerprint", UI_CenterPrint_f); Cmd_AddCommand("locationprint", UI_LocationPrint_f); Cmd_AddCommand("ui_addhud", UI_AddHud_f); Cmd_AddCommand("ui_removehud", UI_RemoveHud_f); Cmd_AddCommand("startserver", UI_StartServer_f); Cmd_AddCommand("finishloadingscreen", UI_FinishLoadingScreen_f); Cmd_AddCommand("playermodel", UI_PlayerModel_f); Cmd_AddCommand("ui_applyplayermodel", UI_ApplyPlayerModel_f); Cmd_AddCommand("ui_getplayermodel", UI_GetPlayerModel_f); Cmd_AddCommand("+statistics", UI_ShowStatistics_f); Cmd_AddCommand("-statistics", UI_HideStatistics_f); Cmd_AddCommand("setreturnmenu", UI_SetReturnMenuToCurrent); Cmd_AddCommand("gotoreturnmenu", UI_PushReturnMenu_f); if (developer->integer) { UColor bgColor; Cmd_AddCommand("devcon", UI_ToggleDeveloperConsole_f); developer_console = new UIFloatingConsole; bgColor = UWindowColor; developer_console->Create(NULL, getDefaultConsoleRectangle(), "Developer Console", bgColor, UHudColor); developer_console->setConsoleHandler(ConsoleCommandHandler); developer_console->setConsoleBackground(UBlack, 0.800000011920929); developer_console->setShow(false); developer_console->Connect(&s_consolehider, UIFloatingWindow::W_ClosePressed, UIFloatingWindow::W_ClosePressed); developer_console->Connect(&s_consolehider, W_Destroyed, W_Destroyed); } // Create the 3D view view3d = new View3D; view3d->setAlwaysOnBottom(true); view3d->InitFrame(NULL, 0, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight, -1, "facfont-20"); view3d->setName("view3d"); view3d->InitSubtitle(); memset(&intro_stage, 0, sizeof(intro_stage)); // Register the loading material ui_static_materials.loading = uWinMan.RegisterShader("textures/menu/loading"); if (ui_console->integer || developer->integer > 0) { UColor bgColor = UWindowColor; // Create the console fakk_console = getNewConsole(); bgColor = UColor(0.0, 0.5, 1.0, 1.0); // Create the mini console mini_console = new FakkMiniconsole; mini_console->Create(UISize2D(500, 100), UWhite, bgColor, 0.2f); mini_console->setAlwaysOnBottom(true); mini_console->setBorderStyle(border_none); } // Create the dm console if (!dm_console) { dm_console = getNewDMConsole(); } // Create the game message box if (ui_gmbox->integer && !gmbox) { gmbox = new UIGMBox; gmbox->Create(getDefaultGMBoxRectangle(), UHudColor, UHudColor, 0.0); gmbox->setAlwaysOnBottom(true); gmbox->setBorderStyle(border_none); } // Create the deathmatch message box if (!dmbox) { dmbox = new UIDMBox; dmbox->Create(getDefaultDMBoxRectangle(), UHudColor, UHudColor, 0.0); dmbox->setAlwaysOnBottom(true); dmbox->setBorderStyle(border_outline); } // Load all urc files filenames = FS_ListFiles("ui/", "urc", qfalse, &nfiles); for (i = 0; i < nfiles; i++) { char szFilename[MAX_QPATH]; Com_sprintf(szFilename, sizeof(szFilename), "ui/%s", filenames[i]); new UILayout(szFilename); } FS_FreeFileList(filenames); uWinMan.CreateMenus(); // find the crosshair // Removed in 2.0 // Crosshair is now handled by the cgame module //crosshairhud = menuManager.FindMenu("crosshair"); // find weapons hud hud_weapons = menuManager.FindMenu("hud_weapons"); // find items hud hud_items = menuManager.FindMenu("hud_items"); // find the health hud hud_health = menuManager.FindMenu("hud_health"); // find the compass hud hud_compass = menuManager.FindMenu("hud_compass"); // find the boss health hud hud_boss = menuManager.FindMenu("hud_boss"); // find the stats screen missionLog = menuManager.FindMenu("StatsScreen"); // find the connection menu ui_pConnectingMenu = menuManager.FindMenu("connecting"); if (crosshairhud) { crosshairhud->ShowMenu(NULL); } if (hud_health) { hud_health->ShowMenu(NULL); } if (hud_compass) { hud_compass->ShowMenu(NULL); } // find the main menu mainmenu = menuManager.FindMenu("main"); IN_MouseOn(); // realign menus menuManager.RealignMenus(); // clear input CL_ClearButtons(); cls.uiStarted = qtrue; if (!com_dedicated->integer) { CL_TryStartIntro(); } } static char **loadStrings; static unsigned int *loadTimes; static char *loadStringsBuffer; class LoadResourceInfo { public: class LoadResourceInfo *next; unsigned int loadCount; char name[1]; public: LoadResourceInfo(); }; static LoadResourceInfo *loadHead; /* ==================== UI_BeginLoadResource ==================== */ void UI_BeginLoadResource(void) { clock_t time = clock(); startCountHigh = time >> 32; startCountLow = time; } /* ==================== UI_EndLoadResource ==================== */ void UI_EndLoadResource(void) { clock_t time; int i; time = clock() - ((startCountHigh << 32) | startCountLow) + ((loadCountHigh << 32) | loadCountLow); loadCountHigh = time >> 32; loadCountLow = time; loadCount = time >> 25; } /* ==================== UI_EndLoadResource ==================== */ void UI_EndLoadResource(const char *name) { LoadResourceInfo *newLoadHead; if (!loadCount) { return; } newLoadHead = (LoadResourceInfo *)Z_Malloc(sizeof(LoadResourceInfo) + strlen(name)); newLoadHead->next = loadHead; newLoadHead->loadCount = loadCount; strcpy(newLoadHead->name, name); loadHead = newLoadHead; loadNumber++; loadCountLow = 0; loadCountHigh = 0; } /* ==================== UI_IsResourceLoaded ==================== */ qboolean UI_IsResourceLoaded(const char *name) { switch (*name) { case 97: case 98: case 99: case 100: case 101: case 104: return TIKI_FindTikiAnim(name + 1) != NULL; case 103: return SkeletorCacheFindFilename(name + 1, NULL); case 107: return S_IsSoundRegistered(name + 1); case 110: return R_ImageExists(name + 1); default: return qfalse; } } /* ==================== UI_RegisterLoadResource ==================== */ void UI_RegisterLoadResource(const char *name) { int i, j; int low, high; low = 0; high = loadNumber - 1; while (low <= high) { i = (high + low) / 2; j = strcmp(name, loadStrings[i]); if (j >= 0) { if (j <= 0) { currentLoadTime += loadTimes[i]; loadTimes[i] = 0; return; } low = i + 1; } else { high = i - 1; } } } /* ==================== UI_TestUpdateScreen ==================== */ void UI_TestUpdateScreen(unsigned int timeout) { unsigned int newTime = Sys_Milliseconds(); unsigned int startRenderTime, endRenderTime; if (timeout > 0 && (newTime - lastTime) < (timeout + updateTime)) { return; } startRenderTime = Sys_Milliseconds(); Sys_PumpMessageLoop(); SCR_UpdateScreen(); endRenderTime = Sys_Milliseconds(); updateTime = Q_min(endRenderTime - startRenderTime, 1000); lastTime = endRenderTime; } /* ==================== UI_ClearResource ==================== */ void UI_ClearResource(void) { if (cls.loading == SS_DEAD || cls.loading != SS_GAME) { return; } UI_BeginLoadResource(); UI_TestUpdateScreen(0); } /* ==================== UI_LoadResource ==================== */ void UI_LoadResource(const char *name) { if (cls.loading == SS_DEAD) { return; } if (cls.loading == SS_GAME) { UI_EndLoadResource(); UI_EndLoadResource(name); UI_BeginLoadResource(); } else if (cls.loading == SS_LOADING2) { UI_RegisterLoadResource(name); Cvar_SetValue("loadingbar", (float)currentLoadTime / (float)totalLoadTime); } UI_TestUpdateScreen(33); } /* ==================== UI_FreeLoadStrings ==================== */ void UI_FreeLoadStrings() { if (loadStrings) { Z_Free(loadStrings); loadStrings = NULL; } } /* ==================== UI_DeleteLoadInfo ==================== */ void UI_DeleteLoadInfo() { LoadResourceInfo *ptr; LoadResourceInfo *nextPtr; for (ptr = loadHead; ptr != NULL; ptr = nextPtr) { nextPtr = ptr->next; Z_Free(ptr); } } /* ==================== UI_ParseLoadMapinfo ==================== */ bool UI_ParseLoadMapinfo(Script *scr) { int size, index; int allocLen; char *pos; const char *token; char *newPos; int time; loadNumber = scr->GetInteger(false); size = scr->GetInteger(false); scr->SkipWhiteSpace(true); allocLen = size + sizeof(loadStrings[0]) * loadNumber + sizeof(loadTimes[0]) * loadNumber; loadStrings = (char **)Z_Malloc(allocLen); loadTimes = (unsigned int *)(loadStrings + loadNumber); loadStringsBuffer = (char *)(loadTimes + loadNumber); pos = loadStringsBuffer; totalLoadTime = 0; index = 0; do { token = scr->GetToken(true); newPos = &pos[strlen(token) + 1]; strcpy(pos, token); loadStrings[index] = pos; time = scr->GetInteger(true); if (UI_IsResourceLoaded(pos)) { loadTimes[index] = 0; } else { loadTimes[index] = time; totalLoadTime += time; } pos = newPos; index++; } while (index != loadNumber); assert(pos <= (char *)loadStrings + allocLen); if (newPos != loadStringsBuffer + size) { UI_FreeLoadStrings(); return false; } return true; } /* ==================== UI_ArchiveLoadMapinfo ==================== */ bool UI_ArchiveLoadMapinfo(const char *mapname) { Script scr; int version; byte *tempbuf; int length; bool success; length = FS_ReadFile(loadName, (void **)&tempbuf); if (length <= 0) { return false; } scr.LoadFile(loadName, length, (const char *)tempbuf); FS_FreeFile(tempbuf); version = scr.GetInteger(false); scr.SkipWhiteSpace(true); if (version == 3) { success = UI_ParseLoadMapinfo(&scr); } else { Com_Printf("Expecting version %d map info file. Map info is version %d.\n", 3, version); success = false; } scr.Close(); return success; } /* ==================== UI_BeginLoad ==================== */ void UI_BeginLoad(const char *pszMapName) { str mapfile; if (cls.loading) { if (cls.loading == SS_GAME) { UI_DeleteLoadInfo(); } UI_FreeLoadStrings(); cls.loading = SS_DEAD; } server_loading = qtrue; server_loading_waiting = qfalse; strcpy(server_mapname, pszMapName); if (str::icmp(ui_sCurrentLoadingMenu, server_mapname)) { ui_sCurrentLoadingMenu = server_mapname; ui_pLoadingMenu = menuManager.FindMenu(ui_sCurrentLoadingMenu); } if (!ui_pLoadingMenu) { ui_sCurrentLoadingMenu = "loading_default"; ui_pLoadingMenu = menuManager.FindMenu(ui_sCurrentLoadingMenu); } UI_ForceMenuOff(true); UI_DeactiveFloatingWindows(); if (ui_pLoadingMenu) { if (!developer->integer && UI_ConsoleIsVisible()) { UI_CloseConsole(); } ui_pLoadingMenu->PassEventToWidget("continuebutton", new Event(EV_Widget_Disable)); loadName = "maps/"; loadName += pszMapName; loadName += ".min"; mapfile = loadName + ".bsp"; if (UI_ArchiveLoadMapinfo(mapfile)) { cls.loading = SS_LOADING2; } else { cls.loading = SS_GAME; } if (cls.loading == SS_LOADING2) { ui_pLoadingMenu->PassEventToWidget("loadingflasher", new Event(EV_Widget_Disable)); ui_pLoadingMenu->PassEventToWidget("loadingbar", new Event(EV_Widget_Enable)); ui_pLoadingMenu->PassEventToWidget("loadingbar_border", new Event(EV_Widget_Enable)); currentLoadTime = 0; Cvar_SetValue("loadingbar", 0); L_ProcessPendingEvents(); lastTime = Sys_Milliseconds(); if (com_sv_running->integer) { SCR_UpdateScreen(); } } else { ui_pLoadingMenu->PassEventToWidget("loadingflasher", new Event(EV_Widget_Enable)); ui_pLoadingMenu->PassEventToWidget("loadingbar", new Event(EV_Widget_Disable)); ui_pLoadingMenu->PassEventToWidget("loadingbar_border", new Event(EV_Widget_Disable)); UI_BeginLoadResource(); loadCountLow = 0; loadCountHigh = 0; loadHead = NULL; loadNumber = 0; cls.loading = SS_LOADING; L_ProcessPendingEvents(); lastTime = Sys_Milliseconds(); if (com_sv_running->integer) { SCR_UpdateScreen(); } } } else { cls.loading = SS_LOADING; // process all events L_ProcessPendingEvents(); lastTime = Sys_Milliseconds(); if (com_sv_running->integer) { SCR_UpdateScreen(); } } } /* ==================== UI_CompareLoadResources ==================== */ int UI_CompareLoadResources(const void *elem1, const void *elem2) { LoadResourceInfo *e1 = *(LoadResourceInfo **)elem1; LoadResourceInfo *e2 = *(LoadResourceInfo **)elem2; return strcmp(e1->name, e2->name); } /* ==================== UI_EndLoad ==================== */ void UI_EndLoad(void) { LoadResourceInfo *ptr; LoadResourceInfo **base; int i; fileHandle_t file; int size; char buf[1024]; if (!cls.loading) { return; } UI_LoadResource("*end"); if (cls.loading == SS_GAME) { base = (LoadResourceInfo **)Z_Malloc(loadNumber * sizeof(LoadResourceInfo *)); i = 0; for (ptr = loadHead; ptr != NULL; ptr = ptr->next) { base[i] = ptr; i++; } qsort(base, loadNumber, sizeof(LoadResourceInfo *), UI_CompareLoadResources); size = 0; for (i = 0; i < loadNumber; i++) { ptr = base[i]; size += strlen(ptr->name) + 1; } file = FS_FOpenFileWrite(loadName); Com_sprintf(buf, sizeof(buf), "%d\n%d %d\n", 3, loadNumber, size); FS_Write(buf, strlen(buf), file); for (i = 0; i < loadNumber; i++) { Com_sprintf(buf, sizeof(buf), "%s\n%d\n", base[i]->name, base[i]->loadCount); FS_Write(buf, strlen(buf), file); } FS_FCloseFile(file); Z_Free(base); UI_DeleteLoadInfo(); } else if (cls.loading == SS_LOADING2) { if (ui_debugload->integer) { Com_Printf("Following resources not accounted for on load:\n"); } for (i = 0; i < loadNumber; i++) { if (loadTimes[i]) { if (ui_debugload->integer) { Com_Printf("%s\n", loadStrings[i]); } loadTimes[i] = 0; } } currentLoadTime = totalLoadTime; } UI_FreeLoadStrings(); cls.loading = SS_DEAD; } /* ==================== UI_AbortLoad ==================== */ void UI_AbortLoad(void) { if (cls.loading) { if (cls.loading == SS_GAME) { UI_DeleteLoadInfo(); } cls.loading = SS_DEAD; } } /* ==================== CL_FontStringWidth ==================== */ int CL_FontStringWidth(fontheader_t *pFont, const char *pszString, int iMaxLen) { return uie.FontStringWidth(pFont, pszString, iMaxLen); } griditemtype_t TestListItem::getListItemType(int which) const { return TYPE_STRING; } str TestListItem::getListItemString(int i) const { return strings[i]; } int TestListItem::getListItemValue(int i) const { return atoi(strings[i]); } void TestListItem::DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) {} qboolean TestListItem::IsHeaderEntry(void) const { return qfalse; } void ScoreboardListItem::SetListItemStrings( const char *string1, const char *string2, const char *string3, const char *string4, const char *string5, const char *string6, const char *string7, const char *string8 ) { strings[0] = string1; strings[1] = string2; strings[2] = string3; strings[3] = string4; strings[4] = string5; strings[5] = string6; strings[6] = string7; strings[7] = string8; } griditemtype_t ScoreboardListItem::getListItemType(int i) const { return bColorSet != 0 ? TYPE_OWNERDRAW : TYPE_STRING; } str ScoreboardListItem::getListItemString(int i) const { return strings[i]; } int ScoreboardListItem::getListItemValue(int i) const { return atoi(strings[i]); } void ScoreboardListItem::SetTitleItem(qboolean bSet) { bTitleItem = bSet; } qboolean ScoreboardListItem::IsHeaderEntry(void) const { return bTitleItem; }