mirror of
https://github.com/bearstonem/openmohaa-vr.git
synced 2026-10-18 09:00:21 +02:00
Restore desktop HUD behavior and objective state, fix stereo text lifetimes, HUD placement and colors, sprite culling, and font shader passes. Handle swapchain timeouts and incomplete stereo frames safely, remove forced GPU waits, and correct rendering timing attribution. Track client-game source additions in CMake. Validated desktop and Android GL1/GL2 builds plus targeted regression and sanitizer checks. Headset appearance and performance remain unverified.
6275 lines
159 KiB
C++
6275 lines
159 KiB
C++
/*
|
|
===========================================================================
|
|
Copyright (C) 2024 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 "../corepp/tiki.h"
|
|
#include "../qcommon/localization.h"
|
|
#include "../qcommon/q_version.h"
|
|
|
|
#include "cl_ui.h"
|
|
#ifdef USE_OPENXR
|
|
#include "../vr/vr_common.h"
|
|
#endif
|
|
#include "cl_uigamespy.h"
|
|
|
|
#include <chrono>
|
|
|
|
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;
|
|
// Added in OPM
|
|
// Where the compass sits, as fractions of the flat screen. hud_compass.urc
|
|
// aligns it left top, which in a headset is the far corner of the lens - it is
|
|
// there, and it is barely visible. See UI_PlaceVRCompass.
|
|
cvar_t *vr_compassX;
|
|
cvar_t *vr_compassY;
|
|
static cvar_t *ui_vrHud;
|
|
|
|
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;
|
|
|
|
unsigned char UIListCtrlItem[8];
|
|
|
|
static const float maxWidthRes = 1920;
|
|
static const float maxHeightRes = 1080;
|
|
|
|
inventory_t client_inv;
|
|
bind_t client_bind;
|
|
static str scoreboard_menuname;
|
|
static str ui_sCurrentLoadingMenu;
|
|
static Container<Menu *> hudList;
|
|
|
|
const UColor UWhiteChatMessageColor(0.75, 0.75, 0.75);
|
|
const UColor URedChatMessageColor(1.0, 0.333, 0.333);
|
|
const UColor UGreenChatMessageColor(0.0, 1.0, 0.333, 1.0);
|
|
|
|
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] - uid.vidWidth;
|
|
rect.pos.y = f[1] - uid.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 = (uid.vidWidth - 50);
|
|
rect.size.height = (uid.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_BaseDir_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_BaseDir_FOpenFileWrite_HomeData("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] - uid.vidWidth;
|
|
rect.pos.y = f[1] - uid.vidHeight;
|
|
rect.size.width = f[2] + 50.0;
|
|
rect.size.height = f[3] + 50.0;
|
|
} else {
|
|
rect.pos.x = 0;
|
|
rect.pos.y = uid.vidHeight * 0.58;
|
|
rect.size.width = uid.vidWidth;
|
|
rect.size.height = uid.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] - uid.vidWidth;
|
|
rect.pos.y = f[1] - uid.vidHeight;
|
|
rect.size.width = f[2] + 50.0;
|
|
rect.size.height = f[3] + 50.0;
|
|
} else {
|
|
rect.pos.x = 0;
|
|
rect.pos.y = uid.vidHeight * 0.66;
|
|
rect.size.width = uid.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 * uid.scaleRes[1];
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
/*
|
|
====================
|
|
getScreenWidth
|
|
====================
|
|
*/
|
|
static float getScreenWidth()
|
|
{
|
|
if (uid.bHighResScaling) {
|
|
return maxWidthRes;
|
|
} else {
|
|
return uid.vidWidth;
|
|
}
|
|
}
|
|
|
|
/*
|
|
====================
|
|
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 = uid.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, (getScreenWidth() - 20) * uid.scaleRes[0], 128.0f * uid.scaleRes[1]);
|
|
}
|
|
|
|
/*
|
|
====================
|
|
getDefaultDMBoxRectangle
|
|
====================
|
|
*/
|
|
static UIRect2D getDefaultDMBoxRectangle(void)
|
|
{
|
|
float width;
|
|
float screenWidth = getScreenWidth();
|
|
|
|
width = screenWidth * uid.scaleRes[0] * ui_compass_scale->value * 0.2f;
|
|
|
|
return UIRect2D(width, 0, (screenWidth - (width + 192.0f)) * uid.scaleRes[0], 120.0f * uid.scaleRes[1]);
|
|
}
|
|
|
|
/*
|
|
====================
|
|
UI_GetObjectivesTop
|
|
====================
|
|
*/
|
|
float UI_GetObjectivesTop(void)
|
|
{
|
|
return getDefaultGMBoxRectangle().pos.y;
|
|
}
|
|
|
|
/*
|
|
====================
|
|
UI_GetObjectivesTop
|
|
====================
|
|
*/
|
|
void UI_GetHighResolutionScale(vec2_t scale)
|
|
{
|
|
if (uid.bHighResScaling) {
|
|
scale[0] = uid.scaleRes[0];
|
|
scale[1] = uid.scaleRes[1];
|
|
} else {
|
|
scale[0] = scale[1] = 1.0;
|
|
}
|
|
}
|
|
|
|
/*
|
|
====================
|
|
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)
|
|
{
|
|
const UColor *pColor = NULL;
|
|
const char *pszString;
|
|
char szBlah[1024];
|
|
qboolean bPrintedDMBox = qfalse;
|
|
|
|
pszString = msg;
|
|
|
|
if (*pszString > 0 && (unsigned char)*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 = &UWhiteChatMessageColor;
|
|
break;
|
|
case MESSAGE_WHITE:
|
|
bBold = qtrue;
|
|
pColor = &UWhite;
|
|
break;
|
|
case MESSAGE_CHAT_RED:
|
|
bDeathMessage = MESSAGE_CHAT_RED;
|
|
pColor = &URedChatMessageColor;
|
|
break;
|
|
case MESSAGE_CHAT_GREEN:
|
|
bDeathMessage = MESSAGE_CHAT_GREEN;
|
|
pColor = &UGreenChatMessageColor;
|
|
break;
|
|
}
|
|
|
|
pszString++;
|
|
|
|
//
|
|
// print to the deathmatch console
|
|
//
|
|
if (dm_console && !bNormalMessage) {
|
|
if (bDMMessage) {
|
|
dm_console->AddDMMessageText(pszString, pColor);
|
|
} else {
|
|
dm_console->AddText(pszString, pColor);
|
|
}
|
|
}
|
|
|
|
//
|
|
// print to the deathmatch message box
|
|
//
|
|
if (dmbox) {
|
|
// Changed in OPM
|
|
// Avoid touching/copying buffers
|
|
/*
|
|
if (bDMMessage) {
|
|
*szString = MESSAGE_CHAT_WHITE;
|
|
dmbox->Print(szString);
|
|
} else if (bDeathMessage) {
|
|
*szString = bDeathMessage;
|
|
dmbox->Print(szString);
|
|
}
|
|
*/
|
|
|
|
if (bDMMessage || bDeathMessage) {
|
|
dmbox->Print(msg);
|
|
bPrintedDMBox = qtrue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// print to the game message box
|
|
//
|
|
if (gmbox && !bPrintedDMBox) {
|
|
if (bBold) {
|
|
// Changed in OPM
|
|
// Avoid touching/copying buffers
|
|
//*szString = MESSAGE_WHITE;
|
|
//gmbox->Print(szString);
|
|
|
|
gmbox->Print(msg);
|
|
uii.Snd_PlaySound("objective_text");
|
|
} else {
|
|
gmbox->Print(pszString);
|
|
}
|
|
|
|
if (!ui_gmboxspam->integer) {
|
|
return;
|
|
}
|
|
|
|
if (!bDMMessage) {
|
|
Q_strncpyz(szBlah, "Game Message: ", sizeof(szBlah));
|
|
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_RESETSTRING);
|
|
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, uid.vidWidth, uid.vidHeight, 0, uid.vidWidth, uid.vidHeight, 0, -1, 1);
|
|
re.Scissor(0, 0, uid.vidWidth, uid.vidHeight);
|
|
re.SetColor(g_color_table[0]);
|
|
re.DrawBox(0, 0, uid.vidWidth, uid.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.
|
|
====================
|
|
*/
|
|
/*
|
|
====================
|
|
UI_PlaceVRCompass
|
|
|
|
Added in OPM.
|
|
|
|
hud_compass.urc aligns the compass left top, so it is drawn at 0,0. On a flat
|
|
screen that is a corner you can glance at; in a headset it is the far edge of
|
|
the lens, where it is technically visible and practically not.
|
|
|
|
Centred horizontally and set a little below the middle, which is where a thing
|
|
you check without breaking your aim wants to be. Fractions of the screen rather
|
|
than pixels so it means the same at any eye resolution, and the widget's own
|
|
size is taken off so the fraction places its centre rather than its corner.
|
|
|
|
Applied only when the numbers change. setFrame propagates the coordinate system
|
|
and fires signals, which is not something to do every frame for a widget that is
|
|
not moving - and the alignment flags are cleared at the same time, so nothing
|
|
puts it back.
|
|
====================
|
|
*/
|
|
static void UI_PlaceVRCompass(void)
|
|
{
|
|
UIWidget *widget;
|
|
UIRect2D frame;
|
|
|
|
#ifdef USE_OPENXR
|
|
if (!VR_Enabled()) {
|
|
return;
|
|
}
|
|
#else
|
|
return;
|
|
#endif
|
|
|
|
if (!hud_compass || !vr_compassX || !vr_compassY) {
|
|
return;
|
|
}
|
|
|
|
widget = hud_compass->GetContainerWidget();
|
|
|
|
//
|
|
// The alignment flags have to go first, or none of this survives.
|
|
// hud_compass.urc says "align left top", and UIWidget::AlignPosition
|
|
// turns that into a flat "pos.x = 0; pos.y = 0" every time it runs -
|
|
// which it does on Realign and ResetMotion, after this. Setting the frame
|
|
// without clearing the flags puts the compass back in the corner a moment
|
|
// later, which is exactly what it did.
|
|
//
|
|
widget->setAlign(0);
|
|
|
|
frame = widget->getFrame();
|
|
|
|
// Compare the actual frame so a resize or recreated menu is repositioned
|
|
// even when the cvars have not changed. Avoid relayout for an unchanged frame.
|
|
const float x = uid.vidWidth * vr_compassX->value - frame.size.width * 0.5f;
|
|
const float y = uid.vidHeight * vr_compassY->value - frame.size.height * 0.5f;
|
|
if (frame.pos.x != x || frame.pos.y != y) {
|
|
frame.pos.x = x;
|
|
frame.pos.y = y;
|
|
widget->setFrame(frame);
|
|
}
|
|
}
|
|
|
|
void UI_Update(void)
|
|
{
|
|
Menu *currentMenu;
|
|
UIRect2D frame;
|
|
qboolean vrHudActive = qfalse;
|
|
|
|
#ifdef USE_OPENXR
|
|
vrHudActive = VR_Enabled() && ui_vrHud && ui_vrHud->integer;
|
|
#endif
|
|
|
|
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);
|
|
|
|
//
|
|
// Added in OPM
|
|
// The health, ammo and compass widgets are flat, so in VR they belong
|
|
// on the wrist panel rather than in the eye buffers.
|
|
//
|
|
if (cl_vrDrawMode == VRDRAW_WORLD) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Added in OPM
|
|
// The retail corner HUD, off while the gathered one is up.
|
|
//
|
|
// These five menus are aligned to the four corners of a 4:3 screen -
|
|
// hud_health.urc says "align left bottom", hud_compass.urc "align left
|
|
// top". On a monitor that is a glance away; through a lens it is the
|
|
// far edge, where they were reported as visible and unreadable. They
|
|
// are drawn again, together and in the middle, by CG_DrawVRHud, and
|
|
// leaving these up as well would draw everything twice.
|
|
//
|
|
// Read the current cvar value so the retail HUD can be restored
|
|
// without a rebuild. Desktop frames always keep their own HUD.
|
|
//
|
|
if (ui_hud && !view3d->LetterboxActive() && !vrHudActive) {
|
|
// 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
|
|
//
|
|
// Added in OPM
|
|
// ...including whenever the gathered VR HUD is up, which is the condition
|
|
// that actually turns the retail corner HUD off.
|
|
//
|
|
// Gating the explicit Display calls in the cls.no_menus branch above was
|
|
// not enough and looked like it was: the widgets kept drawing, measured
|
|
// off an eye dump with hud_health's meter still at the bottom left corner
|
|
// and hud_ammo's clip still at the bottom right, both exactly where their
|
|
// .urc alignment puts them. That branch returns early and is not the path
|
|
// taken here - when it is not, UI_Update falls through to
|
|
// uWinMan.UpdateViews(), which walks the whole widget tree and draws every
|
|
// shown menu whether anything asked it to or not. Hiding them is the only
|
|
// thing that covers both routes.
|
|
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))
|
|
|| vrHudActive) {
|
|
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 && !(cl.snap.ps.pm_flags & PMF_NO_WEAPONBAR)) {
|
|
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();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Added in OPM
|
|
// An eye pass wants the 3D view and none of the widgets around it, so it
|
|
// goes straight at the view rather than walking the whole tree. Everything
|
|
// else in the tree is flat and is drawn in the panel pass instead.
|
|
//
|
|
if (cl_vrDrawMode == VRDRAW_WORLD) {
|
|
if (view3d && view3d->getShow()) {
|
|
view3d->Display(uWinMan.getFrame(), 1.0);
|
|
}
|
|
return;
|
|
}
|
|
|
|
#ifdef USE_OPENXR
|
|
VR_TraceEvent(VRTRACE_UPDATEVIEWS);
|
|
VR_TraceState((int)cl_vrDrawMode, Cvar_Get("vr_hudPass", "0", 0)->integer, cls.no_menus);
|
|
#endif
|
|
|
|
UI_PlaceVRCompass();
|
|
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 <menuname>\n");
|
|
return;
|
|
}
|
|
|
|
UI_ToggleMenu(Cmd_Argv(1));
|
|
}
|
|
|
|
/*
|
|
====================
|
|
UI_PopMenu
|
|
====================
|
|
*/
|
|
void UI_PopMenu(qboolean restore_cvars)
|
|
{
|
|
Menu *menu;
|
|
|
|
//
|
|
// Added in OPM
|
|
// Close any active floating windows (e.g. maplist)
|
|
//
|
|
UI_DeactiveFloatingWindows();
|
|
|
|
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 <menuname>\n");
|
|
return;
|
|
}
|
|
|
|
UI_PushMenu(Cmd_Argv(1));
|
|
}
|
|
|
|
/*
|
|
====================
|
|
UI_PushMenuSP_f
|
|
====================
|
|
*/
|
|
void UI_PushMenuSP_f(void)
|
|
{
|
|
if (Cmd_Argc() <= 1) {
|
|
Com_Printf("Usage: pushmenu_sp <menuname>\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 == GT_SINGLE_PLAYER)) {
|
|
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 <menuname>\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 != GT_SINGLE_PLAYER) {
|
|
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 <menuname>\n");
|
|
return;
|
|
}
|
|
|
|
UI_ForceMenu(Cmd_Argv(1));
|
|
}
|
|
|
|
/*
|
|
====================
|
|
UI_PopMenu_f
|
|
====================
|
|
*/
|
|
void UI_PopMenu_f(void)
|
|
{
|
|
if (Cmd_Argc() <= 1) {
|
|
Com_Printf("Usage: popmenu <restore_cvars - set to 1 if you want all cvars restored to their original values>");
|
|
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 <menuname>\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 <menuname>\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 <name> <args1...argsN>\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 <name> <args1...argsN>\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);
|
|
CL_NET_OutOfBandPrint(adr, "info %i", 8);
|
|
}
|
|
|
|
noipx = Cvar_Get("noipx", "0", CVAR_INIT);
|
|
if (!noipx->integer) {
|
|
adr.type = NA_BROADCAST_IPX;
|
|
adr.port = BigShort(12203);
|
|
CL_NET_OutOfBandPrint(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);
|
|
}
|
|
|
|
CL_NET_OutOfBandPrint(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(uid.vidWidth / 2, uid.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(uid.vidWidth / 2, uid.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(uid.vidWidth / 2, uid.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_strncpyz(donotshowssindeorfr, "german_waffenss_", sizeof(donotshowssindeorfr));
|
|
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 (!Q_stricmpn(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 <file>\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.Rend_ImageExists = re.ImageExists;
|
|
|
|
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;
|
|
|
|
uii.GetRefSequence = CL_GetRefSequence;
|
|
uii.IsRendererLoaded = CL_IsRendererLoaded;
|
|
uii.Rend_LoadRawImage = re.LoadRawImage;
|
|
uii.Rend_FreeRawImage = re.FreeRawImage;
|
|
|
|
uii.Rend_Set2DStartTime = re.Set2DInitialShaderTime;
|
|
}
|
|
|
|
/*
|
|
====================
|
|
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((uid.vidWidth - width) / 2, (uid.vidHeight - height) / 2, 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;
|
|
|
|
if (com_target_game->integer >= TG_MOHTA) {
|
|
ui_compass_scale = Cvar_Get("ui_compass_scale", "0.75", CVAR_ARCHIVE | CVAR_LATCH);
|
|
} else {
|
|
// Older version doesn't have an adjustable compass, so assume 0.5 by default
|
|
ui_compass_scale = Cvar_Get("ui_compass_scale", "0.55", CVAR_ARCHIVE | CVAR_LATCH);
|
|
}
|
|
|
|
vr_compassX = Cvar_Get("vr_compassX", "0.5", CVAR_ARCHIVE);
|
|
vr_compassY = Cvar_Get("vr_compassY", "0.62", CVAR_ARCHIVE);
|
|
ui_vrHud = Cvar_Get("vr_hud", "1", CVAR_ARCHIVE);
|
|
|
|
CL_FillUIImports();
|
|
CL_FillUIDef();
|
|
|
|
// Added in OPM
|
|
// Scaling for high resolutions
|
|
if (uid.vidWidth > maxWidthRes && uid.vidHeight > maxHeightRes) {
|
|
const float vidRatio = (float)uid.vidWidth / (float)uid.vidHeight;
|
|
|
|
uid.scaleRes[0] = (float)uid.vidWidth / (maxHeightRes * vidRatio);
|
|
uid.scaleRes[1] = (float)uid.vidHeight / maxHeightRes;
|
|
//uid.scaleRes[0] = (float)uid.vidWidth / maxWidthRes;
|
|
//uid.scaleRes[1] = (float)uid.vidHeight / maxHeightRes;
|
|
uid.bHighResScaling = qtrue;
|
|
} else {
|
|
uid.scaleRes[0] = 1;
|
|
uid.scaleRes[1] = 1;
|
|
uid.bHighResScaling = qfalse;
|
|
}
|
|
|
|
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, uid.vidWidth, uid.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();
|
|
}
|
|
|
|
// Added in OPM
|
|
SCR_StopCinematic();
|
|
}
|
|
|
|
/*
|
|
====================
|
|
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() && str::icmp(scoreboard_menuname, pszMenuName) && scoreboard_menu) {
|
|
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()) {
|
|
// Fixed in 2.30 (scoreboard_menu check)
|
|
if (scoreboard_menu) {
|
|
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) / uid.scaleRes[0],
|
|
drawRect.pos.y / uid.scaleRes[1],
|
|
Sys_LV_CL_ConvertString(getListItemString(iColumn)),
|
|
-1,
|
|
uid.scaleRes
|
|
);
|
|
|
|
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 = uid.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);
|
|
}
|
|
|
|
/*
|
|
====================
|
|
UI_SalesScreen_f
|
|
====================
|
|
*/
|
|
void UI_SalesScreen_f()
|
|
{
|
|
if (random() > 0.5) {
|
|
Cbuf_AddText("pushmenu sales_splash1\n");
|
|
} else {
|
|
Cbuf_AddText("pushmenu sales_splash2\n");
|
|
}
|
|
}
|
|
|
|
/*
|
|
====================
|
|
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_shortversion->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);
|
|
Cmd_AddCommand("salesscreen", UI_SalesScreen_f);
|
|
Cmd_AddCommand("launchgamespy", UI_LaunchGameSpy_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, uid.vidWidth, uid.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();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Map info load information
|
|
//
|
|
|
|
static constexpr unsigned int MAP_INFO_VERSION = 3;
|
|
|
|
#if 0
|
|
static unsigned int startCountLow;
|
|
static unsigned int startCountHigh;
|
|
static unsigned int loadCountLow;
|
|
static unsigned int loadCountHigh;
|
|
#endif
|
|
std::chrono::time_point<std::chrono::steady_clock> startCount;
|
|
|
|
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;
|
|
|
|
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)
|
|
{
|
|
#if 0
|
|
clock_t time = clock();
|
|
|
|
startCountHigh = time >> 32;
|
|
startCountLow = time;
|
|
#endif
|
|
|
|
// Fixed in OPM
|
|
// Use reliable cross-platform CPU clock
|
|
startCount = std::chrono::steady_clock::now();
|
|
}
|
|
|
|
/*
|
|
====================
|
|
UI_EndLoadResource
|
|
====================
|
|
*/
|
|
void UI_EndLoadResource(void)
|
|
{
|
|
#if 0
|
|
clock_t time;
|
|
|
|
time =
|
|
clock() - (((clock_t)startCountHigh << 32) | startCountLow) + (((clock_t)loadCountHigh << 32) | loadCountLow);
|
|
|
|
loadCountHigh = time >> 32;
|
|
loadCountLow = time;
|
|
loadCount = time >> 25;
|
|
#endif
|
|
|
|
// Fixed in OPM
|
|
// Correctly calculate the load time for a resource
|
|
std::chrono::nanoseconds deltaTime;
|
|
|
|
deltaTime = std::chrono::steady_clock::now() - startCount;
|
|
|
|
// This will take into account resources that take at least 1 millisecond
|
|
loadCount = std::chrono::duration_cast<std::chrono::milliseconds>(deltaTime).count();
|
|
}
|
|
|
|
/*
|
|
====================
|
|
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++;
|
|
|
|
#if 0
|
|
loadCountLow = 0;
|
|
loadCountHigh = 0;
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
====================
|
|
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 uii.Rend_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 = (low + high) / 2;
|
|
j = strcmp(name, loadStrings[i]);
|
|
|
|
if (j < 0) {
|
|
high = i - 1;
|
|
} else if (j > 0) {
|
|
low = i + 1;
|
|
} else {
|
|
currentLoadTime += loadTimes[i];
|
|
loadTimes[i] = 0;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
====================
|
|
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 == LOAD_PROGRESS_FALSE || cls.loading != LOAD_PROGRESS_SAVE) {
|
|
return;
|
|
}
|
|
|
|
UI_BeginLoadResource();
|
|
UI_TestUpdateScreen(0);
|
|
}
|
|
|
|
/*
|
|
====================
|
|
UI_LoadResource
|
|
====================
|
|
*/
|
|
void UI_LoadResource(const char *name)
|
|
{
|
|
if (cls.loading == LOAD_PROGRESS_FALSE) {
|
|
return;
|
|
}
|
|
|
|
if (cls.loading == LOAD_PROGRESS_SAVE) {
|
|
UI_EndLoadResource();
|
|
UI_EndLoadResource(name);
|
|
UI_BeginLoadResource();
|
|
} else if (cls.loading == LOAD_PROGRESS_LOAD) {
|
|
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 == MAP_INFO_VERSION) {
|
|
success = UI_ParseLoadMapinfo(&scr);
|
|
} else {
|
|
Com_Printf("Expecting version %d map info file. Map info is version %d.\n", MAP_INFO_VERSION, version);
|
|
success = false;
|
|
}
|
|
|
|
scr.Close();
|
|
return success;
|
|
}
|
|
|
|
/*
|
|
====================
|
|
UI_BeginLoad
|
|
====================
|
|
*/
|
|
void UI_BeginLoad(const char *pszMapName)
|
|
{
|
|
str mapfile;
|
|
|
|
if (cls.loading != LOAD_PROGRESS_FALSE) {
|
|
if (cls.loading == LOAD_PROGRESS_SAVE) {
|
|
UI_DeleteLoadInfo();
|
|
}
|
|
|
|
UI_FreeLoadStrings();
|
|
cls.loading = LOAD_PROGRESS_FALSE;
|
|
}
|
|
|
|
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;
|
|
mapfile = loadName;
|
|
loadName += ".min";
|
|
|
|
if (CL_UseLargeLightmap(pszMapName)) {
|
|
mapfile += ".bsp";
|
|
} else {
|
|
// Added in 2.0
|
|
mapfile += "_sml.bsp";
|
|
}
|
|
|
|
if (UI_ArchiveLoadMapinfo(mapfile)) {
|
|
cls.loading = LOAD_PROGRESS_LOAD;
|
|
} else {
|
|
cls.loading = LOAD_PROGRESS_SAVE;
|
|
}
|
|
|
|
if (cls.loading == LOAD_PROGRESS_LOAD) {
|
|
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;
|
|
} 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();
|
|
#if 0
|
|
loadCountLow = 0;
|
|
loadCountHigh = 0;
|
|
#endif
|
|
loadHead = NULL;
|
|
loadNumber = 0;
|
|
}
|
|
|
|
Cvar_SetValue("loadingbar", 0);
|
|
|
|
L_ProcessPendingEvents();
|
|
|
|
lastTime = Sys_Milliseconds();
|
|
} else {
|
|
cls.loading = LOAD_PROGRESS_DEFAULT;
|
|
|
|
// 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 == LOAD_PROGRESS_FALSE) {
|
|
return;
|
|
}
|
|
|
|
UI_LoadResource("*end");
|
|
|
|
switch(cls.loading)
|
|
{
|
|
case LOAD_PROGRESS_SAVE:
|
|
// Fixed in OPM
|
|
// Don't save progress if there are no resources.
|
|
// NOTE:
|
|
// The original game can crash when there is no load number, because it attempts to free a NULL pointer.
|
|
// If all resources load very fast (less than 1 millisecond), no load number is generated.
|
|
// This can occur on high-end systems with very fast NVMe SSDs.
|
|
// This means custom maps without a .min file can crash the original game.
|
|
if (loadNumber) {
|
|
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);
|
|
|
|
//
|
|
// Save the total length of all names
|
|
//
|
|
size = 0;
|
|
for (i = 0; i < loadNumber; i++) {
|
|
ptr = base[i];
|
|
size += strlen(ptr->name) + 1;
|
|
}
|
|
|
|
file = FS_FOpenFileWrite_HomeData(loadName);
|
|
Com_sprintf(buf, sizeof(buf), "%d\n%d %d\n", MAP_INFO_VERSION, loadNumber, size);
|
|
FS_Write(buf, strlen(buf), file);
|
|
|
|
//
|
|
// Save individual resources (name and time)
|
|
//
|
|
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();
|
|
break;
|
|
case LOAD_PROGRESS_LOAD:
|
|
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;
|
|
break;
|
|
}
|
|
|
|
UI_FreeLoadStrings();
|
|
|
|
cls.loading = LOAD_PROGRESS_FALSE;
|
|
}
|
|
|
|
/*
|
|
====================
|
|
UI_AbortLoad
|
|
====================
|
|
*/
|
|
void UI_AbortLoad(void)
|
|
{
|
|
if (cls.loading != LOAD_PROGRESS_FALSE) {
|
|
if (cls.loading == LOAD_PROGRESS_SAVE) {
|
|
UI_DeleteLoadInfo();
|
|
}
|
|
cls.loading = LOAD_PROGRESS_FALSE;
|
|
}
|
|
}
|
|
|
|
/*
|
|
====================
|
|
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;
|
|
}
|