summaryrefslogtreecommitdiff
path: root/src/ui
diff options
context:
space:
mode:
authorIronClawTrem <louie.nutman@gmail.com>2020-02-16 03:40:06 +0000
committerIronClawTrem <louie.nutman@gmail.com>2020-02-16 03:40:06 +0000
commit425decdf7e9284d15aa726e3ae96b9942fb0e3ea (patch)
tree6c0dd7edfefff1be7b9e75fe0b3a0a85fe1595f3 /src/ui
parentccb0b2e4d6674a7a00c9bf491f08fc73b6898c54 (diff)
create tremded branch
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/CMakeLists.txt67
-rw-r--r--src/ui/menudef.h363
-rw-r--r--src/ui/ui_atoms.c620
-rw-r--r--src/ui/ui_gameinfo.c482
-rw-r--r--src/ui/ui_local.h1455
-rw-r--r--src/ui/ui_main.c9532
-rw-r--r--src/ui/ui_players.c1369
-rw-r--r--src/ui/ui_public.h303
-rw-r--r--src/ui/ui_shared.c11444
-rw-r--r--src/ui/ui_shared.h681
-rw-r--r--src/ui/ui_syscalls.asm3
-rw-r--r--src/ui/ui_syscalls.c413
-rw-r--r--src/ui/ui_syscalls_11.asm2
13 files changed, 12004 insertions, 14730 deletions
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
new file mode 100644
index 0000000..18ddfe1
--- /dev/null
+++ b/src/ui/CMakeLists.txt
@@ -0,0 +1,67 @@
+#
+## _ _ ___ ____ _
+## | | | |_ _| / ___|___ __| | ___
+## | | | || | | | / _ \ / _` |/ _ \
+## | |_| || | | |__| (_) | (_| | __/
+## \___/|___| \____\___/ \__,_|\___|
+##
+#
+
+set(CMAKE_INSTALL_NAME_DIR ${PROJECT_BINARY_DIR}/gpp)
+
+set(BG_SOURCE_DIR ../game)
+set(QC_SOURCE_DIR ../qcommon)
+set(RC_SOURCE_DIR ../renderercommon)
+set(CLIENT_SOURCE_DIR ../client)
+
+add_definitions( -DUI )
+
+#add_custom_command(
+# OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/menudef.h
+# COMMAND ${CMAKE_COMMAND}
+# ARGS -E copy ${CMAKE_BINARY_DIR}/assets/ui/menudef.h ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/menudef.h
+# DEPENDS ${CMAKE_BINARY_DIR}/assets/ui/menudef.h
+# )
+#set_source_files_properties(menudef.h PROPERTIES GENERATED TRUE)
+
+set(UI_SOURCES
+ ui_main.c # Must be listed first!
+ ui_atoms.c
+ ui_gameinfo.c
+ ui_local.h
+ ui_shared.c
+ ui_shared.h
+ ${CMAKE_SOURCE_DIR}/assets/ui/menudef.h
+ ${BG_SOURCE_DIR}/bg_lib.h
+ ${BG_SOURCE_DIR}/bg_public.h
+ ${BG_SOURCE_DIR}/bg_alloc.c
+ ${BG_SOURCE_DIR}/bg_lib.c
+ ${BG_SOURCE_DIR}/bg_misc.c
+ ${BG_SOURCE_DIR}/bg_voice.c
+ ${QC_SOURCE_DIR}/q_shared.h
+ ${QC_SOURCE_DIR}/q_shared.c
+ ${QC_SOURCE_DIR}/q_math.c
+ ${RC_SOURCE_DIR}/tr_types.h
+ ${CLIENT_SOURCE_DIR}/keycodes.h
+ )
+
+add_library(
+ ui SHARED
+ ${UI_SOURCES}
+ ui_syscalls.c
+ )
+
+target_include_directories(
+ ui PUBLIC
+ ${QC_SOURCE_DIR}
+ ${BG_SOURCE_DIR}
+ )
+
+include(${CMAKE_SOURCE_DIR}/cmake/AddQVM.cmake)
+add_qvm( ui ${UI_SOURCES} ui_syscalls.asm )
+
+add_custom_command(
+ TARGET ui POST_BUILD
+ COMMAND ${CMAKE_COMMAND}
+ ARGS -E copy ${CMAKE_CURRENT_BINARY_DIR}/libui${CMAKE_SHARED_LIBRARY_SUFFIX} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/gpp/ui${CMAKE_SHARED_LIBRARY_SUFFIX}
+ )
diff --git a/src/ui/menudef.h b/src/ui/menudef.h
deleted file mode 100644
index dbd0996..0000000
--- a/src/ui/menudef.h
+++ /dev/null
@@ -1,363 +0,0 @@
-
-#define ITEM_TYPE_TEXT 0 // simple text
-#define ITEM_TYPE_BUTTON 1 // button, basically text with a border
-#define ITEM_TYPE_RADIOBUTTON 2 // toggle button, may be grouped
-#define ITEM_TYPE_CHECKBOX 3 // check box
-#define ITEM_TYPE_EDITFIELD 4 // editable text, associated with a cvar
-#define ITEM_TYPE_SAYFIELD 5 // the chat field
-#define ITEM_TYPE_COMBO 6 // drop down list
-#define ITEM_TYPE_LISTBOX 7 // scrollable list
-#define ITEM_TYPE_MODEL 8 // model
-#define ITEM_TYPE_OWNERDRAW 9 // owner draw, name specs what it is
-#define ITEM_TYPE_NUMERICFIELD 10 // editable text, associated with a cvar
-#define ITEM_TYPE_SLIDER 11 // mouse speed, volume, etc.
-#define ITEM_TYPE_YESNO 12 // yes no cvar setting
-#define ITEM_TYPE_MULTI 13 // multiple list setting, enumerated
-#define ITEM_TYPE_BIND 14 // multiple list setting, enumerated
-
-#define ITEM_ALIGN_LEFT 0 // left alignment
-#define ITEM_ALIGN_CENTER 1 // center alignment
-#define ITEM_ALIGN_RIGHT 2 // right alignment
-
-#define ITEM_TEXTSTYLE_NORMAL 0 // normal text
-#define ITEM_TEXTSTYLE_BLINK 1 // fast blinking
-#define ITEM_TEXTSTYLE_PULSE 2 // slow pulsing
-#define ITEM_TEXTSTYLE_SHADOWED 3 // drop shadow ( need a color for this )
-#define ITEM_TEXTSTYLE_OUTLINED 4 // drop shadow ( need a color for this )
-#define ITEM_TEXTSTYLE_OUTLINESHADOWED 5 // drop shadow ( need a color for this )
-#define ITEM_TEXTSTYLE_SHADOWEDMORE 6 // drop shadow ( need a color for this )
-#define ITEM_TEXTSTYLE_NEON 7 // drop shadow ( need a color for this )
-
-#define WINDOW_BORDER_NONE 0 // no border
-#define WINDOW_BORDER_FULL 1 // full border based on border color ( single pixel )
-#define WINDOW_BORDER_HORZ 2 // horizontal borders only
-#define WINDOW_BORDER_VERT 3 // vertical borders only
-#define WINDOW_BORDER_KCGRADIENT 4 // horizontal border using the gradient bars
-
-#define WINDOW_STYLE_EMPTY 0 // no background
-#define WINDOW_STYLE_FILLED 1 // filled with background color
-#define WINDOW_STYLE_GRADIENT 2 // gradient bar based on background color
-#define WINDOW_STYLE_SHADER 3 // gradient bar based on background color
-#define WINDOW_STYLE_TEAMCOLOR 4 // team color
-#define WINDOW_STYLE_CINEMATIC 5 // cinematic
-
-#define MENU_TRUE 1 // uh.. true
-#define MENU_FALSE 0 // and false
-
-#define HUD_VERTICAL 0x00
-#define HUD_HORIZONTAL 0x01
-
-// list box element types
-#define LISTBOX_TEXT 0x00
-#define LISTBOX_IMAGE 0x01
-
-// list feeders
-#define FEEDER_HEADS 0x00 // model heads
-#define FEEDER_MAPS 0x01 // text maps based on game type
-#define FEEDER_SERVERS 0x02 // servers
-#define FEEDER_CLANS 0x03 // clan names
-#define FEEDER_ALLMAPS 0x04 // all maps available, in graphic format
-#define FEEDER_ALIENTEAM_LIST 0x05 // red team members
-#define FEEDER_HUMANTEAM_LIST 0x06 // blue team members
-#define FEEDER_PLAYER_LIST 0x07 // players
-#define FEEDER_TEAM_LIST 0x08 // team members for team voting
-#define FEEDER_MODS 0x09 // team members for team voting
-#define FEEDER_DEMOS 0x0a // team members for team voting
-#define FEEDER_SCOREBOARD 0x0b // team members for team voting
-#define FEEDER_Q3HEADS 0x0c // model heads
-#define FEEDER_SERVERSTATUS 0x0d // server status
-#define FEEDER_FINDPLAYER 0x0e // find player
-#define FEEDER_CINEMATICS 0x0f // cinematics
-
-//TA: tremulous menus
-#define FEEDER_TREMTEAMS 0x10 //teams
-#define FEEDER_TREMALIENCLASSES 0x11 //alien classes
-#define FEEDER_TREMHUMANITEMS 0x12 //human items
-#define FEEDER_TREMHUMANARMOURYBUY 0x13 //human buy
-#define FEEDER_TREMHUMANARMOURYSELL 0x14 //human sell
-#define FEEDER_TREMALIENUPGRADE 0x15 //alien upgrade
-#define FEEDER_TREMALIENBUILD 0x16 //alien buildables
-#define FEEDER_TREMHUMANBUILD 0x17 //human buildables
-//TA: tremulous menus
-#define FEEDER_IGNORE_LIST 0x18 //ignored players
-
-// display flags
-#define CG_SHOW_BLUE_TEAM_HAS_REDFLAG 0x00000001
-#define CG_SHOW_RED_TEAM_HAS_BLUEFLAG 0x00000002
-#define CG_SHOW_ANYTEAMGAME 0x00000004
-#define CG_SHOW_HARVESTER 0x00000008
-#define CG_SHOW_ONEFLAG 0x00000010
-#define CG_SHOW_CTF 0x00000020
-#define CG_SHOW_OBELISK 0x00000040
-#define CG_SHOW_HEALTHCRITICAL 0x00000080
-#define CG_SHOW_SINGLEPLAYER 0x00000100
-#define CG_SHOW_TOURNAMENT 0x00000200
-#define CG_SHOW_DURINGINCOMINGVOICE 0x00000400
-#define CG_SHOW_IF_PLAYER_HAS_FLAG 0x00000800
-#define CG_SHOW_LANPLAYONLY 0x00001000
-#define CG_SHOW_MINED 0x00002000
-#define CG_SHOW_HEALTHOK 0x00004000
-#define CG_SHOW_TEAMINFO 0x00008000
-#define CG_SHOW_NOTEAMINFO 0x00010000
-#define CG_SHOW_OTHERTEAMHASFLAG 0x00020000
-#define CG_SHOW_YOURTEAMHASENEMYFLAG 0x00040000
-#define CG_SHOW_ANYNONTEAMGAME 0x00080000
-#define CG_SHOW_2DONLY 0x10000000
-
-
-#define UI_SHOW_LEADER 0x00000001
-#define UI_SHOW_NOTLEADER 0x00000002
-#define UI_SHOW_FAVORITESERVERS 0x00000004
-#define UI_SHOW_ANYNONTEAMGAME 0x00000008
-#define UI_SHOW_ANYTEAMGAME 0x00000010
-#define UI_SHOW_NEWHIGHSCORE 0x00000020
-#define UI_SHOW_DEMOAVAILABLE 0x00000040
-#define UI_SHOW_NEWBESTTIME 0x00000080
-#define UI_SHOW_FFA 0x00000100
-#define UI_SHOW_NOTFFA 0x00000200
-#define UI_SHOW_NETANYNONTEAMGAME 0x00000400
-#define UI_SHOW_NETANYTEAMGAME 0x00000800
-#define UI_SHOW_NOTFAVORITESERVERS 0x00001000
-
-#define UI_SHOW_VOTEACTIVE 0x00002000
-#define UI_SHOW_CANVOTE 0x00004000
-#define UI_SHOW_TEAMVOTEACTIVE 0x00008000
-#define UI_SHOW_CANTEAMVOTE 0x00010000
-
-#define UI_SHOW_NOTSPECTATING 0x00020000
-
-// owner draw types
-// ideally these should be done outside of this file but
-// this makes it much easier for the macro expansion to
-// convert them for the designers ( from the .menu files )
-#define CG_OWNERDRAW_BASE 1
-#define CG_PLAYER_ARMOR_ICON 1
-#define CG_PLAYER_ARMOR_VALUE 2
-#define CG_PLAYER_HEAD 3
-#define CG_PLAYER_HEALTH 4
-#define CG_PLAYER_HEALTH_BAR 92
-#define CG_PLAYER_HEALTH_CROSS 99
-#define CG_PLAYER_AMMO_ICON 5
-#define CG_PLAYER_AMMO_VALUE 6
-#define CG_PLAYER_CLIPS_VALUE 70
-#define CG_PLAYER_BUILD_TIMER 115
-#define CG_PLAYER_CREDITS_VALUE 71
-#define CG_PLAYER_BANK_VALUE 72
-#define CG_PLAYER_CREDITS_VALUE_NOPAD 106
-#define CG_PLAYER_BANK_VALUE_NOPAD 107
-#define CG_PLAYER_STAMINA 73
-#define CG_PLAYER_STAMINA_1 93
-#define CG_PLAYER_STAMINA_2 94
-#define CG_PLAYER_STAMINA_3 95
-#define CG_PLAYER_STAMINA_4 96
-#define CG_PLAYER_STAMINA_BOLT 97
-#define CG_PLAYER_BOOST_BOLT 112
-#define CG_PLAYER_CLIPS_RING 98
-#define CG_PLAYER_BUILD_TIMER_RING 113
-#define CG_PLAYER_SELECT 74
-#define CG_PLAYER_SELECTTEXT 75
-#define CG_PLAYER_WEAPONICON 111
-#define CG_PLAYER_WALLCLIMBING 103
-#define CG_PLAYER_BOOSTED 104
-#define CG_PLAYER_POISON_BARBS 105
-#define CG_PLAYER_ALIEN_SENSE 108
-#define CG_PLAYER_HUMAN_SCANNER 109
-#define CG_PLAYER_USABLE_BUILDABLE 110
-#define CG_SELECTEDPLAYER_HEAD 7
-#define CG_SELECTEDPLAYER_NAME 8
-#define CG_SELECTEDPLAYER_LOCATION 9
-#define CG_SELECTEDPLAYER_STATUS 10
-#define CG_SELECTEDPLAYER_WEAPON 11
-#define CG_SELECTEDPLAYER_POWERUP 12
-
-#define CG_FLAGCARRIER_HEAD 13
-#define CG_FLAGCARRIER_NAME 14
-#define CG_FLAGCARRIER_LOCATION 15
-#define CG_FLAGCARRIER_STATUS 16
-#define CG_FLAGCARRIER_WEAPON 17
-#define CG_FLAGCARRIER_POWERUP 18
-
-#define CG_PLAYER_ITEM 19
-#define CG_PLAYER_SCORE 20
-
-#define CG_BLUE_FLAGHEAD 21
-#define CG_BLUE_FLAGSTATUS 22
-#define CG_BLUE_FLAGNAME 23
-#define CG_RED_FLAGHEAD 24
-#define CG_RED_FLAGSTATUS 25
-#define CG_RED_FLAGNAME 26
-
-#define CG_BLUE_SCORE 27
-#define CG_RED_SCORE 28
-#define CG_RED_NAME 29
-#define CG_BLUE_NAME 30
-#define CG_HARVESTER_SKULLS 31 // only shows in harvester
-#define CG_ONEFLAG_STATUS 32 // only shows in one flag
-#define CG_PLAYER_LOCATION 33
-#define CG_TEAM_COLOR 34
-#define CG_CTF_POWERUP 35
-
-#define CG_AREA_POWERUP 36
-#define CG_AREA_LAGOMETER 37 // painted with old system
-#define CG_PLAYER_HASFLAG 38
-#define CG_GAME_TYPE 39 // not done
-
-#define CG_SELECTEDPLAYER_ARMOR 40
-#define CG_SELECTEDPLAYER_HEALTH 41
-#define CG_PLAYER_STATUS 42
-#define CG_FRAGGED_MSG 43 // painted with old system
-#define CG_PROXMINED_MSG 44 // painted with old system
-#define CG_AREA_FPSINFO 45 // painted with old system
-#define CG_GAME_STATUS 49
-#define CG_KILLER 50
-#define CG_PLAYER_ARMOR_ICON2D 51
-#define CG_PLAYER_AMMO_ICON2D 52
-#define CG_ACCURACY 53
-#define CG_ASSISTS 54
-#define CG_DEFEND 55
-#define CG_EXCELLENT 56
-#define CG_IMPRESSIVE 57
-#define CG_PERFECT 58
-#define CG_GAUNTLET 59
-#define CG_SPECTATORS 60
-#define CG_TEAMINFO 61
-#define CG_VOICE_HEAD 62
-#define CG_VOICE_NAME 63
-#define CG_PLAYER_HASFLAG2D 64
-#define CG_HARVESTER_SKULLS2D 65 // only shows in harvester
-#define CG_CAPFRAGLIMIT 66
-#define CG_1STPLACE 67
-#define CG_2NDPLACE 68
-#define CG_CAPTURES 69
-
-//TA: loading screen
-#define CG_LOAD_LEVELSHOT 76
-#define CG_LOAD_MEDIA 77
-#define CG_LOAD_MEDIA_LABEL 78
-#define CG_LOAD_BUILDABLES 79
-#define CG_LOAD_BUILDABLES_LABEL 80
-#define CG_LOAD_CHARMODEL 81
-#define CG_LOAD_CHARMODEL_LABEL 82
-#define CG_LOAD_OVERALL 83
-#define CG_LOAD_LEVELNAME 84
-#define CG_LOAD_MOTD 85
-#define CG_LOAD_HOSTNAME 86
-
-#define CG_FPS 87
-#define CG_FPS_FIXED 100
-#define CG_TIMER 88
-#define CG_TIMER_MINS 101
-#define CG_TIMER_SECS 102
-#define CG_SNAPSHOT 89
-#define CG_LAGOMETER 90
-#define CG_PLAYER_CROSSHAIRNAMES 114
-#define CG_STAGE_REPORT_TEXT 116
-#define CG_DEMO_PLAYBACK 117
-#define CG_DEMO_RECORDING 118
-
-#define CG_CONSOLE 91
-#define CG_TUTORIAL 119
-#define CG_CLOCK 120
-
-
-
-#define UI_OWNERDRAW_BASE 200
-#define UI_HANDICAP 200
-#define UI_PLAYERMODEL 202
-#define UI_CLANNAME 203
-#define UI_CLANLOGO 204
-#define UI_GAMETYPE 205
-#define UI_MAPPREVIEW 206
-#define UI_SKILL 207
-#define UI_BLUETEAMNAME 208
-#define UI_REDTEAMNAME 209
-#define UI_BLUETEAM1 210
-#define UI_BLUETEAM2 211
-#define UI_BLUETEAM3 212
-#define UI_BLUETEAM4 213
-#define UI_BLUETEAM5 214
-#define UI_REDTEAM1 215
-#define UI_REDTEAM2 216
-#define UI_REDTEAM3 217
-#define UI_REDTEAM4 218
-#define UI_REDTEAM5 219
-#define UI_NETSOURCE 220
-#define UI_NETMAPPREVIEW 221
-#define UI_NETFILTER 222
-#define UI_TIER 223
-#define UI_OPPONENTMODEL 224
-#define UI_TIERMAP1 225
-#define UI_TIERMAP2 226
-#define UI_TIERMAP3 227
-#define UI_PLAYERLOGO 228
-#define UI_OPPONENTLOGO 229
-#define UI_PLAYERLOGO_METAL 230
-#define UI_OPPONENTLOGO_METAL 231
-#define UI_PLAYERLOGO_NAME 232
-#define UI_OPPONENTLOGO_NAME 233
-#define UI_TIER_MAPNAME 234
-#define UI_TIER_GAMETYPE 235
-#define UI_ALLMAPS_SELECTION 236
-#define UI_OPPONENT_NAME 237
-#define UI_VOTE_KICK 238
-#define UI_BOTNAME 239
-#define UI_BOTSKILL 240
-#define UI_REDBLUE 241
-#define UI_SELECTEDPLAYER 243
-#define UI_MAPCINEMATIC 244
-#define UI_NETGAMETYPE 245
-#define UI_NETMAPCINEMATIC 246
-#define UI_SERVERREFRESHDATE 247
-#define UI_SERVERMOTD 248
-#define UI_GLINFO 249
-#define UI_KEYBINDSTATUS 250
-#define UI_CLANCINEMATIC 251
-#define UI_MAP_TIMETOBEAT 252
-#define UI_JOINGAMETYPE 253
-#define UI_PREVIEWCINEMATIC 254
-#define UI_STARTMAPCINEMATIC 255
-#define UI_MAPS_SELECTION 256
-
-//TA:
-//#define UI_DIALOG 257
-#define UI_TEAMINFOPANE 258
-#define UI_ACLASSINFOPANE 259
-#define UI_AUPGRADEINFOPANE 260
-#define UI_HITEMINFOPANE 261
-#define UI_HBUYINFOPANE 262
-#define UI_HSELLINFOPANE 263
-#define UI_ABUILDINFOPANE 264
-#define UI_HBUILDINFOPANE 265
-
-#define UI_PLAYERLIST_SELECTION 266
-#define UI_TEAMLIST_SELECTION 267
-
-#define VOICECHAT_GETFLAG "getflag" // command someone to get the flag
-#define VOICECHAT_OFFENSE "offense" // command someone to go on offense
-#define VOICECHAT_DEFEND "defend" // command someone to go on defense
-#define VOICECHAT_DEFENDFLAG "defendflag" // command someone to defend the flag
-#define VOICECHAT_PATROL "patrol" // command someone to go on patrol (roam)
-#define VOICECHAT_CAMP "camp" // command someone to camp (we don't have sounds for this one)
-#define VOICECHAT_FOLLOWME "followme" // command someone to follow you
-#define VOICECHAT_RETURNFLAG "returnflag" // command someone to return our flag
-#define VOICECHAT_FOLLOWFLAGCARRIER "followflagcarrier" // command someone to follow the flag carrier
-#define VOICECHAT_YES "yes" // yes, affirmative, etc.
-#define VOICECHAT_NO "no" // no, negative, etc.
-#define VOICECHAT_ONGETFLAG "ongetflag" // I'm getting the flag
-#define VOICECHAT_ONOFFENSE "onoffense" // I'm on offense
-#define VOICECHAT_ONDEFENSE "ondefense" // I'm on defense
-#define VOICECHAT_ONPATROL "onpatrol" // I'm on patrol (roaming)
-#define VOICECHAT_ONCAMPING "oncamp" // I'm camping somewhere
-#define VOICECHAT_ONFOLLOW "onfollow" // I'm following
-#define VOICECHAT_ONFOLLOWCARRIER "onfollowcarrier" // I'm following the flag carrier
-#define VOICECHAT_ONRETURNFLAG "onreturnflag" // I'm returning our flag
-#define VOICECHAT_INPOSITION "inposition" // I'm in position
-#define VOICECHAT_IHAVEFLAG "ihaveflag" // I have the flag
-#define VOICECHAT_BASEATTACK "baseattack" // the base is under attack
-#define VOICECHAT_ENEMYHASFLAG "enemyhasflag" // the enemy has our flag (CTF)
-#define VOICECHAT_STARTLEADER "startleader" // I'm the leader
-#define VOICECHAT_STOPLEADER "stopleader" // I resign leadership
-#define VOICECHAT_TRASH "trash" // lots of trash talk
-#define VOICECHAT_WHOISLEADER "whoisleader" // who is the team leader
-#define VOICECHAT_WANTONDEFENSE "wantondefense" // I want to be on defense
-#define VOICECHAT_WANTONOFFENSE "wantonoffense" // I want to be on offense
diff --git a/src/ui/ui_atoms.c b/src/ui/ui_atoms.c
index a3033c4..b70d34d 100644
--- a/src/ui/ui_atoms.c
+++ b/src/ui/ui_atoms.c
@@ -1,13 +1,14 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
-Copyright (C) 2000-2006 Tim Angus
+Copyright (C) 2000-2013 Darklegion Development
+Copyright (C) 2015-2019 GrangerHub
This file is part of Tremulous.
Tremulous 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,
+published by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
Tremulous is distributed in the hope that it will be
@@ -16,8 +17,8 @@ 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 Tremulous; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+along with Tremulous; if not, see <https://www.gnu.org/licenses/>
+
===========================================================================
*/
@@ -28,43 +29,46 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
**********************************************************************/
#include "ui_local.h"
-qboolean m_entersound; // after a frame, so caching won't disrupt the sound
+qboolean m_entersound; // after a frame, so caching won't disrupt the sound
-void QDECL Com_Error( int level, const char *error, ... ) {
- va_list argptr;
- char text[1024];
+void QDECL Com_Error(int level, const char *error, ...)
+{
+ va_list argptr;
+ char text[1024];
- va_start (argptr, error);
- vsprintf (text, error, argptr);
- va_end (argptr);
+ va_start(argptr, error);
+ Q_vsnprintf(text, sizeof(text), error, argptr);
+ va_end(argptr);
- trap_Error( va("%s", text) );
+ trap_Error(text);
}
-void QDECL Com_Printf( const char *msg, ... ) {
- va_list argptr;
- char text[1024];
+void QDECL Com_Printf(const char *msg, ...)
+{
+ va_list argptr;
+ char text[1024];
- va_start (argptr, msg);
- vsprintf (text, msg, argptr);
- va_end (argptr);
+ va_start(argptr, msg);
+ Q_vsnprintf(text, sizeof(text), msg, argptr);
+ va_end(argptr);
- trap_Print( va("%s", text) );
+ trap_Print(text);
}
-qboolean newUI = qfalse;
-
-
/*
=================
UI_ClampCvar
=================
*/
-float UI_ClampCvar( float min, float max, float value )
+float UI_ClampCvar(float min, float max, float value)
{
- if ( value < min ) return min;
- if ( value > max ) return max;
- return value;
+ if (value < min)
+ return min;
+
+ if (value > max)
+ return max;
+
+ return value;
}
/*
@@ -72,418 +76,196 @@ float UI_ClampCvar( float min, float max, float value )
UI_StartDemoLoop
=================
*/
-void UI_StartDemoLoop( void ) {
- trap_Cmd_ExecuteText( EXEC_APPEND, "d1\n" );
-}
+void UI_StartDemoLoop(void) { trap_Cmd_ExecuteText(EXEC_APPEND, "d1\n"); }
-char *UI_Argv( int arg ) {
- static char buffer[MAX_STRING_CHARS];
+char *UI_Argv(int arg)
+{
+ static char buffer[MAX_STRING_CHARS];
- trap_Argv( arg, buffer, sizeof( buffer ) );
+ trap_Argv(arg, buffer, sizeof(buffer));
- return buffer;
+ return buffer;
}
+char *UI_ConcatArgs(int arg, char *buf, int len)
+{
+ char *p;
+ int c;
-char *UI_Cvar_VariableString( const char *var_name ) {
- static char buffer[MAX_STRING_CHARS];
+ if (len <= 0)
+ return buf;
- trap_Cvar_VariableStringBuffer( var_name, buffer, sizeof( buffer ) );
+ p = buf;
+ c = trap_Argc();
- return buffer;
-}
+ for (; arg < c; arg++)
+ {
+ char *argp = UI_Argv(arg);
+ while (*argp && p < &buf[len - 1])
+ *p++ = *argp++;
+ if (p < &buf[len - 2])
+ *p++ = ' ';
+ else
+ break;
+ }
-void UI_SetBestScores(postGameInfo_t *newInfo, qboolean postGame) {
- trap_Cvar_Set("ui_scoreAccuracy", va("%i%%", newInfo->accuracy));
- trap_Cvar_Set("ui_scoreImpressives", va("%i", newInfo->impressives));
- trap_Cvar_Set("ui_scoreExcellents", va("%i", newInfo->excellents));
- trap_Cvar_Set("ui_scoreDefends", va("%i", newInfo->defends));
- trap_Cvar_Set("ui_scoreAssists", va("%i", newInfo->assists));
- trap_Cvar_Set("ui_scoreGauntlets", va("%i", newInfo->gauntlets));
- trap_Cvar_Set("ui_scoreScore", va("%i", newInfo->score));
- trap_Cvar_Set("ui_scorePerfect", va("%i", newInfo->perfects));
- trap_Cvar_Set("ui_scoreTeam", va("%i to %i", newInfo->redScore, newInfo->blueScore));
- trap_Cvar_Set("ui_scoreBase", va("%i", newInfo->baseScore));
- trap_Cvar_Set("ui_scoreTimeBonus", va("%i", newInfo->timeBonus));
- trap_Cvar_Set("ui_scoreSkillBonus", va("%i", newInfo->skillBonus));
- trap_Cvar_Set("ui_scoreShutoutBonus", va("%i", newInfo->shutoutBonus));
- trap_Cvar_Set("ui_scoreTime", va("%02i:%02i", newInfo->time / 60, newInfo->time % 60));
- trap_Cvar_Set("ui_scoreCaptures", va("%i", newInfo->captures));
- if (postGame) {
- trap_Cvar_Set("ui_scoreAccuracy2", va("%i%%", newInfo->accuracy));
- trap_Cvar_Set("ui_scoreImpressives2", va("%i", newInfo->impressives));
- trap_Cvar_Set("ui_scoreExcellents2", va("%i", newInfo->excellents));
- trap_Cvar_Set("ui_scoreDefends2", va("%i", newInfo->defends));
- trap_Cvar_Set("ui_scoreAssists2", va("%i", newInfo->assists));
- trap_Cvar_Set("ui_scoreGauntlets2", va("%i", newInfo->gauntlets));
- trap_Cvar_Set("ui_scoreScore2", va("%i", newInfo->score));
- trap_Cvar_Set("ui_scorePerfect2", va("%i", newInfo->perfects));
- trap_Cvar_Set("ui_scoreTeam2", va("%i to %i", newInfo->redScore, newInfo->blueScore));
- trap_Cvar_Set("ui_scoreBase2", va("%i", newInfo->baseScore));
- trap_Cvar_Set("ui_scoreTimeBonus2", va("%i", newInfo->timeBonus));
- trap_Cvar_Set("ui_scoreSkillBonus2", va("%i", newInfo->skillBonus));
- trap_Cvar_Set("ui_scoreShutoutBonus2", va("%i", newInfo->shutoutBonus));
- trap_Cvar_Set("ui_scoreTime2", va("%02i:%02i", newInfo->time / 60, newInfo->time % 60));
- trap_Cvar_Set("ui_scoreCaptures2", va("%i", newInfo->captures));
- }
-}
+ *p = '\0';
-void UI_LoadBestScores(const char *map, int game) {
- char fileName[MAX_QPATH];
- fileHandle_t f;
- postGameInfo_t newInfo;
- memset(&newInfo, 0, sizeof(postGameInfo_t));
- Com_sprintf(fileName, MAX_QPATH, "games/%s_%i.game", map, game);
- if (trap_FS_FOpenFile(fileName, &f, FS_READ) >= 0) {
- int size = 0;
- trap_FS_Read(&size, sizeof(int), f);
- if (size == sizeof(postGameInfo_t)) {
- trap_FS_Read(&newInfo, sizeof(postGameInfo_t), f);
- }
- trap_FS_FCloseFile(f);
- }
- UI_SetBestScores(&newInfo, qfalse);
-
- Com_sprintf(fileName, MAX_QPATH, "demos/%s_%d.dm_%d", map, game, (int)trap_Cvar_VariableValue("protocol"));
- uiInfo.demoAvailable = qfalse;
- if (trap_FS_FOpenFile(fileName, &f, FS_READ) >= 0) {
- uiInfo.demoAvailable = qtrue;
- trap_FS_FCloseFile(f);
- }
+ return buf;
}
-/*
-===============
-UI_ClearScores
-===============
-*/
-void UI_ClearScores( void ) {
- char gameList[4096];
- char *gameFile;
- int i, len, count, size;
- fileHandle_t f;
- postGameInfo_t newInfo;
-
- count = trap_FS_GetFileList( "games", "game", gameList, sizeof(gameList) );
-
- size = sizeof(postGameInfo_t);
- memset(&newInfo, 0, size);
-
- if (count > 0) {
- gameFile = gameList;
- for ( i = 0; i < count; i++ ) {
- len = strlen(gameFile);
- if (trap_FS_FOpenFile(va("games/%s",gameFile), &f, FS_WRITE) >= 0) {
- trap_FS_Write(&size, sizeof(int), f);
- trap_FS_Write(&newInfo, size, f);
- trap_FS_FCloseFile(f);
- }
- gameFile += len + 1;
- }
- }
+char *UI_Cvar_VariableString(const char *var_name)
+{
+ static char buffer[MAX_STRING_CHARS];
- UI_SetBestScores(&newInfo, qfalse);
+ trap_Cvar_VariableStringBuffer(var_name, buffer, sizeof(buffer));
+ return buffer;
}
+static void UI_Cache_f(void) { Display_CacheAll(); }
-
-static void UI_Cache_f( void ) {
- Display_CacheAll();
+static void UI_Menu_f(void)
+{
+ if (Menu_Count() > 0)
+ {
+ trap_Key_SetCatcher(KEYCATCH_UI);
+ Menus_ActivateByName(UI_Argv(1));
+ }
}
-/*
-=======================
-UI_CalcPostGameStats
-=======================
-*/
-static void UI_CalcPostGameStats( void ) {
- char map[MAX_QPATH];
- char fileName[MAX_QPATH];
- char info[MAX_INFO_STRING];
- fileHandle_t f;
- int size, game, time, adjustedTime;
- postGameInfo_t oldInfo;
- postGameInfo_t newInfo;
- qboolean newHigh = qfalse;
-
- trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) );
- Q_strncpyz( map, Info_ValueForKey( info, "mapname" ), sizeof(map) );
- game = atoi(Info_ValueForKey(info, "g_gametype"));
-
- // compose file name
- Com_sprintf(fileName, MAX_QPATH, "games/%s_%i.game", map, game);
- // see if we have one already
- memset(&oldInfo, 0, sizeof(postGameInfo_t));
- if (trap_FS_FOpenFile(fileName, &f, FS_READ) >= 0) {
- // if so load it
- size = 0;
- trap_FS_Read(&size, sizeof(int), f);
- if (size == sizeof(postGameInfo_t)) {
- trap_FS_Read(&oldInfo, sizeof(postGameInfo_t), f);
- }
- trap_FS_FCloseFile(f);
- }
-
- newInfo.accuracy = atoi(UI_Argv(3));
- newInfo.impressives = atoi(UI_Argv(4));
- newInfo.excellents = atoi(UI_Argv(5));
- newInfo.defends = atoi(UI_Argv(6));
- newInfo.assists = atoi(UI_Argv(7));
- newInfo.gauntlets = atoi(UI_Argv(8));
- newInfo.baseScore = atoi(UI_Argv(9));
- newInfo.perfects = atoi(UI_Argv(10));
- newInfo.redScore = atoi(UI_Argv(11));
- newInfo.blueScore = atoi(UI_Argv(12));
- time = atoi(UI_Argv(13));
- newInfo.captures = atoi(UI_Argv(14));
-
- newInfo.time = (time - trap_Cvar_VariableValue("ui_matchStartTime")) / 1000;
- adjustedTime = uiInfo.mapList[ui_currentMap.integer].timeToBeat[game];
- if (newInfo.time < adjustedTime) {
- newInfo.timeBonus = (adjustedTime - newInfo.time) * 10;
- } else {
- newInfo.timeBonus = 0;
- }
-
- if (newInfo.redScore > newInfo.blueScore && newInfo.blueScore <= 0) {
- newInfo.shutoutBonus = 100;
- } else {
- newInfo.shutoutBonus = 0;
- }
-
- newInfo.skillBonus = trap_Cvar_VariableValue("g_spSkill");
- if (newInfo.skillBonus <= 0) {
- newInfo.skillBonus = 1;
- }
- newInfo.score = newInfo.baseScore + newInfo.shutoutBonus + newInfo.timeBonus;
- newInfo.score *= newInfo.skillBonus;
-
- // see if the score is higher for this one
- newHigh = (newInfo.redScore > newInfo.blueScore && newInfo.score > oldInfo.score);
-
- if (newHigh) {
- // if so write out the new one
- uiInfo.newHighScoreTime = uiInfo.uiDC.realTime + 20000;
- if (trap_FS_FOpenFile(fileName, &f, FS_WRITE) >= 0) {
- size = sizeof(postGameInfo_t);
- trap_FS_Write(&size, sizeof(int), f);
- trap_FS_Write(&newInfo, sizeof(postGameInfo_t), f);
- trap_FS_FCloseFile(f);
+static void UI_CloseMenus_f(void)
+{
+ if (Menu_Count() > 0)
+ {
+ trap_Key_SetCatcher(trap_Key_GetCatcher() & ~KEYCATCH_UI);
+ trap_Key_ClearStates();
+ trap_Cvar_Set("cl_paused", "0");
+ Menus_CloseAll();
}
- }
+}
- if (newInfo.time < oldInfo.time) {
- uiInfo.newBestTime = uiInfo.uiDC.realTime + 20000;
- }
+static void UI_MessageMode_f(void)
+{
+ char *arg = UI_Argv(0);
- // put back all the ui overrides
- trap_Cvar_Set("capturelimit", UI_Cvar_VariableString("ui_saveCaptureLimit"));
- trap_Cvar_Set("fraglimit", UI_Cvar_VariableString("ui_saveFragLimit"));
- trap_Cvar_Set("cg_drawTimer", UI_Cvar_VariableString("ui_drawTimer"));
- trap_Cvar_Set("g_doWarmup", UI_Cvar_VariableString("ui_doWarmup"));
- trap_Cvar_Set("g_Warmup", UI_Cvar_VariableString("ui_Warmup"));
- trap_Cvar_Set("sv_pure", UI_Cvar_VariableString("ui_pure"));
- trap_Cvar_Set("g_friendlyFire", UI_Cvar_VariableString("ui_friendlyFire"));
+ trap_Cvar_Set("ui_sayBuffer", "");
- UI_SetBestScores(&newInfo, qtrue);
- UI_ShowPostGame(newHigh);
+ switch (arg[11])
+ {
+ default:
+ case '\0':
+ // Global
+ uiInfo.chatTeam = qfalse;
+ break;
+
+ case '2':
+ // Team
+ uiInfo.chatTeam = qtrue;
+ break;
+ }
+ trap_Key_SetCatcher(KEYCATCH_UI);
+ Menus_CloseByName("say");
+ Menus_CloseByName("say_team");
+ if (uiInfo.chatTeam)
+ Menus_ActivateByName("say_team");
+ else
+ Menus_ActivateByName("say");
}
-static void UI_MessageMode_f( void )
+static void UI_Me_f(void)
{
- char *arg = UI_Argv( 0 );
-
- trap_Cvar_Set( "ui_sayBuffer", "" );
-
- switch( arg[ 11 ] )
- {
- default:
- case '\0':
- // Global
- uiInfo.chatTeam = qfalse;
- break;
-
- case '2':
- // Team
- uiInfo.chatTeam = qtrue;
- break;
- }
-
- trap_Key_SetCatcher( KEYCATCH_UI );
- Menus_CloseByName( "say" );
- Menus_CloseByName( "say_team" );
-
- if( uiInfo.chatTeam )
- Menus_ActivateByName( "say_team" );
- else
- Menus_ActivateByName( "say" );
+ char buf[MAX_SAY_TEXT - 4];
+
+ UI_ConcatArgs(1, buf, sizeof(buf));
+
+ trap_Cmd_ExecuteText(EXEC_APPEND, va("say \"/me %s\"\n", buf));
}
+struct uicmd {
+ char *cmd;
+ void (*function)(void);
+} commands[] =
+{
+ {"closemenus", UI_CloseMenus_f},
+ {"me", UI_Me_f},
+ {"menu", UI_Menu_f},
+ {"messagemode", UI_MessageMode_f},
+ {"messagemode2", UI_MessageMode_f},
+ {"ui_cache", UI_Cache_f},
+ {"ui_load", UI_Load},
+ {"ui_report", UI_Report}
+};
/*
=================
UI_ConsoleCommand
=================
*/
-qboolean UI_ConsoleCommand( int realTime )
+qboolean UI_ConsoleCommand(int realTime)
{
- char *cmd;
- char *arg1;
-
- uiInfo.uiDC.frameTime = realTime - uiInfo.uiDC.realTime;
- uiInfo.uiDC.realTime = realTime;
-
- cmd = UI_Argv( 0 );
-
- // ensure minimum menu data is available
- //Menu_Cache();
-
- if ( Q_stricmp (cmd, "ui_test") == 0 ) {
- UI_ShowPostGame(qtrue);
- }
-
- if ( Q_stricmp (cmd, "ui_report") == 0 ) {
- UI_Report();
- return qtrue;
- }
-
- if ( Q_stricmp (cmd, "ui_load") == 0 ) {
- UI_Load();
- return qtrue;
- }
-
- if ( Q_stricmp (cmd, "remapShader") == 0 ) {
- if (trap_Argc() == 4) {
- char shader1[MAX_QPATH];
- char shader2[MAX_QPATH];
- Q_strncpyz(shader1, UI_Argv(1), sizeof(shader1));
- Q_strncpyz(shader2, UI_Argv(2), sizeof(shader2));
- trap_R_RemapShader(shader1, shader2, UI_Argv(3));
- return qtrue;
- }
- }
-
- if ( Q_stricmp (cmd, "postgame") == 0 ) {
- UI_CalcPostGameStats();
- return qtrue;
- }
+ struct uicmd *cmd = bsearch(UI_Argv(0), commands, ARRAY_LEN(commands), sizeof(commands[0]), cmdcmp);
- if ( Q_stricmp (cmd, "ui_cache") == 0 ) {
- UI_Cache_f();
- return qtrue;
- }
+ uiInfo.uiDC.frameTime = realTime - uiInfo.uiDC.realTime;
+ uiInfo.uiDC.realTime = realTime;
- if ( Q_stricmp (cmd, "ui_teamOrders") == 0 ) {
- //UI_TeamOrdersMenu_f();
- return qtrue;
- }
-
- if( Q_stricmp ( cmd, "menu" ) == 0 )
- {
- arg1 = UI_Argv( 1 );
-
- if( Menu_Count( ) > 0 )
+ if (cmd)
{
- trap_Key_SetCatcher( KEYCATCH_UI );
- Menus_ActivateByName( arg1 );
- return qtrue;
+ cmd->function();
+ return qtrue;
}
- }
-
- if( Q_stricmp ( cmd, "closemenus" ) == 0 )
- {
- if( Menu_Count( ) > 0 )
- {
- trap_Key_SetCatcher( trap_Key_GetCatcher( ) & ~KEYCATCH_UI );
- trap_Key_ClearStates( );
- trap_Cvar_Set( "cl_paused", "0" );
- Menus_CloseAll( );
- return qtrue;
- }
- }
-
- if( Q_stricmp ( cmd, "messagemode" ) == 0 ||
- Q_stricmp ( cmd, "messagemode2" ) == 0 )
- {
- UI_MessageMode_f();
- return qtrue;
- }
-
- return qfalse;
-}
-/*
-=================
-UI_Shutdown
-=================
-*/
-void UI_Shutdown( void ) {
+ return qfalse;
}
-/*
-================
-UI_AdjustFrom640
-
-Adjusted for resolution and screen aspect ratio
-================
-*/
-void UI_AdjustFrom640( float *x, float *y, float *w, float *h ) {
- // expect valid pointers
-#if 0
- *x = *x * uiInfo.uiDC.scale + uiInfo.uiDC.bias;
- *y *= uiInfo.uiDC.scale;
- *w *= uiInfo.uiDC.scale;
- *h *= uiInfo.uiDC.scale;
-#endif
-
- *x *= uiInfo.uiDC.xscale;
- *y *= uiInfo.uiDC.yscale;
- *w *= uiInfo.uiDC.xscale;
- *h *= uiInfo.uiDC.yscale;
+void UI_DrawNamedPic(float x, float y, float width, float height, const char *picname)
+{
+ qhandle_t hShader;
+ hShader = trap_R_RegisterShaderNoMip(picname);
+ UI_AdjustFrom640(&x, &y, &width, &height);
+ trap_R_DrawStretchPic(x, y, width, height, 0, 0, 1, 1, hShader);
}
-void UI_DrawNamedPic( float x, float y, float width, float height, const char *picname ) {
- qhandle_t hShader;
+void UI_DrawHandlePic(float x, float y, float w, float h, qhandle_t hShader)
+{
+ float s0;
+ float s1;
+ float t0;
+ float t1;
+
+ if (w < 0)
+ {
+ // flip about vertical
+ w = -w;
+ s0 = 1;
+ s1 = 0;
+ }
+ else
+ {
+ s0 = 0;
+ s1 = 1;
+ }
- hShader = trap_R_RegisterShaderNoMip( picname );
- UI_AdjustFrom640( &x, &y, &width, &height );
- trap_R_DrawStretchPic( x, y, width, height, 0, 0, 1, 1, hShader );
-}
+ if (h < 0)
+ {
+ // flip about horizontal
+ h = -h;
+ t0 = 1;
+ t1 = 0;
+ }
+ else
+ {
+ t0 = 0;
+ t1 = 1;
+ }
-void UI_DrawHandlePic( float x, float y, float w, float h, qhandle_t hShader ) {
- float s0;
- float s1;
- float t0;
- float t1;
-
- if( w < 0 ) { // flip about vertical
- w = -w;
- s0 = 1;
- s1 = 0;
- }
- else {
- s0 = 0;
- s1 = 1;
- }
-
- if( h < 0 ) { // flip about horizontal
- h = -h;
- t0 = 1;
- t1 = 0;
- }
- else {
- t0 = 0;
- t1 = 1;
- }
-
- UI_AdjustFrom640( &x, &y, &w, &h );
- trap_R_DrawStretchPic( x, y, w, h, s0, t0, s1, t1, hShader );
+ UI_AdjustFrom640(&x, &y, &w, &h);
+ trap_R_DrawStretchPic(x, y, w, h, s0, t0, s1, t1, hShader);
}
/*
@@ -493,64 +275,14 @@ UI_FillRect
Coordinates are 640*480 virtual values
=================
*/
-void UI_FillRect( float x, float y, float width, float height, const float *color ) {
- trap_R_SetColor( color );
-
- UI_AdjustFrom640( &x, &y, &width, &height );
- trap_R_DrawStretchPic( x, y, width, height, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
-
- trap_R_SetColor( NULL );
-}
-
-void UI_DrawSides(float x, float y, float w, float h) {
- UI_AdjustFrom640( &x, &y, &w, &h );
- trap_R_DrawStretchPic( x, y, 1, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
- trap_R_DrawStretchPic( x + w - 1, y, 1, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
-}
-
-void UI_DrawTopBottom(float x, float y, float w, float h) {
- UI_AdjustFrom640( &x, &y, &w, &h );
- trap_R_DrawStretchPic( x, y, w, 1, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
- trap_R_DrawStretchPic( x, y + h - 1, w, 1, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
-}
-/*
-================
-UI_DrawRect
-
-Coordinates are 640*480 virtual values
-=================
-*/
-void UI_DrawRect( float x, float y, float width, float height, const float *color ) {
- trap_R_SetColor( color );
-
- UI_DrawTopBottom(x, y, width, height);
- UI_DrawSides(x, y, width, height);
-
- trap_R_SetColor( NULL );
-}
-
-void UI_SetColor( const float *rgba ) {
- trap_R_SetColor( rgba );
-}
-
-void UI_UpdateScreen( void ) {
- trap_UpdateScreen();
-}
-
-
-void UI_DrawTextBox (int x, int y, int width, int lines)
+void UI_FillRect(float x, float y, float width, float height, const float *color)
{
- UI_FillRect( x + BIGCHAR_WIDTH/2, y + BIGCHAR_HEIGHT/2, ( width + 1 ) * BIGCHAR_WIDTH, ( lines + 1 ) * BIGCHAR_HEIGHT, colorBlack );
- UI_DrawRect( x + BIGCHAR_WIDTH/2, y + BIGCHAR_HEIGHT/2, ( width + 1 ) * BIGCHAR_WIDTH, ( lines + 1 ) * BIGCHAR_HEIGHT, colorWhite );
-}
+ trap_R_SetColor(color);
-qboolean UI_CursorInRect (int x, int y, int width, int height)
-{
- if (uiInfo.uiDC.cursorx < x ||
- uiInfo.uiDC.cursory < y ||
- uiInfo.uiDC.cursorx > x+width ||
- uiInfo.uiDC.cursory > y+height)
- return qfalse;
+ UI_AdjustFrom640(&x, &y, &width, &height);
+ trap_R_DrawStretchPic(x, y, width, height, 0, 0, 0, 0, uiInfo.uiDC.whiteShader);
- return qtrue;
+ trap_R_SetColor(NULL);
}
+
+void UI_SetColor(const float *rgba) { trap_R_SetColor(rgba); }
diff --git a/src/ui/ui_gameinfo.c b/src/ui/ui_gameinfo.c
index 43639e5..92c8a7b 100644
--- a/src/ui/ui_gameinfo.c
+++ b/src/ui/ui_gameinfo.c
@@ -1,13 +1,14 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
-Copyright (C) 2000-2006 Tim Angus
+Copyright (C) 2000-2013 Darklegion Development
+Copyright (C) 2015-2019 GrangerHub
This file is part of Tremulous.
Tremulous 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,
+published by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
Tremulous is distributed in the hope that it will be
@@ -16,8 +17,8 @@ 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 Tremulous; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+along with Tremulous; if not, see <https://www.gnu.org/licenses/>
+
===========================================================================
*/
@@ -27,72 +28,85 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "ui_local.h"
-
//
// arena and bot info
//
+int ui_numBots;
+static char *ui_botInfos[MAX_BOTS];
-int ui_numBots;
-static char *ui_botInfos[MAX_BOTS];
-
-static int ui_numArenas;
-static char *ui_arenaInfos[MAX_ARENAS];
+static int ui_numArenas;
+static char *ui_arenaInfos[MAX_ARENAS];
/*
===============
UI_ParseInfos
===============
*/
-int UI_ParseInfos( char *buf, int max, char *infos[] ) {
- char *token;
- int count;
- char key[MAX_TOKEN_CHARS];
- char info[MAX_INFO_STRING];
-
- count = 0;
-
- while ( 1 ) {
- token = COM_Parse( &buf );
- if ( !token[0] ) {
- break;
- }
- if ( strcmp( token, "{" ) ) {
- Com_Printf( "Missing { in info file\n" );
- break;
- }
+int UI_ParseInfos(char *buf, int max, char *infos[])
+{
+ char *token;
+ int count;
+ char key[MAX_TOKEN_CHARS];
+ char info[MAX_INFO_STRING];
- if ( count == max ) {
- Com_Printf( "Max infos exceeded\n" );
- break;
- }
+ count = 0;
- info[0] = '\0';
- while ( 1 ) {
- token = COM_ParseExt( &buf, qtrue );
- if ( !token[0] ) {
- Com_Printf( "Unexpected end of info file\n" );
- break;
- }
- if ( !strcmp( token, "}" ) ) {
- break;
- }
- Q_strncpyz( key, token, sizeof( key ) );
-
- token = COM_ParseExt( &buf, qfalse );
- if ( !token[0] ) {
- strcpy( token, "<NULL>" );
- }
- Info_SetValueForKey( info, key, token );
- }
- //NOTE: extra space for arena number
- infos[count] = UI_Alloc(strlen(info) + strlen("\\num\\") + strlen(va("%d", MAX_ARENAS)) + 1);
- if (infos[count]) {
- strcpy(infos[count], info);
- count++;
+ while (1)
+ {
+ token = COM_Parse(&buf);
+
+ if (!token[0])
+ break;
+
+ if (strcmp(token, "{"))
+ {
+ Com_Printf("Missing { in info file\n");
+ break;
+ }
+
+ if (count == max)
+ {
+ Com_Printf("Max infos exceeded\n");
+ break;
+ }
+
+ info[0] = '\0';
+
+ while (1)
+ {
+ token = COM_ParseExt(&buf, qtrue);
+
+ if (!token[0])
+ {
+ Com_Printf("Unexpected end of info file\n");
+ break;
+ }
+
+ if (!strcmp(token, "}"))
+ break;
+
+ Q_strncpyz(key, token, sizeof(key));
+
+ token = COM_ParseExt(&buf, qfalse);
+
+ if (!token[0])
+ strcpy(token, "<NULL>");
+
+ Info_SetValueForKey(info, key, token);
+ }
+
+ // NOTE: extra space for arena number
+ infos[count] = UI_Alloc(strlen(info) + strlen("\\num\\") + strlen(va("%d", MAX_ARENAS)) + 1);
+
+ if (infos[count])
+ {
+ strcpy(infos[count], info);
+ count++;
+ }
}
- }
- return count;
+
+ return count;
}
/*
@@ -100,27 +114,32 @@ int UI_ParseInfos( char *buf, int max, char *infos[] ) {
UI_LoadArenasFromFile
===============
*/
-static void UI_LoadArenasFromFile( char *filename ) {
- int len;
- fileHandle_t f;
- char buf[MAX_ARENAS_TEXT];
-
- len = trap_FS_FOpenFile( filename, &f, FS_READ );
- if ( !f ) {
- trap_Print( va( S_COLOR_RED "file not found: %s\n", filename ) );
- return;
- }
- if ( len >= MAX_ARENAS_TEXT ) {
- trap_Print( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, MAX_ARENAS_TEXT ) );
- trap_FS_FCloseFile( f );
- return;
- }
-
- trap_FS_Read( buf, len, f );
- buf[len] = 0;
- trap_FS_FCloseFile( f );
-
- ui_numArenas += UI_ParseInfos( buf, MAX_ARENAS - ui_numArenas, &ui_arenaInfos[ui_numArenas] );
+static void UI_LoadArenasFromFile(char *filename)
+{
+ int len;
+ fileHandle_t f;
+ char buf[MAX_ARENAS_TEXT];
+
+ len = trap_FS_FOpenFile(filename, &f, FS_READ);
+
+ if (!f)
+ {
+ trap_Print(va(S_COLOR_RED "file not found: %s\n", filename));
+ return;
+ }
+
+ if (len >= MAX_ARENAS_TEXT)
+ {
+ trap_Print(va(S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, MAX_ARENAS_TEXT));
+ trap_FS_FCloseFile(f);
+ return;
+ }
+
+ trap_FS_Read(buf, len, f);
+ buf[len] = 0;
+ trap_FS_FCloseFile(f);
+
+ ui_numArenas += UI_ParseInfos(buf, MAX_ARENAS - ui_numArenas, &ui_arenaInfos[ui_numArenas]);
}
/*
@@ -128,12 +147,12 @@ static void UI_LoadArenasFromFile( char *filename ) {
UI_MapNameCompare
=================
*/
-static int UI_MapNameCompare( const void *a, const void *b )
+static int UI_MapNameCompare(const void *a, const void *b)
{
- mapInfo *A = (mapInfo *)a;
- mapInfo *B = (mapInfo *)b;
+ mapInfo *A = (mapInfo *)a;
+ mapInfo *B = (mapInfo *)b;
- return Q_stricmp( A->mapName, B->mapName );
+ return Q_stricmp(A->mapName, B->mapName);
}
/*
@@ -141,86 +160,86 @@ static int UI_MapNameCompare( const void *a, const void *b )
UI_LoadArenas
===============
*/
-void UI_LoadArenas( void ) {
- int numdirs;
- char filename[128];
- char dirlist[1024];
- char* dirptr;
- int i, n;
- int dirlen;
- char *type;
-
- ui_numArenas = 0;
- uiInfo.mapCount = 0;
-
- // get all arenas from .arena files
- numdirs = trap_FS_GetFileList("scripts", ".arena", dirlist, 1024 );
- dirptr = dirlist;
- for (i = 0; i < numdirs; i++, dirptr += dirlen+1) {
- dirlen = strlen(dirptr);
- strcpy(filename, "scripts/");
- strcat(filename, dirptr);
- UI_LoadArenasFromFile(filename);
- }
- trap_Print( va( "[skipnotify]%i arenas parsed\n", ui_numArenas ) );
- if (UI_OutOfMemory()) {
- trap_Print(S_COLOR_YELLOW"WARNING: not anough memory in pool to load all arenas\n");
- }
-
- for( n = 0; n < ui_numArenas; n++ )
- {
- // determine type
- type = Info_ValueForKey( ui_arenaInfos[ n ], "type" );
- // if no type specified, it will be treated as "ffa"
-
- if( *type && strstr( type, "tremulous" ) )
- uiInfo.mapList[ uiInfo.mapCount ].typeBits |= ( 1 << 0 );
- else
- continue; //not a trem map
+void UI_LoadArenas(void)
+{
+ int numdirs;
+ char filename[128];
+ char dirlist[1024];
+ char *dirptr;
+ int i, n;
+ int dirlen;
+
+ ui_numArenas = 0;
+ uiInfo.mapCount = 0;
+
+ // get all arenas from .arena files
+ numdirs = trap_FS_GetFileList("scripts", ".arena", dirlist, 1024);
+ dirptr = dirlist;
+
+ for (i = 0; i < numdirs; i++, dirptr += dirlen + 1)
+ {
+ dirlen = strlen(dirptr);
+ strcpy(filename, "scripts/");
+ strcat(filename, dirptr);
+ UI_LoadArenasFromFile(filename);
+ }
- uiInfo.mapList[uiInfo.mapCount].cinematic = -1;
- uiInfo.mapList[uiInfo.mapCount].mapLoadName = String_Alloc(Info_ValueForKey(ui_arenaInfos[n], "map"));
- uiInfo.mapList[uiInfo.mapCount].mapName = String_Alloc(Info_ValueForKey(ui_arenaInfos[n], "longname"));
- uiInfo.mapList[uiInfo.mapCount].levelShot = -1;
- uiInfo.mapList[uiInfo.mapCount].imageName = String_Alloc(va("levelshots/%s", uiInfo.mapList[uiInfo.mapCount].mapLoadName));
+ trap_Print(va("[skipnotify]%i arenas parsed\n", ui_numArenas));
- uiInfo.mapCount++;
- if( uiInfo.mapCount >= MAX_MAPS )
- break;
- }
+ if (UI_OutOfMemory())
+ trap_Print(S_COLOR_YELLOW "WARNING: not anough memory in pool to load all arenas\n");
- qsort( uiInfo.mapList, uiInfo.mapCount, sizeof( mapInfo ), UI_MapNameCompare );
-}
+ for (n = 0; n < ui_numArenas; n++)
+ {
+ uiInfo.mapList[uiInfo.mapCount].cinematic = -1;
+ uiInfo.mapList[uiInfo.mapCount].mapLoadName = String_Alloc(Info_ValueForKey(ui_arenaInfos[n], "map"));
+ uiInfo.mapList[uiInfo.mapCount].mapName = String_Alloc(Info_ValueForKey(ui_arenaInfos[n], "longname"));
+ uiInfo.mapList[uiInfo.mapCount].levelShot = -1;
+ uiInfo.mapList[uiInfo.mapCount].imageName =
+ String_Alloc(va("levelshots/%s", uiInfo.mapList[uiInfo.mapCount].mapLoadName));
+
+ uiInfo.mapCount++;
+ if (uiInfo.mapCount >= MAX_MAPS)
+ break;
+ }
+
+ qsort(uiInfo.mapList, uiInfo.mapCount, sizeof(mapInfo), UI_MapNameCompare);
+}
/*
===============
UI_LoadBotsFromFile
===============
*/
-static void UI_LoadBotsFromFile( char *filename ) {
- int len;
- fileHandle_t f;
- char buf[MAX_BOTS_TEXT];
-
- len = trap_FS_FOpenFile( filename, &f, FS_READ );
- if ( !f ) {
- trap_Print( va( S_COLOR_RED "file not found: %s\n", filename ) );
- return;
- }
- if ( len >= MAX_BOTS_TEXT ) {
- trap_Print( va( S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, MAX_BOTS_TEXT ) );
- trap_FS_FCloseFile( f );
- return;
- }
-
- trap_FS_Read( buf, len, f );
- buf[len] = 0;
- trap_FS_FCloseFile( f );
-
- COM_Compress(buf);
-
- ui_numBots += UI_ParseInfos( buf, MAX_BOTS - ui_numBots, &ui_botInfos[ui_numBots] );
+static void UI_LoadBotsFromFile(char *filename)
+{
+ int len;
+ fileHandle_t f;
+ char buf[MAX_BOTS_TEXT];
+
+ len = trap_FS_FOpenFile(filename, &f, FS_READ);
+
+ if (!f)
+ {
+ trap_Print(va(S_COLOR_RED "file not found: %s\n", filename));
+ return;
+ }
+
+ if (len >= MAX_BOTS_TEXT)
+ {
+ trap_Print(va(S_COLOR_RED "file too large: %s is %i, max allowed is %i", filename, len, MAX_BOTS_TEXT));
+ trap_FS_FCloseFile(f);
+ return;
+ }
+
+ trap_FS_Read(buf, len, f);
+ buf[len] = 0;
+ trap_FS_FCloseFile(f);
+
+ COM_Compress(buf);
+
+ ui_numBots += UI_ParseInfos(buf, MAX_BOTS - ui_numBots, &ui_botInfos[ui_numBots]);
}
/*
@@ -228,106 +247,109 @@ static void UI_LoadBotsFromFile( char *filename ) {
UI_LoadBots
===============
*/
-void UI_LoadBots( void ) {
- vmCvar_t botsFile;
- int numdirs;
- char filename[128];
- char dirlist[1024];
- char* dirptr;
- int i;
- int dirlen;
-
- ui_numBots = 0;
-
- trap_Cvar_Register( &botsFile, "g_botsFile", "", CVAR_INIT|CVAR_ROM );
- if( *botsFile.string ) {
- UI_LoadBotsFromFile(botsFile.string);
- }
- else {
- UI_LoadBotsFromFile("scripts/bots.txt");
- }
-
- // get all bots from .bot files
- numdirs = trap_FS_GetFileList("scripts", ".bot", dirlist, 1024 );
- dirptr = dirlist;
- for (i = 0; i < numdirs; i++, dirptr += dirlen+1) {
- dirlen = strlen(dirptr);
- strcpy(filename, "scripts/");
- strcat(filename, dirptr);
- UI_LoadBotsFromFile(filename);
- }
- trap_Print( va( "%i bots parsed\n", ui_numBots ) );
-}
+void UI_LoadBots(void)
+{
+ vmCvar_t botsFile;
+ int numdirs;
+ char filename[128];
+ char dirlist[1024];
+ char *dirptr;
+ int i;
+ int dirlen;
+
+ ui_numBots = 0;
+ trap_Cvar_Register(&botsFile, "g_botsFile", "", CVAR_INIT | CVAR_ROM);
+
+ if (*botsFile.string)
+ UI_LoadBotsFromFile(botsFile.string);
+ else
+ UI_LoadBotsFromFile("scripts/bots.txt");
+
+ // get all bots from .bot files
+ numdirs = trap_FS_GetFileList("scripts", ".bot", dirlist, 1024);
+
+ dirptr = dirlist;
+
+ for (i = 0; i < numdirs; i++, dirptr += dirlen + 1)
+ {
+ dirlen = strlen(dirptr);
+ strcpy(filename, "scripts/");
+ strcat(filename, dirptr);
+ UI_LoadBotsFromFile(filename);
+ }
+
+ trap_Print(va("%i bots parsed\n", ui_numBots));
+}
/*
===============
UI_GetBotInfoByNumber
===============
*/
-char *UI_GetBotInfoByNumber( int num ) {
- if( num < 0 || num >= ui_numBots ) {
- trap_Print( va( S_COLOR_RED "Invalid bot number: %i\n", num ) );
- return NULL;
- }
- return ui_botInfos[num];
-}
+char *UI_GetBotInfoByNumber(int num)
+{
+ if (num < 0 || num >= ui_numBots)
+ {
+ trap_Print(va(S_COLOR_RED "Invalid bot number: %i\n", num));
+ return NULL;
+ }
+ return ui_botInfos[num];
+}
/*
===============
UI_GetBotInfoByName
===============
*/
-char *UI_GetBotInfoByName( const char *name ) {
- int n;
- char *value;
-
- for ( n = 0; n < ui_numBots ; n++ ) {
- value = Info_ValueForKey( ui_botInfos[n], "name" );
- if ( !Q_stricmp( value, name ) ) {
- return ui_botInfos[n];
+char *UI_GetBotInfoByName(const char *name)
+{
+ int n;
+ char *value;
+
+ for (n = 0; n < ui_numBots; n++)
+ {
+ value = Info_ValueForKey(ui_botInfos[n], "name");
+
+ if (!Q_stricmp(value, name))
+ return ui_botInfos[n];
}
- }
- return NULL;
+ return NULL;
}
-int UI_GetNumBots() {
- return ui_numBots;
-}
+int UI_GetNumBots(void) { return ui_numBots; }
+
+char *UI_GetBotNameByNumber(int num)
+{
+ char *info = UI_GetBotInfoByNumber(num);
+ if (info)
+ return Info_ValueForKey(info, "name");
-char *UI_GetBotNameByNumber( int num ) {
- char *info = UI_GetBotInfoByNumber(num);
- if (info) {
- return Info_ValueForKey( info, "name" );
- }
- return "Sarge";
+ return "";
}
-void UI_ServerInfo( void )
+void UI_ServerInfo(void)
{
- char info[ MAX_INFO_VALUE ];
-
- info[0] = '\0';
- if( trap_GetConfigString( CS_SERVERINFO, info, sizeof( info ) ) )
- {
- trap_Cvar_Set( "ui_serverinfo_mapname",
- Info_ValueForKey( info, "mapname" ) );
- trap_Cvar_Set( "ui_serverinfo_timelimit",
- Info_ValueForKey( info, "timelimit" ) );
- trap_Cvar_Set( "ui_serverinfo_sd",
- Info_ValueForKey( info, "g_suddenDeathTime" ) );
- trap_Cvar_Set( "ui_serverinfo_hostname",
- Info_ValueForKey( info, "sv_hostname" ) );
- trap_Cvar_Set( "ui_serverinfo_maxclients",
- Info_ValueForKey( info, "sv_maxclients" ) );
- trap_Cvar_Set( "ui_serverinfo_version",
- Info_ValueForKey( info, "version" ) );
- trap_Cvar_Set( "ui_serverinfo_unlagged",
- Info_ValueForKey( info, "g_unlagged" ) );
- trap_Cvar_Set( "ui_serverinfo_ff",
- Info_ValueForKey( info, "ff" ) );
- }
+ char info[MAX_INFO_VALUE];
+ char hostname[MAX_HOSTNAME_LENGTH];
+
+ info[0] = '\0';
+
+ if (trap_GetConfigString(CS_SERVERINFO, info, sizeof(info)))
+ {
+ trap_Cvar_Set("ui_serverinfo_mapname", Info_ValueForKey(info, "mapname"));
+ trap_Cvar_Set("ui_serverinfo_timelimit", Info_ValueForKey(info, "timelimit"));
+ trap_Cvar_Set("ui_serverinfo_sd", Info_ValueForKey(info, "g_suddenDeathTime"));
+ UI_EscapeEmoticons(hostname, Info_ValueForKey(info, "sv_hostname"), sizeof(hostname));
+ trap_Cvar_Set("ui_serverinfo_hostname", hostname);
+ trap_Cvar_Set("ui_serverinfo_maxclients", Info_ValueForKey(info, "sv_maxclients"));
+ trap_Cvar_Set("ui_serverinfo_version", Info_ValueForKey(info, "version"));
+ trap_Cvar_Set("ui_serverinfo_unlagged", Info_ValueForKey(info, "g_unlagged"));
+ trap_Cvar_Set("ui_serverinfo_friendlyFire", Info_ValueForKey(info, "g_friendlyFire"));
+ trap_Cvar_Set("ui_serverinfo_friendlyBuildableFire", Info_ValueForKey(info, "g_friendlyBuildableFire"));
+ trap_Cvar_Set("ui_serverinfo_allowdl", Info_ValueForKey(info, "sv_allowdownload"));
+ }
}
diff --git a/src/ui/ui_local.h b/src/ui/ui_local.h
index 0066593..936c414 100644
--- a/src/ui/ui_local.h
+++ b/src/ui/ui_local.h
@@ -1,13 +1,14 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
-Copyright (C) 2000-2006 Tim Angus
+Copyright (C) 2000-2013 Darklegion Development
+Copyright (C) 2015-2019 GrangerHub
This file is part of Tremulous.
Tremulous 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,
+published by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
Tremulous is distributed in the hope that it will be
@@ -16,1195 +17,381 @@ 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 Tremulous; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+along with Tremulous; if not, see <https://www.gnu.org/licenses/>
+
===========================================================================
*/
-#ifndef __UI_LOCAL_H__
-#define __UI_LOCAL_H__
+#ifndef UI_LOCAL_H
+#define UI_LOCAL_H
-#include "../qcommon/q_shared.h"
-#include "../renderer/tr_types.h"
+#include "client/keycodes.h"
+#include "game/bg_public.h"
+#include "qcommon/q_shared.h"
+#include "renderercommon/tr_types.h"
#include "ui_public.h"
-#include "../client/keycodes.h"
-#include "../game/bg_public.h"
#include "ui_shared.h"
-// global display context
-
-extern vmCvar_t ui_ffa_fraglimit;
-extern vmCvar_t ui_ffa_timelimit;
-
-extern vmCvar_t ui_tourney_fraglimit;
-extern vmCvar_t ui_tourney_timelimit;
-
-extern vmCvar_t ui_team_fraglimit;
-extern vmCvar_t ui_team_timelimit;
-extern vmCvar_t ui_team_friendly;
-
-extern vmCvar_t ui_ctf_capturelimit;
-extern vmCvar_t ui_ctf_timelimit;
-extern vmCvar_t ui_ctf_friendly;
-
-extern vmCvar_t ui_arenasFile;
-extern vmCvar_t ui_botsFile;
-extern vmCvar_t ui_spScores1;
-extern vmCvar_t ui_spScores2;
-extern vmCvar_t ui_spScores3;
-extern vmCvar_t ui_spScores4;
-extern vmCvar_t ui_spScores5;
-extern vmCvar_t ui_spAwards;
-extern vmCvar_t ui_spVideos;
-extern vmCvar_t ui_spSkill;
-
-extern vmCvar_t ui_spSelection;
-
-extern vmCvar_t ui_browserMaster;
-extern vmCvar_t ui_browserGameType;
-extern vmCvar_t ui_browserSortKey;
-extern vmCvar_t ui_browserShowFull;
-extern vmCvar_t ui_browserShowEmpty;
-
-extern vmCvar_t ui_brassTime;
-extern vmCvar_t ui_drawCrosshair;
-extern vmCvar_t ui_drawCrosshairNames;
-extern vmCvar_t ui_marks;
-
-extern vmCvar_t ui_server1;
-extern vmCvar_t ui_server2;
-extern vmCvar_t ui_server3;
-extern vmCvar_t ui_server4;
-extern vmCvar_t ui_server5;
-extern vmCvar_t ui_server6;
-extern vmCvar_t ui_server7;
-extern vmCvar_t ui_server8;
-extern vmCvar_t ui_server9;
-extern vmCvar_t ui_server10;
-extern vmCvar_t ui_server11;
-extern vmCvar_t ui_server12;
-extern vmCvar_t ui_server13;
-extern vmCvar_t ui_server14;
-extern vmCvar_t ui_server15;
-extern vmCvar_t ui_server16;
-
-extern vmCvar_t ui_captureLimit;
-extern vmCvar_t ui_fragLimit;
-extern vmCvar_t ui_gameType;
-extern vmCvar_t ui_netGameType;
-extern vmCvar_t ui_actualNetGameType;
-extern vmCvar_t ui_joinGameType;
-extern vmCvar_t ui_netSource;
-extern vmCvar_t ui_serverFilterType;
-extern vmCvar_t ui_dedicated;
-extern vmCvar_t ui_opponentName;
-extern vmCvar_t ui_menuFiles;
-extern vmCvar_t ui_currentTier;
-extern vmCvar_t ui_currentMap;
-extern vmCvar_t ui_currentNetMap;
-extern vmCvar_t ui_mapIndex;
-extern vmCvar_t ui_currentOpponent;
-extern vmCvar_t ui_selectedPlayer;
-extern vmCvar_t ui_selectedPlayerName;
-extern vmCvar_t ui_lastServerRefresh_0;
-extern vmCvar_t ui_lastServerRefresh_1;
-extern vmCvar_t ui_lastServerRefresh_2;
-extern vmCvar_t ui_lastServerRefresh_3;
-extern vmCvar_t ui_singlePlayerActive;
-extern vmCvar_t ui_scoreAccuracy;
-extern vmCvar_t ui_scoreImpressives;
-extern vmCvar_t ui_scoreExcellents;
-extern vmCvar_t ui_scoreDefends;
-extern vmCvar_t ui_scoreAssists;
-extern vmCvar_t ui_scoreGauntlets;
-extern vmCvar_t ui_scoreScore;
-extern vmCvar_t ui_scorePerfect;
-extern vmCvar_t ui_scoreTeam;
-extern vmCvar_t ui_scoreBase;
-extern vmCvar_t ui_scoreTimeBonus;
-extern vmCvar_t ui_scoreSkillBonus;
-extern vmCvar_t ui_scoreShutoutBonus;
-extern vmCvar_t ui_scoreTime;
-extern vmCvar_t ui_smallFont;
-extern vmCvar_t ui_bigFont;
-extern vmCvar_t ui_serverStatusTimeOut;
-
-//TA: bank values
-extern vmCvar_t ui_bank;
-
-extern vmCvar_t ui_chatCommands;
-
-//
-// ui_qmenu.c
-//
-
-#define RCOLUMN_OFFSET ( BIGCHAR_WIDTH )
-#define LCOLUMN_OFFSET (-BIGCHAR_WIDTH )
-
-#define SLIDER_RANGE 10
-#define MAX_EDIT_LINE 256
-
-#define MAX_MENUDEPTH 8
-#define MAX_MENUITEMS 128
-
-#define MTYPE_NULL 0
-#define MTYPE_SLIDER 1
-#define MTYPE_ACTION 2
-#define MTYPE_SPINCONTROL 3
-#define MTYPE_FIELD 4
-#define MTYPE_RADIOBUTTON 5
-#define MTYPE_BITMAP 6
-#define MTYPE_TEXT 7
-#define MTYPE_SCROLLLIST 8
-#define MTYPE_PTEXT 9
-#define MTYPE_BTEXT 10
-
-#define QMF_BLINK 0x00000001
-#define QMF_SMALLFONT 0x00000002
-#define QMF_LEFT_JUSTIFY 0x00000004
-#define QMF_CENTER_JUSTIFY 0x00000008
-#define QMF_RIGHT_JUSTIFY 0x00000010
-#define QMF_NUMBERSONLY 0x00000020 // edit field is only numbers
-#define QMF_HIGHLIGHT 0x00000040
-#define QMF_HIGHLIGHT_IF_FOCUS 0x00000080 // steady focus
-#define QMF_PULSEIFFOCUS 0x00000100 // pulse if focus
-#define QMF_HASMOUSEFOCUS 0x00000200
-#define QMF_NOONOFFTEXT 0x00000400
-#define QMF_MOUSEONLY 0x00000800 // only mouse input allowed
-#define QMF_HIDDEN 0x00001000 // skips drawing
-#define QMF_GRAYED 0x00002000 // grays and disables
-#define QMF_INACTIVE 0x00004000 // disables any input
-#define QMF_NODEFAULTINIT 0x00008000 // skip default initialization
-#define QMF_OWNERDRAW 0x00010000
-#define QMF_PULSE 0x00020000
-#define QMF_LOWERCASE 0x00040000 // edit field is all lower case
-#define QMF_UPPERCASE 0x00080000 // edit field is all upper case
-#define QMF_SILENT 0x00100000
-
-// callback notifications
-#define QM_GOTFOCUS 1
-#define QM_LOSTFOCUS 2
-#define QM_ACTIVATED 3
-
-typedef struct _tag_menuframework
-{
- int cursor;
- int cursor_prev;
-
- int nitems;
- void *items[MAX_MENUITEMS];
-
- void (*draw) (void);
- sfxHandle_t (*key) (int key);
-
- qboolean wrapAround;
- qboolean fullscreen;
- qboolean showlogo;
-} menuframework_s;
-
-typedef struct
-{
- int type;
- const char *name;
- int id;
- int x, y;
- int left;
- int top;
- int right;
- int bottom;
- menuframework_s *parent;
- int menuPosition;
- unsigned flags;
-
- void (*callback)( void *self, int event );
- void (*statusbar)( void *self );
- void (*ownerdraw)( void *self );
-} menucommon_s;
-
-typedef struct {
- int cursor;
- int scroll;
- int widthInChars;
- char buffer[MAX_EDIT_LINE];
- int maxchars;
-} mfield_t;
-
-typedef struct
-{
- menucommon_s generic;
- mfield_t field;
-} menufield_s;
-
-typedef struct
-{
- menucommon_s generic;
-
- float minvalue;
- float maxvalue;
- float curvalue;
-
- float range;
-} menuslider_s;
-
-typedef struct
-{
- menucommon_s generic;
-
- int oldvalue;
- int curvalue;
- int numitems;
- int top;
-
- const char **itemnames;
-
- int width;
- int height;
- int columns;
- int seperation;
-} menulist_s;
-
-typedef struct
-{
- menucommon_s generic;
-} menuaction_s;
-
-typedef struct
-{
- menucommon_s generic;
- int curvalue;
-} menuradiobutton_s;
-
-typedef struct
-{
- menucommon_s generic;
- char* focuspic;
- char* errorpic;
- qhandle_t shader;
- qhandle_t focusshader;
- int width;
- int height;
- float* focuscolor;
-} menubitmap_s;
-
-typedef struct
-{
- menucommon_s generic;
- char* string;
- int style;
- float* color;
-} menutext_s;
-
-extern void Menu_Cache( void );
-extern void Menu_Focus( menucommon_s *m );
-extern void Menu_AddItem( menuframework_s *menu, void *item );
-extern void Menu_AdjustCursor( menuframework_s *menu, int dir );
-extern void Menu_Draw( menuframework_s *menu );
-extern void *Menu_ItemAtCursor( menuframework_s *m );
-extern sfxHandle_t Menu_ActivateItem( menuframework_s *s, menucommon_s* item );
-extern void Menu_SetCursor( menuframework_s *s, int cursor );
-extern void Menu_SetCursorToItem( menuframework_s *m, void* ptr );
-extern sfxHandle_t Menu_DefaultKey( menuframework_s *s, int key );
-extern void Bitmap_Init( menubitmap_s *b );
-extern void Bitmap_Draw( menubitmap_s *b );
-extern void ScrollList_Draw( menulist_s *l );
-extern sfxHandle_t ScrollList_Key( menulist_s *l, int key );
-extern sfxHandle_t menu_in_sound;
-extern sfxHandle_t menu_move_sound;
-extern sfxHandle_t menu_out_sound;
-extern sfxHandle_t menu_buzz_sound;
-extern sfxHandle_t menu_null_sound;
-extern sfxHandle_t weaponChangeSound;
-extern vec4_t menu_text_color;
-extern vec4_t menu_grayed_color;
-extern vec4_t menu_dark_color;
-extern vec4_t menu_highlight_color;
-extern vec4_t menu_red_color;
-extern vec4_t menu_black_color;
-extern vec4_t menu_dim_color;
-extern vec4_t color_black;
-extern vec4_t color_white;
-extern vec4_t color_yellow;
-extern vec4_t color_blue;
-extern vec4_t color_orange;
-extern vec4_t color_red;
-extern vec4_t color_dim;
-extern vec4_t name_color;
-extern vec4_t list_color;
-extern vec4_t listbar_color;
-extern vec4_t text_color_disabled;
-extern vec4_t text_color_normal;
-extern vec4_t text_color_highlight;
-
-extern char *ui_medalNames[];
-extern char *ui_medalPicNames[];
-extern char *ui_medalSounds[];
-
-//
-// ui_mfield.c
-//
-extern void MField_Clear( mfield_t *edit );
-extern void MField_KeyDownEvent( mfield_t *edit, int key );
-extern void MField_CharEvent( mfield_t *edit, int ch );
-extern void MField_Draw( mfield_t *edit, int x, int y, int style, vec4_t color );
-extern void MenuField_Init( menufield_s* m );
-extern void MenuField_Draw( menufield_s *f );
-extern sfxHandle_t MenuField_Key( menufield_s* m, int* key );
-
//
// ui_main.c
//
-void UI_Report( void );
-void UI_Load( void );
+void UI_Report(void);
+void UI_Load(void);
void UI_LoadMenus(const char *menuFile, qboolean reset);
-void _UI_SetActiveMenu( uiMenuCommand_t menu );
int UI_AdjustTimeByGame(int time);
-void UI_ShowPostGame(qboolean newHigh);
-void UI_ClearScores( void );
+void UI_ClearScores(void);
void UI_LoadArenas(void);
void UI_ServerInfo(void);
+void UI_UpdateNews(qboolean);
+void UI_UpdateGithubRelease(void);
-//
-// ui_menu.c
-//
-extern void MainMenu_Cache( void );
-extern void UI_MainMenu(void);
-extern void UI_RegisterCvars( void );
-extern void UI_UpdateCvars( void );
-
-//
-// ui_credits.c
-//
-extern void UI_CreditMenu( void );
-
-//
-// ui_ingame.c
-//
-extern void InGame_Cache( void );
-extern void UI_InGameMenu(void);
-
-//
-// ui_confirm.c
-//
-extern void ConfirmMenu_Cache( void );
-extern void UI_ConfirmMenu( const char *question, void (*draw)( void ), void (*action)( qboolean result ) );
-
-//
-// ui_setup.c
-//
-extern void UI_SetupMenu_Cache( void );
-extern void UI_SetupMenu(void);
-
-//
-// ui_team.c
-//
-extern void UI_TeamMainMenu( void );
-extern void TeamMain_Cache( void );
-
-//
-// ui_connect.c
-//
-extern void UI_DrawConnectScreen( qboolean overlay );
-
-//
-// ui_controls2.c
-//
-extern void UI_ControlsMenu( void );
-extern void Controls_Cache( void );
-
-//
-// ui_demo2.c
-//
-extern void UI_DemosMenu( void );
-extern void Demos_Cache( void );
-
-//
-// ui_cinematics.c
-//
-extern void UI_CinematicsMenu( void );
-extern void UI_CinematicsMenu_f( void );
-extern void UI_CinematicsMenu_Cache( void );
-
-//
-// ui_mods.c
-//
-extern void UI_ModsMenu( void );
-extern void UI_ModsMenu_Cache( void );
-
-//
-// ui_playermodel.c
-//
-extern void UI_PlayerModelMenu( void );
-extern void PlayerModel_Cache( void );
-
-//
-// ui_playersettings.c
-//
-extern void UI_PlayerSettingsMenu( void );
-extern void PlayerSettings_Cache( void );
-
-//
-// ui_preferences.c
-//
-extern void UI_PreferencesMenu( void );
-extern void Preferences_Cache( void );
-
-//
-// ui_specifyleague.c
-//
-extern void UI_SpecifyLeagueMenu( void );
-extern void SpecifyLeague_Cache( void );
-
-//
-// ui_specifyserver.c
-//
-extern void UI_SpecifyServerMenu( void );
-extern void SpecifyServer_Cache( void );
-
-//
-// ui_servers2.c
-//
-#define MAX_FAVORITESERVERS 16
-
-extern void UI_ArenaServersMenu( void );
-extern void ArenaServers_Cache( void );
-
-//
-// ui_startserver.c
-//
-extern void UI_StartServerMenu( qboolean multiplayer );
-extern void StartServer_Cache( void );
-extern void ServerOptions_Cache( void );
-extern void UI_BotSelectMenu( char *bot );
-extern void UI_BotSelectMenu_Cache( void );
-
-//
-// ui_serverinfo.c
-//
-extern void UI_ServerInfoMenu( void );
-extern void ServerInfo_Cache( void );
-
-//
-// ui_video.c
-//
-extern void UI_GraphicsOptionsMenu( void );
-extern void GraphicsOptions_Cache( void );
-extern void DriverInfo_Cache( void );
-
-//
-// ui_players.c
-//
-
-//FIXME ripped from cg_local.h
-typedef struct {
- int oldFrame;
- int oldFrameTime; // time when ->oldFrame was exactly on
-
- int frame;
- int frameTime; // time when ->frame will be exactly on
-
- float backlerp;
-
- float yawAngle;
- qboolean yawing;
- float pitchAngle;
- qboolean pitching;
-
- int animationNumber; // may include ANIM_TOGGLEBIT
- animation_t *animation;
- int animationTime; // time when the first frame of the animation will be exact
-} lerpFrame_t;
-
-typedef struct {
- // model info
- qhandle_t legsModel;
- qhandle_t legsSkin;
- lerpFrame_t legs;
-
- qhandle_t torsoModel;
- qhandle_t torsoSkin;
- lerpFrame_t torso;
-
- qhandle_t headModel;
- qhandle_t headSkin;
-
- animation_t animations[MAX_PLAYER_TOTALANIMATIONS];
-
- qhandle_t weaponModel;
- qhandle_t barrelModel;
- qhandle_t flashModel;
- vec3_t flashDlightColor;
- int muzzleFlashTime;
-
- // currently in use drawing parms
- vec3_t viewAngles;
- vec3_t moveAngles;
- weapon_t currentWeapon;
- int legsAnim;
- int torsoAnim;
-
- // animation vars
- weapon_t weapon;
- weapon_t lastWeapon;
- weapon_t pendingWeapon;
- int weaponTimer;
- int pendingLegsAnim;
- int torsoAnimationTimer;
-
- int pendingTorsoAnim;
- int legsAnimationTimer;
-
- qboolean chat;
- qboolean newModel;
-
- qboolean barrelSpinning;
- float barrelAngle;
- int barrelTime;
-
- int realWeapon;
-} playerInfo_t;
-
-void UI_DrawPlayer( float x, float y, float w, float h, playerInfo_t *pi, int time );
-void UI_PlayerInfo_SetModel( playerInfo_t *pi, const char *model, const char *headmodel, char *teamName );
-void UI_PlayerInfo_SetInfo( playerInfo_t *pi, int legsAnim, int torsoAnim, vec3_t viewAngles, vec3_t moveAngles, weapon_t weaponNum, qboolean chat );
-qboolean UI_RegisterClientModelname( playerInfo_t *pi, const char *modelSkinName , const char *headName, const char *teamName);
-
-//
-// ui_atoms.c
-//
-// this is only used in the old ui, the new ui has it's own version
-typedef struct {
- int frametime;
- int realtime;
- int cursorx;
- int cursory;
- glconfig_t glconfig;
- qboolean debug;
- qhandle_t whiteShader;
- qhandle_t charset;
- qhandle_t charsetProp;
- qhandle_t charsetPropGlow;
- qhandle_t charsetPropB;
- qhandle_t cursor;
- qhandle_t rb_on;
- qhandle_t rb_off;
- float scale;
- float bias;
- qboolean demoversion;
- qboolean firstdraw;
-} uiStatic_t;
-
+void UI_RegisterCvars(void);
+void UI_UpdateCvars(void);
+void UI_DrawConnectScreen(void);
// new ui stuff
-#define UI_NUMFX 7
-#define MAX_HEADS 64
-#define MAX_ALIASES 64
-#define MAX_HEADNAME 32
-#define MAX_TEAMS 64
-#define MAX_GAMETYPES 16
#define MAX_MAPS 128
-#define MAX_SPMAPS 16
-#define PLAYERS_PER_TEAM 5
-#define MAX_PINGREQUESTS 32
-#define MAX_ADDRESSLENGTH 64
-#define MAX_HOSTNAMELENGTH 22
-#define MAX_MAPNAMELENGTH 16
-#define MAX_STATUSLENGTH 64
-#define MAX_LISTBOXWIDTH 59
-#define UI_FONT_THRESHOLD 0.1
-#define MAX_DISPLAY_SERVERS 2048
-#define MAX_SERVERSTATUS_LINES 128
-#define MAX_SERVERSTATUS_TEXT 1024
-#define MAX_FOUNDPLAYER_SERVERS 16
-#define TEAM_MEMBERS 5
-#define GAMES_ALL 0
-#define GAMES_FFA 1
-#define GAMES_TEAMPLAY 2
-#define GAMES_TOURNEY 3
-#define GAMES_CTF 4
-#define MAPS_PER_TIER 3
-#define MAX_TIERS 16
+#define MAX_PINGREQUESTS 32
+#define MAX_ADDRESSLENGTH 64
+#define MAX_DISPLAY_SERVERS 2048
+#define MAX_SERVERSTATUS_LINES 128
+#define MAX_SERVERSTATUS_TEXT 1024
+#define MAX_NEWS_LINES 50
+#define MAX_NEWS_LINEWIDTH 85
+#define MAX_FOUNDPLAYER_SERVERS 16
#define MAX_MODS 64
#define MAX_DEMOS 256
#define MAX_MOVIES 256
-#define MAX_PLAYERMODELS 256
-
-
-typedef struct {
- const char *name;
- const char *imageName;
- qhandle_t headImage;
- const char *base;
- qboolean active;
- int reference;
-} characterInfo;
-
-typedef struct {
- const char *name;
- const char *ai;
- const char *action;
-} aliasInfo;
-
-typedef struct {
- const char *teamName;
- const char *imageName;
- const char *teamMembers[TEAM_MEMBERS];
- qhandle_t teamIcon;
- qhandle_t teamIcon_Metal;
- qhandle_t teamIcon_Name;
- int cinematic;
-} teamInfo;
-
-typedef struct {
- const char *gameType;
- int gtEnum;
-} gameTypeInfo;
+#define MAX_HELP_INFOPANES 32
+#define MAX_RESOLUTIONS 32
typedef struct {
- const char *mapName;
- const char *mapLoadName;
- const char *imageName;
- const char *opponentName;
- int teamMembers;
- int typeBits;
- int cinematic;
- int timeToBeat[MAX_GAMETYPES];
- qhandle_t levelShot;
- qboolean active;
+ const char *mapName;
+ const char *mapLoadName;
+ const char *imageName;
+ int cinematic;
+ qhandle_t levelShot;
} mapInfo;
-typedef struct {
- const char *tierName;
- const char *maps[MAPS_PER_TIER];
- int gameTypes[MAPS_PER_TIER];
- qhandle_t mapHandles[MAPS_PER_TIER];
-} tierInfo;
-
typedef struct serverFilter_s {
- const char *description;
- const char *basedir;
+ const char *description;
+ const char *basedir;
} serverFilter_t;
typedef struct {
- char adrstr[MAX_ADDRESSLENGTH];
- int start;
+ char adrstr[MAX_ADDRESSLENGTH];
+ int start;
} pinglist_t;
-
typedef struct serverStatus_s {
- pinglist_t pingList[MAX_PINGREQUESTS];
- int numqueriedservers;
- int currentping;
- int nextpingtime;
- int maxservers;
- int refreshtime;
- int numServers;
- int sortKey;
- int sortDir;
- qboolean sorted;
- int lastCount;
- qboolean refreshActive;
- int currentServer;
- int displayServers[MAX_DISPLAY_SERVERS];
- int numDisplayServers;
- int numPlayersOnServers;
- int nextDisplayRefresh;
- int nextSortTime;
- qhandle_t currentServerPreview;
- int currentServerCinematic;
- int motdLen;
- int motdWidth;
- int motdPaintX;
- int motdPaintX2;
- int motdOffset;
- int motdTime;
- char motd[MAX_STRING_CHARS];
+ pinglist_t pingList[MAX_PINGREQUESTS];
+ int numqueriedservers;
+ int currentping;
+ int nextpingtime;
+ int maxservers;
+ int refreshtime;
+ int numServers;
+ int sortKey;
+ int sortDir;
+ qboolean sorted;
+ int lastCount;
+ qboolean refreshActive;
+ int currentServer;
+ int displayServers[MAX_DISPLAY_SERVERS];
+ int numDisplayServers;
+ int numDuplicateMultiprotocolServers;
+ int numDuplicateMultiprotocolServerClients;
+ int numPlayersOnServers;
+ int nextDisplayRefresh;
+ int nextSortTime;
+ qhandle_t currentServerPreview;
+ int currentServerCinematic;
+ int motdLen;
+ int motdWidth;
+ int motdPaintX;
+ int motdPaintX2;
+ int motdOffset;
+ int motdTime;
+ char motd[MAX_STRING_CHARS];
} serverStatus_t;
-
typedef struct {
- char adrstr[MAX_ADDRESSLENGTH];
- char name[MAX_ADDRESSLENGTH];
- int startTime;
- int serverNum;
- qboolean valid;
+ char adrstr[MAX_ADDRESSLENGTH];
+ char name[MAX_ADDRESSLENGTH];
+ int startTime;
+ int serverNum;
+ qboolean valid;
} pendingServer_t;
typedef struct {
- int num;
- pendingServer_t server[MAX_SERVERSTATUSREQUESTS];
+ int num;
+ pendingServer_t server[MAX_SERVERSTATUSREQUESTS];
} pendingServerStatus_t;
typedef struct {
- char address[MAX_ADDRESSLENGTH];
- char *lines[MAX_SERVERSTATUS_LINES][4];
- char text[MAX_SERVERSTATUS_TEXT];
- char pings[MAX_CLIENTS * 3];
- int numLines;
+ char address[MAX_ADDRESSLENGTH];
+ char *lines[MAX_SERVERSTATUS_LINES][4];
+ char text[MAX_SERVERSTATUS_TEXT];
+ char pings[MAX_CLIENTS * 3];
+ int numLines;
} serverStatusInfo_t;
typedef struct {
- const char *modName;
- const char *modDescr;
-} modInfo_t;
-
-//TA: tremulous menus
-#define MAX_INFOPANE_TEXT 4096
-#define MAX_INFOPANE_GRAPHICS 16
-#define MAX_INFOPANES 128
-
-typedef enum
-{
- INFOPANE_TOP,
- INFOPANE_BOTTOM,
- INFOPANE_LEFT,
- INFOPANE_RIGHT
-} tremIPSide_t;
-
-typedef struct
-{
- qhandle_t graphic;
-
- tremIPSide_t side;
- int offset;
-
- int width, height;
-} tremIPGraphic_t;
-
-typedef struct
-{
- const char *name;
- char text[ MAX_INFOPANE_TEXT ];
- int align;
-
- tremIPGraphic_t graphics[ MAX_INFOPANE_GRAPHICS ];
- int numGraphics;
-} tremInfoPane_t;
-
-typedef struct
-{
- const char *text;
- const char *cmd;
- tremInfoPane_t *infopane;
-} tremMenuItem_t;
-//TA: tremulous menus
+ char text[MAX_NEWS_LINES][MAX_NEWS_LINEWIDTH];
+ int numLines;
+ qboolean refreshActive;
+ int refreshtime;
+} newsInfo_t;
typedef struct {
- displayContextDef_t uiDC;
- int newHighScoreTime;
- int newBestTime;
- int showPostGameTime;
- qboolean newHighScore;
- qboolean demoAvailable;
- qboolean soundHighScore;
+ char text[MAX_NEWS_LINES][MAX_NEWS_LINEWIDTH];
+ int numLines;
+ qboolean refreshActive;
+ int nextTime;
+} githubRelease_t;
- int characterCount;
- int botIndex;
- characterInfo characterList[MAX_HEADS];
-
- int aliasCount;
- aliasInfo aliasList[MAX_ALIASES];
-
- int teamCount;
- teamInfo teamList[MAX_TEAMS];
-
- int numGameTypes;
- gameTypeInfo gameTypes[MAX_GAMETYPES];
-
- int numJoinGameTypes;
- gameTypeInfo joinGameTypes[MAX_GAMETYPES];
-
- int redBlue;
- int playerCount;
- int myTeamCount;
- int teamIndex;
- int playerRefresh;
- int playerIndex;
- int playerNumber;
- int myPlayerIndex;
- int ignoreIndex;
- qboolean teamLeader;
- char playerNames[MAX_CLIENTS][MAX_NAME_LENGTH];
- char rawPlayerNames[MAX_CLIENTS][MAX_NAME_LENGTH];
- char teamNames[MAX_CLIENTS][MAX_NAME_LENGTH];
- char rawTeamNames[MAX_CLIENTS][MAX_NAME_LENGTH];
- int clientNums[MAX_CLIENTS];
- int teamClientNums[MAX_CLIENTS];
- clientList_t ignoreList[MAX_CLIENTS];
-
- int mapCount;
- mapInfo mapList[MAX_MAPS];
-
-
- int tierCount;
- tierInfo tierList[MAX_TIERS];
-
- int skillIndex;
-
- modInfo_t modList[MAX_MODS];
- int modCount;
- int modIndex;
-
- const char *demoList[MAX_DEMOS];
- int demoCount;
- int demoIndex;
-
- const char *movieList[MAX_MOVIES];
- int movieCount;
- int movieIndex;
- int previewMovie;
-
- tremInfoPane_t tremInfoPanes[ MAX_INFOPANES ];
- int tremInfoPaneCount;
-
-//TA: tremulous menus
- tremMenuItem_t tremTeamList[ 4 ];
- int tremTeamCount;
- int tremTeamIndex;
-
- tremMenuItem_t tremAlienClassList[ 3 ];
- int tremAlienClassCount;
- int tremAlienClassIndex;
-
- tremMenuItem_t tremHumanItemList[ 3 ];
- int tremHumanItemCount;
- int tremHumanItemIndex;
-
- tremMenuItem_t tremHumanArmouryBuyList[ 32 ];
- int tremHumanArmouryBuyCount;
- int tremHumanArmouryBuyIndex;
-
- tremMenuItem_t tremHumanArmourySellList[ 32 ];
- int tremHumanArmourySellCount;
- int tremHumanArmourySellIndex;
-
- tremMenuItem_t tremAlienUpgradeList[ 16 ];
- int tremAlienUpgradeCount;
- int tremAlienUpgradeIndex;
-
- tremMenuItem_t tremAlienBuildList[ 32 ];
- int tremAlienBuildCount;
- int tremAlienBuildIndex;
-
- tremMenuItem_t tremHumanBuildList[ 32 ];
- int tremHumanBuildCount;
- int tremHumanBuildIndex;
-//TA: tremulous menus
-
- serverStatus_t serverStatus;
-
- // for the showing the status of a server
- char serverStatusAddress[MAX_ADDRESSLENGTH];
- serverStatusInfo_t serverStatusInfo;
- int nextServerStatusRefresh;
-
- // to retrieve the status of server to find a player
- pendingServerStatus_t pendingServerStatus;
- char findPlayerName[MAX_STRING_CHARS];
- char foundPlayerServerAddresses[MAX_FOUNDPLAYER_SERVERS][MAX_ADDRESSLENGTH];
- char foundPlayerServerNames[MAX_FOUNDPLAYER_SERVERS][MAX_ADDRESSLENGTH];
- int currentFoundPlayerServer;
- int numFoundPlayerServers;
- int nextFindPlayerRefresh;
-
- int currentCrosshair;
- int startPostGameTime;
- sfxHandle_t newHighScoreSound;
+typedef struct {
+ const char *modName;
+ const char *modDescr;
+} modInfo_t;
- int q3HeadCount;
- char q3HeadNames[MAX_PLAYERMODELS][64];
- qhandle_t q3HeadIcons[MAX_PLAYERMODELS];
- int q3SelectedHead;
+typedef enum {
+ INFOTYPE_TEXT,
+ INFOTYPE_BUILDABLE,
+ INFOTYPE_CLASS,
+ INFOTYPE_WEAPON,
+ INFOTYPE_UPGRADE,
+ INFOTYPE_VOICECMD
+} infoType_t;
- int effectsColor;
+typedef struct {
+ const char *text;
+ const char *cmd;
+ infoType_t type;
+ union {
+ const char *text;
+ buildable_t buildable;
+ class_t pclass;
+ weapon_t weapon;
+ upgrade_t upgrade;
+ } v;
+} menuItem_t;
- qboolean inGameLoad;
+typedef struct {
+ int w;
+ int h;
+} resolution_t;
- qboolean chatTeam;
-} uiInfo_t;
+typedef struct {
+ displayContextDef_t uiDC;
+
+ int playerCount;
+ int myTeamCount;
+ int teamPlayerIndex;
+ int playerRefresh;
+ int playerIndex;
+ int playerNumber;
+ int myPlayerIndex;
+ int ignoreIndex;
+ char playerNames[MAX_CLIENTS][MAX_NAME_LENGTH];
+ char rawPlayerNames[MAX_CLIENTS][MAX_NAME_LENGTH];
+ char teamNames[MAX_CLIENTS][MAX_NAME_LENGTH];
+ char rawTeamNames[MAX_CLIENTS][MAX_NAME_LENGTH];
+ int clientNums[MAX_CLIENTS];
+ int teamClientNums[MAX_CLIENTS];
+ clientList_t ignoreList[MAX_CLIENTS];
+
+ int mapCount;
+ mapInfo mapList[MAX_MAPS];
+
+ modInfo_t modList[MAX_MODS];
+ int modCount;
+ int modIndex;
+
+ const char *demoList[MAX_DEMOS];
+ int demoCount;
+ int demoIndex;
+
+ const char *movieList[MAX_MOVIES];
+ int movieCount;
+ int movieIndex;
+ int previewMovie;
+
+ menuItem_t teamList[4];
+ int teamCount;
+ int teamIndex;
+
+ menuItem_t alienClassList[3];
+ int alienClassCount;
+ int alienClassIndex;
+
+ menuItem_t humanItemList[3];
+ int humanItemCount;
+ int humanItemIndex;
+
+ menuItem_t humanArmouryBuyList[32];
+ int humanArmouryBuyCount;
+ int humanArmouryBuyIndex;
+
+ menuItem_t humanArmourySellList[32];
+ int humanArmourySellCount;
+ int humanArmourySellIndex;
+
+ menuItem_t alienUpgradeList[16];
+ int alienUpgradeCount;
+ int alienUpgradeIndex;
+
+ menuItem_t alienBuildList[32];
+ int alienBuildCount;
+ int alienBuildIndex;
+
+ menuItem_t humanBuildList[32];
+ int humanBuildCount;
+ int humanBuildIndex;
+
+ menuItem_t voiceCmdList[32];
+ int voiceCmdCount;
+ int voiceCmdIndex;
+
+ menuItem_t helpList[MAX_HELP_INFOPANES];
+ int helpCount;
+ int helpIndex;
+
+ int weapons;
+ int upgrades;
+
+ serverStatus_t serverStatus;
+
+ // for showing the game news window
+ newsInfo_t newsInfo;
+
+ githubRelease_t githubRelease;
+
+ // for the showing the status of a server
+ char serverStatusAddress[MAX_ADDRESSLENGTH];
+ serverStatusInfo_t serverStatusInfo;
+ int nextServerStatusRefresh;
+
+ // to retrieve the status of server to find a player
+ pendingServerStatus_t pendingServerStatus;
+ char findPlayerName[MAX_STRING_CHARS];
+ char foundPlayerServerAddresses[MAX_FOUNDPLAYER_SERVERS][MAX_ADDRESSLENGTH];
+ char foundPlayerServerNames[MAX_FOUNDPLAYER_SERVERS][MAX_ADDRESSLENGTH];
+ int currentFoundPlayerServer;
+ int numFoundPlayerServers;
+ int nextFindPlayerRefresh;
+
+ resolution_t resolutions[MAX_RESOLUTIONS];
+ int numResolutions;
+ int resolutionIndex;
+
+ voice_t *voices;
+
+ qboolean inGameLoad;
+
+ qboolean chatTeam;
+ qboolean voiceCmd;
+} uiInfo_t;
extern uiInfo_t uiInfo;
-
-extern void UI_Init( void );
-extern void UI_Shutdown( void );
-extern void UI_KeyEvent( int key );
-extern void UI_MouseEvent( int dx, int dy );
-extern void UI_Refresh( int realtime );
-extern qboolean UI_ConsoleCommand( int realTime );
-extern float UI_ClampCvar( float min, float max, float value );
-extern void UI_DrawNamedPic( float x, float y, float width, float height, const char *picname );
-extern void UI_DrawHandlePic( float x, float y, float w, float h, qhandle_t hShader );
-extern void UI_FillRect( float x, float y, float width, float height, const float *color );
-extern void UI_DrawRect( float x, float y, float width, float height, const float *color );
-extern void UI_DrawTopBottom(float x, float y, float w, float h);
-extern void UI_DrawSides(float x, float y, float w, float h);
-extern void UI_UpdateScreen( void );
-extern void UI_SetColor( const float *rgba );
-extern void UI_LerpColor(vec4_t a, vec4_t b, vec4_t c, float t);
-extern void UI_DrawBannerString( int x, int y, const char* str, int style, vec4_t color );
-extern float UI_ProportionalSizeScale( int style );
-extern void UI_DrawProportionalString( int x, int y, const char* str, int style, vec4_t color );
-extern int UI_ProportionalStringWidth( const char* str );
-extern void UI_DrawString( int x, int y, const char* str, int style, vec4_t color );
-extern void UI_DrawChar( int x, int y, int ch, int style, vec4_t color );
-extern qboolean UI_CursorInRect (int x, int y, int width, int height);
-extern void UI_AdjustFrom640( float *x, float *y, float *w, float *h );
-extern void UI_DrawTextBox (int x, int y, int width, int lines);
-extern qboolean UI_IsFullscreen( void );
-extern void UI_SetActiveMenu( uiMenuCommand_t menu );
-extern void UI_PushMenu ( menuframework_s *menu );
-extern void UI_PopMenu (void);
-extern void UI_ForceMenuOff (void);
-extern char *UI_Argv( int arg );
-extern char *UI_Cvar_VariableString( const char *var_name );
-extern void UI_Refresh( int time );
-extern void UI_KeyEvent( int key );
-extern void UI_StartDemoLoop( void );
-extern qboolean m_entersound;
-void UI_LoadBestScores(const char *map, int game);
-extern uiStatic_t uis;
-
-//
-// ui_spLevel.c
-//
-void UI_SPLevelMenu_Cache( void );
-void UI_SPLevelMenu( void );
-void UI_SPLevelMenu_f( void );
-void UI_SPLevelMenu_ReInit( void );
-
-//
-// ui_spArena.c
-//
-void UI_SPArena_Start( const char *arenaInfo );
-
-//
-// ui_spPostgame.c
-//
-void UI_SPPostgameMenu_Cache( void );
-void UI_SPPostgameMenu_f( void );
-
-//
-// ui_spSkill.c
-//
-void UI_SPSkillMenu( const char *arenaInfo );
-void UI_SPSkillMenu_Cache( void );
+qboolean UI_ConsoleCommand(int realTime);
+char *UI_Cvar_VariableString(const char *var_name);
+void UI_SetColor(const float *rgba);
+void UI_AdjustFrom640(float *x, float *y, float *w, float *h);
+void UI_Refresh(int time);
+void UI_DrawHandlePic(float x, float y, float w, float h, qhandle_t hShader);
+void UI_FillRect(float x, float y, float width, float height, const float *color);
//
// ui_syscalls.c
//
-void trap_Print( const char *string );
-void trap_Error( const char *string );
-int trap_Milliseconds( void );
-void trap_Cvar_Register( vmCvar_t *vmCvar, const char *varName, const char *defaultValue, int flags );
-void trap_Cvar_Update( vmCvar_t *vmCvar );
-void trap_Cvar_Set( const char *var_name, const char *value );
-float trap_Cvar_VariableValue( const char *var_name );
-void trap_Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize );
-void trap_Cvar_SetValue( const char *var_name, float value );
-void trap_Cvar_Reset( const char *name );
-void trap_Cvar_Create( const char *var_name, const char *var_value, int flags );
-void trap_Cvar_InfoStringBuffer( int bit, char *buffer, int bufsize );
-int trap_Argc( void );
-void trap_Argv( int n, char *buffer, int bufferLength );
-void trap_Cmd_ExecuteText( int exec_when, const char *text ); // don't use EXEC_NOW!
-int trap_FS_FOpenFile( const char *qpath, fileHandle_t *f, fsMode_t mode );
-void trap_FS_Read( void *buffer, int len, fileHandle_t f );
-void trap_FS_Write( const void *buffer, int len, fileHandle_t f );
-void trap_FS_FCloseFile( fileHandle_t f );
-int trap_FS_GetFileList( const char *path, const char *extension, char *listbuf, int bufsize );
-int trap_FS_Seek( fileHandle_t f, long offset, int origin ); // fsOrigin_t
-qhandle_t trap_R_RegisterModel( const char *name );
-qhandle_t trap_R_RegisterSkin( const char *name );
-qhandle_t trap_R_RegisterShaderNoMip( const char *name );
-void trap_R_ClearScene( void );
-void trap_R_AddRefEntityToScene( const refEntity_t *re );
-void trap_R_AddPolyToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts );
-void trap_R_AddLightToScene( const vec3_t org, float intensity, float r, float g, float b );
-void trap_R_RenderScene( const refdef_t *fd );
-void trap_R_SetColor( const float *rgba );
-void trap_R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t hShader );
-void trap_R_ModelBounds( clipHandle_t model, vec3_t mins, vec3_t maxs );
-void trap_UpdateScreen( void );
-int trap_CM_LerpTag( orientation_t *tag, clipHandle_t mod, int startFrame, int endFrame, float frac, const char *tagName );
-void trap_S_StartLocalSound( sfxHandle_t sfx, int channelNum );
-sfxHandle_t trap_S_RegisterSound( const char *sample, qboolean compressed );
-void trap_Key_KeynumToStringBuf( int keynum, char *buf, int buflen );
-void trap_Key_GetBindingBuf( int keynum, char *buf, int buflen );
-void trap_Key_SetBinding( int keynum, const char *binding );
-qboolean trap_Key_IsDown( int keynum );
-qboolean trap_Key_GetOverstrikeMode( void );
-void trap_Key_SetOverstrikeMode( qboolean state );
-void trap_Key_ClearStates( void );
-int trap_Key_GetCatcher( void );
-void trap_Key_SetCatcher( int catcher );
-void trap_GetClipboardData( char *buf, int bufsize );
-void trap_GetClientState( uiClientState_t *state );
-void trap_GetGlconfig( glconfig_t *glconfig );
-int trap_GetConfigString( int index, char* buff, int buffsize );
-int trap_LAN_GetServerCount( int source );
-void trap_LAN_GetServerAddressString( int source, int n, char *buf, int buflen );
-void trap_LAN_GetServerInfo( int source, int n, char *buf, int buflen );
-int trap_LAN_GetServerPing( int source, int n );
-int trap_LAN_GetPingQueueCount( void );
-void trap_LAN_ClearPing( int n );
-void trap_LAN_GetPing( int n, char *buf, int buflen, int *pingtime );
-void trap_LAN_GetPingInfo( int n, char *buf, int buflen );
-void trap_LAN_LoadCachedServers( void );
-void trap_LAN_SaveCachedServers( void );
-void trap_LAN_MarkServerVisible(int source, int n, qboolean visible);
-int trap_LAN_ServerIsVisible( int source, int n);
-qboolean trap_LAN_UpdateVisiblePings( int source );
-int trap_LAN_AddServer(int source, const char *name, const char *addr);
-void trap_LAN_RemoveServer(int source, const char *addr);
-void trap_LAN_ResetPings(int n);
-int trap_LAN_ServerStatus( const char *serverAddress, char *serverStatus, int maxLen );
-int trap_LAN_CompareServers( int source, int sortKey, int sortDir, int s1, int s2 );
-int trap_MemoryRemaining( void );
-void trap_R_RegisterFont(const char *pFontname, int pointSize, fontInfo_t *font);
-void trap_S_StopBackgroundTrack( void );
-void trap_S_StartBackgroundTrack( const char *intro, const char *loop);
-int trap_CIN_PlayCinematic( const char *arg0, int xpos, int ypos, int width, int height, int bits);
-e_status trap_CIN_StopCinematic(int handle);
-e_status trap_CIN_RunCinematic (int handle);
-void trap_CIN_DrawCinematic (int handle);
-void trap_CIN_SetExtents (int handle, int x, int y, int w, int h);
-int trap_RealTime(qtime_t *qtime);
-void trap_R_RemapShader( const char *oldShader, const char *newShader, const char *timeOffset );
-
-void trap_SetPbClStatus( int status );
-
-//
-// ui_addbots.c
-//
-void UI_AddBots_Cache( void );
-void UI_AddBotsMenu( void );
-
-//
-// ui_removebots.c
-//
-void UI_RemoveBots_Cache( void );
-void UI_RemoveBotsMenu( void );
-
-//
-// ui_teamorders.c
-//
-extern void UI_TeamOrdersMenu( void );
-extern void UI_TeamOrdersMenu_f( void );
-extern void UI_TeamOrdersMenu_Cache( void );
-
-//
-// ui_loadconfig.c
-//
-void UI_LoadConfig_Cache( void );
-void UI_LoadConfigMenu( void );
-
-//
-// ui_saveconfig.c
-//
-void UI_SaveConfigMenu_Cache( void );
-void UI_SaveConfigMenu( void );
-
-//
-// ui_display.c
-//
-void UI_DisplayOptionsMenu_Cache( void );
-void UI_DisplayOptionsMenu( void );
-
-//
-// ui_sound.c
-//
-void UI_SoundOptionsMenu_Cache( void );
-void UI_SoundOptionsMenu( void );
-
-//
-// ui_network.c
-//
-void UI_NetworkOptionsMenu_Cache( void );
-void UI_NetworkOptionsMenu( void );
-
-//
-// ui_gameinfo.c
-//
-typedef enum {
- AWARD_ACCURACY,
- AWARD_IMPRESSIVE,
- AWARD_EXCELLENT,
- AWARD_GAUNTLET,
- AWARD_FRAGS,
- AWARD_PERFECT
-} awardType_t;
-
-const char *UI_GetArenaInfoByNumber( int num );
-const char *UI_GetArenaInfoByMap( const char *map );
-const char *UI_GetSpecialArenaInfo( const char *tag );
-int UI_GetNumArenas( void );
-int UI_GetNumSPArenas( void );
-int UI_GetNumSPTiers( void );
-
-char *UI_GetBotInfoByNumber( int num );
-char *UI_GetBotInfoByName( const char *name );
-int UI_GetNumBots( void );
-void UI_LoadBots( void );
-char *UI_GetBotNameByNumber( int num );
-
-void UI_GetBestScore( int level, int *score, int *skill );
-void UI_SetBestScore( int level, int score );
-int UI_TierCompleted( int levelWon );
-qboolean UI_ShowTierVideo( int tier );
-qboolean UI_CanShowTierVideo( int tier );
-int UI_GetCurrentGame( void );
-void UI_NewGame( void );
-void UI_LogAwardData( int award, int data );
-int UI_GetAwardLevel( int award );
-
-void UI_SPUnlock_f( void );
-void UI_SPUnlockMedals_f( void );
-
-void UI_InitGameinfo( void );
-
-//
-// ui_login.c
-//
-void Login_Cache( void );
-void UI_LoginMenu( void );
-
-//
-// ui_signup.c
-//
-void Signup_Cache( void );
-void UI_SignupMenu( void );
-
-//
-// ui_rankstatus.c
-//
-void RankStatus_Cache( void );
-void UI_RankStatusMenu( void );
-
-
-// new ui
-
-#define ASSET_BACKGROUND "uiBackground"
-
-// for tracking sp game info in Team Arena
-typedef struct postGameInfo_s {
- int score;
- int redScore;
- int blueScore;
- int perfects;
- int accuracy;
- int impressives;
- int excellents;
- int defends;
- int assists;
- int gauntlets;
- int captures;
- int time;
- int timeBonus;
- int shutoutBonus;
- int skillBonus;
- int baseScore;
-} postGameInfo_t;
-
-
+void trap_Print(const char *string);
+void trap_Error(const char *string) __attribute__((noreturn));
+int trap_Milliseconds(void);
+void trap_Cvar_Register(vmCvar_t *vmCvar, const char *varName, const char *defaultValue, int flags);
+void trap_Cvar_Update(vmCvar_t *vmCvar);
+void trap_Cvar_Set(const char *var_name, const char *value);
+float trap_Cvar_VariableValue(const char *var_name);
+void trap_Cvar_VariableStringBuffer(const char *var_name, char *buffer, int bufsize);
+void trap_Cvar_SetValue(const char *var_name, float value);
+void trap_Cvar_Reset(const char *name);
+void trap_Cvar_Create(const char *var_name, const char *var_value, int flags);
+void trap_Cvar_InfoStringBuffer(int bit, char *buffer, int bufsize);
+int trap_Argc(void);
+void trap_Argv(int n, char *buffer, int bufferLength);
+void trap_Cmd_ExecuteText(int exec_when, const char *text); // don't use EXEC_NOW!
+int trap_FS_FOpenFile(const char *qpath, fileHandle_t *f, enum FS_Mode mode);
+void trap_FS_Read(void *buffer, int len, fileHandle_t f);
+void trap_FS_Write(const void *buffer, int len, fileHandle_t f);
+void trap_FS_FCloseFile(fileHandle_t f);
+int trap_FS_GetFileList(const char *path, const char *extension, char *listbuf, int bufsize);
+int trap_FS_Seek(fileHandle_t f, long offset, enum FS_Mode origin); // fsOrigin_t
+qhandle_t trap_R_RegisterModel(const char *name);
+qhandle_t trap_R_RegisterSkin(const char *name);
+qhandle_t trap_R_RegisterShaderNoMip(const char *name);
+void trap_R_ClearScene(void);
+void trap_R_AddRefEntityToScene(const refEntity_t *re);
+void trap_R_AddPolyToScene(qhandle_t hShader, int numVerts, const polyVert_t *verts);
+void trap_R_AddLightToScene(const vec3_t org, float intensity, float r, float g, float b);
+void trap_R_RenderScene(const refdef_t *fd);
+void trap_R_SetColor(const float *rgba);
+void trap_R_SetClipRegion(const float *region);
+void trap_R_DrawStretchPic(
+ float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t hShader);
+void trap_R_ModelBounds(clipHandle_t model, vec3_t mins, vec3_t maxs);
+void trap_UpdateScreen(void);
+int trap_CM_LerpTag(
+ orientation_t *tag, clipHandle_t mod, int startFrame, int endFrame, float frac, const char *tagName);
+void trap_S_StartLocalSound(sfxHandle_t sfx, int channelNum);
+sfxHandle_t trap_S_RegisterSound(const char *sample, qboolean compressed);
+void trap_Key_KeynumToStringBuf(int keynum, char *buf, int buflen);
+void trap_Key_GetBindingBuf(int keynum, char *buf, int buflen);
+void trap_Key_SetBinding(int keynum, const char *binding);
+qboolean trap_Key_IsDown(int keynum);
+qboolean trap_Key_GetOverstrikeMode(void);
+void trap_Key_SetOverstrikeMode(qboolean state);
+void trap_Key_ClearStates(void);
+int trap_Key_GetCatcher(void);
+void trap_Key_SetCatcher(int catcher);
+void trap_GetClipboardData(char *buf, int bufsize);
+void trap_GetClientState(uiClientState_t *state);
+void trap_GetGlconfig(glconfig_t *glconfig);
+int trap_GetConfigString(int index, char *buff, int buffsize);
+int trap_LAN_GetServerCount(int source);
+void trap_LAN_GetServerAddressString(int source, int n, char *buf, int buflen);
+void trap_LAN_GetServerInfo(int source, int n, char *buf, int buflen);
+int trap_LAN_GetServerPing(int source, int n);
+int trap_LAN_GetPingQueueCount(void);
+void trap_LAN_ClearPing(int n);
+void trap_LAN_GetPing(int n, char *buf, int buflen, int *pingtime);
+void trap_LAN_GetPingInfo(int n, char *buf, int buflen);
+void trap_LAN_LoadCachedServers(void);
+void trap_LAN_SaveCachedServers(void);
+void trap_LAN_MarkServerVisible(int source, int n, qboolean visible);
+int trap_LAN_ServerIsVisible(int source, int n);
+qboolean trap_LAN_UpdateVisiblePings(int source);
+int trap_LAN_AddServer(int source, const char *name, const char *addr);
+void trap_LAN_RemoveServer(int source, const char *addr);
+void trap_LAN_ResetPings(int n);
+int trap_LAN_ServerStatus(const char *serverAddress, char *serverStatus, int maxLen);
+qboolean trap_GetNews(qboolean force);
+int trap_LAN_CompareServers(int source, int sortKey, int sortDir, int s1, int s2);
+int trap_MemoryRemaining(void);
+void trap_R_RegisterFont(const char *pFontname, int pointSize, fontInfo_t *font);
+void trap_S_StopBackgroundTrack(void);
+void trap_S_StartBackgroundTrack(const char *intro, const char *loop);
+int trap_CIN_PlayCinematic(const char *arg0, int xpos, int ypos, int width, int height, int bits);
+e_status trap_CIN_StopCinematic(int handle);
+e_status trap_CIN_RunCinematic(int handle);
+void trap_CIN_DrawCinematic(int handle);
+void trap_CIN_SetExtents(int handle, int x, int y, int w, int h);
+int trap_RealTime(qtime_t *qtime);
+void trap_R_RemapShader(const char *oldShader, const char *newShader, const char *timeOffset);
+
+void trap_SetPbClStatus(int status);
+
+int trap_CheckForUpdate(int script);
+int trap_InstallUpdate(int script);
#endif
diff --git a/src/ui/ui_main.c b/src/ui/ui_main.c
index e2396a9..ec7c0aa 100644
--- a/src/ui/ui_main.c
+++ b/src/ui/ui_main.c
@@ -1,13 +1,14 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
-Copyright (C) 2000-2006 Tim Angus
+Copyright (C) 2000-2013 Darklegion Development
+Copyright (C) 2015-2019 GrangerHub
This file is part of Tremulous.
Tremulous 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,
+published by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
Tremulous is distributed in the hope that it will be
@@ -16,8 +17,8 @@ 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 Tremulous; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+along with Tremulous; if not, see <https://www.gnu.org/licenses/>
+
===========================================================================
*/
@@ -29,9 +30,6 @@ USER INTERFACE MAIN
=======================================================================
*/
-// use this to get a demo build without an explicit demo build, i.e. to get the demo ui files to build
-//#define PRE_RELEASE_TADEMO
-
#include "ui_local.h"
uiInfo_t uiInfo;
@@ -39,80 +37,84 @@ uiInfo_t uiInfo;
#ifdef MODULE_INTERFACE_11
#undef AS_GLOBAL
#undef AS_LOCAL
-#define AS_GLOBAL 2
-#define AS_LOCAL 0
+#define AS_GLOBAL 2
+#define AS_LOCAL 0
#endif
-static const char *MonthAbbrev[] = {
- "Jan","Feb","Mar",
- "Apr","May","Jun",
- "Jul","Aug","Sep",
- "Oct","Nov","Dec"
-};
-
-
-static const char *skillLevels[] = {
- "I Can Win",
- "Bring It On",
- "Hurt Me Plenty",
- "Hardcore",
- "Nightmare"
-};
-
-static const int numSkillLevels = sizeof(skillLevels) / sizeof(const char*);
-
-
static const char *netSources[] = {
#ifdef MODULE_INTERFACE_11
- "LAN",
- "Mplayer",
- "Internet",
+ "LAN", "Mplayer", "Internet",
#else
- "Internet",
- "Mplayer",
- "LAN",
+ "Internet", "Mplayer", "LAN",
#endif
- "Favorites"
-};
-static const int numNetSources = sizeof(netSources) / sizeof(const char*);
-
-static const serverFilter_t serverFilters[] = {
- {"All", "" },
- {"Quake 3 Arena", "" },
- {"Team Arena", "missionpack" },
- {"Rocket Arena", "arena" },
- {"Alliance", "alliance20" },
- {"Weapons Factory Arena", "wfa" },
- {"OSP", "osp" },
-};
-
-static const int numServerFilters = sizeof(serverFilters) / sizeof(serverFilter_t);
-
-static char* netnames[] = {
- "???",
- "UDP",
- "IPX",
- NULL
-};
-
-static int gamecodetoui[] = {4,2,3,0,5,1,6};
-
-
-static void UI_StartServerRefresh(qboolean full);
-static void UI_StopServerRefresh( void );
-static void UI_DoServerRefresh( void );
-static void UI_FeederSelection(float feederID, int index);
-static void UI_BuildServerDisplayList(int force);
-static void UI_BuildServerStatus(qboolean force);
-static void UI_BuildFindPlayerList(qboolean force);
-static int QDECL UI_ServersQsortCompare( const void *arg1, const void *arg2 );
-static int UI_MapCountByGameType(qboolean singlePlayer);
-static int UI_HeadCountByTeam( void );
-static const char *UI_SelectedMap(int index, int *actual);
-static const char *UI_SelectedHead(int index, int *actual);
-static int UI_GetIndexFromSelection(int actual);
-
-int ProcessNewUI( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6 );
+ "Favorites"};
+
+static const size_t numNetSources = ARRAY_LEN(netSources);
+
+static const char *netnames[] = {"???", "UDP", "IPX", NULL};
+
+/*
+================
+cvars
+================
+*/
+
+typedef struct {
+ vmCvar_t *vmCvar;
+ char *cvarName;
+ char *defaultString;
+ int cvarFlags;
+}
+
+cvarTable_t;
+
+vmCvar_t ui_browserShowFull;
+vmCvar_t ui_browserShowEmpty;
+
+vmCvar_t ui_dedicated;
+vmCvar_t ui_netSource;
+vmCvar_t ui_selectedMap;
+vmCvar_t ui_lastServerRefresh_0;
+vmCvar_t ui_lastServerRefresh_1;
+vmCvar_t ui_lastServerRefresh_2;
+vmCvar_t ui_lastServerRefresh_3;
+vmCvar_t ui_lastServerRefresh_0_time;
+vmCvar_t ui_lastServerRefresh_1_time;
+vmCvar_t ui_lastServerRefresh_2_time;
+vmCvar_t ui_lastServerRefresh_3_time;
+vmCvar_t ui_smallFont;
+vmCvar_t ui_bigFont;
+vmCvar_t ui_findPlayer;
+vmCvar_t ui_serverStatusTimeOut;
+vmCvar_t ui_textWrapCache;
+vmCvar_t ui_developer;
+
+vmCvar_t ui_emoticons;
+vmCvar_t ui_winner;
+vmCvar_t ui_chatCommands;
+
+static cvarTable_t cvarTable[] = {{&ui_browserShowFull, "ui_browserShowFull", "1", CVAR_ARCHIVE},
+ {&ui_browserShowEmpty, "ui_browserShowEmpty", "1", CVAR_ARCHIVE},
+
+ {&ui_dedicated, "ui_dedicated", "0", CVAR_ARCHIVE}, {&ui_netSource, "ui_netSource", "0", CVAR_ARCHIVE},
+ {&ui_selectedMap, "ui_selectedMap", "0", CVAR_ARCHIVE},
+ {&ui_lastServerRefresh_0, "ui_lastServerRefresh_0", "", CVAR_ARCHIVE},
+ {&ui_lastServerRefresh_1, "ui_lastServerRefresh_1", "", CVAR_ARCHIVE},
+ {&ui_lastServerRefresh_2, "ui_lastServerRefresh_2", "", CVAR_ARCHIVE},
+ {&ui_lastServerRefresh_3, "ui_lastServerRefresh_3", "", CVAR_ARCHIVE},
+ {&ui_lastServerRefresh_0, "ui_lastServerRefresh_0_time", "", CVAR_ARCHIVE},
+ {&ui_lastServerRefresh_1, "ui_lastServerRefresh_1_time", "", CVAR_ARCHIVE},
+ {&ui_lastServerRefresh_2, "ui_lastServerRefresh_2_time", "", CVAR_ARCHIVE},
+ {&ui_lastServerRefresh_3, "ui_lastServerRefresh_3_time", "", CVAR_ARCHIVE},
+ {&ui_smallFont, "ui_smallFont", "0.2", CVAR_ARCHIVE | CVAR_LATCH},
+ {&ui_bigFont, "ui_bigFont", "0.5", CVAR_ARCHIVE | CVAR_LATCH}, {&ui_findPlayer, "ui_findPlayer", "", CVAR_ARCHIVE},
+ {&ui_serverStatusTimeOut, "ui_serverStatusTimeOut", "7000", CVAR_ARCHIVE},
+ {&ui_textWrapCache, "ui_textWrapCache", "1", CVAR_ARCHIVE},
+ {&ui_developer, "ui_developer", "0", CVAR_ARCHIVE | CVAR_CHEAT},
+ {&ui_emoticons, "cg_emoticons", "1", CVAR_LATCH | CVAR_ARCHIVE}, {&ui_winner, "ui_winner", "", CVAR_ROM},
+ {&ui_chatCommands, "ui_chatCommands", "1", CVAR_ARCHIVE}};
+
+static size_t cvarTableSize = ARRAY_LEN(cvarTable);
/*
================
@@ -122,100 +124,118 @@ This is the only way control passes into the module.
This must be the very first function compiled into the .qvm file
================
*/
-vmCvar_t ui_new;
-vmCvar_t ui_debug;
-vmCvar_t ui_initialized;
-vmCvar_t ui_teamArenaFirstRun;
-
-void _UI_Init( qboolean );
-void _UI_Shutdown( void );
-void _UI_KeyEvent( int key, qboolean down );
-void _UI_MouseEvent( int dx, int dy );
-int _UI_MousePosition( void );
-void _UI_SetMousePosition( int x, int y );
-void _UI_Refresh( int realtime );
-qboolean _UI_IsFullscreen( void );
-Q_EXPORT intptr_t vmMain( int command, int arg0, int arg1, int arg2, int arg3,
- int arg4, int arg5, int arg6, int arg7,
- int arg8, int arg9, int arg10, int arg11 ) {
- switch ( command ) {
- case UI_GETAPIVERSION:
- return UI_API_VERSION;
-
- case UI_INIT:
- _UI_Init(arg0);
- return 0;
-
- case UI_SHUTDOWN:
- _UI_Shutdown();
- return 0;
-
- case UI_KEY_EVENT:
- _UI_KeyEvent( arg0, arg1 );
- return 0;
-
- case UI_MOUSE_EVENT:
- _UI_MouseEvent( arg0, arg1 );
- return 0;
+void UI_Init(qboolean);
+void UI_Shutdown(void);
+void UI_KeyEvent(int key, qboolean down);
+void UI_MouseEvent(int dx, int dy);
+int UI_MousePosition(void);
+void UI_SetMousePosition(int x, int y);
+void UI_Refresh(int realtime);
+qboolean UI_IsFullscreen(void);
+void UI_SetActiveMenu(uiMenuCommand_t menu);
+
+Q_EXPORT intptr_t vmMain(int command, int arg0, int arg1, int arg2)
+{
+ switch (command)
+ {
+ case UI_GETAPIVERSION:
+ return UI_API_VERSION;
+
+ case UI_INIT:
+ UI_Init(arg0);
+ return 0;
+
+ case UI_SHUTDOWN:
+ UI_Shutdown();
+ return 0;
+
+ case UI_KEY_EVENT:
+ UI_KeyEvent(arg0, arg1);
+ return 0;
+
+ case UI_MOUSE_EVENT:
+ UI_MouseEvent(arg0, arg1);
+ return 0;
#ifndef MODULE_INTERFACE_11
- case UI_MOUSE_POSITION:
- return _UI_MousePosition( );
+ case UI_MOUSE_POSITION:
+ return UI_MousePosition();
- case UI_SET_MOUSE_POSITION:
- _UI_SetMousePosition( arg0, arg1 );
- return 0;
+ case UI_SET_MOUSE_POSITION:
+ UI_SetMousePosition(arg0, arg1);
+ return 0;
#endif
- case UI_REFRESH:
- _UI_Refresh( arg0 );
- return 0;
+ case UI_REFRESH:
+ UI_Refresh(arg0);
+ return 0;
- case UI_IS_FULLSCREEN:
- return _UI_IsFullscreen();
+ case UI_IS_FULLSCREEN:
+ return UI_IsFullscreen();
- case UI_SET_ACTIVE_MENU:
- _UI_SetActiveMenu( arg0 );
- return 0;
+ case UI_SET_ACTIVE_MENU:
+ UI_SetActiveMenu(arg0);
+ return 0;
- case UI_CONSOLE_COMMAND:
- return UI_ConsoleCommand(arg0);
+ case UI_CONSOLE_COMMAND:
+ return UI_ConsoleCommand(arg0);
- case UI_DRAW_CONNECT_SCREEN:
- UI_DrawConnectScreen( arg0 );
- return 0;
- }
+ case UI_DRAW_CONNECT_SCREEN:
+ UI_DrawConnectScreen();
+ return 0;
+ }
- return -1;
+ return -1;
}
+void AssetCache(void)
+{
+ int i;
+ uiInfo.uiDC.Assets.gradientBar = trap_R_RegisterShaderNoMip(ASSET_GRADIENTBAR);
+ uiInfo.uiDC.Assets.scrollBar = trap_R_RegisterShaderNoMip(ASSET_SCROLLBAR);
+ uiInfo.uiDC.Assets.scrollBarArrowDown = trap_R_RegisterShaderNoMip(ASSET_SCROLLBAR_ARROWDOWN);
+ uiInfo.uiDC.Assets.scrollBarArrowUp = trap_R_RegisterShaderNoMip(ASSET_SCROLLBAR_ARROWUP);
+ uiInfo.uiDC.Assets.scrollBarArrowLeft = trap_R_RegisterShaderNoMip(ASSET_SCROLLBAR_ARROWLEFT);
+ uiInfo.uiDC.Assets.scrollBarArrowRight = trap_R_RegisterShaderNoMip(ASSET_SCROLLBAR_ARROWRIGHT);
+ uiInfo.uiDC.Assets.scrollBarThumb = trap_R_RegisterShaderNoMip(ASSET_SCROLL_THUMB);
+ uiInfo.uiDC.Assets.sliderBar = trap_R_RegisterShaderNoMip(ASSET_SLIDER_BAR);
+ uiInfo.uiDC.Assets.sliderThumb = trap_R_RegisterShaderNoMip(ASSET_SLIDER_THUMB);
+
+ if (ui_emoticons.integer)
+ {
+ uiInfo.uiDC.Assets.emoticonCount = BG_LoadEmoticons(uiInfo.uiDC.Assets.emoticons, MAX_EMOTICONS);
+ }
+ else
+ uiInfo.uiDC.Assets.emoticonCount = 0;
-void AssetCache( void ) {
- uiInfo.uiDC.Assets.gradientBar = trap_R_RegisterShaderNoMip( ASSET_GRADIENTBAR );
- uiInfo.uiDC.Assets.scrollBar = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR );
- uiInfo.uiDC.Assets.scrollBarArrowDown = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWDOWN );
- uiInfo.uiDC.Assets.scrollBarArrowUp = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWUP );
- uiInfo.uiDC.Assets.scrollBarArrowLeft = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWLEFT );
- uiInfo.uiDC.Assets.scrollBarArrowRight = trap_R_RegisterShaderNoMip( ASSET_SCROLLBAR_ARROWRIGHT );
- uiInfo.uiDC.Assets.scrollBarThumb = trap_R_RegisterShaderNoMip( ASSET_SCROLL_THUMB );
- uiInfo.uiDC.Assets.sliderBar = trap_R_RegisterShaderNoMip( ASSET_SLIDER_BAR );
- uiInfo.uiDC.Assets.sliderThumb = trap_R_RegisterShaderNoMip( ASSET_SLIDER_THUMB );
+ for (i = 0; i < uiInfo.uiDC.Assets.emoticonCount; i++)
+ {
+ uiInfo.uiDC.Assets.emoticons[i].shader = trap_R_RegisterShaderNoMip(
+ va("emoticons/%s_%dx1.tga", uiInfo.uiDC.Assets.emoticons[i].name, uiInfo.uiDC.Assets.emoticons[i].width));
+ }
}
-void _UI_DrawSides(float x, float y, float w, float h, float size) {
- UI_AdjustFrom640( &x, &y, &w, &h );
- size *= uiInfo.uiDC.xscale;
- trap_R_DrawStretchPic( x, y, size, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
- trap_R_DrawStretchPic( x + w - size, y, size, h, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
+void UI_DrawSides(float x, float y, float w, float h, float size)
+{
+ float sizeY;
+
+ UI_AdjustFrom640(&x, &y, &w, &h);
+ sizeY = size * uiInfo.uiDC.yscale;
+ size *= uiInfo.uiDC.xscale;
+
+ trap_R_DrawStretchPic(x, y + sizeY, size, h - (sizeY * 2.0f), 0, 0, 0, 0, uiInfo.uiDC.whiteShader);
+ trap_R_DrawStretchPic(x + w - size, y + sizeY, size, h - (sizeY * 2.0f), 0, 0, 0, 0, uiInfo.uiDC.whiteShader);
}
-void _UI_DrawTopBottom(float x, float y, float w, float h, float size) {
- UI_AdjustFrom640( &x, &y, &w, &h );
- size *= uiInfo.uiDC.yscale;
- trap_R_DrawStretchPic( x, y, w, size, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
- trap_R_DrawStretchPic( x, y + h - size, w, size, 0, 0, 0, 0, uiInfo.uiDC.whiteShader );
+void UI_DrawTopBottom(float x, float y, float w, float h, float size)
+{
+ UI_AdjustFrom640(&x, &y, &w, &h);
+ size *= uiInfo.uiDC.yscale;
+ trap_R_DrawStretchPic(x, y, w, size, 0, 0, 0, 0, uiInfo.uiDC.whiteShader);
+ trap_R_DrawStretchPic(x, y + h - size, w, size, 0, 0, 0, 0, uiInfo.uiDC.whiteShader);
}
+
/*
================
UI_DrawRect
@@ -223,2884 +243,2077 @@ UI_DrawRect
Coordinates are 640*480 virtual values
=================
*/
-void _UI_DrawRect( float x, float y, float width, float height, float size, const float *color ) {
- trap_R_SetColor( color );
+void UI_DrawRect(float x, float y, float width, float height, float size, const float *color)
+{
+ trap_R_SetColor(color);
- _UI_DrawTopBottom(x, y, width, height, size);
- _UI_DrawSides(x, y, width, height, size);
+ UI_DrawTopBottom(x, y, width, height, size);
+ UI_DrawSides(x, y, width, height, size);
- trap_R_SetColor( NULL );
+ trap_R_SetColor(NULL);
}
+/*
+==================
+UI_ServerInfoIsValid
+Return false if the infostring contains nonprinting characters,
+ or if the hostname is blank/undefined
+==================
+*/
+static qboolean UI_ServerInfoIsValid(char *info)
+{
+ char *c;
+ int len = 0;
-
-int Text_Width(const char *text, float scale, int limit) {
- int count,len;
- float out;
- glyphInfo_t *glyph;
- float useScale;
- const char *s = text;
- fontInfo_t *font = &uiInfo.uiDC.Assets.textFont;
- if (scale <= ui_smallFont.value) {
- font = &uiInfo.uiDC.Assets.smallFont;
- } else if (scale >= ui_bigFont.value) {
- font = &uiInfo.uiDC.Assets.bigFont;
- }
- useScale = scale * font->glyphScale;
- out = 0;
- if (text) {
- len = strlen(text);
- if (limit > 0 && len > limit) {
- len = limit;
- }
- count = 0;
- while (s && *s && count < len) {
- if ( Q_IsColorString(s) ) {
- s += 2;
- continue;
- } else {
- glyph = &font->glyphs[(int)*s];
- out += glyph->xSkip;
- s++;
- count++;
- }
+ for (c = info; *c; c++)
+ {
+ if (!isprint(*c))
+ return qfalse;
}
- }
- return out * useScale;
-}
-int Text_Height(const char *text, float scale, int limit) {
- int len, count;
- float max;
- glyphInfo_t *glyph;
- float useScale;
- const char *s = text; // bk001206 - unsigned
- fontInfo_t *font = &uiInfo.uiDC.Assets.textFont;
- if (scale <= ui_smallFont.value) {
- font = &uiInfo.uiDC.Assets.smallFont;
- } else if (scale >= ui_bigFont.value) {
- font = &uiInfo.uiDC.Assets.bigFont;
- }
- useScale = scale * font->glyphScale;
- max = 0;
- if (text) {
- len = strlen(text);
- if (limit > 0 && len > limit) {
- len = limit;
- }
- count = 0;
- while (s && *s && count < len) {
- if ( Q_IsColorString(s) ) {
- s += 2;
- continue;
- } else {
- glyph = &font->glyphs[(int)*s];
- if (max < glyph->height) {
- max = glyph->height;
- }
- s++;
- count++;
- }
+ for (c = Info_ValueForKey(info, "hostname"); *c; c++)
+ {
+ if (isgraph(*c))
+ len++;
}
- }
- return max * useScale;
-}
-void Text_PaintChar(float x, float y, float width, float height, float scale, float s, float t, float s2, float t2, qhandle_t hShader) {
- float w, h;
- w = width * scale;
- h = height * scale;
- UI_AdjustFrom640( &x, &y, &w, &h );
- trap_R_DrawStretchPic( x, y, w, h, s, t, s2, t2, hShader );
+ if (len)
+ return qtrue;
+ else
+ return qfalse;
}
-void Text_Paint(float x, float y, float scale, vec4_t color, const char *text, float adjust, int limit, int style) {
- int len, count;
- vec4_t newColor;
- glyphInfo_t *glyph;
- float useScale;
- fontInfo_t *font = &uiInfo.uiDC.Assets.textFont;
- if (scale <= ui_smallFont.value) {
- font = &uiInfo.uiDC.Assets.smallFont;
- } else if (scale >= ui_bigFont.value) {
- font = &uiInfo.uiDC.Assets.bigFont;
- }
- useScale = scale * font->glyphScale;
- if (text) {
- const char *s = text; // bk001206 - unsigned
- trap_R_SetColor( color );
- memcpy(&newColor[0], &color[0], sizeof(vec4_t));
- len = strlen(text);
- if (limit > 0 && len > limit) {
- len = limit;
- }
- count = 0;
- while (s && *s && count < len) {
- glyph = &font->glyphs[(int)*s];
- //int yadj = Assets.textFont.glyphs[text[i]].bottom + Assets.textFont.glyphs[text[i]].top;
- //float yadj = scale * (Assets.textFont.glyphs[text[i]].imageHeight - Assets.textFont.glyphs[text[i]].height);
- if ( Q_IsColorString( s ) ) {
- memcpy( newColor, g_color_table[ColorIndex(*(s+1))], sizeof( newColor ) );
- newColor[3] = color[3];
- trap_R_SetColor( newColor );
- s += 2;
- continue;
- } else {
- float yadj = useScale * glyph->top;
- if (style == ITEM_TEXTSTYLE_SHADOWED || style == ITEM_TEXTSTYLE_SHADOWEDMORE) {
- int ofs = style == ITEM_TEXTSTYLE_SHADOWED ? 1 : 2;
- colorBlack[3] = newColor[3];
- trap_R_SetColor( colorBlack );
- Text_PaintChar(x + ofs, y - yadj + ofs,
- glyph->imageWidth,
- glyph->imageHeight,
- useScale,
- glyph->s,
- glyph->t,
- glyph->s2,
- glyph->t2,
- glyph->glyph);
- trap_R_SetColor( newColor );
- colorBlack[3] = 1.0;
- }
- else if( style == ITEM_TEXTSTYLE_NEON )
- {
- vec4_t glow, outer, inner, white;
-
- glow[ 0 ] = newColor[ 0 ] * 0.5;
- glow[ 1 ] = newColor[ 1 ] * 0.5;
- glow[ 2 ] = newColor[ 2 ] * 0.5;
- glow[ 3 ] = newColor[ 3 ] * 0.2;
-
- outer[ 0 ] = newColor[ 0 ];
- outer[ 1 ] = newColor[ 1 ];
- outer[ 2 ] = newColor[ 2 ];
- outer[ 3 ] = newColor[ 3 ];
-
- inner[ 0 ] = newColor[ 0 ] * 1.5 > 1.0f ? 1.0f : newColor[ 0 ] * 1.5;
- inner[ 1 ] = newColor[ 1 ] * 1.5 > 1.0f ? 1.0f : newColor[ 1 ] * 1.5;
- inner[ 2 ] = newColor[ 2 ] * 1.5 > 1.0f ? 1.0f : newColor[ 2 ] * 1.5;
- inner[ 3 ] = newColor[ 3 ];
-
- white[ 0 ] = white[ 1 ] = white[ 2 ] = white[ 3 ] = 1.0f;
-
- trap_R_SetColor( glow );
- Text_PaintChar( x - 1.5, y - yadj - 1.5,
- glyph->imageWidth + 3,
- glyph->imageHeight + 3,
- useScale,
- glyph->s,
- glyph->t,
- glyph->s2,
- glyph->t2,
- glyph->glyph );
-
- trap_R_SetColor( outer );
- Text_PaintChar( x - 1, y - yadj - 1,
- glyph->imageWidth + 2,
- glyph->imageHeight + 2,
- useScale,
- glyph->s,
- glyph->t,
- glyph->s2,
- glyph->t2,
- glyph->glyph );
-
- trap_R_SetColor( inner );
- Text_PaintChar( x - 0.5, y - yadj - 0.5,
- glyph->imageWidth + 1,
- glyph->imageHeight + 1,
- useScale,
- glyph->s,
- glyph->t,
- glyph->s2,
- glyph->t2,
- glyph->glyph );
-
- trap_R_SetColor( white );
- }
-
- Text_PaintChar(x, y - yadj,
- glyph->imageWidth,
- glyph->imageHeight,
- useScale,
- glyph->s,
- glyph->t,
- glyph->s2,
- glyph->t2,
- glyph->glyph);
-
- x += (glyph->xSkip * useScale) + adjust;
- s++;
- count++;
- }
+/*
+==================
+UI_SanitiseString
+
+Remove color codes and non-alphanumeric characters from a string
+==================
+*/
+void UI_SanitiseString( char *in, char *out, int len )
+{
+ len--;
+
+ while( *in && len > 0 )
+ {
+ if( Q_IsColorString( in ) )
+ {
+ in += 2; // skip color code
+ continue;
+ }
+
+ if( isalnum( *in ) )
+ {
+ *out++ = tolower( *in );
+ len--;
+ }
+ in++;
}
- trap_R_SetColor( NULL );
- }
+ *out = 0;
}
-void Text_PaintWithCursor(float x, float y, float scale, vec4_t color, const char *text, int cursorPos, char cursor, int limit, int style) {
- int len, count;
- vec4_t newColor;
- glyphInfo_t *glyph, *glyph2;
- float yadj;
- float useScale;
- fontInfo_t *font = &uiInfo.uiDC.Assets.textFont;
- if (scale <= ui_smallFont.value) {
- font = &uiInfo.uiDC.Assets.smallFont;
- } else if (scale >= ui_bigFont.value) {
- font = &uiInfo.uiDC.Assets.bigFont;
- }
- useScale = scale * font->glyphScale;
- if (text) {
- const char *s = text; // bk001206 - unsigned
- trap_R_SetColor( color );
- memcpy(&newColor[0], &color[0], sizeof(vec4_t));
- len = strlen(text);
- if (limit > 0 && len > limit) {
- len = limit;
- }
- count = 0;
- glyph2 = &font->glyphs[ (int) cursor]; // bk001206 - possible signed char
- while (s && *s && count < len) {
- glyph = &font->glyphs[(int)*s];
- if ( Q_IsColorString( s ) ) {
- memcpy( newColor, g_color_table[ColorIndex(*(s+1))], sizeof( newColor ) );
- newColor[3] = color[3];
- trap_R_SetColor( newColor );
- s += 2;
- continue;
- } else {
- yadj = useScale * glyph->top;
- if (style == ITEM_TEXTSTYLE_SHADOWED || style == ITEM_TEXTSTYLE_SHADOWEDMORE) {
- int ofs = style == ITEM_TEXTSTYLE_SHADOWED ? 1 : 2;
- colorBlack[3] = newColor[3];
- trap_R_SetColor( colorBlack );
- Text_PaintChar(x + ofs, y - yadj + ofs,
- glyph->imageWidth,
- glyph->imageHeight,
- useScale,
- glyph->s,
- glyph->t,
- glyph->s2,
- glyph->t2,
- glyph->glyph);
- colorBlack[3] = 1.0;
- trap_R_SetColor( newColor );
- }
- else if( style == ITEM_TEXTSTYLE_NEON )
- {
- vec4_t glow, outer, inner, white;
-
- glow[ 0 ] = newColor[ 0 ] * 0.5;
- glow[ 1 ] = newColor[ 1 ] * 0.5;
- glow[ 2 ] = newColor[ 2 ] * 0.5;
- glow[ 3 ] = newColor[ 3 ] * 0.2;
-
- outer[ 0 ] = newColor[ 0 ];
- outer[ 1 ] = newColor[ 1 ];
- outer[ 2 ] = newColor[ 2 ];
- outer[ 3 ] = newColor[ 3 ];
-
- inner[ 0 ] = newColor[ 0 ] * 1.5 > 1.0f ? 1.0f : newColor[ 0 ] * 1.5;
- inner[ 1 ] = newColor[ 1 ] * 1.5 > 1.0f ? 1.0f : newColor[ 1 ] * 1.5;
- inner[ 2 ] = newColor[ 2 ] * 1.5 > 1.0f ? 1.0f : newColor[ 2 ] * 1.5;
- inner[ 3 ] = newColor[ 3 ];
-
- white[ 0 ] = white[ 1 ] = white[ 2 ] = white[ 3 ] = 1.0f;
-
- trap_R_SetColor( glow );
- Text_PaintChar( x - 1.5, y - yadj - 1.5,
- glyph->imageWidth + 3,
- glyph->imageHeight + 3,
- useScale,
- glyph->s,
- glyph->t,
- glyph->s2,
- glyph->t2,
- glyph->glyph );
-
- trap_R_SetColor( outer );
- Text_PaintChar( x - 1, y - yadj - 1,
- glyph->imageWidth + 2,
- glyph->imageHeight + 2,
- useScale,
- glyph->s,
- glyph->t,
- glyph->s2,
- glyph->t2,
- glyph->glyph );
-
- trap_R_SetColor( inner );
- Text_PaintChar( x - 0.5, y - yadj - 0.5,
- glyph->imageWidth + 1,
- glyph->imageHeight + 1,
- useScale,
- glyph->s,
- glyph->t,
- glyph->s2,
- glyph->t2,
- glyph->glyph );
-
- trap_R_SetColor( white );
- }
-
- Text_PaintChar(x, y - yadj,
- glyph->imageWidth,
- glyph->imageHeight,
- useScale,
- glyph->s,
- glyph->t,
- glyph->s2,
- glyph->t2,
- glyph->glyph);
-
- // CG_DrawPic(x, y - yadj, scale * uiDC.Assets.textFont.glyphs[text[i]].imageWidth, scale * uiDC.Assets.textFont.glyphs[text[i]].imageHeight, uiDC.Assets.textFont.glyphs[text[i]].glyph);
- yadj = useScale * glyph2->top;
- if (count == cursorPos && !((uiInfo.uiDC.realTime/BLINK_DIVISOR) & 1)) {
- Text_PaintChar(x, y - yadj,
- glyph2->imageWidth,
- glyph2->imageHeight,
- useScale,
- glyph2->s,
- glyph2->t,
- glyph2->s2,
- glyph2->t2,
- glyph2->glyph);
- }
-
- x += (glyph->xSkip * useScale);
- s++;
- count++;
- }
- }
- // need to paint cursor at end of text
- if (cursorPos == len && !((uiInfo.uiDC.realTime/BLINK_DIVISOR) & 1)) {
- yadj = useScale * glyph2->top;
- Text_PaintChar(x, y - yadj,
- glyph2->imageWidth,
- glyph2->imageHeight,
- useScale,
- glyph2->s,
- glyph2->t,
- glyph2->s2,
- glyph2->t2,
- glyph2->glyph);
+/*
+==================
+UI_PortFromAddress
+==================
+*/
+static int UI_PortFromAddress(const char *adrStr) {
+ int i;
+ int portLength = 0;
+ char portStr[MAX_ADDRESSLENGTH] = "";
+ qboolean foundPort = qfalse;
+ if (!adrStr || !adrStr[0]) {
+ return -1;
}
+ for (i = 0; adrStr[i] && (adrStr[i] != ' '); i++) {
+ if (!foundPort) {
+ if (adrStr[i] == ':') {
+ foundPort = qtrue;
+ }
- trap_R_SetColor( NULL );
- }
+ continue;
+ }
+
+ portStr[portLength] = adrStr[i];
+ portLength++;
+ }
+
+ if (portLength) {
+ return atoi(portStr);
+ } else {
+ return -1;
+ }
}
+/*
+==================
+UI_ProtocolFromAddress
-static void Text_Paint_Limit(float *maxX, float x, float y, float scale, vec4_t color, const char* text, float adjust, int limit) {
- int len, count;
- vec4_t newColor;
- glyphInfo_t *glyph;
- if (text) {
- const char *s = text; // bk001206 - unsigned
- float max = *maxX;
- float useScale;
- fontInfo_t *font = &uiInfo.uiDC.Assets.textFont;
- if (scale <= ui_smallFont.value) {
- font = &uiInfo.uiDC.Assets.smallFont;
- } else if (scale > ui_bigFont.value) {
- font = &uiInfo.uiDC.Assets.bigFont;
- }
- useScale = scale * font->glyphScale;
- trap_R_SetColor( color );
- len = strlen(text);
- if (limit > 0 && len > limit) {
- len = limit;
- }
- count = 0;
- while (s && *s && count < len) {
- glyph = &font->glyphs[(int)*s];
- if ( Q_IsColorString( s ) ) {
- memcpy( newColor, g_color_table[ColorIndex(*(s+1))], sizeof( newColor ) );
- newColor[3] = color[3];
- trap_R_SetColor( newColor );
- s += 2;
- continue;
- } else {
- float yadj = useScale * glyph->top;
- if (Text_Width(s, useScale, 1) + x > max) {
- *maxX = 0;
- break;
- }
- Text_PaintChar(x, y - yadj,
- glyph->imageWidth,
- glyph->imageHeight,
- useScale,
- glyph->s,
- glyph->t,
- glyph->s2,
- glyph->t2,
- glyph->glyph);
- x += (glyph->xSkip * useScale) + adjust;
- *maxX = x;
- count++;
- s++;
- }
+returns 2 if 1.1 is detected, returns 1 if gpp is detected, otherwise returns 0
+==================
+*/
+static int UI_ProtocolFromAddress(const char *adrStr) {
+ int i;
+
+ if (!adrStr || !adrStr[0]) {
+ return 0;
}
- trap_R_SetColor( NULL );
- }
-}
+ for (i = 0; adrStr[i]; i++) {
+ if (adrStr[i] == '-') {
+ if (adrStr[i+1]) {
+ switch (adrStr[i+1]) {
+ case '1':
+ return 2;
+ case 'g':
+ return 1;
-void UI_ShowPostGame(qboolean newHigh) {
- trap_Cvar_Set ("cg_cameraOrbit", "0");
- trap_Cvar_Set("cg_thirdPerson", "0");
- trap_Cvar_Set( "sv_killserver", "1" );
- uiInfo.soundHighScore = newHigh;
- _UI_SetActiveMenu(UIMENU_POSTGAME);
+ default:
+ return 0;
+ }
+ }
+ }
+ }
+
+ return 0;
}
+
/*
-=================
-_UI_Refresh
-=================
+==================
+UI_RemoveServerFromDisplayList
+==================
*/
+static void UI_RemoveServerFromDisplayList(int num)
+{
+ int i, j;
+ static char info[MAX_STRING_CHARS];
-void UI_DrawCenteredPic(qhandle_t image, int w, int h) {
- int x, y;
- x = (SCREEN_WIDTH - w) / 2;
- y = (SCREEN_HEIGHT - h) / 2;
- UI_DrawHandlePic(x, y, w, h, image);
-}
+ for (i = 0; i < uiInfo.serverStatus.numDisplayServers; i++)
+ {
+ if (uiInfo.serverStatus.displayServers[i] == num)
+ {
+ uiInfo.serverStatus.numDisplayServers--;
-int frameCount = 0;
-int startTime;
+ trap_LAN_GetServerInfo(ui_netSource.integer, num, info, MAX_STRING_CHARS);
-#define UI_FPS_FRAMES 4
-void _UI_Refresh( int realtime )
-{
- static int index;
- static int previousTimes[UI_FPS_FRAMES];
-
- //if ( !( trap_Key_GetCatcher() & KEYCATCH_UI ) ) {
- // return;
- //}
-
- uiInfo.uiDC.frameTime = realtime - uiInfo.uiDC.realTime;
- uiInfo.uiDC.realTime = realtime;
-
- previousTimes[index % UI_FPS_FRAMES] = uiInfo.uiDC.frameTime;
- index++;
- if ( index > UI_FPS_FRAMES ) {
- int i, total;
- // average multiple frames together to smooth changes out a bit
- total = 0;
- for ( i = 0 ; i < UI_FPS_FRAMES ; i++ ) {
- total += previousTimes[i];
- }
- if ( !total ) {
- total = 1;
- }
- uiInfo.uiDC.FPS = 1000 * UI_FPS_FRAMES / total;
- }
-
-
-
- UI_UpdateCvars();
-
- if (Menu_Count() > 0) {
- // paint all the menus
- Menu_PaintAll();
- // refresh server browser list
- UI_DoServerRefresh();
- // refresh server status
- UI_BuildServerStatus(qfalse);
- // refresh find player list
- UI_BuildFindPlayerList(qfalse);
- }
-
- // draw cursor
- UI_SetColor( NULL );
-
- //TA: don't draw the cursor whilst loading
- if( Menu_Count( ) > 0 && !trap_Cvar_VariableValue( "ui_loading" ) && !trap_Cvar_VariableValue( "ui_hideCursor" ) )
- UI_DrawHandlePic( uiInfo.uiDC.cursorx-16, uiInfo.uiDC.cursory-16, 32, 32, uiInfo.uiDC.Assets.cursor);
-
-#ifndef NDEBUG
- if (uiInfo.uiDC.debug)
- {
- // cursor coordinates
- //FIXME
- //UI_DrawString( 0, 0, va("(%d,%d)",uis.cursorx,uis.cursory), UI_LEFT|UI_SMALLFONT, colorRed );
- }
-#endif
+ for (j = i; j < uiInfo.serverStatus.numDisplayServers; j++)
+ uiInfo.serverStatus.displayServers[j] = uiInfo.serverStatus.displayServers[j+1];
+ return;
+ }
+ }
}
/*
-=================
-_UI_Shutdown
-=================
+==================
+UI_InsertServerIntoDisplayList
+==================
*/
-void _UI_Shutdown( void ) {
- trap_LAN_SaveCachedServers();
-}
+static qboolean UI_InsertServerIntoDisplayList(int num, int position)
+{
+ int i;
+ int hostnameLen;
+ int protocol;
+ int port;
+ char adrstr[MAX_ADDRESSLENGTH];
+ char hostname[MAX_HOSTNAME_LENGTH];
+ char basehostname[MAX_HOSTNAME_LENGTH];
+ static char info[MAX_STRING_CHARS];
+
+ if (position < 0 || position > uiInfo.serverStatus.numDisplayServers)
+ return qfalse;
-char *defaultMenu = NULL;
-
-char *GetMenuBuffer(const char *filename) {
- int len;
- fileHandle_t f;
- static char buf[MAX_MENUFILE];
-
- len = trap_FS_FOpenFile( filename, &f, FS_READ );
- if ( !f ) {
- trap_Print( va( S_COLOR_RED "menu file not found: %s, using default\n", filename ) );
- return defaultMenu;
- }
- if ( len >= MAX_MENUFILE ) {
- trap_Print( va( S_COLOR_RED "menu file too large: %s is %i, max allowed is %i", filename, len, MAX_MENUFILE ) );
- trap_FS_FCloseFile( f );
- return defaultMenu;
- }
-
- trap_FS_Read( buf, len, f );
- buf[len] = 0;
- trap_FS_FCloseFile( f );
- //COM_Compress(buf);
- return buf;
+ trap_LAN_GetServerInfo(ui_netSource.integer, num, info, MAX_STRING_CHARS);
-}
+ if (!UI_ServerInfoIsValid(info)) // don't list servers with invalid info
+ return qfalse;
-qboolean Asset_Parse(int handle) {
- pc_token_t token;
- const char *tempStr;
+ Q_strncpyz(hostname, Info_ValueForKey(info, "hostname"), MAX_HOSTNAME_LENGTH);
- if (!trap_Parse_ReadToken(handle, &token))
- return qfalse;
- if (Q_stricmp(token.string, "{") != 0) {
- return qfalse;
- }
+ hostnameLen = strlen(hostname);
- while ( 1 ) {
+ trap_LAN_GetServerAddressString(
+ ui_netSource.integer, num, adrstr, MAX_ADDRESSLENGTH);
- memset(&token, 0, sizeof(pc_token_t));
+ protocol = UI_ProtocolFromAddress(adrstr);
- if (!trap_Parse_ReadToken(handle, &token))
- return qfalse;
+ port = UI_PortFromAddress(adrstr);
- if (Q_stricmp(token.string, "}") == 0) {
- return qtrue;
+ if (protocol && hostnameLen > 6) {
+ // strip the protocol tags from the hostname
+ hostname[hostnameLen - 6] = '\0';
}
- // font
- if (Q_stricmp(token.string, "font") == 0) {
- int pointSize;
- if (!PC_String_Parse(handle, &tempStr) || !PC_Int_Parse(handle,&pointSize)) {
- return qfalse;
- }
- trap_R_RegisterFont(tempStr, pointSize, &uiInfo.uiDC.Assets.textFont);
- uiInfo.uiDC.Assets.fontRegistered = qtrue;
- continue;
- }
+ UI_SanitiseString(hostname, basehostname, sizeof(basehostname));
- if (Q_stricmp(token.string, "smallFont") == 0) {
- int pointSize;
- if (!PC_String_Parse(handle, &tempStr) || !PC_Int_Parse(handle,&pointSize)) {
- return qfalse;
- }
- trap_R_RegisterFont(tempStr, pointSize, &uiInfo.uiDC.Assets.smallFont);
- continue;
- }
+ // check if this is a duplicate listing of a multiprotocol server
+ for (i = 0; i < uiInfo.serverStatus.numDisplayServers; i++) {
+ int j;
+ int clients;
+ int protocol2;
+ int port2;
+ char info2[MAX_STRING_CHARS];
+ char adrstr2[MAX_ADDRESSLENGTH];
- if (Q_stricmp(token.string, "bigFont") == 0) {
- int pointSize;
- if (!PC_String_Parse(handle, &tempStr) || !PC_Int_Parse(handle,&pointSize)) {
- return qfalse;
- }
- trap_R_RegisterFont(tempStr, pointSize, &uiInfo.uiDC.Assets.bigFont);
- continue;
- }
+ trap_LAN_GetServerAddressString(
+ ui_netSource.integer,
+ uiInfo.serverStatus.displayServers[i], adrstr2, MAX_ADDRESSLENGTH);
+ protocol2 = UI_ProtocolFromAddress(adrstr2);
- // gradientbar
- if (Q_stricmp(token.string, "gradientbar") == 0) {
- if (!PC_String_Parse(handle, &tempStr)) {
- return qfalse;
- }
- uiInfo.uiDC.Assets.gradientBar = trap_R_RegisterShaderNoMip(tempStr);
- continue;
- }
+ port2 = UI_PortFromAddress(adrstr2);
- // enterMenuSound
- if (Q_stricmp(token.string, "menuEnterSound") == 0) {
- if (!PC_String_Parse(handle, &tempStr)) {
- return qfalse;
- }
- uiInfo.uiDC.Assets.menuEnterSound = trap_S_RegisterSound( tempStr, qfalse );
- continue;
- }
+ //compare the addresses
+ if (adrstr[0] != adrstr2[0]) {
+ continue;
+ } else {
+ qboolean skip = qfalse;
+
+ for (j = 1; adrstr[j] && adrstr2[j]; j++) {
+ if(adrstr[j] != adrstr2[j]) {
+ skip = qtrue;
+ break;
+ }
+
+ //don't compare ports
+ if (adrstr[j] == ':') {
+ break;
+ }
+ }
- // exitMenuSound
- if (Q_stricmp(token.string, "menuExitSound") == 0) {
- if (!PC_String_Parse(handle, &tempStr)) {
- return qfalse;
- }
- uiInfo.uiDC.Assets.menuExitSound = trap_S_RegisterSound( tempStr, qfalse );
- continue;
- }
+ if (skip) {
+ continue;
+ }
+ }
- // itemFocusSound
- if (Q_stricmp(token.string, "itemFocusSound") == 0) {
- if (!PC_String_Parse(handle, &tempStr)) {
- return qfalse;
- }
- uiInfo.uiDC.Assets.itemFocusSound = trap_S_RegisterSound( tempStr, qfalse );
- continue;
- }
+ trap_LAN_GetServerInfo(
+ ui_netSource.integer,
+ uiInfo.serverStatus.displayServers[i], info2, MAX_STRING_CHARS);
- // menuBuzzSound
- if (Q_stricmp(token.string, "menuBuzzSound") == 0) {
- if (!PC_String_Parse(handle, &tempStr)) {
- return qfalse;
- }
- uiInfo.uiDC.Assets.menuBuzzSound = trap_S_RegisterSound( tempStr, qfalse );
- continue;
- }
+ // if the ports are not the same, check to see if the host names are the
+ // same for older multiprotocol servers
+ if(port != port2) {
+ int hostnameLen2;
+ char hostname2[MAX_HOSTNAME_LENGTH];
+ char basehostname2[MAX_HOSTNAME_LENGTH];
- if (Q_stricmp(token.string, "cursor") == 0) {
- if (!PC_String_Parse(handle, &uiInfo.uiDC.Assets.cursorStr)) {
- return qfalse;
- }
- uiInfo.uiDC.Assets.cursor = trap_R_RegisterShaderNoMip( uiInfo.uiDC.Assets.cursorStr);
- continue;
- }
+ Q_strncpyz(hostname2, Info_ValueForKey(info2, "hostname"), MAX_HOSTNAME_LENGTH);
- if (Q_stricmp(token.string, "fadeClamp") == 0) {
- if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.fadeClamp)) {
- return qfalse;
- }
- continue;
- }
+ hostnameLen2 = strlen(hostname2);
- if (Q_stricmp(token.string, "fadeCycle") == 0) {
- if (!PC_Int_Parse(handle, &uiInfo.uiDC.Assets.fadeCycle)) {
- return qfalse;
- }
- continue;
- }
+ if (protocol2 && hostnameLen2 > 6) {
+ // strip the protocol tags from the hostname
+ hostname2[hostnameLen2 - 7] = '\0';
+ }
- if (Q_stricmp(token.string, "fadeAmount") == 0) {
- if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.fadeAmount)) {
- return qfalse;
- }
- continue;
- }
+ UI_SanitiseString(hostname2, basehostname2, sizeof(basehostname2));
- if (Q_stricmp(token.string, "shadowX") == 0) {
- if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.shadowX)) {
- return qfalse;
- }
- continue;
- }
+ //compare the hostnames
+ if (Q_stricmp(basehostname, basehostname2)) {
+ continue;
+ }
+ }
- if (Q_stricmp(token.string, "shadowY") == 0) {
- if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.shadowY)) {
- return qfalse;
- }
- continue;
- }
+ uiInfo.serverStatus.numDuplicateMultiprotocolServers++;
- if (Q_stricmp(token.string, "shadowColor") == 0) {
- if (!PC_Color_Parse(handle, &uiInfo.uiDC.Assets.shadowColor)) {
- return qfalse;
- }
- uiInfo.uiDC.Assets.shadowFadeClamp = uiInfo.uiDC.Assets.shadowColor[3];
- continue;
+ //show only the most recent protocol for a given server
+ if (protocol >= protocol2) {
+ clients = atoi(Info_ValueForKey(info, "clients"));
+ uiInfo.serverStatus.numDuplicateMultiprotocolServerClients += clients;
+ return qfalse;
+ } else {
+ clients = atoi(Info_ValueForKey(info2, "clients"));
+ uiInfo.serverStatus.numDuplicateMultiprotocolServerClients += clients;
+ UI_RemoveServerFromDisplayList(uiInfo.serverStatus.displayServers[i]);
+ i--;
+ continue;
+ }
}
- }
- return qfalse;
-}
+ //insert the server
+ uiInfo.serverStatus.numDisplayServers++;
-void Font_Report( void ) {
- int i;
- Com_Printf("Font Info\n");
- Com_Printf("=========\n");
- for ( i = 32; i < 96; i++) {
- Com_Printf("Glyph handle %i: %i\n", i, uiInfo.uiDC.Assets.textFont.glyphs[i].glyph);
- }
-}
+ for (i = uiInfo.serverStatus.numDisplayServers; i > position; i--)
+ uiInfo.serverStatus.displayServers[i] = uiInfo.serverStatus.displayServers[i - 1];
-void UI_Report( void ) {
- String_Report();
- //Font_Report();
+ uiInfo.serverStatus.displayServers[position] = num;
+ return qtrue;
}
-void UI_ParseMenu(const char *menuFile) {
- int handle;
- pc_token_t token;
-
- /*Com_Printf("Parsing menu file:%s\n", menuFile);*/
+/*
+==================
+UI_BinaryServerInsertion
+==================
+*/
+static qboolean UI_BinaryServerInsertion(int num)
+{
+ int mid, offset, res, len;
- handle = trap_Parse_LoadSource(menuFile);
- if (!handle) {
- return;
- }
+ // use binary search to insert server
+ len = uiInfo.serverStatus.numDisplayServers;
+ mid = len;
+ offset = 0;
+ res = 0;
- while ( 1 ) {
- memset(&token, 0, sizeof(pc_token_t));
- if (!trap_Parse_ReadToken( handle, &token )) {
- break;
- }
+ while (mid > 0)
+ {
+ mid = len >> 1;
+ //
+ res = trap_LAN_CompareServers(ui_netSource.integer, uiInfo.serverStatus.sortKey, uiInfo.serverStatus.sortDir,
+ num, uiInfo.serverStatus.displayServers[offset + mid]);
+ // if equal
- //if ( Q_stricmp( token, "{" ) ) {
- // Com_Printf( "Missing { in menu file\n" );
- // break;
- //}
+ if (res == 0)
+ {
+ return UI_InsertServerIntoDisplayList(num, offset + mid);
+ }
- //if ( menuCount == MAX_MENUS ) {
- // Com_Printf( "Too many menus!\n" );
- // break;
- //}
+ // if larger
+ else if (res == 1)
+ {
+ offset += mid;
+ len -= mid;
+ }
- if ( token.string[0] == '}' ) {
- break;
+ // if smaller
+ else
+ len -= mid;
}
- if (Q_stricmp(token.string, "assetGlobalDef") == 0) {
- if (Asset_Parse(handle)) {
- continue;
- } else {
- break;
- }
- }
+ if (res == 1)
+ offset++;
- if (Q_stricmp(token.string, "menudef") == 0) {
- // start a new menu
- Menu_New(handle);
- }
- }
- trap_Parse_FreeSource(handle);
+ return UI_InsertServerIntoDisplayList(num, offset);
+}
+
+typedef struct {
+ char *name, *altName;
}
+serverStatusCvar_t;
+
+serverStatusCvar_t serverStatusCvars[] = {{"sv_hostname", "Name"}, {"Address", ""}, {"gamename", "Game name"},
+ {"mapname", "Map"}, {"version", ""}, {"protocol", ""}, {"timelimit", ""}, {NULL, NULL}};
+
/*
-===============
-UI_FindInfoPaneByName
-===============
+==================
+UI_SortServerStatusInfo
+==================
*/
-tremInfoPane_t *UI_FindInfoPaneByName( const char *name )
+
+static int UI_SortServerStatusCompare(const void *a, const void *b)
+{
+ const char **la = (const char **)a;
+ const char **lb = (const char **)b;
+
+ return strcmp(la[0], lb[0]);
+}
+
+static void UI_SortServerStatusInfo(serverStatusInfo_t *info)
{
- int i;
+ int i, j, index;
+ char *tmp1, *tmp2;
- for( i = 0; i < uiInfo.tremInfoPaneCount; i++ )
- {
- if( !Q_stricmp( uiInfo.tremInfoPanes[ i ].name, name ) )
- return &uiInfo.tremInfoPanes[ i ];
- }
+ index = 0;
- //create a dummy infopane demanding the user write the infopane
- uiInfo.tremInfoPanes[ i ].name = String_Alloc( name );
- strncpy( uiInfo.tremInfoPanes[ i ].text, "Not implemented.\n\nui/infopanes.def\n", MAX_INFOPANE_TEXT );
- Q_strcat( uiInfo.tremInfoPanes[ i ].text, MAX_INFOPANE_TEXT, String_Alloc( name ) );
+ for (i = 0; serverStatusCvars[i].name; i++)
+ {
+ for (j = 0; j < info->numLines; j++)
+ {
+ if (!info->lines[j][1] || info->lines[j][1][0])
+ continue;
- uiInfo.tremInfoPaneCount++;
+ if (!Q_stricmp(serverStatusCvars[i].name, info->lines[j][0]))
+ {
+ // swap lines
+ tmp1 = info->lines[index][0];
+ tmp2 = info->lines[index][3];
+ info->lines[index][0] = info->lines[j][0];
+ info->lines[index][3] = info->lines[j][3];
+ info->lines[j][0] = tmp1;
+ info->lines[j][3] = tmp2;
+ //
+
+ if (strlen(serverStatusCvars[i].altName))
+ info->lines[index][0] = serverStatusCvars[i].altName;
+
+ index++;
+ }
+ }
+ }
- return &uiInfo.tremInfoPanes[ i ];
+ // sort remaining cvars
+ qsort(info->lines + index, info->numLines - index, sizeof(info->lines[0]), UI_SortServerStatusCompare);
}
/*
-===============
-UI_LoadInfoPane
-===============
+==================
+UI_GetServerStatusInfo
+==================
*/
-qboolean UI_LoadInfoPane( int handle )
+static int UI_GetServerStatusInfo(const char *serverAddress, serverStatusInfo_t *info)
{
- pc_token_t token;
- qboolean valid = qfalse;
+ char *p, *score, *ping, *name;
+ int i, len;
- while( 1 )
- {
- memset( &token, 0, sizeof( pc_token_t ) );
+ if (!info)
+ {
+ trap_LAN_ServerStatus(serverAddress, NULL, 0);
+ return qfalse;
+ }
- if( !trap_Parse_ReadToken( handle, &token ) )
- break;
+ memset(info, 0, sizeof(*info));
- if( !Q_stricmp( token.string, "name" ) )
+ if (trap_LAN_ServerStatus(serverAddress, info->text, sizeof(info->text)))
{
- memset( &token, 0, sizeof( pc_token_t ) );
+ Q_strncpyz(info->address, serverAddress, sizeof(info->address));
+ p = info->text;
+ info->numLines = 0;
+ info->lines[info->numLines][0] = "Address";
+ info->lines[info->numLines][1] = "";
+ info->lines[info->numLines][2] = "";
+ info->lines[info->numLines][3] = info->address;
+ info->numLines++;
+ // get the cvars
- if( !trap_Parse_ReadToken( handle, &token ) )
- break;
+ while (p && *p)
+ {
+ p = strchr(p, '\\');
- uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].name = String_Alloc( token.string );
- valid = qtrue;
- }
- else if( !Q_stricmp( token.string, "graphic" ) )
- {
- int *graphic;
+ if (!p)
+ break;
- memset( &token, 0, sizeof( pc_token_t ) );
+ *p++ = '\0';
- if( !trap_Parse_ReadToken( handle, &token ) )
- break;
+ if (*p == '\\')
+ break;
- graphic = &uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].numGraphics;
+ info->lines[info->numLines][0] = p;
+ info->lines[info->numLines][1] = "";
+ info->lines[info->numLines][2] = "";
- if( !Q_stricmp( token.string, "top" ) )
- uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].graphics[ *graphic ].side = INFOPANE_TOP;
- else if( !Q_stricmp( token.string, "bottom" ) )
- uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].graphics[ *graphic ].side = INFOPANE_BOTTOM;
- else if( !Q_stricmp( token.string, "left" ) )
- uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].graphics[ *graphic ].side = INFOPANE_LEFT;
- else if( !Q_stricmp( token.string, "right" ) )
- uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].graphics[ *graphic ].side = INFOPANE_RIGHT;
- else
- break;
+ p = strchr(p, '\\');
- memset( &token, 0, sizeof( pc_token_t ) );
+ if (!p)
+ break;
- if( !trap_Parse_ReadToken( handle, &token ) )
- break;
+ *p++ = '\0';
- if( !Q_stricmp( token.string, "center" ) )
- uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].graphics[ *graphic ].offset = -1;
- else
- uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].graphics[ *graphic ].offset = token.intvalue;
+ info->lines[info->numLines][3] = p;
+ info->numLines++;
- memset( &token, 0, sizeof( pc_token_t ) );
+ if (info->numLines >= MAX_SERVERSTATUS_LINES)
+ break;
+ }
- if( !trap_Parse_ReadToken( handle, &token ) )
- break;
+ UI_SortServerStatusInfo(info);
- uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].graphics[ *graphic ].graphic =
- trap_R_RegisterShaderNoMip( token.string );
+ // get the player list
+ if (info->numLines < MAX_SERVERSTATUS_LINES - 3)
+ {
+ // empty line
+ info->lines[info->numLines][0] = "";
+ info->lines[info->numLines][1] = "";
+ info->lines[info->numLines][2] = "";
+ info->lines[info->numLines][3] = "";
+ info->numLines++;
+ // header
+ info->lines[info->numLines][0] = "num";
+ info->lines[info->numLines][1] = "score";
+ info->lines[info->numLines][2] = "ping";
+ info->lines[info->numLines][3] = "name";
+ info->numLines++;
+ // parse players
+ i = 0;
+ len = 0;
+
+ while (p && *p)
+ {
+ if (*p == '\\')
+ *p++ = '\0';
- memset( &token, 0, sizeof( pc_token_t ) );
+ if (!p)
+ break;
- if( !trap_Parse_ReadToken( handle, &token ) )
- break;
+ score = p;
- uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].graphics[ *graphic ].width = token.intvalue;
+ p = strchr(p, ' ');
- memset( &token, 0, sizeof( pc_token_t ) );
+ if (!p)
+ break;
- if( !trap_Parse_ReadToken( handle, &token ) )
- break;
+ *p++ = '\0';
- uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].graphics[ *graphic ].height = token.intvalue;
+ ping = p;
- //increment graphics
- (*graphic)++;
+ p = strchr(p, ' ');
- if( *graphic == MAX_INFOPANE_GRAPHICS )
- break;
- }
- else if( !Q_stricmp( token.string, "text" ) )
- {
- memset( &token, 0, sizeof( pc_token_t ) );
+ if (!p)
+ break;
- if( !trap_Parse_ReadToken( handle, &token ) )
- break;
+ *p++ = '\0';
- Q_strcat( uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].text, MAX_INFOPANE_TEXT, token.string );
- }
- else if( !Q_stricmp( token.string, "align" ) )
- {
- memset( &token, 0, sizeof( pc_token_t ) );
+ name = p;
- if( !trap_Parse_ReadToken( handle, &token ) )
- break;
+ Com_sprintf(&info->pings[len], sizeof(info->pings) - len, "%d", i);
- if( !Q_stricmp( token.string, "left" ) )
- uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].align = ITEM_ALIGN_LEFT;
- else if( !Q_stricmp( token.string, "right" ) )
- uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].align = ITEM_ALIGN_RIGHT;
- else if( !Q_stricmp( token.string, "center" ) )
- uiInfo.tremInfoPanes[ uiInfo.tremInfoPaneCount ].align = ITEM_ALIGN_CENTER;
- }
- else if( token.string[ 0 ] == '}' )
- {
- //reached the end, break
- break;
+ info->lines[info->numLines][0] = &info->pings[len];
+
+ len += strlen(&info->pings[len]) + 1;
+
+ info->lines[info->numLines][1] = score;
+ info->lines[info->numLines][2] = ping;
+ info->lines[info->numLines][3] = name;
+ info->numLines++;
+
+ if (info->numLines >= MAX_SERVERSTATUS_LINES)
+ break;
+
+ p = strchr(p, '\\');
+
+ if (!p)
+ break;
+
+ *p++ = '\0';
+
+ //
+ i++;
+ }
+ }
+
+ return qtrue;
}
- else
- break;
- }
- if( valid )
- {
- uiInfo.tremInfoPaneCount++;
- return qtrue;
- }
- else
- {
return qfalse;
- }
}
/*
-===============
-UI_LoadInfoPanes
-===============
+==================
+stristr
+==================
*/
-void UI_LoadInfoPanes( const char *file )
+static char *stristr(char *str, char *charset)
{
- pc_token_t token;
- int handle;
- int count;
+ int i;
- uiInfo.tremInfoPaneCount = count = 0;
+ while (*str)
+ {
+ for (i = 0; charset[i] && str[i]; i++)
+ if (toupper(charset[i]) != toupper(str[i]))
+ break;
- handle = trap_Parse_LoadSource( file );
+ if (!charset[i])
+ return str;
- if( !handle )
- {
- trap_Error( va( S_COLOR_YELLOW "infopane file not found: %s\n", file ) );
- return;
- }
+ str++;
+ }
- while( 1 )
- {
- if( !trap_Parse_ReadToken( handle, &token ) )
- break;
+ return NULL;
+}
- if( token.string[ 0 ] == 0 )
- break;
+/*
+==================
+UI_BuildFindPlayerList
+==================
+*/
+static void UI_FeederSelection(int feederID, int index);
- if( token.string[ 0 ] == '{' )
+static void UI_BuildFindPlayerList(qboolean force)
+{
+ static int numFound, numTimeOuts;
+ int i, j, k, resend;
+ serverStatusInfo_t info;
+ char name[MAX_NAME_LENGTH + 2];
+ char infoString[MAX_STRING_CHARS];
+ qboolean duplicate;
+
+ if (!force)
{
- if( UI_LoadInfoPane( handle ) )
- count++;
-
- if( count == MAX_INFOPANES )
- break;
+ if (!uiInfo.nextFindPlayerRefresh || uiInfo.nextFindPlayerRefresh > uiInfo.uiDC.realTime)
+ return;
}
- }
+ else
+ {
+ memset(&uiInfo.pendingServerStatus, 0, sizeof(uiInfo.pendingServerStatus));
+ uiInfo.numFoundPlayerServers = 0;
+ uiInfo.currentFoundPlayerServer = 0;
+ trap_Cvar_VariableStringBuffer("ui_findPlayer", uiInfo.findPlayerName, sizeof(uiInfo.findPlayerName));
+ Q_CleanStr(uiInfo.findPlayerName);
+ // should have a string of some length
+
+ if (!strlen(uiInfo.findPlayerName))
+ {
+ uiInfo.nextFindPlayerRefresh = 0;
+ return;
+ }
- trap_Parse_FreeSource( handle );
-}
+ // set resend time
+ resend = ui_serverStatusTimeOut.integer / 2 - 10;
-qboolean Load_Menu(int handle) {
- pc_token_t token;
+ if (resend < 50)
+ resend = 50;
- if (!trap_Parse_ReadToken(handle, &token))
- return qfalse;
- if (token.string[0] != '{') {
- return qfalse;
- }
+ trap_Cvar_Set("cl_serverStatusResendTime", va("%d", resend));
+ // reset all server status requests
+ trap_LAN_ServerStatus(NULL, NULL, 0);
+ //
+ uiInfo.numFoundPlayerServers = 1;
+ Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers - 1],
+ sizeof(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers - 1]), "searching %d...",
+ uiInfo.pendingServerStatus.num);
+ numFound = 0;
+ numTimeOuts++;
+ }
- while ( 1 ) {
+ for (i = 0; i < MAX_SERVERSTATUSREQUESTS; i++)
+ {
+ // if this pending server is valid
- if (!trap_Parse_ReadToken(handle, &token))
- return qfalse;
+ if (uiInfo.pendingServerStatus.server[i].valid)
+ {
+ // try to get the server status for this server
- if ( token.string[0] == 0 ) {
- return qfalse;
- }
+ if (UI_GetServerStatusInfo(uiInfo.pendingServerStatus.server[i].adrstr, &info))
+ {
+ //
+ numFound++;
+ // parse through the server status lines
+
+ for (j = 0; j < info.numLines; j++)
+ {
+ // should have ping info
+
+ if (!info.lines[j][2] || !info.lines[j][2][0])
+ continue;
+
+ // clean string first
+ Q_strncpyz(name, info.lines[j][3], sizeof(name));
+
+ Q_CleanStr(name);
+
+ duplicate = qfalse;
+
+ for (k = 0; k < uiInfo.numFoundPlayerServers - 1; k++)
+ {
+ if (Q_strncmp(uiInfo.foundPlayerServerAddresses[k], uiInfo.pendingServerStatus.server[i].adrstr,
+ MAX_ADDRESSLENGTH) == 0)
+ duplicate = qtrue;
+ }
+
+ // if the player name is a substring
+ if (stristr(name, uiInfo.findPlayerName) && !duplicate)
+ {
+ // add to found server list if we have space (always leave space for a line with the number
+ // found)
+
+ if (uiInfo.numFoundPlayerServers < MAX_FOUNDPLAYER_SERVERS - 1)
+ {
+ //
+ Q_strncpyz(uiInfo.foundPlayerServerAddresses[uiInfo.numFoundPlayerServers - 1],
+ uiInfo.pendingServerStatus.server[i].adrstr,
+ sizeof(uiInfo.foundPlayerServerAddresses[0]));
+ Q_strncpyz(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers - 1],
+ uiInfo.pendingServerStatus.server[i].name, sizeof(uiInfo.foundPlayerServerNames[0]));
+ uiInfo.numFoundPlayerServers++;
+ }
+ else
+ {
+ // can't add any more so we're done
+ uiInfo.pendingServerStatus.num = uiInfo.serverStatus.numDisplayServers;
+ }
+ }
+ }
+
+ Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers - 1],
+ sizeof(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers - 1]), "searching %d/%d...",
+ numFound, uiInfo.pendingServerStatus.num);
+ // retrieved the server status so reuse this spot
+ uiInfo.pendingServerStatus.server[i].valid = qfalse;
+ }
+ }
- if ( token.string[0] == '}' ) {
- return qtrue;
- }
+ // if empty pending slot or timed out
+ if (!uiInfo.pendingServerStatus.server[i].valid ||
+ uiInfo.pendingServerStatus.server[i].startTime < uiInfo.uiDC.realTime - ui_serverStatusTimeOut.integer)
+ {
+ if (uiInfo.pendingServerStatus.server[i].valid)
+ numTimeOuts++;
- UI_ParseMenu(token.string);
- }
- return qfalse;
-}
+ // reset server status request for this address
+ UI_GetServerStatusInfo(uiInfo.pendingServerStatus.server[i].adrstr, NULL);
-void UI_LoadMenus(const char *menuFile, qboolean reset) {
- pc_token_t token;
- int handle;
- int start;
+ // reuse pending slot
+ uiInfo.pendingServerStatus.server[i].valid = qfalse;
- start = trap_Milliseconds();
+ // if we didn't try to get the status of all servers in the main browser yet
+ if (uiInfo.pendingServerStatus.num < uiInfo.serverStatus.numDisplayServers)
+ {
+ uiInfo.pendingServerStatus.server[i].startTime = uiInfo.uiDC.realTime;
+ trap_LAN_GetServerAddressString(ui_netSource.integer,
+ uiInfo.serverStatus.displayServers[uiInfo.pendingServerStatus.num],
+ uiInfo.pendingServerStatus.server[i].adrstr, sizeof(uiInfo.pendingServerStatus.server[i].adrstr));
+
+ trap_LAN_GetServerInfo(ui_netSource.integer,
+ uiInfo.serverStatus.displayServers[uiInfo.pendingServerStatus.num], infoString, sizeof(infoString));
+
+ Q_strncpyz(uiInfo.pendingServerStatus.server[i].name, Info_ValueForKey(infoString, "hostname"),
+ sizeof(uiInfo.pendingServerStatus.server[0].name));
+
+ uiInfo.pendingServerStatus.server[i].valid = qtrue;
+ uiInfo.pendingServerStatus.num++;
+ Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers - 1],
+ sizeof(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers - 1]), "searching %d/%d...",
+ numFound, uiInfo.pendingServerStatus.num);
+ }
+ }
+ }
- handle = trap_Parse_LoadSource( menuFile );
- if (!handle) {
- trap_Error( va( S_COLOR_YELLOW "menu file not found: %s, using default\n", menuFile ) );
- handle = trap_Parse_LoadSource( "ui/menus.txt" );
- if (!handle) {
- trap_Error( va( S_COLOR_RED "default menu file not found: ui/menus.txt, unable to continue!\n" ) );
+ for (i = 0; i < MAX_SERVERSTATUSREQUESTS; i++)
+ {
+ if (uiInfo.pendingServerStatus.server[i].valid)
+ break;
}
- }
- ui_new.integer = 1;
+ // if still trying to retrieve server status info
+ if (i < MAX_SERVERSTATUSREQUESTS)
+ uiInfo.nextFindPlayerRefresh = uiInfo.uiDC.realTime + 25;
+ else
+ {
+ // add a line that shows the number of servers found
- if (reset) {
- Menu_Reset();
- }
+ if (!uiInfo.numFoundPlayerServers)
+ {
+ Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers - 1],
+ sizeof(uiInfo.foundPlayerServerAddresses[0]), "no servers found");
+ }
+ else
+ {
+ Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers - 1],
+ sizeof(uiInfo.foundPlayerServerAddresses[0]), "%d server%s found with player %s",
+ uiInfo.numFoundPlayerServers - 1, uiInfo.numFoundPlayerServers == 2 ? "" : "s", uiInfo.findPlayerName);
+ }
- while ( 1 ) {
- if (!trap_Parse_ReadToken(handle, &token))
- break;
- if( token.string[0] == 0 || token.string[0] == '}') {
- break;
+ uiInfo.nextFindPlayerRefresh = 0;
+ // show the server status info for the selected server
+ UI_FeederSelection(FEEDER_FINDPLAYER, uiInfo.currentFoundPlayerServer);
}
+}
- if ( token.string[0] == '}' ) {
- break;
- }
+/*
+==================
+UI_BuildServerStatus
+==================
+*/
+static void UI_BuildServerStatus(qboolean force)
+{
+ if (uiInfo.nextFindPlayerRefresh)
+ return;
- if (Q_stricmp(token.string, "loadmenu") == 0) {
- if (Load_Menu(handle)) {
- continue;
- } else {
- break;
- }
+ if (!force)
+ {
+ if (!uiInfo.nextServerStatusRefresh || uiInfo.nextServerStatusRefresh > uiInfo.uiDC.realTime)
+ return;
+ }
+ else
+ {
+ Menu_SetFeederSelection(NULL, FEEDER_SERVERSTATUS, 0, NULL);
+ uiInfo.serverStatusInfo.numLines = 0;
+ // reset all server status requests
+ trap_LAN_ServerStatus(NULL, NULL, 0);
}
- }
- Com_Printf("UI menu load time = %d milli seconds\n", trap_Milliseconds() - start);
+ if (uiInfo.serverStatus.currentServer < 0 ||
+ uiInfo.serverStatus.currentServer > uiInfo.serverStatus.numDisplayServers ||
+ uiInfo.serverStatus.numDisplayServers == 0)
+ return;
- trap_Parse_FreeSource( handle );
+ if (UI_GetServerStatusInfo(uiInfo.serverStatusAddress, &uiInfo.serverStatusInfo))
+ {
+ uiInfo.nextServerStatusRefresh = 0;
+ UI_GetServerStatusInfo(uiInfo.serverStatusAddress, NULL);
+ }
+ else
+ uiInfo.nextServerStatusRefresh = uiInfo.uiDC.realTime + 500;
}
-void UI_Load( void ) {
- char lastName[1024];
- menuDef_t *menu = Menu_GetFocused();
- char *menuSet = UI_Cvar_VariableString("ui_menuFiles");
- if (menu && menu->window.name) {
- strcpy(lastName, menu->window.name);
- }
- if (menuSet == NULL || menuSet[0] == '\0') {
- menuSet = "ui/menus.txt";
- }
+/*
+==================
+UI_BuildServerDisplayList
+==================
+*/
+static void UI_BuildServerDisplayList(int force)
+{
+ int i, count, clients, maxClients, ping, len, visible;
+ char info[MAX_STRING_CHARS];
+ static int numinvisible;
- String_Init();
+ if (!(force || uiInfo.uiDC.realTime > uiInfo.serverStatus.nextDisplayRefresh))
+ return;
-/* UI_ParseGameInfo("gameinfo.txt");
- UI_LoadArenas();*/
+ // if we shouldn't reset
+ if (force == 2)
+ force = 0;
- UI_LoadMenus(menuSet, qtrue);
- Menus_CloseAll();
- Menus_ActivateByName(lastName);
+ // do motd updates here too
+ trap_Cvar_VariableStringBuffer("cl_motdString", uiInfo.serverStatus.motd, sizeof(uiInfo.serverStatus.motd));
-}
+ len = strlen(uiInfo.serverStatus.motd);
-static const char *handicapValues[] = {"None","95","90","85","80","75","70","65","60","55","50","45","40","35","30","25","20","15","10","5",NULL};
+ if (len != uiInfo.serverStatus.motdLen)
+ {
+ uiInfo.serverStatus.motdLen = len;
+ uiInfo.serverStatus.motdWidth = -1;
+ }
-static void UI_DrawHandicap(rectDef_t *rect, float scale, vec4_t color, int textStyle) {
- int i, h;
+ if (force)
+ {
+ numinvisible = 0;
+ // clear number of displayed servers
+ uiInfo.serverStatus.numDisplayServers = 0;
+ uiInfo.serverStatus.numPlayersOnServers = 0;
+ uiInfo.serverStatus.numDuplicateMultiprotocolServers = 0;
+ uiInfo.serverStatus.numDuplicateMultiprotocolServerClients = 0;
+ // set list box index to zero
+ Menu_SetFeederSelection(NULL, FEEDER_SERVERS, 0, NULL);
+ // mark all servers as visible so we store ping updates for them
+ trap_LAN_MarkServerVisible(ui_netSource.integer, -1, qtrue);
+ }
+
+ // get the server count (comes from the master)
+ count = trap_LAN_GetServerCount(ui_netSource.integer);
+
+ if (count == -1 || (ui_netSource.integer == AS_LOCAL && count == 0))
+ {
+ // still waiting on a response from the master
+ uiInfo.serverStatus.numDisplayServers = 0;
+ uiInfo.serverStatus.numPlayersOnServers = 0;
+ uiInfo.serverStatus.numDuplicateMultiprotocolServers = 0;
+ uiInfo.serverStatus.numDuplicateMultiprotocolServerClients = 0;
+ uiInfo.serverStatus.nextDisplayRefresh = uiInfo.uiDC.realTime + 500;
+ return;
+ }
- h = Com_Clamp( 5, 100, trap_Cvar_VariableValue("handicap") );
- i = 20 - h / 5;
+ visible = qfalse;
- Text_Paint(rect->x, rect->y, scale, color, handicapValues[i], 0, 0, textStyle);
-}
+ for (i = 0; i < count; i++)
+ {
+ // if we already got info for this server
-static void UI_DrawClanName(rectDef_t *rect, float scale, vec4_t color, int textStyle) {
- Text_Paint(rect->x, rect->y, scale, color, UI_Cvar_VariableString("ui_teamName"), 0, 0, textStyle);
-}
+ if (!trap_LAN_ServerIsVisible(ui_netSource.integer, i))
+ continue;
+ visible = qtrue;
+ // get the ping for this server
+ ping = trap_LAN_GetServerPing(ui_netSource.integer, i);
-static void UI_SetCapFragLimits(qboolean uiVars) {
- int cap = 5;
- int frag = 10;
- if (uiVars) {
- trap_Cvar_Set("ui_captureLimit", va("%d", cap));
- trap_Cvar_Set("ui_fragLimit", va("%d", frag));
- } else {
- trap_Cvar_Set("capturelimit", va("%d", cap));
- trap_Cvar_Set("fraglimit", va("%d", frag));
- }
-}
-// ui_gameType assumes gametype 0 is -1 ALL and will not show
-static void UI_DrawGameType(rectDef_t *rect, float scale, vec4_t color, int textStyle) {
- Text_Paint(rect->x, rect->y, scale, color, uiInfo.gameTypes[ui_gameType.integer].gameType, 0, 0, textStyle);
-}
+ if (ping > 0 || ui_netSource.integer == AS_FAVORITES)
+ {
+ trap_LAN_GetServerInfo(ui_netSource.integer, i, info, MAX_STRING_CHARS);
-static void UI_DrawNetGameType(rectDef_t *rect, float scale, vec4_t color, int textStyle) {
- if (ui_netGameType.integer < 0 || ui_netGameType.integer > uiInfo.numGameTypes) {
- trap_Cvar_Set("ui_netGameType", "0");
- trap_Cvar_Set("ui_actualNetGameType", "0");
- }
- Text_Paint(rect->x, rect->y, scale, color, uiInfo.gameTypes[ui_netGameType.integer].gameType , 0, 0, textStyle);
-}
+ clients = atoi(Info_ValueForKey(info, "clients"));
+ uiInfo.serverStatus.numPlayersOnServers += clients;
-static void UI_DrawJoinGameType(rectDef_t *rect, float scale, vec4_t color, int textStyle) {
- if (ui_joinGameType.integer < 0 || ui_joinGameType.integer > uiInfo.numJoinGameTypes) {
- trap_Cvar_Set("ui_joinGameType", "0");
- }
- Text_Paint(rect->x, rect->y, scale, color, uiInfo.joinGameTypes[ui_joinGameType.integer].gameType , 0, 0, textStyle);
-}
+ if (ui_browserShowEmpty.integer == 0)
+ {
+ if (clients == 0)
+ {
+ trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse);
+ continue;
+ }
+ }
+ if (ui_browserShowFull.integer == 0)
+ {
+ maxClients = atoi(Info_ValueForKey(info, "sv_maxclients"));
+ if (clients == maxClients)
+ {
+ trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse);
+ continue;
+ }
+ }
-static int UI_TeamIndexFromName(const char *name) {
- int i;
+ // make sure we never add a favorite server twice
+ if (ui_netSource.integer == AS_FAVORITES)
+ UI_RemoveServerFromDisplayList(i);
- if (name && *name) {
- for (i = 0; i < uiInfo.teamCount; i++) {
- if (Q_stricmp(name, uiInfo.teamList[i].teamName) == 0) {
- return i;
- }
+ // insert the server into the list
+ UI_BinaryServerInsertion(i);
+
+ // done with this server
+ if (ping > 0)
+ {
+ trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse);
+ numinvisible++;
+ }
+ }
}
- }
- return 0;
+ uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime;
+
+ // if there were no servers visible for ping updates
+ if (!visible)
+ {
+ // UI_StopServerRefresh();
+ // uiInfo.serverStatus.nextDisplayRefresh = 0;
+ }
}
-static void UI_DrawClanLogo(rectDef_t *rect, float scale, vec4_t color) {
- int i;
- i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
- if (i >= 0 && i < uiInfo.teamCount) {
- trap_R_SetColor( color );
+/*
+=================
+UI_StopServerRefresh
+=================
+*/
+static void UI_StopServerRefresh(void)
+{
+ int count;
- if (uiInfo.teamList[i].teamIcon == -1) {
- uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName);
- uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName));
- uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName));
+ if (!uiInfo.serverStatus.refreshActive)
+ {
+ // not currently refreshing
+ return;
}
- UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon);
- trap_R_SetColor(NULL);
- }
+ uiInfo.serverStatus.refreshActive = qfalse;
+ Com_Printf("%d servers listed in browser with %d players.\n", uiInfo.serverStatus.numDisplayServers,
+ uiInfo.serverStatus.numPlayersOnServers -
+ uiInfo.serverStatus.numDuplicateMultiprotocolServerClients);
+ count = trap_LAN_GetServerCount(ui_netSource.integer);
+
+ if (count - uiInfo.serverStatus.numDisplayServers - uiInfo.serverStatus.numDuplicateMultiprotocolServers > 0)
+ {
+ Com_Printf(
+ "%d servers not listed due to packet loss, invalid info,"
+ " or pings higher than %d\n",
+ count - uiInfo.serverStatus.numDisplayServers - uiInfo.serverStatus.numDuplicateMultiprotocolServers,
+ (int)trap_Cvar_VariableValue("cl_maxPing"));
+ }
}
-static void UI_DrawClanCinematic(rectDef_t *rect, float scale, vec4_t color) {
- int i;
- i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
- if (i >= 0 && i < uiInfo.teamCount) {
+/*
+=================
+UI_DoServerRefresh
+=================
+*/
+static void UI_DoServerRefresh(void)
+{
+ qboolean wait = qfalse;
+
+ if (!uiInfo.serverStatus.refreshActive)
+ return;
- if (uiInfo.teamList[i].cinematic >= -2) {
- if (uiInfo.teamList[i].cinematic == -1) {
- uiInfo.teamList[i].cinematic = trap_CIN_PlayCinematic(va("%s.roq", uiInfo.teamList[i].imageName), 0, 0, 0, 0, (CIN_loop | CIN_silent) );
- }
- if (uiInfo.teamList[i].cinematic >= 0) {
- trap_CIN_RunCinematic(uiInfo.teamList[i].cinematic);
- trap_CIN_SetExtents(uiInfo.teamList[i].cinematic, rect->x, rect->y, rect->w, rect->h);
- trap_CIN_DrawCinematic(uiInfo.teamList[i].cinematic);
- } else {
- trap_R_SetColor( color );
- UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon_Metal);
- trap_R_SetColor(NULL);
- uiInfo.teamList[i].cinematic = -2;
- }
- } else {
- trap_R_SetColor( color );
- UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon);
- trap_R_SetColor(NULL);
+ if (ui_netSource.integer != AS_FAVORITES)
+ {
+ if (ui_netSource.integer == AS_LOCAL)
+ {
+ if (!trap_LAN_GetServerCount(ui_netSource.integer))
+ wait = qtrue;
+ }
+ else
+ {
+ if (trap_LAN_GetServerCount(ui_netSource.integer) < 0)
+ wait = qtrue;
+ }
}
- }
-}
+ if (uiInfo.uiDC.realTime < uiInfo.serverStatus.refreshtime)
+ {
+ if (wait)
+ return;
+ }
-static void UI_DrawPreviewCinematic(rectDef_t *rect, float scale, vec4_t color) {
- if (uiInfo.previewMovie > -2) {
- uiInfo.previewMovie = trap_CIN_PlayCinematic(va("%s.roq", uiInfo.movieList[uiInfo.movieIndex]), 0, 0, 0, 0, (CIN_loop | CIN_silent) );
- if (uiInfo.previewMovie >= 0) {
- trap_CIN_RunCinematic(uiInfo.previewMovie);
- trap_CIN_SetExtents(uiInfo.previewMovie, rect->x, rect->y, rect->w, rect->h);
- trap_CIN_DrawCinematic(uiInfo.previewMovie);
- } else {
- uiInfo.previewMovie = -2;
+ // if still trying to retrieve pings
+ if (trap_LAN_UpdateVisiblePings(ui_netSource.integer))
+ uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 1000;
+ else if (!wait)
+ {
+ // get the last servers in the list
+ UI_BuildServerDisplayList(2);
+ // stop the refresh
+ UI_StopServerRefresh();
}
- }
+ //
+ UI_BuildServerDisplayList(qfalse);
}
+/*
+=================
+UI_UpdatePendingPings
+=================
+*/
+static void UI_UpdatePendingPings(void)
+{
+ trap_LAN_ResetPings(ui_netSource.integer);
+ uiInfo.serverStatus.refreshActive = qtrue;
+ uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 1000;
+}
-#define GRAPHIC_BWIDTH 8.0f
/*
-===============
-UI_DrawInfoPane
-===============
+=================
+UI_StartServerRefresh
+=================
*/
-static void UI_DrawInfoPane( tremInfoPane_t *pane, rectDef_t *rect, float text_x, float text_y,
- float scale, vec4_t color, int textStyle )
+static void UI_StartServerRefresh(qboolean full)
{
- int i;
- float maxLeft = 0, maxTop = 0;
- float maxRight = 0, maxBottom = 0;
- float x = rect->x - text_x, y = rect->y - text_y, w, h;
- float xoffset = 0, yoffset = 0;
- menuDef_t dummyParent;
- itemDef_t textItem;
+ int time;
+ qtime_t q;
- //iterate through graphics
- for( i = 0; i < pane->numGraphics; i++ )
- {
- float width = pane->graphics[ i ].width;
- float height = pane->graphics[ i ].height;
- qhandle_t graphic = pane->graphics[ i ].graphic;
+ time = trap_RealTime(&q);
+ trap_Cvar_Set(va("ui_lastServerRefresh_%i_time", ui_netSource.integer), va("%i", time));
+ trap_Cvar_Set(va("ui_lastServerRefresh_%i", ui_netSource.integer),
+ va("%04i-%02i-%02i %02i:%02i:%02i", q.tm_year + 1900, q.tm_mon + 1, q.tm_mday, q.tm_hour, q.tm_min, q.tm_sec));
- if( pane->graphics[ i ].side == INFOPANE_TOP || pane->graphics[ i ].side == INFOPANE_BOTTOM )
+ if (!full)
{
- //set horizontal offset of graphic
- if( pane->graphics[ i ].offset < 0 )
- xoffset = ( rect->w / 2 ) - ( pane->graphics[ i ].width / 2 );
- else
- xoffset = pane->graphics[ i ].offset + GRAPHIC_BWIDTH;
+ UI_UpdatePendingPings();
+ return;
}
- else if( pane->graphics[ i ].side == INFOPANE_LEFT || pane->graphics[ i ].side == INFOPANE_RIGHT )
+
+ uiInfo.serverStatus.refreshActive = qtrue;
+ uiInfo.serverStatus.nextDisplayRefresh = uiInfo.uiDC.realTime + 1000;
+ // clear number of displayed servers
+ uiInfo.serverStatus.numDisplayServers = 0;
+ uiInfo.serverStatus.numPlayersOnServers = 0;
+ uiInfo.serverStatus.numDuplicateMultiprotocolServers = 0;
+ uiInfo.serverStatus.numDuplicateMultiprotocolServerClients = 0;
+ // mark all servers as visible so we store ping updates for them
+ trap_LAN_MarkServerVisible(ui_netSource.integer, -1, qtrue);
+ // reset all the pings
+ trap_LAN_ResetPings(ui_netSource.integer);
+ //
+
+ if (ui_netSource.integer == AS_LOCAL)
{
- //set vertical offset of graphic
- if( pane->graphics[ i ].offset < 0 )
- yoffset = ( rect->h / 2 ) - ( pane->graphics[ i ].height / 2 );
- else
- yoffset = pane->graphics[ i ].offset + GRAPHIC_BWIDTH;
+ trap_Cmd_ExecuteText(EXEC_APPEND, "localservers\n");
+ uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 1000;
+ return;
}
- if( pane->graphics[ i ].side == INFOPANE_LEFT )
- {
- //set the horizontal offset of the text
- if( pane->graphics[ i ].width > maxLeft )
- maxLeft = pane->graphics[ i ].width + GRAPHIC_BWIDTH;
+ uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 5000;
- xoffset = GRAPHIC_BWIDTH;
- }
- else if( pane->graphics[ i ].side == INFOPANE_RIGHT )
+ if (ui_netSource.integer == AS_GLOBAL || ui_netSource.integer == AS_MPLAYER)
{
- if( pane->graphics[ i ].width > maxRight )
- maxRight = pane->graphics[ i ].width + GRAPHIC_BWIDTH;
+ qboolean global = ui_netSource.integer == AS_GLOBAL;
- xoffset = rect->w - width - GRAPHIC_BWIDTH;
+#ifdef MODULE_INTERFACE_11
+ trap_Cmd_ExecuteText(EXEC_APPEND, va("globalservers %d 69 full empty\n",
+#else
+ trap_Cmd_ExecuteText(EXEC_APPEND, va("globalservers %d 70 full empty\n",
+#endif
+ global ? 0 : 1));
}
- else if( pane->graphics[ i ].side == INFOPANE_TOP )
+}
+
+int frameCount = 0;
+int startTime;
+
+#define UI_FPS_FRAMES 4
+void UI_Refresh(int realtime)
+{
+ static int index;
+ static int previousTimes[UI_FPS_FRAMES];
+
+ // if( !( trap_Key_GetCatcher() & KEYCATCH_UI ) ) {
+ // return;
+ //}
+
+ uiInfo.uiDC.frameTime = realtime - uiInfo.uiDC.realTime;
+ uiInfo.uiDC.realTime = realtime;
+
+ previousTimes[index % UI_FPS_FRAMES] = uiInfo.uiDC.frameTime;
+ index++;
+
+ if (index > UI_FPS_FRAMES)
{
- //set the vertical offset of the text
- if( pane->graphics[ i ].height > maxTop )
- maxTop = pane->graphics[ i ].height + GRAPHIC_BWIDTH;
+ int i, total;
+ // average multiple frames together to smooth changes out a bit
+ total = 0;
+
+ for (i = 0; i < UI_FPS_FRAMES; i++)
+ total += previousTimes[i];
- yoffset = GRAPHIC_BWIDTH;
+ if (!total)
+ total = 1;
+
+ uiInfo.uiDC.FPS = 1000 * UI_FPS_FRAMES / total;
}
- else if( pane->graphics[ i ].side == INFOPANE_BOTTOM )
- {
- if( pane->graphics[ i ].height > maxBottom )
- maxBottom = pane->graphics[ i ].height + GRAPHIC_BWIDTH;
- yoffset = rect->h - height - GRAPHIC_BWIDTH;
+ UI_UpdateCvars();
+
+ if (Menu_Count() > 0)
+ {
+ Menu_UpdateAll();
+ Menu_PaintAll();
+ UI_DoServerRefresh();
+ UI_BuildServerStatus(qfalse);
+ UI_BuildFindPlayerList(qfalse);
+ UI_UpdateNews(qfalse);
+ // FIXME: CHECK FOR "AUTOMATICALLLY CHECK FOR UPDATES == true"
+ // UI_UpdateGithubRelease( );
}
- //draw the graphic
- UI_DrawHandlePic( x + xoffset, y + yoffset, width, height, graphic );
- }
+ // draw cursor
+ UI_SetColor(NULL);
- //offset the text
- x = rect->x + maxLeft;
- y = rect->y + maxTop;
- w = rect->w - ( maxLeft + maxRight + 16 + ( 2 * text_x ) ); //16 to ensure text within frame
- h = rect->h - ( maxTop + maxBottom );
+ if (trap_Key_GetCatcher() == KEYCATCH_UI && !trap_Cvar_VariableValue("ui_hideCursor"))
+ {
+ UI_DrawHandlePic(uiInfo.uiDC.cursorx - (16.0f * uiInfo.uiDC.aspectScale), uiInfo.uiDC.cursory - 16.0f,
+ 32.0f * uiInfo.uiDC.aspectScale, 32.0f, uiInfo.uiDC.Assets.cursor);
+ }
+}
- textItem.text = pane->text;
+/*
+=================
+UI_Shutdown
+=================
+*/
+void UI_Shutdown(void) { trap_LAN_SaveCachedServers(); }
- textItem.parent = &dummyParent;
- memcpy( textItem.window.foreColor, color, sizeof( vec4_t ) );
- textItem.window.flags = 0;
+qboolean Asset_Parse(int handle)
+{
+ pc_token_t token;
+ const char *tempStr;
- switch( pane->align )
- {
- case ITEM_ALIGN_LEFT:
- textItem.window.rect.x = x;
- break;
+ if (!trap_Parse_ReadToken(handle, &token))
+ return qfalse;
- case ITEM_ALIGN_RIGHT:
- textItem.window.rect.x = x + w;
- break;
+ if (Q_stricmp(token.string, "{") != 0)
+ return qfalse;
- case ITEM_ALIGN_CENTER:
- textItem.window.rect.x = x + ( w / 2 );
- break;
+ while (1)
+ {
+ memset(&token, 0, sizeof(pc_token_t));
- default:
- textItem.window.rect.x = x;
- break;
- }
+ if (!trap_Parse_ReadToken(handle, &token))
+ return qfalse;
- textItem.window.rect.y = y;
- textItem.window.rect.w = w;
- textItem.window.rect.h = h;
- textItem.window.borderSize = 0;
- textItem.textRect.x = 0;
- textItem.textRect.y = 0;
- textItem.textRect.w = 0;
- textItem.textRect.h = 0;
- textItem.textalignment = pane->align;
- textItem.textalignx = text_x;
- textItem.textaligny = text_y;
- textItem.textscale = scale;
- textItem.textStyle = textStyle;
+ if (Q_stricmp(token.string, "}") == 0)
+ return qtrue;
- textItem.enableCvar = NULL;
- textItem.cvarTest = NULL;
+ // font
+ if (Q_stricmp(token.string, "font") == 0)
+ {
+ int pointSize;
- //hack to utilise existing autowrap code
- Item_Text_AutoWrapped_Paint( &textItem );
-}
+ if (!PC_String_Parse(handle, &tempStr) || !PC_Int_Parse(handle, &pointSize))
+ return qfalse;
+ trap_R_RegisterFont(tempStr, pointSize, &uiInfo.uiDC.Assets.textFont);
+ uiInfo.uiDC.Assets.fontRegistered = qtrue;
+ continue;
+ }
-static void UI_DrawSkill(rectDef_t *rect, float scale, vec4_t color, int textStyle) {
- int i;
- i = trap_Cvar_VariableValue( "g_spSkill" );
- if (i < 1 || i > numSkillLevels) {
- i = 1;
- }
- Text_Paint(rect->x, rect->y, scale, color, skillLevels[i-1],0, 0, textStyle);
-}
+ if (Q_stricmp(token.string, "smallFont") == 0)
+ {
+ int pointSize;
+ if (!PC_String_Parse(handle, &tempStr) || !PC_Int_Parse(handle, &pointSize))
+ return qfalse;
-static void UI_DrawTeamName(rectDef_t *rect, float scale, vec4_t color, qboolean blue, int textStyle) {
- int i;
- i = UI_TeamIndexFromName(UI_Cvar_VariableString((blue) ? "ui_blueTeam" : "ui_redTeam"));
- if (i >= 0 && i < uiInfo.teamCount) {
- Text_Paint(rect->x, rect->y, scale, color, va("%s: %s", (blue) ? "Blue" : "Red", uiInfo.teamList[i].teamName),0, 0, textStyle);
- }
-}
+ trap_R_RegisterFont(tempStr, pointSize, &uiInfo.uiDC.Assets.smallFont);
+ continue;
+ }
-static void UI_DrawTeamMember(rectDef_t *rect, float scale, vec4_t color, qboolean blue, int num, int textStyle) {
- // 0 - None
- // 1 - Human
- // 2..NumCharacters - Bot
- int value = trap_Cvar_VariableValue(va(blue ? "ui_blueteam%i" : "ui_redteam%i", num));
- const char *text;
- if (value <= 0) {
- text = "Closed";
- } else if (value == 1) {
- text = "Human";
- } else {
- value -= 2;
-
- if( value >= UI_GetNumBots( ) )
- value = 0;
-
- text = UI_GetBotNameByNumber(value);
- }
- Text_Paint(rect->x, rect->y, scale, color, text, 0, 0, textStyle);
-}
+ if (Q_stricmp(token.string, "bigFont") == 0)
+ {
+ int pointSize;
-static void UI_DrawMapPreview(rectDef_t *rect, float scale, vec4_t color, qboolean net) {
- int map = (net) ? ui_currentNetMap.integer : ui_currentMap.integer;
- if (map < 0 || map > uiInfo.mapCount) {
- if (net) {
- ui_currentNetMap.integer = 0;
- trap_Cvar_Set("ui_currentNetMap", "0");
- } else {
- ui_currentMap.integer = 0;
- trap_Cvar_Set("ui_currentMap", "0");
- }
- map = 0;
- }
+ if (!PC_String_Parse(handle, &tempStr) || !PC_Int_Parse(handle, &pointSize))
+ return qfalse;
- if (uiInfo.mapList[map].levelShot == -1) {
- uiInfo.mapList[map].levelShot = trap_R_RegisterShaderNoMip(uiInfo.mapList[map].imageName);
- }
+ trap_R_RegisterFont(tempStr, pointSize, &uiInfo.uiDC.Assets.bigFont);
+ continue;
+ }
- if (uiInfo.mapList[map].levelShot > 0) {
- UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.mapList[map].levelShot);
- } else {
- UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, trap_R_RegisterShaderNoMip("gfx/2d/load_screen"));
- }
-}
+ // gradientbar
+ if (Q_stricmp(token.string, "gradientbar") == 0)
+ {
+ if (!PC_String_Parse(handle, &tempStr))
+ return qfalse;
+ uiInfo.uiDC.Assets.gradientBar = trap_R_RegisterShaderNoMip(tempStr);
+ continue;
+ }
-static void UI_DrawMapTimeToBeat(rectDef_t *rect, float scale, vec4_t color, int textStyle) {
- int minutes, seconds, time;
- if (ui_currentMap.integer < 0 || ui_currentMap.integer > uiInfo.mapCount) {
- ui_currentMap.integer = 0;
- trap_Cvar_Set("ui_currentMap", "0");
- }
+ // enterMenuSound
+ if (Q_stricmp(token.string, "menuEnterSound") == 0)
+ {
+ if (!PC_String_Parse(handle, &tempStr))
+ return qfalse;
- time = uiInfo.mapList[ui_currentMap.integer].timeToBeat[uiInfo.gameTypes[ui_gameType.integer].gtEnum];
+ uiInfo.uiDC.Assets.menuEnterSound = trap_S_RegisterSound(tempStr, qfalse);
+ continue;
+ }
- minutes = time / 60;
- seconds = time % 60;
+ // exitMenuSound
+ if (Q_stricmp(token.string, "menuExitSound") == 0)
+ {
+ if (!PC_String_Parse(handle, &tempStr))
+ return qfalse;
- Text_Paint(rect->x, rect->y, scale, color, va("%02i:%02i", minutes, seconds), 0, 0, textStyle);
-}
+ uiInfo.uiDC.Assets.menuExitSound = trap_S_RegisterSound(tempStr, qfalse);
+ continue;
+ }
+ // itemFocusSound
+ if (Q_stricmp(token.string, "itemFocusSound") == 0)
+ {
+ if (!PC_String_Parse(handle, &tempStr))
+ return qfalse;
+ uiInfo.uiDC.Assets.itemFocusSound = trap_S_RegisterSound(tempStr, qfalse);
+ continue;
+ }
-static void UI_DrawMapCinematic(rectDef_t *rect, float scale, vec4_t color, qboolean net) {
+ // menuBuzzSound
+ if (Q_stricmp(token.string, "menuBuzzSound") == 0)
+ {
+ if (!PC_String_Parse(handle, &tempStr))
+ return qfalse;
- int map = (net) ? ui_currentNetMap.integer : ui_currentMap.integer;
- if (map < 0 || map > uiInfo.mapCount) {
- if (net) {
- ui_currentNetMap.integer = 0;
- trap_Cvar_Set("ui_currentNetMap", "0");
- } else {
- ui_currentMap.integer = 0;
- trap_Cvar_Set("ui_currentMap", "0");
- }
- map = 0;
- }
+ uiInfo.uiDC.Assets.menuBuzzSound = trap_S_RegisterSound(tempStr, qfalse);
+ continue;
+ }
- if (uiInfo.mapList[map].cinematic >= -1) {
- if (uiInfo.mapList[map].cinematic == -1) {
- uiInfo.mapList[map].cinematic = trap_CIN_PlayCinematic(va("%s.roq", uiInfo.mapList[map].mapLoadName), 0, 0, 0, 0, (CIN_loop | CIN_silent) );
- }
- if (uiInfo.mapList[map].cinematic >= 0) {
- trap_CIN_RunCinematic(uiInfo.mapList[map].cinematic);
- trap_CIN_SetExtents(uiInfo.mapList[map].cinematic, rect->x, rect->y, rect->w, rect->h);
- trap_CIN_DrawCinematic(uiInfo.mapList[map].cinematic);
- } else {
- uiInfo.mapList[map].cinematic = -2;
- }
- } else {
- UI_DrawMapPreview(rect, scale, color, net);
- }
-}
+ if (Q_stricmp(token.string, "cursor") == 0)
+ {
+ if (!PC_String_Parse(handle, &uiInfo.uiDC.Assets.cursorStr))
+ return qfalse;
+ uiInfo.uiDC.Assets.cursor = trap_R_RegisterShaderNoMip(uiInfo.uiDC.Assets.cursorStr);
+ continue;
+ }
+ if (Q_stricmp(token.string, "fadeClamp") == 0)
+ {
+ if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.fadeClamp))
+ return qfalse;
-static qboolean updateModel = qtrue;
-static qboolean q3Model = qfalse;
-
-static void UI_DrawPlayerModel(rectDef_t *rect) {
- static playerInfo_t info;
- char model[MAX_QPATH];
- char team[256];
- char head[256];
- vec3_t viewangles;
- vec3_t moveangles;
-
- if (trap_Cvar_VariableValue("ui_Q3Model")) {
- strcpy(model, UI_Cvar_VariableString("model"));
- strcpy(head, UI_Cvar_VariableString("headmodel"));
- if (!q3Model) {
- q3Model = qtrue;
- updateModel = qtrue;
- }
- team[0] = '\0';
- } else {
-
- strcpy(team, UI_Cvar_VariableString("ui_teamName"));
- strcpy(model, UI_Cvar_VariableString("team_model"));
- strcpy(head, UI_Cvar_VariableString("team_headmodel"));
- if (q3Model) {
- q3Model = qfalse;
- updateModel = qtrue;
- }
- }
- if (updateModel) {
- memset( &info, 0, sizeof(playerInfo_t) );
- viewangles[YAW] = 180 - 10;
- viewangles[PITCH] = 0;
- viewangles[ROLL] = 0;
- VectorClear( moveangles );
- UI_PlayerInfo_SetModel( &info, model, head, team);
- UI_PlayerInfo_SetInfo( &info, LEGS_IDLE, TORSO_STAND, viewangles, vec3_origin, WP_MACHINEGUN, qfalse );
-// UI_RegisterClientModelname( &info, model, head, team);
- updateModel = qfalse;
- }
-
- UI_DrawPlayer( rect->x, rect->y, rect->w, rect->h, &info, uiInfo.uiDC.realTime / 2);
+ continue;
+ }
-}
+ if (Q_stricmp(token.string, "fadeCycle") == 0)
+ {
+ if (!PC_Int_Parse(handle, &uiInfo.uiDC.Assets.fadeCycle))
+ return qfalse;
-static void UI_DrawNetSource(rectDef_t *rect, float scale, vec4_t color, int textStyle) {
- if (ui_netSource.integer < 0 || ui_netSource.integer > numNetSources) {
- ui_netSource.integer = 0;
- }
- Text_Paint(rect->x, rect->y, scale, color, va("Source: %s", netSources[ui_netSource.integer]), 0, 0, textStyle);
-}
+ continue;
+ }
-static void UI_DrawNetMapPreview(rectDef_t *rect, float scale, vec4_t color) {
+ if (Q_stricmp(token.string, "fadeAmount") == 0)
+ {
+ if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.fadeAmount))
+ return qfalse;
- if (uiInfo.serverStatus.currentServerPreview > 0) {
- UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.serverStatus.currentServerPreview);
- } else {
- UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, trap_R_RegisterShaderNoMip("gfx/2d/load_screen"));
- }
-}
+ continue;
+ }
-static void UI_DrawNetMapCinematic(rectDef_t *rect, float scale, vec4_t color) {
- if (ui_currentNetMap.integer < 0 || ui_currentNetMap.integer > uiInfo.mapCount) {
- ui_currentNetMap.integer = 0;
- trap_Cvar_Set("ui_currentNetMap", "0");
- }
-
- if (uiInfo.serverStatus.currentServerCinematic >= 0) {
- trap_CIN_RunCinematic(uiInfo.serverStatus.currentServerCinematic);
- trap_CIN_SetExtents(uiInfo.serverStatus.currentServerCinematic, rect->x, rect->y, rect->w, rect->h);
- trap_CIN_DrawCinematic(uiInfo.serverStatus.currentServerCinematic);
- } else {
- UI_DrawNetMapPreview(rect, scale, color);
- }
-}
+ if (Q_stricmp(token.string, "shadowX") == 0)
+ {
+ if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.shadowX))
+ return qfalse;
+
+ continue;
+ }
+ if (Q_stricmp(token.string, "shadowY") == 0)
+ {
+ if (!PC_Float_Parse(handle, &uiInfo.uiDC.Assets.shadowY))
+ return qfalse;
+ continue;
+ }
-static void UI_DrawNetFilter(rectDef_t *rect, float scale, vec4_t color, int textStyle) {
- if (ui_serverFilterType.integer < 0 || ui_serverFilterType.integer > numServerFilters) {
- ui_serverFilterType.integer = 0;
- }
- Text_Paint(rect->x, rect->y, scale, color, va("Filter: %s", serverFilters[ui_serverFilterType.integer].description), 0, 0, textStyle);
-}
+ if (Q_stricmp(token.string, "shadowColor") == 0)
+ {
+ if (!PC_Color_Parse(handle, &uiInfo.uiDC.Assets.shadowColor))
+ return qfalse;
+ uiInfo.uiDC.Assets.shadowFadeClamp = uiInfo.uiDC.Assets.shadowColor[3];
+ continue;
+ }
+ }
-static void UI_DrawTier(rectDef_t *rect, float scale, vec4_t color, int textStyle) {
- int i;
- i = trap_Cvar_VariableValue( "ui_currentTier" );
- if (i < 0 || i >= uiInfo.tierCount) {
- i = 0;
- }
- Text_Paint(rect->x, rect->y, scale, color, va("Tier: %s", uiInfo.tierList[i].tierName),0, 0, textStyle);
+ return qfalse;
}
-static void UI_DrawTierMap(rectDef_t *rect, int index) {
- int i;
- i = trap_Cvar_VariableValue( "ui_currentTier" );
- if (i < 0 || i >= uiInfo.tierCount) {
- i = 0;
- }
+void UI_Report(void) { String_Report(); }
- if (uiInfo.tierList[i].mapHandles[index] == -1) {
- uiInfo.tierList[i].mapHandles[index] = trap_R_RegisterShaderNoMip(va("levelshots/%s", uiInfo.tierList[i].maps[index]));
- }
+void UI_ParseMenu(const char *menuFile)
+{
+ int handle;
+ pc_token_t token;
- UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.tierList[i].mapHandles[index]);
-}
+ handle = trap_Parse_LoadSource(menuFile);
-static const char *UI_EnglishMapName(const char *map) {
- int i;
- for (i = 0; i < uiInfo.mapCount; i++) {
- if (Q_stricmp(map, uiInfo.mapList[i].mapLoadName) == 0) {
- return uiInfo.mapList[i].mapName;
+ if (!handle)
+ {
+ Com_Printf(S_COLOR_YELLOW "WARNING: Menu file %s not found\n", menuFile);
+ return;
}
- }
- return "";
-}
-static void UI_DrawTierMapName(rectDef_t *rect, float scale, vec4_t color, int textStyle) {
- int i, j;
- i = trap_Cvar_VariableValue( "ui_currentTier" );
- if (i < 0 || i >= uiInfo.tierCount) {
- i = 0;
- }
- j = trap_Cvar_VariableValue("ui_currentMap");
- if (j < 0 || j > MAPS_PER_TIER) {
- j = 0;
- }
-
- Text_Paint(rect->x, rect->y, scale, color, UI_EnglishMapName(uiInfo.tierList[i].maps[j]), 0, 0, textStyle);
-}
+ while (1)
+ {
+ memset(&token, 0, sizeof(pc_token_t));
-static void UI_DrawTierGameType(rectDef_t *rect, float scale, vec4_t color, int textStyle) {
- int i, j;
- i = trap_Cvar_VariableValue( "ui_currentTier" );
- if (i < 0 || i >= uiInfo.tierCount) {
- i = 0;
- }
- j = trap_Cvar_VariableValue("ui_currentMap");
- if (j < 0 || j > MAPS_PER_TIER) {
- j = 0;
- }
-
- Text_Paint(rect->x, rect->y, scale, color, uiInfo.gameTypes[uiInfo.tierList[i].gameTypes[j]].gameType , 0, 0, textStyle);
-}
+ if (!trap_Parse_ReadToken(handle, &token))
+ break;
+
+ // if( Q_stricmp( token, "{" ) ) {
+ // Com_Printf( "Missing { in menu file\n" );
+ // break;
+ //}
+ // if( menuCount == MAX_MENUS ) {
+ // Com_Printf( "Too many menus!\n" );
+ // break;
+ //}
-static const char *UI_AIFromName(const char *name) {
- int j;
- for (j = 0; j < uiInfo.aliasCount; j++) {
- if (Q_stricmp(uiInfo.aliasList[j].name, name) == 0) {
- return uiInfo.aliasList[j].ai;
+ if (token.string[0] == '}')
+ break;
+
+ if (Q_stricmp(token.string, "assetGlobalDef") == 0)
+ {
+ if (Asset_Parse(handle))
+ continue;
+ else
+ break;
+ }
+
+ if (Q_stricmp(token.string, "menudef") == 0)
+ {
+ // start a new menu
+ Menu_New(handle);
+ }
}
- }
- return "James";
+
+ trap_Parse_FreeSource(handle);
}
-static qboolean updateOpponentModel = qtrue;
-static void UI_DrawOpponent(rectDef_t *rect) {
- static playerInfo_t info2;
- char model[MAX_QPATH];
- char headmodel[MAX_QPATH];
- char team[256];
- vec3_t viewangles;
- vec3_t moveangles;
-
- if (updateOpponentModel) {
-
- strcpy(model, UI_Cvar_VariableString("ui_opponentModel"));
- strcpy(headmodel, UI_Cvar_VariableString("ui_opponentModel"));
- team[0] = '\0';
-
- memset( &info2, 0, sizeof(playerInfo_t) );
- viewangles[YAW] = 180 - 10;
- viewangles[PITCH] = 0;
- viewangles[ROLL] = 0;
- VectorClear( moveangles );
- UI_PlayerInfo_SetModel( &info2, model, headmodel, "");
- UI_PlayerInfo_SetInfo( &info2, LEGS_IDLE, TORSO_STAND, viewangles, vec3_origin, WP_MACHINEGUN, qfalse );
- UI_RegisterClientModelname( &info2, model, headmodel, team);
- updateOpponentModel = qfalse;
- }
-
- UI_DrawPlayer( rect->x, rect->y, rect->w, rect->h, &info2, uiInfo.uiDC.realTime / 2);
+qboolean Load_Menu(int handle)
+{
+ pc_token_t token;
+
+ if (!trap_Parse_ReadToken(handle, &token))
+ return qfalse;
-}
+ if (token.string[0] != '{')
+ return qfalse;
-static void UI_NextOpponent( void ) {
- int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName"));
- int j = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
- i++;
- if (i >= uiInfo.teamCount) {
- i = 0;
- }
- if (i == j) {
- i++;
- if ( i >= uiInfo.teamCount) {
- i = 0;
- }
- }
- trap_Cvar_Set( "ui_opponentName", uiInfo.teamList[i].teamName );
-}
+ while (1)
+ {
+ if (!trap_Parse_ReadToken(handle, &token))
+ return qfalse;
-static void UI_PriorOpponent( void ) {
- int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName"));
- int j = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
- i--;
- if (i < 0) {
- i = uiInfo.teamCount - 1;
- }
- if (i == j) {
- i--;
- if ( i < 0) {
- i = uiInfo.teamCount - 1;
- }
- }
- trap_Cvar_Set( "ui_opponentName", uiInfo.teamList[i].teamName );
-}
+ if (token.string[0] == 0)
+ return qfalse;
-static void UI_DrawPlayerLogo(rectDef_t *rect, vec3_t color) {
- int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
+ if (token.string[0] == '}')
+ return qtrue;
- if (uiInfo.teamList[i].teamIcon == -1) {
- uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName);
- uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName));
- uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName));
- }
+ UI_ParseMenu(token.string);
+ }
- trap_R_SetColor( color );
- UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon );
- trap_R_SetColor( NULL );
+ return qfalse;
}
-static void UI_DrawPlayerLogoMetal(rectDef_t *rect, vec3_t color) {
- int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
- if (uiInfo.teamList[i].teamIcon == -1) {
- uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName);
- uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName));
- uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName));
- }
-
- trap_R_SetColor( color );
- UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon_Metal );
- trap_R_SetColor( NULL );
-}
+void UI_LoadMenus(const char *menuFile, qboolean reset)
+{
+ pc_token_t token;
+ int handle;
+ int start;
-static void UI_DrawPlayerLogoName(rectDef_t *rect, vec3_t color) {
- int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
- if (uiInfo.teamList[i].teamIcon == -1) {
- uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName);
- uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName));
- uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName));
- }
-
- trap_R_SetColor( color );
- UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon_Name );
- trap_R_SetColor( NULL );
-}
+ start = trap_Milliseconds();
-static void UI_DrawOpponentLogo(rectDef_t *rect, vec3_t color) {
- int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName"));
- if (uiInfo.teamList[i].teamIcon == -1) {
- uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName);
- uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName));
- uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName));
- }
-
- trap_R_SetColor( color );
- UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon );
- trap_R_SetColor( NULL );
-}
+ handle = trap_Parse_LoadSource(menuFile);
-static void UI_DrawOpponentLogoMetal(rectDef_t *rect, vec3_t color) {
- int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName"));
- if (uiInfo.teamList[i].teamIcon == -1) {
- uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName);
- uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName));
- uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName));
- }
-
- trap_R_SetColor( color );
- UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon_Metal );
- trap_R_SetColor( NULL );
-}
+ if (!handle)
+ trap_Error(va(S_COLOR_RED "menu list '%s' not found, unable to continue!", menuFile));
-static void UI_DrawOpponentLogoName(rectDef_t *rect, vec3_t color) {
- int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName"));
- if (uiInfo.teamList[i].teamIcon == -1) {
- uiInfo.teamList[i].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[i].imageName);
- uiInfo.teamList[i].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[i].imageName));
- uiInfo.teamList[i].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[i].imageName));
- }
-
- trap_R_SetColor( color );
- UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon_Name );
- trap_R_SetColor( NULL );
-}
+ if (reset)
+ Menu_Reset();
-static void UI_DrawAllMapsSelection(rectDef_t *rect, float scale, vec4_t color, int textStyle, qboolean net) {
- int map = (net) ? ui_currentNetMap.integer : ui_currentMap.integer;
- if (map >= 0 && map < uiInfo.mapCount) {
- Text_Paint(rect->x, rect->y, scale, color, uiInfo.mapList[map].mapName, 0, 0, textStyle);
- }
-}
+ while (1)
+ {
+ if (!trap_Parse_ReadToken(handle, &token))
+ break;
-static void UI_DrawPlayerListSelection( rectDef_t *rect, float scale,
- vec4_t color, int textStyle )
-{
- if( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount )
- {
- Text_Paint(rect->x, rect->y, scale, color,
- uiInfo.rawPlayerNames[ uiInfo.playerIndex ],
- 0, 0, textStyle);
- }
+ if (token.string[0] == 0 || token.string[0] == '}')
+ break;
+
+ if (token.string[0] == '}')
+ break;
+
+ if (Q_stricmp(token.string, "loadmenu") == 0)
+ {
+ if (Load_Menu(handle))
+ continue;
+ else
+ break;
+ }
+ }
+
+ Com_Printf("UI menu file '%s' loaded in %d msec\n", menuFile, trap_Milliseconds() - start);
+
+ trap_Parse_FreeSource(handle);
}
-static void UI_DrawTeamListSelection( rectDef_t *rect, float scale,
- vec4_t color, int textStyle )
+void UI_LoadHelp(const char *helpFile)
{
- if( uiInfo.teamIndex >= 0 && uiInfo.teamIndex < uiInfo.myTeamCount )
- {
- Text_Paint(rect->x, rect->y, scale, color,
- uiInfo.rawTeamNames[ uiInfo.teamIndex ],
- 0, 0, textStyle);
- }
-}
+ pc_token_t token;
+ int handle, start;
+ char title[32], buffer[1024];
-static void UI_DrawOpponentName(rectDef_t *rect, float scale, vec4_t color, int textStyle) {
- Text_Paint(rect->x, rect->y, scale, color, UI_Cvar_VariableString("ui_opponentName"), 0, 0, textStyle);
-}
+ start = trap_Milliseconds();
+ handle = trap_Parse_LoadSource(helpFile);
+ if (!handle)
+ {
+ Com_Printf(S_COLOR_YELLOW "WARNING: help file '%s' not found!\n", helpFile);
+ return;
+ }
-static int UI_OwnerDrawWidth(int ownerDraw, float scale) {
- int i, h, value;
- const char *text;
- const char *s = NULL;
-
- switch( ownerDraw )
- {
- case UI_HANDICAP:
- h = Com_Clamp( 5, 100, trap_Cvar_VariableValue("handicap") );
- i = 20 - h / 5;
- s = handicapValues[i];
- break;
- case UI_CLANNAME:
- s = UI_Cvar_VariableString("ui_teamName");
- break;
- case UI_GAMETYPE:
- s = uiInfo.gameTypes[ui_gameType.integer].gameType;
- break;
- case UI_SKILL:
- i = trap_Cvar_VariableValue( "g_spSkill" );
- if (i < 1 || i > numSkillLevels) {
- i = 1;
- }
- s = skillLevels[i-1];
- break;
- case UI_BLUETEAMNAME:
- i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_blueTeam"));
- if (i >= 0 && i < uiInfo.teamCount) {
- s = va("%s: %s", "Blue", uiInfo.teamList[i].teamName);
- }
- break;
- case UI_REDTEAMNAME:
- i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_redTeam"));
- if (i >= 0 && i < uiInfo.teamCount) {
- s = va("%s: %s", "Red", uiInfo.teamList[i].teamName);
- }
- break;
- case UI_BLUETEAM1:
- case UI_BLUETEAM2:
- case UI_BLUETEAM3:
- case UI_BLUETEAM4:
- case UI_BLUETEAM5:
- value = trap_Cvar_VariableValue(va("ui_blueteam%i", ownerDraw-UI_BLUETEAM1 + 1));
- if (value <= 0) {
- text = "Closed";
- } else if (value == 1) {
- text = "Human";
- } else {
- value -= 2;
- if (value >= uiInfo.aliasCount) {
- value = 0;
- }
- text = uiInfo.aliasList[value].name;
- }
- s = va("%i. %s", ownerDraw-UI_BLUETEAM1 + 1, text);
- break;
- case UI_REDTEAM1:
- case UI_REDTEAM2:
- case UI_REDTEAM3:
- case UI_REDTEAM4:
- case UI_REDTEAM5:
- value = trap_Cvar_VariableValue(va("ui_redteam%i", ownerDraw-UI_REDTEAM1 + 1));
- if (value <= 0) {
- text = "Closed";
- } else if (value == 1) {
- text = "Human";
- } else {
- value -= 2;
- if (value >= uiInfo.aliasCount) {
- value = 0;
- }
- text = uiInfo.aliasList[value].name;
- }
- s = va("%i. %s", ownerDraw-UI_REDTEAM1 + 1, text);
- break;
- case UI_NETSOURCE:
- if (ui_netSource.integer < 0 || ui_netSource.integer > uiInfo.numJoinGameTypes) {
- ui_netSource.integer = 0;
- }
- s = va("Source: %s", netSources[ui_netSource.integer]);
- break;
- case UI_NETFILTER:
- if (ui_serverFilterType.integer < 0 || ui_serverFilterType.integer > numServerFilters) {
- ui_serverFilterType.integer = 0;
- }
- s = va("Filter: %s", serverFilters[ui_serverFilterType.integer].description );
- break;
- case UI_TIER:
- break;
- case UI_TIER_MAPNAME:
- break;
- case UI_TIER_GAMETYPE:
- break;
- case UI_ALLMAPS_SELECTION:
- break;
- case UI_PLAYERLIST_SELECTION:
- break;
- case UI_TEAMLIST_SELECTION:
- break;
- case UI_OPPONENT_NAME:
- break;
- case UI_KEYBINDSTATUS:
- if (Display_KeyBindPending()) {
- s = "Waiting for new key... Press ESCAPE to cancel";
- } else {
- s = "Press ENTER or CLICK to change, Press BACKSPACE to clear";
- }
- break;
- case UI_SERVERREFRESHDATE:
- s = UI_Cvar_VariableString(va("ui_lastServerRefresh_%i", ui_netSource.integer));
- break;
- default:
- break;
- }
-
- if (s) {
- return Text_Width(s, scale, 0);
- }
- return 0;
-}
+ if (!trap_Parse_ReadToken(handle, &token) || token.string[0] == 0 || token.string[0] != '{')
+ {
+ Com_Printf(S_COLOR_YELLOW
+ "WARNING: help file '%s' does not start with "
+ "'{'\n",
+ helpFile);
+ return;
+ }
-static void UI_DrawBotName(rectDef_t *rect, float scale, vec4_t color, int textStyle) {
- int value = uiInfo.botIndex;
- const char *text = "";
+ uiInfo.helpCount = 0;
+ title[0] = 0;
+ while (1)
+ {
+ if (!trap_Parse_ReadToken(handle, &token) || token.string[0] == 0 || token.string[0] == '}')
+ break;
- if( value >= UI_GetNumBots( ) )
- value = 0;
+ if (token.string[0] == '{')
+ {
+ buffer[0] = 0;
+ Q_strcat(buffer, sizeof(buffer), title);
+ Q_strcat(buffer, sizeof(buffer), "\n\n");
+ while (trap_Parse_ReadToken(handle, &token) && token.string[0] != 0 && token.string[0] != '}')
+ {
+ Q_strcat(buffer, sizeof(buffer), token.string);
+ }
- text = UI_GetBotNameByNumber( value );
+ uiInfo.helpList[uiInfo.helpCount].text = String_Alloc(title);
+ uiInfo.helpList[uiInfo.helpCount].v.text = String_Alloc(buffer);
+ uiInfo.helpList[uiInfo.helpCount].type = INFOTYPE_TEXT;
+ uiInfo.helpCount++;
+ title[0] = 0;
+ }
+ else
+ Q_strcat(title, sizeof(title), token.string);
+ }
- Text_Paint(rect->x, rect->y, scale, color, text, 0, 0, textStyle);
-}
+ trap_Parse_FreeSource(handle);
-static void UI_DrawBotSkill(rectDef_t *rect, float scale, vec4_t color, int textStyle) {
- if (uiInfo.skillIndex >= 0 && uiInfo.skillIndex < numSkillLevels) {
- Text_Paint(rect->x, rect->y, scale, color, skillLevels[uiInfo.skillIndex], 0, 0, textStyle);
- }
+ Com_Printf("UI help file '%s' loaded in %d msec (%d infopanes)\n", helpFile, trap_Milliseconds() - start,
+ uiInfo.helpCount);
}
-static void UI_DrawRedBlue(rectDef_t *rect, float scale, vec4_t color, int textStyle) {
- Text_Paint(rect->x, rect->y, scale, color, (uiInfo.redBlue == 0) ? "Red" : "Blue", 0, 0, textStyle);
+void UI_Load(void)
+{
+ char lastName[1024];
+ menuDef_t *menu = Menu_GetFocused();
+
+ if (menu && menu->window.name)
+ strcpy(lastName, menu->window.name);
+
+ String_Init();
+
+ UI_LoadMenus("ui/menus.txt", qtrue);
+ UI_LoadMenus("ui/ingame.txt", qfalse);
+ UI_LoadMenus("ui/tremulous.txt", qfalse);
+ UI_LoadHelp("ui/help.txt");
+ Menus_CloseAll();
+ Menus_ActivateByName(lastName);
}
/*
===============
-UI_BuildPlayerList
+UI_GetCurrentAlienStage
===============
*/
-static void UI_BuildPlayerList( void ) {
- uiClientState_t cs;
- int n, count, team, team2, playerTeamNumber;
- char info[MAX_INFO_STRING];
-
- trap_GetClientState( &cs );
- trap_GetConfigString( CS_PLAYERS + cs.clientNum, info, MAX_INFO_STRING );
- uiInfo.playerNumber = cs.clientNum;
- uiInfo.teamLeader = atoi(Info_ValueForKey(info, "tl"));
- team = atoi(Info_ValueForKey(info, "t"));
- trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) );
- count = atoi( Info_ValueForKey( info, "sv_maxclients" ) );
- uiInfo.playerCount = 0;
- uiInfo.myTeamCount = 0;
- uiInfo.myPlayerIndex = 0;
- playerTeamNumber = 0;
- for( n = 0; n < count; n++ ) {
- trap_GetConfigString( CS_PLAYERS + n, info, MAX_INFO_STRING );
-
- if (info[0]) {
- BG_ClientListParse( &uiInfo.ignoreList[ uiInfo.playerCount ],
- Info_ValueForKey( info, "ig" ) );
- Q_strncpyz( uiInfo.rawPlayerNames[uiInfo.playerCount],
- Info_ValueForKey( info, "n" ), MAX_NAME_LENGTH );
- Q_strncpyz( uiInfo.playerNames[uiInfo.playerCount],
- Info_ValueForKey( info, "n" ), MAX_NAME_LENGTH );
- Q_CleanStr( uiInfo.playerNames[uiInfo.playerCount] );
- uiInfo.clientNums[uiInfo.playerCount] = n;
- if( n == uiInfo.playerNumber )
- uiInfo.myPlayerIndex = uiInfo.playerCount;
- uiInfo.playerCount++;
- team2 = atoi(Info_ValueForKey(info, "t"));
- if (team2 == team) {
- Q_strncpyz( uiInfo.rawTeamNames[uiInfo.myTeamCount],
- Info_ValueForKey( info, "n" ), MAX_NAME_LENGTH );
- Q_strncpyz( uiInfo.teamNames[uiInfo.myTeamCount],
- Info_ValueForKey( info, "n" ), MAX_NAME_LENGTH );
- Q_CleanStr( uiInfo.teamNames[uiInfo.myTeamCount] );
- uiInfo.teamClientNums[uiInfo.myTeamCount] = n;
- if (uiInfo.playerNumber == n) {
- playerTeamNumber = uiInfo.myTeamCount;
- }
- uiInfo.myTeamCount++;
- }
- }
- }
+static stage_t UI_GetCurrentAlienStage(void)
+{
+ char buffer[MAX_TOKEN_CHARS];
+ stage_t stage, dummy;
- if (!uiInfo.teamLeader) {
- trap_Cvar_Set("cg_selectedPlayer", va("%d", playerTeamNumber));
- }
+ trap_Cvar_VariableStringBuffer("ui_stages", buffer, sizeof(buffer));
+ sscanf(buffer, "%d %d", (int *)&stage, (int *)&dummy);
- n = trap_Cvar_VariableValue("cg_selectedPlayer");
- if (n < 0 || n > uiInfo.myTeamCount) {
- n = 0;
- }
- if (n < uiInfo.myTeamCount) {
- trap_Cvar_Set("cg_selectedPlayerName", uiInfo.teamNames[n]);
- }
+ return stage;
}
+/*
+===============
+UI_GetCurrentHumanStage
+===============
+*/
+static stage_t UI_GetCurrentHumanStage(void)
+{
+ char buffer[MAX_TOKEN_CHARS];
+ stage_t stage, dummy;
-static void UI_DrawSelectedPlayer(rectDef_t *rect, float scale, vec4_t color, int textStyle) {
- char name[ MAX_NAME_LENGTH ];
- char *s;
-
- if (uiInfo.uiDC.realTime > uiInfo.playerRefresh) {
- uiInfo.playerRefresh = uiInfo.uiDC.realTime + 3000;
- UI_BuildPlayerList();
- }
- if( uiInfo.teamLeader )
- s = UI_Cvar_VariableString("cg_selectedPlayerName");
- else
- s = UI_Cvar_VariableString("name");
- Q_strncpyz( name, s, sizeof( name ) );
- Text_Paint(rect->x, rect->y, scale, color, name, 0, 0, textStyle);
-}
+ trap_Cvar_VariableStringBuffer("ui_stages", buffer, sizeof(buffer));
+ sscanf(buffer, "%d %d", (int *)&dummy, (int *)&stage);
-static void UI_DrawServerRefreshDate(rectDef_t *rect, float scale, vec4_t color, int textStyle) {
- if (uiInfo.serverStatus.refreshActive) {
- vec4_t lowLight, newColor;
- lowLight[0] = 0.8 * color[0];
- lowLight[1] = 0.8 * color[1];
- lowLight[2] = 0.8 * color[2];
- lowLight[3] = 0.8 * color[3];
- LerpColor(color,lowLight,newColor,0.5+0.5*sin(uiInfo.uiDC.realTime / PULSE_DIVISOR));
- Text_Paint(rect->x, rect->y, scale, newColor, va("Getting info for %d servers (ESC to cancel)", trap_LAN_GetServerCount(ui_netSource.integer)), 0, 0, textStyle);
- } else {
- char buff[64];
- Q_strncpyz(buff, UI_Cvar_VariableString(va("ui_lastServerRefresh_%i", ui_netSource.integer)), 64);
- Text_Paint(rect->x, rect->y, scale, color, va("Refresh Time: %s", buff), 0, 0, textStyle);
- }
+ return stage;
}
-static void UI_DrawServerMOTD(rectDef_t *rect, float scale, vec4_t color) {
- if (uiInfo.serverStatus.motdLen) {
- float maxX;
+/*
+===============
+UI_DrawInfoPane
+===============
+*/
+static void UI_DrawInfoPane(menuItem_t *item, rectDef_t *rect, float text_x, float text_y, float scale, int textalign,
+ int textvalign, vec4_t color, int textStyle)
+{
+ int value = 0;
+ const char *s = "";
+ char *string = "";
- if (uiInfo.serverStatus.motdWidth == -1) {
- uiInfo.serverStatus.motdWidth = 0;
- uiInfo.serverStatus.motdPaintX = rect->x + 1;
- uiInfo.serverStatus.motdPaintX2 = -1;
- }
+ int class, credits;
+ char ui_currentClass[MAX_STRING_CHARS];
- if (uiInfo.serverStatus.motdOffset > uiInfo.serverStatus.motdLen) {
- uiInfo.serverStatus.motdOffset = 0;
- uiInfo.serverStatus.motdPaintX = rect->x + 1;
- uiInfo.serverStatus.motdPaintX2 = -1;
- }
+ trap_Cvar_VariableStringBuffer("ui_currentClass", ui_currentClass, MAX_STRING_CHARS);
- if (uiInfo.uiDC.realTime > uiInfo.serverStatus.motdTime) {
- uiInfo.serverStatus.motdTime = uiInfo.uiDC.realTime + 10;
- if (uiInfo.serverStatus.motdPaintX <= rect->x + 2) {
- if (uiInfo.serverStatus.motdOffset < uiInfo.serverStatus.motdLen) {
- uiInfo.serverStatus.motdPaintX += Text_Width(&uiInfo.serverStatus.motd[uiInfo.serverStatus.motdOffset], scale, 1) - 1;
- uiInfo.serverStatus.motdOffset++;
- } else {
- uiInfo.serverStatus.motdOffset = 0;
- if (uiInfo.serverStatus.motdPaintX2 >= 0) {
- uiInfo.serverStatus.motdPaintX = uiInfo.serverStatus.motdPaintX2;
- } else {
- uiInfo.serverStatus.motdPaintX = rect->x + rect->w - 2;
- }
- uiInfo.serverStatus.motdPaintX2 = -1;
- }
- } else {
- //serverStatus.motdPaintX--;
- uiInfo.serverStatus.motdPaintX -= 2;
- if (uiInfo.serverStatus.motdPaintX2 >= 0) {
- //serverStatus.motdPaintX2--;
- uiInfo.serverStatus.motdPaintX2 -= 2;
- }
- }
- }
+ sscanf(ui_currentClass, "%d %d", &class, &credits);
- maxX = rect->x + rect->w - 2;
- Text_Paint_Limit(&maxX, uiInfo.serverStatus.motdPaintX, rect->y + rect->h - 3, scale, color, &uiInfo.serverStatus.motd[uiInfo.serverStatus.motdOffset], 0, 0);
- if (uiInfo.serverStatus.motdPaintX2 >= 0) {
- float maxX2 = rect->x + rect->w - 2;
- Text_Paint_Limit(&maxX2, uiInfo.serverStatus.motdPaintX2, rect->y + rect->h - 3, scale, color, uiInfo.serverStatus.motd, 0, uiInfo.serverStatus.motdOffset);
- }
- if (uiInfo.serverStatus.motdOffset && maxX > 0) {
- // if we have an offset ( we are skipping the first part of the string ) and we fit the string
- if (uiInfo.serverStatus.motdPaintX2 == -1) {
- uiInfo.serverStatus.motdPaintX2 = rect->x + rect->w - 2;
- }
- } else {
- uiInfo.serverStatus.motdPaintX2 = -1;
- }
+ switch (item->type)
+ {
+ case INFOTYPE_TEXT:
+ case INFOTYPE_VOICECMD:
+ s = item->v.text;
+ break;
- }
-}
+ case INFOTYPE_CLASS:
+ value = (BG_ClassCanEvolveFromTo(class, item->v.pclass, credits, UI_GetCurrentAlienStage(), 0) +
+ ALIEN_CREDITS_PER_KILL - 1) /
+ ALIEN_CREDITS_PER_KILL;
-static void UI_DrawKeyBindStatus(rectDef_t *rect, float scale, vec4_t color, int textStyle) {
-// int ofs = 0; TTimo: unused
- if (Display_KeyBindPending()) {
- Text_Paint(rect->x, rect->y, scale, color, "Waiting for new key... Press ESCAPE to cancel", 0, 0, textStyle);
- } else {
- Text_Paint(rect->x, rect->y, scale, color, "Press ENTER or CLICK to change, Press BACKSPACE to clear", 0, 0, textStyle);
- }
-}
+ if (value < 1)
+ {
+ s = va("%s\n\n%s", BG_ClassConfig(item->v.pclass)->humanName, BG_Class(item->v.pclass)->info);
+ }
+ else
+ {
+ s = va("%s\n\n%s\n\nFrags: %d", BG_ClassConfig(item->v.pclass)->humanName,
+ BG_Class(item->v.pclass)->info, value);
+ }
-static void UI_DrawGLInfo(rectDef_t *rect, float scale, vec4_t color, int textStyle) {
- char * eptr;
- char buff[1024];
- const char *lines[64];
- int y, numLines, i;
+ break;
- Text_Paint(rect->x + 2, rect->y, scale, color, va("VENDOR: %s", uiInfo.uiDC.glconfig.vendor_string), 0, 30, textStyle);
- Text_Paint(rect->x + 2, rect->y + 15, scale, color, va("VERSION: %s: %s", uiInfo.uiDC.glconfig.version_string,uiInfo.uiDC.glconfig.renderer_string), 0, 30, textStyle);
- Text_Paint(rect->x + 2, rect->y + 30, scale, color, va ("PIXELFORMAT: color(%d-bits) Z(%d-bits) stencil(%d-bits)", uiInfo.uiDC.glconfig.colorBits, uiInfo.uiDC.glconfig.depthBits, uiInfo.uiDC.glconfig.stencilBits), 0, 30, textStyle);
+ case INFOTYPE_WEAPON:
+ value = BG_Weapon(item->v.weapon)->price;
- // build null terminated extension strings
- // TTimo: https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=399
- // in TA this was not directly crashing, but displaying a nasty broken shader right in the middle
- // brought down the string size to 1024, there's not much that can be shown on the screen anyway
- Q_strncpyz(buff, uiInfo.uiDC.glconfig.extensions_string, 1024);
- eptr = buff;
- y = rect->y + 45;
- numLines = 0;
- while ( y < rect->y + rect->h && *eptr )
- {
- while ( *eptr && *eptr == ' ' )
- *eptr++ = '\0';
+ if (value == 0)
+ {
+ s = va(
+ "%s\n\n%s\n\nCredits: Free", BG_Weapon(item->v.weapon)->humanName, BG_Weapon(item->v.weapon)->info);
+ }
+ else
+ {
+ s = va("%s\n\n%s\n\nCredits: %d", BG_Weapon(item->v.weapon)->humanName, BG_Weapon(item->v.weapon)->info,
+ value);
+ }
- // track start of valid string
- if (*eptr && *eptr != ' ') {
- lines[numLines++] = eptr;
- }
+ break;
- while ( *eptr && *eptr != ' ' )
- eptr++;
- }
+ case INFOTYPE_UPGRADE:
+ value = BG_Upgrade(item->v.upgrade)->price;
- i = 0;
- while (i < numLines) {
- Text_Paint(rect->x + 2, y, scale, color, lines[i++], 0, 20, textStyle);
- if (i < numLines) {
- Text_Paint(rect->x + rect->w / 2, y, scale, color, lines[i++], 0, 20, textStyle);
- }
- y += 10;
- if (y > rect->y + rect->h - 11) {
- break;
- }
- }
+ if (value == 0)
+ {
+ s = va("%s\n\n%s\n\nCredits: Free", BG_Upgrade(item->v.upgrade)->humanName,
+ BG_Upgrade(item->v.upgrade)->info);
+ }
+ else
+ {
+ s = va("%s\n\n%s\n\nCredits: %d", BG_Upgrade(item->v.upgrade)->humanName,
+ BG_Upgrade(item->v.upgrade)->info, value);
+ }
+ break;
-}
+ case INFOTYPE_BUILDABLE:
+ value = BG_Buildable(item->v.buildable)->buildPoints;
-// FIXME: table drive
-//
-static void UI_OwnerDraw( float x, float y, float w, float h,
- float text_x, float text_y, int ownerDraw,
- int ownerDrawFlags, int align, float special,
- float scale, vec4_t color, qhandle_t shader, int textStyle )
-{
- rectDef_t rect;
- tremInfoPane_t *pane = NULL;
-
- rect.x = x + text_x;
- rect.y = y + text_y;
- rect.w = w;
- rect.h = h;
-
- switch( ownerDraw )
- {
- case UI_TEAMINFOPANE:
- if( ( pane = uiInfo.tremTeamList[ uiInfo.tremTeamIndex ].infopane ) )
- UI_DrawInfoPane( pane, &rect, text_x, text_y, scale, color, textStyle );
- break;
-
- case UI_ACLASSINFOPANE:
- if( ( pane = uiInfo.tremAlienClassList[ uiInfo.tremAlienClassIndex ].infopane ) )
- UI_DrawInfoPane( pane, &rect, text_x, text_y, scale, color, textStyle );
- break;
-
- case UI_AUPGRADEINFOPANE:
- if( ( pane = uiInfo.tremAlienUpgradeList[ uiInfo.tremAlienUpgradeIndex ].infopane ) )
- UI_DrawInfoPane( pane, &rect, text_x, text_y, scale, color, textStyle );
- break;
-
- case UI_HITEMINFOPANE:
- if( ( pane = uiInfo.tremHumanItemList[ uiInfo.tremHumanItemIndex ].infopane ) )
- UI_DrawInfoPane( pane, &rect, text_x, text_y, scale, color, textStyle );
- break;
-
- case UI_HBUYINFOPANE:
- if( ( pane = uiInfo.tremHumanArmouryBuyList[ uiInfo.tremHumanArmouryBuyIndex ].infopane ) )
- UI_DrawInfoPane( pane, &rect, text_x, text_y, scale, color, textStyle );
- break;
-
- case UI_HSELLINFOPANE:
- if( ( pane = uiInfo.tremHumanArmourySellList[ uiInfo.tremHumanArmourySellIndex ].infopane ) )
- UI_DrawInfoPane( pane, &rect, text_x, text_y, scale, color, textStyle );
- break;
-
- case UI_ABUILDINFOPANE:
- if( ( pane = uiInfo.tremAlienBuildList[ uiInfo.tremAlienBuildIndex ].infopane ) )
- UI_DrawInfoPane( pane, &rect, text_x, text_y, scale, color, textStyle );
- break;
-
- case UI_HBUILDINFOPANE:
- if( ( pane = uiInfo.tremHumanBuildList[ uiInfo.tremHumanBuildIndex ].infopane ) )
- UI_DrawInfoPane( pane, &rect, text_x, text_y, scale, color, textStyle );
- break;
-
- case UI_HANDICAP:
- UI_DrawHandicap(&rect, scale, color, textStyle);
- break;
- case UI_PLAYERMODEL:
- UI_DrawPlayerModel(&rect);
- break;
- case UI_CLANNAME:
- UI_DrawClanName(&rect, scale, color, textStyle);
- break;
- case UI_CLANLOGO:
- UI_DrawClanLogo(&rect, scale, color);
- break;
- case UI_CLANCINEMATIC:
- UI_DrawClanCinematic(&rect, scale, color);
- break;
- case UI_PREVIEWCINEMATIC:
- UI_DrawPreviewCinematic(&rect, scale, color);
- break;
- case UI_GAMETYPE:
- UI_DrawGameType(&rect, scale, color, textStyle);
- break;
- case UI_NETGAMETYPE:
- UI_DrawNetGameType(&rect, scale, color, textStyle);
- break;
- case UI_JOINGAMETYPE:
- UI_DrawJoinGameType(&rect, scale, color, textStyle);
- break;
- case UI_MAPPREVIEW:
- UI_DrawMapPreview(&rect, scale, color, qtrue);
- break;
- case UI_MAP_TIMETOBEAT:
- UI_DrawMapTimeToBeat(&rect, scale, color, textStyle);
- break;
- case UI_MAPCINEMATIC:
- UI_DrawMapCinematic(&rect, scale, color, qfalse);
- break;
- case UI_STARTMAPCINEMATIC:
- UI_DrawMapCinematic(&rect, scale, color, qtrue);
- break;
- case UI_SKILL:
- UI_DrawSkill(&rect, scale, color, textStyle);
- break;
- case UI_BLUETEAMNAME:
- UI_DrawTeamName(&rect, scale, color, qtrue, textStyle);
- break;
- case UI_REDTEAMNAME:
- UI_DrawTeamName(&rect, scale, color, qfalse, textStyle);
- break;
- case UI_BLUETEAM1:
- case UI_BLUETEAM2:
- case UI_BLUETEAM3:
- case UI_BLUETEAM4:
- case UI_BLUETEAM5:
- UI_DrawTeamMember(&rect, scale, color, qtrue, ownerDraw - UI_BLUETEAM1 + 1, textStyle);
- break;
- case UI_REDTEAM1:
- case UI_REDTEAM2:
- case UI_REDTEAM3:
- case UI_REDTEAM4:
- case UI_REDTEAM5:
- UI_DrawTeamMember(&rect, scale, color, qfalse, ownerDraw - UI_REDTEAM1 + 1, textStyle);
- break;
- case UI_NETSOURCE:
- UI_DrawNetSource(&rect, scale, color, textStyle);
- break;
- case UI_NETMAPPREVIEW:
- UI_DrawNetMapPreview(&rect, scale, color);
- break;
- case UI_NETMAPCINEMATIC:
- UI_DrawNetMapCinematic(&rect, scale, color);
- break;
- case UI_NETFILTER:
- UI_DrawNetFilter(&rect, scale, color, textStyle);
- break;
- case UI_TIER:
- UI_DrawTier(&rect, scale, color, textStyle);
- break;
- case UI_OPPONENTMODEL:
- UI_DrawOpponent(&rect);
- break;
- case UI_TIERMAP1:
- UI_DrawTierMap(&rect, 0);
- break;
- case UI_TIERMAP2:
- UI_DrawTierMap(&rect, 1);
- break;
- case UI_TIERMAP3:
- UI_DrawTierMap(&rect, 2);
- break;
- case UI_PLAYERLOGO:
- UI_DrawPlayerLogo(&rect, color);
- break;
- case UI_PLAYERLOGO_METAL:
- UI_DrawPlayerLogoMetal(&rect, color);
- break;
- case UI_PLAYERLOGO_NAME:
- UI_DrawPlayerLogoName(&rect, color);
- break;
- case UI_OPPONENTLOGO:
- UI_DrawOpponentLogo(&rect, color);
- break;
- case UI_OPPONENTLOGO_METAL:
- UI_DrawOpponentLogoMetal(&rect, color);
- break;
- case UI_OPPONENTLOGO_NAME:
- UI_DrawOpponentLogoName(&rect, color);
- break;
- case UI_TIER_MAPNAME:
- UI_DrawTierMapName(&rect, scale, color, textStyle);
- break;
- case UI_TIER_GAMETYPE:
- UI_DrawTierGameType(&rect, scale, color, textStyle);
- break;
- case UI_ALLMAPS_SELECTION:
- UI_DrawAllMapsSelection(&rect, scale, color, textStyle, qtrue);
- break;
- case UI_MAPS_SELECTION:
- UI_DrawAllMapsSelection(&rect, scale, color, textStyle, qfalse);
- break;
- case UI_PLAYERLIST_SELECTION:
- UI_DrawPlayerListSelection(&rect, scale, color, textStyle);
- break;
- case UI_TEAMLIST_SELECTION:
- UI_DrawTeamListSelection(&rect, scale, color, textStyle);
- break;
- case UI_OPPONENT_NAME:
- UI_DrawOpponentName(&rect, scale, color, textStyle);
- break;
- case UI_BOTNAME:
- UI_DrawBotName(&rect, scale, color, textStyle);
- break;
- case UI_BOTSKILL:
- UI_DrawBotSkill(&rect, scale, color, textStyle);
- break;
- case UI_REDBLUE:
- UI_DrawRedBlue(&rect, scale, color, textStyle);
- break;
- case UI_SELECTEDPLAYER:
- UI_DrawSelectedPlayer(&rect, scale, color, textStyle);
- break;
- case UI_SERVERREFRESHDATE:
- UI_DrawServerRefreshDate(&rect, scale, color, textStyle);
- break;
- case UI_SERVERMOTD:
- UI_DrawServerMOTD(&rect, scale, color);
- break;
- case UI_GLINFO:
- UI_DrawGLInfo(&rect,scale, color, textStyle);
- break;
- case UI_KEYBINDSTATUS:
- UI_DrawKeyBindStatus(&rect,scale, color, textStyle);
- break;
- default:
- break;
- }
+ switch (BG_Buildable(item->v.buildable)->team)
+ {
+ case TEAM_ALIENS:
+ string = "Sentience";
+ break;
-}
+ case TEAM_HUMANS:
+ string = "Power";
+ break;
-static qboolean UI_OwnerDrawVisible(int flags) {
- qboolean vis = qtrue;
- uiClientState_t cs;
- pTeam_t team;
- char info[ MAX_INFO_STRING ];
+ default:
+ break;
+ }
- trap_GetClientState( &cs );
- trap_GetConfigString( CS_PLAYERS + cs.clientNum, info, MAX_INFO_STRING );
- team = atoi( Info_ValueForKey( info, "t" ) );
+ if (value == 0)
+ {
+ s = va("%s\n\n%s", BG_Buildable(item->v.buildable)->humanName, BG_Buildable(item->v.buildable)->info);
+ }
+ else
+ {
+ s = va("%s\n\n%s\n\n%s: %d", BG_Buildable(item->v.buildable)->humanName,
+ BG_Buildable(item->v.buildable)->info, string, value);
+ }
+ break;
+ }
- while (flags) {
+ UI_DrawTextBlock(rect, text_x, text_y, color, scale, textalign, textvalign, textStyle, s);
+}
- if( flags & UI_SHOW_NOTSPECTATING )
+static void UI_DrawServerMapPreview(rectDef_t *rect, float scale, vec4_t color)
+{
+ if (uiInfo.serverStatus.currentServerCinematic >= 0)
{
- if( team == PTE_NONE )
- vis = qfalse;
-
- flags &= ~UI_SHOW_NOTSPECTATING;
+ trap_CIN_RunCinematic(uiInfo.serverStatus.currentServerCinematic);
+ trap_CIN_SetExtents(uiInfo.serverStatus.currentServerCinematic, rect->x, rect->y, rect->w, rect->h);
+ trap_CIN_DrawCinematic(uiInfo.serverStatus.currentServerCinematic);
}
+ else if (uiInfo.serverStatus.currentServerPreview > 0)
+ UI_DrawHandlePic(rect->x, rect->y, rect->w, rect->h, uiInfo.serverStatus.currentServerPreview);
+ else
+ UI_DrawHandlePic(rect->x, rect->y, rect->w, rect->h, trap_R_RegisterShaderNoMip("gfx/2d/load_screen"));
+}
- if( flags & UI_SHOW_VOTEACTIVE )
- {
- if( !trap_Cvar_VariableValue( "ui_voteActive" ) )
- vis = qfalse;
-
- flags &= ~UI_SHOW_VOTEACTIVE;
- }
+static void UI_DrawSelectedMapPreview(rectDef_t *rect, float scale, vec4_t color)
+{
+ int map = ui_selectedMap.integer;
- if( flags & UI_SHOW_CANVOTE )
+ if (map < 0 || map > uiInfo.mapCount)
{
- if( trap_Cvar_VariableValue( "ui_voteActive" ) )
- vis = qfalse;
-
- flags &= ~UI_SHOW_CANVOTE;
+ ui_selectedMap.integer = 0;
+ trap_Cvar_Set("ui_selectedMap", "0");
+ map = 0;
}
- if( flags & UI_SHOW_TEAMVOTEACTIVE )
+ if (uiInfo.mapList[map].cinematic >= -1)
{
- if( team == PTE_ALIENS )
- {
- if( !trap_Cvar_VariableValue( "ui_alienTeamVoteActive" ) )
- vis = qfalse;
- }
- else if( team == PTE_HUMANS )
- {
- if( !trap_Cvar_VariableValue( "ui_humanTeamVoteActive" ) )
- vis = qfalse;
- }
+ if (uiInfo.mapList[map].cinematic == -1)
+ uiInfo.mapList[map].cinematic = trap_CIN_PlayCinematic(
+ va("%s.roq", uiInfo.mapList[map].mapLoadName), 0, 0, 0, 0, (CIN_loop | CIN_silent));
- flags &= ~UI_SHOW_TEAMVOTEACTIVE;
+ if (uiInfo.mapList[map].cinematic >= 0)
+ {
+ trap_CIN_RunCinematic(uiInfo.mapList[map].cinematic);
+ trap_CIN_SetExtents(uiInfo.mapList[map].cinematic, rect->x, rect->y, rect->w, rect->h);
+ trap_CIN_DrawCinematic(uiInfo.mapList[map].cinematic);
+ }
+ else
+ uiInfo.mapList[map].cinematic = -2;
}
-
- if( flags & UI_SHOW_CANTEAMVOTE )
+ else
{
- if( team == PTE_ALIENS )
- {
- if( trap_Cvar_VariableValue( "ui_alienTeamVoteActive" ) )
- vis = qfalse;
- }
- else if( team == PTE_HUMANS )
- {
- if( trap_Cvar_VariableValue( "ui_humanTeamVoteActive" ) )
- vis = qfalse;
- }
-
- flags &= ~UI_SHOW_CANTEAMVOTE;
- }
+ if (uiInfo.mapList[map].levelShot == -1)
+ uiInfo.mapList[map].levelShot = trap_R_RegisterShaderNoMip(uiInfo.mapList[map].imageName);
- if (flags & UI_SHOW_LEADER) {
- // these need to show when this client can give orders to a player or a group
- if (!uiInfo.teamLeader) {
- vis = qfalse;
- } else {
- // if showing yourself
- if (ui_selectedPlayer.integer < uiInfo.myTeamCount && uiInfo.teamClientNums[ui_selectedPlayer.integer] == uiInfo.playerNumber) {
- vis = qfalse;
- }
- }
- flags &= ~UI_SHOW_LEADER;
- }
- if (flags & UI_SHOW_NOTLEADER) {
- // these need to show when this client is assigning their own status or they are NOT the leader
- if (uiInfo.teamLeader) {
- // if not showing yourself
- if (!(ui_selectedPlayer.integer < uiInfo.myTeamCount && uiInfo.teamClientNums[ui_selectedPlayer.integer] == uiInfo.playerNumber)) {
- vis = qfalse;
- }
- // these need to show when this client can give orders to a player or a group
- }
- flags &= ~UI_SHOW_NOTLEADER;
- }
- if (flags & UI_SHOW_FAVORITESERVERS) {
- // this assumes you only put this type of display flag on something showing in the proper context
- if (ui_netSource.integer != AS_FAVORITES) {
- vis = qfalse;
- }
- flags &= ~UI_SHOW_FAVORITESERVERS;
- }
- if (flags & UI_SHOW_NOTFAVORITESERVERS) {
- // this assumes you only put this type of display flag on something showing in the proper context
- if (ui_netSource.integer == AS_FAVORITES) {
- vis = qfalse;
- }
- flags &= ~UI_SHOW_NOTFAVORITESERVERS;
- }
- if (flags & UI_SHOW_NEWHIGHSCORE) {
- if (uiInfo.newHighScoreTime < uiInfo.uiDC.realTime) {
- vis = qfalse;
- } else {
- if (uiInfo.soundHighScore) {
- if (trap_Cvar_VariableValue("sv_killserver") == 0) {
- // wait on server to go down before playing sound
- trap_S_StartLocalSound(uiInfo.newHighScoreSound, CHAN_ANNOUNCER);
- uiInfo.soundHighScore = qfalse;
- }
- }
- }
- flags &= ~UI_SHOW_NEWHIGHSCORE;
- }
- if (flags & UI_SHOW_NEWBESTTIME) {
- if (uiInfo.newBestTime < uiInfo.uiDC.realTime) {
- vis = qfalse;
- }
- flags &= ~UI_SHOW_NEWBESTTIME;
- }
- if (flags & UI_SHOW_DEMOAVAILABLE) {
- if (!uiInfo.demoAvailable) {
- vis = qfalse;
- }
- flags &= ~UI_SHOW_DEMOAVAILABLE;
- } else {
- flags = 0;
+ if (uiInfo.mapList[map].levelShot > 0)
+ UI_DrawHandlePic(rect->x, rect->y, rect->w, rect->h, uiInfo.mapList[map].levelShot);
+ else
+ UI_DrawHandlePic(rect->x, rect->y, rect->w, rect->h, trap_R_RegisterShaderNoMip("gfx/2d/load_screen"));
}
- }
- return vis;
}
-static qboolean UI_Handicap_HandleKey(int flags, float *special, int key) {
- if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
- int h;
- h = Com_Clamp( 5, 100, trap_Cvar_VariableValue("handicap") );
- if (key == K_MOUSE2) {
- h -= 5;
- } else {
- h += 5;
- }
- if (h > 100) {
- h = 5;
- } else if (h < 0) {
- h = 100;
- }
- trap_Cvar_Set( "handicap", va( "%i", h) );
- return qtrue;
- }
- return qfalse;
-}
+static void UI_DrawSelectedMapName(rectDef_t *rect, float scale, vec4_t color, int textStyle)
+{
+ int map = ui_selectedMap.integer;
-static qboolean UI_ClanName_HandleKey(int flags, float *special, int key) {
- if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
- int i;
- i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
- if (uiInfo.teamList[i].cinematic >= 0) {
- trap_CIN_StopCinematic(uiInfo.teamList[i].cinematic);
- uiInfo.teamList[i].cinematic = -1;
- }
- if (key == K_MOUSE2) {
- i--;
- } else {
- i++;
- }
- if (i >= uiInfo.teamCount) {
- i = 0;
- } else if (i < 0) {
- i = uiInfo.teamCount - 1;
- }
- trap_Cvar_Set( "ui_teamName", uiInfo.teamList[i].teamName);
- UI_HeadCountByTeam();
- UI_FeederSelection(FEEDER_HEADS, 0);
- updateModel = qtrue;
- return qtrue;
- }
- return qfalse;
+ if (map >= 0 && map < uiInfo.mapCount)
+ UI_Text_Paint(rect->x, rect->y, scale, color, uiInfo.mapList[map].mapName, 0, 0, textStyle);
}
-static qboolean UI_GameType_HandleKey(int flags, float *special, int key, qboolean resetMap) {
- if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
- int oldCount = UI_MapCountByGameType(qtrue);
-
- // hard coded mess here
- if (key == K_MOUSE2) {
- ui_gameType.integer--;
- if (ui_gameType.integer == 2) {
- ui_gameType.integer = 1;
- } else if (ui_gameType.integer < 2) {
- ui_gameType.integer = uiInfo.numGameTypes - 1;
- }
- } else {
- ui_gameType.integer++;
- if (ui_gameType.integer >= uiInfo.numGameTypes) {
- ui_gameType.integer = 1;
- } else if (ui_gameType.integer == 2) {
- ui_gameType.integer = 3;
- }
- }
+static const char *UI_OwnerDrawText(int ownerDraw)
+{
+ const char *s = NULL;
- trap_Cvar_Set("ui_Q3Model", "0");
+ switch (ownerDraw)
+ {
+ case UI_NETSOURCE:
+ if (ui_netSource.integer < 0 || ui_netSource.integer >= numNetSources)
+ ui_netSource.integer = 0;
- trap_Cvar_Set("ui_gameType", va("%d", ui_gameType.integer));
- UI_SetCapFragLimits(qtrue);
- UI_LoadBestScores(uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum);
- if (resetMap && oldCount != UI_MapCountByGameType(qtrue)) {
- trap_Cvar_Set( "ui_currentMap", "0");
- Menu_SetFeederSelection(NULL, FEEDER_MAPS, 0, NULL);
- }
- return qtrue;
- }
- return qfalse;
-}
+ s = netSources[ui_netSource.integer];
+ break;
-static qboolean UI_NetGameType_HandleKey(int flags, float *special, int key) {
- if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
+ case UI_KEYBINDSTATUS:
+ if (Display_KeyBindPending())
+ s = "Waiting for new key... Press ESCAPE to cancel";
+ else
+ s = "Press ENTER or CLICK to change, Press BACKSPACE to clear";
- if (key == K_MOUSE2) {
- ui_netGameType.integer--;
- } else {
- ui_netGameType.integer++;
- }
+ break;
- if (ui_netGameType.integer < 0) {
- ui_netGameType.integer = uiInfo.numGameTypes - 1;
- } else if (ui_netGameType.integer >= uiInfo.numGameTypes) {
- ui_netGameType.integer = 0;
- }
+ case UI_SERVERREFRESHDATE:
+ if (uiInfo.serverStatus.refreshActive)
+ {
+#define MAX_DOTS 5
+ int numServers = trap_LAN_GetServerCount(ui_netSource.integer);
+ int numDots = (uiInfo.uiDC.realTime / 500) % (MAX_DOTS + 1);
+ char dots[MAX_DOTS + 1];
+ int i;
- trap_Cvar_Set( "ui_netGameType", va("%d", ui_netGameType.integer));
- trap_Cvar_Set( "ui_actualnetGameType", va("%d", uiInfo.gameTypes[ui_netGameType.integer].gtEnum));
- trap_Cvar_Set( "ui_currentNetMap", "0");
- UI_MapCountByGameType(qfalse);
- Menu_SetFeederSelection(NULL, FEEDER_ALLMAPS, 0, NULL);
- return qtrue;
- }
- return qfalse;
-}
+ for (i = 0; i < numDots; i++)
+ dots[i] = '.';
-static qboolean UI_JoinGameType_HandleKey(int flags, float *special, int key) {
- if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
+ dots[i] = '\0';
- if (key == K_MOUSE2) {
- ui_joinGameType.integer--;
- } else {
- ui_joinGameType.integer++;
- }
+ s = numServers < 0 ? va("Waiting for response%s", dots)
+ : va("Getting info for %d servers (ESC to cancel)%s", numServers, dots);
+ }
+ else
+ s = va("Refresh Time: %s", UI_Cvar_VariableString(va("ui_lastServerRefresh_%i", ui_netSource.integer)));
- if (ui_joinGameType.integer < 0) {
- ui_joinGameType.integer = uiInfo.numJoinGameTypes - 1;
- } else if (ui_joinGameType.integer >= uiInfo.numJoinGameTypes) {
- ui_joinGameType.integer = 0;
+ break;
+
+ case UI_SERVERMOTD:
+ s = uiInfo.serverStatus.motd;
+ break;
+
+ default:
+ break;
}
- trap_Cvar_Set( "ui_joinGameType", va("%d", ui_joinGameType.integer));
- UI_BuildServerDisplayList(qtrue);
- return qtrue;
- }
- return qfalse;
+ return s;
}
+static int UI_OwnerDrawWidth(int ownerDraw, float scale)
+{
+ const char *s = NULL;
+ switch (ownerDraw)
+ {
+ case UI_NETSOURCE:
+ case UI_KEYBINDSTATUS:
+ case UI_SERVERREFRESHDATE:
+ case UI_SERVERMOTD:
+ s = UI_OwnerDrawText(ownerDraw);
+ break;
-static qboolean UI_Skill_HandleKey(int flags, float *special, int key) {
- if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
- int i = trap_Cvar_VariableValue( "g_spSkill" );
-
- if (key == K_MOUSE2) {
- i--;
- } else {
- i++;
+ default:
+ break;
}
- if (i < 1) {
- i = numSkillLevels;
- } else if (i > numSkillLevels) {
- i = 1;
- }
+ if (s)
+ return UI_Text_Width(s, scale);
- trap_Cvar_Set("g_spSkill", va("%i", i));
- return qtrue;
- }
- return qfalse;
+ return 0;
}
-static qboolean UI_TeamName_HandleKey(int flags, float *special, int key, qboolean blue) {
- if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
- int i;
- i = UI_TeamIndexFromName(UI_Cvar_VariableString((blue) ? "ui_blueTeam" : "ui_redTeam"));
+/*
+===============
+UI_BuildPlayerList
+===============
+*/
+static void UI_BuildPlayerList(void)
+{
+ uiClientState_t cs;
+ int n, count, team, team2;
+ char info[MAX_INFO_STRING];
+
+ trap_GetClientState(&cs);
+ trap_GetConfigString(CS_PLAYERS + cs.clientNum, info, MAX_INFO_STRING);
+ uiInfo.playerNumber = cs.clientNum;
+ team = atoi(Info_ValueForKey(info, "t"));
+ trap_GetConfigString(CS_SERVERINFO, info, sizeof(info));
+ count = atoi(Info_ValueForKey(info, "sv_maxclients"));
+ uiInfo.playerCount = 0;
+ uiInfo.myTeamCount = 0;
+ uiInfo.myPlayerIndex = 0;
+
+ for (n = 0; n < count; n++)
+ {
+ trap_GetConfigString(CS_PLAYERS + n, info, MAX_INFO_STRING);
- if (key == K_MOUSE2) {
- i--;
- } else {
- i++;
- }
+ if (info[0])
+ {
+ Com_ClientListParse(&uiInfo.ignoreList[uiInfo.playerCount], Info_ValueForKey(info, "ig"));
+ Q_strncpyz(uiInfo.rawPlayerNames[uiInfo.playerCount], Info_ValueForKey(info, "n"), MAX_NAME_LENGTH);
+ Q_strncpyz(uiInfo.playerNames[uiInfo.playerCount], Info_ValueForKey(info, "n"), MAX_NAME_LENGTH);
+ Q_CleanStr(uiInfo.playerNames[uiInfo.playerCount]);
+ uiInfo.clientNums[uiInfo.playerCount] = n;
- if (i >= uiInfo.teamCount) {
- i = 0;
- } else if (i < 0) {
- i = uiInfo.teamCount - 1;
- }
+ if (n == uiInfo.playerNumber)
+ uiInfo.myPlayerIndex = uiInfo.playerCount;
- trap_Cvar_Set( (blue) ? "ui_blueTeam" : "ui_redTeam", uiInfo.teamList[i].teamName);
+ uiInfo.playerCount++;
- return qtrue;
- }
- return qfalse;
-}
+ team2 = atoi(Info_ValueForKey(info, "t"));
-static qboolean UI_TeamMember_HandleKey(int flags, float *special, int key, qboolean blue, int num) {
- if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
- // 0 - None
- // 1 - Human
- // 2..NumCharacters - Bot
- char *cvar = va(blue ? "ui_blueteam%i" : "ui_redteam%i", num);
- int value = trap_Cvar_VariableValue(cvar);
+ if (team2 == team)
+ {
+ Q_strncpyz(uiInfo.rawTeamNames[uiInfo.myTeamCount], Info_ValueForKey(info, "n"), MAX_NAME_LENGTH);
+ Q_strncpyz(uiInfo.teamNames[uiInfo.myTeamCount], Info_ValueForKey(info, "n"), MAX_NAME_LENGTH);
+ Q_CleanStr(uiInfo.teamNames[uiInfo.myTeamCount]);
+ uiInfo.teamClientNums[uiInfo.myTeamCount] = n;
- if (key == K_MOUSE2) {
- value--;
- } else {
- value++;
+ uiInfo.myTeamCount++;
+ }
+ }
}
+}
- if( value >= UI_GetNumBots( ) + 2 )
- value = 0;
- else if( value < 0 )
- value = UI_GetNumBots( ) + 2 - 1;
+static void UI_DrawGLInfo(rectDef_t *rect, float scale, int textalign, int textvalign, vec4_t color, int textStyle,
+ float text_x, float text_y)
+{
+ char buffer[4096];
- trap_Cvar_Set(cvar, va("%i", value));
- return qtrue;
- }
- return qfalse;
+ Com_sprintf(buffer, sizeof(buffer),
+ "VENDOR: %s\nVERSION: %s\n"
+ "PIXELFORMAT: color(%d-bits) Z(%d-bits) stencil(%d-bits)\n%s",
+ uiInfo.uiDC.glconfig.vendor_string, uiInfo.uiDC.glconfig.renderer_string, uiInfo.uiDC.glconfig.colorBits,
+ uiInfo.uiDC.glconfig.depthBits, uiInfo.uiDC.glconfig.stencilBits, uiInfo.uiDC.glconfig.extensions_string);
+
+ UI_DrawTextBlock(rect, text_x, text_y, color, scale, textalign, textvalign, textStyle, buffer);
}
-static qboolean UI_NetSource_HandleKey(int flags, float *special, int key) {
- if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
+// FIXME: table drive
+//
+static void UI_OwnerDraw(float x, float y, float w, float h, float text_x, float text_y, int ownerDraw,
+ int ownerDrawFlags, int align, int textalign, int textvalign, float borderSize, float scale, vec4_t foreColor,
+ vec4_t backColor, qhandle_t shader, int textStyle)
+{
+ rectDef_t rect;
- if (key == K_MOUSE2) {
- ui_netSource.integer--;
- if (ui_netSource.integer == AS_MPLAYER)
- ui_netSource.integer--;
- } else {
- ui_netSource.integer++;
- if (ui_netSource.integer == AS_MPLAYER)
- ui_netSource.integer++;
- }
+ rect.x = x;
+ rect.y = y;
+ rect.w = w;
+ rect.h = h;
- if (ui_netSource.integer >= numNetSources) {
- ui_netSource.integer = 0;
- } else if (ui_netSource.integer < 0) {
- ui_netSource.integer = numNetSources - 1;
- }
+ switch (ownerDraw)
+ {
+ case UI_TEAMINFOPANE:
+ UI_DrawInfoPane(&uiInfo.teamList[uiInfo.teamIndex], &rect, text_x, text_y, scale, textalign, textvalign,
+ foreColor, textStyle);
+ break;
+
+ case UI_VOICECMDINFOPANE:
+ UI_DrawInfoPane(&uiInfo.voiceCmdList[uiInfo.voiceCmdIndex], &rect, text_x, text_y, scale, textalign,
+ textvalign, foreColor, textStyle);
+ break;
+
+ case UI_ACLASSINFOPANE:
+ UI_DrawInfoPane(&uiInfo.alienClassList[uiInfo.alienClassIndex], &rect, text_x, text_y, scale, textalign,
+ textvalign, foreColor, textStyle);
+ break;
+
+ case UI_AUPGRADEINFOPANE:
+ UI_DrawInfoPane(&uiInfo.alienUpgradeList[uiInfo.alienUpgradeIndex], &rect, text_x, text_y, scale, textalign,
+ textvalign, foreColor, textStyle);
+ break;
+
+ case UI_HITEMINFOPANE:
+ UI_DrawInfoPane(&uiInfo.humanItemList[uiInfo.humanItemIndex], &rect, text_x, text_y, scale, textalign,
+ textvalign, foreColor, textStyle);
+ break;
+
+ case UI_HBUYINFOPANE:
+ UI_DrawInfoPane(&uiInfo.humanArmouryBuyList[uiInfo.humanArmouryBuyIndex], &rect, text_x, text_y, scale,
+ textalign, textvalign, foreColor, textStyle);
+ break;
+
+ case UI_HSELLINFOPANE:
+ UI_DrawInfoPane(&uiInfo.humanArmourySellList[uiInfo.humanArmourySellIndex], &rect, text_x, text_y, scale,
+ textalign, textvalign, foreColor, textStyle);
+ break;
+
+ case UI_ABUILDINFOPANE:
+ UI_DrawInfoPane(&uiInfo.alienBuildList[uiInfo.alienBuildIndex], &rect, text_x, text_y, scale, textalign,
+ textvalign, foreColor, textStyle);
+ break;
+
+ case UI_HBUILDINFOPANE:
+ UI_DrawInfoPane(&uiInfo.humanBuildList[uiInfo.humanBuildIndex], &rect, text_x, text_y, scale, textalign,
+ textvalign, foreColor, textStyle);
+ break;
+
+ case UI_HELPINFOPANE:
+ UI_DrawInfoPane(&uiInfo.helpList[uiInfo.helpIndex], &rect, text_x, text_y, scale, textalign, textvalign,
+ foreColor, textStyle);
+ break;
+
+ case UI_NETMAPPREVIEW:
+ UI_DrawServerMapPreview(&rect, scale, foreColor);
+ break;
+
+ case UI_SELECTEDMAPPREVIEW:
+ UI_DrawSelectedMapPreview(&rect, scale, foreColor);
+ break;
+
+ case UI_SELECTEDMAPNAME:
+ UI_DrawSelectedMapName(&rect, scale, foreColor, textStyle);
+ break;
+
+ case UI_GLINFO:
+ UI_DrawGLInfo(&rect, scale, textalign, textvalign, foreColor, textStyle, text_x, text_y);
+ break;
- UI_BuildServerDisplayList(qtrue);
- if (ui_netSource.integer != AS_GLOBAL) {
- UI_StartServerRefresh(qtrue);
+ default:
+ break;
}
- trap_Cvar_Set( "ui_netSource", va("%d", ui_netSource.integer));
- return qtrue;
- }
- return qfalse;
}
-static qboolean UI_NetFilter_HandleKey(int flags, float *special, int key) {
- if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
+static qboolean UI_OwnerDrawVisible(int flags)
+{
+ qboolean vis = qtrue;
+ uiClientState_t cs;
+ team_t team;
+ char info[MAX_INFO_STRING];
- if (key == K_MOUSE2) {
- ui_serverFilterType.integer--;
- } else {
- ui_serverFilterType.integer++;
- }
+ trap_GetClientState(&cs);
+ trap_GetConfigString(CS_PLAYERS + cs.clientNum, info, MAX_INFO_STRING);
+ team = atoi(Info_ValueForKey(info, "t"));
- if (ui_serverFilterType.integer >= numServerFilters) {
- ui_serverFilterType.integer = 0;
- } else if (ui_serverFilterType.integer < 0) {
- ui_serverFilterType.integer = numServerFilters - 1;
- }
- UI_BuildServerDisplayList(qtrue);
- return qtrue;
- }
- return qfalse;
-}
+ while (flags)
+ {
+ if (flags & UI_SHOW_NOTSPECTATING)
+ {
+ if (team == TEAM_NONE)
+ vis = qfalse;
-static qboolean UI_OpponentName_HandleKey(int flags, float *special, int key) {
- if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
- if (key == K_MOUSE2) {
- UI_PriorOpponent();
- } else {
- UI_NextOpponent();
- }
- return qtrue;
- }
- return qfalse;
-}
+ flags &= ~UI_SHOW_NOTSPECTATING;
+ }
-static qboolean UI_BotName_HandleKey(int flags, float *special, int key) {
- if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
- int value = uiInfo.botIndex;
+ if (flags & UI_SHOW_VOTEACTIVE)
+ {
+ if (!trap_Cvar_VariableValue("ui_voteActive"))
+ vis = qfalse;
- if (key == K_MOUSE2) {
- value--;
- } else {
- value++;
- }
+ flags &= ~UI_SHOW_VOTEACTIVE;
+ }
+ if (flags & UI_SHOW_CANVOTE)
+ {
+ if (trap_Cvar_VariableValue("ui_voteActive"))
+ vis = qfalse;
- if( value >= UI_GetNumBots( ) + 2 )
- value = 0;
- else if( value < 0 )
- value = UI_GetNumBots( ) + 2 - 1;
+ flags &= ~UI_SHOW_CANVOTE;
+ }
- uiInfo.botIndex = value;
- return qtrue;
- }
- return qfalse;
-}
+ if (flags & UI_SHOW_TEAMVOTEACTIVE)
+ {
+ if (team == TEAM_ALIENS)
+ {
+ if (!trap_Cvar_VariableValue("ui_alienTeamVoteActive"))
+ vis = qfalse;
+ }
+ else if (team == TEAM_HUMANS)
+ {
+ if (!trap_Cvar_VariableValue("ui_humanTeamVoteActive"))
+ vis = qfalse;
+ }
-static qboolean UI_BotSkill_HandleKey(int flags, float *special, int key) {
- if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
- if (key == K_MOUSE2) {
- uiInfo.skillIndex--;
- } else {
- uiInfo.skillIndex++;
- }
- if (uiInfo.skillIndex >= numSkillLevels) {
- uiInfo.skillIndex = 0;
- } else if (uiInfo.skillIndex < 0) {
- uiInfo.skillIndex = numSkillLevels-1;
- }
- return qtrue;
- }
- return qfalse;
-}
+ flags &= ~UI_SHOW_TEAMVOTEACTIVE;
+ }
-static qboolean UI_RedBlue_HandleKey(int flags, float *special, int key) {
- if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
- uiInfo.redBlue ^= 1;
- return qtrue;
- }
- return qfalse;
-}
+ if (flags & UI_SHOW_CANTEAMVOTE)
+ {
+ if (team == TEAM_ALIENS)
+ {
+ if (trap_Cvar_VariableValue("ui_alienTeamVoteActive"))
+ vis = qfalse;
+ }
+ else if (team == TEAM_HUMANS)
+ {
+ if (trap_Cvar_VariableValue("ui_humanTeamVoteActive"))
+ vis = qfalse;
+ }
+ flags &= ~UI_SHOW_CANTEAMVOTE;
+ }
+ if (flags & UI_SHOW_FAVORITESERVERS)
+ {
+ // this assumes you only put this type of display flag on something showing in the proper context
-static qboolean UI_SelectedPlayer_HandleKey(int flags, float *special, int key) {
- if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER) {
- int selected;
+ if (ui_netSource.integer != AS_FAVORITES)
+ vis = qfalse;
- UI_BuildPlayerList();
- if (!uiInfo.teamLeader) {
- return qfalse;
- }
- selected = trap_Cvar_VariableValue("cg_selectedPlayer");
+ flags &= ~UI_SHOW_FAVORITESERVERS;
+ }
- if (key == K_MOUSE2) {
- selected--;
- } else {
- selected++;
- }
+ if (flags & UI_SHOW_NOTFAVORITESERVERS)
+ {
+ // this assumes you only put this type of display flag on something showing in the proper context
- if (selected > uiInfo.myTeamCount) {
- selected = 0;
- } else if (selected < 0) {
- selected = uiInfo.myTeamCount;
- }
+ if (ui_netSource.integer == AS_FAVORITES)
+ vis = qfalse;
- if (selected == uiInfo.myTeamCount) {
- trap_Cvar_Set( "cg_selectedPlayerName", "Everyone");
- } else {
- trap_Cvar_Set( "cg_selectedPlayerName", uiInfo.teamNames[selected]);
+ flags &= ~UI_SHOW_NOTFAVORITESERVERS;
+ }
+ else
+ flags = 0;
}
- trap_Cvar_Set( "cg_selectedPlayer", va("%d", selected));
- }
- return qfalse;
+
+ return vis;
}
+static qboolean UI_NetSource_HandleKey(int key)
+{
+ if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_ENTER || key == K_KP_ENTER)
+ {
+ if (key == K_MOUSE2)
+ {
+ ui_netSource.integer--;
-static qboolean UI_OwnerDrawHandleKey(int ownerDraw, int flags, float *special, int key) {
- switch (ownerDraw) {
- case UI_HANDICAP:
- return UI_Handicap_HandleKey(flags, special, key);
- break;
- case UI_CLANNAME:
- return UI_ClanName_HandleKey(flags, special, key);
- break;
- case UI_GAMETYPE:
- return UI_GameType_HandleKey(flags, special, key, qtrue);
- break;
- case UI_NETGAMETYPE:
- return UI_NetGameType_HandleKey(flags, special, key);
- break;
- case UI_JOINGAMETYPE:
- return UI_JoinGameType_HandleKey(flags, special, key);
- break;
- case UI_SKILL:
- return UI_Skill_HandleKey(flags, special, key);
- break;
- case UI_BLUETEAMNAME:
- return UI_TeamName_HandleKey(flags, special, key, qtrue);
- break;
- case UI_REDTEAMNAME:
- return UI_TeamName_HandleKey(flags, special, key, qfalse);
- break;
- case UI_BLUETEAM1:
- case UI_BLUETEAM2:
- case UI_BLUETEAM3:
- case UI_BLUETEAM4:
- case UI_BLUETEAM5:
- UI_TeamMember_HandleKey(flags, special, key, qtrue, ownerDraw - UI_BLUETEAM1 + 1);
- break;
- case UI_REDTEAM1:
- case UI_REDTEAM2:
- case UI_REDTEAM3:
- case UI_REDTEAM4:
- case UI_REDTEAM5:
- UI_TeamMember_HandleKey(flags, special, key, qfalse, ownerDraw - UI_REDTEAM1 + 1);
- break;
- case UI_NETSOURCE:
- UI_NetSource_HandleKey(flags, special, key);
- break;
- case UI_NETFILTER:
- UI_NetFilter_HandleKey(flags, special, key);
- break;
- case UI_OPPONENT_NAME:
- UI_OpponentName_HandleKey(flags, special, key);
- break;
- case UI_BOTNAME:
- return UI_BotName_HandleKey(flags, special, key);
- break;
- case UI_BOTSKILL:
- return UI_BotSkill_HandleKey(flags, special, key);
- break;
- case UI_REDBLUE:
- UI_RedBlue_HandleKey(flags, special, key);
- break;
- case UI_SELECTEDPLAYER:
- UI_SelectedPlayer_HandleKey(flags, special, key);
- break;
- default:
- break;
- }
-
- return qfalse;
+ if (ui_netSource.integer == AS_MPLAYER)
+ ui_netSource.integer--;
+ }
+ else
+ {
+ ui_netSource.integer++;
+
+ if (ui_netSource.integer == AS_MPLAYER)
+ ui_netSource.integer++;
+ }
+
+ if (ui_netSource.integer < 0)
+ ui_netSource.integer = numNetSources - 1;
+ else if (ui_netSource.integer >= numNetSources)
+ ui_netSource.integer = 0;
+
+ UI_BuildServerDisplayList(qtrue);
+
+ if (ui_netSource.integer != AS_GLOBAL)
+ UI_StartServerRefresh(qtrue);
+
+ trap_Cvar_Set("ui_netSource", va("%d", ui_netSource.integer));
+ return qtrue;
+ }
+
+ return qfalse;
}
+static qboolean UI_OwnerDrawHandleKey(int ownerDraw, int key)
+{
+ switch (ownerDraw)
+ {
+ case UI_NETSOURCE:
+ UI_NetSource_HandleKey(key);
+ break;
-static float UI_GetValue(int ownerDraw) {
- return 0;
+ default:
+ break;
+ }
+
+ return qfalse;
}
/*
@@ -3108,446 +2321,462 @@ static float UI_GetValue(int ownerDraw) {
UI_ServersQsortCompare
=================
*/
-static int QDECL UI_ServersQsortCompare( const void *arg1, const void *arg2 ) {
- return trap_LAN_CompareServers( ui_netSource.integer, uiInfo.serverStatus.sortKey, uiInfo.serverStatus.sortDir, *(int*)arg1, *(int*)arg2);
+static int QDECL UI_ServersQsortCompare(const void *arg1, const void *arg2)
+{
+ return trap_LAN_CompareServers(
+ ui_netSource.integer, uiInfo.serverStatus.sortKey, uiInfo.serverStatus.sortDir, *(int *)arg1, *(int *)arg2);
}
-
/*
=================
UI_ServersSort
=================
*/
-void UI_ServersSort(int column, qboolean force) {
-
- if ( !force ) {
- if ( uiInfo.serverStatus.sortKey == column ) {
- return;
+void UI_ServersSort(int column, qboolean force)
+{
+ if (!force)
+ {
+ if (uiInfo.serverStatus.sortKey == column)
+ return;
}
- }
- uiInfo.serverStatus.sortKey = column;
- qsort( &uiInfo.serverStatus.displayServers[0], uiInfo.serverStatus.numDisplayServers, sizeof(int), UI_ServersQsortCompare);
+ uiInfo.serverStatus.sortKey = column;
+ qsort(&uiInfo.serverStatus.displayServers[0], uiInfo.serverStatus.numDisplayServers, sizeof(int),
+ UI_ServersQsortCompare);
}
-
/*
===============
-UI_GetCurrentAlienStage
+UI_LoadTeams
===============
*/
-static stage_t UI_GetCurrentAlienStage( void )
+static void UI_LoadTeams(void)
{
- char buffer[ MAX_TOKEN_CHARS ];
- stage_t stage, dummy;
-
- trap_Cvar_VariableStringBuffer( "ui_stages", buffer, sizeof( buffer ) );
- sscanf( buffer, "%d %d", (int *)&stage , (int *)&dummy );
-
- return stage;
+ uiInfo.teamCount = 4;
+
+ uiInfo.teamList[0].text = "Aliens";
+ uiInfo.teamList[0].cmd = "cmd team aliens\n";
+ uiInfo.teamList[0].type = INFOTYPE_TEXT;
+ uiInfo.teamList[0].v.text =
+ "The Alien Team\n\n"
+ "The Aliens' strengths are in movement and the ability to "
+ "quickly construct new bases quickly. They possess a range "
+ "of abilities including basic melee attacks, movement-"
+ "crippling poisons and more.";
+
+ uiInfo.teamList[1].text = "Humans";
+ uiInfo.teamList[1].cmd = "cmd team humans\n";
+ uiInfo.teamList[1].type = INFOTYPE_TEXT;
+ uiInfo.teamList[1].v.text =
+ "The Human Team\n\n"
+ "The humans are the masters of technology. Although their "
+ "bases take long to construct, their automated defense "
+ "ensures they stay built. A wide range of upgrades and "
+ "weapons are available to the humans, each contributing "
+ "to eradicate the alien threat.";
+
+ uiInfo.teamList[2].text = "Spectate";
+ uiInfo.teamList[2].cmd = "cmd team spectate\n";
+ uiInfo.teamList[2].type = INFOTYPE_TEXT;
+ uiInfo.teamList[2].v.text = "Watch the game without playing.";
+
+ uiInfo.teamList[3].text = "Auto select";
+ uiInfo.teamList[3].cmd = "cmd team auto\n";
+ uiInfo.teamList[3].type = INFOTYPE_TEXT;
+ uiInfo.teamList[3].v.text = "Join the team with the least players.";
}
/*
===============
-UI_GetCurrentHumanStage
+UI_AddClass
===============
*/
-static stage_t UI_GetCurrentHumanStage( void )
+
+static void UI_AddClass(class_t class)
{
- char buffer[ MAX_TOKEN_CHARS ];
- stage_t stage, dummy;
+ uiInfo.alienClassList[uiInfo.alienClassCount].text = BG_ClassConfig(class)->humanName;
+ uiInfo.alienClassList[uiInfo.alienClassCount].cmd = String_Alloc(va("cmd class %s\n", BG_Class(class)->name));
+ uiInfo.alienClassList[uiInfo.alienClassCount].type = INFOTYPE_CLASS;
- trap_Cvar_VariableStringBuffer( "ui_stages", buffer, sizeof( buffer ) );
- sscanf( buffer, "%d %d", (int *)&dummy, (int *)&stage );
+ uiInfo.alienClassList[uiInfo.alienClassCount].v.pclass = class;
- return stage;
+ uiInfo.alienClassCount++;
}
/*
===============
-UI_LoadTremTeams
+UI_LoadAlienClasses
===============
*/
-static void UI_LoadTremTeams( void )
+static void UI_LoadAlienClasses(void)
{
- uiInfo.tremTeamCount = 4;
+ uiInfo.alienClassCount = 0;
- uiInfo.tremTeamList[ 0 ].text = String_Alloc( "Aliens" );
- uiInfo.tremTeamList[ 0 ].cmd = String_Alloc( "cmd team aliens\n" );
- uiInfo.tremTeamList[ 0 ].infopane = UI_FindInfoPaneByName( "alienteam" );
+ if (BG_ClassIsAllowed(PCL_ALIEN_LEVEL0))
+ UI_AddClass(PCL_ALIEN_LEVEL0);
- uiInfo.tremTeamList[ 1 ].text = String_Alloc( "Humans" );
- uiInfo.tremTeamList[ 1 ].cmd = String_Alloc( "cmd team humans\n" );
- uiInfo.tremTeamList[ 1 ].infopane = UI_FindInfoPaneByName( "humanteam" );
-
- uiInfo.tremTeamList[ 2 ].text = String_Alloc( "Spectate" );
- uiInfo.tremTeamList[ 2 ].cmd = String_Alloc( "cmd team spectate\n" );
- uiInfo.tremTeamList[ 2 ].infopane = UI_FindInfoPaneByName( "spectateteam" );
-
- uiInfo.tremTeamList[ 3 ].text = String_Alloc( "Auto select" );
- uiInfo.tremTeamList[ 3 ].cmd = String_Alloc( "cmd team auto\n" );
- uiInfo.tremTeamList[ 3 ].infopane = UI_FindInfoPaneByName( "autoteam" );
+ if (BG_ClassIsAllowed(PCL_ALIEN_BUILDER0_UPG) &&
+ BG_ClassAllowedInStage(PCL_ALIEN_BUILDER0_UPG, UI_GetCurrentAlienStage()))
+ UI_AddClass(PCL_ALIEN_BUILDER0_UPG);
+ else if (BG_ClassIsAllowed(PCL_ALIEN_BUILDER0))
+ UI_AddClass(PCL_ALIEN_BUILDER0);
}
/*
===============
-UI_AddClass
+UI_AddItem
===============
*/
-static void UI_AddClass( pClass_t class )
+static void UI_AddItem(weapon_t weapon)
{
- uiInfo.tremAlienClassList[ uiInfo.tremAlienClassCount ].text =
- String_Alloc( BG_FindHumanNameForClassNum( class ) );
- uiInfo.tremAlienClassList[ uiInfo.tremAlienClassCount ].cmd =
- String_Alloc( va( "cmd class %s\n", BG_FindNameForClassNum( class ) ) );
- uiInfo.tremAlienClassList[ uiInfo.tremAlienClassCount ].infopane =
- UI_FindInfoPaneByName( va( "%sclass", BG_FindNameForClassNum( class ) ) );
-
- uiInfo.tremAlienClassCount++;
+ uiInfo.humanItemList[uiInfo.humanItemCount].text = BG_Weapon(weapon)->humanName;
+ uiInfo.humanItemList[uiInfo.humanItemCount].cmd = String_Alloc(va("cmd class %s\n", BG_Weapon(weapon)->name));
+ uiInfo.humanItemList[uiInfo.humanItemCount].type = INFOTYPE_WEAPON;
+ uiInfo.humanItemList[uiInfo.humanItemCount].v.weapon = weapon;
+
+ uiInfo.humanItemCount++;
}
/*
===============
-UI_LoadTremAlienClasses
+UI_LoadHumanItems
===============
*/
-static void UI_LoadTremAlienClasses( void )
+static void UI_LoadHumanItems(void)
{
- uiInfo.tremAlienClassCount = 0;
+ uiInfo.humanItemCount = 0;
- if( BG_ClassIsAllowed( PCL_ALIEN_LEVEL0 ) )
- UI_AddClass( PCL_ALIEN_LEVEL0 );
+ if (BG_WeaponIsAllowed(WP_MACHINEGUN))
+ UI_AddItem(WP_MACHINEGUN);
- if( BG_ClassIsAllowed( PCL_ALIEN_BUILDER0_UPG ) &&
- BG_FindStagesForClass( PCL_ALIEN_BUILDER0_UPG, UI_GetCurrentAlienStage( ) ) )
- UI_AddClass( PCL_ALIEN_BUILDER0_UPG );
- else if( BG_ClassIsAllowed( PCL_ALIEN_BUILDER0 ) )
- UI_AddClass( PCL_ALIEN_BUILDER0 );
+ if (BG_WeaponIsAllowed(WP_HBUILD))
+ UI_AddItem(WP_HBUILD);
}
/*
===============
-UI_AddItem
+UI_ParseCarriageList
===============
*/
-static void UI_AddItem( weapon_t weapon )
+static void UI_ParseCarriageList(void)
{
- uiInfo.tremHumanItemList[ uiInfo.tremHumanItemCount ].text =
- String_Alloc( BG_FindHumanNameForWeapon( weapon ) );
- uiInfo.tremHumanItemList[ uiInfo.tremHumanItemCount ].cmd =
- String_Alloc( va( "cmd class %s\n", BG_FindNameForWeapon( weapon ) ) );
- uiInfo.tremHumanItemList[ uiInfo.tremHumanItemCount ].infopane =
- UI_FindInfoPaneByName( va( "%sitem", BG_FindNameForWeapon( weapon ) ) );
-
- uiInfo.tremHumanItemCount++;
-}
+ int i;
+ char carriageCvar[MAX_TOKEN_CHARS];
+ char *iterator;
+ char buffer[MAX_TOKEN_CHARS];
+ char *bufPointer;
-/*
-===============
-UI_LoadTremHumanItems
-===============
-*/
-static void UI_LoadTremHumanItems( void )
-{
- uiInfo.tremHumanItemCount = 0;
+ trap_Cvar_VariableStringBuffer("ui_carriage", carriageCvar, sizeof(carriageCvar));
+ iterator = carriageCvar;
- if( BG_WeaponIsAllowed( WP_MACHINEGUN ) )
- UI_AddItem( WP_MACHINEGUN );
+ uiInfo.weapons = 0;
+ uiInfo.upgrades = 0;
+
+ // simple parser to give rise to weapon/upgrade list
+
+ while (iterator && iterator[0] != '$')
+ {
+ bufPointer = buffer;
+
+ if (iterator[0] == 'W')
+ {
+ iterator++;
+
+ while (iterator[0] != ' ')
+ *bufPointer++ = *iterator++;
+
+ *bufPointer++ = '\n';
+
+ i = atoi(buffer);
+
+ uiInfo.weapons |= (1 << i);
+ }
+ else if (iterator[0] == 'U')
+ {
+ iterator++;
+
+ while (iterator[0] != ' ')
+ *bufPointer++ = *iterator++;
+
+ *bufPointer++ = '\n';
+
+ i = atoi(buffer);
+
+ uiInfo.upgrades |= (1 << i);
+ }
- if( BG_WeaponIsAllowed( WP_HBUILD2 ) &&
- BG_FindStagesForWeapon( WP_HBUILD2, UI_GetCurrentHumanStage( ) ) )
- UI_AddItem( WP_HBUILD2 );
- else if( BG_WeaponIsAllowed( WP_HBUILD ) )
- UI_AddItem( WP_HBUILD );
+ iterator++;
+ }
}
/*
===============
-UI_ParseCarriageList
+UI_LoadHumanArmouryBuys
===============
*/
-static void UI_ParseCarriageList( int *weapons, int *upgrades )
+static void UI_LoadHumanArmouryBuys(void)
{
- int i;
- char carriageCvar[ MAX_TOKEN_CHARS ];
- char *iterator;
- char buffer[ MAX_TOKEN_CHARS ];
- char *bufPointer;
+ int i, j = 0;
+ stage_t stage = UI_GetCurrentHumanStage();
+ int slots = 0;
- trap_Cvar_VariableStringBuffer( "ui_carriage", carriageCvar, sizeof( carriageCvar ) );
- iterator = carriageCvar;
+ UI_ParseCarriageList();
- if( weapons )
- *weapons = 0;
+ for (i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++)
+ {
+ if (uiInfo.weapons & (1 << i))
+ slots |= BG_Weapon(i)->slots;
+ }
- if( upgrades )
- *upgrades = 0;
+ for (i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++)
+ {
+ if (uiInfo.upgrades & (1 << i))
+ slots |= BG_Upgrade(i)->slots;
+ }
- //simple parser to give rise to weapon/upgrade list
- while( iterator && iterator[ 0 ] != '$' )
- {
- bufPointer = buffer;
+ uiInfo.humanArmouryBuyCount = 0;
- if( iterator[ 0 ] == 'W' )
+ for (i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++)
{
- iterator++;
+ if (BG_Weapon(i)->team == TEAM_HUMANS && BG_Weapon(i)->purchasable && BG_WeaponAllowedInStage(i, stage) &&
+ BG_WeaponIsAllowed(i) && !(BG_Weapon(i)->slots & slots) && !(uiInfo.weapons & (1 << i)))
+ {
+ uiInfo.humanArmouryBuyList[j].text = BG_Weapon(i)->humanName;
+ uiInfo.humanArmouryBuyList[j].cmd = String_Alloc(va("cmd buy %s\n", BG_Weapon(i)->name));
+ uiInfo.humanArmouryBuyList[j].type = INFOTYPE_WEAPON;
+ uiInfo.humanArmouryBuyList[j].v.weapon = i;
- while( iterator[ 0 ] != ' ' )
- *bufPointer++ = *iterator++;
+ j++;
- *bufPointer++ = '\n';
+ uiInfo.humanArmouryBuyCount++;
+ }
+ }
- i = atoi( buffer );
+ for (i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++)
+ {
+ if (BG_Upgrade(i)->team == TEAM_HUMANS && BG_Upgrade(i)->purchasable && BG_UpgradeAllowedInStage(i, stage) &&
+ BG_UpgradeIsAllowed(i) && !(BG_Upgrade(i)->slots & slots) && !(uiInfo.upgrades & (1 << i)))
+ {
+ uiInfo.humanArmouryBuyList[j].text = BG_Upgrade(i)->humanName;
+ uiInfo.humanArmouryBuyList[j].cmd = String_Alloc(va("cmd buy %s\n", BG_Upgrade(i)->name));
+ uiInfo.humanArmouryBuyList[j].type = INFOTYPE_UPGRADE;
+ uiInfo.humanArmouryBuyList[j].v.upgrade = i;
- if( weapons )
- *weapons |= ( 1 << i );
+ j++;
+
+ uiInfo.humanArmouryBuyCount++;
+ }
}
- else if( iterator[ 0 ] == 'U' )
- {
- iterator++;
+}
- while( iterator[ 0 ] != ' ' )
- *bufPointer++ = *iterator++;
+/*
+===============
+UI_LoadHumanArmourySells
+===============
+*/
+static void UI_LoadHumanArmourySells(void)
+{
+ int i, j = 0;
- *bufPointer++ = '\n';
+ uiInfo.humanArmourySellCount = 0;
+ UI_ParseCarriageList();
- i = atoi( buffer );
+ for (i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++)
+ {
+ if (uiInfo.weapons & (1 << i))
+ {
+ uiInfo.humanArmourySellList[j].text = BG_Weapon(i)->humanName;
+ uiInfo.humanArmourySellList[j].cmd = String_Alloc(va("cmd sell %s\n", BG_Weapon(i)->name));
+ uiInfo.humanArmourySellList[j].type = INFOTYPE_WEAPON;
+ uiInfo.humanArmourySellList[j].v.weapon = i;
+
+ j++;
- if( upgrades )
- *upgrades |= ( 1 << i );
+ uiInfo.humanArmourySellCount++;
+ }
}
- iterator++;
- }
+ for (i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++)
+ {
+ if (uiInfo.upgrades & (1 << i))
+ {
+ uiInfo.humanArmourySellList[j].text = BG_Upgrade(i)->humanName;
+ uiInfo.humanArmourySellList[j].cmd = String_Alloc(va("cmd sell %s\n", BG_Upgrade(i)->name));
+ uiInfo.humanArmourySellList[j].type = INFOTYPE_UPGRADE;
+ uiInfo.humanArmourySellList[j].v.upgrade = i;
+
+ j++;
+
+ uiInfo.humanArmourySellCount++;
+ }
+ }
}
/*
===============
-UI_LoadTremHumanArmouryBuys
+UI_ArmouryRefreshCb
===============
*/
-static void UI_LoadTremHumanArmouryBuys( void )
+static void UI_ArmouryRefreshCb(void *data)
{
- int i, j = 0;
- stage_t stage = UI_GetCurrentHumanStage( );
- int weapons, upgrades;
- int slots = 0;
-
- UI_ParseCarriageList( &weapons, &upgrades );
-
- for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ )
- {
- if( weapons & ( 1 << i ) )
- slots |= BG_FindSlotsForWeapon( i );
- }
-
- for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ )
- {
- if( upgrades & ( 1 << i ) )
- slots |= BG_FindSlotsForUpgrade( i );
- }
-
- uiInfo.tremHumanArmouryBuyCount = 0;
-
- for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ )
- {
- if( BG_FindTeamForWeapon( i ) == WUT_HUMANS &&
- BG_FindPurchasableForWeapon( i ) &&
- BG_FindStagesForWeapon( i, stage ) &&
- BG_WeaponIsAllowed( i ) &&
- !( BG_FindSlotsForWeapon( i ) & slots ) &&
- !( weapons & ( 1 << i ) ) )
- {
- uiInfo.tremHumanArmouryBuyList[ j ].text =
- String_Alloc( BG_FindHumanNameForWeapon( i ) );
- uiInfo.tremHumanArmouryBuyList[ j ].cmd =
- String_Alloc( va( "cmd buy %s retrigger\n", BG_FindNameForWeapon( i ) ) );
- uiInfo.tremHumanArmouryBuyList[ j ].infopane =
- UI_FindInfoPaneByName( va( "%sitem", BG_FindNameForWeapon( i ) ) );
-
- j++;
-
- uiInfo.tremHumanArmouryBuyCount++;
- }
- }
-
- for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ )
- {
- if( BG_FindTeamForUpgrade( i ) == WUT_HUMANS &&
- BG_FindPurchasableForUpgrade( i ) &&
- BG_FindStagesForUpgrade( i, stage ) &&
- BG_UpgradeIsAllowed( i ) &&
- !( BG_FindSlotsForUpgrade( i ) & slots ) &&
- !( upgrades & ( 1 << i ) ) )
- {
- uiInfo.tremHumanArmouryBuyList[ j ].text =
- String_Alloc( BG_FindHumanNameForUpgrade( i ) );
- uiInfo.tremHumanArmouryBuyList[ j ].cmd =
- String_Alloc( va( "cmd buy %s retrigger\n", BG_FindNameForUpgrade( i ) ) );
- uiInfo.tremHumanArmouryBuyList[ j ].infopane =
- UI_FindInfoPaneByName( va( "%sitem", BG_FindNameForUpgrade( i ) ) );
-
- j++;
-
- uiInfo.tremHumanArmouryBuyCount++;
- }
- }
+ int oldWeapons = uiInfo.weapons;
+ int oldUpgrades = uiInfo.upgrades;
+
+ UI_ParseCarriageList();
+
+ if (uiInfo.weapons != oldWeapons || uiInfo.upgrades != oldUpgrades)
+ {
+ UI_LoadHumanArmouryBuys();
+ UI_LoadHumanArmourySells();
+ UI_RemoveCaptureFunc();
+ }
}
/*
===============
-UI_LoadTremHumanArmourySells
+UI_LoadAlienUpgrades
===============
*/
-static void UI_LoadTremHumanArmourySells( void )
+static void UI_LoadAlienUpgrades(void)
{
- int weapons, upgrades;
- int i, j = 0;
+ int i, j = 0;
- uiInfo.tremHumanArmourySellCount = 0;
- UI_ParseCarriageList( &weapons, &upgrades );
+ int class, credits;
+ char ui_currentClass[MAX_STRING_CHARS];
+ stage_t stage = UI_GetCurrentAlienStage();
- for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ )
- {
- if( weapons & ( 1 << i ) )
- {
- uiInfo.tremHumanArmourySellList[ j ].text = String_Alloc( BG_FindHumanNameForWeapon( i ) );
- uiInfo.tremHumanArmourySellList[ j ].cmd =
- String_Alloc( va( "cmd sell %s retrigger\n", BG_FindNameForWeapon( i ) ) );
- uiInfo.tremHumanArmourySellList[ j ].infopane =
- UI_FindInfoPaneByName( va( "%sitem", BG_FindNameForWeapon( i ) ) );
+ trap_Cvar_VariableStringBuffer("ui_currentClass", ui_currentClass, MAX_STRING_CHARS);
- j++;
+ sscanf(ui_currentClass, "%d %d", &class, &credits);
- uiInfo.tremHumanArmourySellCount++;
- }
- }
+ uiInfo.alienUpgradeCount = 0;
- for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ )
- {
- if( upgrades & ( 1 << i ) )
+ for (i = PCL_NONE + 1; i < PCL_NUM_CLASSES; i++)
{
- uiInfo.tremHumanArmourySellList[ j ].text = String_Alloc( BG_FindHumanNameForUpgrade( i ) );
- uiInfo.tremHumanArmourySellList[ j ].cmd =
- String_Alloc( va( "cmd sell %s retrigger\n", BG_FindNameForUpgrade( i ) ) );
- uiInfo.tremHumanArmourySellList[ j ].infopane =
- UI_FindInfoPaneByName( va( "%sitem", BG_FindNameForUpgrade( i ) ) );
+ if (BG_ClassCanEvolveFromTo(class, i, credits, stage, 0) >= 0)
+ {
+ uiInfo.alienUpgradeList[j].text = BG_ClassConfig(i)->humanName;
+ uiInfo.alienUpgradeList[j].cmd = String_Alloc(va("cmd class %s\n", BG_Class(i)->name));
+ uiInfo.alienUpgradeList[j].type = INFOTYPE_CLASS;
+ uiInfo.alienUpgradeList[j].v.pclass = i;
- j++;
+ j++;
- uiInfo.tremHumanArmourySellCount++;
+ uiInfo.alienUpgradeCount++;
+ }
}
- }
}
/*
===============
-UI_LoadTremAlienUpgrades
+UI_LoadAlienBuilds
===============
*/
-static void UI_LoadTremAlienUpgrades( void )
+static void UI_LoadAlienBuilds(void)
{
- int i, j = 0;
- int class, credits;
- char ui_currentClass[ MAX_STRING_CHARS ];
- stage_t stage = UI_GetCurrentAlienStage( );
+ int i, j = 0;
+ stage_t stage;
- trap_Cvar_VariableStringBuffer( "ui_currentClass", ui_currentClass, MAX_STRING_CHARS );
- sscanf( ui_currentClass, "%d %d", &class, &credits );
+ UI_ParseCarriageList();
+ stage = UI_GetCurrentAlienStage();
- uiInfo.tremAlienUpgradeCount = 0;
+ uiInfo.alienBuildCount = 0;
- for( i = PCL_NONE + 1; i < PCL_NUM_CLASSES; i++ )
- {
- if( BG_ClassCanEvolveFromTo( class, i, credits, 0 ) >= 0 &&
- BG_FindStagesForClass( i, stage ) &&
- BG_ClassIsAllowed( i ) )
+ for (i = BA_NONE + 1; i < BA_NUM_BUILDABLES; i++)
{
- uiInfo.tremAlienUpgradeList[ j ].text = String_Alloc( BG_FindHumanNameForClassNum( i ) );
- uiInfo.tremAlienUpgradeList[ j ].cmd =
- String_Alloc( va( "cmd class %s\n", BG_FindNameForClassNum( i ) ) );
- uiInfo.tremAlienUpgradeList[ j ].infopane =
- UI_FindInfoPaneByName( va( "%sclass", BG_FindNameForClassNum( i ) ) );
+ if (BG_Buildable(i)->team == TEAM_ALIENS && BG_Buildable(i)->buildWeapon & uiInfo.weapons &&
+ BG_BuildableAllowedInStage(i, stage) && BG_BuildableIsAllowed(i))
+ {
+ uiInfo.alienBuildList[j].text = BG_Buildable(i)->humanName;
+ uiInfo.alienBuildList[j].cmd = String_Alloc(va("cmd build %s\n", BG_Buildable(i)->name));
+ uiInfo.alienBuildList[j].type = INFOTYPE_BUILDABLE;
+ uiInfo.alienBuildList[j].v.buildable = i;
- j++;
+ j++;
- uiInfo.tremAlienUpgradeCount++;
+ uiInfo.alienBuildCount++;
+ }
}
- }
}
/*
===============
-UI_LoadTremAlienBuilds
+UI_LoadHumanBuilds
===============
*/
-static void UI_LoadTremAlienBuilds( void )
+static void UI_LoadHumanBuilds(void)
{
- int weapons;
- int i, j = 0;
- stage_t stage;
+ int i, j = 0;
+ stage_t stage;
- UI_ParseCarriageList( &weapons, NULL );
- stage = UI_GetCurrentAlienStage( );
+ UI_ParseCarriageList();
+ stage = UI_GetCurrentHumanStage();
- uiInfo.tremAlienBuildCount = 0;
+ uiInfo.humanBuildCount = 0;
- for( i = BA_NONE +1; i < BA_NUM_BUILDABLES; i++ )
- {
- if( BG_FindTeamForBuildable( i ) == BIT_ALIENS &&
- BG_FindBuildWeaponForBuildable( i ) & weapons &&
- BG_FindStagesForBuildable( i, stage ) &&
- BG_BuildableIsAllowed( i ) )
+ for (i = BA_NONE + 1; i < BA_NUM_BUILDABLES; i++)
{
- uiInfo.tremAlienBuildList[ j ].text =
- String_Alloc( BG_FindHumanNameForBuildable( i ) );
- uiInfo.tremAlienBuildList[ j ].cmd =
- String_Alloc( va( "cmd build %s\n", BG_FindNameForBuildable( i ) ) );
- uiInfo.tremAlienBuildList[ j ].infopane =
- UI_FindInfoPaneByName( va( "%sbuild", BG_FindNameForBuildable( i ) ) );
+ if (BG_Buildable(i)->team == TEAM_HUMANS && BG_Buildable(i)->buildWeapon & uiInfo.weapons &&
+ BG_BuildableAllowedInStage(i, stage) && BG_BuildableIsAllowed(i))
+ {
+ uiInfo.humanBuildList[j].text = BG_Buildable(i)->humanName;
+ uiInfo.humanBuildList[j].cmd = String_Alloc(va("cmd build %s\n", BG_Buildable(i)->name));
+ uiInfo.humanBuildList[j].type = INFOTYPE_BUILDABLE;
+ uiInfo.humanBuildList[j].v.buildable = i;
- j++;
+ j++;
- uiInfo.tremAlienBuildCount++;
+ uiInfo.humanBuildCount++;
+ }
}
- }
}
/*
===============
-UI_LoadTremHumanBuilds
+UI_LoadVoiceCmds
===============
*/
-static void UI_LoadTremHumanBuilds( void )
+static void UI_LoadVoiceCmds(void)
{
- int weapons;
- int i, j = 0;
- stage_t stage;
+ voice_t *v;
+ voiceCmd_t *c;
+
+ const char *cmd;
+ char mode[2];
+ char ui_voice[MAX_VOICE_CMD_LEN];
- UI_ParseCarriageList( &weapons, NULL );
- stage = UI_GetCurrentHumanStage( );
+ trap_Cvar_VariableStringBuffer("ui_voicemenu", mode, sizeof(mode));
+ trap_Cvar_VariableStringBuffer("voice", ui_voice, sizeof(ui_voice));
- uiInfo.tremHumanBuildCount = 0;
+ uiInfo.voiceCmdCount = 0;
- for( i = BA_NONE +1; i < BA_NUM_BUILDABLES; i++ )
- {
- if( BG_FindTeamForBuildable( i ) == BIT_HUMANS &&
- BG_FindBuildWeaponForBuildable( i ) & weapons &&
- BG_FindStagesForBuildable( i, stage ) &&
- BG_BuildableIsAllowed( i ) )
+ switch (mode[0])
{
- uiInfo.tremHumanBuildList[ j ].text =
- String_Alloc( BG_FindHumanNameForBuildable( i ) );
- uiInfo.tremHumanBuildList[ j ].cmd =
- String_Alloc( va( "cmd build %s\n", BG_FindNameForBuildable( i ) ) );
- uiInfo.tremHumanBuildList[ j ].infopane =
- UI_FindInfoPaneByName( va( "%sbuild", BG_FindNameForBuildable( i ) ) );
+ default:
+ case '1':
+ cmd = "vsay";
+ break;
+ case '2':
+ cmd = "vsay_team";
+ break;
+ case '3':
+ cmd = "vsay_local";
+ break;
+ };
+
+ v = BG_VoiceByName(uiInfo.voices, ui_voice);
+ if (!v)
+ return;
- j++;
+ for (c = v->cmds; c; c = c->next)
+ {
+ uiInfo.voiceCmdList[uiInfo.voiceCmdCount].text = c->cmd;
+ uiInfo.voiceCmdList[uiInfo.voiceCmdCount].cmd = String_Alloc(va("cmd %s %s\n", cmd, c->cmd));
+ uiInfo.voiceCmdList[uiInfo.voiceCmdCount].type = INFOTYPE_VOICECMD;
+ uiInfo.voiceCmdList[uiInfo.voiceCmdCount].v.text = c->tracks[0].text;
- uiInfo.tremHumanBuildCount++;
+ uiInfo.voiceCmdCount++;
}
- }
}
/*
@@ -3555,2156 +2784,1545 @@ static void UI_LoadTremHumanBuilds( void )
UI_LoadMods
===============
*/
-static void UI_LoadMods( void ) {
- int numdirs;
- char dirlist[2048];
- char *dirptr;
- char *descptr;
- int i;
- int dirlen;
-
- uiInfo.modCount = 0;
- numdirs = trap_FS_GetFileList( "$modlist", "", dirlist, sizeof(dirlist) );
- dirptr = dirlist;
- for( i = 0; i < numdirs; i++ ) {
- dirlen = strlen( dirptr ) + 1;
- descptr = dirptr + dirlen;
- uiInfo.modList[uiInfo.modCount].modName = String_Alloc(dirptr);
- uiInfo.modList[uiInfo.modCount].modDescr = String_Alloc(descptr);
- dirptr += dirlen + strlen(descptr) + 1;
- uiInfo.modCount++;
- if (uiInfo.modCount >= MAX_MODS) {
- break;
- }
- }
+static void UI_LoadMods(void)
+{
+ int numdirs;
+ char dirlist[2048];
+ char *dirptr;
+ char *descptr;
+ int i;
+ int dirlen;
-}
+ uiInfo.modCount = 0;
+ numdirs = trap_FS_GetFileList("$modlist", "", dirlist, sizeof(dirlist));
+ dirptr = dirlist;
+
+ for (i = 0; i < numdirs; i++)
+ {
+ dirlen = strlen(dirptr) + 1;
+ uiInfo.modList[uiInfo.modCount].modName = String_Alloc(dirptr);
+ dirptr += dirlen;
+ uiInfo.modCount++;
+ if (uiInfo.modCount >= MAX_MODS)
+ break;
+ }
+}
/*
===============
UI_LoadMovies
===============
*/
-static void UI_LoadMovies( void ) {
- char movielist[4096];
- char *moviename;
- int i, len;
-
- uiInfo.movieCount = trap_FS_GetFileList( "video", "roq", movielist, 4096 );
-
- if (uiInfo.movieCount) {
- if (uiInfo.movieCount > MAX_MOVIES) {
- uiInfo.movieCount = MAX_MOVIES;
- }
- moviename = movielist;
- for ( i = 0; i < uiInfo.movieCount; i++ ) {
- len = strlen( moviename );
- if (!Q_stricmp(moviename + len - 4,".roq")) {
- moviename[len-4] = '\0';
- }
- Q_strupr(moviename);
- uiInfo.movieList[i] = String_Alloc(moviename);
- moviename += len + 1;
- }
- }
+static void UI_LoadMovies(void)
+{
+ char movielist[4096];
+ char *moviename;
+ int i, len;
-}
+ uiInfo.movieCount = trap_FS_GetFileList("video", "roq", movielist, 4096);
+
+ if (uiInfo.movieCount)
+ {
+ if (uiInfo.movieCount > MAX_MOVIES)
+ uiInfo.movieCount = MAX_MOVIES;
+
+ moviename = movielist;
+
+ for (i = 0; i < uiInfo.movieCount; i++)
+ {
+ len = strlen(moviename);
+ if (!Q_stricmp(moviename + len - 4, ".roq"))
+ moviename[len - 4] = '\0';
+ Q_strupr(moviename);
+ uiInfo.movieList[i] = String_Alloc(moviename);
+ moviename += len + 1;
+ }
+ }
+}
/*
===============
UI_LoadDemos
===============
*/
-static void UI_LoadDemos( void ) {
- char demolist[4096];
- char demoExt[32];
- char *demoname;
- int i, len;
+static void UI_LoadDemos(void)
+{
+ char demolist[4096];
+ char demoExt[32];
+ char *demoname;
+ int i = 0;
+ int len, protocol;
- Com_sprintf(demoExt, sizeof(demoExt), "dm_%d", (int)trap_Cvar_VariableValue("protocol"));
+ uiInfo.demoCount = 0;
- uiInfo.demoCount = trap_FS_GetFileList( "demos", demoExt, demolist, 4096 );
+ for(protocol = 0; protocol < 3; protocol++) {
+ Com_sprintf(
+ demoExt, sizeof(demoExt), "%s%d", DEMOEXT,
+ protocol == 2 ? 69 : protocol == 1 ? 70 : 71);
- Com_sprintf(demoExt, sizeof(demoExt), ".dm_%d", (int)trap_Cvar_VariableValue("protocol"));
+ uiInfo.demoCount += trap_FS_GetFileList("demos", demoExt, demolist, 4096);
- if (uiInfo.demoCount) {
- if (uiInfo.demoCount > MAX_DEMOS) {
- uiInfo.demoCount = MAX_DEMOS;
- }
- demoname = demolist;
- for ( i = 0; i < uiInfo.demoCount; i++ ) {
- len = strlen( demoname );
- if (!Q_stricmp(demoname + len - strlen(demoExt), demoExt)) {
- demoname[len-strlen(demoExt)] = '\0';
- }
- Q_strupr(demoname);
- uiInfo.demoList[i] = String_Alloc(demoname);
- demoname += len + 1;
- }
- }
+ Com_sprintf(
+ demoExt, sizeof(demoExt), ".%s%d", DEMOEXT,
+ protocol == 2 ? 69 : protocol == 1 ? 70 : 71);
-}
+ if (uiInfo.demoCount)
+ {
+ if (uiInfo.demoCount > MAX_DEMOS)
+ uiInfo.demoCount = MAX_DEMOS;
+ demoname = demolist;
-static qboolean UI_SetNextMap(int actual, int index) {
- int i;
- for (i = actual + 1; i < uiInfo.mapCount; i++) {
- if (uiInfo.mapList[i].active) {
- Menu_SetFeederSelection(NULL, FEEDER_MAPS, index + 1, "skirmish");
- return qtrue;
- }
- }
- return qfalse;
-}
-
+ for (; i < uiInfo.demoCount; i++)
+ {
+ len = strlen(demoname);
-static void UI_StartSkirmish(qboolean next) {
- int i, k, g, delay, temp;
- float skill;
- char buff[MAX_STRING_CHARS];
+ if (!Q_stricmp(demoname + len - strlen(demoExt), demoExt))
+ demoname[len - strlen(demoExt)] = '\0';
- if (next) {
- int actual;
- int index = trap_Cvar_VariableValue("ui_mapIndex");
- UI_MapCountByGameType(qtrue);
- UI_SelectedMap(index, &actual);
- if (UI_SetNextMap(actual, index)) {
- } else {
- UI_GameType_HandleKey(0, NULL, K_MOUSE1, qfalse);
- UI_MapCountByGameType(qtrue);
- Menu_SetFeederSelection(NULL, FEEDER_MAPS, 0, "skirmish");
- }
- }
-
- g = uiInfo.gameTypes[ui_gameType.integer].gtEnum;
- trap_Cvar_SetValue( "g_gametype", g );
- trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait ; wait ; map %s\n", uiInfo.mapList[ui_currentMap.integer].mapLoadName) );
- skill = trap_Cvar_VariableValue( "g_spSkill" );
- trap_Cvar_Set("ui_scoreMap", uiInfo.mapList[ui_currentMap.integer].mapName);
-
- k = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName"));
-
- trap_Cvar_Set("ui_singlePlayerActive", "1");
-
- // set up sp overrides, will be replaced on postgame
- temp = trap_Cvar_VariableValue( "capturelimit" );
- trap_Cvar_Set("ui_saveCaptureLimit", va("%i", temp));
- temp = trap_Cvar_VariableValue( "fraglimit" );
- trap_Cvar_Set("ui_saveFragLimit", va("%i", temp));
-
- UI_SetCapFragLimits(qfalse);
-
- temp = trap_Cvar_VariableValue( "cg_drawTimer" );
- trap_Cvar_Set("ui_drawTimer", va("%i", temp));
- temp = trap_Cvar_VariableValue( "g_doWarmup" );
- trap_Cvar_Set("ui_doWarmup", va("%i", temp));
- temp = trap_Cvar_VariableValue( "g_friendlyFire" );
- trap_Cvar_Set("ui_friendlyFire", va("%i", temp));
- temp = trap_Cvar_VariableValue( "sv_maxClients" );
- trap_Cvar_Set("ui_maxClients", va("%i", temp));
- temp = trap_Cvar_VariableValue( "g_warmup" );
- trap_Cvar_Set("ui_Warmup", va("%i", temp));
- temp = trap_Cvar_VariableValue( "sv_pure" );
- trap_Cvar_Set("ui_pure", va("%i", temp));
-
- trap_Cvar_Set("cg_cameraOrbit", "0");
- trap_Cvar_Set("cg_thirdPerson", "0");
- trap_Cvar_Set("cg_drawTimer", "1");
- trap_Cvar_Set("g_doWarmup", "1");
- trap_Cvar_Set("g_warmup", "15");
- trap_Cvar_Set("sv_pure", "0");
- trap_Cvar_Set("g_friendlyFire", "0");
- trap_Cvar_Set("g_redTeam", UI_Cvar_VariableString("ui_teamName"));
- trap_Cvar_Set("g_blueTeam", UI_Cvar_VariableString("ui_opponentName"));
-
- if (trap_Cvar_VariableValue("ui_recordSPDemo")) {
- Com_sprintf(buff, MAX_STRING_CHARS, "%s_%i", uiInfo.mapList[ui_currentMap.integer].mapLoadName, g);
- trap_Cvar_Set("ui_recordSPDemoName", buff);
- }
-
- delay = 500;
-
- {
- temp = uiInfo.mapList[ui_currentMap.integer].teamMembers * 2;
- trap_Cvar_Set("sv_maxClients", va("%d", temp));
- for (i =0; i < uiInfo.mapList[ui_currentMap.integer].teamMembers; i++) {
- Com_sprintf( buff, sizeof(buff), "addbot %s %f %s %i %s\n", UI_AIFromName(uiInfo.teamList[k].teamMembers[i]), skill, "", delay, uiInfo.teamList[k].teamMembers[i]);
- trap_Cmd_ExecuteText( EXEC_APPEND, buff );
- delay += 500;
- }
- k = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
- for (i =0; i < uiInfo.mapList[ui_currentMap.integer].teamMembers-1; i++) {
- Com_sprintf( buff, sizeof(buff), "addbot %s %f %s %i %s\n", UI_AIFromName(uiInfo.teamList[k].teamMembers[i]), skill, "", delay, uiInfo.teamList[k].teamMembers[i]);
- trap_Cmd_ExecuteText( EXEC_APPEND, buff );
- delay += 500;
- }
- }
-}
-
-static void UI_Update(const char *name) {
- int val = trap_Cvar_VariableValue(name);
-
- if (Q_stricmp(name, "ui_SetName") == 0) {
- trap_Cvar_Set( "name", UI_Cvar_VariableString("ui_Name"));
- } else if (Q_stricmp(name, "ui_setRate") == 0) {
- float rate = trap_Cvar_VariableValue("rate");
- if (rate >= 5000) {
- trap_Cvar_Set("cl_maxpackets", "30");
- trap_Cvar_Set("cl_packetdup", "1");
- } else if (rate >= 4000) {
- trap_Cvar_Set("cl_maxpackets", "15");
- trap_Cvar_Set("cl_packetdup", "2"); // favor less prediction errors when there's packet loss
- } else {
- trap_Cvar_Set("cl_maxpackets", "15");
- trap_Cvar_Set("cl_packetdup", "1"); // favor lower bandwidth
- }
- } else if (Q_stricmp(name, "ui_GetName") == 0) {
- trap_Cvar_Set( "ui_Name", UI_Cvar_VariableString("name"));
- } else if (Q_stricmp(name, "r_colorbits") == 0) {
- switch (val) {
- case 0:
- trap_Cvar_SetValue( "r_depthbits", 0 );
- trap_Cvar_SetValue( "r_stencilbits", 0 );
- break;
- case 16:
- trap_Cvar_SetValue( "r_depthbits", 16 );
- trap_Cvar_SetValue( "r_stencilbits", 0 );
- break;
- case 32:
- trap_Cvar_SetValue( "r_depthbits", 24 );
- break;
- }
- } else if (Q_stricmp(name, "r_lodbias") == 0) {
- switch (val) {
- case 0:
- trap_Cvar_SetValue( "r_subdivisions", 4 );
- break;
- case 1:
- trap_Cvar_SetValue( "r_subdivisions", 12 );
- break;
- case 2:
- trap_Cvar_SetValue( "r_subdivisions", 20 );
- break;
- }
- } else if (Q_stricmp(name, "ui_glCustom") == 0) {
- switch (val) {
- case 0: // high quality
- trap_Cvar_SetValue( "r_fullScreen", 1 );
- trap_Cvar_SetValue( "r_subdivisions", 4 );
- trap_Cvar_SetValue( "r_vertexlight", 0 );
- trap_Cvar_SetValue( "r_lodbias", 0 );
- trap_Cvar_SetValue( "r_colorbits", 32 );
- trap_Cvar_SetValue( "r_depthbits", 24 );
- trap_Cvar_SetValue( "r_picmip", 0 );
- trap_Cvar_SetValue( "r_mode", 4 );
- trap_Cvar_SetValue( "r_texturebits", 32 );
- trap_Cvar_SetValue( "r_fastSky", 0 );
- trap_Cvar_SetValue( "r_inGameVideo", 1 );
- trap_Cvar_SetValue( "cg_shadows", 1 );
- trap_Cvar_SetValue( "cg_brassTime", 2500 );
- trap_Cvar_SetValue( "cg_bounceParticles", 1 );
- trap_Cvar_Set( "r_texturemode", "GL_LINEAR_MIPMAP_LINEAR" );
- break;
- case 1: // normal
- trap_Cvar_SetValue( "r_fullScreen", 1 );
- trap_Cvar_SetValue( "r_subdivisions", 12 );
- trap_Cvar_SetValue( "r_vertexlight", 0 );
- trap_Cvar_SetValue( "r_lodbias", 0 );
- trap_Cvar_SetValue( "r_colorbits", 0 );
- trap_Cvar_SetValue( "r_depthbits", 24 );
- trap_Cvar_SetValue( "r_picmip", 1 );
- trap_Cvar_SetValue( "r_mode", 3 );
- trap_Cvar_SetValue( "r_texturebits", 0 );
- trap_Cvar_SetValue( "r_fastSky", 0 );
- trap_Cvar_SetValue( "r_inGameVideo", 1 );
- trap_Cvar_SetValue( "cg_brassTime", 2500 );
- trap_Cvar_Set( "r_texturemode", "GL_LINEAR_MIPMAP_LINEAR" );
- trap_Cvar_SetValue( "cg_shadows", 0 );
- trap_Cvar_SetValue( "cg_bounceParticles", 0 );
- break;
- case 2: // fast
- trap_Cvar_SetValue( "r_fullScreen", 1 );
- trap_Cvar_SetValue( "r_subdivisions", 8 );
- trap_Cvar_SetValue( "r_vertexlight", 0 );
- trap_Cvar_SetValue( "r_lodbias", 1 );
- trap_Cvar_SetValue( "r_colorbits", 0 );
- trap_Cvar_SetValue( "r_depthbits", 0 );
- trap_Cvar_SetValue( "r_picmip", 1 );
- trap_Cvar_SetValue( "r_mode", 3 );
- trap_Cvar_SetValue( "r_texturebits", 0 );
- trap_Cvar_SetValue( "cg_shadows", 0 );
- trap_Cvar_SetValue( "r_fastSky", 1 );
- trap_Cvar_SetValue( "r_inGameVideo", 0 );
- trap_Cvar_SetValue( "cg_brassTime", 0 );
- trap_Cvar_SetValue( "cg_bounceParticles", 0 );
- trap_Cvar_Set( "r_texturemode", "GL_LINEAR_MIPMAP_NEAREST" );
- break;
- case 3: // fastest
- trap_Cvar_SetValue( "r_fullScreen", 1 );
- trap_Cvar_SetValue( "r_subdivisions", 20 );
- trap_Cvar_SetValue( "r_vertexlight", 1 );
- trap_Cvar_SetValue( "r_lodbias", 2 );
- trap_Cvar_SetValue( "r_colorbits", 16 );
- trap_Cvar_SetValue( "r_depthbits", 16 );
- trap_Cvar_SetValue( "r_mode", 3 );
- trap_Cvar_SetValue( "r_picmip", 2 );
- trap_Cvar_SetValue( "r_texturebits", 16 );
- trap_Cvar_SetValue( "cg_shadows", 0 );
- trap_Cvar_SetValue( "cg_brassTime", 0 );
- trap_Cvar_SetValue( "r_fastSky", 1 );
- trap_Cvar_SetValue( "r_inGameVideo", 0 );
- trap_Cvar_SetValue( "cg_bounceParticles", 0 );
- trap_Cvar_Set( "r_texturemode", "GL_LINEAR_MIPMAP_NEAREST" );
- break;
- }
- } else if (Q_stricmp(name, "ui_mousePitch") == 0) {
- if (val == 0) {
- trap_Cvar_SetValue( "m_pitch", 0.022f );
- } else {
- trap_Cvar_SetValue( "m_pitch", -0.022f );
+ uiInfo.demoList[i] = String_Alloc(demoname);
+ demoname += len + 1;
+ }
+ }
}
- }
}
-static void UI_RunMenuScript(char **args) {
- const char *name, *name2;
- char buff[1024];
- const char *cmd;
-
- if (String_Parse(args, &name)) {
- if (Q_stricmp(name, "StartServer") == 0) {
- int i, clients, oldclients;
- float skill;
- trap_Cvar_Set("cg_thirdPerson", "0");
- trap_Cvar_Set("cg_cameraOrbit", "0");
- trap_Cvar_Set("ui_singlePlayerActive", "0");
- trap_Cvar_SetValue( "dedicated", Com_Clamp( 0, 2, ui_dedicated.integer ) );
- trap_Cvar_SetValue( "g_gametype", Com_Clamp( 0, 8, uiInfo.gameTypes[ui_netGameType.integer].gtEnum ) );
- trap_Cvar_Set("g_redTeam", UI_Cvar_VariableString("ui_teamName"));
- trap_Cvar_Set("g_blueTeam", UI_Cvar_VariableString("ui_opponentName"));
- trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait ; wait ; map %s\n", uiInfo.mapList[ui_currentNetMap.integer].mapLoadName ) );
- skill = trap_Cvar_VariableValue( "g_spSkill" );
- // set max clients based on spots
- oldclients = trap_Cvar_VariableValue( "sv_maxClients" );
- clients = 0;
- for (i = 0; i < PLAYERS_PER_TEAM; i++) {
- int bot = trap_Cvar_VariableValue( va("ui_blueteam%i", i+1));
- if (bot >= 0) {
- clients++;
- }
- bot = trap_Cvar_VariableValue( va("ui_redteam%i", i+1));
- if (bot >= 0) {
- clients++;
- }
- }
- if (clients == 0) {
- clients = 8;
- }
-
- if (oldclients > clients) {
- clients = oldclients;
- }
+static void UI_Update(const char *name)
+{
+ int val = trap_Cvar_VariableValue(name);
- trap_Cvar_Set("sv_maxClients", va("%d",clients));
+ if (Q_stricmp(name, "ui_SetName") == 0)
+ trap_Cvar_Set("name", UI_Cvar_VariableString("ui_Name"));
+ else if (Q_stricmp(name, "ui_setRate") == 0)
+ {
+ float rate = trap_Cvar_VariableValue("rate");
- for (i = 0; i < PLAYERS_PER_TEAM; i++) {
- int bot = trap_Cvar_VariableValue( va("ui_blueteam%i", i+1));
- if (bot > 1) {
- Com_sprintf( buff, sizeof(buff), "addbot %s %f \n", UI_GetBotNameByNumber(bot-2), skill);
- trap_Cmd_ExecuteText( EXEC_APPEND, buff );
+ if (rate >= 5000)
+ {
+ trap_Cvar_Set("cl_maxpackets", "30");
+ trap_Cvar_Set("cl_packetdup", "1");
}
- bot = trap_Cvar_VariableValue( va("ui_redteam%i", i+1));
- if (bot > 1) {
- Com_sprintf( buff, sizeof(buff), "addbot %s %f \n", UI_GetBotNameByNumber(bot-2), skill);
- trap_Cmd_ExecuteText( EXEC_APPEND, buff );
+ else if (rate >= 4000)
+ {
+ trap_Cvar_Set("cl_maxpackets", "15");
+ trap_Cvar_Set("cl_packetdup", "2"); // favor less prediction errors when there's packet loss
+ }
+ else
+ {
+ trap_Cvar_Set("cl_maxpackets", "15");
+ trap_Cvar_Set("cl_packetdup", "1"); // favor lower bandwidth
}
- }
- } else if (Q_stricmp(name, "updateSPMenu") == 0) {
- UI_SetCapFragLimits(qtrue);
- UI_MapCountByGameType(qtrue);
- ui_mapIndex.integer = UI_GetIndexFromSelection(ui_currentMap.integer);
- trap_Cvar_Set("ui_mapIndex", va("%d", ui_mapIndex.integer));
- Menu_SetFeederSelection(NULL, FEEDER_MAPS, ui_mapIndex.integer, "skirmish");
- UI_GameType_HandleKey(0, NULL, K_MOUSE1, qfalse);
- UI_GameType_HandleKey(0, NULL, K_MOUSE2, qfalse);
- } else if (Q_stricmp(name, "resetDefaults") == 0) {
- trap_Cmd_ExecuteText( EXEC_APPEND, "exec default.cfg\n");
- trap_Cmd_ExecuteText( EXEC_APPEND, "cvar_restart\n");
- Controls_SetDefaults();
- trap_Cvar_Set("com_introPlayed", "1" );
- trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart\n" );
- } else if (Q_stricmp(name, "loadArenas") == 0) {
- UI_LoadArenas();
- UI_MapCountByGameType(qfalse);
- Menu_SetFeederSelection(NULL, FEEDER_ALLMAPS, 0, "createserver");
- } else if (Q_stricmp(name, "loadServerInfo") == 0) {
- UI_ServerInfo();
- } else if (Q_stricmp(name, "saveControls") == 0) {
- Controls_SetConfig(qtrue);
- } else if (Q_stricmp(name, "loadControls") == 0) {
- Controls_GetConfig();
- } else if (Q_stricmp(name, "clearError") == 0) {
- trap_Cvar_Set("com_errorMessage", "");
- } else if (Q_stricmp(name, "loadGameInfo") == 0) {
-/* UI_ParseGameInfo("gameinfo.txt");
- UI_LoadBestScores(uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum);*/
- } else if (Q_stricmp(name, "resetScores") == 0) {
- UI_ClearScores();
- } else if (Q_stricmp(name, "RefreshServers") == 0) {
- UI_StartServerRefresh(qtrue);
- UI_BuildServerDisplayList(qtrue);
- } else if (Q_stricmp(name, "InitServerList") == 0) {
- int time = trap_RealTime( NULL );
- int last;
- int sortColumn;
-
- // set up default sorting
- if(!uiInfo.serverStatus.sorted && Int_Parse(args, &sortColumn))
- {
- uiInfo.serverStatus.sortKey = sortColumn;
- uiInfo.serverStatus.sortDir = 0;
- }
-
- // refresh if older than 3 days or if list is empty
- last = atoi( UI_Cvar_VariableString( va( "ui_lastServerRefresh_%i_time",
- ui_netSource.integer ) ) );
- if( trap_LAN_GetServerCount( ui_netSource.integer ) < 1 ||
- ( time - last ) > 3600 )
- {
- UI_StartServerRefresh(qtrue);
- UI_BuildServerDisplayList(qtrue);
- }
- } else if (Q_stricmp(name, "RefreshFilter") == 0) {
- UI_StartServerRefresh(qfalse);
- UI_BuildServerDisplayList(qtrue);
- } else if (Q_stricmp(name, "RunSPDemo") == 0) {
- if (uiInfo.demoAvailable) {
- trap_Cmd_ExecuteText( EXEC_APPEND, va("demo %s_%i\n", uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum));
- }
- } else if (Q_stricmp(name, "LoadDemos") == 0) {
- UI_LoadDemos();
- } else if (Q_stricmp(name, "LoadMovies") == 0) {
- UI_LoadMovies();
- } else if (Q_stricmp(name, "LoadMods") == 0) {
- UI_LoadMods();
- }
-
-//TA: tremulous menus
- else if( Q_stricmp( name, "LoadTeams" ) == 0 )
- UI_LoadTremTeams( );
- else if( Q_stricmp( name, "JoinTeam" ) == 0 )
- {
- if( ( cmd = uiInfo.tremTeamList[ uiInfo.tremTeamIndex ].cmd ) )
- trap_Cmd_ExecuteText( EXEC_APPEND, cmd );
- }
- else if( Q_stricmp( name, "LoadHumanItems" ) == 0 )
- UI_LoadTremHumanItems( );
- else if( Q_stricmp( name, "SpawnWithHumanItem" ) == 0 )
- {
- if( ( cmd = uiInfo.tremHumanItemList[ uiInfo.tremHumanItemIndex ].cmd ) )
- trap_Cmd_ExecuteText( EXEC_APPEND, cmd );
- }
- else if( Q_stricmp( name, "LoadAlienClasses" ) == 0 )
- UI_LoadTremAlienClasses( );
- else if( Q_stricmp( name, "SpawnAsAlienClass" ) == 0 )
- {
- if( ( cmd = uiInfo.tremAlienClassList[ uiInfo.tremAlienClassIndex ].cmd ) )
- trap_Cmd_ExecuteText( EXEC_APPEND, cmd );
- }
- else if( Q_stricmp( name, "LoadHumanArmouryBuys" ) == 0 )
- UI_LoadTremHumanArmouryBuys( );
- else if( Q_stricmp( name, "BuyFromArmoury" ) == 0 )
- {
- if( ( cmd = uiInfo.tremHumanArmouryBuyList[ uiInfo.tremHumanArmouryBuyIndex ].cmd ) )
- trap_Cmd_ExecuteText( EXEC_APPEND, cmd );
}
- else if( Q_stricmp( name, "LoadHumanArmourySells" ) == 0 )
- UI_LoadTremHumanArmourySells( );
- else if( Q_stricmp( name, "SellToArmoury" ) == 0 )
+ else if (Q_stricmp(name, "ui_GetName") == 0)
+ trap_Cvar_Set("ui_Name", UI_Cvar_VariableString("name"));
+ else if (Q_stricmp(name, "r_colorbits") == 0)
{
- if( ( cmd = uiInfo.tremHumanArmourySellList[ uiInfo.tremHumanArmourySellIndex ].cmd ) )
- trap_Cmd_ExecuteText( EXEC_APPEND, cmd );
+ switch (val)
+ {
+ case 0:
+ trap_Cvar_SetValue("r_depthbits", 0);
+ trap_Cvar_SetValue("r_stencilbits", 0);
+ break;
+
+ case 16:
+ trap_Cvar_SetValue("r_depthbits", 16);
+ trap_Cvar_SetValue("r_stencilbits", 0);
+ break;
+
+ case 32:
+ trap_Cvar_SetValue("r_depthbits", 24);
+ break;
+ }
}
- else if( Q_stricmp( name, "LoadAlienUpgrades" ) == 0 )
+ else if (Q_stricmp(name, "r_lodbias") == 0)
{
- UI_LoadTremAlienUpgrades( );
+ switch (val)
+ {
+ case 0:
+ trap_Cvar_SetValue("r_subdivisions", 4);
+ break;
- //disallow the menu if it would be empty
- if( uiInfo.tremAlienUpgradeCount <= 0 )
- Menus_CloseAll( );
- }
- else if( Q_stricmp( name, "UpgradeToNewClass" ) == 0 )
- {
- if( ( cmd = uiInfo.tremAlienUpgradeList[ uiInfo.tremAlienUpgradeIndex ].cmd ) )
- trap_Cmd_ExecuteText( EXEC_APPEND, cmd );
+ case 1:
+ trap_Cvar_SetValue("r_subdivisions", 12);
+ break;
+
+ case 2:
+ trap_Cvar_SetValue("r_subdivisions", 20);
+ break;
+ }
}
- else if( Q_stricmp( name, "LoadAlienBuilds" ) == 0 )
- UI_LoadTremAlienBuilds( );
- else if( Q_stricmp( name, "BuildAlienBuildable" ) == 0 )
+ else if (Q_stricmp(name, "ui_glCustom") == 0)
{
- if( ( cmd = uiInfo.tremAlienBuildList[ uiInfo.tremAlienBuildIndex ].cmd ) )
- trap_Cmd_ExecuteText( EXEC_APPEND, cmd );
+ switch (val)
+ {
+ case 0: // high quality
+ trap_Cvar_SetValue("r_subdivisions", 4);
+ trap_Cvar_SetValue("r_vertexlight", 0);
+ trap_Cvar_SetValue("r_lodbias", 0);
+ trap_Cvar_SetValue("r_colorbits", 32);
+ trap_Cvar_SetValue("r_depthbits", 24);
+ trap_Cvar_SetValue("r_picmip", 0);
+ trap_Cvar_SetValue("r_texturebits", 32);
+ trap_Cvar_SetValue("r_fastSky", 0);
+ trap_Cvar_SetValue("r_inGameVideo", 1);
+ trap_Cvar_SetValue("cg_shadows", 1);
+ trap_Cvar_SetValue("cg_bounceParticles", 1);
+ trap_Cvar_Set("r_texturemode", "GL_LINEAR_MIPMAP_LINEAR");
+ break;
+
+ case 1: // normal
+ trap_Cvar_SetValue("r_subdivisions", 12);
+ trap_Cvar_SetValue("r_vertexlight", 0);
+ trap_Cvar_SetValue("r_lodbias", 0);
+ trap_Cvar_SetValue("r_colorbits", 0);
+ trap_Cvar_SetValue("r_depthbits", 24);
+ trap_Cvar_SetValue("r_picmip", 1);
+ trap_Cvar_SetValue("r_texturebits", 0);
+ trap_Cvar_SetValue("r_fastSky", 0);
+ trap_Cvar_SetValue("r_inGameVideo", 1);
+ trap_Cvar_Set("r_texturemode", "GL_LINEAR_MIPMAP_LINEAR");
+ trap_Cvar_SetValue("cg_shadows", 0);
+ trap_Cvar_SetValue("cg_bounceParticles", 0);
+ break;
+
+ case 2: // fast
+ trap_Cvar_SetValue("r_subdivisions", 8);
+ trap_Cvar_SetValue("r_vertexlight", 0);
+ trap_Cvar_SetValue("r_lodbias", 1);
+ trap_Cvar_SetValue("r_colorbits", 0);
+ trap_Cvar_SetValue("r_depthbits", 0);
+ trap_Cvar_SetValue("r_picmip", 1);
+ trap_Cvar_SetValue("r_texturebits", 0);
+ trap_Cvar_SetValue("cg_shadows", 0);
+ trap_Cvar_SetValue("r_fastSky", 1);
+ trap_Cvar_SetValue("r_inGameVideo", 0);
+ trap_Cvar_SetValue("cg_bounceParticles", 0);
+ trap_Cvar_Set("r_texturemode", "GL_LINEAR_MIPMAP_NEAREST");
+ break;
+
+ case 3: // fastest
+ trap_Cvar_SetValue("r_subdivisions", 20);
+ trap_Cvar_SetValue("r_vertexlight", 1);
+ trap_Cvar_SetValue("r_lodbias", 2);
+ trap_Cvar_SetValue("r_colorbits", 16);
+ trap_Cvar_SetValue("r_depthbits", 16);
+ trap_Cvar_SetValue("r_picmip", 2);
+ trap_Cvar_SetValue("r_texturebits", 16);
+ trap_Cvar_SetValue("cg_shadows", 0);
+ trap_Cvar_SetValue("r_fastSky", 1);
+ trap_Cvar_SetValue("r_inGameVideo", 0);
+ trap_Cvar_SetValue("cg_bounceParticles", 0);
+ trap_Cvar_Set("r_texturemode", "GL_LINEAR_MIPMAP_NEAREST");
+ break;
+ }
}
- else if( Q_stricmp( name, "LoadHumanBuilds" ) == 0 )
- UI_LoadTremHumanBuilds( );
- else if( Q_stricmp( name, "BuildHumanBuildable" ) == 0 )
+ else if (Q_stricmp(name, "ui_mousePitch") == 0)
{
- if( ( cmd = uiInfo.tremHumanBuildList[ uiInfo.tremHumanBuildIndex ].cmd ) )
- trap_Cmd_ExecuteText( EXEC_APPEND, cmd );
+ if (val == 0)
+ trap_Cvar_SetValue("m_pitch", 0.022f);
+ else
+ trap_Cvar_SetValue("m_pitch", -0.022f);
}
- else if( Q_stricmp( name, "Say" ) == 0 )
- {
- char buffer[ MAX_CVAR_VALUE_STRING ];
- trap_Cvar_VariableStringBuffer( "ui_sayBuffer", buffer, sizeof( buffer ) );
+}
- if( !buffer[ 0 ] )
- ;
- else if( ui_chatCommands.integer && ( buffer[ 0 ] == '/' ||
- buffer[ 0 ] == '\\' ) )
- {
- trap_Cmd_ExecuteText( EXEC_APPEND, va( "%s\n", buffer + 1 ) );
- }
- else if( uiInfo.chatTeam )
- trap_Cmd_ExecuteText( EXEC_APPEND, va( "say_team \"%s\"\n", buffer ) );
- else
- trap_Cmd_ExecuteText( EXEC_APPEND, va( "say \"%s\"\n", buffer ) );
- }
- else if( Q_stricmp( name, "PTRCRestore" ) == 0 )
+// FIXME: lookup table
+static void UI_RunMenuScript(char **args)
+{
+ const char *name, *name2;
+ char buff[1024];
+ const char *cmd;
+
+ if (String_Parse(args, &name))
{
- int len;
- char text[ 16 ];
- fileHandle_t f;
- char command[ 32 ];
+ if (Q_stricmp(name, "StartServer") == 0)
+ {
+ trap_Cvar_SetValue("dedicated", Com_Clamp(0, 2, ui_dedicated.integer));
+ trap_Cmd_ExecuteText(
+ EXEC_APPEND, va("wait ; wait ; map \"%s\"\n", uiInfo.mapList[ui_selectedMap.integer].mapLoadName));
+ }
+ else if (Q_stricmp(name, "resetDefaults") == 0)
+ {
+ trap_Cmd_ExecuteText(EXEC_APPEND, "exec default.cfg\n");
+ trap_Cmd_ExecuteText(EXEC_APPEND, "cvar_restart\n");
+ Controls_SetDefaults();
+ trap_Cvar_Set("com_introPlayed", "1");
+ trap_Cmd_ExecuteText(EXEC_APPEND, "vid_restart\n");
+ }
+ else if (Q_stricmp(name, "loadArenas") == 0)
+ {
+ UI_LoadArenas();
+ Menu_SetFeederSelection(NULL, FEEDER_MAPS, 0, "createserver");
+ }
+ else if (Q_stricmp(name, "loadServerInfo") == 0)
+ UI_ServerInfo();
+ else if (Q_stricmp(name, "getNews") == 0)
+ UI_UpdateNews(qtrue);
+ else if (Q_stricmp(name, "checkForUpdate") == 0)
+ UI_UpdateGithubRelease();
+ else if (Q_stricmp(name, "downloadUpdate") == 0)
+ trap_Cmd_ExecuteText(EXEC_APPEND, "downloadUpdate");
+ else if (Q_stricmp(name, "installUpdate") == 0)
+ trap_Cmd_ExecuteText(EXEC_APPEND, "installUpdate");
+ else if (Q_stricmp(name, "saveControls") == 0)
+ Controls_SetConfig(qtrue);
+ else if (Q_stricmp(name, "loadControls") == 0)
+ Controls_GetConfig();
+ else if (Q_stricmp(name, "clearError") == 0)
+ {
+ trap_Cvar_Set("com_errorMessage", "");
+ }
+ else if (Q_stricmp(name, "clearDemoError") == 0)
+ {
+ trap_Cvar_Set("com_demoErrorMessage", "");
+ }
+ else if (Q_stricmp(name, "downloadIgnore") == 0)
+ {
+ trap_Cvar_Set("com_downloadPrompt", va("%d", DLP_IGNORE));
+ }
+ else if (Q_stricmp(name, "downloadCURL") == 0)
+ {
+ trap_Cvar_Set("com_downloadPrompt", va("%d", DLP_CURL));
+ }
+ else if (Q_stricmp(name, "downloadUDP") == 0)
+ {
+ trap_Cvar_Set("com_downloadPrompt", va("%d", DLP_UDP));
+ }
+ else if (Q_stricmp(name, "RefreshServers") == 0)
+ {
+ UI_StartServerRefresh(qtrue);
+ UI_BuildServerDisplayList(qtrue);
+ }
+ else if (Q_stricmp(name, "InitServerList") == 0)
+ {
+ int time = trap_RealTime(NULL);
+ int last;
+ int sortColumn;
- // load the file
- len = trap_FS_FOpenFile( "ptrc.cfg", &f, FS_READ );
+ // set up default sorting
- if( len > 0 && ( len < sizeof( text ) - 1 ) )
- {
- trap_FS_Read( text, len, f );
- text[ len ] = 0;
- trap_FS_FCloseFile( f );
+ if (!uiInfo.serverStatus.sorted && Int_Parse(args, &sortColumn))
+ {
+ uiInfo.serverStatus.sortKey = sortColumn;
+ uiInfo.serverStatus.sortDir = 0;
+ }
- Com_sprintf( command, 32, "ptrcrestore %s", text );
+ // refresh if older than 3 days or if list is empty
+ last = atoi(UI_Cvar_VariableString(va("ui_lastServerRefresh_%i_time", ui_netSource.integer)));
- trap_Cmd_ExecuteText( EXEC_APPEND, command );
- }
- }
-//TA: tremulous menus
+ if (trap_LAN_GetServerCount(ui_netSource.integer) < 1 || (time - last) > 3600)
+ {
+ UI_StartServerRefresh(qtrue);
+ UI_BuildServerDisplayList(qtrue);
+ }
+ }
+ else if (Q_stricmp(name, "RefreshFilter") == 0)
+ {
+ UI_StartServerRefresh(qfalse);
+ UI_BuildServerDisplayList(qtrue);
+ }
+ else if (Q_stricmp(name, "LoadDemos") == 0)
+ UI_LoadDemos();
+ else if (Q_stricmp(name, "LoadMovies") == 0)
+ UI_LoadMovies();
+ else if (Q_stricmp(name, "LoadMods") == 0)
+ UI_LoadMods();
+ else if (Q_stricmp(name, "LoadTeams") == 0)
+ UI_LoadTeams();
+ else if (Q_stricmp(name, "JoinTeam") == 0)
+ {
+ if ((cmd = uiInfo.teamList[uiInfo.teamIndex].cmd))
+ trap_Cmd_ExecuteText(EXEC_APPEND, cmd);
+ }
+ else if (Q_stricmp(name, "LoadHumanItems") == 0)
+ UI_LoadHumanItems();
+ else if (Q_stricmp(name, "SpawnWithHumanItem") == 0)
+ {
+ if ((cmd = uiInfo.humanItemList[uiInfo.humanItemIndex].cmd))
+ trap_Cmd_ExecuteText(EXEC_APPEND, cmd);
+ }
+ else if (Q_stricmp(name, "LoadAlienClasses") == 0)
+ UI_LoadAlienClasses();
+ else if (Q_stricmp(name, "SpawnAsAlienClass") == 0)
+ {
+ if ((cmd = uiInfo.alienClassList[uiInfo.alienClassIndex].cmd))
+ trap_Cmd_ExecuteText(EXEC_APPEND, cmd);
+ }
+ else if (Q_stricmp(name, "LoadHumanArmouryBuys") == 0)
+ UI_LoadHumanArmouryBuys();
+ else if (Q_stricmp(name, "BuyFromArmoury") == 0)
+ {
+ if ((cmd = uiInfo.humanArmouryBuyList[uiInfo.humanArmouryBuyIndex].cmd))
+ trap_Cmd_ExecuteText(EXEC_APPEND, cmd);
- else if (Q_stricmp(name, "playMovie") == 0) {
- if (uiInfo.previewMovie >= 0) {
- trap_CIN_StopCinematic(uiInfo.previewMovie);
- }
- trap_Cmd_ExecuteText( EXEC_APPEND, va("cinematic %s.roq 2\n", uiInfo.movieList[uiInfo.movieIndex]));
- } else if (Q_stricmp(name, "RunMod") == 0) {
- trap_Cvar_Set( "fs_game", uiInfo.modList[uiInfo.modIndex].modName);
- trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart;" );
- } else if (Q_stricmp(name, "RunDemo") == 0) {
- trap_Cmd_ExecuteText( EXEC_APPEND, va("demo %s\n", uiInfo.demoList[uiInfo.demoIndex]));
- } else if (Q_stricmp(name, "Tremulous") == 0) {
- trap_Cvar_Set( "fs_game", "");
- trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart;" );
- } else if (Q_stricmp(name, "closeJoin") == 0) {
- if (uiInfo.serverStatus.refreshActive) {
- UI_StopServerRefresh();
- uiInfo.serverStatus.nextDisplayRefresh = 0;
- uiInfo.nextServerStatusRefresh = 0;
- uiInfo.nextFindPlayerRefresh = 0;
- UI_BuildServerDisplayList(qtrue);
- } else {
- Menus_CloseByName("joinserver");
- Menus_OpenByName("main");
- }
- } else if (Q_stricmp(name, "StopRefresh") == 0) {
- UI_StopServerRefresh();
- uiInfo.serverStatus.nextDisplayRefresh = 0;
- uiInfo.nextServerStatusRefresh = 0;
- uiInfo.nextFindPlayerRefresh = 0;
- } else if (Q_stricmp(name, "UpdateFilter") == 0) {
- if (ui_netSource.integer == AS_LOCAL) {
- UI_StartServerRefresh(qtrue);
- }
- UI_BuildServerDisplayList(qtrue);
- UI_FeederSelection(FEEDER_SERVERS, 0);
- } else if (Q_stricmp(name, "ServerStatus") == 0) {
- trap_LAN_GetServerAddressString(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], uiInfo.serverStatusAddress, sizeof(uiInfo.serverStatusAddress));
- UI_BuildServerStatus(qtrue);
- } else if (Q_stricmp(name, "FoundPlayerServerStatus") == 0) {
- Q_strncpyz(uiInfo.serverStatusAddress, uiInfo.foundPlayerServerAddresses[uiInfo.currentFoundPlayerServer], sizeof(uiInfo.serverStatusAddress));
- UI_BuildServerStatus(qtrue);
- Menu_SetFeederSelection(NULL, FEEDER_FINDPLAYER, 0, NULL);
- } else if (Q_stricmp(name, "FindPlayer") == 0) {
- UI_BuildFindPlayerList(qtrue);
- // clear the displayed server status info
- uiInfo.serverStatusInfo.numLines = 0;
- Menu_SetFeederSelection(NULL, FEEDER_FINDPLAYER, 0, NULL);
- } else if (Q_stricmp(name, "JoinServer") == 0) {
- trap_Cvar_Set("cg_thirdPerson", "0");
- trap_Cvar_Set("cg_cameraOrbit", "0");
- trap_Cvar_Set("ui_singlePlayerActive", "0");
- if (uiInfo.serverStatus.currentServer >= 0 && uiInfo.serverStatus.currentServer < uiInfo.serverStatus.numDisplayServers) {
- trap_LAN_GetServerAddressString(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], buff, 1024);
- trap_Cmd_ExecuteText( EXEC_APPEND, va( "connect %s\n", buff ) );
- }
- } else if (Q_stricmp(name, "FoundPlayerJoinServer") == 0) {
- trap_Cvar_Set("ui_singlePlayerActive", "0");
- if (uiInfo.currentFoundPlayerServer >= 0 && uiInfo.currentFoundPlayerServer < uiInfo.numFoundPlayerServers) {
- trap_Cmd_ExecuteText( EXEC_APPEND, va( "connect %s\n", uiInfo.foundPlayerServerAddresses[uiInfo.currentFoundPlayerServer] ) );
- }
- } else if (Q_stricmp(name, "Quit") == 0) {
- trap_Cvar_Set("ui_singlePlayerActive", "0");
- trap_Cmd_ExecuteText( EXEC_NOW, "quit");
- } else if (Q_stricmp(name, "Controls") == 0) {
- trap_Cvar_Set( "cl_paused", "1" );
- trap_Key_SetCatcher( KEYCATCH_UI );
- Menus_CloseAll();
- Menus_ActivateByName("setup_menu2");
- } else if (Q_stricmp(name, "Leave") == 0) {
- trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect\n" );
- trap_Key_SetCatcher( KEYCATCH_UI );
- Menus_CloseAll();
- Menus_ActivateByName("main");
- } else if (Q_stricmp(name, "ServerSort") == 0) {
- int sortColumn;
- if (Int_Parse(args, &sortColumn)) {
- // if same column we're already sorting on then flip the direction
- if (sortColumn == uiInfo.serverStatus.sortKey) {
- uiInfo.serverStatus.sortDir = !uiInfo.serverStatus.sortDir;
- }
- // make sure we sort again
- UI_ServersSort(sortColumn, qtrue);
- uiInfo.serverStatus.sorted = qtrue;
- }
- } else if (Q_stricmp(name, "nextSkirmish") == 0) {
- UI_StartSkirmish(qtrue);
- } else if (Q_stricmp(name, "SkirmishStart") == 0) {
- UI_StartSkirmish(qfalse);
- } else if (Q_stricmp(name, "closeingame") == 0) {
- trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI );
- trap_Key_ClearStates();
- trap_Cvar_Set( "cl_paused", "0" );
- Menus_CloseAll();
- } else if (Q_stricmp(name, "voteMap") == 0) {
- if (ui_currentNetMap.integer >=0 && ui_currentNetMap.integer < uiInfo.mapCount) {
- trap_Cmd_ExecuteText( EXEC_APPEND, va("callvote map %s\n",uiInfo.mapList[ui_currentNetMap.integer].mapLoadName) );
- }
- }
- else if( Q_stricmp( name, "voteKick" ) == 0 )
- {
- if( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount )
- {
- trap_Cmd_ExecuteText( EXEC_APPEND, va( "callvote kick %d\n",
- uiInfo.clientNums[ uiInfo.playerIndex ] ) );
- }
- }
- else if( Q_stricmp( name, "voteMute" ) == 0 )
- {
- if( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount )
- {
- trap_Cmd_ExecuteText( EXEC_APPEND, va( "callvote mute %d\n",
- uiInfo.clientNums[ uiInfo.playerIndex ] ) );
- }
- }
- else if( Q_stricmp( name, "voteUnMute" ) == 0 )
- {
- if( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount )
- {
- trap_Cmd_ExecuteText( EXEC_APPEND, va( "callvote unmute %d\n",
- uiInfo.clientNums[ uiInfo.playerIndex ] ) );
- }
- }
- else if( Q_stricmp( name, "voteTeamKick" ) == 0 )
- {
- if( uiInfo.teamIndex >= 0 && uiInfo.teamIndex < uiInfo.myTeamCount )
- {
- trap_Cmd_ExecuteText( EXEC_APPEND, va( "callteamvote kick %d\n",
- uiInfo.teamClientNums[ uiInfo.teamIndex ] ) );
- }
- }
- else if( Q_stricmp( name, "voteTeamDenyBuild" ) == 0 )
- {
- if( uiInfo.teamIndex >= 0 && uiInfo.teamIndex < uiInfo.myTeamCount )
- {
- trap_Cmd_ExecuteText( EXEC_APPEND, va( "callteamvote denybuild %d\n",
- uiInfo.teamClientNums[ uiInfo.teamIndex ] ) );
- }
- }
- else if( Q_stricmp( name, "voteTeamAllowBuild" ) == 0 )
- {
- if( uiInfo.teamIndex >= 0 && uiInfo.teamIndex < uiInfo.myTeamCount )
- {
- trap_Cmd_ExecuteText( EXEC_APPEND, va( "callteamvote allowbuild %d\n",
- uiInfo.teamClientNums[ uiInfo.teamIndex ] ) );
- }
- }
- else if (Q_stricmp(name, "addFavorite") == 0) {
- if (ui_netSource.integer != AS_FAVORITES) {
- char name[MAX_NAME_LENGTH];
- char addr[MAX_NAME_LENGTH];
- int res;
-
- trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], buff, MAX_STRING_CHARS);
- name[0] = addr[0] = '\0';
- Q_strncpyz(name, Info_ValueForKey(buff, "hostname"), MAX_NAME_LENGTH);
- Q_strncpyz(addr, Info_ValueForKey(buff, "addr"), MAX_NAME_LENGTH);
- if (strlen(name) > 0 && strlen(addr) > 0) {
- res = trap_LAN_AddServer(AS_FAVORITES, name, addr);
- if (res == 0) {
- // server already in the list
- Com_Printf("Favorite already in list\n");
- }
- else if (res == -1) {
- // list full
- Com_Printf("Favorite list full\n");
- }
- else {
- // successfully added
- Com_Printf("Added favorite server %s\n", addr);
- }
+ UI_InstallCaptureFunc(UI_ArmouryRefreshCb, NULL, 1000);
}
- }
- } else if (Q_stricmp(name, "deleteFavorite") == 0) {
- if (ui_netSource.integer == AS_FAVORITES) {
- char addr[MAX_NAME_LENGTH];
- trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], buff, MAX_STRING_CHARS);
- addr[0] = '\0';
- Q_strncpyz(addr, Info_ValueForKey(buff, "addr"), MAX_NAME_LENGTH);
- if (strlen(addr) > 0) {
- trap_LAN_RemoveServer(AS_FAVORITES, addr);
+ else if (Q_stricmp(name, "LoadHumanArmourySells") == 0)
+ UI_LoadHumanArmourySells();
+ else if (Q_stricmp(name, "SellToArmoury") == 0)
+ {
+ if ((cmd = uiInfo.humanArmourySellList[uiInfo.humanArmourySellIndex].cmd))
+ trap_Cmd_ExecuteText(EXEC_APPEND, cmd);
+
+ UI_InstallCaptureFunc(UI_ArmouryRefreshCb, NULL, 1000);
}
- }
- } else if (Q_stricmp(name, "createFavorite") == 0) {
- if (ui_netSource.integer == AS_FAVORITES) {
- char name[MAX_NAME_LENGTH];
- char addr[MAX_NAME_LENGTH];
- int res;
-
- name[0] = addr[0] = '\0';
- Q_strncpyz(name, UI_Cvar_VariableString("ui_favoriteName"), MAX_NAME_LENGTH);
- Q_strncpyz(addr, UI_Cvar_VariableString("ui_favoriteAddress"), MAX_NAME_LENGTH);
- if (strlen(name) > 0 && strlen(addr) > 0) {
- res = trap_LAN_AddServer(AS_FAVORITES, name, addr);
- if (res == 0) {
- // server already in the list
- Com_Printf("Favorite already in list\n");
- }
- else if (res == -1) {
- // list full
- Com_Printf("Favorite list full\n");
- }
- else {
- // successfully added
- Com_Printf("Added favorite server %s\n", addr);
- }
+ else if (Q_stricmp(name, "LoadAlienUpgrades") == 0)
+ {
+ UI_LoadAlienUpgrades();
}
- }
- } else if (Q_stricmp(name, "orders") == 0) {
- const char *orders;
- if (String_Parse(args, &orders)) {
- int selectedPlayer = trap_Cvar_VariableValue("cg_selectedPlayer");
- if (selectedPlayer < uiInfo.myTeamCount) {
- strcpy(buff, orders);
- trap_Cmd_ExecuteText( EXEC_APPEND, va(buff, uiInfo.teamClientNums[selectedPlayer]) );
- trap_Cmd_ExecuteText( EXEC_APPEND, "\n" );
- } else {
- int i;
- for (i = 0; i < uiInfo.myTeamCount; i++) {
- if (Q_stricmp(UI_Cvar_VariableString("name"), uiInfo.teamNames[i]) == 0) {
- continue;
- }
- strcpy(buff, orders);
- trap_Cmd_ExecuteText( EXEC_APPEND, va(buff, uiInfo.teamNames[i]) );
- trap_Cmd_ExecuteText( EXEC_APPEND, "\n" );
- }
+ else if (Q_stricmp(name, "UpgradeToNewClass") == 0)
+ {
+ if ((cmd = uiInfo.alienUpgradeList[uiInfo.alienUpgradeIndex].cmd))
+ trap_Cmd_ExecuteText(EXEC_APPEND, cmd);
}
- trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI );
- trap_Key_ClearStates();
- trap_Cvar_Set( "cl_paused", "0" );
- Menus_CloseAll();
- }
- } else if (Q_stricmp(name, "voiceOrdersTeam") == 0) {
- const char *orders;
- if (String_Parse(args, &orders)) {
- int selectedPlayer = trap_Cvar_VariableValue("cg_selectedPlayer");
- if (selectedPlayer == uiInfo.myTeamCount) {
- trap_Cmd_ExecuteText( EXEC_APPEND, orders );
- trap_Cmd_ExecuteText( EXEC_APPEND, "\n" );
- }
- trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI );
- trap_Key_ClearStates();
- trap_Cvar_Set( "cl_paused", "0" );
- Menus_CloseAll();
- }
- } else if (Q_stricmp(name, "voiceOrders") == 0) {
- const char *orders;
- if (String_Parse(args, &orders)) {
- int selectedPlayer = trap_Cvar_VariableValue("cg_selectedPlayer");
- if (selectedPlayer < uiInfo.myTeamCount) {
- strcpy(buff, orders);
- trap_Cmd_ExecuteText( EXEC_APPEND, va(buff, uiInfo.teamClientNums[selectedPlayer]) );
- trap_Cmd_ExecuteText( EXEC_APPEND, "\n" );
- }
- trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI );
- trap_Key_ClearStates();
- trap_Cvar_Set( "cl_paused", "0" );
- Menus_CloseAll();
- }
- } else if (Q_stricmp(name, "glCustom") == 0) {
- trap_Cvar_Set("ui_glCustom", "4");
- } else if (Q_stricmp(name, "update") == 0) {
- if (String_Parse(args, &name2))
- UI_Update(name2);
- } else if (Q_stricmp(name, "InitIgnoreList") == 0) {
- UI_BuildPlayerList();
- } else if (Q_stricmp(name, "ToggleIgnore") == 0) {
- if( uiInfo.ignoreIndex >= 0 && uiInfo.ignoreIndex < uiInfo.playerCount )
- {
- if( BG_ClientListTest( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ],
- uiInfo.clientNums[ uiInfo.ignoreIndex ] ) )
+ else if (Q_stricmp(name, "LoadAlienBuilds") == 0)
+ UI_LoadAlienBuilds();
+ else if (Q_stricmp(name, "BuildAlienBuildable") == 0)
{
- BG_ClientListRemove( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ],
- uiInfo.clientNums[ uiInfo.ignoreIndex ] );
- trap_Cmd_ExecuteText( EXEC_NOW, va( "unignore %i\n",
- uiInfo.clientNums[ uiInfo.ignoreIndex ] ) );
+ if ((cmd = uiInfo.alienBuildList[uiInfo.alienBuildIndex].cmd))
+ trap_Cmd_ExecuteText(EXEC_APPEND, cmd);
}
- else
+ else if (Q_stricmp(name, "LoadHumanBuilds") == 0)
+ UI_LoadHumanBuilds();
+ else if (Q_stricmp(name, "BuildHumanBuildable") == 0)
{
- BG_ClientListAdd( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ],
- uiInfo.clientNums[ uiInfo.ignoreIndex ] );
- trap_Cmd_ExecuteText( EXEC_NOW, va( "ignore %i\n",
- uiInfo.clientNums[ uiInfo.ignoreIndex ] ) );
+ if ((cmd = uiInfo.humanBuildList[uiInfo.humanBuildIndex].cmd))
+ trap_Cmd_ExecuteText(EXEC_APPEND, cmd);
}
- }
- } else if (Q_stricmp(name, "IgnorePlayer") == 0) {
- if( uiInfo.ignoreIndex >= 0 && uiInfo.ignoreIndex < uiInfo.playerCount )
- {
- if( !BG_ClientListTest( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ],
- uiInfo.clientNums[ uiInfo.ignoreIndex ] ) )
+ else if (Q_stricmp(name, "LoadVoiceCmds") == 0)
{
- BG_ClientListAdd( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ],
- uiInfo.clientNums[ uiInfo.ignoreIndex ] );
- trap_Cmd_ExecuteText( EXEC_NOW, va( "ignore %i\n",
- uiInfo.clientNums[ uiInfo.ignoreIndex ] ) );
+ UI_LoadVoiceCmds();
}
- }
- } else if (Q_stricmp(name, "UnIgnorePlayer") == 0) {
- if( uiInfo.ignoreIndex >= 0 && uiInfo.ignoreIndex < uiInfo.playerCount )
- {
- if( BG_ClientListTest( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ],
- uiInfo.clientNums[ uiInfo.ignoreIndex ] ) )
+ else if (Q_stricmp(name, "ExecuteVoiceCmd") == 0)
{
- BG_ClientListRemove( &uiInfo.ignoreList[ uiInfo.myPlayerIndex ],
- uiInfo.clientNums[ uiInfo.ignoreIndex ] );
- trap_Cmd_ExecuteText( EXEC_NOW, va( "unignore %i\n",
- uiInfo.clientNums[ uiInfo.ignoreIndex ] ) );
+ if ((cmd = uiInfo.voiceCmdList[uiInfo.voiceCmdIndex].cmd))
+ trap_Cmd_ExecuteText(EXEC_APPEND, cmd);
}
- }
- } else if (Q_stricmp(name, "setPbClStatus") == 0) {
- int stat;
- if ( Int_Parse( args, &stat ) )
- trap_SetPbClStatus( stat );
- }
- else {
- Com_Printf("unknown UI script %s\n", name);
- }
- }
-}
+ else if (Q_stricmp(name, "Say") == 0)
+ {
+ char buffer[MAX_CVAR_VALUE_STRING];
+ trap_Cvar_VariableStringBuffer("ui_sayBuffer", buffer, sizeof(buffer));
-static void UI_GetTeamColor(vec4_t *color) {
-}
+ if (!buffer[0])
+ ;
+ else if (ui_chatCommands.integer && (buffer[0] == '/' || buffer[0] == '\\'))
+ {
+ trap_Cmd_ExecuteText(EXEC_APPEND, va("%s\n", buffer + 1));
+ }
+ else if (uiInfo.chatTeam)
+ trap_Cmd_ExecuteText(EXEC_APPEND, va("say_team \"%s\"\n", buffer));
+ else
+ trap_Cmd_ExecuteText(EXEC_APPEND, va("say \"%s\"\n", buffer));
+ }
+ else if (Q_stricmp(name, "SayKeydown") == 0)
+ {
+ if (ui_chatCommands.integer)
+ {
+ char buffer[MAX_CVAR_VALUE_STRING];
+ trap_Cvar_VariableStringBuffer("ui_sayBuffer", buffer, sizeof(buffer));
+
+ if (buffer[0] == '/' || buffer[0] == '\\')
+ Menus_ReplaceActiveByName("say_command");
+ else if (uiInfo.chatTeam)
+ Menus_ReplaceActiveByName("say_team");
+ else
+ Menus_ReplaceActiveByName("say");
+ }
+ }
+ else if (Q_stricmp(name, "playMovie") == 0)
+ {
+ if (uiInfo.previewMovie >= 0)
+ trap_CIN_StopCinematic(uiInfo.previewMovie);
-/*
-==================
-UI_MapCountByGameType
-==================
-*/
-static int UI_MapCountByGameType(qboolean singlePlayer) {
- int i, c, game;
- c = 0;
- game = singlePlayer ? uiInfo.gameTypes[ui_gameType.integer].gtEnum : uiInfo.gameTypes[ui_netGameType.integer].gtEnum;
-
- for (i = 0; i < uiInfo.mapCount; i++) {
- uiInfo.mapList[i].active = qfalse;
- if ( uiInfo.mapList[i].typeBits & (1 << game)) {
- if (singlePlayer) {
- if (!(uiInfo.mapList[i].typeBits & (1 << 2))) {
- continue;
+ trap_Cmd_ExecuteText(EXEC_APPEND, va("cinematic \"%s.roq\" 2\n", uiInfo.movieList[uiInfo.movieIndex]));
}
- }
- c++;
- uiInfo.mapList[i].active = qtrue;
- }
- }
- return c;
-}
+ else if (Q_stricmp(name, "RunMod") == 0)
+ {
+ trap_Cvar_Set("fs_game", uiInfo.modList[uiInfo.modIndex].modName);
+ trap_Cmd_ExecuteText(EXEC_APPEND, "vid_restart\n");
+ }
+ else if (Q_stricmp(name, "RunDemo") == 0)
+ {
+ if(uiInfo.demoList[uiInfo.demoIndex])
+ {
+ trap_Cmd_ExecuteText(EXEC_APPEND, va("demo \"%s\"\n", uiInfo.demoList[uiInfo.demoIndex]));
+ } else {
+ trap_Cvar_Set("com_demoErrorMessage", "No demo selected.");
+ Menus_ActivateByName("demo_error_popmenu");
+ }
+ }
+ else if (Q_stricmp(name, "Tremulous") == 0)
+ {
+ trap_Cvar_Set("fs_game", "");
+ trap_Cmd_ExecuteText(EXEC_APPEND, "vid_restart\n");
+ }
+ else if (Q_stricmp(name, "closeJoin") == 0)
+ {
+ if (uiInfo.serverStatus.refreshActive)
+ {
+ UI_StopServerRefresh();
+ uiInfo.serverStatus.nextDisplayRefresh = 0;
+ uiInfo.nextServerStatusRefresh = 0;
+ uiInfo.nextFindPlayerRefresh = 0;
+ UI_BuildServerDisplayList(qtrue);
+ }
+ else
+ {
+ Menus_CloseByName("joinserver");
+ Menus_ActivateByName("main");
+ }
+ }
+ else if (Q_stricmp(name, "StopRefresh") == 0)
+ {
+ UI_StopServerRefresh();
+ uiInfo.serverStatus.nextDisplayRefresh = 0;
+ uiInfo.nextServerStatusRefresh = 0;
+ uiInfo.nextFindPlayerRefresh = 0;
+ }
+ else if (Q_stricmp(name, "UpdateFilter") == 0)
+ {
+ if (ui_netSource.integer == AS_LOCAL)
+ UI_StartServerRefresh(qtrue);
-qboolean UI_hasSkinForBase(const char *base, const char *team) {
- char test[1024];
+ UI_BuildServerDisplayList(qtrue);
+ UI_FeederSelection(FEEDER_SERVERS, 0);
+ }
+ else if (Q_stricmp(name, "ServerStatus") == 0)
+ {
+ trap_LAN_GetServerAddressString(ui_netSource.integer,
+ uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], uiInfo.serverStatusAddress,
+ sizeof(uiInfo.serverStatusAddress));
+ UI_BuildServerStatus(qtrue);
+ }
+ else if (Q_stricmp(name, "FoundPlayerServerStatus") == 0)
+ {
+ Q_strncpyz(uiInfo.serverStatusAddress, uiInfo.foundPlayerServerAddresses[uiInfo.currentFoundPlayerServer],
+ sizeof(uiInfo.serverStatusAddress));
+ UI_BuildServerStatus(qtrue);
+ Menu_SetFeederSelection(NULL, FEEDER_FINDPLAYER, 0, NULL);
+ }
+ else if (Q_stricmp(name, "FindPlayer") == 0)
+ {
+ UI_BuildFindPlayerList(qtrue);
+ // clear the displayed server status info
+ uiInfo.serverStatusInfo.numLines = 0;
+ Menu_SetFeederSelection(NULL, FEEDER_FINDPLAYER, 0, NULL);
+ }
+ else if (Q_stricmp(name, "JoinServer") == 0)
+ {
+ if (uiInfo.serverStatus.currentServer >= 0 &&
+ uiInfo.serverStatus.currentServer < uiInfo.serverStatus.numDisplayServers)
+ {
+ trap_LAN_GetServerAddressString(ui_netSource.integer,
+ uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], buff, 1024);
+ trap_Cmd_ExecuteText(EXEC_APPEND, va("connect %s\n", buff));
+ }
+ }
+ else if (Q_stricmp(name, "FoundPlayerJoinServer") == 0)
+ {
+ if (uiInfo.currentFoundPlayerServer >= 0 && uiInfo.currentFoundPlayerServer < uiInfo.numFoundPlayerServers)
+ {
+ trap_Cmd_ExecuteText(EXEC_APPEND,
+ va("connect %s\n", uiInfo.foundPlayerServerAddresses[uiInfo.currentFoundPlayerServer]));
+ }
+ }
+ else if (Q_stricmp(name, "Quit") == 0)
+ trap_Cmd_ExecuteText(EXEC_APPEND, "quit\n");
+ else if (Q_stricmp(name, "Leave") == 0)
+ {
+ trap_Cmd_ExecuteText(EXEC_APPEND, "disconnect\n");
+ trap_Key_SetCatcher(KEYCATCH_UI);
+ Menus_CloseAll();
+ Menus_ActivateByName("main");
+ }
+ else if (Q_stricmp(name, "ServerSort") == 0)
+ {
+ int sortColumn;
- Com_sprintf( test, sizeof( test ), "models/players/%s/%s/lower_default.skin", base, team );
+ if (Int_Parse(args, &sortColumn))
+ {
+ // if same column we're already sorting on then flip the direction
- if (trap_FS_FOpenFile(test, NULL, FS_READ)) {
- return qtrue;
- }
- Com_sprintf( test, sizeof( test ), "models/players/characters/%s/%s/lower_default.skin", base, team );
+ if (sortColumn == uiInfo.serverStatus.sortKey)
+ uiInfo.serverStatus.sortDir = !uiInfo.serverStatus.sortDir;
- if (trap_FS_FOpenFile(test, NULL, FS_READ)) {
- return qtrue;
- }
- return qfalse;
-}
+ // make sure we sort again
+ UI_ServersSort(sortColumn, qtrue);
-/*
-==================
-UI_MapCountByTeam
-==================
-*/
-static int UI_HeadCountByTeam( void ) {
- static int init = 0;
- int i, j, k, c, tIndex;
-
- c = 0;
- if (!init) {
- for (i = 0; i < uiInfo.characterCount; i++) {
- uiInfo.characterList[i].reference = 0;
- for (j = 0; j < uiInfo.teamCount; j++) {
- if (UI_hasSkinForBase(uiInfo.characterList[i].base, uiInfo.teamList[j].teamName)) {
- uiInfo.characterList[i].reference |= (1<<j);
+ uiInfo.serverStatus.sorted = qtrue;
+ }
}
- }
- }
- init = 1;
- }
+ else if (Q_stricmp(name, "closeingame") == 0)
+ {
+ trap_Key_SetCatcher(trap_Key_GetCatcher() & ~KEYCATCH_UI);
+ trap_Key_ClearStates();
+ trap_Cvar_Set("cl_paused", "0");
+ Menus_CloseAll();
+ }
+ else if (Q_stricmp(name, "voteMap") == 0)
+ {
+ if (ui_selectedMap.integer >= 0 && ui_selectedMap.integer < uiInfo.mapCount)
+ {
+ trap_Cmd_ExecuteText(
+ EXEC_APPEND, va("callvote map \"%s\"\n", uiInfo.mapList[ui_selectedMap.integer].mapLoadName));
+ }
+ }
+ else if (Q_stricmp(name, "voteNextMap") == 0)
+ {
+ if (ui_selectedMap.integer >= 0 && ui_selectedMap.integer < uiInfo.mapCount)
+ {
+ trap_Cmd_ExecuteText(
+ EXEC_APPEND, va("callvote nextmap \"%s\"\n", uiInfo.mapList[ui_selectedMap.integer].mapLoadName));
+ }
+ }
+ else if (Q_stricmp(name, "voteKick") == 0)
+ {
+ if (uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount)
+ {
+ char buffer[MAX_CVAR_VALUE_STRING];
+ trap_Cvar_VariableStringBuffer("ui_reason", buffer, sizeof(buffer));
- tIndex = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
+ trap_Cmd_ExecuteText(EXEC_APPEND, va("callvote kick %d%s\n", uiInfo.clientNums[uiInfo.playerIndex],
+ (buffer[0] ? va(" \"%s\"", buffer) : "")));
+ trap_Cvar_Set("ui_reason", "");
+ }
+ }
+ else if (Q_stricmp(name, "voteMute") == 0)
+ {
+ if (uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount)
+ {
+ char buffer[MAX_CVAR_VALUE_STRING];
+ trap_Cvar_VariableStringBuffer("ui_reason", buffer, sizeof(buffer));
- // do names
- for (i = 0; i < uiInfo.characterCount; i++) {
- uiInfo.characterList[i].active = qfalse;
- for(j = 0; j < TEAM_MEMBERS; j++) {
- if (uiInfo.teamList[tIndex].teamMembers[j] != NULL) {
- if (uiInfo.characterList[i].reference&(1<<tIndex)) {// && Q_stricmp(uiInfo.teamList[tIndex].teamMembers[j], uiInfo.characterList[i].name)==0) {
- uiInfo.characterList[i].active = qtrue;
- c++;
- break;
+ trap_Cmd_ExecuteText(EXEC_APPEND, va("callvote mute %d%s\n", uiInfo.clientNums[uiInfo.playerIndex],
+ (buffer[0] ? va(" \"%s\"", buffer) : "")));
+ trap_Cvar_Set("ui_reason", "");
+ }
}
- }
- }
- }
-
- // and then aliases
- for(j = 0; j < TEAM_MEMBERS; j++) {
- for(k = 0; k < uiInfo.aliasCount; k++) {
- if (uiInfo.aliasList[k].name != NULL) {
- if (Q_stricmp(uiInfo.teamList[tIndex].teamMembers[j], uiInfo.aliasList[k].name)==0) {
- for (i = 0; i < uiInfo.characterCount; i++) {
- if (uiInfo.characterList[i].headImage != -1 && uiInfo.characterList[i].reference&(1<<tIndex) && Q_stricmp(uiInfo.aliasList[k].ai, uiInfo.characterList[i].name)==0) {
- if (uiInfo.characterList[i].active == qfalse) {
- uiInfo.characterList[i].active = qtrue;
- c++;
- }
- break;
+ else if (Q_stricmp(name, "voteUnMute") == 0)
+ {
+ if (uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount)
+ {
+ trap_Cmd_ExecuteText(EXEC_APPEND, va("callvote unmute %d\n", uiInfo.clientNums[uiInfo.playerIndex]));
}
- }
}
- }
- }
- }
- return c;
-}
+ else if (Q_stricmp(name, "voteTeamKick") == 0)
+ {
+ if (uiInfo.teamPlayerIndex >= 0 && uiInfo.teamPlayerIndex < uiInfo.myTeamCount)
+ {
+ char buffer[MAX_CVAR_VALUE_STRING];
+ trap_Cvar_VariableStringBuffer("ui_reason", buffer, sizeof(buffer));
-/*
-==================
-UI_InsertServerIntoDisplayList
-==================
-*/
-static void UI_InsertServerIntoDisplayList(int num, int position) {
- int i;
-
- if (position < 0 || position > uiInfo.serverStatus.numDisplayServers ) {
- return;
- }
- //
- uiInfo.serverStatus.numDisplayServers++;
- for (i = uiInfo.serverStatus.numDisplayServers; i > position; i--) {
- uiInfo.serverStatus.displayServers[i] = uiInfo.serverStatus.displayServers[i-1];
- }
- uiInfo.serverStatus.displayServers[position] = num;
-}
+ trap_Cmd_ExecuteText(
+ EXEC_APPEND, va("callteamvote kick %d%s\n", uiInfo.teamClientNums[uiInfo.teamPlayerIndex],
+ (buffer[0] ? va(" \"%s\"", buffer) : "")));
+ trap_Cvar_Set("ui_reason", "");
+ }
+ }
+ else if (Q_stricmp(name, "voteTeamDenyBuild") == 0)
+ {
+ if (uiInfo.teamPlayerIndex >= 0 && uiInfo.teamPlayerIndex < uiInfo.myTeamCount)
+ {
+ char buffer[MAX_CVAR_VALUE_STRING];
+ trap_Cvar_VariableStringBuffer("ui_reason", buffer, sizeof(buffer));
-/*
-==================
-UI_RemoveServerFromDisplayList
-==================
-*/
-static void UI_RemoveServerFromDisplayList(int num) {
- int i, j;
-
- for (i = 0; i < uiInfo.serverStatus.numDisplayServers; i++) {
- if (uiInfo.serverStatus.displayServers[i] == num) {
- uiInfo.serverStatus.numDisplayServers--;
- for (j = i; j < uiInfo.serverStatus.numDisplayServers; j++) {
- uiInfo.serverStatus.displayServers[j] = uiInfo.serverStatus.displayServers[j+1];
- }
- return;
+ trap_Cmd_ExecuteText(
+ EXEC_APPEND, va("callteamvote denybuild %d%s\n", uiInfo.teamClientNums[uiInfo.teamPlayerIndex],
+ (buffer[0] ? va(" \"%s\"", buffer) : "")));
+ trap_Cvar_Set("ui_reason", "");
+ }
+ }
+ else if (Q_stricmp(name, "voteTeamAllowBuild") == 0)
+ {
+ if (uiInfo.teamPlayerIndex >= 0 && uiInfo.teamPlayerIndex < uiInfo.myTeamCount)
+ {
+ trap_Cmd_ExecuteText(
+ EXEC_APPEND, va("callteamvote allowbuild %d\n", uiInfo.teamClientNums[uiInfo.teamPlayerIndex]));
+ }
+ }
+ else if (Q_stricmp(name, "addFavorite") == 0)
+ {
+ if (ui_netSource.integer != AS_FAVORITES)
+ {
+ char name[MAX_NAME_LENGTH];
+ char addr[MAX_NAME_LENGTH];
+ int res;
+
+ trap_LAN_GetServerInfo(ui_netSource.integer,
+ uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], buff, MAX_STRING_CHARS);
+ name[0] = addr[0] = '\0';
+ Q_strncpyz(name, Info_ValueForKey(buff, "hostname"), MAX_NAME_LENGTH);
+ Q_strncpyz(addr, Info_ValueForKey(buff, "addr"), MAX_NAME_LENGTH);
+
+ if (strlen(name) > 0 && strlen(addr) > 0)
+ {
+ res = trap_LAN_AddServer(AS_FAVORITES, name, addr);
+
+ if (res == 0)
+ {
+ // server already in the list
+ Com_Printf("Favorite already in list\n");
+ }
+ else if (res == -1)
+ {
+ // list full
+ Com_Printf("Favorite list full\n");
+ }
+ else
+ {
+ // successfully added
+ Com_Printf("Added favorite server %s\n", addr);
+ }
+ }
+ }
+ }
+ else if (Q_stricmp(name, "deleteFavorite") == 0)
+ {
+ if (ui_netSource.integer == AS_FAVORITES)
+ {
+ char addr[MAX_NAME_LENGTH];
+ trap_LAN_GetServerInfo(ui_netSource.integer,
+ uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], buff, MAX_STRING_CHARS);
+ addr[0] = '\0';
+ Q_strncpyz(addr, Info_ValueForKey(buff, "addr"), MAX_NAME_LENGTH);
+
+ if (strlen(addr) > 0)
+ trap_LAN_RemoveServer(AS_FAVORITES, addr);
+ }
+ }
+ else if (Q_stricmp(name, "createFavorite") == 0)
+ {
+ if (ui_netSource.integer == AS_FAVORITES)
+ {
+ char name[MAX_NAME_LENGTH];
+ char addr[MAX_NAME_LENGTH];
+ int res;
+
+ name[0] = addr[0] = '\0';
+ Q_strncpyz(name, UI_Cvar_VariableString("ui_favoriteName"), MAX_NAME_LENGTH);
+ Q_strncpyz(addr, UI_Cvar_VariableString("ui_favoriteAddress"), MAX_NAME_LENGTH);
+
+ if (strlen(name) > 0 && strlen(addr) > 0)
+ {
+ res = trap_LAN_AddServer(AS_FAVORITES, name, addr);
+
+ if (res == 0)
+ {
+ // server already in the list
+ Com_Printf("Favorite already in list\n");
+ }
+ else if (res == -1)
+ {
+ // list full
+ Com_Printf("Favorite list full\n");
+ }
+ else
+ {
+ // successfully added
+ Com_Printf("Added favorite server %s\n", addr);
+ }
+ }
+ }
+ }
+ else if (Q_stricmp(name, "glCustom") == 0)
+ trap_Cvar_Set("ui_glCustom", "4");
+ else if (Q_stricmp(name, "update") == 0)
+ {
+ if (String_Parse(args, &name2))
+ UI_Update(name2);
+ }
+ else if (Q_stricmp(name, "InitIgnoreList") == 0)
+ UI_BuildPlayerList();
+ else if (Q_stricmp(name, "ToggleIgnore") == 0)
+ {
+ if (uiInfo.ignoreIndex >= 0 && uiInfo.ignoreIndex < uiInfo.playerCount)
+ {
+ if (Com_ClientListContains(
+ &uiInfo.ignoreList[uiInfo.myPlayerIndex], uiInfo.clientNums[uiInfo.ignoreIndex]))
+ {
+ Com_ClientListRemove(
+ &uiInfo.ignoreList[uiInfo.myPlayerIndex], uiInfo.clientNums[uiInfo.ignoreIndex]);
+ trap_Cmd_ExecuteText(EXEC_APPEND, va("unignore %i\n", uiInfo.clientNums[uiInfo.ignoreIndex]));
+ }
+ else
+ {
+ Com_ClientListAdd(&uiInfo.ignoreList[uiInfo.myPlayerIndex], uiInfo.clientNums[uiInfo.ignoreIndex]);
+ trap_Cmd_ExecuteText(EXEC_APPEND, va("ignore %i\n", uiInfo.clientNums[uiInfo.ignoreIndex]));
+ }
+ }
+ }
+ else if (Q_stricmp(name, "IgnorePlayer") == 0)
+ {
+ if (uiInfo.ignoreIndex >= 0 && uiInfo.ignoreIndex < uiInfo.playerCount)
+ {
+ if (!Com_ClientListContains(
+ &uiInfo.ignoreList[uiInfo.myPlayerIndex], uiInfo.clientNums[uiInfo.ignoreIndex]))
+ {
+ Com_ClientListAdd(&uiInfo.ignoreList[uiInfo.myPlayerIndex], uiInfo.clientNums[uiInfo.ignoreIndex]);
+ trap_Cmd_ExecuteText(EXEC_APPEND, va("ignore %i\n", uiInfo.clientNums[uiInfo.ignoreIndex]));
+ }
+ }
+ }
+ else if (Q_stricmp(name, "UnIgnorePlayer") == 0)
+ {
+ if (uiInfo.ignoreIndex >= 0 && uiInfo.ignoreIndex < uiInfo.playerCount)
+ {
+ if (Com_ClientListContains(
+ &uiInfo.ignoreList[uiInfo.myPlayerIndex], uiInfo.clientNums[uiInfo.ignoreIndex]))
+ {
+ Com_ClientListRemove(
+ &uiInfo.ignoreList[uiInfo.myPlayerIndex], uiInfo.clientNums[uiInfo.ignoreIndex]);
+ trap_Cmd_ExecuteText(EXEC_APPEND, va("unignore %i\n", uiInfo.clientNums[uiInfo.ignoreIndex]));
+ }
+ }
+ }
+ else
+ Com_Printf("unknown UI script %s\n", name);
}
- }
}
-/*
-==================
-UI_BinaryServerInsertion
-==================
-*/
-static void UI_BinaryServerInsertion(int num) {
- int mid, offset, res, len;
-
- // use binary search to insert server
- len = uiInfo.serverStatus.numDisplayServers;
- mid = len;
- offset = 0;
- res = 0;
- while(mid > 0) {
- mid = len >> 1;
- //
- res = trap_LAN_CompareServers( ui_netSource.integer, uiInfo.serverStatus.sortKey,
- uiInfo.serverStatus.sortDir, num, uiInfo.serverStatus.displayServers[offset+mid]);
- // if equal
- if (res == 0) {
- UI_InsertServerIntoDisplayList(num, offset+mid);
- return;
- }
- // if larger
- else if (res == 1) {
- offset += mid;
- len -= mid;
- }
- // if smaller
- else {
- len -= mid;
- }
- }
- if (res == 1) {
- offset++;
- }
- UI_InsertServerIntoDisplayList(num, offset);
-}
+static int UI_FeederInitialise(int feederID);
/*
==================
-UI_BuildServerDisplayList
+UI_FeederCount
==================
*/
-static void UI_BuildServerDisplayList(int force) {
- int i, count, clients, maxClients, ping, game, len, visible;
- char info[MAX_STRING_CHARS];
-// qboolean startRefresh = qtrue; TTimo: unused
- static int numinvisible;
-
- if (!(force || uiInfo.uiDC.realTime > uiInfo.serverStatus.nextDisplayRefresh)) {
- return;
- }
- // if we shouldn't reset
- if ( force == 2 ) {
- force = 0;
- }
-
- // do motd updates here too
- trap_Cvar_VariableStringBuffer( "cl_motdString", uiInfo.serverStatus.motd, sizeof(uiInfo.serverStatus.motd) );
- len = strlen(uiInfo.serverStatus.motd);
- if (len != uiInfo.serverStatus.motdLen) {
- uiInfo.serverStatus.motdLen = len;
- uiInfo.serverStatus.motdWidth = -1;
- }
-
- if (force) {
- numinvisible = 0;
- // clear number of displayed servers
- uiInfo.serverStatus.numDisplayServers = 0;
- uiInfo.serverStatus.numPlayersOnServers = 0;
- // set list box index to zero
- Menu_SetFeederSelection(NULL, FEEDER_SERVERS, 0, NULL);
- // mark all servers as visible so we store ping updates for them
- trap_LAN_MarkServerVisible(ui_netSource.integer, -1, qtrue);
- }
+static int UI_FeederCount(int feederID)
+{
+ if (feederID == FEEDER_CINEMATICS)
+ return uiInfo.movieCount;
+ else if (feederID == FEEDER_MAPS)
+ return uiInfo.mapCount;
+ else if (feederID == FEEDER_SERVERS)
+ return uiInfo.serverStatus.numDisplayServers;
+ else if (feederID == FEEDER_SERVERSTATUS)
+ return uiInfo.serverStatusInfo.numLines;
+ else if (feederID == FEEDER_NEWS)
+ return uiInfo.newsInfo.numLines;
+ else if (feederID == FEEDER_GITHUB_RELEASE)
+ return uiInfo.githubRelease.numLines;
+ else if (feederID == FEEDER_FINDPLAYER)
+ return uiInfo.numFoundPlayerServers;
+ else if (feederID == FEEDER_PLAYER_LIST)
+ {
+ if (uiInfo.uiDC.realTime > uiInfo.playerRefresh)
+ {
+ uiInfo.playerRefresh = uiInfo.uiDC.realTime + 3000;
+ UI_BuildPlayerList();
+ }
- // get the server count (comes from the master)
- count = trap_LAN_GetServerCount(ui_netSource.integer);
- if (count == -1 || (ui_netSource.integer == AS_LOCAL && count == 0) ) {
- // still waiting on a response from the master
- uiInfo.serverStatus.numDisplayServers = 0;
- uiInfo.serverStatus.numPlayersOnServers = 0;
- uiInfo.serverStatus.nextDisplayRefresh = uiInfo.uiDC.realTime + 500;
- return;
- }
+ return uiInfo.playerCount;
+ }
+ else if (feederID == FEEDER_TEAM_LIST)
+ {
+ if (uiInfo.uiDC.realTime > uiInfo.playerRefresh)
+ {
+ uiInfo.playerRefresh = uiInfo.uiDC.realTime + 3000;
+ UI_BuildPlayerList();
+ }
- visible = qfalse;
- for (i = 0; i < count; i++) {
- // if we already got info for this server
- if (!trap_LAN_ServerIsVisible(ui_netSource.integer, i)) {
- continue;
+ return uiInfo.myTeamCount;
+ }
+ else if (feederID == FEEDER_IGNORE_LIST)
+ return uiInfo.playerCount;
+ else if (feederID == FEEDER_HELP_LIST)
+ return uiInfo.helpCount;
+ else if (feederID == FEEDER_MODS)
+ return uiInfo.modCount;
+ else if (feederID == FEEDER_DEMOS)
+ return uiInfo.demoCount;
+ else if (feederID == FEEDER_TREMTEAMS)
+ return uiInfo.teamCount;
+ else if (feederID == FEEDER_TREMHUMANITEMS)
+ return uiInfo.humanItemCount;
+ else if (feederID == FEEDER_TREMALIENCLASSES)
+ return uiInfo.alienClassCount;
+ else if (feederID == FEEDER_TREMHUMANARMOURYBUY)
+ return uiInfo.humanArmouryBuyCount;
+ else if (feederID == FEEDER_TREMHUMANARMOURYSELL)
+ return uiInfo.humanArmourySellCount;
+ else if (feederID == FEEDER_TREMALIENUPGRADE)
+ return uiInfo.alienUpgradeCount;
+ else if (feederID == FEEDER_TREMALIENBUILD)
+ return uiInfo.alienBuildCount;
+ else if (feederID == FEEDER_TREMHUMANBUILD)
+ return uiInfo.humanBuildCount;
+ else if (feederID == FEEDER_RESOLUTIONS)
+ {
+ if (UI_FeederInitialise(feederID) == uiInfo.numResolutions)
+ return uiInfo.numResolutions + 1;
+ else
+ return uiInfo.numResolutions;
}
- visible = qtrue;
- // get the ping for this server
- ping = trap_LAN_GetServerPing(ui_netSource.integer, i);
- if (ping > 0 || ui_netSource.integer == AS_FAVORITES) {
+ else if (feederID == FEEDER_TREMVOICECMD)
+ return uiInfo.voiceCmdCount;
- trap_LAN_GetServerInfo(ui_netSource.integer, i, info, MAX_STRING_CHARS);
+ return 0;
+}
- clients = atoi(Info_ValueForKey(info, "clients"));
- uiInfo.serverStatus.numPlayersOnServers += clients;
+static const char *UI_SelectedMap(int index, int *actual)
+{
+ int i, c;
+ c = 0;
+ *actual = 0;
- if (ui_browserShowEmpty.integer == 0) {
- if (clients == 0) {
- trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse);
- continue;
+ for (i = 0; i < uiInfo.mapCount; i++)
+ {
+ if (c == index)
+ {
+ *actual = i;
+ return uiInfo.mapList[i].mapName;
}
- }
+ else
+ c++;
+ }
- if (ui_browserShowFull.integer == 0) {
- maxClients = atoi(Info_ValueForKey(info, "sv_maxclients"));
- if (clients == maxClients) {
- trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse);
- continue;
- }
- }
+ return "";
+}
- if (uiInfo.joinGameTypes[ui_joinGameType.integer].gtEnum != -1) {
- game = atoi(Info_ValueForKey(info, "gametype"));
- if (game != uiInfo.joinGameTypes[ui_joinGameType.integer].gtEnum) {
- trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse);
- continue;
- }
- }
+static int GCD(int a, int b)
+{
+ int c;
- // make sure we never add a favorite server twice
- if (ui_netSource.integer == AS_FAVORITES) {
- UI_RemoveServerFromDisplayList(i);
- }
- // insert the server into the list
- UI_BinaryServerInsertion(i);
- // done with this server
- if (ping > 0) {
- trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse);
- numinvisible++;
- }
+ while (b != 0)
+ {
+ c = a % b;
+ a = b;
+ b = c;
}
- }
- uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime;
-
- // if there were no servers visible for ping updates
- if (!visible) {
-// UI_StopServerRefresh();
-// uiInfo.serverStatus.nextDisplayRefresh = 0;
- }
+ return a;
}
-typedef struct
+static const char *UI_DisplayAspectString(int w, int h)
{
- char *name, *altName;
-} serverStatusCvar_t;
-
-serverStatusCvar_t serverStatusCvars[] = {
- {"sv_hostname", "Name"},
- {"Address", ""},
- {"gamename", "Game name"},
- {"g_gametype", "Game type"},
- {"mapname", "Map"},
- {"version", ""},
- {"protocol", ""},
- {"timelimit", ""},
- {"fraglimit", ""},
- {NULL, NULL}
-};
+ int gcd = GCD(w, h);
-/*
-==================
-UI_SortServerStatusInfo
-==================
-*/
-static void UI_SortServerStatusInfo( serverStatusInfo_t *info ) {
- int i, j, index;
- char *tmp1, *tmp2;
-
- // FIXME: if "gamename" == "baseq3" or "missionpack" then
- // replace the gametype number by FFA, CTF etc.
- //
- index = 0;
- for (i = 0; serverStatusCvars[i].name; i++) {
- for (j = 0; j < info->numLines; j++) {
- if ( !info->lines[j][1] || info->lines[j][1][0] ) {
- continue;
- }
- if ( !Q_stricmp(serverStatusCvars[i].name, info->lines[j][0]) ) {
- // swap lines
- tmp1 = info->lines[index][0];
- tmp2 = info->lines[index][3];
- info->lines[index][0] = info->lines[j][0];
- info->lines[index][3] = info->lines[j][3];
- info->lines[j][0] = tmp1;
- info->lines[j][3] = tmp2;
- //
- if ( strlen(serverStatusCvars[i].altName) ) {
- info->lines[index][0] = serverStatusCvars[i].altName;
- }
- index++;
- }
+ w /= gcd;
+ h /= gcd;
+
+ // For some reason 8:5 is usually referred to as 16:10
+ if (w == 8 && h == 5)
+ {
+ w = 16;
+ h = 10;
}
- }
+
+ return va("%d:%d", w, h);
}
-/*
-==================
-UI_GetServerStatusInfo
-==================
-*/
-static int UI_GetServerStatusInfo( const char *serverAddress, serverStatusInfo_t *info ) {
- char *p, *score, *ping, *name;
- int i, len;
+static const char *UI_FeederItemText(int feederID, int index, int column, qhandle_t *handle)
+{
+ if (handle)
+ *handle = -1;
- if (!info) {
- trap_LAN_ServerStatus( serverAddress, NULL, 0);
- return qfalse;
- }
- memset(info, 0, sizeof(*info));
- if ( trap_LAN_ServerStatus( serverAddress, info->text, sizeof(info->text)) ) {
- Q_strncpyz(info->address, serverAddress, sizeof(info->address));
- p = info->text;
- info->numLines = 0;
- info->lines[info->numLines][0] = "Address";
- info->lines[info->numLines][1] = "";
- info->lines[info->numLines][2] = "";
- info->lines[info->numLines][3] = info->address;
- info->numLines++;
- // get the cvars
- while (p && *p) {
- p = strchr(p, '\\');
- if (!p) break;
- *p++ = '\0';
- if (*p == '\\')
- break;
- info->lines[info->numLines][0] = p;
- info->lines[info->numLines][1] = "";
- info->lines[info->numLines][2] = "";
- p = strchr(p, '\\');
- if (!p) break;
- *p++ = '\0';
- info->lines[info->numLines][3] = p;
-
- info->numLines++;
- if (info->numLines >= MAX_SERVERSTATUS_LINES)
- break;
- }
- // get the player list
- if (info->numLines < MAX_SERVERSTATUS_LINES-3) {
- // empty line
- info->lines[info->numLines][0] = "";
- info->lines[info->numLines][1] = "";
- info->lines[info->numLines][2] = "";
- info->lines[info->numLines][3] = "";
- info->numLines++;
- // header
- info->lines[info->numLines][0] = "num";
- info->lines[info->numLines][1] = "score";
- info->lines[info->numLines][2] = "ping";
- info->lines[info->numLines][3] = "name";
- info->numLines++;
- // parse players
- i = 0;
- len = 0;
- while (p && *p) {
- if (*p == '\\')
- *p++ = '\0';
- if (!p)
- break;
- score = p;
- p = strchr(p, ' ');
- if (!p)
- break;
- *p++ = '\0';
- ping = p;
- p = strchr(p, ' ');
- if (!p)
- break;
- *p++ = '\0';
- name = p;
- Com_sprintf(&info->pings[len], sizeof(info->pings)-len, "%d", i);
- info->lines[info->numLines][0] = &info->pings[len];
- len += strlen(&info->pings[len]) + 1;
- info->lines[info->numLines][1] = score;
- info->lines[info->numLines][2] = ping;
- info->lines[info->numLines][3] = name;
- info->numLines++;
- if (info->numLines >= MAX_SERVERSTATUS_LINES)
- break;
- p = strchr(p, '\\');
- if (!p)
- break;
- *p++ = '\0';
- //
- i++;
- }
+ if (feederID == FEEDER_MAPS)
+ {
+ int actual;
+ return UI_SelectedMap(index, &actual);
}
- UI_SortServerStatusInfo( info );
- return qtrue;
- }
- return qfalse;
-}
+ else if (feederID == FEEDER_SERVERS)
+ {
+ if (index >= 0 && index < UI_FeederCount(feederID))
+ {
+ static char info[MAX_STRING_CHARS];
+ static char clientBuff[32];
+ static char cleaned[MAX_STRING_CHARS];
+ static int lastColumn = -1;
+ static int lastTime = 0;
+ int ping;
+
+ if (lastColumn != column || lastTime > uiInfo.uiDC.realTime + 5000)
+ {
+ trap_LAN_GetServerInfo(
+ ui_netSource.integer, uiInfo.serverStatus.displayServers[index], info, MAX_STRING_CHARS);
+ lastColumn = column;
+ lastTime = uiInfo.uiDC.realTime;
+ }
-/*
-==================
-stristr
-==================
-*/
-static char *stristr(char *str, char *charset) {
- int i;
+ ping = atoi(Info_ValueForKey(info, "ping"));
- while(*str) {
- for (i = 0; charset[i] && str[i]; i++) {
- if (toupper(charset[i]) != toupper(str[i])) break;
- }
- if (!charset[i]) return str;
- str++;
- }
- return NULL;
-}
+ UI_EscapeEmoticons(cleaned, Info_ValueForKey(info, "hostname"), sizeof(cleaned));
-/*
-==================
-UI_BuildFindPlayerList
-==================
-*/
-static void UI_BuildFindPlayerList(qboolean force) {
- static int numFound, numTimeOuts;
- int i, j, resend;
- serverStatusInfo_t info;
- char name[MAX_NAME_LENGTH+2];
- char infoString[MAX_STRING_CHARS];
-
- if (!force) {
- if (!uiInfo.nextFindPlayerRefresh || uiInfo.nextFindPlayerRefresh > uiInfo.uiDC.realTime) {
- return;
- }
- }
- else {
- memset(&uiInfo.pendingServerStatus, 0, sizeof(uiInfo.pendingServerStatus));
- uiInfo.numFoundPlayerServers = 0;
- uiInfo.currentFoundPlayerServer = 0;
- trap_Cvar_VariableStringBuffer( "ui_findPlayer", uiInfo.findPlayerName, sizeof(uiInfo.findPlayerName));
- Q_CleanStr(uiInfo.findPlayerName);
- // should have a string of some length
- if (!strlen(uiInfo.findPlayerName)) {
- uiInfo.nextFindPlayerRefresh = 0;
- return;
- }
- // set resend time
- resend = ui_serverStatusTimeOut.integer / 2 - 10;
- if (resend < 50) {
- resend = 50;
- }
- trap_Cvar_Set("cl_serverStatusResendTime", va("%d", resend));
- // reset all server status requests
- trap_LAN_ServerStatus( NULL, NULL, 0);
- //
- uiInfo.numFoundPlayerServers = 1;
- Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1],
- sizeof(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1]),
- "searching %d...", uiInfo.pendingServerStatus.num);
- numFound = 0;
- numTimeOuts++;
- }
- for (i = 0; i < MAX_SERVERSTATUSREQUESTS; i++) {
- // if this pending server is valid
- if (uiInfo.pendingServerStatus.server[i].valid) {
- // try to get the server status for this server
- if (UI_GetServerStatusInfo( uiInfo.pendingServerStatus.server[i].adrstr, &info ) ) {
- //
- numFound++;
- // parse through the server status lines
- for (j = 0; j < info.numLines; j++) {
- // should have ping info
- if ( !info.lines[j][2] || !info.lines[j][2][0] ) {
- continue;
- }
- // clean string first
- Q_strncpyz(name, info.lines[j][3], sizeof(name));
- Q_CleanStr(name);
- // if the player name is a substring
- if (stristr(name, uiInfo.findPlayerName)) {
- // add to found server list if we have space (always leave space for a line with the number found)
- if (uiInfo.numFoundPlayerServers < MAX_FOUNDPLAYER_SERVERS-1) {
- //
- Q_strncpyz(uiInfo.foundPlayerServerAddresses[uiInfo.numFoundPlayerServers-1],
- uiInfo.pendingServerStatus.server[i].adrstr,
- sizeof(uiInfo.foundPlayerServerAddresses[0]));
- Q_strncpyz(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1],
- uiInfo.pendingServerStatus.server[i].name,
- sizeof(uiInfo.foundPlayerServerNames[0]));
- uiInfo.numFoundPlayerServers++;
+ switch (column)
+ {
+ case SORT_HOST:
+ if (ping <= 0)
+ return Info_ValueForKey(info, "addr");
+ else
+ {
+ static char hostname[1024];
+
+ if (ui_netSource.integer == AS_LOCAL)
+ {
+ Com_sprintf(hostname, sizeof(hostname), "%s [%s]", cleaned,
+ netnames[atoi(Info_ValueForKey(info, "nettype"))]);
+ return hostname;
+ }
+ else
+ {
+ char *text;
+ char *label;
+
+ label = Info_ValueForKey(info, "label");
+ if (label[0])
+ {
+ // First char of the label response is a sorting tag. Skip it.
+ label += 1;
+
+ Com_sprintf(hostname, sizeof(hostname), "%s %s", label, cleaned);
+ }
+ else
+ {
+ Com_sprintf(hostname, sizeof(hostname), "%s", cleaned);
+ }
+
+ // Strip leading whitespace
+ text = hostname;
+
+ while (*text != '\0' && *text == ' ')
+ text++;
+
+ return text;
+ }
+ }
+
+ case SORT_GAME:
+ return Info_ValueForKey(info, "game");
+
+ case SORT_MAP:
+ return Info_ValueForKey(info, "mapname");
+
+ case SORT_CLIENTS:
+ Com_sprintf(clientBuff, sizeof(clientBuff), "%s (%s)", Info_ValueForKey(info, "clients"),
+ Info_ValueForKey(info, "sv_maxclients"));
+ return clientBuff;
+
+ case SORT_PING:
+ if (ping <= 0)
+ return "...";
+ else
+ return Info_ValueForKey(info, "ping");
}
- else {
- // can't add any more so we're done
- uiInfo.pendingServerStatus.num = uiInfo.serverStatus.numDisplayServers;
+ }
+ }
+ else if (feederID == FEEDER_SERVERSTATUS)
+ {
+ if (index >= 0 && index < uiInfo.serverStatusInfo.numLines)
+ {
+ if (column >= 0 && column < 4)
+ return uiInfo.serverStatusInfo.lines[index][column];
+ }
+ }
+ else if (feederID == FEEDER_NEWS)
+ {
+ if (index >= 0 && index < uiInfo.newsInfo.numLines)
+ return uiInfo.newsInfo.text[index];
+ }
+ else if (feederID == FEEDER_GITHUB_RELEASE)
+ {
+ if (index >= 0 && index < uiInfo.githubRelease.numLines)
+ return uiInfo.githubRelease.text[index];
+ }
+ else if (feederID == FEEDER_FINDPLAYER)
+ {
+ if (index >= 0 && index < uiInfo.numFoundPlayerServers)
+ return uiInfo.foundPlayerServerNames[index];
+ }
+ else if (feederID == FEEDER_PLAYER_LIST)
+ {
+ if (index >= 0 && index < uiInfo.playerCount)
+ return uiInfo.playerNames[index];
+ }
+ else if (feederID == FEEDER_TEAM_LIST)
+ {
+ if (index >= 0 && index < uiInfo.myTeamCount)
+ return uiInfo.teamNames[index];
+ }
+ else if (feederID == FEEDER_IGNORE_LIST)
+ {
+ if (index >= 0 && index < uiInfo.playerCount)
+ {
+ switch (column)
+ {
+ case 1:
+ // am I ignoring him
+ return Com_ClientListContains(&uiInfo.ignoreList[uiInfo.myPlayerIndex], uiInfo.clientNums[index])
+ ? "X"
+ : "";
+
+ case 2:
+ // is he ignoring me
+ return Com_ClientListContains(&uiInfo.ignoreList[index], uiInfo.playerNumber) ? "X" : "";
+
+ default:
+ return uiInfo.playerNames[index];
}
- }
}
- Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1],
- sizeof(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1]),
- "searching %d/%d...", uiInfo.pendingServerStatus.num, numFound);
- // retrieved the server status so reuse this spot
- uiInfo.pendingServerStatus.server[i].valid = qfalse;
- }
}
- // if empty pending slot or timed out
- if (!uiInfo.pendingServerStatus.server[i].valid ||
- uiInfo.pendingServerStatus.server[i].startTime < uiInfo.uiDC.realTime - ui_serverStatusTimeOut.integer) {
- if (uiInfo.pendingServerStatus.server[i].valid) {
- numTimeOuts++;
- }
- // reset server status request for this address
- UI_GetServerStatusInfo( uiInfo.pendingServerStatus.server[i].adrstr, NULL );
- // reuse pending slot
- uiInfo.pendingServerStatus.server[i].valid = qfalse;
- // if we didn't try to get the status of all servers in the main browser yet
- if (uiInfo.pendingServerStatus.num < uiInfo.serverStatus.numDisplayServers) {
- uiInfo.pendingServerStatus.server[i].startTime = uiInfo.uiDC.realTime;
- trap_LAN_GetServerAddressString(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.pendingServerStatus.num],
- uiInfo.pendingServerStatus.server[i].adrstr, sizeof(uiInfo.pendingServerStatus.server[i].adrstr));
- trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.pendingServerStatus.num], infoString, sizeof(infoString));
- Q_strncpyz(uiInfo.pendingServerStatus.server[i].name, Info_ValueForKey(infoString, "hostname"), sizeof(uiInfo.pendingServerStatus.server[0].name));
- uiInfo.pendingServerStatus.server[i].valid = qtrue;
- uiInfo.pendingServerStatus.num++;
- Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1],
- sizeof(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1]),
- "searching %d/%d...", uiInfo.pendingServerStatus.num, numFound);
- }
+ else if (feederID == FEEDER_HELP_LIST)
+ {
+ if (index >= 0 && index < uiInfo.helpCount)
+ return uiInfo.helpList[index].text;
}
- }
- for (i = 0; i < MAX_SERVERSTATUSREQUESTS; i++) {
- if (uiInfo.pendingServerStatus.server[i].valid) {
- break;
- }
- }
- // if still trying to retrieve server status info
- if (i < MAX_SERVERSTATUSREQUESTS) {
- uiInfo.nextFindPlayerRefresh = uiInfo.uiDC.realTime + 25;
- }
- else {
- // add a line that shows the number of servers found
- if (!uiInfo.numFoundPlayerServers) {
- Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1], sizeof(uiInfo.foundPlayerServerAddresses[0]), "no servers found");
- }
- else {
- Com_sprintf(uiInfo.foundPlayerServerNames[uiInfo.numFoundPlayerServers-1], sizeof(uiInfo.foundPlayerServerAddresses[0]),
- "%d server%s found with player %s", uiInfo.numFoundPlayerServers-1,
- uiInfo.numFoundPlayerServers == 2 ? "":"s", uiInfo.findPlayerName);
- }
- uiInfo.nextFindPlayerRefresh = 0;
- // show the server status info for the selected server
- UI_FeederSelection(FEEDER_FINDPLAYER, uiInfo.currentFoundPlayerServer);
- }
-}
+ else if (feederID == FEEDER_MODS)
+ {
+ if (index >= 0 && index < uiInfo.modCount)
+ {
+ if (uiInfo.modList[index].modDescr && *uiInfo.modList[index].modDescr)
+ return uiInfo.modList[index].modDescr;
+ else
+ return uiInfo.modList[index].modName;
+ }
+ }
+ else if (feederID == FEEDER_CINEMATICS)
+ {
+ if (index >= 0 && index < uiInfo.movieCount)
+ return uiInfo.movieList[index];
+ }
+ else if (feederID == FEEDER_DEMOS)
+ {
+ if (index >= 0 && index < uiInfo.demoCount)
+ return uiInfo.demoList[index];
+ }
+ else if (feederID == FEEDER_TREMTEAMS)
+ {
+ if (index >= 0 && index < uiInfo.teamCount)
+ return uiInfo.teamList[index].text;
+ }
+ else if (feederID == FEEDER_TREMHUMANITEMS)
+ {
+ if (index >= 0 && index < uiInfo.humanItemCount)
+ return uiInfo.humanItemList[index].text;
+ }
+ else if (feederID == FEEDER_TREMALIENCLASSES)
+ {
+ if (index >= 0 && index < uiInfo.alienClassCount)
+ return uiInfo.alienClassList[index].text;
+ }
+ else if (feederID == FEEDER_TREMHUMANARMOURYBUY)
+ {
+ if (index >= 0 && index < uiInfo.humanArmouryBuyCount)
+ return uiInfo.humanArmouryBuyList[index].text;
+ }
+ else if (feederID == FEEDER_TREMHUMANARMOURYSELL)
+ {
+ if (index >= 0 && index < uiInfo.humanArmourySellCount)
+ return uiInfo.humanArmourySellList[index].text;
+ }
+ else if (feederID == FEEDER_TREMALIENUPGRADE)
+ {
+ if (index >= 0 && index < uiInfo.alienUpgradeCount)
+ return uiInfo.alienUpgradeList[index].text;
+ }
+ else if (feederID == FEEDER_TREMALIENBUILD)
+ {
+ if (index >= 0 && index < uiInfo.alienBuildCount)
+ return uiInfo.alienBuildList[index].text;
+ }
+ else if (feederID == FEEDER_TREMHUMANBUILD)
+ {
+ if (index >= 0 && index < uiInfo.humanBuildCount)
+ return uiInfo.humanBuildList[index].text;
+ }
+ else if (feederID == FEEDER_RESOLUTIONS)
+ {
+ static char resolution[MAX_STRING_CHARS];
+ int w, h;
-/*
-==================
-UI_BuildServerStatus
-==================
-*/
-static void UI_BuildServerStatus(qboolean force) {
-
- if (uiInfo.nextFindPlayerRefresh) {
- return;
- }
- if (!force) {
- if (!uiInfo.nextServerStatusRefresh || uiInfo.nextServerStatusRefresh > uiInfo.uiDC.realTime) {
- return;
- }
- }
- else {
- Menu_SetFeederSelection(NULL, FEEDER_SERVERSTATUS, 0, NULL);
- uiInfo.serverStatusInfo.numLines = 0;
- // reset all server status requests
- trap_LAN_ServerStatus( NULL, NULL, 0);
- }
- if (uiInfo.serverStatus.currentServer < 0 || uiInfo.serverStatus.currentServer > uiInfo.serverStatus.numDisplayServers || uiInfo.serverStatus.numDisplayServers == 0) {
- return;
- }
- if (UI_GetServerStatusInfo( uiInfo.serverStatusAddress, &uiInfo.serverStatusInfo ) ) {
- uiInfo.nextServerStatusRefresh = 0;
- UI_GetServerStatusInfo( uiInfo.serverStatusAddress, NULL );
- }
- else {
- uiInfo.nextServerStatusRefresh = uiInfo.uiDC.realTime + 500;
- }
-}
+ if (index >= 0 && index < uiInfo.numResolutions)
+ {
+ w = uiInfo.resolutions[index].w;
+ h = uiInfo.resolutions[index].h;
-/*
-==================
-UI_FeederCount
-==================
-*/
-static int UI_FeederCount(float feederID) {
-
- if (feederID == FEEDER_HEADS) {
- return UI_HeadCountByTeam();
- } else if (feederID == FEEDER_Q3HEADS) {
- return uiInfo.q3HeadCount;
- } else if (feederID == FEEDER_CINEMATICS) {
- return uiInfo.movieCount;
- } else if (feederID == FEEDER_MAPS || feederID == FEEDER_ALLMAPS) {
- return UI_MapCountByGameType(feederID == FEEDER_MAPS ? qtrue : qfalse);
- } else if (feederID == FEEDER_SERVERS) {
- return uiInfo.serverStatus.numDisplayServers;
- } else if (feederID == FEEDER_SERVERSTATUS) {
- return uiInfo.serverStatusInfo.numLines;
- } else if (feederID == FEEDER_FINDPLAYER) {
- return uiInfo.numFoundPlayerServers;
- } else if (feederID == FEEDER_PLAYER_LIST) {
- if (uiInfo.uiDC.realTime > uiInfo.playerRefresh) {
- uiInfo.playerRefresh = uiInfo.uiDC.realTime + 3000;
- UI_BuildPlayerList();
- }
- return uiInfo.playerCount;
- } else if (feederID == FEEDER_TEAM_LIST) {
- if (uiInfo.uiDC.realTime > uiInfo.playerRefresh) {
- uiInfo.playerRefresh = uiInfo.uiDC.realTime + 3000;
- UI_BuildPlayerList();
- }
- return uiInfo.myTeamCount;
- } else if (feederID == FEEDER_IGNORE_LIST) {
- return uiInfo.playerCount;
- } else if (feederID == FEEDER_MODS) {
- return uiInfo.modCount;
- } else if (feederID == FEEDER_DEMOS) {
- return uiInfo.demoCount;
- }
-
-//TA: tremulous menus
- else if( feederID == FEEDER_TREMTEAMS )
- return uiInfo.tremTeamCount;
- else if( feederID == FEEDER_TREMHUMANITEMS )
- return uiInfo.tremHumanItemCount;
- else if( feederID == FEEDER_TREMALIENCLASSES )
- return uiInfo.tremAlienClassCount;
- else if( feederID == FEEDER_TREMHUMANARMOURYBUY )
- return uiInfo.tremHumanArmouryBuyCount;
- else if( feederID == FEEDER_TREMHUMANARMOURYSELL )
- return uiInfo.tremHumanArmourySellCount;
- else if( feederID == FEEDER_TREMALIENUPGRADE )
- return uiInfo.tremAlienUpgradeCount;
- else if( feederID == FEEDER_TREMALIENBUILD )
- return uiInfo.tremAlienBuildCount;
- else if( feederID == FEEDER_TREMHUMANBUILD )
- return uiInfo.tremHumanBuildCount;
-//TA: tremulous menus
-
- return 0;
-}
+ Com_sprintf(resolution, sizeof(resolution), "%dx%d (%s)", w, h, UI_DisplayAspectString(w, h));
-static const char *UI_SelectedMap(int index, int *actual) {
- int i, c;
- c = 0;
- *actual = 0;
- for (i = 0; i < uiInfo.mapCount; i++) {
- if (uiInfo.mapList[i].active) {
- if (c == index) {
- *actual = i;
- return uiInfo.mapList[i].mapName;
- } else {
- c++;
- }
- }
- }
- return "";
-}
+ return resolution;
+ }
-static const char *UI_SelectedHead(int index, int *actual) {
- int i, c;
- c = 0;
- *actual = 0;
- for (i = 0; i < uiInfo.characterCount; i++) {
- if (uiInfo.characterList[i].active) {
- if (c == index) {
- *actual = i;
- return uiInfo.characterList[i].name;
- } else {
- c++;
- }
- }
- }
- return "";
-}
+ w = (int)trap_Cvar_VariableValue("r_width");
+ h = (int)trap_Cvar_VariableValue("r_height");
+ Com_sprintf(resolution, sizeof(resolution), "Custom (%dx%d)", w, h);
-static int UI_GetIndexFromSelection(int actual) {
- int i, c;
- c = 0;
- for (i = 0; i < uiInfo.mapCount; i++) {
- if (uiInfo.mapList[i].active) {
- if (i == actual) {
- return c;
- }
- c++;
+ return resolution;
}
- }
- return 0;
+ else if (feederID == FEEDER_TREMVOICECMD)
+ {
+ if (index >= 0 && index < uiInfo.voiceCmdCount)
+ return uiInfo.voiceCmdList[index].text;
+ }
+
+ return "";
}
-static void UI_UpdatePendingPings( void ) {
- trap_LAN_ResetPings(ui_netSource.integer);
- uiInfo.serverStatus.refreshActive = qtrue;
- uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 1000;
+static qhandle_t UI_FeederItemImage(int feederID, int index)
+{
+ if (feederID == FEEDER_MAPS)
+ {
+ int actual;
+ UI_SelectedMap(index, &actual);
+ index = actual;
+
+ if (index >= 0 && index < uiInfo.mapCount)
+ {
+ if (uiInfo.mapList[index].levelShot == -1)
+ uiInfo.mapList[index].levelShot = trap_R_RegisterShaderNoMip(uiInfo.mapList[index].imageName);
+
+ return uiInfo.mapList[index].levelShot;
+ }
+ }
+ return 0;
}
-static const char *UI_FeederItemText(float feederID, int index, int column, qhandle_t *handle) {
- static char info[MAX_STRING_CHARS];
- static char hostname[1024];
- static char clientBuff[32];
- static int lastColumn = -1;
- static int lastTime = 0;
- *handle = -1;
- if (feederID == FEEDER_HEADS) {
- int actual;
- return UI_SelectedHead(index, &actual);
- } else if (feederID == FEEDER_Q3HEADS) {
- if (index >= 0 && index < uiInfo.q3HeadCount) {
- return uiInfo.q3HeadNames[index];
- }
- } else if (feederID == FEEDER_MAPS || feederID == FEEDER_ALLMAPS) {
- int actual;
- return UI_SelectedMap(index, &actual);
- } else if (feederID == FEEDER_SERVERS) {
- if (index >= 0 && index < uiInfo.serverStatus.numDisplayServers) {
- int ping;
- if (lastColumn != column || lastTime > uiInfo.uiDC.realTime + 5000) {
- trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[index], info, MAX_STRING_CHARS);
- lastColumn = column;
- lastTime = uiInfo.uiDC.realTime;
- }
+static void UI_FeederSelection(int feederID, int index)
+{
+ static char info[MAX_STRING_CHARS];
- ping = atoi(Info_ValueForKey(info, "ping"));
- if (ping == -1) {
- // if we ever see a ping that is out of date, do a server refresh
- // UI_UpdatePendingPings();
- }
- switch (column) {
- case SORT_HOST :
- if (ping <= 0) {
- return Info_ValueForKey(info, "addr");
- } else {
- if ( ui_netSource.integer == AS_LOCAL ) {
- Com_sprintf( hostname, sizeof(hostname), "%s [%s]",
- Info_ValueForKey(info, "hostname"),
- netnames[atoi(Info_ValueForKey(info, "nettype"))] );
- return hostname;
- }
- else
- {
- char *text;
+ if (feederID == FEEDER_MAPS)
+ {
+ int actual, map;
+ map = ui_selectedMap.integer;
- Com_sprintf( hostname, sizeof(hostname), "%s", Info_ValueForKey(info, "hostname"));
+ if (uiInfo.mapList[map].cinematic >= 0)
+ {
+ trap_CIN_StopCinematic(uiInfo.mapList[map].cinematic);
+ uiInfo.mapList[map].cinematic = -1;
+ }
- // Strip leading whitespace
- text = hostname;
- while( *text != '\0' && *text == ' ' )
- text++;
+ UI_SelectedMap(index, &actual);
- return text;
- }
- }
- case SORT_MAP :
- return Info_ValueForKey(info, "mapname");
- case SORT_CLIENTS :
- Com_sprintf( clientBuff, sizeof(clientBuff), "%s (%s)", Info_ValueForKey(info, "clients"), Info_ValueForKey(info, "sv_maxclients"));
- return clientBuff;
- case SORT_PING :
- if (ping <= 0) {
- return "...";
- } else {
- return Info_ValueForKey(info, "ping");
- }
- }
- }
- } else if (feederID == FEEDER_SERVERSTATUS) {
- if ( index >= 0 && index < uiInfo.serverStatusInfo.numLines ) {
- if ( column >= 0 && column < 4 ) {
- return uiInfo.serverStatusInfo.lines[index][column];
- }
- }
- } else if (feederID == FEEDER_FINDPLAYER) {
- if ( index >= 0 && index < uiInfo.numFoundPlayerServers ) {
- //return uiInfo.foundPlayerServerAddresses[index];
- return uiInfo.foundPlayerServerNames[index];
+ ui_selectedMap.integer = actual;
+ trap_Cvar_Set("ui_selectedMap", va("%d", actual));
+ uiInfo.mapList[ui_selectedMap.integer].cinematic = trap_CIN_PlayCinematic(
+ va("%s.roq", uiInfo.mapList[ui_selectedMap.integer].mapLoadName), 0, 0, 0, 0, (CIN_loop | CIN_silent));
}
- } else if (feederID == FEEDER_PLAYER_LIST) {
- if (index >= 0 && index < uiInfo.playerCount) {
- return uiInfo.playerNames[index];
+ else if (feederID == FEEDER_SERVERS)
+ {
+ const char *mapName = NULL;
+
+ uiInfo.serverStatus.currentServer = index;
+ trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[index], info, MAX_STRING_CHARS);
+ uiInfo.serverStatus.currentServerPreview =
+ trap_R_RegisterShaderNoMip(va("levelshots/%s", Info_ValueForKey(info, "mapname")));
+
+ if (uiInfo.serverStatus.currentServerCinematic >= 0)
+ {
+ trap_CIN_StopCinematic(uiInfo.serverStatus.currentServerCinematic);
+ uiInfo.serverStatus.currentServerCinematic = -1;
+ }
+
+ mapName = Info_ValueForKey(info, "mapname");
+
+ if (mapName && *mapName)
+ {
+ uiInfo.serverStatus.currentServerCinematic =
+ trap_CIN_PlayCinematic(va("%s.roq", mapName), 0, 0, 0, 0, (CIN_loop | CIN_silent));
+ }
}
- } else if (feederID == FEEDER_TEAM_LIST) {
- if (index >= 0 && index < uiInfo.myTeamCount) {
- return uiInfo.teamNames[index];
+ else if (feederID == FEEDER_SERVERSTATUS)
+ {
}
- } else if (feederID == FEEDER_IGNORE_LIST) {
- if (index >= 0 && index < uiInfo.playerCount) {
- switch( column )
- {
- case 1:
- // am I ignoring him
- return ( BG_ClientListTest(&uiInfo.ignoreList[ uiInfo.myPlayerIndex ],
- uiInfo.clientNums[ index ] ) ) ? "X" : "";
- case 2:
- // is he ignoring me
- return ( BG_ClientListTest( &uiInfo.ignoreList[ index ],
- uiInfo.playerNumber ) ) ? "X" : "";
- default:
- return uiInfo.playerNames[index];
- }
+ else if (feederID == FEEDER_FINDPLAYER)
+ {
+ uiInfo.currentFoundPlayerServer = index;
+ //
+
+ if (index < uiInfo.numFoundPlayerServers - 1)
+ {
+ // build a new server status for this server
+ Q_strncpyz(uiInfo.serverStatusAddress, uiInfo.foundPlayerServerAddresses[uiInfo.currentFoundPlayerServer],
+ sizeof(uiInfo.serverStatusAddress));
+ Menu_SetFeederSelection(NULL, FEEDER_SERVERSTATUS, 0, NULL);
+ UI_BuildServerStatus(qtrue);
+ }
}
- } else if (feederID == FEEDER_MODS) {
- if (index >= 0 && index < uiInfo.modCount) {
- if (uiInfo.modList[index].modDescr && *uiInfo.modList[index].modDescr) {
- return uiInfo.modList[index].modDescr;
- } else {
- return uiInfo.modList[index].modName;
- }
+ else if (feederID == FEEDER_PLAYER_LIST)
+ uiInfo.playerIndex = index;
+ else if (feederID == FEEDER_TEAM_LIST)
+ uiInfo.teamPlayerIndex = index;
+ else if (feederID == FEEDER_IGNORE_LIST)
+ uiInfo.ignoreIndex = index;
+ else if (feederID == FEEDER_HELP_LIST)
+ uiInfo.helpIndex = index;
+ else if (feederID == FEEDER_MODS)
+ uiInfo.modIndex = index;
+ else if (feederID == FEEDER_CINEMATICS)
+ {
+ uiInfo.movieIndex = index;
+
+ if (uiInfo.previewMovie >= 0)
+ trap_CIN_StopCinematic(uiInfo.previewMovie);
+
+ uiInfo.previewMovie = -1;
+ }
+ else if (feederID == FEEDER_DEMOS)
+ uiInfo.demoIndex = index;
+ else if (feederID == FEEDER_TREMTEAMS)
+ uiInfo.teamIndex = index;
+ else if (feederID == FEEDER_TREMHUMANITEMS)
+ uiInfo.humanItemIndex = index;
+ else if (feederID == FEEDER_TREMALIENCLASSES)
+ uiInfo.alienClassIndex = index;
+ else if (feederID == FEEDER_TREMHUMANARMOURYBUY)
+ uiInfo.humanArmouryBuyIndex = index;
+ else if (feederID == FEEDER_TREMHUMANARMOURYSELL)
+ uiInfo.humanArmourySellIndex = index;
+ else if (feederID == FEEDER_TREMALIENUPGRADE)
+ uiInfo.alienUpgradeIndex = index;
+ else if (feederID == FEEDER_TREMALIENBUILD)
+ uiInfo.alienBuildIndex = index;
+ else if (feederID == FEEDER_TREMHUMANBUILD)
+ uiInfo.humanBuildIndex = index;
+ else if (feederID == FEEDER_RESOLUTIONS)
+ {
+ if (index >= 0 && index < uiInfo.numResolutions)
+ {
+ trap_Cvar_Set("r_width", va("%d", uiInfo.resolutions[index].w));
+ trap_Cvar_Set("r_height", va("%d", uiInfo.resolutions[index].h));
+ }
+
+ uiInfo.resolutionIndex = index;
}
- } else if (feederID == FEEDER_CINEMATICS) {
- if (index >= 0 && index < uiInfo.movieCount) {
- return uiInfo.movieList[index];
- }
- } else if (feederID == FEEDER_DEMOS) {
- if (index >= 0 && index < uiInfo.demoCount) {
- return uiInfo.demoList[index];
- }
- }
-
-//TA: tremulous menus
- else if( feederID == FEEDER_TREMTEAMS )
- {
- if( index >= 0 && index < uiInfo.tremTeamCount )
- return uiInfo.tremTeamList[ index ].text;
- }
- else if( feederID == FEEDER_TREMHUMANITEMS )
- {
- if( index >= 0 && index < uiInfo.tremHumanItemCount )
- return uiInfo.tremHumanItemList[ index ].text;
- }
- else if( feederID == FEEDER_TREMALIENCLASSES )
- {
- if( index >= 0 && index < uiInfo.tremAlienClassCount )
- return uiInfo.tremAlienClassList[ index ].text;
- }
- else if( feederID == FEEDER_TREMHUMANARMOURYBUY )
- {
- if( index >= 0 && index < uiInfo.tremHumanArmouryBuyCount )
- return uiInfo.tremHumanArmouryBuyList[ index ].text;
- }
- else if( feederID == FEEDER_TREMHUMANARMOURYSELL )
- {
- if( index >= 0 && index < uiInfo.tremHumanArmourySellCount )
- return uiInfo.tremHumanArmourySellList[ index ].text;
- }
- else if( feederID == FEEDER_TREMALIENUPGRADE )
- {
- if( index >= 0 && index < uiInfo.tremAlienUpgradeCount )
- return uiInfo.tremAlienUpgradeList[ index ].text;
- }
- else if( feederID == FEEDER_TREMALIENBUILD )
- {
- if( index >= 0 && index < uiInfo.tremAlienBuildCount )
- return uiInfo.tremAlienBuildList[ index ].text;
- }
- else if( feederID == FEEDER_TREMHUMANBUILD )
- {
- if( index >= 0 && index < uiInfo.tremHumanBuildCount )
- return uiInfo.tremHumanBuildList[ index ].text;
- }
-//TA: tremulous menus
-
- return "";
+ else if (feederID == FEEDER_TREMVOICECMD)
+ uiInfo.voiceCmdIndex = index;
}
+static int UI_FeederInitialise(int feederID)
+{
+ if (feederID == FEEDER_RESOLUTIONS)
+ {
+ int i;
+ int w = trap_Cvar_VariableValue("r_width");
+ int h = trap_Cvar_VariableValue("r_height");
-static qhandle_t UI_FeederItemImage(float feederID, int index) {
- if (feederID == FEEDER_HEADS) {
- int actual;
- UI_SelectedHead(index, &actual);
- index = actual;
- if (index >= 0 && index < uiInfo.characterCount) {
- if (uiInfo.characterList[index].headImage == -1) {
- uiInfo.characterList[index].headImage = trap_R_RegisterShaderNoMip(uiInfo.characterList[index].imageName);
- }
- return uiInfo.characterList[index].headImage;
- }
- } else if (feederID == FEEDER_Q3HEADS) {
- if (index >= 0 && index < uiInfo.q3HeadCount) {
- return uiInfo.q3HeadIcons[index];
- }
- } else if (feederID == FEEDER_ALLMAPS || feederID == FEEDER_MAPS) {
- int actual;
- UI_SelectedMap(index, &actual);
- index = actual;
- if (index >= 0 && index < uiInfo.mapCount) {
- if (uiInfo.mapList[index].levelShot == -1) {
- uiInfo.mapList[index].levelShot = trap_R_RegisterShaderNoMip(uiInfo.mapList[index].imageName);
- }
- return uiInfo.mapList[index].levelShot;
- }
- }
- return 0;
-}
+ for (i = 0; i < uiInfo.numResolutions; i++)
+ {
+ if (w == uiInfo.resolutions[i].w && h == uiInfo.resolutions[i].h)
+ return i;
+ }
-static void UI_FeederSelection(float feederID, int index) {
- static char info[MAX_STRING_CHARS];
- if (feederID == FEEDER_HEADS) {
- int actual;
- UI_SelectedHead(index, &actual);
- index = actual;
- if (index >= 0 && index < uiInfo.characterCount) {
- trap_Cvar_Set( "team_model", va("%s", uiInfo.characterList[index].base));
- trap_Cvar_Set( "team_headmodel", va("*%s", uiInfo.characterList[index].name));
- updateModel = qtrue;
- }
- } else if (feederID == FEEDER_Q3HEADS) {
- if (index >= 0 && index < uiInfo.q3HeadCount) {
- trap_Cvar_Set( "model", uiInfo.q3HeadNames[index]);
- trap_Cvar_Set( "headmodel", uiInfo.q3HeadNames[index]);
- updateModel = qtrue;
- }
- } else if (feederID == FEEDER_MAPS || feederID == FEEDER_ALLMAPS) {
- int actual, map;
- map = (feederID == FEEDER_ALLMAPS) ? ui_currentNetMap.integer : ui_currentMap.integer;
- if (uiInfo.mapList[map].cinematic >= 0) {
- trap_CIN_StopCinematic(uiInfo.mapList[map].cinematic);
- uiInfo.mapList[map].cinematic = -1;
- }
- UI_SelectedMap(index, &actual);
- trap_Cvar_Set("ui_mapIndex", va("%d", index));
- ui_mapIndex.integer = index;
-
- if (feederID == FEEDER_MAPS) {
- ui_currentMap.integer = actual;
- trap_Cvar_Set("ui_currentMap", va("%d", actual));
- uiInfo.mapList[ui_currentMap.integer].cinematic = trap_CIN_PlayCinematic(va("%s.roq", uiInfo.mapList[ui_currentMap.integer].mapLoadName), 0, 0, 0, 0, (CIN_loop | CIN_silent) );
- UI_LoadBestScores(uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum);
- trap_Cvar_Set("ui_opponentModel", uiInfo.mapList[ui_currentMap.integer].opponentName);
- updateOpponentModel = qtrue;
- } else {
- ui_currentNetMap.integer = actual;
- trap_Cvar_Set("ui_currentNetMap", va("%d", actual));
- uiInfo.mapList[ui_currentNetMap.integer].cinematic = trap_CIN_PlayCinematic(va("%s.roq", uiInfo.mapList[ui_currentNetMap.integer].mapLoadName), 0, 0, 0, 0, (CIN_loop | CIN_silent) );
+ return uiInfo.numResolutions;
}
- } else if (feederID == FEEDER_SERVERS) {
- const char *mapName = NULL;
- uiInfo.serverStatus.currentServer = index;
- trap_LAN_GetServerInfo(ui_netSource.integer, uiInfo.serverStatus.displayServers[index], info, MAX_STRING_CHARS);
- uiInfo.serverStatus.currentServerPreview = trap_R_RegisterShaderNoMip(va("levelshots/%s", Info_ValueForKey(info, "mapname")));
- if (uiInfo.serverStatus.currentServerCinematic >= 0) {
- trap_CIN_StopCinematic(uiInfo.serverStatus.currentServerCinematic);
- uiInfo.serverStatus.currentServerCinematic = -1;
- }
- mapName = Info_ValueForKey(info, "mapname");
- if (mapName && *mapName) {
- uiInfo.serverStatus.currentServerCinematic = trap_CIN_PlayCinematic(va("%s.roq", mapName), 0, 0, 0, 0, (CIN_loop | CIN_silent) );
+ return 0;
+}
+
+static void UI_Pause(qboolean b)
+{
+ if (b)
+ {
+ // pause the game and set the ui keycatcher
+ trap_Cvar_Set("cl_paused", "1");
+ trap_Key_SetCatcher(KEYCATCH_UI);
}
- } else if (feederID == FEEDER_SERVERSTATUS) {
- //
- } else if (feederID == FEEDER_FINDPLAYER) {
- uiInfo.currentFoundPlayerServer = index;
- //
- if ( index < uiInfo.numFoundPlayerServers-1) {
- // build a new server status for this server
- Q_strncpyz(uiInfo.serverStatusAddress, uiInfo.foundPlayerServerAddresses[uiInfo.currentFoundPlayerServer], sizeof(uiInfo.serverStatusAddress));
- Menu_SetFeederSelection(NULL, FEEDER_SERVERSTATUS, 0, NULL);
- UI_BuildServerStatus(qtrue);
- }
- } else if (feederID == FEEDER_PLAYER_LIST) {
- uiInfo.playerIndex = index;
- } else if (feederID == FEEDER_TEAM_LIST) {
- uiInfo.teamIndex = index;
- } else if (feederID == FEEDER_IGNORE_LIST) {
- uiInfo.ignoreIndex = index;
- } else if (feederID == FEEDER_MODS) {
- uiInfo.modIndex = index;
- } else if (feederID == FEEDER_CINEMATICS) {
- uiInfo.movieIndex = index;
- if (uiInfo.previewMovie >= 0) {
- trap_CIN_StopCinematic(uiInfo.previewMovie);
+ else
+ {
+ // unpause the game and clear the ui keycatcher
+ trap_Key_SetCatcher(trap_Key_GetCatcher() & ~KEYCATCH_UI);
+ trap_Key_ClearStates();
+ trap_Cvar_Set("cl_paused", "0");
}
- uiInfo.previewMovie = -1;
- } else if (feederID == FEEDER_DEMOS) {
- uiInfo.demoIndex = index;
- }
-
-//TA: tremulous menus
- else if( feederID == FEEDER_TREMTEAMS )
- uiInfo.tremTeamIndex = index;
- else if( feederID == FEEDER_TREMHUMANITEMS )
- uiInfo.tremHumanItemIndex = index;
- else if( feederID == FEEDER_TREMALIENCLASSES )
- uiInfo.tremAlienClassIndex = index;
- else if( feederID == FEEDER_TREMHUMANARMOURYBUY )
- uiInfo.tremHumanArmouryBuyIndex = index;
- else if( feederID == FEEDER_TREMHUMANARMOURYSELL )
- uiInfo.tremHumanArmourySellIndex = index;
- else if( feederID == FEEDER_TREMALIENUPGRADE )
- uiInfo.tremAlienUpgradeIndex = index;
- else if( feederID == FEEDER_TREMALIENBUILD )
- uiInfo.tremAlienBuildIndex = index;
- else if( feederID == FEEDER_TREMHUMANBUILD )
- uiInfo.tremHumanBuildIndex = index;
-//TA: tremulous menus
}
-static void UI_Pause(qboolean b) {
- if (b) {
- // pause the game and set the ui keycatcher
- trap_Cvar_Set( "cl_paused", "1" );
- trap_Key_SetCatcher( KEYCATCH_UI );
- } else {
- // unpause the game and clear the ui keycatcher
- trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI );
- trap_Key_ClearStates();
- trap_Cvar_Set( "cl_paused", "0" );
- }
+static int UI_PlayCinematic(const char *name, float x, float y, float w, float h)
+{
+ return trap_CIN_PlayCinematic(name, x, y, w, h, (CIN_loop | CIN_silent));
}
-static int UI_PlayCinematic(const char *name, float x, float y, float w, float h) {
- return trap_CIN_PlayCinematic(name, x, y, w, h, (CIN_loop | CIN_silent));
-}
+static void UI_StopCinematic(int handle)
+{
+ if (handle >= 0)
+ trap_CIN_StopCinematic(handle);
+ else
+ {
+ handle = abs(handle);
-static void UI_StopCinematic(int handle) {
- if (handle >= 0) {
- trap_CIN_StopCinematic(handle);
- } else {
- handle = abs(handle);
- if (handle == UI_MAPCINEMATIC) {
- if (uiInfo.mapList[ui_currentMap.integer].cinematic >= 0) {
- trap_CIN_StopCinematic(uiInfo.mapList[ui_currentMap.integer].cinematic);
- uiInfo.mapList[ui_currentMap.integer].cinematic = -1;
- }
- } else if (handle == UI_NETMAPCINEMATIC) {
- if (uiInfo.serverStatus.currentServerCinematic >= 0) {
- trap_CIN_StopCinematic(uiInfo.serverStatus.currentServerCinematic);
- uiInfo.serverStatus.currentServerCinematic = -1;
- }
- } else if (handle == UI_CLANCINEMATIC) {
- int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_teamName"));
- if (i >= 0 && i < uiInfo.teamCount) {
- if (uiInfo.teamList[i].cinematic >= 0) {
- trap_CIN_StopCinematic(uiInfo.teamList[i].cinematic);
- uiInfo.teamList[i].cinematic = -1;
+ if (handle == UI_NETMAPCINEMATIC)
+ {
+ if (uiInfo.serverStatus.currentServerCinematic >= 0)
+ {
+ trap_CIN_StopCinematic(uiInfo.serverStatus.currentServerCinematic);
+ uiInfo.serverStatus.currentServerCinematic = -1;
+ }
}
- }
}
- }
}
-static void UI_DrawCinematic(int handle, float x, float y, float w, float h) {
- trap_CIN_SetExtents(handle, x, y, w, h);
- trap_CIN_DrawCinematic(handle);
+static void UI_DrawCinematic(int handle, float x, float y, float w, float h)
+{
+ trap_CIN_SetExtents(handle, x, y, w, h);
+ trap_CIN_DrawCinematic(handle);
}
-static void UI_RunCinematicFrame(int handle) {
- trap_CIN_RunCinematic(handle);
-}
+static void UI_RunCinematicFrame(int handle) { trap_CIN_RunCinematic(handle); }
+static float UI_GetValue(int ownerDraw) { return 0.0f; }
/*
=================
-UI_Init
+UI_ParseResolutions
=================
*/
-void _UI_Init( qboolean inGameLoad ) {
- const char *menuSet;
- int start;
-
- BG_InitClassOverrides( );
- BG_InitAllowedGameElements( );
-
- //uiInfo.inGameLoad = inGameLoad;
-
- UI_RegisterCvars();
- UI_InitMemory();
-
- // cache redundant calulations
- trap_GetGlconfig( &uiInfo.uiDC.glconfig );
-
- // for 640x480 virtualized screen
- uiInfo.uiDC.yscale = uiInfo.uiDC.glconfig.vidHeight * (1.0/480.0);
- uiInfo.uiDC.xscale = uiInfo.uiDC.glconfig.vidWidth * (1.0/640.0);
- if ( uiInfo.uiDC.glconfig.vidWidth * 480 > uiInfo.uiDC.glconfig.vidHeight * 640 ) {
- // wide screen
- uiInfo.uiDC.bias = 0.5 * ( uiInfo.uiDC.glconfig.vidWidth - ( uiInfo.uiDC.glconfig.vidHeight * (640.0/480.0) ) );
- }
- else {
- // no wide screen
- uiInfo.uiDC.bias = 0;
- }
-
-
- //UI_Load();
- uiInfo.uiDC.registerShaderNoMip = &trap_R_RegisterShaderNoMip;
- uiInfo.uiDC.setColor = &UI_SetColor;
- uiInfo.uiDC.drawHandlePic = &UI_DrawHandlePic;
- uiInfo.uiDC.drawStretchPic = &trap_R_DrawStretchPic;
- uiInfo.uiDC.drawText = &Text_Paint;
- uiInfo.uiDC.textWidth = &Text_Width;
- uiInfo.uiDC.textHeight = &Text_Height;
- uiInfo.uiDC.registerModel = &trap_R_RegisterModel;
- uiInfo.uiDC.modelBounds = &trap_R_ModelBounds;
- uiInfo.uiDC.fillRect = &UI_FillRect;
- uiInfo.uiDC.drawRect = &_UI_DrawRect;
- uiInfo.uiDC.drawSides = &_UI_DrawSides;
- uiInfo.uiDC.drawTopBottom = &_UI_DrawTopBottom;
- uiInfo.uiDC.clearScene = &trap_R_ClearScene;
- uiInfo.uiDC.drawSides = &_UI_DrawSides;
- uiInfo.uiDC.addRefEntityToScene = &trap_R_AddRefEntityToScene;
- uiInfo.uiDC.renderScene = &trap_R_RenderScene;
- uiInfo.uiDC.registerFont = &trap_R_RegisterFont;
- uiInfo.uiDC.ownerDrawItem = &UI_OwnerDraw;
- uiInfo.uiDC.getValue = &UI_GetValue;
- uiInfo.uiDC.ownerDrawVisible = &UI_OwnerDrawVisible;
- uiInfo.uiDC.runScript = &UI_RunMenuScript;
- uiInfo.uiDC.getTeamColor = &UI_GetTeamColor;
- uiInfo.uiDC.setCVar = trap_Cvar_Set;
- uiInfo.uiDC.getCVarString = trap_Cvar_VariableStringBuffer;
- uiInfo.uiDC.getCVarValue = trap_Cvar_VariableValue;
- uiInfo.uiDC.drawTextWithCursor = &Text_PaintWithCursor;
- uiInfo.uiDC.setOverstrikeMode = &trap_Key_SetOverstrikeMode;
- uiInfo.uiDC.getOverstrikeMode = &trap_Key_GetOverstrikeMode;
- uiInfo.uiDC.startLocalSound = &trap_S_StartLocalSound;
- uiInfo.uiDC.ownerDrawHandleKey = &UI_OwnerDrawHandleKey;
- uiInfo.uiDC.feederCount = &UI_FeederCount;
- uiInfo.uiDC.feederItemImage = &UI_FeederItemImage;
- uiInfo.uiDC.feederItemText = &UI_FeederItemText;
- uiInfo.uiDC.feederSelection = &UI_FeederSelection;
- uiInfo.uiDC.setBinding = &trap_Key_SetBinding;
- uiInfo.uiDC.getBindingBuf = &trap_Key_GetBindingBuf;
- uiInfo.uiDC.keynumToStringBuf = &trap_Key_KeynumToStringBuf;
- uiInfo.uiDC.executeText = &trap_Cmd_ExecuteText;
- uiInfo.uiDC.Error = &Com_Error;
- uiInfo.uiDC.Print = &Com_Printf;
- uiInfo.uiDC.Pause = &UI_Pause;
- uiInfo.uiDC.ownerDrawWidth = &UI_OwnerDrawWidth;
- uiInfo.uiDC.registerSound = &trap_S_RegisterSound;
- uiInfo.uiDC.startBackgroundTrack = &trap_S_StartBackgroundTrack;
- uiInfo.uiDC.stopBackgroundTrack = &trap_S_StopBackgroundTrack;
- uiInfo.uiDC.playCinematic = &UI_PlayCinematic;
- uiInfo.uiDC.stopCinematic = &UI_StopCinematic;
- uiInfo.uiDC.drawCinematic = &UI_DrawCinematic;
- uiInfo.uiDC.runCinematicFrame = &UI_RunCinematicFrame;
-
- Init_Display(&uiInfo.uiDC);
-
- String_Init();
-
- uiInfo.uiDC.whiteShader = trap_R_RegisterShaderNoMip( "white" );
-
- AssetCache();
-
- start = trap_Milliseconds();
-
- uiInfo.teamCount = 0;
- uiInfo.characterCount = 0;
- uiInfo.aliasCount = 0;
-
-/* UI_ParseTeamInfo("teaminfo.txt");
- UI_LoadTeams();
- UI_ParseGameInfo("gameinfo.txt");*/
-
- menuSet = UI_Cvar_VariableString("ui_menuFiles");
- if (menuSet == NULL || menuSet[0] == '\0') {
- menuSet = "ui/menus.txt";
- }
-
-#if 0
- if (uiInfo.inGameLoad) {
- UI_LoadMenus("ui/ingame.txt", qtrue);
- } else { // bk010222: left this: UI_LoadMenus(menuSet, qtrue);
- }
-#else
- UI_LoadMenus(menuSet, qtrue);
- UI_LoadMenus("ui/ingame.txt", qfalse);
- UI_LoadMenus("ui/tremulous.txt", qfalse);
-
- UI_LoadInfoPanes( "ui/infopanes.def" );
+void UI_ParseResolutions(void)
+{
+ char buf[MAX_STRING_CHARS];
+ char w[16], h[16];
+ char *p;
+ const char *out;
+ char *s = NULL;
- if( uiInfo.uiDC.debug )
- {
- int i, j;
+ trap_Cvar_VariableStringBuffer("r_availableModes", buf, sizeof(buf));
+ p = buf;
+ uiInfo.numResolutions = 0;
- for( i = 0; i < uiInfo.tremInfoPaneCount; i++ )
+ while (uiInfo.numResolutions < MAX_RESOLUTIONS && String_Parse(&p, &out))
{
- Com_Printf( "name: %s\n", uiInfo.tremInfoPanes[ i ].name );
+ Q_strncpyz(w, out, sizeof(w));
+ s = strchr(w, 'x');
+ if (!s)
+ return;
- Com_Printf( "text: %s\n", uiInfo.tremInfoPanes[ i ].text );
+ *s++ = '\0';
+ Q_strncpyz(h, s, sizeof(h));
- for( j = 0; j < uiInfo.tremInfoPanes[ i ].numGraphics; j++ )
- Com_Printf( "graphic %d: %d %d %d %d\n", j, uiInfo.tremInfoPanes[ i ].graphics[ j ].side,
- uiInfo.tremInfoPanes[ i ].graphics[ j ].offset,
- uiInfo.tremInfoPanes[ i ].graphics[ j ].width,
- uiInfo.tremInfoPanes[ i ].graphics[ j ].height );
+ uiInfo.resolutions[uiInfo.numResolutions].w = atoi(w);
+ uiInfo.resolutions[uiInfo.numResolutions].h = atoi(h);
+ uiInfo.numResolutions++;
}
- }
-#endif
+}
- Menus_CloseAll();
+/*
+=================
+UI_Init
+=================
+*/
+void UI_Init(qboolean inGameLoad)
+{
+ BG_InitClassConfigs();
+ BG_InitAllowedGameElements();
- trap_LAN_LoadCachedServers();
- UI_LoadBestScores(uiInfo.mapList[ui_currentMap.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum);
+ uiInfo.inGameLoad = inGameLoad;
- // sets defaults for ui temp cvars
- uiInfo.effectsColor = gamecodetoui[(int)trap_Cvar_VariableValue("color1")-1];
- uiInfo.currentCrosshair = (int)trap_Cvar_VariableValue("cg_drawCrosshair");
- trap_Cvar_Set("ui_mousePitch", (trap_Cvar_VariableValue("m_pitch") >= 0) ? "0" : "1");
+ UI_RegisterCvars();
+ UI_InitMemory();
+ BG_InitMemory(); // FIXIT-M: Merge with UI_InitMemory or something
- uiInfo.serverStatus.currentServerCinematic = -1;
- uiInfo.previewMovie = -1;
+ // cache redundant calulations
+ trap_GetGlconfig(&uiInfo.uiDC.glconfig);
- if (trap_Cvar_VariableValue("ui_TeamArenaFirstRun") == 0) {
- trap_Cvar_Set("s_volume", "0.8");
- trap_Cvar_Set("s_musicvolume", "0.5");
- trap_Cvar_Set("ui_TeamArenaFirstRun", "1");
- }
+ // for 640x480 virtualized screen
+ uiInfo.uiDC.yscale = uiInfo.uiDC.glconfig.vidHeight * (1.0f / 480.0f);
+ uiInfo.uiDC.xscale = uiInfo.uiDC.glconfig.vidWidth * (1.0f / 640.0f);
- trap_Cvar_Register(NULL, "debug_protocol", "", 0 );
+ // wide screen
+ uiInfo.uiDC.aspectScale = ((640.0f * uiInfo.uiDC.glconfig.vidHeight) / (480.0f * uiInfo.uiDC.glconfig.vidWidth));
+
+ uiInfo.uiDC.smallFontScale = trap_Cvar_VariableValue("ui_smallFont");
+ uiInfo.uiDC.bigFontScale = trap_Cvar_VariableValue("ui_bigFont");
+
+ uiInfo.uiDC.registerShaderNoMip = &trap_R_RegisterShaderNoMip;
+ uiInfo.uiDC.setColor = &UI_SetColor;
+ uiInfo.uiDC.drawHandlePic = &UI_DrawHandlePic;
+ uiInfo.uiDC.drawStretchPic = &trap_R_DrawStretchPic;
+ uiInfo.uiDC.registerModel = &trap_R_RegisterModel;
+ uiInfo.uiDC.modelBounds = &trap_R_ModelBounds;
+ uiInfo.uiDC.fillRect = &UI_FillRect;
+ uiInfo.uiDC.drawRect = &UI_DrawRect;
+ uiInfo.uiDC.drawSides = &UI_DrawSides;
+ uiInfo.uiDC.drawTopBottom = &UI_DrawTopBottom;
+ uiInfo.uiDC.clearScene = &trap_R_ClearScene;
+ uiInfo.uiDC.addRefEntityToScene = &trap_R_AddRefEntityToScene;
+ uiInfo.uiDC.renderScene = &trap_R_RenderScene;
+ uiInfo.uiDC.registerFont = &trap_R_RegisterFont;
+ uiInfo.uiDC.ownerDrawItem = &UI_OwnerDraw;
+ uiInfo.uiDC.getValue = &UI_GetValue;
+ uiInfo.uiDC.ownerDrawVisible = &UI_OwnerDrawVisible;
+ uiInfo.uiDC.runScript = &UI_RunMenuScript;
+ uiInfo.uiDC.setCVar = trap_Cvar_Set;
+ uiInfo.uiDC.getCVarString = trap_Cvar_VariableStringBuffer;
+ uiInfo.uiDC.getCVarValue = trap_Cvar_VariableValue;
+ uiInfo.uiDC.setOverstrikeMode = &trap_Key_SetOverstrikeMode;
+ uiInfo.uiDC.getOverstrikeMode = &trap_Key_GetOverstrikeMode;
+ uiInfo.uiDC.startLocalSound = &trap_S_StartLocalSound;
+ uiInfo.uiDC.ownerDrawHandleKey = &UI_OwnerDrawHandleKey;
+ uiInfo.uiDC.feederCount = &UI_FeederCount;
+ uiInfo.uiDC.feederItemImage = &UI_FeederItemImage;
+ uiInfo.uiDC.feederItemText = &UI_FeederItemText;
+ uiInfo.uiDC.feederSelection = &UI_FeederSelection;
+ uiInfo.uiDC.feederInitialise = &UI_FeederInitialise;
+ uiInfo.uiDC.setBinding = &trap_Key_SetBinding;
+ uiInfo.uiDC.getBindingBuf = &trap_Key_GetBindingBuf;
+ uiInfo.uiDC.keynumToStringBuf = &trap_Key_KeynumToStringBuf;
+ uiInfo.uiDC.executeText = &trap_Cmd_ExecuteText;
+ uiInfo.uiDC.Error = &Com_Error;
+ uiInfo.uiDC.Print = &Com_Printf;
+ uiInfo.uiDC.Pause = &UI_Pause;
+ uiInfo.uiDC.ownerDrawWidth = &UI_OwnerDrawWidth;
+ uiInfo.uiDC.ownerDrawText = &UI_OwnerDrawText;
+ uiInfo.uiDC.registerSound = &trap_S_RegisterSound;
+ uiInfo.uiDC.startBackgroundTrack = &trap_S_StartBackgroundTrack;
+ uiInfo.uiDC.stopBackgroundTrack = &trap_S_StopBackgroundTrack;
+ uiInfo.uiDC.playCinematic = &UI_PlayCinematic;
+ uiInfo.uiDC.stopCinematic = &UI_StopCinematic;
+ uiInfo.uiDC.drawCinematic = &UI_DrawCinematic;
+ uiInfo.uiDC.runCinematicFrame = &UI_RunCinematicFrame;
+
+ Init_Display(&uiInfo.uiDC);
+
+ String_Init();
+
+ uiInfo.uiDC.whiteShader = trap_R_RegisterShaderNoMip("white");
+
+ AssetCache();
+
+ UI_LoadMenus("ui/menus.txt", qtrue);
+ UI_LoadMenus("ui/ingame.txt", qfalse);
+ UI_LoadMenus("ui/tremulous.txt", qfalse);
+ UI_LoadHelp("ui/help.txt");
+
+ Menus_CloseAll();
+
+ trap_LAN_LoadCachedServers();
+
+ // sets defaults for ui temp cvars
+ trap_Cvar_Set("ui_mousePitch", (trap_Cvar_VariableValue("m_pitch") >= 0) ? "0" : "1");
+
+ uiInfo.serverStatus.currentServerCinematic = -1;
+ uiInfo.previewMovie = -1;
- trap_Cvar_Set("ui_actualNetGameType", va("%d", ui_netGameType.integer));
+ UI_ParseResolutions();
+ uiInfo.voices = BG_VoiceInit();
}
-
/*
=================
UI_KeyEvent
=================
*/
-void _UI_KeyEvent( int key, qboolean down ) {
+void UI_KeyEvent(int key, qboolean down)
+{
+ if (Menu_Count() > 0)
+ {
+ menuDef_t *menu = Menu_GetFocused();
- if (Menu_Count() > 0) {
- menuDef_t *menu = Menu_GetFocused();
- if (menu) {
- if (key == K_ESCAPE && down && !Menus_AnyFullScreenVisible()) {
- Menus_CloseAll();
- } else {
- Menu_HandleKey(menu, key, down );
- }
- } else {
- trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI );
- trap_Key_ClearStates();
- trap_Cvar_Set( "cl_paused", "0" );
+ if (menu)
+ {
+ if (key == K_ESCAPE && down && !Menus_AnyFullScreenVisible())
+ Menus_CloseAll();
+ else
+ Menu_HandleKey(menu, key, down);
+ }
+ else
+ {
+ trap_Key_SetCatcher(trap_Key_GetCatcher() & ~KEYCATCH_UI);
+ trap_Key_ClearStates();
+ trap_Cvar_Set("cl_paused", "0");
+ }
}
- }
-
- //if ((s > 0) && (s != menu_null_sound)) {
- // trap_S_StartLocalSound( s, CHAN_LOCAL_SOUND );
- //}
}
/*
@@ -5712,27 +4330,25 @@ void _UI_KeyEvent( int key, qboolean down ) {
UI_MouseEvent
=================
*/
-void _UI_MouseEvent( int dx, int dy )
+void UI_MouseEvent(int dx, int dy)
{
- // update mouse screen position
- uiInfo.uiDC.cursorx += dx;
- if (uiInfo.uiDC.cursorx < 0)
- uiInfo.uiDC.cursorx = 0;
- else if (uiInfo.uiDC.cursorx > SCREEN_WIDTH)
- uiInfo.uiDC.cursorx = SCREEN_WIDTH;
-
- uiInfo.uiDC.cursory += dy;
- if (uiInfo.uiDC.cursory < 0)
- uiInfo.uiDC.cursory = 0;
- else if (uiInfo.uiDC.cursory > SCREEN_HEIGHT)
- uiInfo.uiDC.cursory = SCREEN_HEIGHT;
-
- if (Menu_Count() > 0) {
- //menuDef_t *menu = Menu_GetFocused();
- //Menu_HandleMouseMove(menu, uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory);
- Display_MouseMove(NULL, uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory);
- }
+ // update mouse screen position
+ uiInfo.uiDC.cursorx += (dx * uiInfo.uiDC.aspectScale);
+
+ if (uiInfo.uiDC.cursorx < 0)
+ uiInfo.uiDC.cursorx = 0;
+ else if (uiInfo.uiDC.cursorx > SCREEN_WIDTH)
+ uiInfo.uiDC.cursorx = SCREEN_WIDTH;
+
+ uiInfo.uiDC.cursory += dy;
+
+ if (uiInfo.uiDC.cursory < 0)
+ uiInfo.uiDC.cursory = 0;
+ else if (uiInfo.uiDC.cursory > SCREEN_HEIGHT)
+ uiInfo.uiDC.cursory = SCREEN_HEIGHT;
+ if (Menu_Count() > 0)
+ Display_MouseMove(NULL, uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory);
}
/*
@@ -5740,791 +4356,523 @@ void _UI_MouseEvent( int dx, int dy )
UI_MousePosition
=================
*/
-int _UI_MousePosition( void )
-{
- return (int)rint( uiInfo.uiDC.cursorx ) |
- (int)rint( uiInfo.uiDC.cursory ) << 16;
-}
+int UI_MousePosition(void) { return (int)rint(uiInfo.uiDC.cursorx) | (int)rint(uiInfo.uiDC.cursory) << 16; }
/*
=================
UI_SetMousePosition
=================
*/
-void _UI_SetMousePosition( int x, int y )
+void UI_SetMousePosition(int x, int y)
{
- uiInfo.uiDC.cursorx = x;
- uiInfo.uiDC.cursory = y;
+ uiInfo.uiDC.cursorx = x;
+ uiInfo.uiDC.cursory = y;
- if( Menu_Count( ) > 0 )
- Display_MouseMove( NULL, uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory );
+ if (Menu_Count() > 0)
+ Display_MouseMove(NULL, uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory);
}
-void UI_LoadNonIngame( void ) {
- const char *menuSet = UI_Cvar_VariableString("ui_menuFiles");
- if (menuSet == NULL || menuSet[0] == '\0') {
- menuSet = "ui/menus.txt";
- }
- UI_LoadMenus(menuSet, qfalse);
- uiInfo.inGameLoad = qfalse;
-}
+void UI_SetActiveMenu(uiMenuCommand_t menu)
+{
+ char buf[256];
-void _UI_SetActiveMenu( uiMenuCommand_t menu ) {
- char buf[256];
-
- // this should be the ONLY way the menu system is brought up
- // enusure minumum menu data is cached
- if (Menu_Count() > 0) {
- vec3_t v;
- v[0] = v[1] = v[2] = 0;
- switch ( menu ) {
- case UIMENU_NONE:
- trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI );
- trap_Key_ClearStates();
- trap_Cvar_Set( "cl_paused", "0" );
- Menus_CloseAll();
-
- return;
- case UIMENU_MAIN:
- //trap_Cvar_Set( "sv_killserver", "1" );
- trap_Key_SetCatcher( KEYCATCH_UI );
- //trap_S_StartLocalSound( trap_S_RegisterSound("sound/misc/menu_background.wav", qfalse) , CHAN_LOCAL_SOUND );
- //trap_S_StartBackgroundTrack("sound/misc/menu_background.wav", NULL);
- if (uiInfo.inGameLoad) {
- UI_LoadNonIngame();
- }
- Menus_CloseAll();
- Menus_ActivateByName("main");
- trap_Cvar_Set( "ui_loading", "0" );
- trap_Cvar_VariableStringBuffer("com_errorMessage", buf, sizeof(buf));
- if (strlen(buf)) {
- if (!ui_singlePlayerActive.integer) {
- if( trap_Cvar_VariableValue( "com_errorCode" ) == ERR_SERVERDISCONNECT )
- Menus_ActivateByName("drop_popmenu");
- else
- Menus_ActivateByName("error_popmenu");
- } else {
- trap_Cvar_Set("com_errorMessage", "");
- }
- }
- return;
- case UIMENU_TEAM:
- trap_Key_SetCatcher( KEYCATCH_UI );
- Menus_ActivateByName("team");
- return;
- case UIMENU_POSTGAME:
- //trap_Cvar_Set( "sv_killserver", "1" );
- trap_Key_SetCatcher( KEYCATCH_UI );
- if (uiInfo.inGameLoad) {
- UI_LoadNonIngame();
- }
- Menus_CloseAll();
- Menus_ActivateByName("endofgame");
- return;
- case UIMENU_INGAME:
- trap_Cvar_Set( "cl_paused", "1" );
- trap_Key_SetCatcher( KEYCATCH_UI );
- UI_BuildPlayerList();
- Menus_CloseAll();
- Menus_ActivateByName("ingame");
- return;
- }
- }
-}
+ // this should be the ONLY way the menu system is brought up
+ // enusure minumum menu data is cached
-qboolean _UI_IsFullscreen( void ) {
- return Menus_AnyFullScreenVisible();
-}
+ if (Menu_Count() > 0)
+ {
+ vec3_t v;
+ v[0] = v[1] = v[2] = 0;
+ switch (menu)
+ {
+ case UIMENU_NONE:
+ trap_Key_SetCatcher(trap_Key_GetCatcher() & ~KEYCATCH_UI);
+ trap_Key_ClearStates();
+ trap_Cvar_Set("cl_paused", "0");
+ Menus_CloseAll();
+ return;
+
+ case UIMENU_MAIN:
+ trap_Cvar_Set("sv_killserver", "1");
+ trap_Key_SetCatcher(KEYCATCH_UI);
+ Menus_CloseAll();
+ Menus_ActivateByName("main");
+ trap_Cvar_VariableStringBuffer("com_errorMessage", buf, sizeof(buf));
+
+ if (strlen(buf))
+ {
+ if (trap_Cvar_VariableValue("com_errorCode") == ERR_SERVERDISCONNECT)
+ Menus_ActivateByName("drop_popmenu");
+ else
+ Menus_ActivateByName("error_popmenu");
+ }
+ return;
+
+ case UIMENU_INGAME:
+ trap_Cvar_Set("cl_paused", "1");
+ trap_Key_SetCatcher(KEYCATCH_UI);
+ UI_BuildPlayerList();
+ Menus_CloseAll();
+ Menus_ActivateByName("ingame");
+ return;
+ }
+ }
+}
+qboolean UI_IsFullscreen(void) { return Menus_AnyFullScreenVisible(); }
-static connstate_t lastConnState;
-static char lastLoadingText[MAX_INFO_VALUE];
+static connstate_t lastConnState;
+static char lastLoadingText[MAX_INFO_VALUE];
-static void UI_ReadableSize ( char *buf, int bufsize, int value )
+static void UI_ReadableSize(char *buf, int bufsize, int value)
{
- if (value > 1024*1024*1024 ) { // gigs
- Com_sprintf( buf, bufsize, "%d", value / (1024*1024*1024) );
- Com_sprintf( buf+strlen(buf), bufsize-strlen(buf), ".%02d GB",
- (value % (1024*1024*1024))*100 / (1024*1024*1024) );
- } else if (value > 1024*1024 ) { // megs
- Com_sprintf( buf, bufsize, "%d", value / (1024*1024) );
- Com_sprintf( buf+strlen(buf), bufsize-strlen(buf), ".%02d MB",
- (value % (1024*1024))*100 / (1024*1024) );
- } else if (value > 1024 ) { // kilos
- Com_sprintf( buf, bufsize, "%d KB", value / 1024 );
- } else { // bytes
- Com_sprintf( buf, bufsize, "%d bytes", value );
- }
+ if (value > 1024 * 1024 * 1024)
+ { // gigs
+ Com_sprintf(buf, bufsize, "%d", value / (1024 * 1024 * 1024));
+ Com_sprintf(buf + strlen(buf), bufsize - strlen(buf), ".%02d GB",
+ (value % (1024 * 1024 * 1024)) * 100 / (1024 * 1024 * 1024));
+ }
+ else if (value > 1024 * 1024)
+ { // megs
+ Com_sprintf(buf, bufsize, "%d", value / (1024 * 1024));
+ Com_sprintf(
+ buf + strlen(buf), bufsize - strlen(buf), ".%02d MB", (value % (1024 * 1024)) * 100 / (1024 * 1024));
+ }
+ else if (value > 1024)
+ { // kilos
+ Com_sprintf(buf, bufsize, "%d KB", value / 1024);
+ }
+ else
+ { // bytes
+ Com_sprintf(buf, bufsize, "%d bytes", value);
+ }
}
// Assumes time is in msec
-static void UI_PrintTime ( char *buf, int bufsize, int time ) {
- time /= 1000; // change to seconds
-
- if (time > 3600) { // in the hours range
- Com_sprintf( buf, bufsize, "%d hr %d min", time / 3600, (time % 3600) / 60 );
- } else if (time > 60) { // mins
- Com_sprintf( buf, bufsize, "%d min %d sec", time / 60, time % 60 );
- } else { // secs
- Com_sprintf( buf, bufsize, "%d sec", time );
- }
-}
-
-void Text_PaintCenter(float x, float y, float scale, vec4_t color, const char *text, float adjust) {
- int len = Text_Width(text, scale, 0);
- Text_Paint(x - len / 2, y, scale, color, text, 0, 0, ITEM_TEXTSTYLE_SHADOWEDMORE);
-}
+static void UI_PrintTime(char *buf, int bufsize, int time)
+{
+ time /= 1000; // change to seconds
-void Text_PaintCenter_AutoWrapped(float x, float y, float xmax, float ystep, float scale, vec4_t color, const char *str, float adjust) {
- int width;
- char *s1,*s2,*s3;
- char c_bcp;
- char buf[1024];
-
- if (!str || str[0]=='\0')
- return;
-
- Q_strncpyz(buf, str, sizeof(buf));
- s1 = s2 = s3 = buf;
-
- while (1) {
- do {
- s3++;
- } while (*s3!=' ' && *s3!='\0');
- c_bcp = *s3;
- *s3 = '\0';
- width = Text_Width(s1, scale, 0);
- *s3 = c_bcp;
- if (width > xmax) {
- if (s1==s2)
- {
- // fuck, don't have a clean cut, we'll overflow
- s2 = s3;
- }
- *s2 = '\0';
- Text_PaintCenter(x, y, scale, color, s1, adjust);
- y += ystep;
- if (c_bcp == '\0')
- {
- // that was the last word
- // we could start a new loop, but that wouldn't be much use
- // even if the word is too long, we would overflow it (see above)
- // so just print it now if needed
- s2++;
- if (*s2 != '\0') // if we are printing an overflowing line we have s2 == s3
- Text_PaintCenter(x, y, scale, color, s2, adjust);
- break;
- }
- s2++;
- s1 = s2;
- s3 = s2;
+ if (time > 3600)
+ { // in the hours range
+ Com_sprintf(buf, bufsize, "%d hr %d min", time / 3600, (time % 3600) / 60);
+ }
+ else if (time > 60)
+ { // mins
+ Com_sprintf(buf, bufsize, "%d min %d sec", time / 60, time % 60);
}
else
- {
- s2 = s3;
- if (c_bcp == '\0') // we reached the end
- {
- Text_PaintCenter(x, y, scale, color, s1, adjust);
- break;
- }
+ { // secs
+ Com_sprintf(buf, bufsize, "%d sec", time);
}
- }
}
+// FIXME: move to ui_shared.c?
+void Text_PaintCenter(float x, float y, float scale, vec4_t color, const char *text, float adjust)
+{
+ int len = UI_Text_Width(text, scale);
+ UI_Text_Paint(x - len / 2, y, scale, color, text, 0, 0, ITEM_TEXTSTYLE_SHADOWEDMORE);
+}
-static void UI_DisplayDownloadInfo( const char *downloadName, float centerPoint, float yStart, float scale ) {
- static char dlText[] = "Downloading:";
- static char etaText[] = "Estimated time left:";
- static char xferText[] = "Transfer rate:";
+void Text_PaintCenter_AutoWrapped(
+ float x, float y, float xmax, float ystep, float scale, vec4_t color, const char *str, float adjust)
+{
+ int width;
+ char *s1, *s2, *s3;
+ char c_bcp;
+ char buf[1024];
- int downloadSize, downloadCount, downloadTime;
- char dlSizeBuf[64], totalSizeBuf[64], xferRateBuf[64], dlTimeBuf[64];
- int xferRate;
- int leftWidth;
- const char *s;
+ if (!str || str[0] == '\0')
+ return;
+
+ Q_strncpyz(buf, str, sizeof(buf));
- downloadSize = trap_Cvar_VariableValue( "cl_downloadSize" );
- downloadCount = trap_Cvar_VariableValue( "cl_downloadCount" );
- downloadTime = trap_Cvar_VariableValue( "cl_downloadTime" );
+ s1 = s2 = s3 = buf;
- leftWidth = 320;
+ while (1)
+ {
+ do
+ s3++;
+ while (*s3 != ' ' && *s3 != '\0');
- UI_SetColor(colorWhite);
- Text_PaintCenter(centerPoint, yStart + 112, scale, colorWhite, dlText, 0);
- Text_PaintCenter(centerPoint, yStart + 192, scale, colorWhite, etaText, 0);
- Text_PaintCenter(centerPoint, yStart + 248, scale, colorWhite, xferText, 0);
+ c_bcp = *s3;
- if (downloadSize > 0) {
- s = va( "%s (%d%%)", downloadName, downloadCount * 100 / downloadSize );
- } else {
- s = downloadName;
- }
+ *s3 = '\0';
- Text_PaintCenter(centerPoint, yStart+136, scale, colorWhite, s, 0);
+ width = UI_Text_Width(s1, scale);
- UI_ReadableSize( dlSizeBuf, sizeof dlSizeBuf, downloadCount );
- UI_ReadableSize( totalSizeBuf, sizeof totalSizeBuf, downloadSize );
+ *s3 = c_bcp;
- if (downloadCount < 4096 || !downloadTime) {
- Text_PaintCenter(leftWidth, yStart+216, scale, colorWhite, "estimating", 0);
- Text_PaintCenter(leftWidth, yStart+160, scale, colorWhite, va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), 0);
- } else {
- if ((uiInfo.uiDC.realTime - downloadTime) / 1000) {
- xferRate = downloadCount / ((uiInfo.uiDC.realTime - downloadTime) / 1000);
- } else {
- xferRate = 0;
+ if (width > xmax)
+ {
+ if (s1 == s2)
+ {
+ // fuck, don't have a clean cut, we'll overflow
+ s2 = s3;
+ }
+
+ *s2 = '\0';
+ Text_PaintCenter(x, y, scale, color, s1, adjust);
+ y += ystep;
+
+ if (c_bcp == '\0')
+ {
+ // that was the last word
+ // we could start a new loop, but that wouldn't be much use
+ // even if the word is too long, we would overflow it (see above)
+ // so just print it now if needed
+ s2++;
+
+ if (*s2 != '\0') // if we are printing an overflowing line we have s2 == s3
+ Text_PaintCenter(x, y, scale, color, s2, adjust);
+
+ break;
+ }
+
+ s2++;
+ s1 = s2;
+ s3 = s2;
+ }
+ else
+ {
+ s2 = s3;
+
+ if (c_bcp == '\0') // we reached the end
+ {
+ Text_PaintCenter(x, y, scale, color, s1, adjust);
+ break;
+ }
+ }
}
- UI_ReadableSize( xferRateBuf, sizeof xferRateBuf, xferRate );
+}
- // Extrapolate estimated completion time
- if (downloadSize && xferRate) {
- int n = downloadSize / xferRate; // estimated time for entire d/l in secs
+static void UI_DisplayDownloadInfo(const char *downloadName, float centerPoint, float yStart, float scale)
+{
+ static char dlText[] = "Downloading:";
+ static char etaText[] = "Estimated time left:";
+ static char xferText[] = "Transfer rate:";
- // We do it in K (/1024) because we'd overflow around 4MB
- UI_PrintTime ( dlTimeBuf, sizeof dlTimeBuf,
- (n - (((downloadCount/1024) * n) / (downloadSize/1024))) * 1000);
+ int downloadSize, downloadCount, downloadTime;
+ char dlSizeBuf[64], totalSizeBuf[64], xferRateBuf[64], dlTimeBuf[64];
+ int xferRate;
+ int leftWidth;
+ const char *s;
- Text_PaintCenter(leftWidth, yStart+216, scale, colorWhite, dlTimeBuf, 0);
- Text_PaintCenter(leftWidth, yStart+160, scale, colorWhite, va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), 0);
- } else {
- Text_PaintCenter(leftWidth, yStart+216, scale, colorWhite, "estimating", 0);
- if (downloadSize) {
- Text_PaintCenter(leftWidth, yStart+160, scale, colorWhite, va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), 0);
- } else {
- Text_PaintCenter(leftWidth, yStart+160, scale, colorWhite, va("(%s copied)", dlSizeBuf), 0);
- }
+ downloadSize = trap_Cvar_VariableValue("cl_downloadSize");
+ downloadCount = trap_Cvar_VariableValue("cl_downloadCount");
+ downloadTime = trap_Cvar_VariableValue("cl_downloadTime");
+
+ leftWidth = 320;
+
+ UI_SetColor(colorWhite);
+ Text_PaintCenter(centerPoint, yStart + 112, scale, colorWhite, dlText, 0);
+ Text_PaintCenter(centerPoint, yStart + 192, scale, colorWhite, etaText, 0);
+ Text_PaintCenter(centerPoint, yStart + 248, scale, colorWhite, xferText, 0);
+
+ if (downloadSize > 0)
+ s = va("%s (%d%%)", downloadName, (int)((float)downloadCount * 100.0f / downloadSize));
+ else
+ s = downloadName;
+
+ Text_PaintCenter(centerPoint, yStart + 136, scale, colorWhite, s, 0);
+
+ UI_ReadableSize(dlSizeBuf, sizeof dlSizeBuf, downloadCount);
+ UI_ReadableSize(totalSizeBuf, sizeof totalSizeBuf, downloadSize);
+
+ if (downloadCount < 4096 || !downloadTime)
+ {
+ Text_PaintCenter(leftWidth, yStart + 216, scale, colorWhite, "estimating", 0);
+ Text_PaintCenter(
+ leftWidth, yStart + 160, scale, colorWhite, va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), 0);
}
+ else
+ {
+ if ((uiInfo.uiDC.realTime - downloadTime) / 1000)
+ xferRate = downloadCount / ((uiInfo.uiDC.realTime - downloadTime) / 1000);
+ else
+ xferRate = 0;
+
+ UI_ReadableSize(xferRateBuf, sizeof xferRateBuf, xferRate);
+
+ // Extrapolate estimated completion time
+
+ if (downloadSize && xferRate)
+ {
+ int n = downloadSize / xferRate; // estimated time for entire d/l in secs
- if (xferRate) {
- Text_PaintCenter(leftWidth, yStart+272, scale, colorWhite, va("%s/Sec", xferRateBuf), 0);
+ // We do it in K (/1024) because we'd overflow around 4MB
+ UI_PrintTime(
+ dlTimeBuf, sizeof dlTimeBuf, (n - (((downloadCount / 1024) * n) / (downloadSize / 1024))) * 1000);
+
+ Text_PaintCenter(leftWidth, yStart + 216, scale, colorWhite, dlTimeBuf, 0);
+ Text_PaintCenter(
+ leftWidth, yStart + 160, scale, colorWhite, va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), 0);
+ }
+ else
+ {
+ Text_PaintCenter(leftWidth, yStart + 216, scale, colorWhite, "estimating", 0);
+
+ if (downloadSize)
+ Text_PaintCenter(
+ leftWidth, yStart + 160, scale, colorWhite, va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), 0);
+ else
+ Text_PaintCenter(leftWidth, yStart + 160, scale, colorWhite, va("(%s copied)", dlSizeBuf), 0);
+ }
+
+ if (xferRate)
+ Text_PaintCenter(leftWidth, yStart + 272, scale, colorWhite, va("%s/Sec", xferRateBuf), 0);
}
- }
}
/*
========================
UI_DrawConnectScreen
-
-This will also be overlaid on the cgame info screen during loading
-to prevent it from blinking away too rapidly on local or lan games.
========================
*/
-void UI_DrawConnectScreen( qboolean overlay ) {
- char *s;
- uiClientState_t cstate;
- char info[MAX_INFO_VALUE];
- char text[256];
- float centerPoint, yStart, scale;
-
- menuDef_t *menu = Menus_FindByName("Connect");
-
-
- if ( !overlay && menu ) {
- Menu_Paint(menu, qtrue);
- }
-
- if (!overlay) {
- centerPoint = 320;
- yStart = 130;
- scale = 0.5f;
- } else {
- centerPoint = 320;
- yStart = 32;
- scale = 0.6f;
- return;
- }
-
- // see what information we should display
- trap_GetClientState( &cstate );
-
- info[0] = '\0';
- if( trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) ) ) {
- Text_PaintCenter(centerPoint, yStart, scale, colorWhite, va( "Loading %s", Info_ValueForKey( info, "mapname" )), 0);
- }
-
- if (!Q_stricmp(cstate.servername,"localhost")) {
- Text_PaintCenter(centerPoint, yStart + 48, scale, colorWhite, va("Starting up..."), ITEM_TEXTSTYLE_SHADOWEDMORE);
- } else {
- strcpy(text, va("Connecting to %s", cstate.servername));
- Text_PaintCenter(centerPoint, yStart + 48, scale, colorWhite,text , ITEM_TEXTSTYLE_SHADOWEDMORE);
- }
-
-
- // display global MOTD at bottom
- Text_PaintCenter(centerPoint, 600, scale, colorWhite, Info_ValueForKey( cstate.updateInfoString, "motd" ), 0);
- // print any server info (server full, bad version, etc)
- if ( cstate.connState < CA_CONNECTED ) {
- Text_PaintCenter_AutoWrapped(centerPoint, yStart + 176, 630, 20, scale, colorWhite, cstate.messageString, 0);
- }
-
- if ( lastConnState > cstate.connState ) {
- lastLoadingText[0] = '\0';
- }
- lastConnState = cstate.connState;
-
- switch ( cstate.connState ) {
- case CA_CONNECTING:
- s = va("Awaiting connection...%i", cstate.connectPacketCount);
- break;
- case CA_CHALLENGING:
- s = va("Awaiting challenge...%i", cstate.connectPacketCount);
- break;
- case CA_CONNECTED: {
- char downloadName[MAX_INFO_VALUE];
-
- trap_Cvar_VariableStringBuffer( "cl_downloadName", downloadName, sizeof(downloadName) );
- if (*downloadName) {
- UI_DisplayDownloadInfo( downloadName, centerPoint, yStart, scale );
- return;
- }
+void UI_DrawConnectScreen()
+{
+ const char *s;
+ uiClientState_t cstate;
+ char info[MAX_INFO_VALUE];
+ char text[256];
+ float centerPoint = 320, yStart = 130, scale = 0.5f;
+
+ menuDef_t *menu = Menus_FindByName("Connect");
+
+ if ( menu )
+ Menu_Paint(menu, qtrue);
+
+ // see what information we should display
+ trap_GetClientState(&cstate);
+
+ info[0] = '\0';
+
+ if (trap_GetConfigString(CS_SERVERINFO, info, sizeof(info)))
+ Text_PaintCenter(
+ centerPoint, yStart, scale, colorWhite, va("Loading %s", Info_ValueForKey(info, "mapname")), 0);
+
+ if (!Q_stricmp(cstate.servername, "localhost"))
+ Text_PaintCenter(centerPoint, yStart + 48, scale, colorWhite, "Starting up...", ITEM_TEXTSTYLE_SHADOWEDMORE);
+ else
+ {
+ Com_sprintf(text, sizeof(text), "Connecting to %s", cstate.servername);
+ Text_PaintCenter(centerPoint, yStart + 48, scale, colorWhite, text, ITEM_TEXTSTYLE_SHADOWEDMORE);
}
- s = "Awaiting gamestate...";
- break;
- case CA_LOADING:
- return;
- case CA_PRIMED:
- return;
- default:
- return;
- }
+ // display global MOTD at bottom
+ Text_PaintCenter(centerPoint, 600, scale, colorWhite, Info_ValueForKey(cstate.updateInfoString, "motd"), 0);
- if (Q_stricmp(cstate.servername,"localhost")) {
- Text_PaintCenter(centerPoint, yStart + 80, scale, colorWhite, s, 0);
- }
+ // print any server info (server full, bad version, etc)
+ if (cstate.connState < CA_CONNECTED)
+ Text_PaintCenter(centerPoint, yStart + 176, scale, colorWhite, cstate.messageString, 0);
- // password required / connection rejected information goes here
-}
+ if (lastConnState > cstate.connState)
+ lastLoadingText[0] = '\0';
+ lastConnState = cstate.connState;
-/*
-================
-cvars
-================
-*/
+ switch (cstate.connState)
+ {
+ case CA_CONNECTING:
+ s = va("Awaiting connection...%i", cstate.connectPacketCount);
+ break;
-typedef struct {
- vmCvar_t *vmCvar;
- char *cvarName;
- char *defaultString;
- int cvarFlags;
-} cvarTable_t;
-
-vmCvar_t ui_ffa_fraglimit;
-vmCvar_t ui_ffa_timelimit;
-
-vmCvar_t ui_tourney_fraglimit;
-vmCvar_t ui_tourney_timelimit;
-
-vmCvar_t ui_team_fraglimit;
-vmCvar_t ui_team_timelimit;
-vmCvar_t ui_team_friendly;
-
-vmCvar_t ui_ctf_capturelimit;
-vmCvar_t ui_ctf_timelimit;
-vmCvar_t ui_ctf_friendly;
-
-vmCvar_t ui_arenasFile;
-vmCvar_t ui_botsFile;
-vmCvar_t ui_spScores1;
-vmCvar_t ui_spScores2;
-vmCvar_t ui_spScores3;
-vmCvar_t ui_spScores4;
-vmCvar_t ui_spScores5;
-vmCvar_t ui_spAwards;
-vmCvar_t ui_spVideos;
-vmCvar_t ui_spSkill;
-
-vmCvar_t ui_spSelection;
-
-vmCvar_t ui_browserMaster;
-vmCvar_t ui_browserGameType;
-vmCvar_t ui_browserSortKey;
-vmCvar_t ui_browserShowFull;
-vmCvar_t ui_browserShowEmpty;
-
-vmCvar_t ui_brassTime;
-vmCvar_t ui_drawCrosshair;
-vmCvar_t ui_drawCrosshairNames;
-vmCvar_t ui_marks;
-
-vmCvar_t ui_server1;
-vmCvar_t ui_server2;
-vmCvar_t ui_server3;
-vmCvar_t ui_server4;
-vmCvar_t ui_server5;
-vmCvar_t ui_server6;
-vmCvar_t ui_server7;
-vmCvar_t ui_server8;
-vmCvar_t ui_server9;
-vmCvar_t ui_server10;
-vmCvar_t ui_server11;
-vmCvar_t ui_server12;
-vmCvar_t ui_server13;
-vmCvar_t ui_server14;
-vmCvar_t ui_server15;
-vmCvar_t ui_server16;
-
-vmCvar_t ui_redteam;
-vmCvar_t ui_redteam1;
-vmCvar_t ui_redteam2;
-vmCvar_t ui_redteam3;
-vmCvar_t ui_redteam4;
-vmCvar_t ui_redteam5;
-vmCvar_t ui_blueteam;
-vmCvar_t ui_blueteam1;
-vmCvar_t ui_blueteam2;
-vmCvar_t ui_blueteam3;
-vmCvar_t ui_blueteam4;
-vmCvar_t ui_blueteam5;
-vmCvar_t ui_teamName;
-vmCvar_t ui_dedicated;
-vmCvar_t ui_gameType;
-vmCvar_t ui_netGameType;
-vmCvar_t ui_actualNetGameType;
-vmCvar_t ui_joinGameType;
-vmCvar_t ui_netSource;
-vmCvar_t ui_serverFilterType;
-vmCvar_t ui_opponentName;
-vmCvar_t ui_menuFiles;
-vmCvar_t ui_currentTier;
-vmCvar_t ui_currentMap;
-vmCvar_t ui_currentNetMap;
-vmCvar_t ui_mapIndex;
-vmCvar_t ui_currentOpponent;
-vmCvar_t ui_selectedPlayer;
-vmCvar_t ui_selectedPlayerName;
-vmCvar_t ui_lastServerRefresh_0;
-vmCvar_t ui_lastServerRefresh_1;
-vmCvar_t ui_lastServerRefresh_2;
-vmCvar_t ui_lastServerRefresh_3;
-vmCvar_t ui_lastServerRefresh_0_time;
-vmCvar_t ui_lastServerRefresh_1_time;
-vmCvar_t ui_lastServerRefresh_2_time;
-vmCvar_t ui_lastServerRefresh_3_time;
-vmCvar_t ui_singlePlayerActive;
-vmCvar_t ui_scoreAccuracy;
-vmCvar_t ui_scoreImpressives;
-vmCvar_t ui_scoreExcellents;
-vmCvar_t ui_scoreCaptures;
-vmCvar_t ui_scoreDefends;
-vmCvar_t ui_scoreAssists;
-vmCvar_t ui_scoreGauntlets;
-vmCvar_t ui_scoreScore;
-vmCvar_t ui_scorePerfect;
-vmCvar_t ui_scoreTeam;
-vmCvar_t ui_scoreBase;
-vmCvar_t ui_scoreTimeBonus;
-vmCvar_t ui_scoreSkillBonus;
-vmCvar_t ui_scoreShutoutBonus;
-vmCvar_t ui_scoreTime;
-vmCvar_t ui_captureLimit;
-vmCvar_t ui_fragLimit;
-vmCvar_t ui_smallFont;
-vmCvar_t ui_bigFont;
-vmCvar_t ui_findPlayer;
-vmCvar_t ui_Q3Model;
-vmCvar_t ui_hudFiles;
-vmCvar_t ui_recordSPDemo;
-vmCvar_t ui_realCaptureLimit;
-vmCvar_t ui_realWarmUp;
-vmCvar_t ui_serverStatusTimeOut;
-
-//TA: bank values
-vmCvar_t ui_bank;
-vmCvar_t ui_winner;
-
-vmCvar_t ui_chatCommands;
-
-
-// bk001129 - made static to avoid aliasing
-static cvarTable_t cvarTable[] = {
- { &ui_ffa_fraglimit, "ui_ffa_fraglimit", "20", CVAR_ARCHIVE },
- { &ui_ffa_timelimit, "ui_ffa_timelimit", "0", CVAR_ARCHIVE },
-
- { &ui_tourney_fraglimit, "ui_tourney_fraglimit", "0", CVAR_ARCHIVE },
- { &ui_tourney_timelimit, "ui_tourney_timelimit", "15", CVAR_ARCHIVE },
-
- { &ui_team_fraglimit, "ui_team_fraglimit", "0", CVAR_ARCHIVE },
- { &ui_team_timelimit, "ui_team_timelimit", "20", CVAR_ARCHIVE },
- { &ui_team_friendly, "ui_team_friendly", "1", CVAR_ARCHIVE },
-
- { &ui_ctf_capturelimit, "ui_ctf_capturelimit", "8", CVAR_ARCHIVE },
- { &ui_ctf_timelimit, "ui_ctf_timelimit", "30", CVAR_ARCHIVE },
- { &ui_ctf_friendly, "ui_ctf_friendly", "0", CVAR_ARCHIVE },
-
- { &ui_arenasFile, "g_arenasFile", "", CVAR_INIT|CVAR_ROM },
- { &ui_botsFile, "g_botsFile", "", CVAR_INIT|CVAR_ROM },
- { &ui_spScores1, "g_spScores1", "", CVAR_ARCHIVE | CVAR_ROM },
- { &ui_spScores2, "g_spScores2", "", CVAR_ARCHIVE | CVAR_ROM },
- { &ui_spScores3, "g_spScores3", "", CVAR_ARCHIVE | CVAR_ROM },
- { &ui_spScores4, "g_spScores4", "", CVAR_ARCHIVE | CVAR_ROM },
- { &ui_spScores5, "g_spScores5", "", CVAR_ARCHIVE | CVAR_ROM },
- { &ui_spAwards, "g_spAwards", "", CVAR_ARCHIVE | CVAR_ROM },
- { &ui_spVideos, "g_spVideos", "", CVAR_ARCHIVE | CVAR_ROM },
- { &ui_spSkill, "g_spSkill", "2", CVAR_ARCHIVE },
-
- { &ui_spSelection, "ui_spSelection", "", CVAR_ROM },
- { &ui_winner, "ui_winner", "", CVAR_ROM },
-
- { &ui_browserMaster, "ui_browserMaster", "0", CVAR_ARCHIVE },
- { &ui_browserGameType, "ui_browserGameType", "0", CVAR_ARCHIVE },
- { &ui_browserSortKey, "ui_browserSortKey", "4", CVAR_ARCHIVE },
- { &ui_browserShowFull, "ui_browserShowFull", "1", CVAR_ARCHIVE },
- { &ui_browserShowEmpty, "ui_browserShowEmpty", "1", CVAR_ARCHIVE },
-
- { &ui_brassTime, "cg_brassTime", "2500", CVAR_ARCHIVE },
- { &ui_drawCrosshair, "cg_drawCrosshair", "4", CVAR_ARCHIVE },
- { &ui_drawCrosshairNames, "cg_drawCrosshairNames", "1", CVAR_ARCHIVE },
- { &ui_marks, "cg_marks", "1", CVAR_ARCHIVE },
-
- { &ui_server1, "server1", "", CVAR_ARCHIVE },
- { &ui_server2, "server2", "", CVAR_ARCHIVE },
- { &ui_server3, "server3", "", CVAR_ARCHIVE },
- { &ui_server4, "server4", "", CVAR_ARCHIVE },
- { &ui_server5, "server5", "", CVAR_ARCHIVE },
- { &ui_server6, "server6", "", CVAR_ARCHIVE },
- { &ui_server7, "server7", "", CVAR_ARCHIVE },
- { &ui_server8, "server8", "", CVAR_ARCHIVE },
- { &ui_server9, "server9", "", CVAR_ARCHIVE },
- { &ui_server10, "server10", "", CVAR_ARCHIVE },
- { &ui_server11, "server11", "", CVAR_ARCHIVE },
- { &ui_server12, "server12", "", CVAR_ARCHIVE },
- { &ui_server13, "server13", "", CVAR_ARCHIVE },
- { &ui_server14, "server14", "", CVAR_ARCHIVE },
- { &ui_server15, "server15", "", CVAR_ARCHIVE },
- { &ui_server16, "server16", "", CVAR_ARCHIVE },
- { &ui_new, "ui_new", "0", CVAR_TEMP },
- { &ui_debug, "ui_debug", "0", CVAR_TEMP },
- { &ui_initialized, "ui_initialized", "0", CVAR_TEMP },
- { &ui_teamName, "ui_teamName", "Pagans", CVAR_ARCHIVE },
- { &ui_opponentName, "ui_opponentName", "Stroggs", CVAR_ARCHIVE },
- { &ui_redteam, "ui_redteam", "Pagans", CVAR_ARCHIVE },
- { &ui_blueteam, "ui_blueteam", "Stroggs", CVAR_ARCHIVE },
- { &ui_dedicated, "ui_dedicated", "0", CVAR_ARCHIVE },
- { &ui_gameType, "ui_gametype", "3", CVAR_ARCHIVE },
- { &ui_joinGameType, "ui_joinGametype", "0", CVAR_ARCHIVE },
- { &ui_netGameType, "ui_netGametype", "3", CVAR_ARCHIVE },
- { &ui_actualNetGameType, "ui_actualNetGametype", "3", CVAR_ARCHIVE },
- { &ui_redteam1, "ui_redteam1", "0", CVAR_ARCHIVE },
- { &ui_redteam2, "ui_redteam2", "0", CVAR_ARCHIVE },
- { &ui_redteam3, "ui_redteam3", "0", CVAR_ARCHIVE },
- { &ui_redteam4, "ui_redteam4", "0", CVAR_ARCHIVE },
- { &ui_redteam5, "ui_redteam5", "0", CVAR_ARCHIVE },
- { &ui_blueteam1, "ui_blueteam1", "0", CVAR_ARCHIVE },
- { &ui_blueteam2, "ui_blueteam2", "0", CVAR_ARCHIVE },
- { &ui_blueteam3, "ui_blueteam3", "0", CVAR_ARCHIVE },
- { &ui_blueteam4, "ui_blueteam4", "0", CVAR_ARCHIVE },
- { &ui_blueteam5, "ui_blueteam5", "0", CVAR_ARCHIVE },
- { &ui_netSource, "ui_netSource", "0", CVAR_ARCHIVE },
- { &ui_menuFiles, "ui_menuFiles", "ui/menus.txt", CVAR_ARCHIVE },
- { &ui_currentTier, "ui_currentTier", "0", CVAR_ARCHIVE },
- { &ui_currentMap, "ui_currentMap", "0", CVAR_ARCHIVE },
- { &ui_currentNetMap, "ui_currentNetMap", "0", CVAR_ARCHIVE },
- { &ui_mapIndex, "ui_mapIndex", "0", CVAR_ARCHIVE },
- { &ui_currentOpponent, "ui_currentOpponent", "0", CVAR_ARCHIVE },
- { &ui_selectedPlayer, "cg_selectedPlayer", "0", CVAR_ARCHIVE},
- { &ui_selectedPlayerName, "cg_selectedPlayerName", "", CVAR_ARCHIVE},
- { &ui_lastServerRefresh_0, "ui_lastServerRefresh_0", "", CVAR_ARCHIVE},
- { &ui_lastServerRefresh_1, "ui_lastServerRefresh_1", "", CVAR_ARCHIVE},
- { &ui_lastServerRefresh_2, "ui_lastServerRefresh_2", "", CVAR_ARCHIVE},
- { &ui_lastServerRefresh_3, "ui_lastServerRefresh_3", "", CVAR_ARCHIVE},
- { &ui_lastServerRefresh_0, "ui_lastServerRefresh_0_time", "", CVAR_ARCHIVE},
- { &ui_lastServerRefresh_1, "ui_lastServerRefresh_1_time", "", CVAR_ARCHIVE},
- { &ui_lastServerRefresh_2, "ui_lastServerRefresh_2_time", "", CVAR_ARCHIVE},
- { &ui_lastServerRefresh_3, "ui_lastServerRefresh_3_time", "", CVAR_ARCHIVE},
- { &ui_singlePlayerActive, "ui_singlePlayerActive", "0", 0},
- { &ui_scoreAccuracy, "ui_scoreAccuracy", "0", CVAR_ARCHIVE},
- { &ui_scoreImpressives, "ui_scoreImpressives", "0", CVAR_ARCHIVE},
- { &ui_scoreExcellents, "ui_scoreExcellents", "0", CVAR_ARCHIVE},
- { &ui_scoreCaptures, "ui_scoreCaptures", "0", CVAR_ARCHIVE},
- { &ui_scoreDefends, "ui_scoreDefends", "0", CVAR_ARCHIVE},
- { &ui_scoreAssists, "ui_scoreAssists", "0", CVAR_ARCHIVE},
- { &ui_scoreGauntlets, "ui_scoreGauntlets", "0",CVAR_ARCHIVE},
- { &ui_scoreScore, "ui_scoreScore", "0", CVAR_ARCHIVE},
- { &ui_scorePerfect, "ui_scorePerfect", "0", CVAR_ARCHIVE},
- { &ui_scoreTeam, "ui_scoreTeam", "0 to 0", CVAR_ARCHIVE},
- { &ui_scoreBase, "ui_scoreBase", "0", CVAR_ARCHIVE},
- { &ui_scoreTime, "ui_scoreTime", "00:00", CVAR_ARCHIVE},
- { &ui_scoreTimeBonus, "ui_scoreTimeBonus", "0", CVAR_ARCHIVE},
- { &ui_scoreSkillBonus, "ui_scoreSkillBonus", "0", CVAR_ARCHIVE},
- { &ui_scoreShutoutBonus, "ui_scoreShutoutBonus", "0", CVAR_ARCHIVE},
- { &ui_fragLimit, "ui_fragLimit", "10", 0},
- { &ui_captureLimit, "ui_captureLimit", "5", 0},
- { &ui_smallFont, "ui_smallFont", "0.2", CVAR_ARCHIVE},
- { &ui_bigFont, "ui_bigFont", "0.5", CVAR_ARCHIVE},
- { &ui_findPlayer, "ui_findPlayer", "Sarge", CVAR_ARCHIVE},
- { &ui_Q3Model, "ui_q3model", "0", CVAR_ARCHIVE},
- { &ui_hudFiles, "cg_hudFiles", "ui/hud.txt", CVAR_ARCHIVE},
- { &ui_recordSPDemo, "ui_recordSPDemo", "0", CVAR_ARCHIVE},
- { &ui_teamArenaFirstRun, "ui_teamArenaFirstRun", "0", CVAR_ARCHIVE},
- { &ui_realWarmUp, "g_warmup", "20", CVAR_ARCHIVE},
- { &ui_realCaptureLimit, "capturelimit", "8", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_NORESTART},
- { &ui_serverStatusTimeOut, "ui_serverStatusTimeOut", "7000", CVAR_ARCHIVE},
-
- { &ui_bank, "ui_bank", "0", 0 },
-
- { &ui_chatCommands, "ui_chatCommands", "1", CVAR_ARCHIVE},
-};
-
-// bk001129 - made static to avoid aliasing
-static int cvarTableSize = sizeof(cvarTable) / sizeof(cvarTable[0]);
+ case CA_CHALLENGING:
+ s = va("Awaiting challenge...%i", cstate.connectPacketCount);
+ break;
+ case CA_CONNECTED:
+ {
+ char downloadName[MAX_INFO_VALUE];
+ int prompt = trap_Cvar_VariableValue("com_downloadPrompt");
-/*
-=================
-UI_RegisterCvars
-=================
-*/
-void UI_RegisterCvars( void ) {
- int i;
- cvarTable_t *cv;
+ if (prompt & DLP_SHOW)
+ {
+ trap_Key_SetCatcher(KEYCATCH_UI);
+ Menus_ActivateByName("download_popmenu");
+ trap_Cvar_Set("com_downloadPrompt", "0");
+ }
+
+ trap_Cvar_VariableStringBuffer("cl_downloadName", downloadName, sizeof(downloadName));
+
+ if (*downloadName)
+ {
+ UI_DisplayDownloadInfo(downloadName, centerPoint, yStart, scale);
+ return;
+ }
+ }
- for ( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ ) {
- trap_Cvar_Register( cv->vmCvar, cv->cvarName, cv->defaultString, cv->cvarFlags );
- }
+ s = "Awaiting gamestate...";
+ break;
+
+ case CA_LOADING:
+ return;
+
+ case CA_PRIMED:
+ return;
+
+ default:
+ return;
+ }
+
+ if (Q_stricmp(cstate.servername, "localhost"))
+ Text_PaintCenter(centerPoint, yStart + 80, scale, colorWhite, s, 0);
+
+ // password required / connection rejected information goes here
}
/*
=================
-UI_UpdateCvars
+UI_RegisterCvars
=================
*/
-void UI_UpdateCvars( void ) {
- int i;
- cvarTable_t *cv;
+void UI_RegisterCvars(void)
+{
+ size_t i;
+ cvarTable_t *cv;
- for ( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ ) {
- trap_Cvar_Update( cv->vmCvar );
- }
+ for (i = 0, cv = cvarTable; i < cvarTableSize; i++, cv++)
+ trap_Cvar_Register(cv->vmCvar, cv->cvarName, cv->defaultString, cv->cvarFlags);
}
-
/*
=================
-ArenaServers_StopRefresh
+UI_UpdateCvars
=================
*/
-static void UI_StopServerRefresh( void )
+void UI_UpdateCvars(void)
{
- int count;
-
- if (!uiInfo.serverStatus.refreshActive) {
- // not currently refreshing
- return;
- }
- uiInfo.serverStatus.refreshActive = qfalse;
- Com_Printf("%d servers listed in browser with %d players.\n",
- uiInfo.serverStatus.numDisplayServers,
- uiInfo.serverStatus.numPlayersOnServers);
- count = trap_LAN_GetServerCount(ui_netSource.integer);
- if (count - uiInfo.serverStatus.numDisplayServers > 0) {
- Com_Printf("%d servers not listed due to packet loss or pings higher than %d\n",
- count - uiInfo.serverStatus.numDisplayServers,
- (int) trap_Cvar_VariableValue("cl_maxPing"));
- }
+ size_t i;
+ cvarTable_t *cv;
+ for (i = 0, cv = cvarTable; i < cvarTableSize; i++, cv++)
+ trap_Cvar_Update(cv->vmCvar);
}
/*
=================
-UI_DoServerRefresh
+UI_UpdateNews
=================
*/
-static void UI_DoServerRefresh( void )
+void UI_UpdateNews(qboolean begin)
{
- qboolean wait = qfalse;
-
- if (!uiInfo.serverStatus.refreshActive) {
- return;
- }
- if (ui_netSource.integer != AS_FAVORITES) {
- if (ui_netSource.integer == AS_LOCAL) {
- if (!trap_LAN_GetServerCount(ui_netSource.integer)) {
- wait = qtrue;
- }
- } else {
- if (trap_LAN_GetServerCount(ui_netSource.integer) < 0) {
- wait = qtrue;
- }
+ char newsString[MAX_NEWS_STRING];
+ const char *c;
+ const char *wrapped;
+ int line = 0;
+ int linePos = 0;
+ qboolean finished;
+
+ if (begin && !uiInfo.newsInfo.refreshActive)
+ {
+ uiInfo.newsInfo.refreshtime = uiInfo.uiDC.realTime + 10000;
+ uiInfo.newsInfo.refreshActive = qtrue;
+ }
+ else if (!uiInfo.newsInfo.refreshActive) // do nothing
+ {
+ return;
}
- }
+ else if (uiInfo.uiDC.realTime > uiInfo.newsInfo.refreshtime)
+ {
+ strcpy(uiInfo.newsInfo.text[0], "^1Error: Timed out while contacting the server.");
+ uiInfo.newsInfo.numLines = 1;
+ return;
+ }
+
+ // start the news fetching
+ finished = trap_GetNews(begin);
- if (uiInfo.uiDC.realTime < uiInfo.serverStatus.refreshtime) {
- if (wait) {
- return;
+ // parse what comes back. Parse newlines and otherwise chop when necessary
+ trap_Cvar_VariableStringBuffer("cl_newsString", newsString, sizeof(newsString));
+
+ // FIXME remove magic width constant
+ wrapped = Item_Text_Wrap(newsString, 0.25f, 325 * uiInfo.uiDC.aspectScale);
+
+ for (c = wrapped; *c != '\0'; ++c)
+ {
+ if (linePos == (MAX_NEWS_LINEWIDTH - 1) || *c == '\n')
+ {
+ uiInfo.newsInfo.text[line][linePos] = '\0';
+
+ if (line == (MAX_NEWS_LINES - 1))
+ break;
+
+ linePos = 0;
+ line++;
+
+ if (*c != '\n')
+ {
+ uiInfo.newsInfo.text[line][linePos] = *c;
+ linePos++;
+ }
+ }
+ else if (isprint(*c))
+ {
+ uiInfo.newsInfo.text[line][linePos] = *c;
+ linePos++;
+ }
}
- }
- // if still trying to retrieve pings
- if (trap_LAN_UpdateVisiblePings(ui_netSource.integer)) {
- uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 1000;
- } else if (!wait) {
- // get the last servers in the list
- UI_BuildServerDisplayList(2);
- // stop the refresh
- UI_StopServerRefresh();
- }
- //
- UI_BuildServerDisplayList(qfalse);
+ uiInfo.newsInfo.text[line][linePos] = '\0';
+ uiInfo.newsInfo.numLines = line + 1;
+
+ if (finished)
+ uiInfo.newsInfo.refreshActive = qfalse;
}
-/*
-=================
-UI_StartServerRefresh
-=================
-*/
-static void UI_StartServerRefresh(qboolean full)
+void UI_UpdateGithubRelease()
{
- int i;
- char *ptr;
- int time;
- qtime_t q;
-
- time = trap_RealTime(&q);
- trap_Cvar_Set( va("ui_lastServerRefresh_%i_time", ui_netSource.integer ),
- va( "%i", time ) );
- trap_Cvar_Set( va("ui_lastServerRefresh_%i", ui_netSource.integer),
- va("%s-%i, %i at %i:%02i", MonthAbbrev[q.tm_mon],q.tm_mday, 1900+q.tm_year,q.tm_hour,q.tm_min));
-
- if (!full) {
- UI_UpdatePendingPings();
- return;
- }
-
- uiInfo.serverStatus.refreshActive = qtrue;
- uiInfo.serverStatus.nextDisplayRefresh = uiInfo.uiDC.realTime + 1000;
- // clear number of displayed servers
- uiInfo.serverStatus.numDisplayServers = 0;
- uiInfo.serverStatus.numPlayersOnServers = 0;
- // mark all servers as visible so we store ping updates for them
- trap_LAN_MarkServerVisible(ui_netSource.integer, -1, qtrue);
- // reset all the pings
- trap_LAN_ResetPings(ui_netSource.integer);
- //
- if( ui_netSource.integer == AS_LOCAL ) {
- trap_Cmd_ExecuteText( EXEC_NOW, "localservers\n" );
- uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 1000;
- return;
- }
+ char newsString[MAX_NEWS_STRING];
+ const char *c;
+ const char *wrapped;
+ int line = 0, linePos = 0;
+ int nexttime = uiInfo.githubRelease.nextTime;
- uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 5000;
- if( ui_netSource.integer == AS_GLOBAL || ui_netSource.integer == AS_MPLAYER ) {
- if( ui_netSource.integer == AS_GLOBAL ) {
- i = 0;
- }
- else {
- i = 1;
- }
+ if (nexttime && !(nexttime > uiInfo.uiDC.realTime))
+ return;
- ptr = UI_Cvar_VariableString("debug_protocol");
- if (strlen(ptr)) {
- trap_Cmd_ExecuteText( EXEC_NOW, va( "globalservers %d %s full empty\n", i, ptr));
- }
- else {
- trap_Cmd_ExecuteText( EXEC_NOW, va( "globalservers %d %d full empty\n", i, (int)trap_Cvar_VariableValue( "protocol" ) ) );
+ // Limit checks to 1x every 10seconds
+ uiInfo.githubRelease.nextTime = uiInfo.uiDC.realTime + 10000;
+ trap_Cmd_ExecuteText(EXEC_INSERT, "checkForUpdate");
+
+ // parse what comes back. Parse newlines and otherwise chop when necessary
+ trap_Cvar_VariableStringBuffer("cl_latestRelease", newsString, sizeof(newsString));
+
+ // FIXME remove magic width constant
+ wrapped = Item_Text_Wrap(newsString, 0.33f, 450 * uiInfo.uiDC.aspectScale);
+
+ for (c = wrapped; *c != '\0'; ++c)
+ {
+ if (linePos == (MAX_NEWS_LINEWIDTH - 1) || *c == '\n')
+ {
+ uiInfo.githubRelease.text[line][linePos] = '\0';
+
+ if (line == (MAX_NEWS_LINES - 1))
+ break;
+
+ linePos = 0;
+ line++;
+
+ if (*c != '\n')
+ {
+ uiInfo.githubRelease.text[line][linePos] = *c;
+ linePos++;
+ }
+ }
+ else if (isprint(*c))
+ {
+ uiInfo.githubRelease.text[line][linePos] = *c;
+ linePos++;
+ }
}
- }
+
+ uiInfo.githubRelease.text[line][linePos] = '\0';
+ uiInfo.githubRelease.numLines = line + 1;
}
+#ifdef MODULE_INTERFACE_11
+void trap_R_SetClipRegion(const float *region) {}
+
+qboolean trap_GetNews(qboolean force) { return qtrue; }
+#endif
diff --git a/src/ui/ui_players.c b/src/ui/ui_players.c
deleted file mode 100644
index 55fce51..0000000
--- a/src/ui/ui_players.c
+++ /dev/null
@@ -1,1369 +0,0 @@
-/*
-===========================================================================
-Copyright (C) 1999-2005 Id Software, Inc.
-Copyright (C) 2000-2006 Tim Angus
-
-This file is part of Tremulous.
-
-Tremulous 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.
-
-Tremulous 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 Tremulous; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-===========================================================================
-*/
-
-// ui_players.c
-
-#include "ui_local.h"
-
-
-#define UI_TIMER_GESTURE 2300
-#define UI_TIMER_JUMP 1000
-#define UI_TIMER_LAND 130
-#define UI_TIMER_WEAPON_SWITCH 300
-#define UI_TIMER_ATTACK 500
-#define UI_TIMER_MUZZLE_FLASH 20
-#define UI_TIMER_WEAPON_DELAY 250
-
-#define JUMP_HEIGHT 56
-
-#define SWINGSPEED 0.3f
-
-#define SPIN_SPEED 0.9f
-#define COAST_TIME 1000
-
-
-static int dp_realtime;
-static float jumpHeight;
-sfxHandle_t weaponChangeSound;
-
-
-/*
-===============
-UI_PlayerInfo_SetWeapon
-===============
-*/
-static void UI_PlayerInfo_SetWeapon( playerInfo_t *pi, weapon_t weaponNum )
-{
- //TA: FIXME: this is probably useless for trem
-/* gitem_t * item;
- char path[MAX_QPATH];
-
- pi->currentWeapon = weaponNum;
-tryagain:
- pi->realWeapon = weaponNum;
- pi->weaponModel = 0;
- pi->barrelModel = 0;
- pi->flashModel = 0;
-
- if ( weaponNum == WP_NONE ) {
- return;
- }
-
- if ( item->classname ) {
- pi->weaponModel = trap_R_RegisterModel( item->world_model[0] );
- }
-
- if( pi->weaponModel == 0 ) {
- if( weaponNum == WP_MACHINEGUN ) {
- weaponNum = WP_NONE;
- goto tryagain;
- }
- weaponNum = WP_MACHINEGUN;
- goto tryagain;
- }
-
- if ( weaponNum == WP_MACHINEGUN ) {
- strcpy( path, item->world_model[0] );
- COM_StripExtension( path, path );
- strcat( path, "_barrel.md3" );
- pi->barrelModel = trap_R_RegisterModel( path );
- }
-
- strcpy( path, item->world_model[0] );
- COM_StripExtension( path, path );
- strcat( path, "_flash.md3" );
- pi->flashModel = trap_R_RegisterModel( path );
-
- switch( weaponNum ) {
- case WP_GAUNTLET:
- MAKERGB( pi->flashDlightColor, 0.6f, 0.6f, 1 );
- break;
-
- case WP_MACHINEGUN:
- MAKERGB( pi->flashDlightColor, 1, 1, 0 );
- break;
-
- case WP_SHOTGUN:
- MAKERGB( pi->flashDlightColor, 1, 1, 0 );
- break;
-
- case WP_GRENADE_LAUNCHER:
- MAKERGB( pi->flashDlightColor, 1, 0.7f, 0.5f );
- break;
-
- case WP_ROCKET_LAUNCHER:
- MAKERGB( pi->flashDlightColor, 1, 0.75f, 0 );
- break;
-
- case WP_TESLAGEN:
- MAKERGB( pi->flashDlightColor, 0.6f, 0.6f, 1 );
- break;
-
- case WP_RAILGUN:
- MAKERGB( pi->flashDlightColor, 1, 0.5f, 0 );
- break;
-
- case WP_BFG:
- MAKERGB( pi->flashDlightColor, 1, 0.7f, 1 );
- break;
-
- case WP_GRAPPLING_HOOK:
- MAKERGB( pi->flashDlightColor, 0.6f, 0.6f, 1 );
- break;
-
- default:
- MAKERGB( pi->flashDlightColor, 1, 1, 1 );
- break;
- }*/
-}
-
-
-/*
-===============
-UI_ForceLegsAnim
-===============
-*/
-static void UI_ForceLegsAnim( playerInfo_t *pi, int anim ) {
- pi->legsAnim = ( ( pi->legsAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim;
-
- if ( anim == LEGS_JUMP ) {
- pi->legsAnimationTimer = UI_TIMER_JUMP;
- }
-}
-
-
-/*
-===============
-UI_SetLegsAnim
-===============
-*/
-static void UI_SetLegsAnim( playerInfo_t *pi, int anim ) {
- if ( pi->pendingLegsAnim ) {
- anim = pi->pendingLegsAnim;
- pi->pendingLegsAnim = 0;
- }
- UI_ForceLegsAnim( pi, anim );
-}
-
-
-/*
-===============
-UI_ForceTorsoAnim
-===============
-*/
-static void UI_ForceTorsoAnim( playerInfo_t *pi, int anim ) {
- pi->torsoAnim = ( ( pi->torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | anim;
-
- if ( anim == TORSO_GESTURE ) {
- pi->torsoAnimationTimer = UI_TIMER_GESTURE;
- }
-
- if ( anim == TORSO_ATTACK || anim == TORSO_ATTACK2 ) {
- pi->torsoAnimationTimer = UI_TIMER_ATTACK;
- }
-}
-
-
-/*
-===============
-UI_SetTorsoAnim
-===============
-*/
-static void UI_SetTorsoAnim( playerInfo_t *pi, int anim ) {
- if ( pi->pendingTorsoAnim ) {
- anim = pi->pendingTorsoAnim;
- pi->pendingTorsoAnim = 0;
- }
-
- UI_ForceTorsoAnim( pi, anim );
-}
-
-
-/*
-===============
-UI_TorsoSequencing
-===============
-*/
-static void UI_TorsoSequencing( playerInfo_t *pi ) {
- int currentAnim;
-
- currentAnim = pi->torsoAnim & ~ANIM_TOGGLEBIT;
-
- if ( pi->weapon != pi->currentWeapon ) {
- if ( currentAnim != TORSO_DROP ) {
- pi->torsoAnimationTimer = UI_TIMER_WEAPON_SWITCH;
- UI_ForceTorsoAnim( pi, TORSO_DROP );
- }
- }
-
- if ( pi->torsoAnimationTimer > 0 ) {
- return;
- }
-
- if( currentAnim == TORSO_GESTURE ) {
- UI_SetTorsoAnim( pi, TORSO_STAND );
- return;
- }
-
- if( currentAnim == TORSO_ATTACK || currentAnim == TORSO_ATTACK2 ) {
- UI_SetTorsoAnim( pi, TORSO_STAND );
- return;
- }
-
- if ( currentAnim == TORSO_DROP ) {
- UI_PlayerInfo_SetWeapon( pi, pi->weapon );
- pi->torsoAnimationTimer = UI_TIMER_WEAPON_SWITCH;
- UI_ForceTorsoAnim( pi, TORSO_RAISE );
- return;
- }
-
- if ( currentAnim == TORSO_RAISE ) {
- UI_SetTorsoAnim( pi, TORSO_STAND );
- return;
- }
-}
-
-
-/*
-===============
-UI_LegsSequencing
-===============
-*/
-static void UI_LegsSequencing( playerInfo_t *pi ) {
- int currentAnim;
-
- currentAnim = pi->legsAnim & ~ANIM_TOGGLEBIT;
-
- if ( pi->legsAnimationTimer > 0 ) {
- if ( currentAnim == LEGS_JUMP ) {
- jumpHeight = JUMP_HEIGHT * sin( M_PI * ( UI_TIMER_JUMP - pi->legsAnimationTimer ) / UI_TIMER_JUMP );
- }
- return;
- }
-
- if ( currentAnim == LEGS_JUMP ) {
- UI_ForceLegsAnim( pi, LEGS_LAND );
- pi->legsAnimationTimer = UI_TIMER_LAND;
- jumpHeight = 0;
- return;
- }
-
- if ( currentAnim == LEGS_LAND ) {
- UI_SetLegsAnim( pi, LEGS_IDLE );
- return;
- }
-}
-
-
-/*
-======================
-UI_PositionEntityOnTag
-======================
-*/
-static void UI_PositionEntityOnTag( refEntity_t *entity, const refEntity_t *parent,
- clipHandle_t parentModel, char *tagName ) {
- int i;
- orientation_t lerped;
-
- // lerp the tag
- trap_CM_LerpTag( &lerped, parentModel, parent->oldframe, parent->frame,
- 1.0 - parent->backlerp, tagName );
-
- // FIXME: allow origin offsets along tag?
- VectorCopy( parent->origin, entity->origin );
- for ( i = 0 ; i < 3 ; i++ ) {
- VectorMA( entity->origin, lerped.origin[i], parent->axis[i], entity->origin );
- }
-
- // cast away const because of compiler problems
- MatrixMultiply( lerped.axis, ((refEntity_t*)parent)->axis, entity->axis );
- entity->backlerp = parent->backlerp;
-}
-
-
-/*
-======================
-UI_PositionRotatedEntityOnTag
-======================
-*/
-static void UI_PositionRotatedEntityOnTag( refEntity_t *entity, const refEntity_t *parent,
- clipHandle_t parentModel, char *tagName ) {
- int i;
- orientation_t lerped;
- vec3_t tempAxis[3];
-
- // lerp the tag
- trap_CM_LerpTag( &lerped, parentModel, parent->oldframe, parent->frame,
- 1.0 - parent->backlerp, tagName );
-
- // FIXME: allow origin offsets along tag?
- VectorCopy( parent->origin, entity->origin );
- for ( i = 0 ; i < 3 ; i++ ) {
- VectorMA( entity->origin, lerped.origin[i], parent->axis[i], entity->origin );
- }
-
- // cast away const because of compiler problems
- MatrixMultiply( entity->axis, ((refEntity_t *)parent)->axis, tempAxis );
- MatrixMultiply( lerped.axis, tempAxis, entity->axis );
-}
-
-
-/*
-===============
-UI_SetLerpFrameAnimation
-===============
-*/
-static void UI_SetLerpFrameAnimation( playerInfo_t *ci, lerpFrame_t *lf, int newAnimation ) {
- animation_t *anim;
-
- lf->animationNumber = newAnimation;
- newAnimation &= ~ANIM_TOGGLEBIT;
-
- if ( newAnimation < 0 || newAnimation >= MAX_PLAYER_ANIMATIONS ) {
- trap_Error( va("Bad animation number: %i", newAnimation) );
- }
-
- anim = &ci->animations[ newAnimation ];
-
- lf->animation = anim;
- lf->animationTime = lf->frameTime + anim->initialLerp;
-}
-
-
-/*
-===============
-UI_RunLerpFrame
-===============
-*/
-static void UI_RunLerpFrame( playerInfo_t *ci, lerpFrame_t *lf, int newAnimation ) {
- int f;
- animation_t *anim;
-
- // see if the animation sequence is switching
- if ( newAnimation != lf->animationNumber || !lf->animation ) {
- UI_SetLerpFrameAnimation( ci, lf, newAnimation );
- }
-
- // if we have passed the current frame, move it to
- // oldFrame and calculate a new frame
- if ( dp_realtime >= lf->frameTime ) {
- lf->oldFrame = lf->frame;
- lf->oldFrameTime = lf->frameTime;
-
- // get the next frame based on the animation
- anim = lf->animation;
- if ( dp_realtime < lf->animationTime ) {
- lf->frameTime = lf->animationTime; // initial lerp
- } else {
- lf->frameTime = lf->oldFrameTime + anim->frameLerp;
- }
- f = ( lf->frameTime - lf->animationTime ) / anim->frameLerp;
- if ( f >= anim->numFrames ) {
- f -= anim->numFrames;
- if ( anim->loopFrames ) {
- f %= anim->loopFrames;
- f += anim->numFrames - anim->loopFrames;
- } else {
- f = anim->numFrames - 1;
- // the animation is stuck at the end, so it
- // can immediately transition to another sequence
- lf->frameTime = dp_realtime;
- }
- }
- lf->frame = anim->firstFrame + f;
- if ( dp_realtime > lf->frameTime ) {
- lf->frameTime = dp_realtime;
- }
- }
-
- if ( lf->frameTime > dp_realtime + 200 ) {
- lf->frameTime = dp_realtime;
- }
-
- if ( lf->oldFrameTime > dp_realtime ) {
- lf->oldFrameTime = dp_realtime;
- }
- // calculate current lerp value
- if ( lf->frameTime == lf->oldFrameTime ) {
- lf->backlerp = 0;
- } else {
- lf->backlerp = 1.0 - (float)( dp_realtime - lf->oldFrameTime ) / ( lf->frameTime - lf->oldFrameTime );
- }
-}
-
-
-/*
-===============
-UI_PlayerAnimation
-===============
-*/
-static void UI_PlayerAnimation( playerInfo_t *pi, int *legsOld, int *legs, float *legsBackLerp,
- int *torsoOld, int *torso, float *torsoBackLerp ) {
-
- // legs animation
- pi->legsAnimationTimer -= uiInfo.uiDC.frameTime;
- if ( pi->legsAnimationTimer < 0 ) {
- pi->legsAnimationTimer = 0;
- }
-
- UI_LegsSequencing( pi );
-
- if ( pi->legs.yawing && ( pi->legsAnim & ~ANIM_TOGGLEBIT ) == LEGS_IDLE ) {
- UI_RunLerpFrame( pi, &pi->legs, LEGS_TURN );
- } else {
- UI_RunLerpFrame( pi, &pi->legs, pi->legsAnim );
- }
- *legsOld = pi->legs.oldFrame;
- *legs = pi->legs.frame;
- *legsBackLerp = pi->legs.backlerp;
-
- // torso animation
- pi->torsoAnimationTimer -= uiInfo.uiDC.frameTime;
- if ( pi->torsoAnimationTimer < 0 ) {
- pi->torsoAnimationTimer = 0;
- }
-
- UI_TorsoSequencing( pi );
-
- UI_RunLerpFrame( pi, &pi->torso, pi->torsoAnim );
- *torsoOld = pi->torso.oldFrame;
- *torso = pi->torso.frame;
- *torsoBackLerp = pi->torso.backlerp;
-}
-
-
-/*
-==================
-UI_SwingAngles
-==================
-*/
-static void UI_SwingAngles( float destination, float swingTolerance, float clampTolerance,
- float speed, float *angle, qboolean *swinging ) {
- float swing;
- float move;
- float scale;
-
- if ( !*swinging ) {
- // see if a swing should be started
- swing = AngleSubtract( *angle, destination );
- if ( swing > swingTolerance || swing < -swingTolerance ) {
- *swinging = qtrue;
- }
- }
-
- if ( !*swinging ) {
- return;
- }
-
- // modify the speed depending on the delta
- // so it doesn't seem so linear
- swing = AngleSubtract( destination, *angle );
- scale = fabs( swing );
- if ( scale < swingTolerance * 0.5 ) {
- scale = 0.5;
- } else if ( scale < swingTolerance ) {
- scale = 1.0;
- } else {
- scale = 2.0;
- }
-
- // swing towards the destination angle
- if ( swing >= 0 ) {
- move = uiInfo.uiDC.frameTime * scale * speed;
- if ( move >= swing ) {
- move = swing;
- *swinging = qfalse;
- }
- *angle = AngleMod( *angle + move );
- } else if ( swing < 0 ) {
- move = uiInfo.uiDC.frameTime * scale * -speed;
- if ( move <= swing ) {
- move = swing;
- *swinging = qfalse;
- }
- *angle = AngleMod( *angle + move );
- }
-
- // clamp to no more than tolerance
- swing = AngleSubtract( destination, *angle );
- if ( swing > clampTolerance ) {
- *angle = AngleMod( destination - (clampTolerance - 1) );
- } else if ( swing < -clampTolerance ) {
- *angle = AngleMod( destination + (clampTolerance - 1) );
- }
-}
-
-
-/*
-======================
-UI_MovedirAdjustment
-======================
-*/
-static float UI_MovedirAdjustment( playerInfo_t *pi ) {
- vec3_t relativeAngles;
- vec3_t moveVector;
-
- VectorSubtract( pi->viewAngles, pi->moveAngles, relativeAngles );
- AngleVectors( relativeAngles, moveVector, NULL, NULL );
- if ( Q_fabs( moveVector[0] ) < 0.01 ) {
- moveVector[0] = 0.0;
- }
- if ( Q_fabs( moveVector[1] ) < 0.01 ) {
- moveVector[1] = 0.0;
- }
-
- if ( moveVector[1] == 0 && moveVector[0] > 0 ) {
- return 0;
- }
- if ( moveVector[1] < 0 && moveVector[0] > 0 ) {
- return 22;
- }
- if ( moveVector[1] < 0 && moveVector[0] == 0 ) {
- return 45;
- }
- if ( moveVector[1] < 0 && moveVector[0] < 0 ) {
- return -22;
- }
- if ( moveVector[1] == 0 && moveVector[0] < 0 ) {
- return 0;
- }
- if ( moveVector[1] > 0 && moveVector[0] < 0 ) {
- return 22;
- }
- if ( moveVector[1] > 0 && moveVector[0] == 0 ) {
- return -45;
- }
-
- return -22;
-}
-
-
-/*
-===============
-UI_PlayerAngles
-===============
-*/
-static void UI_PlayerAngles( playerInfo_t *pi, vec3_t legs[3], vec3_t torso[3], vec3_t head[3] ) {
- vec3_t legsAngles, torsoAngles, headAngles;
- float dest;
- float adjust;
-
- VectorCopy( pi->viewAngles, headAngles );
- headAngles[YAW] = AngleMod( headAngles[YAW] );
- VectorClear( legsAngles );
- VectorClear( torsoAngles );
-
- // --------- yaw -------------
-
- // allow yaw to drift a bit
- if ( ( pi->legsAnim & ~ANIM_TOGGLEBIT ) != LEGS_IDLE
- || ( pi->torsoAnim & ~ANIM_TOGGLEBIT ) != TORSO_STAND ) {
- // if not standing still, always point all in the same direction
- pi->torso.yawing = qtrue; // always center
- pi->torso.pitching = qtrue; // always center
- pi->legs.yawing = qtrue; // always center
- }
-
- // adjust legs for movement dir
- adjust = UI_MovedirAdjustment( pi );
- legsAngles[YAW] = headAngles[YAW] + adjust;
- torsoAngles[YAW] = headAngles[YAW] + 0.25 * adjust;
-
-
- // torso
- UI_SwingAngles( torsoAngles[YAW], 25, 90, SWINGSPEED, &pi->torso.yawAngle, &pi->torso.yawing );
- UI_SwingAngles( legsAngles[YAW], 40, 90, SWINGSPEED, &pi->legs.yawAngle, &pi->legs.yawing );
-
- torsoAngles[YAW] = pi->torso.yawAngle;
- legsAngles[YAW] = pi->legs.yawAngle;
-
- // --------- pitch -------------
-
- // only show a fraction of the pitch angle in the torso
- if ( headAngles[PITCH] > 180 ) {
- dest = (-360 + headAngles[PITCH]) * 0.75;
- } else {
- dest = headAngles[PITCH] * 0.75;
- }
- UI_SwingAngles( dest, 15, 30, 0.1f, &pi->torso.pitchAngle, &pi->torso.pitching );
- torsoAngles[PITCH] = pi->torso.pitchAngle;
-
- // pull the angles back out of the hierarchial chain
- AnglesSubtract( headAngles, torsoAngles, headAngles );
- AnglesSubtract( torsoAngles, legsAngles, torsoAngles );
- AnglesToAxis( legsAngles, legs );
- AnglesToAxis( torsoAngles, torso );
- AnglesToAxis( headAngles, head );
-}
-
-
-/*
-===============
-UI_PlayerFloatSprite
-===============
-*/
-static void UI_PlayerFloatSprite( playerInfo_t *pi, vec3_t origin, qhandle_t shader ) {
- refEntity_t ent;
-
- memset( &ent, 0, sizeof( ent ) );
- VectorCopy( origin, ent.origin );
- ent.origin[2] += 48;
- ent.reType = RT_SPRITE;
- ent.customShader = shader;
- ent.radius = 10;
- ent.renderfx = 0;
- trap_R_AddRefEntityToScene( &ent );
-}
-
-
-/*
-======================
-UI_MachinegunSpinAngle
-======================
-*/
-float UI_MachinegunSpinAngle( playerInfo_t *pi ) {
- int delta;
- float angle;
- float speed;
- int torsoAnim;
-
- delta = dp_realtime - pi->barrelTime;
- if ( pi->barrelSpinning ) {
- angle = pi->barrelAngle + delta * SPIN_SPEED;
- } else {
- if ( delta > COAST_TIME ) {
- delta = COAST_TIME;
- }
-
- speed = 0.5 * ( SPIN_SPEED + (float)( COAST_TIME - delta ) / COAST_TIME );
- angle = pi->barrelAngle + delta * speed;
- }
-
- torsoAnim = pi->torsoAnim & ~ANIM_TOGGLEBIT;
- if( torsoAnim == TORSO_ATTACK2 ) {
- torsoAnim = TORSO_ATTACK;
- }
- if ( pi->barrelSpinning == !(torsoAnim == TORSO_ATTACK) ) {
- pi->barrelTime = dp_realtime;
- pi->barrelAngle = AngleMod( angle );
- pi->barrelSpinning = !!(torsoAnim == TORSO_ATTACK);
- }
-
- return angle;
-}
-
-
-/*
-===============
-UI_DrawPlayer
-===============
-*/
-void UI_DrawPlayer( float x, float y, float w, float h, playerInfo_t *pi, int time ) {
- refdef_t refdef;
- refEntity_t legs;
- refEntity_t torso;
- refEntity_t head;
- refEntity_t gun;
- refEntity_t barrel;
- refEntity_t flash;
- vec3_t origin;
- int renderfx;
- vec3_t mins = {-16, -16, -24};
- vec3_t maxs = {16, 16, 32};
- float len;
- float xx;
-
- if ( !pi->legsModel || !pi->torsoModel || !pi->headModel || !pi->animations[0].numFrames ) {
- return;
- }
-
- // this allows the ui to cache the player model on the main menu
- if (w == 0 || h == 0) {
- return;
- }
-
- dp_realtime = time;
-
- if ( pi->pendingWeapon != WP_NUM_WEAPONS && dp_realtime > pi->weaponTimer ) {
- pi->weapon = pi->pendingWeapon;
- pi->lastWeapon = pi->pendingWeapon;
- pi->pendingWeapon = WP_NUM_WEAPONS;
- pi->weaponTimer = 0;
- if( pi->currentWeapon != pi->weapon ) {
- trap_S_StartLocalSound( weaponChangeSound, CHAN_LOCAL );
- }
- }
-
- UI_AdjustFrom640( &x, &y, &w, &h );
-
- y -= jumpHeight;
-
- memset( &refdef, 0, sizeof( refdef ) );
- memset( &legs, 0, sizeof(legs) );
- memset( &torso, 0, sizeof(torso) );
- memset( &head, 0, sizeof(head) );
-
- refdef.rdflags = RDF_NOWORLDMODEL;
-
- AxisClear( refdef.viewaxis );
-
- refdef.x = x;
- refdef.y = y;
- refdef.width = w;
- refdef.height = h;
-
- refdef.fov_x = (int)((float)refdef.width / 640.0f * 90.0f);
- xx = refdef.width / tan( refdef.fov_x / 360 * M_PI );
- refdef.fov_y = atan2( refdef.height, xx );
- refdef.fov_y *= ( 360 / (float)M_PI );
-
- // calculate distance so the player nearly fills the box
- len = 0.7 * ( maxs[2] - mins[2] );
- origin[0] = len / tan( DEG2RAD(refdef.fov_x) * 0.5 );
- origin[1] = 0.5 * ( mins[1] + maxs[1] );
- origin[2] = -0.5 * ( mins[2] + maxs[2] );
-
- refdef.time = dp_realtime;
-
- trap_R_ClearScene();
-
- // get the rotation information
- UI_PlayerAngles( pi, legs.axis, torso.axis, head.axis );
-
- // get the animation state (after rotation, to allow feet shuffle)
- UI_PlayerAnimation( pi, &legs.oldframe, &legs.frame, &legs.backlerp,
- &torso.oldframe, &torso.frame, &torso.backlerp );
-
- renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW;
-
- //
- // add the legs
- //
- legs.hModel = pi->legsModel;
- legs.customSkin = pi->legsSkin;
-
- VectorCopy( origin, legs.origin );
-
- VectorCopy( origin, legs.lightingOrigin );
- legs.renderfx = renderfx;
- VectorCopy (legs.origin, legs.oldorigin);
-
- trap_R_AddRefEntityToScene( &legs );
-
- if (!legs.hModel) {
- return;
- }
-
- //
- // add the torso
- //
- torso.hModel = pi->torsoModel;
- if (!torso.hModel) {
- return;
- }
-
- torso.customSkin = pi->torsoSkin;
-
- VectorCopy( origin, torso.lightingOrigin );
-
- UI_PositionRotatedEntityOnTag( &torso, &legs, pi->legsModel, "tag_torso");
-
- torso.renderfx = renderfx;
-
- trap_R_AddRefEntityToScene( &torso );
-
- //
- // add the head
- //
- head.hModel = pi->headModel;
- if (!head.hModel) {
- return;
- }
- head.customSkin = pi->headSkin;
-
- VectorCopy( origin, head.lightingOrigin );
-
- UI_PositionRotatedEntityOnTag( &head, &torso, pi->torsoModel, "tag_head");
-
- head.renderfx = renderfx;
-
- trap_R_AddRefEntityToScene( &head );
-
- //
- // add the gun
- //
- if ( pi->currentWeapon != WP_NONE ) {
- memset( &gun, 0, sizeof(gun) );
- gun.hModel = pi->weaponModel;
- VectorCopy( origin, gun.lightingOrigin );
- UI_PositionEntityOnTag( &gun, &torso, pi->torsoModel, "tag_weapon");
- gun.renderfx = renderfx;
- trap_R_AddRefEntityToScene( &gun );
- }
-
- //
- // add the spinning barrel
- //
- if ( pi->realWeapon == WP_MACHINEGUN ) {
- vec3_t angles;
-
- memset( &barrel, 0, sizeof(barrel) );
- VectorCopy( origin, barrel.lightingOrigin );
- barrel.renderfx = renderfx;
-
- barrel.hModel = pi->barrelModel;
- angles[YAW] = 0;
- angles[PITCH] = 0;
- angles[ROLL] = UI_MachinegunSpinAngle( pi );
-/* if( pi->realWeapon == WP_GAUNTLET || pi->realWeapon == WP_BFG ) {
- angles[PITCH] = angles[ROLL];
- angles[ROLL] = 0;
- }*/
- AnglesToAxis( angles, barrel.axis );
-
- UI_PositionRotatedEntityOnTag( &barrel, &gun, pi->weaponModel, "tag_barrel");
-
- trap_R_AddRefEntityToScene( &barrel );
- }
-
- //
- // add muzzle flash
- //
- if ( dp_realtime <= pi->muzzleFlashTime ) {
- if ( pi->flashModel ) {
- memset( &flash, 0, sizeof(flash) );
- flash.hModel = pi->flashModel;
- VectorCopy( origin, flash.lightingOrigin );
- UI_PositionEntityOnTag( &flash, &gun, pi->weaponModel, "tag_flash");
- flash.renderfx = renderfx;
- trap_R_AddRefEntityToScene( &flash );
- }
-
- // make a dlight for the flash
- if ( pi->flashDlightColor[0] || pi->flashDlightColor[1] || pi->flashDlightColor[2] ) {
- trap_R_AddLightToScene( flash.origin, 200 + (rand()&31), pi->flashDlightColor[0],
- pi->flashDlightColor[1], pi->flashDlightColor[2] );
- }
- }
-
- //
- // add the chat icon
- //
- if ( pi->chat ) {
- UI_PlayerFloatSprite( pi, origin, trap_R_RegisterShaderNoMip( "sprites/balloon3" ) );
- }
-
- //
- // add an accent light
- //
- origin[0] -= 100; // + = behind, - = in front
- origin[1] += 100; // + = left, - = right
- origin[2] += 100; // + = above, - = below
- trap_R_AddLightToScene( origin, 500, 1.0, 1.0, 1.0 );
-
- origin[0] -= 100;
- origin[1] -= 100;
- origin[2] -= 100;
- trap_R_AddLightToScene( origin, 500, 1.0, 0.0, 0.0 );
-
- trap_R_RenderScene( &refdef );
-}
-
-/*
-==========================
-UI_FileExists
-==========================
-*/
-static qboolean UI_FileExists(const char *filename) {
- int len;
-
- len = trap_FS_FOpenFile( filename, NULL, FS_READ );
- if (len>0) {
- return qtrue;
- }
- return qfalse;
-}
-
-/*
-==========================
-UI_FindClientHeadFile
-==========================
-*/
-static qboolean UI_FindClientHeadFile( char *filename, int length, const char *teamName, const char *headModelName, const char *headSkinName, const char *base, const char *ext ) {
- char *team, *headsFolder;
- int i;
-
- team = "default";
-
- if ( headModelName[0] == '*' ) {
- headsFolder = "heads/";
- headModelName++;
- }
- else {
- headsFolder = "";
- }
- while(1) {
- for ( i = 0; i < 2; i++ ) {
- if ( i == 0 && teamName && *teamName ) {
- Com_sprintf( filename, length, "models/players/%s%s/%s/%s%s_%s.%s", headsFolder, headModelName, headSkinName, teamName, base, team, ext );
- }
- else {
- Com_sprintf( filename, length, "models/players/%s%s/%s/%s_%s.%s", headsFolder, headModelName, headSkinName, base, team, ext );
- }
- if ( UI_FileExists( filename ) ) {
- return qtrue;
- }
- if ( i == 0 && teamName && *teamName ) {
- Com_sprintf( filename, length, "models/players/%s%s/%s%s_%s.%s", headsFolder, headModelName, teamName, base, headSkinName, ext );
- }
- else {
- Com_sprintf( filename, length, "models/players/%s%s/%s_%s.%s", headsFolder, headModelName, base, headSkinName, ext );
- }
- if ( UI_FileExists( filename ) ) {
- return qtrue;
- }
- if ( !teamName || !*teamName ) {
- break;
- }
- }
- // if tried the heads folder first
- if ( headsFolder[0] ) {
- break;
- }
- headsFolder = "heads/";
- }
-
- return qfalse;
-}
-
-/*
-==========================
-UI_RegisterClientSkin
-==========================
-*/
-static qboolean UI_RegisterClientSkin( playerInfo_t *pi, const char *modelName, const char *skinName, const char *headModelName, const char *headSkinName , const char *teamName) {
- char filename[MAX_QPATH*2];
-
- if (teamName && *teamName) {
- Com_sprintf( filename, sizeof( filename ), "models/players/%s/%s/lower_%s.skin", modelName, teamName, skinName );
- } else {
- Com_sprintf( filename, sizeof( filename ), "models/players/%s/lower_%s.skin", modelName, skinName );
- }
- pi->legsSkin = trap_R_RegisterSkin( filename );
- if (!pi->legsSkin) {
- if (teamName && *teamName) {
- Com_sprintf( filename, sizeof( filename ), "models/players/characters/%s/%s/lower_%s.skin", modelName, teamName, skinName );
- } else {
- Com_sprintf( filename, sizeof( filename ), "models/players/characters/%s/lower_%s.skin", modelName, skinName );
- }
- pi->legsSkin = trap_R_RegisterSkin( filename );
- }
-
- if (teamName && *teamName) {
- Com_sprintf( filename, sizeof( filename ), "models/players/%s/%s/upper_%s.skin", modelName, teamName, skinName );
- } else {
- Com_sprintf( filename, sizeof( filename ), "models/players/%s/upper_%s.skin", modelName, skinName );
- }
- pi->torsoSkin = trap_R_RegisterSkin( filename );
- if (!pi->torsoSkin) {
- if (teamName && *teamName) {
- Com_sprintf( filename, sizeof( filename ), "models/players/characters/%s/%s/upper_%s.skin", modelName, teamName, skinName );
- } else {
- Com_sprintf( filename, sizeof( filename ), "models/players/characters/%s/upper_%s.skin", modelName, skinName );
- }
- pi->torsoSkin = trap_R_RegisterSkin( filename );
- }
-
- if ( UI_FindClientHeadFile( filename, sizeof(filename), teamName, headModelName, headSkinName, "head", "skin" ) ) {
- pi->headSkin = trap_R_RegisterSkin( filename );
- }
-
- if ( !pi->legsSkin || !pi->torsoSkin || !pi->headSkin ) {
- return qfalse;
- }
-
- return qtrue;
-}
-
-
-/*
-======================
-UI_ParseAnimationFile
-======================
-*/
-static qboolean UI_ParseAnimationFile( const char *filename, animation_t *animations ) {
- char *text_p, *prev;
- int len;
- int i;
- char *token;
- float fps;
- int skip;
- char text[20000];
- fileHandle_t f;
-
- memset( animations, 0, sizeof( animation_t ) * MAX_PLAYER_ANIMATIONS );
-
- // load the file
- len = trap_FS_FOpenFile( filename, &f, FS_READ );
- if ( len <= 0 ) {
- return qfalse;
- }
- if ( len >= ( sizeof( text ) - 1 ) ) {
- Com_Printf( "File %s too long\n", filename );
- trap_FS_FCloseFile( f );
- return qfalse;
- }
- trap_FS_Read( text, len, f );
- text[len] = 0;
- trap_FS_FCloseFile( f );
-
- COM_Compress(text);
-
- // parse the text
- text_p = text;
- skip = 0; // quite the compiler warning
-
- // read optional parameters
- while ( 1 ) {
- prev = text_p; // so we can unget
- token = COM_Parse( &text_p );
- if ( !token ) {
- break;
- }
- if ( !Q_stricmp( token, "footsteps" ) ) {
- token = COM_Parse( &text_p );
- if ( !token ) {
- break;
- }
- continue;
- } else if ( !Q_stricmp( token, "headoffset" ) ) {
- for ( i = 0 ; i < 3 ; i++ ) {
- token = COM_Parse( &text_p );
- if ( !token ) {
- break;
- }
- }
- continue;
- } else if ( !Q_stricmp( token, "sex" ) ) {
- token = COM_Parse( &text_p );
- if ( !token ) {
- break;
- }
- continue;
- }
-
- // if it is a number, start parsing animations
- if ( token[0] >= '0' && token[0] <= '9' ) {
- text_p = prev; // unget the token
- break;
- }
-
- Com_Printf( "unknown token '%s' is %s\n", token, filename );
- }
-
- // read information for each frame
- for ( i = 0 ; i < MAX_PLAYER_ANIMATIONS ; i++ ) {
-
- token = COM_Parse( &text_p );
- if ( !token ) {
- break;
- }
- animations[i].firstFrame = atoi( token );
- // leg only frames are adjusted to not count the upper body only frames
- if ( i == LEGS_WALKCR ) {
- skip = animations[LEGS_WALKCR].firstFrame - animations[TORSO_GESTURE].firstFrame;
- }
- if ( i >= LEGS_WALKCR ) {
- animations[i].firstFrame -= skip;
- }
-
- token = COM_Parse( &text_p );
- if ( !token ) {
- break;
- }
- animations[i].numFrames = atoi( token );
-
- token = COM_Parse( &text_p );
- if ( !token ) {
- break;
- }
- animations[i].loopFrames = atoi( token );
-
- token = COM_Parse( &text_p );
- if ( !token ) {
- break;
- }
- fps = atof( token );
- if ( fps == 0 ) {
- fps = 1;
- }
- animations[i].frameLerp = 1000 / fps;
- animations[i].initialLerp = 1000 / fps;
- }
-
- if ( i != MAX_PLAYER_ANIMATIONS ) {
- Com_Printf( "Error parsing animation file: %s", filename );
- return qfalse;
- }
-
- return qtrue;
-}
-
-/*
-==========================
-UI_RegisterClientModelname
-==========================
-*/
-qboolean UI_RegisterClientModelname( playerInfo_t *pi, const char *modelSkinName, const char *headModelSkinName, const char *teamName ) {
- char modelName[MAX_QPATH];
- char skinName[MAX_QPATH];
- char headModelName[MAX_QPATH];
- char headSkinName[MAX_QPATH];
- char filename[MAX_QPATH];
- char *slash;
-
- pi->torsoModel = 0;
- pi->headModel = 0;
-
- if ( !modelSkinName[0] ) {
- return qfalse;
- }
-
- Q_strncpyz( modelName, modelSkinName, sizeof( modelName ) );
-
- slash = strchr( modelName, '/' );
- if ( !slash ) {
- // modelName did not include a skin name
- Q_strncpyz( skinName, "default", sizeof( skinName ) );
- } else {
- Q_strncpyz( skinName, slash + 1, sizeof( skinName ) );
- *slash = '\0';
- }
-
- Q_strncpyz( headModelName, headModelSkinName, sizeof( headModelName ) );
- slash = strchr( headModelName, '/' );
- if ( !slash ) {
- // modelName did not include a skin name
- Q_strncpyz( headSkinName, "default", sizeof( skinName ) );
- } else {
- Q_strncpyz( headSkinName, slash + 1, sizeof( skinName ) );
- *slash = '\0';
- }
-
- // load cmodels before models so filecache works
-
- Com_sprintf( filename, sizeof( filename ), "models/players/%s/lower.md3", modelName );
- pi->legsModel = trap_R_RegisterModel( filename );
- if ( !pi->legsModel ) {
- Com_sprintf( filename, sizeof( filename ), "models/players/characters/%s/lower.md3", modelName );
- pi->legsModel = trap_R_RegisterModel( filename );
- if ( !pi->legsModel ) {
- Com_Printf( "Failed to load model file %s\n", filename );
- return qfalse;
- }
- }
-
- Com_sprintf( filename, sizeof( filename ), "models/players/%s/upper.md3", modelName );
- pi->torsoModel = trap_R_RegisterModel( filename );
- if ( !pi->torsoModel ) {
- Com_sprintf( filename, sizeof( filename ), "models/players/characters/%s/upper.md3", modelName );
- pi->torsoModel = trap_R_RegisterModel( filename );
- if ( !pi->torsoModel ) {
- Com_Printf( "Failed to load model file %s\n", filename );
- return qfalse;
- }
- }
-
- if (headModelName[0] == '*' ) {
- Com_sprintf( filename, sizeof( filename ), "models/players/heads/%s/%s.md3", &headModelName[1], &headModelName[1] );
- }
- else {
- Com_sprintf( filename, sizeof( filename ), "models/players/%s/head.md3", headModelName );
- }
- pi->headModel = trap_R_RegisterModel( filename );
- if ( !pi->headModel && headModelName[0] != '*') {
- Com_sprintf( filename, sizeof( filename ), "models/players/heads/%s/%s.md3", headModelName, headModelName );
- pi->headModel = trap_R_RegisterModel( filename );
- }
-
- if (!pi->headModel) {
- Com_Printf( "Failed to load model file %s\n", filename );
- return qfalse;
- }
-
- // if any skins failed to load, fall back to default
- if ( !UI_RegisterClientSkin( pi, modelName, skinName, headModelName, headSkinName, teamName) ) {
- if ( !UI_RegisterClientSkin( pi, modelName, "default", headModelName, "default", teamName ) ) {
- Com_Printf( "Failed to load skin file: %s : %s\n", modelName, skinName );
- return qfalse;
- }
- }
-
- // load the animations
- Com_sprintf( filename, sizeof( filename ), "models/players/%s/animation.cfg", modelName );
- if ( !UI_ParseAnimationFile( filename, pi->animations ) ) {
- Com_sprintf( filename, sizeof( filename ), "models/players/characters/%s/animation.cfg", modelName );
- if ( !UI_ParseAnimationFile( filename, pi->animations ) ) {
- Com_Printf( "Failed to load animation file %s\n", filename );
- return qfalse;
- }
- }
-
- return qtrue;
-}
-
-
-/*
-===============
-UI_PlayerInfo_SetModel
-===============
-*/
-void UI_PlayerInfo_SetModel( playerInfo_t *pi, const char *model, const char *headmodel, char *teamName ) {
- memset( pi, 0, sizeof(*pi) );
- UI_RegisterClientModelname( pi, model, headmodel, teamName );
- pi->weapon = WP_MACHINEGUN;
- pi->currentWeapon = pi->weapon;
- pi->lastWeapon = pi->weapon;
- pi->pendingWeapon = -1;
- pi->weaponTimer = 0;
- pi->chat = qfalse;
- pi->newModel = qtrue;
- UI_PlayerInfo_SetWeapon( pi, pi->weapon );
-}
-
-
-/*
-===============
-UI_PlayerInfo_SetInfo
-===============
-*/
-void UI_PlayerInfo_SetInfo( playerInfo_t *pi, int legsAnim, int torsoAnim, vec3_t viewAngles, vec3_t moveAngles, weapon_t weaponNumber, qboolean chat ) {
- int currentAnim;
- weapon_t weaponNum;
-
- pi->chat = chat;
-
- // view angles
- VectorCopy( viewAngles, pi->viewAngles );
-
- // move angles
- VectorCopy( moveAngles, pi->moveAngles );
-
- if ( pi->newModel ) {
- pi->newModel = qfalse;
-
- jumpHeight = 0;
- pi->pendingLegsAnim = 0;
- UI_ForceLegsAnim( pi, legsAnim );
- pi->legs.yawAngle = viewAngles[YAW];
- pi->legs.yawing = qfalse;
-
- pi->pendingTorsoAnim = 0;
- UI_ForceTorsoAnim( pi, torsoAnim );
- pi->torso.yawAngle = viewAngles[YAW];
- pi->torso.yawing = qfalse;
-
- if ( weaponNumber != WP_NUM_WEAPONS ) {
- pi->weapon = weaponNumber;
- pi->currentWeapon = weaponNumber;
- pi->lastWeapon = weaponNumber;
- pi->pendingWeapon = WP_NUM_WEAPONS;
- pi->weaponTimer = 0;
- UI_PlayerInfo_SetWeapon( pi, pi->weapon );
- }
-
- return;
- }
-
- // weapon
- if ( weaponNumber == WP_NUM_WEAPONS ) {
- pi->pendingWeapon = WP_NUM_WEAPONS;
- pi->weaponTimer = 0;
- }
- else if ( weaponNumber != WP_NONE ) {
- pi->pendingWeapon = weaponNumber;
- pi->weaponTimer = dp_realtime + UI_TIMER_WEAPON_DELAY;
- }
- weaponNum = pi->lastWeapon;
- pi->weapon = weaponNum;
-
- if ( torsoAnim == BOTH_DEATH1 || legsAnim == BOTH_DEATH1 ) {
- torsoAnim = legsAnim = BOTH_DEATH1;
- pi->weapon = pi->currentWeapon = WP_NONE;
- UI_PlayerInfo_SetWeapon( pi, pi->weapon );
-
- jumpHeight = 0;
- pi->pendingLegsAnim = 0;
- UI_ForceLegsAnim( pi, legsAnim );
-
- pi->pendingTorsoAnim = 0;
- UI_ForceTorsoAnim( pi, torsoAnim );
-
- return;
- }
-
- // leg animation
- currentAnim = pi->legsAnim & ~ANIM_TOGGLEBIT;
- if ( legsAnim != LEGS_JUMP && ( currentAnim == LEGS_JUMP || currentAnim == LEGS_LAND ) ) {
- pi->pendingLegsAnim = legsAnim;
- }
- else if ( legsAnim != currentAnim ) {
- jumpHeight = 0;
- pi->pendingLegsAnim = 0;
- UI_ForceLegsAnim( pi, legsAnim );
- }
-
- // torso animation
- if ( torsoAnim == TORSO_STAND || torsoAnim == TORSO_STAND2 ) {
- if ( weaponNum == WP_NONE ) {
- torsoAnim = TORSO_STAND2;
- }
- else {
- torsoAnim = TORSO_STAND;
- }
- }
-
- if ( torsoAnim == TORSO_ATTACK || torsoAnim == TORSO_ATTACK2 ) {
- if ( weaponNum == WP_NONE ) {
- torsoAnim = TORSO_ATTACK2;
- }
- else {
- torsoAnim = TORSO_ATTACK;
- }
- pi->muzzleFlashTime = dp_realtime + UI_TIMER_MUZZLE_FLASH;
- //FIXME play firing sound here
- }
-
- currentAnim = pi->torsoAnim & ~ANIM_TOGGLEBIT;
-
- if ( weaponNum != pi->currentWeapon || currentAnim == TORSO_RAISE || currentAnim == TORSO_DROP ) {
- pi->pendingTorsoAnim = torsoAnim;
- }
- else if ( ( currentAnim == TORSO_GESTURE || currentAnim == TORSO_ATTACK ) && ( torsoAnim != currentAnim ) ) {
- pi->pendingTorsoAnim = torsoAnim;
- }
- else if ( torsoAnim != currentAnim ) {
- pi->pendingTorsoAnim = 0;
- UI_ForceTorsoAnim( pi, torsoAnim );
- }
-}
diff --git a/src/ui/ui_public.h b/src/ui/ui_public.h
index f62b8b9..2f85e10 100644
--- a/src/ui/ui_public.h
+++ b/src/ui/ui_public.h
@@ -1,13 +1,14 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
-Copyright (C) 2000-2006 Tim Angus
+Copyright (C) 2000-2013 Darklegion Development
+Copyright (C) 2015-2019 GrangerHub
This file is part of Tremulous.
Tremulous 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,
+published by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
Tremulous is distributed in the hope that it will be
@@ -16,195 +17,189 @@ 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 Tremulous; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+along with Tremulous; if not, see <https://www.gnu.org/licenses/>
+
===========================================================================
*/
-#ifndef __UI_PUBLIC_H__
-#define __UI_PUBLIC_H__
+#ifndef UI_PUBLIC_H
+#define UI_PUBLIC_H
+
+#include "qcommon/q_shared.h"
-#define UI_API_VERSION 6
+#define UI_API_VERSION 6
typedef struct {
- connstate_t connState;
- int connectPacketCount;
- int clientNum;
- char servername[MAX_STRING_CHARS];
- char updateInfoString[MAX_STRING_CHARS];
- char messageString[MAX_STRING_CHARS];
+ connstate_t connState;
+ int connectPacketCount;
+ int clientNum;
+ char servername[MAX_STRING_CHARS];
+ char updateInfoString[MAX_STRING_CHARS];
+ char messageString[MAX_STRING_CHARS];
} uiClientState_t;
typedef enum {
- UI_ERROR,
- UI_PRINT,
- UI_MILLISECONDS,
- UI_CVAR_SET,
- UI_CVAR_VARIABLEVALUE,
- UI_CVAR_VARIABLESTRINGBUFFER,
- UI_CVAR_SETVALUE,
- UI_CVAR_RESET,
- UI_CVAR_CREATE,
- UI_CVAR_INFOSTRINGBUFFER,
- UI_ARGC,
- UI_ARGV,
- UI_CMD_EXECUTETEXT,
- UI_FS_FOPENFILE,
- UI_FS_READ,
- UI_FS_WRITE,
- UI_FS_FCLOSEFILE,
- UI_FS_GETFILELIST,
- UI_R_REGISTERMODEL,
- UI_R_REGISTERSKIN,
- UI_R_REGISTERSHADERNOMIP,
- UI_R_CLEARSCENE,
- UI_R_ADDREFENTITYTOSCENE,
- UI_R_ADDPOLYTOSCENE,
- UI_R_ADDLIGHTTOSCENE,
- UI_R_RENDERSCENE,
- UI_R_SETCOLOR,
+ UI_ERROR,
+ UI_PRINT,
+ UI_MILLISECONDS,
+ UI_CVAR_SET,
+ UI_CVAR_VARIABLEVALUE,
+ UI_CVAR_VARIABLESTRINGBUFFER,
+ UI_CVAR_SETVALUE,
+ UI_CVAR_RESET,
+ UI_CVAR_CREATE,
+ UI_CVAR_INFOSTRINGBUFFER,
+ UI_ARGC,
+ UI_ARGV,
+ UI_CMD_EXECUTETEXT,
+ UI_FS_FOPENFILE,
+ UI_FS_READ,
+ UI_FS_WRITE,
+ UI_FS_FCLOSEFILE,
+ UI_FS_GETFILELIST,
+ UI_R_REGISTERMODEL,
+ UI_R_REGISTERSKIN,
+ UI_R_REGISTERSHADERNOMIP,
+ UI_R_CLEARSCENE,
+ UI_R_ADDREFENTITYTOSCENE,
+ UI_R_ADDPOLYTOSCENE,
+ UI_R_ADDLIGHTTOSCENE,
+ UI_R_RENDERSCENE,
+ UI_R_SETCOLOR,
#ifndef MODULE_INTERFACE_11
- UI_R_SETCLIPREGION,
+ UI_R_SETCLIPREGION,
#endif
- UI_R_DRAWSTRETCHPIC,
- UI_UPDATESCREEN,
- UI_CM_LERPTAG,
- UI_CM_LOADMODEL,
- UI_S_REGISTERSOUND,
- UI_S_STARTLOCALSOUND,
- UI_KEY_KEYNUMTOSTRINGBUF,
- UI_KEY_GETBINDINGBUF,
- UI_KEY_SETBINDING,
- UI_KEY_ISDOWN,
- UI_KEY_GETOVERSTRIKEMODE,
- UI_KEY_SETOVERSTRIKEMODE,
- UI_KEY_CLEARSTATES,
- UI_KEY_GETCATCHER,
- UI_KEY_SETCATCHER,
- UI_GETCLIPBOARDDATA,
- UI_GETGLCONFIG,
- UI_GETCLIENTSTATE,
- UI_GETCONFIGSTRING,
- UI_LAN_GETPINGQUEUECOUNT,
- UI_LAN_CLEARPING,
- UI_LAN_GETPING,
- UI_LAN_GETPINGINFO,
- UI_CVAR_REGISTER,
- UI_CVAR_UPDATE,
- UI_MEMORY_REMAINING,
- UI_R_REGISTERFONT,
- UI_R_MODELBOUNDS,
+ UI_R_DRAWSTRETCHPIC,
+ UI_UPDATESCREEN,
+ UI_CM_LERPTAG,
+ UI_CM_LOADMODEL,
+ UI_S_REGISTERSOUND,
+ UI_S_STARTLOCALSOUND,
+ UI_KEY_KEYNUMTOSTRINGBUF,
+ UI_KEY_GETBINDINGBUF,
+ UI_KEY_SETBINDING,
+ UI_KEY_ISDOWN,
+ UI_KEY_GETOVERSTRIKEMODE,
+ UI_KEY_SETOVERSTRIKEMODE,
+ UI_KEY_CLEARSTATES,
+ UI_KEY_GETCATCHER,
+ UI_KEY_SETCATCHER,
+ UI_GETCLIPBOARDDATA,
+ UI_GETGLCONFIG,
+ UI_GETCLIENTSTATE,
+ UI_GETCONFIGSTRING,
+ UI_LAN_GETPINGQUEUECOUNT,
+ UI_LAN_CLEARPING,
+ UI_LAN_GETPING,
+ UI_LAN_GETPINGINFO,
+ UI_CVAR_REGISTER,
+ UI_CVAR_UPDATE,
+ UI_MEMORY_REMAINING,
+ UI_R_REGISTERFONT,
+ UI_R_MODELBOUNDS,
#ifdef MODULE_INTERFACE_11
- UI_PARSE_ADD_GLOBAL_DEFINE,
- UI_PARSE_LOAD_SOURCE,
- UI_PARSE_FREE_SOURCE,
- UI_PARSE_READ_TOKEN,
- UI_PARSE_SOURCE_FILE_AND_LINE,
+ UI_PARSE_ADD_GLOBAL_DEFINE,
+ UI_PARSE_LOAD_SOURCE,
+ UI_PARSE_FREE_SOURCE,
+ UI_PARSE_READ_TOKEN,
+ UI_PARSE_SOURCE_FILE_AND_LINE,
#endif
- UI_S_STOPBACKGROUNDTRACK,
- UI_S_STARTBACKGROUNDTRACK,
- UI_REAL_TIME,
- UI_LAN_GETSERVERCOUNT,
- UI_LAN_GETSERVERADDRESSSTRING,
- UI_LAN_GETSERVERINFO,
- UI_LAN_MARKSERVERVISIBLE,
- UI_LAN_UPDATEVISIBLEPINGS,
- UI_LAN_RESETPINGS,
- UI_LAN_LOADCACHEDSERVERS,
- UI_LAN_SAVECACHEDSERVERS,
- UI_LAN_ADDSERVER,
- UI_LAN_REMOVESERVER,
- UI_CIN_PLAYCINEMATIC,
- UI_CIN_STOPCINEMATIC,
- UI_CIN_RUNCINEMATIC,
- UI_CIN_DRAWCINEMATIC,
- UI_CIN_SETEXTENTS,
- UI_R_REMAP_SHADER,
- UI_LAN_SERVERSTATUS,
- UI_LAN_GETSERVERPING,
- UI_LAN_SERVERISVISIBLE,
- UI_LAN_COMPARESERVERS,
- // 1.32
- UI_FS_SEEK,
- UI_SET_PBCLSTATUS,
+ UI_S_STOPBACKGROUNDTRACK,
+ UI_S_STARTBACKGROUNDTRACK,
+ UI_REAL_TIME,
+ UI_LAN_GETSERVERCOUNT,
+ UI_LAN_GETSERVERADDRESSSTRING,
+ UI_LAN_GETSERVERINFO,
+ UI_LAN_MARKSERVERVISIBLE,
+ UI_LAN_UPDATEVISIBLEPINGS,
+ UI_LAN_RESETPINGS,
+ UI_LAN_LOADCACHEDSERVERS,
+ UI_LAN_SAVECACHEDSERVERS,
+ UI_LAN_ADDSERVER,
+ UI_LAN_REMOVESERVER,
+ UI_CIN_PLAYCINEMATIC,
+ UI_CIN_STOPCINEMATIC,
+ UI_CIN_RUNCINEMATIC,
+ UI_CIN_DRAWCINEMATIC,
+ UI_CIN_SETEXTENTS,
+ UI_R_REMAP_SHADER,
+ UI_LAN_SERVERSTATUS,
+ UI_LAN_GETSERVERPING,
+ UI_LAN_SERVERISVISIBLE,
+ UI_LAN_COMPARESERVERS,
+ // 1.32
+ UI_FS_SEEK,
+ UI_SET_PBCLSTATUS,
#ifndef MODULE_INTERFACE_11
- UI_PARSE_ADD_GLOBAL_DEFINE,
- UI_PARSE_LOAD_SOURCE,
- UI_PARSE_FREE_SOURCE,
- UI_PARSE_READ_TOKEN,
- UI_PARSE_SOURCE_FILE_AND_LINE,
- UI_GETNEWS,
+ UI_PARSE_ADD_GLOBAL_DEFINE,
+ UI_PARSE_LOAD_SOURCE,
+ UI_PARSE_FREE_SOURCE,
+ UI_PARSE_READ_TOKEN,
+ UI_PARSE_SOURCE_FILE_AND_LINE,
+ UI_GETNEWS,
#endif
- UI_MEMSET = 100,
- UI_MEMCPY,
- UI_STRNCPY,
- UI_SIN,
- UI_COS,
- UI_ATAN2,
- UI_SQRT,
- UI_FLOOR,
- UI_CEIL
+ // XXX THERE IS ROOM FOR _1_ (or 2? Did i count from 0?)
+ // SYSCALL BETWEEN UI_GETNEWS and UI_MEMSET
+ // UI_RESERVED_SYSCALL = 99,
+
+ UI_MEMSET = 100,
+ UI_MEMCPY,
+ UI_STRNCPY,
+ UI_SIN,
+ UI_COS,
+ UI_ATAN2,
+ UI_SQRT,
+ UI_FLOOR,
+ UI_CEIL,
} uiImport_t;
-typedef enum {
- UIMENU_NONE,
- UIMENU_MAIN,
- UIMENU_INGAME,
- UIMENU_TEAM,
- UIMENU_POSTGAME
-} uiMenuCommand_t;
-
-typedef enum
-{
- SORT_HOST,
- SORT_MAP,
- SORT_CLIENTS,
- SORT_PING
-} serverSortField_t;
+typedef enum { UIMENU_NONE, UIMENU_MAIN, UIMENU_INGAME } uiMenuCommand_t;
+
+typedef enum { SORT_HOST, SORT_GAME, SORT_MAP, SORT_CLIENTS, SORT_PING } serverSortField_t;
typedef enum {
- UI_GETAPIVERSION = 0, // system reserved
+ UI_GETAPIVERSION = 0, // system reserved
- UI_INIT,
-// void UI_Init( void );
+ UI_INIT,
+ // void UI_Init( void );
- UI_SHUTDOWN,
-// void UI_Shutdown( void );
+ UI_SHUTDOWN,
+ // void UI_Shutdown( void );
- UI_KEY_EVENT,
-// void UI_KeyEvent( int key );
+ UI_KEY_EVENT,
+ // void UI_KeyEvent( int key );
- UI_MOUSE_EVENT,
+ UI_MOUSE_EVENT,
// void UI_MouseEvent( int dx, int dy );
#ifndef MODULE_INTERFACE_11
- UI_MOUSE_POSITION,
-// int UI_MousePosition( void );
+ UI_MOUSE_POSITION,
+ // int UI_MousePosition( void );
- UI_SET_MOUSE_POSITION,
+ UI_SET_MOUSE_POSITION,
// void UI_SetMousePosition( int x, int y );
#endif
- UI_REFRESH,
-// void UI_Refresh( int time );
+ UI_REFRESH,
+ // void UI_Refresh( int time );
- UI_IS_FULLSCREEN,
-// qboolean UI_IsFullscreen( void );
+ UI_IS_FULLSCREEN,
+ // qboolean UI_IsFullscreen( void );
- UI_SET_ACTIVE_MENU,
-// void UI_SetActiveMenu( uiMenuCommand_t menu );
+ UI_SET_ACTIVE_MENU,
+ // void UI_SetActiveMenu( uiMenuCommand_t menu );
- UI_CONSOLE_COMMAND,
-// qboolean UI_ConsoleCommand( int realTime );
+ UI_CONSOLE_COMMAND,
+ // qboolean UI_ConsoleCommand( int realTime );
- UI_DRAW_CONNECT_SCREEN
-// void UI_DrawConnectScreen( qboolean overlay );
+ UI_DRAW_CONNECT_SCREEN
+ // void UI_DrawConnectScreen( qboolean overlay );
-// if !overlay, the background will be drawn, otherwise it will be
-// overlayed over whatever the cgame has drawn.
-// a GetClientState syscall will be made to get the current strings
+ // if !overlay, the background will be drawn, otherwise it will be
+ // overlayed over whatever the cgame has drawn.
+ // a GetClientState syscall will be made to get the current strings
} uiExport_t;
#endif
diff --git a/src/ui/ui_shared.c b/src/ui/ui_shared.c
index 5640e0e..8b6225e 100644
--- a/src/ui/ui_shared.c
+++ b/src/ui/ui_shared.c
@@ -1,13 +1,14 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
-Copyright (C) 2000-2006 Tim Angus
+Copyright (C) 2000-2013 Darklegion Development
+Copyright (C) 2015-2019 GrangerHub
This file is part of Tremulous.
Tremulous 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,
+published by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
Tremulous is distributed in the hope that it will be
@@ -16,38 +17,40 @@ 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 Tremulous; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+along with Tremulous; if not, see <https://www.gnu.org/licenses/>
+
===========================================================================
*/
#include "ui_shared.h"
-#define SCROLL_TIME_START 500
-#define SCROLL_TIME_ADJUST 150
-#define SCROLL_TIME_ADJUSTOFFSET 40
-#define SCROLL_TIME_FLOOR 20
-
-typedef struct scrollInfo_s {
- int nextScrollTime;
- int nextAdjustTime;
- int adjustValue;
- int scrollKey;
- float xStart;
- float yStart;
- itemDef_t *item;
- qboolean scrollDir;
+#define SCROLL_TIME_START 500
+#define SCROLL_TIME_ADJUST 150
+#define SCROLL_TIME_ADJUSTOFFSET 40
+#define SCROLL_TIME_FLOOR 20
+
+typedef struct {
+ int nextScrollTime;
+ int nextAdjustTime;
+ int adjustValue;
+ int scrollKey;
+ float xStart;
+ float yStart;
+ itemDef_t *item;
+ qboolean scrollDir;
} scrollInfo_t;
static scrollInfo_t scrollInfo;
-//TA: hack to prevent compiler warnings
-void voidFunction( void *var ) { return; }
-qboolean voidFunction2( itemDef_t *var1, int var2 ) { return qfalse; }
+// prevent compiler warnings
+void voidFunction(void *var) { return; }
-static void (*captureFunc) (void *p) = voidFunction;
+qboolean voidFunction2(itemDef_t *var1, int var2) { return qfalse; }
+
+static CaptureFunc *captureFunc = voidFunction;
+static int captureFuncExpiry = 0;
static void *captureData = NULL;
-static itemDef_t *itemCapture = NULL; // item that has the mouse captured ( if any )
+static itemDef_t *itemCapture = NULL; // item that has the mouse captured ( if any )
displayContextDef_t *DC = NULL;
@@ -56,20 +59,23 @@ static qboolean g_editingField = qfalse;
static itemDef_t *g_bindItem = NULL;
static itemDef_t *g_editItem = NULL;
+static itemDef_t *g_comboBoxItem = NULL;
-menuDef_t Menus[MAX_MENUS]; // defined menus
-int menuCount = 0; // how many
+menuDef_t Menus[MAX_MENUS]; // defined menus
+int menuCount = 0; // how many
menuDef_t *menuStack[MAX_OPEN_MENUS];
int openMenuCount = 0;
-static qboolean debugMode = qfalse;
-
#define DOUBLE_CLICK_DELAY 300
static int lastListBoxClickTime = 0;
+itemDataType_t Item_DataType(itemDef_t *item);
void Item_RunScript(itemDef_t *item, const char *s);
void Item_SetupKeywordHash(void);
+static ID_INLINE qboolean Item_IsEditField(itemDef_t *item);
+static ID_INLINE qboolean Item_IsListBox(itemDef_t *item);
+static void Item_ListBox_SetStartPos(itemDef_t *item, int startPos);
void Menu_SetupKeywordHash(void);
int BindingIDFromName(const char *name);
qboolean Item_Bind_HandleKey(itemDef_t *item, int key, qboolean down);
@@ -77,40 +83,68 @@ itemDef_t *Menu_SetPrevCursorItem(menuDef_t *menu);
itemDef_t *Menu_SetNextCursorItem(menuDef_t *menu);
static qboolean Menu_OverActiveItem(menuDef_t *menu, float x, float y);
+/*
+===============
+UI_InstallCaptureFunc
+===============
+*/
+void UI_InstallCaptureFunc(CaptureFunc *f, void *data, int timeout)
+{
+ captureFunc = f;
+ captureData = data;
+
+ if (timeout > 0)
+ captureFuncExpiry = DC->realTime + timeout;
+ else
+ captureFuncExpiry = 0;
+}
+
+/*
+===============
+UI_RemoveCaptureFunc
+===============
+*/
+void UI_RemoveCaptureFunc(void)
+{
+ captureFunc = voidFunction;
+ captureData = NULL;
+ captureFuncExpiry = 0;
+}
+
#ifdef CGAME
-#define MEM_POOL_SIZE 128 * 1024
+#define MEM_POOL_SIZE 128 * 1024
#else
-#define MEM_POOL_SIZE 1024 * 1024
+#define MEM_POOL_SIZE 1024 * 1024
#endif
-//TA: hacked variable name to avoid conflict with new cgame Alloc
-static char UI_memoryPool[MEM_POOL_SIZE];
-static int allocPoint, outOfMemory;
+static char UI_memoryPool[MEM_POOL_SIZE];
+static int allocPoint, outOfMemory;
/*
===============
UI_Alloc
===============
*/
-void *UI_Alloc( int size )
+void *UI_Alloc(int size)
{
- char *p;
+ char *p;
+
+ if (allocPoint + size > MEM_POOL_SIZE)
+ {
+ outOfMemory = qtrue;
- if( allocPoint + size > MEM_POOL_SIZE )
- {
- outOfMemory = qtrue;
+ if (DC->Print)
+ DC->Print("UI_Alloc: Failure. Out of memory!\n");
- if( DC->Print )
- DC->Print( "UI_Alloc: Failure. Out of memory!\n" );
- //DC->trap_Print(S_COLOR_YELLOW"WARNING: UI Out of Memory!\n");
- return NULL;
- }
+ // DC->trap_Print(S_COLOR_YELLOW"WARNING: UI Out of Memory!\n");
+ return NULL;
+ }
- p = &UI_memoryPool[ allocPoint ];
+ p = &UI_memoryPool[allocPoint];
- allocPoint += ( size + 15 ) & ~15;
+ allocPoint += (size + 15) & ~15;
- return p;
+ return p;
}
/*
@@ -118,20 +152,13 @@ void *UI_Alloc( int size )
UI_InitMemory
===============
*/
-void UI_InitMemory( void )
+void UI_InitMemory(void)
{
- allocPoint = 0;
- outOfMemory = qfalse;
+ allocPoint = 0;
+ outOfMemory = qfalse;
}
-qboolean UI_OutOfMemory( )
-{
- return outOfMemory;
-}
-
-
-
-
+qboolean UI_OutOfMemory() { return outOfMemory; }
#define HASH_TABLE_SIZE 2048
/*
@@ -139,25 +166,29 @@ qboolean UI_OutOfMemory( )
return a hash value for the string
================
*/
-static long hashForString(const char *str) {
- int i;
- long hash;
- char letter;
-
- hash = 0;
- i = 0;
- while (str[i] != '\0') {
- letter = tolower(str[i]);
- hash+=(long)(letter)*(i+119);
- i++;
- }
- hash &= (HASH_TABLE_SIZE-1);
- return hash;
+static long hashForString(const char *str)
+{
+ int i;
+ long hash;
+ char letter;
+
+ hash = 0;
+ i = 0;
+
+ while (str[i] != '\0')
+ {
+ letter = tolower(str[i]);
+ hash += (long)(letter) * (i + 119);
+ i++;
+ }
+
+ hash &= (HASH_TABLE_SIZE - 1);
+ return hash;
}
typedef struct stringDef_s {
- struct stringDef_s *next;
- const char *str;
+ struct stringDef_s *next;
+ const char *str;
} stringDef_t;
static int strPoolIndex = 0;
@@ -166,69 +197,81 @@ static char strPool[STRING_POOL_SIZE];
static int strHandleCount = 0;
static stringDef_t *strHandle[HASH_TABLE_SIZE];
+// Make a copy of a string for later use. Can safely be called on the
+// same string repeatedly. Redundant on string literals or global
+// constants.
+const char *String_Alloc(const char *p)
+{
+ int len;
+ long hash;
+ stringDef_t *str, *last;
-const char *String_Alloc(const char *p) {
- int len;
- long hash;
- stringDef_t *str, *last;
- static const char *staticNULL = "";
+ if (p == NULL)
+ return NULL;
- if (p == NULL) {
- return NULL;
- }
+ if (*p == 0)
+ return "";
- if (*p == 0) {
- return staticNULL;
- }
+ hash = hashForString(p);
- hash = hashForString(p);
+ str = strHandle[hash];
+
+ while (str)
+ {
+ if (strcmp(p, str->str) == 0)
+ return str->str;
- str = strHandle[hash];
- while (str) {
- if (strcmp(p, str->str) == 0) {
- return str->str;
+ str = str->next;
}
- str = str->next;
- }
- len = strlen(p);
- if (len + strPoolIndex + 1 < STRING_POOL_SIZE) {
- int ph = strPoolIndex;
- strcpy(&strPool[strPoolIndex], p);
- strPoolIndex += len + 1;
+ len = strlen(p);
- str = strHandle[hash];
- last = str;
- while (str && str->next) {
- last = str;
- str = str->next;
- }
-
- str = UI_Alloc(sizeof(stringDef_t));
- str->next = NULL;
- str->str = &strPool[ph];
- if (last) {
- last->next = str;
- } else {
- strHandle[hash] = str;
- }
- return &strPool[ph];
- }
- return NULL;
-}
-
-void String_Report( void ) {
- float f;
- Com_Printf("Memory/String Pool Info\n");
- Com_Printf("----------------\n");
- f = strPoolIndex;
- f /= STRING_POOL_SIZE;
- f *= 100;
- Com_Printf("String Pool is %.1f%% full, %i bytes out of %i used.\n", f, strPoolIndex, STRING_POOL_SIZE);
- f = allocPoint;
- f /= MEM_POOL_SIZE;
- f *= 100;
- Com_Printf("Memory Pool is %.1f%% full, %i bytes out of %i used.\n", f, allocPoint, MEM_POOL_SIZE);
+ if (len + strPoolIndex + 1 < STRING_POOL_SIZE)
+ {
+ int ph = strPoolIndex;
+ strcpy(&strPool[strPoolIndex], p);
+ strPoolIndex += len + 1;
+
+ str = strHandle[hash];
+ last = str;
+
+ while (str && str->next)
+ {
+ last = str;
+ str = str->next;
+ }
+
+ str = UI_Alloc(sizeof(stringDef_t));
+ str->next = NULL;
+ str->str = &strPool[ph];
+
+ if (last)
+ last->next = str;
+ else
+ strHandle[hash] = str;
+
+ return &strPool[ph];
+ }
+ else
+ {
+ Com_Error(ERR_DROP, "String_Alloc( %s ): string pool full!", p);
+ return NULL; // not that we return at all
+ }
+}
+
+void String_Report(void)
+{
+ float f;
+ Com_Printf("Memory/String Pool Info\n");
+ Com_Printf("----------------\n");
+ f = strPoolIndex;
+ f /= STRING_POOL_SIZE;
+ f *= 100;
+ Com_Printf("String Pool is %.1f%% full, %i bytes out of %i used.\n", f, strPoolIndex, STRING_POOL_SIZE);
+ f = allocPoint;
+ f /= MEM_POOL_SIZE;
+ f *= 100;
+ Com_Printf("Memory Pool is %.1f%% full, %i bytes out of %i used.\n", f, allocPoint, MEM_POOL_SIZE);
}
/*
@@ -236,22 +279,29 @@ void String_Report( void ) {
String_Init
=================
*/
-void String_Init( void )
+void String_Init(void)
{
- int i;
- for( i = 0; i < HASH_TABLE_SIZE; i++ )
- strHandle[ i ] = 0;
+ int i;
- strHandleCount = 0;
- strPoolIndex = 0;
- menuCount = 0;
- openMenuCount = 0;
- UI_InitMemory( );
- Item_SetupKeywordHash( );
- Menu_SetupKeywordHash( );
+ for (i = 0; i < HASH_TABLE_SIZE; i++)
+ strHandle[i] = 0;
- if( DC && DC->getBindingBuf )
- Controls_GetConfig( );
+ strHandleCount = 0;
+
+ strPoolIndex = 0;
+
+ menuCount = 0;
+
+ openMenuCount = 0;
+
+ UI_InitMemory();
+
+ Item_SetupKeywordHash();
+
+ Menu_SetupKeywordHash();
+
+ if (DC && DC->getBindingBuf)
+ Controls_GetConfig();
}
/*
@@ -259,21 +309,22 @@ void String_Init( void )
PC_SourceWarning
=================
*/
-void PC_SourceWarning(int handle, char *format, ...) {
- int line;
- char filename[128];
- va_list argptr;
- static char string[4096];
+__attribute__((format(printf, 2, 3))) void PC_SourceWarning(int handle, char *format, ...)
+{
+ int line;
+ char filename[128];
+ va_list argptr;
+ static char string[4096];
- va_start (argptr, format);
- vsprintf (string, format, argptr);
- va_end (argptr);
+ va_start(argptr, format);
+ Q_vsnprintf(string, sizeof(string), format, argptr);
+ va_end(argptr);
- filename[0] = '\0';
- line = 0;
- trap_Parse_SourceFileAndLine(handle, filename, &line);
+ filename[0] = '\0';
+ line = 0;
+ trap_Parse_SourceFileAndLine(handle, filename, &line);
- Com_Printf(S_COLOR_YELLOW "WARNING: %s, line %d: %s\n", filename, line, string);
+ Com_Printf(S_COLOR_YELLOW "WARNING: %s, line %d: %s\n", filename, line, string);
}
/*
@@ -281,21 +332,22 @@ void PC_SourceWarning(int handle, char *format, ...) {
PC_SourceError
=================
*/
-void PC_SourceError(int handle, char *format, ...) {
- int line;
- char filename[128];
- va_list argptr;
- static char string[4096];
+__attribute__((format(printf, 2, 3))) void PC_SourceError(int handle, char *format, ...)
+{
+ int line;
+ char filename[128];
+ va_list argptr;
+ static char string[4096];
- va_start (argptr, format);
- vsprintf (string, format, argptr);
- va_end (argptr);
+ va_start(argptr, format);
+ Q_vsnprintf(string, sizeof(string), format, argptr);
+ va_end(argptr);
- filename[0] = '\0';
- line = 0;
- trap_Parse_SourceFileAndLine(handle, filename, &line);
+ filename[0] = '\0';
+ line = 0;
+ trap_Parse_SourceFileAndLine(handle, filename, &line);
- Com_Printf(S_COLOR_RED "ERROR: %s, line %d: %s\n", filename, line, string);
+ Com_Printf(S_COLOR_RED "ERROR: %s, line %d: %s\n", filename, line, string);
}
/*
@@ -305,17 +357,19 @@ LerpColor
*/
void LerpColor(vec4_t a, vec4_t b, vec4_t c, float t)
{
- int i;
+ int i;
- // lerp and clamp each component
- for (i=0; i<4; i++)
- {
- c[i] = a[i] + t*(b[i]-a[i]);
- if (c[i] < 0)
- c[i] = 0;
- else if (c[i] > 1.0)
- c[i] = 1.0;
- }
+ // lerp and clamp each component
+
+ for (i = 0; i < 4; i++)
+ {
+ c[i] = a[i] + t * (b[i] - a[i]);
+
+ if (c[i] < 0)
+ c[i] = 0;
+ else if (c[i] > 1.0)
+ c[i] = 1.0;
+ }
}
/*
@@ -323,15 +377,271 @@ void LerpColor(vec4_t a, vec4_t b, vec4_t c, float t)
Float_Parse
=================
*/
-qboolean Float_Parse(char **p, float *f) {
- char *token;
- token = COM_ParseExt(p, qfalse);
- if (token && token[0] != 0) {
- *f = atof(token);
+qboolean Float_Parse(char **p, float *f)
+{
+ char *token;
+ token = COM_ParseExt(p, qfalse);
+
+ if (token && token[0] != 0)
+ {
+ *f = atof(token);
+ return qtrue;
+ }
+ else
+ return qfalse;
+}
+
+#define MAX_EXPR_ELEMENTS 32
+
+typedef enum { EXPR_OPERATOR, EXPR_VALUE } exprType_t;
+
+typedef struct exprToken_s {
+ exprType_t type;
+ union {
+ char op;
+ float val;
+ } u;
+} exprToken_t;
+
+typedef struct exprList_s {
+ exprToken_t l[MAX_EXPR_ELEMENTS];
+ int f, b;
+} exprList_t;
+
+/*
+=================
+OpPrec
+
+Return a value reflecting operator precedence
+=================
+*/
+static ID_INLINE int OpPrec(char op)
+{
+ switch (op)
+ {
+ case '*':
+ return 4;
+
+ case '/':
+ return 3;
+
+ case '+':
+ return 2;
+
+ case '-':
+ return 1;
+
+ case '(':
+ return 0;
+
+ default:
+ return -1;
+ }
+}
+
+/*
+=================
+PC_Expression_Parse
+=================
+*/
+static qboolean PC_Expression_Parse(int handle, float *f)
+{
+ pc_token_t token;
+ int unmatchedParentheses = 0;
+ exprList_t stack, fifo;
+ exprToken_t value;
+ qboolean expectingNumber = qtrue;
+
+#define FULL(a) (a.b >= (MAX_EXPR_ELEMENTS - 1))
+#define EMPTY(a) (a.f > a.b)
+
+#define PUSH_VAL(a, v) \
+ { \
+ if (FULL(a)) \
+ return qfalse; \
+ a.b++; \
+ a.l[a.b].type = EXPR_VALUE; \
+ a.l[a.b].u.val = v; \
+ }
+
+#define PUSH_OP(a, o) \
+ { \
+ if (FULL(a)) \
+ return qfalse; \
+ a.b++; \
+ a.l[a.b].type = EXPR_OPERATOR; \
+ a.l[a.b].u.op = o; \
+ }
+
+#define POP_STACK(a) \
+ { \
+ if (EMPTY(a)) \
+ return qfalse; \
+ value = a.l[a.b]; \
+ a.b--; \
+ }
+
+#define PEEK_STACK_OP(a) (a.l[a.b].u.op)
+#define PEEK_STACK_VAL(a) (a.l[a.b].u.val)
+
+#define POP_FIFO(a) \
+ { \
+ if (EMPTY(a)) \
+ return qfalse; \
+ value = a.l[a.f]; \
+ a.f++; \
+ }
+
+ stack.f = fifo.f = 0;
+ stack.b = fifo.b = -1;
+
+ while (trap_Parse_ReadToken(handle, &token))
+ {
+ if (!unmatchedParentheses && token.string[0] == ')')
+ break;
+
+ // Special case to catch negative numbers
+ if (expectingNumber && token.string[0] == '-')
+ {
+ if (!trap_Parse_ReadToken(handle, &token))
+ return qfalse;
+
+ token.floatvalue = -token.floatvalue;
+ }
+
+ if (token.type == TT_NUMBER)
+ {
+ if (!expectingNumber)
+ return qfalse;
+
+ expectingNumber = !expectingNumber;
+
+ PUSH_VAL(fifo, token.floatvalue);
+ }
+ else
+ {
+ switch (token.string[0])
+ {
+ case '(':
+ unmatchedParentheses++;
+ PUSH_OP(stack, '(');
+ break;
+
+ case ')':
+ unmatchedParentheses--;
+
+ if (unmatchedParentheses < 0)
+ return qfalse;
+
+ while (!EMPTY(stack) && PEEK_STACK_OP(stack) != '(')
+ {
+ POP_STACK(stack);
+ PUSH_OP(fifo, value.u.op);
+ }
+
+ // Pop the '('
+ POP_STACK(stack);
+
+ break;
+
+ case '*':
+ case '/':
+ case '+':
+ case '-':
+ if (expectingNumber)
+ return qfalse;
+
+ expectingNumber = !expectingNumber;
+
+ if (EMPTY(stack))
+ {
+ PUSH_OP(stack, token.string[0]);
+ }
+ else
+ {
+ while (!EMPTY(stack) && OpPrec(token.string[0]) < OpPrec(PEEK_STACK_OP(stack)))
+ {
+ POP_STACK(stack);
+ PUSH_OP(fifo, value.u.op);
+ }
+
+ PUSH_OP(stack, token.string[0]);
+ }
+
+ break;
+
+ default:
+ // Unknown token
+ return qfalse;
+ }
+ }
+ }
+
+ while (!EMPTY(stack))
+ {
+ POP_STACK(stack);
+ PUSH_OP(fifo, value.u.op);
+ }
+
+ while (!EMPTY(fifo))
+ {
+ POP_FIFO(fifo);
+
+ if (value.type == EXPR_VALUE)
+ {
+ PUSH_VAL(stack, value.u.val);
+ }
+ else if (value.type == EXPR_OPERATOR)
+ {
+ char op = value.u.op;
+ float operand1, operand2, result;
+
+ POP_STACK(stack);
+ operand2 = value.u.val;
+ POP_STACK(stack);
+ operand1 = value.u.val;
+
+ switch (op)
+ {
+ case '*':
+ result = operand1 * operand2;
+ break;
+
+ case '/':
+ result = operand1 / operand2;
+ break;
+
+ case '+':
+ result = operand1 + operand2;
+ break;
+
+ case '-':
+ result = operand1 - operand2;
+ break;
+
+ default:
+ Com_Error(ERR_FATAL, "Unknown operator '%c' in postfix string", op);
+ return qfalse;
+ }
+
+ PUSH_VAL(stack, result);
+ }
+ }
+
+ POP_STACK(stack);
+
+ *f = value.u.val;
+
return qtrue;
- } else {
- return qfalse;
- }
+
+#undef FULL
+#undef EMPTY
+#undef PUSH_VAL
+#undef PUSH_OP
+#undef POP_STACK
+#undef PEEK_STACK_OP
+#undef PEEK_STACK_VAL
+#undef POP_FIFO
}
/*
@@ -339,26 +649,37 @@ qboolean Float_Parse(char **p, float *f) {
PC_Float_Parse
=================
*/
-qboolean PC_Float_Parse(int handle, float *f) {
- pc_token_t token;
- int negative = qfalse;
+qboolean PC_Float_Parse(int handle, float *f)
+{
+ pc_token_t token;
+ int negative = qfalse;
- if (!trap_Parse_ReadToken(handle, &token))
- return qfalse;
- if (token.string[0] == '-') {
if (!trap_Parse_ReadToken(handle, &token))
- return qfalse;
- negative = qtrue;
- }
- if (token.type != TT_NUMBER) {
- PC_SourceError(handle, "expected float but found %s\n", token.string);
- return qfalse;
- }
- if (negative)
- *f = -token.floatvalue;
- else
- *f = token.floatvalue;
- return qtrue;
+ return qfalse;
+
+ if (token.string[0] == '(')
+ return PC_Expression_Parse(handle, f);
+
+ if (token.string[0] == '-')
+ {
+ if (!trap_Parse_ReadToken(handle, &token))
+ return qfalse;
+
+ negative = qtrue;
+ }
+
+ if (token.type != TT_NUMBER)
+ {
+ PC_SourceError(handle, "expected float but found %s\n", token.string);
+ return qfalse;
+ }
+
+ if (negative)
+ *f = -token.floatvalue;
+ else
+ *f = token.floatvalue;
+
+ return qtrue;
}
/*
@@ -366,17 +687,20 @@ qboolean PC_Float_Parse(int handle, float *f) {
Color_Parse
=================
*/
-qboolean Color_Parse(char **p, vec4_t *c) {
- int i;
- float f;
+qboolean Color_Parse(char **p, vec4_t *c)
+{
+ int i;
+ float f;
- for (i = 0; i < 4; i++) {
- if (!Float_Parse(p, &f)) {
- return qfalse;
+ for (i = 0; i < 4; i++)
+ {
+ if (!Float_Parse(p, &f))
+ return qfalse;
+
+ (*c)[i] = f;
}
- (*c)[i] = f;
- }
- return qtrue;
+
+ return qtrue;
}
/*
@@ -384,17 +708,20 @@ qboolean Color_Parse(char **p, vec4_t *c) {
PC_Color_Parse
=================
*/
-qboolean PC_Color_Parse(int handle, vec4_t *c) {
- int i;
- float f;
+qboolean PC_Color_Parse(int handle, vec4_t *c)
+{
+ int i;
+ float f;
+
+ for (i = 0; i < 4; i++)
+ {
+ if (!PC_Float_Parse(handle, &f))
+ return qfalse;
- for (i = 0; i < 4; i++) {
- if (!PC_Float_Parse(handle, &f)) {
- return qfalse;
+ (*c)[i] = f;
}
- (*c)[i] = f;
- }
- return qtrue;
+
+ return qtrue;
}
/*
@@ -402,16 +729,18 @@ qboolean PC_Color_Parse(int handle, vec4_t *c) {
Int_Parse
=================
*/
-qboolean Int_Parse(char **p, int *i) {
- char *token;
- token = COM_ParseExt(p, qfalse);
+qboolean Int_Parse(char **p, int *i)
+{
+ char *token;
+ token = COM_ParseExt(p, qfalse);
- if (token && token[0] != 0) {
- *i = atoi(token);
- return qtrue;
- } else {
- return qfalse;
- }
+ if (token && token[0] != 0)
+ {
+ *i = atoi(token);
+ return qtrue;
+ }
+ else
+ return qfalse;
}
/*
@@ -419,25 +748,47 @@ qboolean Int_Parse(char **p, int *i) {
PC_Int_Parse
=================
*/
-qboolean PC_Int_Parse(int handle, int *i) {
- pc_token_t token;
- int negative = qfalse;
+qboolean PC_Int_Parse(int handle, int *i)
+{
+ pc_token_t token;
+ int negative = qfalse;
- if (!trap_Parse_ReadToken(handle, &token))
- return qfalse;
- if (token.string[0] == '-') {
if (!trap_Parse_ReadToken(handle, &token))
- return qfalse;
- negative = qtrue;
- }
- if (token.type != TT_NUMBER) {
- PC_SourceError(handle, "expected integer but found %s\n", token.string);
- return qfalse;
- }
- *i = token.intvalue;
- if (negative)
- *i = - *i;
- return qtrue;
+ return qfalse;
+
+ if (token.string[0] == '(')
+ {
+ float f;
+
+ if (PC_Expression_Parse(handle, &f))
+ {
+ *i = (int)f;
+ return qtrue;
+ }
+ else
+ return qfalse;
+ }
+
+ if (token.string[0] == '-')
+ {
+ if (!trap_Parse_ReadToken(handle, &token))
+ return qfalse;
+
+ negative = qtrue;
+ }
+
+ if (token.type != TT_NUMBER)
+ {
+ PC_SourceError(handle, "expected integer but found %s\n", token.string);
+ return qfalse;
+ }
+
+ *i = token.intvalue;
+
+ if (negative)
+ *i = -*i;
+
+ return qtrue;
}
/*
@@ -445,17 +796,21 @@ qboolean PC_Int_Parse(int handle, int *i) {
Rect_Parse
=================
*/
-qboolean Rect_Parse(char **p, rectDef_t *r) {
- if (Float_Parse(p, &r->x)) {
- if (Float_Parse(p, &r->y)) {
- if (Float_Parse(p, &r->w)) {
- if (Float_Parse(p, &r->h)) {
- return qtrue;
+qboolean Rect_Parse(char **p, rectDef_t *r)
+{
+ if (Float_Parse(p, &r->x))
+ {
+ if (Float_Parse(p, &r->y))
+ {
+ if (Float_Parse(p, &r->w))
+ {
+ if (Float_Parse(p, &r->h))
+ return qtrue;
+ }
}
- }
}
- }
- return qfalse;
+
+ return qfalse;
}
/*
@@ -463,17 +818,21 @@ qboolean Rect_Parse(char **p, rectDef_t *r) {
PC_Rect_Parse
=================
*/
-qboolean PC_Rect_Parse(int handle, rectDef_t *r) {
- if (PC_Float_Parse(handle, &r->x)) {
- if (PC_Float_Parse(handle, &r->y)) {
- if (PC_Float_Parse(handle, &r->w)) {
- if (PC_Float_Parse(handle, &r->h)) {
- return qtrue;
+qboolean PC_Rect_Parse(int handle, rectDef_t *r)
+{
+ if (PC_Float_Parse(handle, &r->x))
+ {
+ if (PC_Float_Parse(handle, &r->y))
+ {
+ if (PC_Float_Parse(handle, &r->w))
+ {
+ if (PC_Float_Parse(handle, &r->h))
+ return qtrue;
+ }
}
- }
}
- }
- return qfalse;
+
+ return qfalse;
}
/*
@@ -481,15 +840,19 @@ qboolean PC_Rect_Parse(int handle, rectDef_t *r) {
String_Parse
=================
*/
-qboolean String_Parse(char **p, const char **out) {
- char *token;
+qboolean String_Parse(char **p, const char **out)
+{
+ char *token;
- token = COM_ParseExt(p, qfalse);
- if (token && token[0] != 0) {
- *(out) = String_Alloc(token);
- return qtrue;
- }
- return qfalse;
+ token = COM_ParseExt(p, qfalse);
+
+ if (token && token[0] != 0)
+ {
+ *(out) = String_Alloc(token);
+ return qtrue;
+ }
+
+ return qfalse;
}
/*
@@ -497,13 +860,15 @@ qboolean String_Parse(char **p, const char **out) {
PC_String_Parse
=================
*/
-qboolean PC_String_Parse(int handle, const char **out) {
- pc_token_t token;
+qboolean PC_String_Parse(int handle, const char **out)
+{
+ pc_token_t token;
- if (!trap_Parse_ReadToken(handle, &token))
- return qfalse;
+ if (!trap_Parse_ReadToken(handle, &token))
+ return qfalse;
+
+ *(out) = String_Alloc(token.string);
- *(out) = String_Alloc(token.string);
return qtrue;
}
@@ -512,37 +877,41 @@ qboolean PC_String_Parse(int handle, const char **out) {
PC_Script_Parse
=================
*/
-qboolean PC_Script_Parse(int handle, const char **out) {
- char script[1024];
- pc_token_t token;
-
- memset(script, 0, sizeof(script));
- // scripts start with { and have ; separated command lists.. commands are command, arg..
- // basically we want everything between the { } as it will be interpreted at run time
+qboolean PC_Script_Parse(int handle, const char **out)
+{
+ char script[1024];
+ pc_token_t token;
- if (!trap_Parse_ReadToken(handle, &token))
- return qfalse;
- if (Q_stricmp(token.string, "{") != 0) {
- return qfalse;
- }
+ memset(script, 0, sizeof(script));
+ // scripts start with { and have ; separated command lists.. commands are command, arg..
+ // basically we want everything between the { } as it will be interpreted at run time
- while ( 1 ) {
if (!trap_Parse_ReadToken(handle, &token))
- return qfalse;
+ return qfalse;
- if (Q_stricmp(token.string, "}") == 0) {
- *out = String_Alloc(script);
- return qtrue;
- }
+ if (Q_stricmp(token.string, "{") != 0)
+ return qfalse;
+
+ while (1)
+ {
+ if (!trap_Parse_ReadToken(handle, &token))
+ return qfalse;
- if (token.string[1] != '\0') {
- Q_strcat(script, 1024, va("\"%s\"", token.string));
- } else {
- Q_strcat(script, 1024, token.string);
+ if (Q_stricmp(token.string, "}") == 0)
+ {
+ *out = String_Alloc(script);
+ return qtrue;
+ }
+
+ if (token.string[1] != '\0')
+ Q_strcat(script, 1024, va("\"%s\"", token.string));
+ else
+ Q_strcat(script, 1024, token.string);
+
+ Q_strcat(script, 1024, " ");
}
- Q_strcat(script, 1024, " ");
- }
- return qfalse; // bk001105 - LCC missing return value
+
+ return qfalse;
}
// display, window, menu, item code
@@ -555,4123 +924,5279 @@ Init_Display
Initializes the display with a structure to all the drawing routines
==================
*/
-void Init_Display( displayContextDef_t *dc )
-{
- DC = dc;
-}
-
-
+void Init_Display(displayContextDef_t *dc) { DC = dc; }
// type and style painting
-void GradientBar_Paint( rectDef_t *rect, vec4_t color )
+void GradientBar_Paint(rectDef_t *rect, vec4_t color)
{
- // gradient bar takes two paints
- DC->setColor( color );
- DC->drawHandlePic( rect->x, rect->y, rect->w, rect->h, DC->Assets.gradientBar );
- DC->setColor( NULL );
+ // gradient bar takes two paints
+ DC->setColor(color);
+ DC->drawHandlePic(rect->x, rect->y, rect->w, rect->h, DC->Assets.gradientBar);
+ DC->setColor(NULL);
}
-
/*
==================
Window_Init
-Initializes a window structure ( windowDef_t ) with defaults
-
+Initializes a window structure ( Window ) with defaults
==================
*/
-void Window_Init(Window *w) {
- memset(w, 0, sizeof(windowDef_t));
- w->borderSize = 1;
- w->foreColor[0] = w->foreColor[1] = w->foreColor[2] = w->foreColor[3] = 1.0;
- w->cinematic = -1;
-}
-
-void Fade(int *flags, float *f, float clamp, int *nextTime, int offsetTime, qboolean bFlags, float fadeAmount) {
- if (*flags & (WINDOW_FADINGOUT | WINDOW_FADINGIN)) {
- if (DC->realTime > *nextTime) {
- *nextTime = DC->realTime + offsetTime;
- if (*flags & WINDOW_FADINGOUT) {
- *f -= fadeAmount;
- if (bFlags && *f <= 0.0) {
- *flags &= ~(WINDOW_FADINGOUT | WINDOW_VISIBLE);
- }
- } else {
- *f += fadeAmount;
- if (*f >= clamp) {
- *f = clamp;
- if (bFlags) {
- *flags &= ~WINDOW_FADINGIN;
- }
- }
- }
- }
- }
-}
-
-
-
-void Window_Paint(Window *w, float fadeAmount, float fadeClamp, float fadeCycle) {
- //float bordersize = 0;
- vec4_t color;
- rectDef_t fillRect = w->rect;
-
-
- if (debugMode) {
- color[0] = color[1] = color[2] = color[3] = 1;
- DC->drawRect(w->rect.x, w->rect.y, w->rect.w, w->rect.h, 1, color);
- }
-
- if (w == NULL || (w->style == 0 && w->border == 0)) {
- return;
- }
-
- if (w->border != 0) {
- fillRect.x += w->borderSize;
- fillRect.y += w->borderSize;
- fillRect.w -= w->borderSize + 1;
- fillRect.h -= w->borderSize + 1;
- }
-
- if (w->style == WINDOW_STYLE_FILLED) {
- // box, but possible a shader that needs filled
- if (w->background) {
- Fade(&w->flags, &w->backColor[3], fadeClamp, &w->nextTime, fadeCycle, qtrue, fadeAmount);
- DC->setColor(w->backColor);
- DC->drawHandlePic(fillRect.x, fillRect.y, fillRect.w, fillRect.h, w->background);
- DC->setColor(NULL);
- } else {
- DC->fillRect(fillRect.x, fillRect.y, fillRect.w, fillRect.h, w->backColor);
- }
- } else if (w->style == WINDOW_STYLE_GRADIENT) {
- GradientBar_Paint(&fillRect, w->backColor);
- // gradient bar
- } else if (w->style == WINDOW_STYLE_SHADER) {
- if (w->flags & WINDOW_FORECOLORSET) {
- DC->setColor(w->foreColor);
- }
- DC->drawHandlePic(fillRect.x, fillRect.y, fillRect.w, fillRect.h, w->background);
- DC->setColor(NULL);
- } else if (w->style == WINDOW_STYLE_TEAMCOLOR) {
- if (DC->getTeamColor) {
- DC->getTeamColor(&color);
- DC->fillRect(fillRect.x, fillRect.y, fillRect.w, fillRect.h, color);
- }
- } else if (w->style == WINDOW_STYLE_CINEMATIC) {
- if (w->cinematic == -1) {
- w->cinematic = DC->playCinematic(w->cinematicName, fillRect.x, fillRect.y, fillRect.w, fillRect.h);
- if (w->cinematic == -1) {
- w->cinematic = -2;
- }
- }
- if (w->cinematic >= 0) {
- DC->runCinematicFrame(w->cinematic);
- DC->drawCinematic(w->cinematic, fillRect.x, fillRect.y, fillRect.w, fillRect.h);
- }
- }
-
- if (w->border == WINDOW_BORDER_FULL) {
- // full
- // HACK HACK HACK
- if (w->style == WINDOW_STYLE_TEAMCOLOR) {
- if (color[0] > 0) {
- // red
- color[0] = 1;
- color[1] = color[2] = .5;
-
- } else {
- color[2] = 1;
- color[0] = color[1] = .5;
- }
- color[3] = 1;
- DC->drawRect(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->borderSize, color);
- } else {
- DC->drawRect(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->borderSize, w->borderColor);
- }
- } else if (w->border == WINDOW_BORDER_HORZ) {
- // top/bottom
- DC->setColor(w->borderColor);
- DC->drawTopBottom(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->borderSize);
- DC->setColor( NULL );
- } else if (w->border == WINDOW_BORDER_VERT) {
- // left right
- DC->setColor(w->borderColor);
- DC->drawSides(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->borderSize);
- DC->setColor( NULL );
- } else if (w->border == WINDOW_BORDER_KCGRADIENT) {
- // this is just two gradient bars along each horz edge
- rectDef_t r = w->rect;
- r.h = w->borderSize;
- GradientBar_Paint(&r, w->borderColor);
- r.y = w->rect.y + w->rect.h - 1;
- GradientBar_Paint(&r, w->borderColor);
- }
-
-}
-
-
-void Item_SetScreenCoords(itemDef_t *item, float x, float y) {
-
- if (item == NULL) {
- return;
- }
-
- if (item->window.border != 0) {
- x += item->window.borderSize;
- y += item->window.borderSize;
- }
-
- item->window.rect.x = x + item->window.rectClient.x;
- item->window.rect.y = y + item->window.rectClient.y;
- item->window.rect.w = item->window.rectClient.w;
- item->window.rect.h = item->window.rectClient.h;
-
- // force the text rects to recompute
- item->textRect.w = 0;
- item->textRect.h = 0;
+void Window_Init(Window *w)
+{
+ memset(w, 0, sizeof(Window));
+ w->borderSize = 1;
+ w->foreColor[0] = w->foreColor[1] = w->foreColor[2] = w->foreColor[3] = 1.0;
+ w->cinematic = -1;
}
-// FIXME: consolidate this with nearby stuff
-void Item_UpdatePosition(itemDef_t *item) {
- float x, y;
- menuDef_t *menu;
+void Fade(int *flags, float *f, float clamp, int *nextTime, int offsetTime, qboolean bFlags, float fadeAmount)
+{
+ if (*flags & (WINDOW_FADINGOUT | WINDOW_FADINGIN))
+ {
+ if (DC->realTime > *nextTime)
+ {
+ *nextTime = DC->realTime + offsetTime;
- if (item == NULL || item->parent == NULL) {
- return;
- }
+ if (*flags & WINDOW_FADINGOUT)
+ {
+ *f -= fadeAmount;
- menu = item->parent;
+ if (bFlags && *f <= 0.0)
+ *flags &= ~(WINDOW_FADINGOUT | WINDOW_VISIBLE);
+ }
+ else
+ {
+ *f += fadeAmount;
- x = menu->window.rect.x;
- y = menu->window.rect.y;
+ if (*f >= clamp)
+ {
+ *f = clamp;
- if (menu->window.border != 0) {
- x += menu->window.borderSize;
- y += menu->window.borderSize;
- }
+ if (bFlags)
+ *flags &= ~WINDOW_FADINGIN;
+ }
+ }
+ }
+ }
+}
- Item_SetScreenCoords(item, x, y);
+static void Window_Paint(Window *w, float fadeAmount, float fadeClamp, float fadeCycle)
+{
+ vec4_t color;
+ rectDef_t fillRect = w->rect;
-}
+ if (DC->getCVarValue("ui_developer"))
+ {
+ color[0] = color[1] = color[2] = color[3] = 1;
+ DC->drawRect(w->rect.x, w->rect.y, w->rect.w, w->rect.h, 1, color);
+ }
-// menus
-void Menu_UpdatePosition(menuDef_t *menu) {
- int i;
- float x, y;
-
- if (menu == NULL) {
- return;
- }
-
- x = menu->window.rect.x;
- y = menu->window.rect.y;
- if (menu->window.border != 0) {
- x += menu->window.borderSize;
- y += menu->window.borderSize;
- }
-
- for (i = 0; i < menu->itemCount; i++) {
- Item_SetScreenCoords(menu->items[i], x, y);
- }
-}
-
-void Menu_PostParse(menuDef_t *menu) {
- if (menu == NULL) {
- return;
- }
- if (menu->fullScreen) {
- menu->window.rect.x = 0;
- menu->window.rect.y = 0;
- menu->window.rect.w = 640;
- menu->window.rect.h = 480;
- }
- Menu_UpdatePosition(menu);
-}
-
-itemDef_t *Menu_ClearFocus(menuDef_t *menu) {
- int i;
- itemDef_t *ret = NULL;
-
- if (menu == NULL) {
- return NULL;
- }
+ if (w == NULL || (w->style == 0 && w->border == 0))
+ return;
- for (i = 0; i < menu->itemCount; i++) {
- if (menu->items[i]->window.flags & WINDOW_HASFOCUS) {
- ret = menu->items[i];
+ if (w->border != 0)
+ {
+ fillRect.x += w->borderSize;
+ fillRect.y += w->borderSize;
+ fillRect.w -= w->borderSize + 1;
+ fillRect.h -= w->borderSize + 1;
}
- menu->items[i]->window.flags &= ~WINDOW_HASFOCUS;
- if (menu->items[i]->leaveFocus) {
- Item_RunScript(menu->items[i], menu->items[i]->leaveFocus);
+
+ if (w->style == WINDOW_STYLE_FILLED)
+ {
+ // box, but possible a shader that needs filled
+
+ if (w->background)
+ {
+ Fade(&w->flags, &w->backColor[3], fadeClamp, &w->nextTime, fadeCycle, qtrue, fadeAmount);
+ DC->setColor(w->backColor);
+ DC->drawHandlePic(fillRect.x, fillRect.y, fillRect.w, fillRect.h, w->background);
+ DC->setColor(NULL);
+ }
+ else
+ DC->fillRect(fillRect.x, fillRect.y, fillRect.w, fillRect.h, w->backColor);
}
- }
+ else if (w->style == WINDOW_STYLE_GRADIENT)
+ {
+ GradientBar_Paint(&fillRect, w->backColor);
+ // gradient bar
+ }
+ else if (w->style == WINDOW_STYLE_SHADER)
+ {
+ if (w->flags & WINDOW_FORECOLORSET)
+ DC->setColor(w->foreColor);
+
+ DC->drawHandlePic(fillRect.x, fillRect.y, fillRect.w, fillRect.h, w->background);
+ DC->setColor(NULL);
+ }
+ else if (w->style == WINDOW_STYLE_CINEMATIC)
+ {
+ if (w->cinematic == -1)
+ {
+ w->cinematic = DC->playCinematic(w->cinematicName, fillRect.x, fillRect.y, fillRect.w, fillRect.h);
- return ret;
+ if (w->cinematic == -1)
+ w->cinematic = -2;
+ }
+
+ if (w->cinematic >= 0)
+ {
+ DC->runCinematicFrame(w->cinematic);
+ DC->drawCinematic(w->cinematic, fillRect.x, fillRect.y, fillRect.w, fillRect.h);
+ }
+ }
}
-qboolean IsVisible(int flags) {
- return (flags & WINDOW_VISIBLE && !(flags & WINDOW_FADINGOUT));
+static void Border_Paint(Window *w)
+{
+ if (w == NULL || (w->style == 0 && w->border == 0))
+ return;
+
+ if (w->border == WINDOW_BORDER_FULL)
+ {
+ // full
+ DC->drawRect(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->borderSize, w->borderColor);
+ }
+ else if (w->border == WINDOW_BORDER_HORZ)
+ {
+ // top/bottom
+ DC->setColor(w->borderColor);
+ DC->drawTopBottom(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->borderSize);
+ DC->setColor(NULL);
+ }
+ else if (w->border == WINDOW_BORDER_VERT)
+ {
+ // left right
+ DC->setColor(w->borderColor);
+ DC->drawSides(w->rect.x, w->rect.y, w->rect.w, w->rect.h, w->borderSize);
+ DC->setColor(NULL);
+ }
+ else if (w->border == WINDOW_BORDER_KCGRADIENT)
+ {
+ // this is just two gradient bars along each horz edge
+ rectDef_t r = w->rect;
+ r.h = w->borderSize;
+ GradientBar_Paint(&r, w->borderColor);
+ r.y = w->rect.y + w->rect.h - 1;
+ GradientBar_Paint(&r, w->borderColor);
+ }
}
-qboolean Rect_ContainsPoint(rectDef_t *rect, float x, float y) {
- if (rect) {
- if (x > rect->x && x < rect->x + rect->w && y > rect->y && y < rect->y + rect->h) {
- return qtrue;
+void Item_SetScreenCoords(itemDef_t *item, float x, float y)
+{
+ if (item == NULL)
+ return;
+
+ if (item->window.border != 0)
+ {
+ x += item->window.borderSize;
+ y += item->window.borderSize;
}
- }
- return qfalse;
+
+ item->window.rect.x = x + item->window.rectClient.x;
+ item->window.rect.y = y + item->window.rectClient.y;
+ item->window.rect.w = item->window.rectClient.w;
+ item->window.rect.h = item->window.rectClient.h;
+
+ // force the text rects to recompute
+ item->textRect.w = 0;
+ item->textRect.h = 0;
}
-int Menu_ItemsMatchingGroup(menuDef_t *menu, const char *name) {
- int i;
- int count = 0;
- for (i = 0; i < menu->itemCount; i++) {
- if (Q_stricmp(menu->items[i]->window.name, name) == 0 || (menu->items[i]->window.group && Q_stricmp(menu->items[i]->window.group, name) == 0)) {
- count++;
+// FIXME: consolidate this with nearby stuff
+void Item_UpdatePosition(itemDef_t *item)
+{
+ float x, y;
+ menuDef_t *menu;
+
+ if (item == NULL || item->parent == NULL)
+ return;
+
+ menu = item->parent;
+
+ x = menu->window.rect.x;
+ y = menu->window.rect.y;
+
+ if (menu->window.border != 0)
+ {
+ x += menu->window.borderSize;
+ y += menu->window.borderSize;
}
- }
- return count;
+
+ Item_SetScreenCoords(item, x, y);
}
-itemDef_t *Menu_GetMatchingItemByNumber(menuDef_t *menu, int index, const char *name) {
- int i;
- int count = 0;
- for (i = 0; i < menu->itemCount; i++) {
- if (Q_stricmp(menu->items[i]->window.name, name) == 0 || (menu->items[i]->window.group && Q_stricmp(menu->items[i]->window.group, name) == 0)) {
- if (count == index) {
- return menu->items[i];
- }
- count++;
+// menus
+void Menu_UpdatePosition(menuDef_t *menu)
+{
+ int i;
+ float x, y;
+
+ if (menu == NULL)
+ return;
+
+ x = menu->window.rect.x;
+ y = menu->window.rect.y;
+
+ if (menu->window.border != 0)
+ {
+ x += menu->window.borderSize;
+ y += menu->window.borderSize;
}
- }
- return NULL;
+
+ for (i = 0; i < menu->itemCount; i++)
+ Item_SetScreenCoords(menu->items[i], x, y);
}
+static void Menu_AspectiseRect(int bias, Rectangle *rect)
+{
+ switch (bias)
+ {
+ case ALIGN_LEFT:
+ rect->x *= DC->aspectScale;
+ rect->w *= DC->aspectScale;
+ break;
+ case ALIGN_CENTER:
+ rect->x = (rect->x * DC->aspectScale) + (320.0f - (320.0f * DC->aspectScale));
+ rect->w *= DC->aspectScale;
+ break;
-void Script_SetColor(itemDef_t *item, char **args) {
- const char *name;
- int i;
- float f;
- vec4_t *out;
- // expecting type of color to set and 4 args for the color
- if (String_Parse(args, &name)) {
- out = NULL;
- if (Q_stricmp(name, "backcolor") == 0) {
- out = &item->window.backColor;
- item->window.flags |= WINDOW_BACKCOLORSET;
- } else if (Q_stricmp(name, "forecolor") == 0) {
- out = &item->window.foreColor;
- item->window.flags |= WINDOW_FORECOLORSET;
- } else if (Q_stricmp(name, "bordercolor") == 0) {
- out = &item->window.borderColor;
- }
+ case ALIGN_RIGHT:
+ rect->x = 640.0f - ((640.0f - rect->x) * DC->aspectScale);
+ rect->w *= DC->aspectScale;
+ break;
- if (out) {
- for (i = 0; i < 4; i++) {
- if (!Float_Parse(args, &f)) {
- return;
- }
- (*out)[i] = f;
+ default:
+
+ case ASPECT_NONE:
+ break;
+ }
+}
+
+void Menu_AspectCompensate(menuDef_t *menu)
+{
+ int i;
+
+ if (menu->window.aspectBias != ASPECT_NONE)
+ {
+ Menu_AspectiseRect(menu->window.aspectBias, &menu->window.rect);
+
+ for (i = 0; i < menu->itemCount; i++)
+ {
+ menu->items[i]->window.rectClient.x *= DC->aspectScale;
+ menu->items[i]->window.rectClient.w *= DC->aspectScale;
+ menu->items[i]->textalignx *= DC->aspectScale;
}
- }
- }
+ }
+ else
+ {
+ for (i = 0; i < menu->itemCount; i++)
+ {
+ Menu_AspectiseRect(menu->items[i]->window.aspectBias, &menu->items[i]->window.rectClient);
+
+ if (menu->items[i]->window.aspectBias != ASPECT_NONE)
+ menu->items[i]->textalignx *= DC->aspectScale;
+ }
+ }
}
-void Script_SetAsset(itemDef_t *item, char **args) {
- const char *name;
- // expecting name to set asset to
- if (String_Parse(args, &name)) {
- // check for a model
- if (item->type == ITEM_TYPE_MODEL) {
+void Menu_PostParse(menuDef_t *menu)
+{
+ int i, j;
+
+ if (menu == NULL)
+ return;
+
+ if (menu->fullScreen)
+ {
+ menu->window.rect.x = 0;
+ menu->window.rect.y = 0;
+ menu->window.rect.w = 640;
+ menu->window.rect.h = 480;
+ }
+
+ Menu_AspectCompensate(menu);
+ Menu_UpdatePosition(menu);
+
+ // Push lists to the end of the array as they can potentially be drawn on top
+ // of other elements
+ for (i = 0; i < menu->itemCount; i++)
+ {
+ itemDef_t *item = menu->items[i];
+
+ if (Item_IsListBox(item))
+ {
+ for (j = i; j < menu->itemCount - 1; j++)
+ menu->items[j] = menu->items[j + 1];
+
+ menu->items[j] = item;
+ }
}
- }
}
-void Script_SetBackground(itemDef_t *item, char **args) {
- const char *name;
- // expecting name to set asset to
- if (String_Parse(args, &name)) {
- item->window.background = DC->registerShaderNoMip(name);
- }
+itemDef_t *Menu_ClearFocus(menuDef_t *menu)
+{
+ int i;
+ itemDef_t *ret = NULL;
+
+ if (menu == NULL)
+ return NULL;
+
+ for (i = 0; i < menu->itemCount; i++)
+ {
+ if (menu->items[i]->window.flags & WINDOW_HASFOCUS)
+ ret = menu->items[i];
+
+ menu->items[i]->window.flags &= ~WINDOW_HASFOCUS;
+
+ if (menu->items[i]->leaveFocus)
+ Item_RunScript(menu->items[i], menu->items[i]->leaveFocus);
+ }
+
+ return ret;
}
+qboolean IsVisible(int flags) { return (flags & WINDOW_VISIBLE && !(flags & WINDOW_FADINGOUT)); }
+qboolean Rect_ContainsPoint(rectDef_t *rect, float x, float y)
+{
+ if (rect)
+ {
+ if (x > rect->x && x < rect->x + rect->w && y > rect->y && y < rect->y + rect->h)
+ return qtrue;
+ }
+ return qfalse;
+}
-itemDef_t *Menu_FindItemByName(menuDef_t *menu, const char *p) {
- int i;
- if (menu == NULL || p == NULL) {
- return NULL;
- }
+int Menu_ItemsMatchingGroup(menuDef_t *menu, const char *name)
+{
+ int i;
+ int count = 0;
- for (i = 0; i < menu->itemCount; i++) {
- if (Q_stricmp(p, menu->items[i]->window.name) == 0) {
- return menu->items[i];
+ for (i = 0; i < menu->itemCount; i++)
+ {
+ if (Q_stricmp(menu->items[i]->window.name, name) == 0 ||
+ (menu->items[i]->window.group && Q_stricmp(menu->items[i]->window.group, name) == 0))
+ {
+ count++;
+ }
}
- }
- return NULL;
+ return count;
}
-void Script_SetTeamColor(itemDef_t *item, char **args) {
- if (DC->getTeamColor) {
+itemDef_t *Menu_GetMatchingItemByNumber(menuDef_t *menu, int index, const char *name)
+{
int i;
- vec4_t color;
- DC->getTeamColor(&color);
- for (i = 0; i < 4; i++) {
- item->window.backColor[i] = color[i];
- }
- }
-}
-
-void Script_SetItemColor(itemDef_t *item, char **args) {
- const char *itemname;
- const char *name;
- vec4_t color;
- int i;
- vec4_t *out;
- // expecting type of color to set and 4 args for the color
- if (String_Parse(args, &itemname) && String_Parse(args, &name)) {
- itemDef_t *item2;
- int j;
- int count = Menu_ItemsMatchingGroup(item->parent, itemname);
+ int count = 0;
+
+ for (i = 0; i < menu->itemCount; i++)
+ {
+ if (Q_stricmp(menu->items[i]->window.name, name) == 0 ||
+ (menu->items[i]->window.group && Q_stricmp(menu->items[i]->window.group, name) == 0))
+ {
+ if (count == index)
+ return menu->items[i];
- if (!Color_Parse(args, &color)) {
- return;
+ count++;
+ }
}
- for (j = 0; j < count; j++) {
- item2 = Menu_GetMatchingItemByNumber(item->parent, j, itemname);
- if (item2 != NULL) {
+ return NULL;
+}
+
+void Script_SetColor(itemDef_t *item, char **args)
+{
+ const char *name;
+ int i;
+ float f;
+ vec4_t *out;
+ // expecting type of color to set and 4 args for the color
+
+ if (String_Parse(args, &name))
+ {
out = NULL;
- if (Q_stricmp(name, "backcolor") == 0) {
- out = &item2->window.backColor;
- } else if (Q_stricmp(name, "forecolor") == 0) {
- out = &item2->window.foreColor;
- item2->window.flags |= WINDOW_FORECOLORSET;
- } else if (Q_stricmp(name, "bordercolor") == 0) {
- out = &item2->window.borderColor;
+
+ if (Q_stricmp(name, "backcolor") == 0)
+ {
+ out = &item->window.backColor;
+ item->window.flags |= WINDOW_BACKCOLORSET;
+ }
+ else if (Q_stricmp(name, "forecolor") == 0)
+ {
+ out = &item->window.foreColor;
+ item->window.flags |= WINDOW_FORECOLORSET;
}
+ else if (Q_stricmp(name, "bordercolor") == 0)
+ out = &item->window.borderColor;
+
+ if (out)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ if (!Float_Parse(args, &f))
+ return;
- if (out) {
- for (i = 0; i < 4; i++) {
- (*out)[i] = color[i];
- }
+ (*out)[i] = f;
+ }
}
- }
}
- }
}
+void Script_SetAsset(itemDef_t *item, char **args)
+{
+ const char *name;
+ // expecting name to set asset to
-void Menu_ShowItemByName(menuDef_t *menu, const char *p, qboolean bShow) {
- itemDef_t *item;
- int i;
- int count = Menu_ItemsMatchingGroup(menu, p);
- for (i = 0; i < count; i++) {
- item = Menu_GetMatchingItemByNumber(menu, i, p);
- if (item != NULL) {
- if (bShow) {
- item->window.flags |= WINDOW_VISIBLE;
- } else {
- item->window.flags &= ~WINDOW_VISIBLE;
- // stop cinematics playing in the window
- if (item->window.cinematic >= 0) {
- DC->stopCinematic(item->window.cinematic);
- item->window.cinematic = -1;
+ if (String_Parse(args, &name))
+ {
+ // check for a model
+ if (item->type == ITEM_TYPE_MODEL)
+ {
}
- }
}
- }
}
-void Menu_FadeItemByName(menuDef_t *menu, const char *p, qboolean fadeOut) {
- itemDef_t *item;
- int i;
- int count = Menu_ItemsMatchingGroup(menu, p);
- for (i = 0; i < count; i++) {
- item = Menu_GetMatchingItemByNumber(menu, i, p);
- if (item != NULL) {
- if (fadeOut) {
- item->window.flags |= (WINDOW_FADINGOUT | WINDOW_VISIBLE);
- item->window.flags &= ~WINDOW_FADINGIN;
- } else {
- item->window.flags |= (WINDOW_VISIBLE | WINDOW_FADINGIN);
- item->window.flags &= ~WINDOW_FADINGOUT;
- }
+void Script_SetBackground(itemDef_t *item, char **args)
+{
+ const char *name;
+ // expecting name to set asset to
+
+ if (String_Parse(args, &name))
+ item->window.background = DC->registerShaderNoMip(name);
+}
+
+itemDef_t *Menu_FindItemByName(menuDef_t *menu, const char *p)
+{
+ int i;
+
+ if (menu == NULL || p == NULL)
+ return NULL;
+
+ for (i = 0; i < menu->itemCount; i++)
+ {
+ if (Q_stricmp(p, menu->items[i]->window.name) == 0)
+ return menu->items[i];
}
- }
+
+ return NULL;
}
-menuDef_t *Menus_FindByName(const char *p) {
- int i;
- for (i = 0; i < menuCount; i++) {
- if (Q_stricmp(Menus[i].window.name, p) == 0) {
- return &Menus[i];
+void Script_SetItemColor(itemDef_t *item, char **args)
+{
+ const char *itemname;
+ const char *name;
+ vec4_t color;
+ int i;
+ vec4_t *out;
+ // expecting type of color to set and 4 args for the color
+
+ if (String_Parse(args, &itemname) && String_Parse(args, &name))
+ {
+ itemDef_t *item2;
+ int j;
+ int count = Menu_ItemsMatchingGroup(item->parent, itemname);
+
+ if (!Color_Parse(args, &color))
+ return;
+
+ for (j = 0; j < count; j++)
+ {
+ item2 = Menu_GetMatchingItemByNumber(item->parent, j, itemname);
+
+ if (item2 != NULL)
+ {
+ out = NULL;
+
+ if (Q_stricmp(name, "backcolor") == 0)
+ out = &item2->window.backColor;
+ else if (Q_stricmp(name, "forecolor") == 0)
+ {
+ out = &item2->window.foreColor;
+ item2->window.flags |= WINDOW_FORECOLORSET;
+ }
+ else if (Q_stricmp(name, "bordercolor") == 0)
+ out = &item2->window.borderColor;
+
+ if (out)
+ {
+ for (i = 0; i < 4; i++)
+ (*out)[i] = color[i];
+ }
+ }
+ }
}
- }
- return NULL;
}
-void Menus_ShowByName(const char *p) {
- menuDef_t *menu = Menus_FindByName(p);
- if (menu) {
- Menus_Activate(menu);
- }
+void Menu_ShowItemByName(menuDef_t *menu, const char *p, qboolean bShow)
+{
+ itemDef_t *item;
+ int i;
+ int count = Menu_ItemsMatchingGroup(menu, p);
+
+ for (i = 0; i < count; i++)
+ {
+ item = Menu_GetMatchingItemByNumber(menu, i, p);
+
+ if (item != NULL)
+ {
+ if (bShow)
+ item->window.flags |= WINDOW_VISIBLE;
+ else
+ {
+ item->window.flags &= ~WINDOW_VISIBLE;
+ // stop cinematics playing in the window
+
+ if (item->window.cinematic >= 0)
+ {
+ DC->stopCinematic(item->window.cinematic);
+ item->window.cinematic = -1;
+ }
+ }
+ }
+ }
}
-void Menus_OpenByName(const char *p) {
- Menus_ActivateByName(p);
+void Menu_FadeItemByName(menuDef_t *menu, const char *p, qboolean fadeOut)
+{
+ itemDef_t *item;
+ int i;
+ int count = Menu_ItemsMatchingGroup(menu, p);
+
+ for (i = 0; i < count; i++)
+ {
+ item = Menu_GetMatchingItemByNumber(menu, i, p);
+
+ if (item != NULL)
+ {
+ if (fadeOut)
+ {
+ item->window.flags |= (WINDOW_FADINGOUT | WINDOW_VISIBLE);
+ item->window.flags &= ~WINDOW_FADINGIN;
+ }
+ else
+ {
+ item->window.flags |= (WINDOW_VISIBLE | WINDOW_FADINGIN);
+ item->window.flags &= ~WINDOW_FADINGOUT;
+ }
+ }
+ }
}
-static void Menu_RunCloseScript(menuDef_t *menu) {
- if (menu && menu->window.flags & WINDOW_VISIBLE && menu->onClose) {
- itemDef_t item;
- item.parent = menu;
- Item_RunScript(&item, menu->onClose);
- }
+menuDef_t *Menus_FindByName(const char *p)
+{
+ int i;
+
+ for (i = 0; i < menuCount; i++)
+ {
+ if (Q_stricmp(Menus[i].window.name, p) == 0)
+ return &Menus[i];
+ }
+
+ return NULL;
}
-void Menus_CloseByName(const char *p) {
- menuDef_t *menu = Menus_FindByName(p);
- if (menu != NULL) {
- Menu_RunCloseScript(menu);
- menu->window.flags &= ~(WINDOW_VISIBLE | WINDOW_HASFOCUS);
- }
+static void Menu_RunCloseScript(menuDef_t *menu)
+{
+ if (menu && menu->window.flags & WINDOW_VISIBLE && menu->onClose)
+ {
+ itemDef_t item;
+ item.parent = menu;
+ Item_RunScript(&item, menu->onClose);
+ }
}
-void Menus_CloseAll( void ) {
- int i;
- for (i = 0; i < menuCount; i++) {
- Menu_RunCloseScript(&Menus[i]);
- Menus[i].window.flags &= ~(WINDOW_HASFOCUS | WINDOW_VISIBLE);
- }
+static void Menus_Close(menuDef_t *menu)
+{
+ if (menu != NULL)
+ {
+ Menu_RunCloseScript(menu);
+ menu->window.flags &= ~(WINDOW_VISIBLE | WINDOW_HASFOCUS);
- g_editingField = qfalse;
- g_waitingForKey = qfalse;
+ if (openMenuCount > 0)
+ openMenuCount--;
+
+ if (openMenuCount > 0)
+ Menus_Activate(menuStack[openMenuCount - 1]);
+ }
}
+void Menus_CloseByName(const char *p) { Menus_Close(Menus_FindByName(p)); }
-void Script_Show(itemDef_t *item, char **args) {
- const char *name;
- if (String_Parse(args, &name)) {
- Menu_ShowItemByName(item->parent, name, qtrue);
- }
+void Menus_CloseAll(void)
+{
+ int i;
+
+ // Close any menus on the stack first
+ if (openMenuCount > 0)
+ {
+ for (i = openMenuCount; i > 0; i--)
+ Menus_Close(menuStack[i - 1]);
+
+ openMenuCount = 0;
+ }
+
+ // Close all other menus
+ for (i = 0; i < menuCount; i++)
+ Menus_Close(&Menus[i]);
+
+ g_editingField = qfalse;
+ g_waitingForKey = qfalse;
+ g_comboBoxItem = NULL;
}
-void Script_Hide(itemDef_t *item, char **args) {
- const char *name;
- if (String_Parse(args, &name)) {
- Menu_ShowItemByName(item->parent, name, qfalse);
- }
+void Script_Show(itemDef_t *item, char **args)
+{
+ const char *name;
+
+ if (String_Parse(args, &name))
+ Menu_ShowItemByName(item->parent, name, qtrue);
}
-void Script_FadeIn(itemDef_t *item, char **args) {
- const char *name;
- if (String_Parse(args, &name)) {
- Menu_FadeItemByName(item->parent, name, qfalse);
- }
+void Script_Hide(itemDef_t *item, char **args)
+{
+ const char *name;
+
+ if (String_Parse(args, &name))
+ Menu_ShowItemByName(item->parent, name, qfalse);
}
-void Script_FadeOut(itemDef_t *item, char **args) {
- const char *name;
- if (String_Parse(args, &name)) {
- Menu_FadeItemByName(item->parent, name, qtrue);
- }
+void Script_FadeIn(itemDef_t *item, char **args)
+{
+ const char *name;
+
+ if (String_Parse(args, &name))
+ Menu_FadeItemByName(item->parent, name, qfalse);
}
+void Script_FadeOut(itemDef_t *item, char **args)
+{
+ const char *name;
+ if (String_Parse(args, &name))
+ Menu_FadeItemByName(item->parent, name, qtrue);
+}
-void Script_Open(itemDef_t *item, char **args) {
- const char *name;
- if (String_Parse(args, &name)) {
- Menus_OpenByName(name);
- }
+void Script_Open(itemDef_t *item, char **args)
+{
+ const char *name;
+
+ if (String_Parse(args, &name))
+ Menus_ActivateByName(name);
}
-void Script_ConditionalOpen(itemDef_t *item, char **args) {
- const char *cvar;
- const char *name1;
- const char *name2;
- float val;
+void Script_ConditionalOpen(itemDef_t *item, char **args)
+{
+ const char *cvar;
+ const char *name1;
+ const char *name2;
+ float val;
+
+ if (String_Parse(args, &cvar) && String_Parse(args, &name1) && String_Parse(args, &name2))
+ {
+ val = DC->getCVarValue(cvar);
- if ( String_Parse(args, &cvar) && String_Parse(args, &name1) && String_Parse(args, &name2) ) {
- val = DC->getCVarValue( cvar );
- if ( val == 0.f ) {
- Menus_OpenByName(name2);
- } else {
- Menus_OpenByName(name1);
+ if (val == 0.0f)
+ Menus_ActivateByName(name2);
+ else
+ Menus_ActivateByName(name1);
}
- }
}
-void Script_Close(itemDef_t *item, char **args) {
- const char *name;
- if (String_Parse(args, &name)) {
- Menus_CloseByName(name);
- }
+void Script_Close(itemDef_t *item, char **args)
+{
+ const char *name;
+
+ (void)item;
+
+ if (String_Parse(args, &name))
+ Menus_CloseByName(name);
}
-void Menu_TransitionItemByName(menuDef_t *menu, const char *p, rectDef_t rectFrom, rectDef_t rectTo, int time, float amt) {
- itemDef_t *item;
- int i;
- int count = Menu_ItemsMatchingGroup(menu, p);
- for (i = 0; i < count; i++) {
- item = Menu_GetMatchingItemByNumber(menu, i, p);
- if (item != NULL) {
- item->window.flags |= (WINDOW_INTRANSITION | WINDOW_VISIBLE);
- item->window.offsetTime = time;
- memcpy(&item->window.rectClient, &rectFrom, sizeof(rectDef_t));
- memcpy(&item->window.rectEffects, &rectTo, sizeof(rectDef_t));
- item->window.rectEffects2.x = fabs(rectTo.x - rectFrom.x) / amt;
- item->window.rectEffects2.y = fabs(rectTo.y - rectFrom.y) / amt;
- item->window.rectEffects2.w = fabs(rectTo.w - rectFrom.w) / amt;
- item->window.rectEffects2.h = fabs(rectTo.h - rectFrom.h) / amt;
- Item_UpdatePosition(item);
+void Menu_TransitionItemByName(
+ menuDef_t *menu, const char *p, rectDef_t rectFrom, rectDef_t rectTo, int time, float amt)
+{
+ itemDef_t *item;
+ int i;
+ int count = Menu_ItemsMatchingGroup(menu, p);
+
+ for (i = 0; i < count; i++)
+ {
+ item = Menu_GetMatchingItemByNumber(menu, i, p);
+
+ if (item != NULL)
+ {
+ item->window.flags |= (WINDOW_INTRANSITION | WINDOW_VISIBLE);
+ item->window.offsetTime = time;
+ memcpy(&item->window.rectClient, &rectFrom, sizeof(rectDef_t));
+ memcpy(&item->window.rectEffects, &rectTo, sizeof(rectDef_t));
+ item->window.rectEffects2.x = fabs(rectTo.x - rectFrom.x) / amt;
+ item->window.rectEffects2.y = fabs(rectTo.y - rectFrom.y) / amt;
+ item->window.rectEffects2.w = fabs(rectTo.w - rectFrom.w) / amt;
+ item->window.rectEffects2.h = fabs(rectTo.h - rectFrom.h) / amt;
+ Item_UpdatePosition(item);
+ }
+ }
+}
+
+void Script_Transition(itemDef_t *item, char **args)
+{
+ const char *name;
+ rectDef_t rectFrom, rectTo;
+ int time;
+ float amt;
+
+ if (String_Parse(args, &name))
+ {
+ if (Rect_Parse(args, &rectFrom) && Rect_Parse(args, &rectTo) && Int_Parse(args, &time) &&
+ Float_Parse(args, &amt))
+ {
+ Menu_TransitionItemByName(item->parent, name, rectFrom, rectTo, time, amt);
+ }
}
- }
}
+void Menu_OrbitItemByName(menuDef_t *menu, const char *p, float x, float y, float cx, float cy, int time)
+{
+ itemDef_t *item;
+ int i;
+ int count = Menu_ItemsMatchingGroup(menu, p);
-void Script_Transition(itemDef_t *item, char **args) {
- const char *name;
- rectDef_t rectFrom, rectTo;
- int time;
- float amt;
+ for (i = 0; i < count; i++)
+ {
+ item = Menu_GetMatchingItemByNumber(menu, i, p);
- if (String_Parse(args, &name)) {
- if ( Rect_Parse(args, &rectFrom) && Rect_Parse(args, &rectTo) && Int_Parse(args, &time) && Float_Parse(args, &amt)) {
- Menu_TransitionItemByName(item->parent, name, rectFrom, rectTo, time, amt);
+ if (item != NULL)
+ {
+ item->window.flags |= (WINDOW_ORBITING | WINDOW_VISIBLE);
+ item->window.offsetTime = time;
+ item->window.rectEffects.x = cx;
+ item->window.rectEffects.y = cy;
+ item->window.rectClient.x = x;
+ item->window.rectClient.y = y;
+ Item_UpdatePosition(item);
+ }
}
- }
}
+void Script_Orbit(itemDef_t *item, char **args)
+{
+ const char *name;
+ float cx, cy, x, y;
+ int time;
-void Menu_OrbitItemByName(menuDef_t *menu, const char *p, float x, float y, float cx, float cy, int time) {
- itemDef_t *item;
- int i;
- int count = Menu_ItemsMatchingGroup(menu, p);
- for (i = 0; i < count; i++) {
- item = Menu_GetMatchingItemByNumber(menu, i, p);
- if (item != NULL) {
- item->window.flags |= (WINDOW_ORBITING | WINDOW_VISIBLE);
- item->window.offsetTime = time;
- item->window.rectEffects.x = cx;
- item->window.rectEffects.y = cy;
- item->window.rectClient.x = x;
- item->window.rectClient.y = y;
- Item_UpdatePosition(item);
+ if (String_Parse(args, &name))
+ {
+ if (Float_Parse(args, &x) && Float_Parse(args, &y) && Float_Parse(args, &cx) && Float_Parse(args, &cy) &&
+ Int_Parse(args, &time))
+ {
+ Menu_OrbitItemByName(item->parent, name, x, y, cx, cy, time);
+ }
}
- }
}
+void Script_SetFocus(itemDef_t *item, char **args)
+{
+ const char *name;
+ itemDef_t *focusItem;
+
+ if (String_Parse(args, &name))
+ {
+ focusItem = Menu_FindItemByName(item->parent, name);
+
+ if (focusItem && !(focusItem->window.flags & WINDOW_DECORATION))
+ {
+ Menu_ClearFocus(item->parent);
+ focusItem->window.flags |= WINDOW_HASFOCUS;
-void Script_Orbit(itemDef_t *item, char **args) {
- const char *name;
- float cx, cy, x, y;
- int time;
+ if (focusItem->onFocus)
+ Item_RunScript(focusItem, focusItem->onFocus);
- if (String_Parse(args, &name)) {
- if ( Float_Parse(args, &x) && Float_Parse(args, &y) && Float_Parse(args, &cx) && Float_Parse(args, &cy) && Int_Parse(args, &time) ) {
- Menu_OrbitItemByName(item->parent, name, x, y, cx, cy, time);
+ // Edit fields get activated too
+ if (Item_IsEditField(focusItem))
+ {
+ g_editingField = qtrue;
+ g_editItem = focusItem;
+ }
+
+ if (DC->Assets.itemFocusSound)
+ DC->startLocalSound(DC->Assets.itemFocusSound, CHAN_LOCAL_SOUND);
+ }
}
- }
}
+void Script_Reset(itemDef_t *item, char **args)
+{
+ const char *name;
+ itemDef_t *resetItem;
+ if (String_Parse(args, &name))
+ {
+ resetItem = Menu_FindItemByName(item->parent, name);
-void Script_SetFocus(itemDef_t *item, char **args) {
- const char *name;
- itemDef_t *focusItem;
-
- if (String_Parse(args, &name)) {
- focusItem = Menu_FindItemByName(item->parent, name);
- if (focusItem && !(focusItem->window.flags & WINDOW_DECORATION)) {
- Menu_ClearFocus(item->parent);
- focusItem->window.flags |= WINDOW_HASFOCUS;
- if (focusItem->onFocus) {
- Item_RunScript(focusItem, focusItem->onFocus);
- }
- if (focusItem->type == ITEM_TYPE_EDITFIELD || focusItem->type == ITEM_TYPE_SAYFIELD || focusItem->type == ITEM_TYPE_NUMERICFIELD) {
- focusItem->cursorPos = 0;
- g_editingField = qtrue;
- g_editItem = focusItem;
- if (focusItem->type == ITEM_TYPE_SAYFIELD) {
- DC->setOverstrikeMode(qfalse);
+ if (resetItem)
+ {
+ if (Item_IsListBox(resetItem))
+ {
+ resetItem->cursorPos = DC->feederInitialise(resetItem->feederID);
+ Item_ListBox_SetStartPos(resetItem, 0);
+ DC->feederSelection(resetItem->feederID, resetItem->cursorPos);
+ }
}
- }
- if (DC->Assets.itemFocusSound) {
- DC->startLocalSound( DC->Assets.itemFocusSound, CHAN_LOCAL_SOUND );
- }
}
- }
-}
-
-void Script_SetPlayerModel(itemDef_t *item, char **args) {
- const char *name;
- if (String_Parse(args, &name)) {
- DC->setCVar("team_model", name);
- }
-}
-
-void Script_SetPlayerHead(itemDef_t *item, char **args) {
- const char *name;
- if (String_Parse(args, &name)) {
- DC->setCVar("team_headmodel", name);
- }
}
-void Script_SetCvar(itemDef_t *item, char **args) {
- const char *cvar, *val;
- if (String_Parse(args, &cvar) && String_Parse(args, &val)) {
- DC->setCVar(cvar, val);
- }
+void Script_SetPlayerModel(itemDef_t *item, char **args)
+{
+ const char *name;
+ (void)item;
+
+ if (String_Parse(args, &name))
+ DC->setCVar("model", name);
}
-void Script_Exec(itemDef_t *item, char **args) {
- const char *val;
- if (String_Parse(args, &val)) {
- DC->executeText(EXEC_APPEND, va("%s ; ", val));
- }
+void Script_SetPlayerHead(itemDef_t *item, char **args)
+{
+ const char *name;
+
+ (void)item;
+
+ if (String_Parse(args, &name))
+ DC->setCVar("headmodel", name);
}
-void Script_Play(itemDef_t *item, char **args) {
- const char *val;
- if (String_Parse(args, &val)) {
- DC->startLocalSound(DC->registerSound(val, qfalse), CHAN_LOCAL_SOUND);
- }
+void Script_SetCvar(itemDef_t *item, char **args)
+{
+ const char *cvar, *val;
+
+ (void)item;
+
+ if (String_Parse(args, &cvar) && String_Parse(args, &val))
+ DC->setCVar(cvar, val);
}
-void Script_playLooped(itemDef_t *item, char **args) {
- const char *val;
- if (String_Parse(args, &val)) {
- DC->stopBackgroundTrack();
- DC->startBackgroundTrack(val, val);
- }
-}
-
-
-commandDef_t commandList[] =
+void Script_Exec(itemDef_t *item, char **args)
{
- {"fadein", &Script_FadeIn}, // group/name
- {"fadeout", &Script_FadeOut}, // group/name
- {"show", &Script_Show}, // group/name
- {"hide", &Script_Hide}, // group/name
- {"setcolor", &Script_SetColor}, // works on this
- {"open", &Script_Open}, // menu
- {"conditionalopen", &Script_ConditionalOpen}, // menu
- {"close", &Script_Close}, // menu
- {"setasset", &Script_SetAsset}, // works on this
- {"setbackground", &Script_SetBackground}, // works on this
- {"setitemcolor", &Script_SetItemColor}, // group/name
- {"setteamcolor", &Script_SetTeamColor}, // sets this background color to team color
- {"setfocus", &Script_SetFocus}, // sets this background color to team color
- {"setplayermodel", &Script_SetPlayerModel}, // sets this background color to team color
- {"setplayerhead", &Script_SetPlayerHead}, // sets this background color to team color
- {"transition", &Script_Transition}, // group/name
- {"setcvar", &Script_SetCvar}, // group/name
- {"exec", &Script_Exec}, // group/name
- {"play", &Script_Play}, // group/name
- {"playlooped", &Script_playLooped}, // group/name
- {"orbit", &Script_Orbit} // group/name
-};
+ const char *val;
-int scriptCommandCount = sizeof(commandList) / sizeof(commandDef_t);
-
-
-void Item_RunScript(itemDef_t *item, const char *s) {
- char script[1024], *p;
- int i;
- qboolean bRan;
- memset(script, 0, sizeof(script));
- if (item && s && s[0]) {
- Q_strcat(script, 1024, s);
- p = script;
- while (1) {
- const char *command;
- // expect command then arguments, ; ends command, NULL ends script
- if (!String_Parse(&p, &command)) {
- return;
- }
+ (void)item;
- if (command[0] == ';' && command[1] == '\0') {
- continue;
- }
+ if (String_Parse(args, &val))
+ DC->executeText(EXEC_APPEND, va("%s\n", val));
+}
- bRan = qfalse;
- for (i = 0; i < scriptCommandCount; i++) {
- if (Q_stricmp(command, commandList[i].name) == 0) {
- (commandList[i].handler(item, &p));
- bRan = qtrue;
- break;
- }
- }
- // not in our auto list, pass to handler
- if (!bRan) {
- DC->runScript(&p);
- }
+void Script_Play(itemDef_t *item, char **args)
+{
+ const char *val;
+
+ (void)item;
+
+ if (String_Parse(args, &val))
+ DC->startLocalSound(DC->registerSound(val, qfalse), CHAN_LOCAL_SOUND);
+}
+
+void Script_playLooped(itemDef_t *item, char **args)
+{
+ const char *val;
+
+ (void)item;
+
+ if (String_Parse(args, &val))
+ {
+ DC->stopBackgroundTrack();
+ DC->startBackgroundTrack(val, val);
}
- }
}
+static ID_INLINE float UI_EmoticonHeight(fontInfo_t *font, float scale)
+{
+ return font->glyphs[(int)'['].height * scale * font->glyphScale;
+}
-qboolean Item_EnableShowViaCvar(itemDef_t *item, int flag) {
- char script[1024], *p;
- memset(script, 0, sizeof(script));
- if (item && item->enableCvar && *item->enableCvar && item->cvarTest && *item->cvarTest) {
- char buff[1024];
- DC->getCVarString(item->cvarTest, buff, sizeof(buff));
-
- Q_strcat(script, 1024, item->enableCvar);
- p = script;
- while (1) {
- const char *val;
- // expect value then ; or NULL, NULL ends list
- if (!String_Parse(&p, &val)) {
- return (item->cvarFlags & flag) ? qfalse : qtrue;
- }
+static ID_INLINE float UI_EmoticonWidth(fontInfo_t *font, float scale)
+{
+ return UI_EmoticonHeight(font, scale) * DC->aspectScale;
+}
- if (val[0] == ';' && val[1] == '\0') {
- continue;
- }
+void UI_EscapeEmoticons(char *dest, const char *src, int destsize)
+{
+ int len;
+ qboolean escaped;
- // enable it if any of the values are true
- if (item->cvarFlags & flag) {
- if (Q_stricmp(buff, val) == 0) {
- return qtrue;
- }
- } else {
- // disable it if any of the values are true
- if (Q_stricmp(buff, val) == 0) {
- return qfalse;
+ for (; *src && destsize > 1; src++, destsize--)
+ {
+ if (UI_Text_IsEmoticon(src, &escaped, &len, NULL, NULL) && !escaped)
+ {
+ *dest++ = '[';
+ destsize--;
}
- }
+ *dest++ = *src;
}
- return (item->cvarFlags & flag) ? qfalse : qtrue;
- }
- return qtrue;
+
+ *dest++ = '\0';
}
+qboolean UI_Text_IsEmoticon(const char *s, qboolean *escaped, int *length, qhandle_t *h, int *width)
+{
+ const char *p = s;
+ char emoticon[MAX_EMOTICON_NAME_LEN];
+ int i;
-// will optionaly set focus to this item
-qboolean Item_SetFocus(itemDef_t *item, float x, float y) {
- int i;
- itemDef_t *oldFocus;
- sfxHandle_t *sfx = &DC->Assets.itemFocusSound;
- qboolean playSound = qfalse;
- menuDef_t *parent; // bk001206: = (menuDef_t*)item->parent;
- // sanity check, non-null, not a decoration and does not already have the focus
- if (item == NULL || item->window.flags & WINDOW_DECORATION || item->window.flags & WINDOW_HASFOCUS || !(item->window.flags & WINDOW_VISIBLE)) {
- return qfalse;
- }
+ if (*p != '[')
+ return qfalse;
+ p++;
- // bk001206 - this can be NULL.
- parent = (menuDef_t*)item->parent;
+ if (*p == '[')
+ {
+ *escaped = qtrue;
+ p++;
+ }
+ else
+ *escaped = qfalse;
- // items can be enabled and disabled based on cvars
- if (item->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(item, CVAR_ENABLE)) {
- return qfalse;
- }
+ for (*length = 0; p[*length] != ']'; (*length)++)
+ {
+ if (!p[*length] || *length == MAX_EMOTICON_NAME_LEN - 1)
+ return qfalse;
- if (item->cvarFlags & (CVAR_SHOW | CVAR_HIDE) && !Item_EnableShowViaCvar(item, CVAR_SHOW)) {
- return qfalse;
- }
+ emoticon[*length] = p[*length];
+ }
+ emoticon[*length] = '\0';
- oldFocus = Menu_ClearFocus(item->parent);
+ for (i = 0; i < DC->Assets.emoticonCount; i++)
+ if (!Q_stricmp(DC->Assets.emoticons[i].name, emoticon))
+ break;
- if (item->type == ITEM_TYPE_TEXT) {
- rectDef_t r;
- r = item->textRect;
- r.y -= r.h;
- if (Rect_ContainsPoint(&r, x, y)) {
- item->window.flags |= WINDOW_HASFOCUS;
- if (item->focusSound) {
- sfx = &item->focusSound;
- }
- playSound = qtrue;
- } else {
- if (oldFocus) {
- oldFocus->window.flags |= WINDOW_HASFOCUS;
- if (oldFocus->onFocus) {
- Item_RunScript(oldFocus, oldFocus->onFocus);
- }
- }
- }
- } else {
- item->window.flags |= WINDOW_HASFOCUS;
- if (item->onFocus) {
- Item_RunScript(item, item->onFocus);
- }
- if (item->focusSound) {
- sfx = &item->focusSound;
- }
- playSound = qtrue;
- }
-
- if (playSound && sfx) {
- DC->startLocalSound( *sfx, CHAN_LOCAL_SOUND );
- }
-
- for (i = 0; i < parent->itemCount; i++) {
- if (parent->items[i] == item) {
- parent->cursorItem = i;
- break;
- }
- }
-
- return qtrue;
-}
-
-int Item_ListBox_MaxScroll(itemDef_t *item) {
- listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
- int count = DC->feederCount(item->special);
- int max;
-
- if (item->window.flags & WINDOW_HORIZONTAL) {
- max = count - (item->window.rect.w / listPtr->elementWidth) + 1;
- }
- else {
- max = count - (item->window.rect.h / listPtr->elementHeight) + 1;
- }
- if (max < 0) {
- return 0;
- }
- return max;
-}
-
-int Item_ListBox_ThumbPosition(itemDef_t *item) {
- float max, pos, size;
- listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
-
- max = Item_ListBox_MaxScroll(item);
- if (item->window.flags & WINDOW_HORIZONTAL) {
- size = item->window.rect.w - (SCROLLBAR_SIZE * 2) - 2;
- if (max > 0) {
- pos = (size-SCROLLBAR_SIZE) / (float) max;
- } else {
- pos = 0;
- }
- pos *= listPtr->startPos;
- return item->window.rect.x + 1 + SCROLLBAR_SIZE + pos;
- }
- else {
- size = item->window.rect.h - (SCROLLBAR_SIZE * 2) - 2;
- if (max > 0) {
- pos = (size-SCROLLBAR_SIZE) / (float) max;
- } else {
- pos = 0;
- }
- pos *= listPtr->startPos;
- return item->window.rect.y + 1 + SCROLLBAR_SIZE + pos;
- }
-}
-
-int Item_ListBox_ThumbDrawPosition(itemDef_t *item) {
- int min, max;
-
- if (itemCapture == item) {
- if (item->window.flags & WINDOW_HORIZONTAL) {
- min = item->window.rect.x + SCROLLBAR_SIZE + 1;
- max = item->window.rect.x + item->window.rect.w - 2*SCROLLBAR_SIZE - 1;
- if (DC->cursorx >= min + SCROLLBAR_SIZE/2 && DC->cursorx <= max + SCROLLBAR_SIZE/2) {
- return DC->cursorx - SCROLLBAR_SIZE/2;
- }
- else {
- return Item_ListBox_ThumbPosition(item);
- }
- }
- else {
- min = item->window.rect.y + SCROLLBAR_SIZE + 1;
- max = item->window.rect.y + item->window.rect.h - 2*SCROLLBAR_SIZE - 1;
- if (DC->cursory >= min + SCROLLBAR_SIZE/2 && DC->cursory <= max + SCROLLBAR_SIZE/2) {
- return DC->cursory - SCROLLBAR_SIZE/2;
- }
- else {
- return Item_ListBox_ThumbPosition(item);
- }
- }
- }
- else {
- return Item_ListBox_ThumbPosition(item);
- }
+ if (i == DC->Assets.emoticonCount)
+ return qfalse;
+
+ if (h)
+ *h = DC->Assets.emoticons[i].shader;
+ if (width)
+ *width = DC->Assets.emoticons[i].width;
+
+ (*length) += 2;
+
+ if (*escaped)
+ (*length)++;
+
+ return qtrue;
}
-float Item_Slider_ThumbPosition(itemDef_t *item) {
- float value, range, x;
- editFieldDef_t *editDef = item->typeData;
+static float UI_Parse_Indent(const char **text)
+{
+ char indentWidth[32];
+ char *indentWidthPtr;
+ const char *p = *text;
+ int numDigits;
+ float pixels;
- if (item->text) {
- x = item->textRect.x + item->textRect.w + 8;
- } else {
- x = item->window.rect.x;
- }
+ while (isdigit(*p) || *p == '.')
+ p++;
- if (editDef == NULL && item->cvar) {
- return x;
- }
-
- value = DC->getCVarValue(item->cvar);
-
- if (value < editDef->minVal) {
- value = editDef->minVal;
- } else if (value > editDef->maxVal) {
- value = editDef->maxVal;
- }
-
- range = editDef->maxVal - editDef->minVal;
- value -= editDef->minVal;
- value /= range;
- //value /= (editDef->maxVal - editDef->minVal);
- value *= SLIDER_WIDTH;
- x += value;
- // vm fuckage
- //x = x + (((float)value / editDef->maxVal) * SLIDER_WIDTH);
- return x;
-}
-
-int Item_Slider_OverSlider(itemDef_t *item, float x, float y) {
- rectDef_t r;
-
- r.x = Item_Slider_ThumbPosition(item) - (SLIDER_THUMB_WIDTH / 2);
- r.y = item->window.rect.y - 2;
- r.w = SLIDER_THUMB_WIDTH;
- r.h = SLIDER_THUMB_HEIGHT;
-
- if (Rect_ContainsPoint(&r, x, y)) {
- return WINDOW_LB_THUMB;
- }
- return 0;
-}
-
-int Item_ListBox_OverLB(itemDef_t *item, float x, float y) {
- rectDef_t r;
- listBoxDef_t *listPtr;
- int thumbstart;
- int count;
-
- count = DC->feederCount(item->special);
- listPtr = (listBoxDef_t*)item->typeData;
- if (item->window.flags & WINDOW_HORIZONTAL) {
- // check if on left arrow
- r.x = item->window.rect.x;
- r.y = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE;
- r.h = r.w = SCROLLBAR_SIZE;
- if (Rect_ContainsPoint(&r, x, y)) {
- return WINDOW_LB_LEFTARROW;
- }
- // check if on right arrow
- r.x = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE;
- if (Rect_ContainsPoint(&r, x, y)) {
- return WINDOW_LB_RIGHTARROW;
- }
- // check if on thumb
- thumbstart = Item_ListBox_ThumbPosition(item);
- r.x = thumbstart;
- if (Rect_ContainsPoint(&r, x, y)) {
- return WINDOW_LB_THUMB;
- }
- r.x = item->window.rect.x + SCROLLBAR_SIZE;
- r.w = thumbstart - r.x;
- if (Rect_ContainsPoint(&r, x, y)) {
- return WINDOW_LB_PGUP;
- }
- r.x = thumbstart + SCROLLBAR_SIZE;
- r.w = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE;
- if (Rect_ContainsPoint(&r, x, y)) {
- return WINDOW_LB_PGDN;
- }
- } else {
- r.x = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE;
- r.y = item->window.rect.y;
- r.h = r.w = SCROLLBAR_SIZE;
- if (Rect_ContainsPoint(&r, x, y)) {
- return WINDOW_LB_LEFTARROW;
- }
- r.y = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE;
- if (Rect_ContainsPoint(&r, x, y)) {
- return WINDOW_LB_RIGHTARROW;
- }
- thumbstart = Item_ListBox_ThumbPosition(item);
- r.y = thumbstart;
- if (Rect_ContainsPoint(&r, x, y)) {
- return WINDOW_LB_THUMB;
- }
- r.y = item->window.rect.y + SCROLLBAR_SIZE;
- r.h = thumbstart - r.y;
- if (Rect_ContainsPoint(&r, x, y)) {
- return WINDOW_LB_PGUP;
- }
- r.y = thumbstart + SCROLLBAR_SIZE;
- r.h = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE;
- if (Rect_ContainsPoint(&r, x, y)) {
- return WINDOW_LB_PGDN;
- }
- }
- return 0;
+ if (*p != INDENT_MARKER)
+ return 0.0f;
+
+ numDigits = (p - *text);
+
+ if (numDigits > sizeof(indentWidth) - 1)
+ return 0.0f;
+
+ strncpy(indentWidth, *text, numDigits);
+
+ indentWidth[numDigits] = '\0';
+ indentWidthPtr = indentWidth;
+
+ if (!Float_Parse(&indentWidthPtr, &pixels))
+ return 0.0f;
+
+ (*text) += (numDigits + 1);
+
+ return pixels;
}
+static ID_INLINE fontInfo_t *UI_FontForScale(float scale)
+{
+ if (scale <= DC->smallFontScale)
+ return &DC->Assets.smallFont;
+ else if (scale >= DC->bigFontScale)
+ return &DC->Assets.bigFont;
+ else
+ return &DC->Assets.textFont;
+}
-void Item_ListBox_MouseEnter(itemDef_t *item, float x, float y)
+float UI_Char_Width(const char **text, float scale)
{
- rectDef_t r;
- listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
-
- item->window.flags &= ~(WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW | WINDOW_LB_THUMB | WINDOW_LB_PGUP | WINDOW_LB_PGDN);
- item->window.flags |= Item_ListBox_OverLB(item, x, y);
-
- if (item->window.flags & WINDOW_HORIZONTAL) {
- if (!(item->window.flags & (WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW | WINDOW_LB_THUMB | WINDOW_LB_PGUP | WINDOW_LB_PGDN))) {
- // check for selection hit as we have exausted buttons and thumb
- if (listPtr->elementStyle == LISTBOX_IMAGE) {
- r.x = item->window.rect.x;
- r.y = item->window.rect.y;
- r.h = item->window.rect.h - SCROLLBAR_SIZE;
- r.w = item->window.rect.w - listPtr->drawPadding;
- if (Rect_ContainsPoint(&r, x, y)) {
- listPtr->cursorPos = (int)((x - r.x) / listPtr->elementWidth) + listPtr->startPos;
- if (listPtr->cursorPos >= listPtr->endPos) {
- listPtr->cursorPos = listPtr->endPos;
- }
- }
- } else {
- // text hit..
- }
- }
- } else if (!(item->window.flags & (WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW | WINDOW_LB_THUMB | WINDOW_LB_PGUP | WINDOW_LB_PGDN))) {
- r.x = item->window.rect.x;
- r.y = item->window.rect.y;
- r.w = item->window.rect.w - SCROLLBAR_SIZE;
- r.h = item->window.rect.h - listPtr->drawPadding;
- if (Rect_ContainsPoint(&r, x, y)) {
- listPtr->cursorPos = (int)((y - 2 - r.y) / listPtr->elementHeight) + listPtr->startPos;
- if (listPtr->cursorPos > listPtr->endPos) {
- listPtr->cursorPos = listPtr->endPos;
- }
- }
- }
-}
-
-void Item_MouseEnter(itemDef_t *item, float x, float y) {
- rectDef_t r;
- if (item) {
- r = item->textRect;
- r.y -= r.h;
- // in the text rect?
+ glyphInfo_t *glyph;
+ fontInfo_t *font;
+ int emoticonLen;
+ qboolean emoticonEscaped;
+ int emoticonWidth;
- // items can be enabled and disabled based on cvars
- if (item->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(item, CVAR_ENABLE)) {
- return;
- }
+ if (text && *text)
+ {
+ if (Q_IsColorString(*text))
+ {
+ *text += 2;
+ return 0.0f;
+ }
- if (item->cvarFlags & (CVAR_SHOW | CVAR_HIDE) && !Item_EnableShowViaCvar(item, CVAR_SHOW)) {
- return;
- }
+ if (**text == INDENT_MARKER)
+ {
+ (*text)++;
+ return 0.0f;
+ }
- if (Rect_ContainsPoint(&r, x, y)) {
- if (!(item->window.flags & WINDOW_MOUSEOVERTEXT)) {
- Item_RunScript(item, item->mouseEnterText);
- item->window.flags |= WINDOW_MOUSEOVERTEXT;
- }
- if (!(item->window.flags & WINDOW_MOUSEOVER)) {
- Item_RunScript(item, item->mouseEnter);
- item->window.flags |= WINDOW_MOUSEOVER;
- }
+ font = UI_FontForScale(scale);
- } else {
- // not in the text rect
- if (item->window.flags & WINDOW_MOUSEOVERTEXT) {
- // if we were
- Item_RunScript(item, item->mouseExitText);
- item->window.flags &= ~WINDOW_MOUSEOVERTEXT;
- }
- if (!(item->window.flags & WINDOW_MOUSEOVER)) {
- Item_RunScript(item, item->mouseEnter);
- item->window.flags |= WINDOW_MOUSEOVER;
- }
+ if (UI_Text_IsEmoticon(*text, &emoticonEscaped, &emoticonLen, NULL, &emoticonWidth))
+ {
+ if (emoticonEscaped)
+ (*text)++;
+ else
+ {
+ *text += emoticonLen;
+ return emoticonWidth * UI_EmoticonWidth(font, scale);
+ }
+ }
+
+ (*text)++;
- if (item->type == ITEM_TYPE_LISTBOX) {
- Item_ListBox_MouseEnter(item, x, y);
- }
+ glyph = &font->glyphs[(int)**text];
+ return glyph->xSkip * DC->aspectScale * scale * font->glyphScale;
}
- }
+
+ return 0.0f;
}
-void Item_MouseLeave(itemDef_t *item) {
- if (item) {
- if (item->window.flags & WINDOW_MOUSEOVERTEXT) {
- Item_RunScript(item, item->mouseExitText);
- item->window.flags &= ~WINDOW_MOUSEOVERTEXT;
+float UI_Text_Width(const char *text, float scale)
+{
+ float out;
+ const char *s = text;
+ float indentWidth = 0.0f;
+
+ out = 0.0f;
+
+ if (text)
+ {
+ indentWidth = UI_Parse_Indent(&s);
+
+ while (*s)
+ out += UI_Char_Width(&s, scale);
}
- Item_RunScript(item, item->mouseExit);
- item->window.flags &= ~(WINDOW_LB_RIGHTARROW | WINDOW_LB_LEFTARROW);
- }
+
+ return out + indentWidth;
}
-itemDef_t *Menu_HitTest(menuDef_t *menu, float x, float y) {
- int i;
- for (i = 0; i < menu->itemCount; i++) {
- if (Rect_ContainsPoint(&menu->items[i]->window.rect, x, y)) {
- return menu->items[i];
+float UI_Text_Height(const char *text, float scale)
+{
+ float max;
+ glyphInfo_t *glyph;
+ float useScale;
+ const char *s = text;
+ fontInfo_t *font = UI_FontForScale(scale);
+
+ useScale = scale * font->glyphScale;
+ max = 0;
+
+ if (text)
+ {
+ while (s && *s)
+ {
+ if (Q_IsColorString(s))
+ {
+ s += 2;
+ continue;
+ }
+ else
+ {
+ glyph = &font->glyphs[(int)*s];
+
+ if (max < glyph->height)
+ max = glyph->height;
+
+ s++;
+ }
+ }
}
- }
- return NULL;
+
+ return max * useScale;
}
-void Item_SetMouseOver(itemDef_t *item, qboolean focus) {
- if (item) {
- if (focus) {
- item->window.flags |= WINDOW_MOUSEOVER;
- } else {
- item->window.flags &= ~WINDOW_MOUSEOVER;
- }
- }
+float UI_Text_EmWidth(float scale) { return UI_Text_Width("M", scale); }
+
+float UI_Text_EmHeight(float scale) { return UI_Text_Height("M", scale); }
+
+/*
+================
+UI_AdjustFrom640
+
+Adjusted for resolution and screen aspect ratio
+================
+*/
+void UI_AdjustFrom640(float *x, float *y, float *w, float *h)
+{
+ *x *= DC->xscale;
+ *y *= DC->yscale;
+ *w *= DC->xscale;
+ *h *= DC->yscale;
}
+/*
+================
+UI_SetClipRegion
+=================
+*/
+void UI_SetClipRegion(float x, float y, float w, float h)
+{
+ vec4_t clip;
+
+ UI_AdjustFrom640(&x, &y, &w, &h);
-qboolean Item_OwnerDraw_HandleKey(itemDef_t *item, int key) {
- if (item && DC->ownerDrawHandleKey) {
- return DC->ownerDrawHandleKey(item->window.ownerDraw, item->window.ownerDrawFlags, &item->special, key);
- }
- return qfalse;
+ clip[0] = x;
+ clip[1] = y;
+ clip[2] = x + w;
+ clip[3] = y + h;
+
+ trap_R_SetClipRegion(clip);
}
-qboolean Item_ListBox_HandleKey(itemDef_t *item, int key, qboolean down, qboolean force) {
- listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
- int count = DC->feederCount(item->special);
- int max, viewmax;
+/*
+================
+UI_ClearClipRegion
+=================
+*/
+void UI_ClearClipRegion(void) { trap_R_SetClipRegion(NULL); }
- if (force || (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS)) {
- max = Item_ListBox_MaxScroll(item);
- if (item->window.flags & WINDOW_HORIZONTAL) {
- viewmax = (item->window.rect.w / listPtr->elementWidth);
- if ( key == K_LEFTARROW || key == K_KP_LEFTARROW )
- {
- if (!listPtr->notselectable) {
- listPtr->cursorPos--;
- if (listPtr->cursorPos < 0) {
- listPtr->cursorPos = 0;
- }
- if (listPtr->cursorPos < listPtr->startPos) {
- listPtr->startPos = listPtr->cursorPos;
- }
- if (listPtr->cursorPos >= listPtr->startPos + viewmax) {
- listPtr->startPos = listPtr->cursorPos - viewmax + 1;
- }
- item->cursorPos = listPtr->cursorPos;
- DC->feederSelection(item->special, item->cursorPos);
- }
- else {
- listPtr->startPos--;
- if (listPtr->startPos < 0)
- listPtr->startPos = 0;
+static void UI_Text_PaintChar(float x, float y, float scale, glyphInfo_t *glyph, float size)
+{
+ float w, h;
+
+ w = glyph->imageWidth;
+ h = glyph->imageHeight;
+
+ if (size > 0.0f)
+ {
+ float half = size * 0.5f * scale;
+ x -= half;
+ y -= half;
+ w += size;
+ h += size;
+ }
+
+ w *= (DC->aspectScale * scale);
+ h *= scale;
+ y -= (glyph->top * scale);
+ UI_AdjustFrom640(&x, &y, &w, &h);
+
+ DC->drawStretchPic(x, y, w, h, glyph->s, glyph->t, glyph->s2, glyph->t2, glyph->glyph);
+}
+
+static void UI_Text_Paint_Generic(float x, float y, float scale, float gapAdjust, const char *text, vec4_t color,
+ int style, int limit, float *maxX, int cursorPos, char cursor)
+{
+ const char *s = text;
+ int len;
+ int count = 0;
+ vec4_t newColor;
+ fontInfo_t *font = UI_FontForScale(scale);
+ glyphInfo_t *glyph;
+ float useScale;
+ qhandle_t emoticonHandle = 0;
+ float emoticonH, emoticonW;
+ qboolean emoticonEscaped;
+ int emoticonLen = 0;
+ int emoticonWidth;
+ int cursorX = -1;
+
+ if (!text)
+ return;
+
+ useScale = scale * font->glyphScale;
+
+ emoticonH = UI_EmoticonHeight(font, scale);
+ emoticonW = UI_EmoticonWidth(font, scale);
+
+ len = strlen(text);
+ if (limit > 0 && len > limit)
+ len = limit;
+
+ DC->setColor(color);
+ memcpy(&newColor[0], &color[0], sizeof(vec4_t));
+
+ x += UI_Parse_Indent(&s);
+
+ while (s && *s && count < len)
+ {
+ const char *t = s;
+ float charWidth = UI_Char_Width(&t, scale);
+ glyph = &font->glyphs[(int)*s];
+
+ if (maxX && charWidth + x > *maxX)
+ {
+ *maxX = 0;
+ break;
}
- return qtrue;
- }
- if ( key == K_RIGHTARROW || key == K_KP_RIGHTARROW )
- {
- if (!listPtr->notselectable) {
- listPtr->cursorPos++;
- if (listPtr->cursorPos < listPtr->startPos) {
- listPtr->startPos = listPtr->cursorPos;
- }
- if (listPtr->cursorPos >= count) {
- listPtr->cursorPos = count-1;
- }
- if (listPtr->cursorPos >= listPtr->startPos + viewmax) {
- listPtr->startPos = listPtr->cursorPos - viewmax + 1;
- }
- item->cursorPos = listPtr->cursorPos;
- DC->feederSelection(item->special, item->cursorPos);
- }
- else {
- listPtr->startPos++;
- if (listPtr->startPos >= count)
- listPtr->startPos = count-1;
+
+ if (cursorPos < 0)
+ {
+ if (Q_IsColorString(s))
+ {
+ memcpy(newColor, g_color_table[ColorIndex(*(s + 1))], sizeof(newColor));
+ newColor[3] = color[3];
+ DC->setColor(newColor);
+ s += 2;
+ continue;
+ }
+
+ if (*s == INDENT_MARKER)
+ {
+ s++;
+ continue;
+ }
+
+ if (UI_Text_IsEmoticon(s, &emoticonEscaped, &emoticonLen, &emoticonHandle, &emoticonWidth))
+ {
+ if (emoticonEscaped)
+ s++;
+ else
+ {
+ float yadj = useScale * glyph->top;
+
+ DC->setColor(NULL);
+ DC->drawHandlePic(x, y - yadj, (emoticonW * emoticonWidth), emoticonH, emoticonHandle);
+ DC->setColor(newColor);
+ x += (emoticonW * emoticonWidth) + gapAdjust;
+ s += emoticonLen;
+ count += emoticonWidth;
+ continue;
+ }
+ }
}
- return qtrue;
- }
- }
- else {
- viewmax = (item->window.rect.h / listPtr->elementHeight);
- if ( key == K_UPARROW || key == K_KP_UPARROW )
- {
- if (!listPtr->notselectable) {
- listPtr->cursorPos--;
- if (listPtr->cursorPos < 0) {
- listPtr->cursorPos = 0;
- }
- if (listPtr->cursorPos < listPtr->startPos) {
- listPtr->startPos = listPtr->cursorPos;
- }
- if (listPtr->cursorPos >= listPtr->startPos + viewmax) {
- listPtr->startPos = listPtr->cursorPos - viewmax + 1;
- }
- item->cursorPos = listPtr->cursorPos;
- DC->feederSelection(item->special, item->cursorPos);
- }
- else {
- listPtr->startPos--;
- if (listPtr->startPos < 0)
- listPtr->startPos = 0;
+
+ if (style == ITEM_TEXTSTYLE_SHADOWED || style == ITEM_TEXTSTYLE_SHADOWEDMORE)
+ {
+ int ofs;
+
+ if (style == ITEM_TEXTSTYLE_SHADOWED)
+ ofs = 1;
+ else
+ ofs = 2;
+ colorBlack[3] = newColor[3];
+ DC->setColor(colorBlack);
+ UI_Text_PaintChar(x + ofs, y + ofs, useScale, glyph, 0.0f);
+ DC->setColor(newColor);
+ colorBlack[3] = 1.0f;
}
- return qtrue;
- }
- if ( key == K_DOWNARROW || key == K_KP_DOWNARROW )
- {
- if (!listPtr->notselectable) {
- listPtr->cursorPos++;
- if (listPtr->cursorPos < listPtr->startPos) {
- listPtr->startPos = listPtr->cursorPos;
- }
- if (listPtr->cursorPos >= count) {
- listPtr->cursorPos = count-1;
- }
- if (listPtr->cursorPos >= listPtr->startPos + viewmax) {
- listPtr->startPos = listPtr->cursorPos - viewmax + 1;
- }
- item->cursorPos = listPtr->cursorPos;
- DC->feederSelection(item->special, item->cursorPos);
- }
- else {
- listPtr->startPos++;
- if (listPtr->startPos > max)
- listPtr->startPos = max;
+ else if (style == ITEM_TEXTSTYLE_NEON)
+ {
+ vec4_t glow;
+
+ memcpy(&glow[0], &newColor[0], sizeof(vec4_t));
+ glow[3] *= 0.2f;
+
+ DC->setColor(glow);
+ UI_Text_PaintChar(x, y, useScale, glyph, 6.0f);
+ UI_Text_PaintChar(x, y, useScale, glyph, 4.0f);
+ DC->setColor(newColor);
+ UI_Text_PaintChar(x, y, useScale, glyph, 2.0f);
+
+ DC->setColor(colorWhite);
}
- return qtrue;
- }
- }
- // mouse hit
- if (key == K_MOUSE1 || key == K_MOUSE2) {
- if (item->window.flags & WINDOW_LB_LEFTARROW) {
- listPtr->startPos--;
- if (listPtr->startPos < 0) {
- listPtr->startPos = 0;
- }
- } else if (item->window.flags & WINDOW_LB_RIGHTARROW) {
- // one down
- listPtr->startPos++;
- if (listPtr->startPos > max) {
- listPtr->startPos = max;
- }
- } else if (item->window.flags & WINDOW_LB_PGUP) {
- // page up
- listPtr->startPos -= viewmax;
- if (listPtr->startPos < 0) {
- listPtr->startPos = 0;
- }
- } else if (item->window.flags & WINDOW_LB_PGDN) {
- // page down
- listPtr->startPos += viewmax;
- if (listPtr->startPos > max) {
- listPtr->startPos = max;
- }
- } else if (item->window.flags & WINDOW_LB_THUMB) {
- // Display_SetCaptureItem(item);
- } else {
- // select an item
- if (DC->realTime < lastListBoxClickTime && listPtr->doubleClick) {
- Item_RunScript(item, listPtr->doubleClick);
- }
- lastListBoxClickTime = DC->realTime + DOUBLE_CLICK_DELAY;
- if (item->cursorPos != listPtr->cursorPos) {
- item->cursorPos = listPtr->cursorPos;
- DC->feederSelection(item->special, item->cursorPos);
- }
- }
- return qtrue;
- }
-
- // Scroll wheel
- if (key == K_MWHEELUP) {
- listPtr->startPos--;
- if (listPtr->startPos < 0) {
- listPtr->startPos = 0;
- }
- return qtrue;
+
+ UI_Text_PaintChar(x, y, useScale, glyph, 0.0f);
+
+ if (count == cursorPos)
+ cursorX = x;
+
+ x += (glyph->xSkip * DC->aspectScale * useScale) + gapAdjust;
+ s++;
+ count++;
}
- if (key == K_MWHEELDOWN) {
- listPtr->startPos++;
- if (listPtr->startPos > max) {
- listPtr->startPos = max;
- }
- return qtrue;
+
+ if (maxX)
+ *maxX = x;
+
+ // paint cursor
+ if (cursorPos >= 0)
+ {
+ if (cursorPos == len)
+ cursorX = x;
+
+ if (cursorX >= 0 && !((DC->realTime / BLINK_DIVISOR) & 1))
+ {
+ glyph = &font->glyphs[(int)cursor];
+ UI_Text_PaintChar(cursorX, y, useScale, glyph, 0.0f);
+ }
}
- // Invoke the doubleClick handler when enter is pressed
- if( key == K_ENTER )
+ DC->setColor(NULL);
+}
+
+void UI_Text_Paint_Limit(
+ float *maxX, float x, float y, float scale, vec4_t color, const char *text, float adjust, int limit)
+{
+ UI_Text_Paint_Generic(x, y, scale, adjust, text, color, ITEM_TEXTSTYLE_NORMAL, limit, maxX, -1, 0);
+}
+
+void UI_Text_Paint(float x, float y, float scale, vec4_t color, const char *text, float adjust, int limit, int style)
+{
+ UI_Text_Paint_Generic(x, y, scale, adjust, text, color, style, limit, NULL, -1, 0);
+}
+
+void UI_Text_PaintWithCursor(
+ float x, float y, float scale, vec4_t color, const char *text, int cursorPos, char cursor, int limit, int style)
+{
+ UI_Text_Paint_Generic(x, y, scale, 0.0, text, color, style, limit, NULL, cursorPos, cursor);
+}
+
+commandDef_t commandList[] = {
+ {"close", &Script_Close}, // menu
+ {"conditionalopen", &Script_ConditionalOpen}, // menu
+ {"exec", &Script_Exec}, // group/name
+ {"fadein", &Script_FadeIn}, // group/name
+ {"fadeout", &Script_FadeOut}, // group/name
+ {"hide", &Script_Hide}, // group/name
+ {"open", &Script_Open}, // menu
+ {"orbit", &Script_Orbit}, // group/name
+ {"play", &Script_Play}, // group/name
+ {"playlooped", &Script_playLooped}, // group/name
+ {"reset", &Script_Reset}, // resets the state of the item argument
+ {"setasset", &Script_SetAsset}, // works on this
+ {"setbackground", &Script_SetBackground}, // works on this
+ {"setcolor", &Script_SetColor}, // works on this
+ {"setcvar", &Script_SetCvar}, // group/name
+ {"setfocus", &Script_SetFocus}, // sets this background color to team color
+ {"setitemcolor", &Script_SetItemColor}, // group/name
+ {"setplayerhead", &Script_SetPlayerHead}, // sets this background color to team color
+ {"setplayermodel", &Script_SetPlayerModel}, // sets this background color to team color
+ {"show", &Script_Show}, // group/name
+ {"transition", &Script_Transition}, // group/name
+};
+
+static size_t scriptCommandCount = ARRAY_LEN(commandList);
+
+// despite what lcc thinks, we do not get cmdcmp here
+static int commandComp(const void *a, const void *b) { return Q_stricmp((const char *)a, ((commandDef_t *)b)->name); }
+
+void Item_RunScript(itemDef_t *item, const char *s)
+{
+ char script[1024], *p;
+ commandDef_t *cmd;
+ memset(script, 0, sizeof(script));
+
+ if (item && s && s[0])
{
- if( listPtr->doubleClick )
- Item_RunScript( item, listPtr->doubleClick );
+ Q_strcat(script, 1024, s);
+ p = script;
+
+ while (1)
+ {
+ const char *command;
+ // expect command then arguments, ; ends command, NULL ends script
+
+ if (!String_Parse(&p, &command))
+ return;
+
+ if (command[0] == ';' && command[1] == '\0')
+ continue;
- return qtrue;
+ cmd = bsearch(command, commandList, scriptCommandCount, sizeof(commandDef_t), commandComp);
+ if (cmd)
+ cmd->handler(item, &p);
+ else
+ // not in our auto list, pass to handler
+ DC->runScript(&p);
+ }
}
+}
- if ( key == K_HOME || key == K_KP_HOME) {
- // home
- listPtr->startPos = 0;
- return qtrue;
+qboolean Item_EnableShowViaCvar(itemDef_t *item, int flag)
+{
+ char script[1024], *p;
+ memset(script, 0, sizeof(script));
+
+ if (item && item->enableCvar && *item->enableCvar && item->cvarTest && *item->cvarTest)
+ {
+ char buff[1024];
+ DC->getCVarString(item->cvarTest, buff, sizeof(buff));
+
+ Q_strcat(script, 1024, item->enableCvar);
+ p = script;
+
+ while (1)
+ {
+ const char *val;
+ // expect value then ; or NULL, NULL ends list
+
+ if (!String_Parse(&p, &val))
+ return (item->cvarFlags & flag) ? qfalse : qtrue;
+
+ if (val[0] == ';' && val[1] == '\0')
+ continue;
+
+ // enable it if any of the values are true
+ if (item->cvarFlags & flag)
+ {
+ if (Q_stricmp(buff, val) == 0)
+ return qtrue;
+ }
+ else
+ {
+ // disable it if any of the values are true
+
+ if (Q_stricmp(buff, val) == 0)
+ return qfalse;
+ }
+ }
+
+ return (item->cvarFlags & flag) ? qfalse : qtrue;
}
- if ( key == K_END || key == K_KP_END) {
- // end
- listPtr->startPos = max;
- return qtrue;
+
+ return qtrue;
+}
+
+// will optionaly set focus to this item
+qboolean Item_SetFocus(itemDef_t *item, float x, float y)
+{
+ int i;
+ itemDef_t *oldFocus;
+ sfxHandle_t *sfx = &DC->Assets.itemFocusSound;
+ qboolean playSound = qfalse;
+ menuDef_t *parent;
+ // sanity check, non-null, not a decoration and does not already have the focus
+
+ if (item == NULL || item->window.flags & WINDOW_DECORATION || item->window.flags & WINDOW_HASFOCUS ||
+ !(item->window.flags & WINDOW_VISIBLE))
+ {
+ return qfalse;
}
- if (key == K_PGUP || key == K_KP_PGUP ) {
- // page up
- if (!listPtr->notselectable) {
- listPtr->cursorPos -= viewmax;
- if (listPtr->cursorPos < 0) {
- listPtr->cursorPos = 0;
- }
- if (listPtr->cursorPos < listPtr->startPos) {
- listPtr->startPos = listPtr->cursorPos;
+
+ parent = (menuDef_t *)item->parent;
+
+ // items can be enabled and disabled based on cvars
+
+ if (item->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(item, CVAR_ENABLE))
+ return qfalse;
+
+ if (item->cvarFlags & (CVAR_SHOW | CVAR_HIDE) && !Item_EnableShowViaCvar(item, CVAR_SHOW))
+ return qfalse;
+
+ oldFocus = Menu_ClearFocus(item->parent);
+
+ if (item->type == ITEM_TYPE_TEXT)
+ {
+ rectDef_t r;
+ r = item->textRect;
+ r.y -= r.h;
+
+ if (Rect_ContainsPoint(&r, x, y))
+ {
+ item->window.flags |= WINDOW_HASFOCUS;
+
+ if (item->focusSound)
+ sfx = &item->focusSound;
+
+ playSound = qtrue;
}
- if (listPtr->cursorPos >= listPtr->startPos + viewmax) {
- listPtr->startPos = listPtr->cursorPos - viewmax + 1;
+ else
+ {
+ if (oldFocus)
+ {
+ oldFocus->window.flags |= WINDOW_HASFOCUS;
+
+ if (oldFocus->onFocus)
+ Item_RunScript(oldFocus, oldFocus->onFocus);
+ }
}
- item->cursorPos = listPtr->cursorPos;
- DC->feederSelection(item->special, item->cursorPos);
- }
- else {
- listPtr->startPos -= viewmax;
- if (listPtr->startPos < 0) {
- listPtr->startPos = 0;
+ }
+ else
+ {
+ item->window.flags |= WINDOW_HASFOCUS;
+
+ if (item->onFocus)
+ Item_RunScript(item, item->onFocus);
+
+ if (item->focusSound)
+ sfx = &item->focusSound;
+
+ playSound = qtrue;
+ }
+
+ if (playSound && sfx)
+ DC->startLocalSound(*sfx, CHAN_LOCAL_SOUND);
+
+ for (i = 0; i < parent->itemCount; i++)
+ {
+ if (parent->items[i] == item)
+ {
+ parent->cursorItem = i;
+ break;
}
- }
- return qtrue;
}
- if ( key == K_PGDN || key == K_KP_PGDN ) {
- // page down
- if (!listPtr->notselectable) {
- listPtr->cursorPos += viewmax;
- if (listPtr->cursorPos < listPtr->startPos) {
- listPtr->startPos = listPtr->cursorPos;
+
+ return qtrue;
+}
+
+static float Item_ListBox_HeightForNumItems(itemDef_t *item, int numItems)
+{
+ listBoxDef_t *listPtr = item->typeData.list;
+
+ return (listPtr->elementHeight * numItems) + 2.0f;
+}
+
+static int Item_ListBox_NumItemsForItemHeight(itemDef_t *item)
+{
+ listBoxDef_t *listPtr = item->typeData.list;
+
+ if (item->type == ITEM_TYPE_COMBOBOX)
+ return listPtr->dropItems;
+ else
+ return ((item->window.rect.h - 2.0f) / listPtr->elementHeight);
+}
+
+int Item_ListBox_MaxScroll(itemDef_t *item)
+{
+ int total = DC->feederCount(item->feederID);
+ int max = total - Item_ListBox_NumItemsForItemHeight(item);
+
+ if (max < 0)
+ return 0;
+
+ return max;
+}
+
+static float oldComboBoxY;
+static float oldComboBoxH;
+
+static qboolean Item_ComboBox_MaybeCastToListBox(itemDef_t *item)
+{
+ listBoxDef_t *listPtr = item->typeData.list;
+ qboolean cast = g_comboBoxItem != NULL && (item->type == ITEM_TYPE_COMBOBOX);
+
+ if (cast)
+ {
+ oldComboBoxY = item->window.rect.y;
+ oldComboBoxH = item->window.rect.h;
+
+ item->window.rect.y += item->window.rect.h;
+ item->window.rect.h = Item_ListBox_HeightForNumItems(item, listPtr->dropItems);
+ item->type = ITEM_TYPE_LISTBOX;
+ }
+
+ return cast;
+}
+
+static void Item_ComboBox_MaybeUnCastFromListBox(itemDef_t *item, qboolean unCast)
+{
+ if (unCast)
+ {
+ item->window.rect.y = oldComboBoxY;
+ item->window.rect.h = oldComboBoxH;
+ item->type = ITEM_TYPE_COMBOBOX;
+ }
+}
+
+static void Item_ListBox_SetStartPos(itemDef_t *item, int startPos)
+{
+ listBoxDef_t *listPtr = item->typeData.list;
+ int total = DC->feederCount(item->feederID);
+ int max = Item_ListBox_MaxScroll(item);
+
+ if (startPos < 0)
+ listPtr->startPos = 0;
+ else if (startPos > max)
+ listPtr->startPos = max;
+ else
+ listPtr->startPos = startPos;
+
+ listPtr->endPos = listPtr->startPos + MIN((total - listPtr->startPos), Item_ListBox_NumItemsForItemHeight(item));
+}
+
+float Item_ListBox_ThumbPosition(itemDef_t *item)
+{
+ float max, pos, size;
+ float startPos = (float)item->typeData.list->startPos;
+
+ max = Item_ListBox_MaxScroll(item);
+ size = SCROLLBAR_SLIDER_HEIGHT(item);
+
+ if (max > 0.0f)
+ pos = (size - SCROLLBAR_ARROW_HEIGHT) / max;
+ else
+ pos = 0.0f;
+
+ pos *= startPos;
+
+ return SCROLLBAR_SLIDER_Y(item) + pos;
+}
+
+float Item_ListBox_ThumbDrawPosition(itemDef_t *item)
+{
+ if (itemCapture == item)
+ {
+ float min = SCROLLBAR_SLIDER_Y(item);
+ float max = min + SCROLLBAR_SLIDER_HEIGHT(item) - SCROLLBAR_ARROW_HEIGHT;
+ float halfThumbSize = SCROLLBAR_ARROW_HEIGHT / 2.0f;
+
+ if (DC->cursory >= min + halfThumbSize && DC->cursory <= max + halfThumbSize)
+ return DC->cursory - halfThumbSize;
+ }
+
+ return Item_ListBox_ThumbPosition(item);
+}
+
+float Item_Slider_ThumbPosition(itemDef_t *item)
+{
+ float value, range, x;
+ editFieldDef_t *editDef = item->typeData.edit;
+
+ if (item->text)
+ x = item->textRect.x + item->textRect.w + ITEM_VALUE_OFFSET;
+ else
+ x = item->window.rect.x;
+
+ if (editDef == NULL && item->cvar)
+ return x;
+
+ value = DC->getCVarValue(item->cvar);
+
+ if (value < editDef->minVal)
+ value = editDef->minVal;
+ else if (value > editDef->maxVal)
+ value = editDef->maxVal;
+
+ range = editDef->maxVal - editDef->minVal;
+ value -= editDef->minVal;
+ value /= range;
+ value *= SLIDER_WIDTH;
+ x += value;
+
+ return x;
+}
+
+static float Item_Slider_VScale(itemDef_t *item)
+{
+ if (SLIDER_THUMB_HEIGHT > item->window.rect.h)
+ return item->window.rect.h / SLIDER_THUMB_HEIGHT;
+ else
+ return 1.0f;
+}
+
+int Item_Slider_OverSlider(itemDef_t *item, float x, float y)
+{
+ rectDef_t r;
+ float vScale = Item_Slider_VScale(item);
+
+ r.x = Item_Slider_ThumbPosition(item) - (SLIDER_THUMB_WIDTH / 2);
+ r.y = item->textRect.y - item->textRect.h + ((item->textRect.h - (SLIDER_THUMB_HEIGHT * vScale)) / 2.0f);
+ r.w = SLIDER_THUMB_WIDTH;
+ r.h = SLIDER_THUMB_HEIGHT * vScale;
+
+ if (Rect_ContainsPoint(&r, x, y))
+ return WINDOW_LB_THUMB;
+
+ return 0;
+}
+
+int Item_ListBox_OverLB(itemDef_t *item, float x, float y)
+{
+ rectDef_t r;
+ int thumbstart;
+
+ r.x = SCROLLBAR_SLIDER_X(item);
+ r.y = SCROLLBAR_Y(item);
+ r.w = SCROLLBAR_ARROW_WIDTH;
+ r.h = SCROLLBAR_ARROW_HEIGHT;
+
+ if (Rect_ContainsPoint(&r, x, y))
+ return WINDOW_LB_UPARROW;
+
+ r.y = SCROLLBAR_SLIDER_Y(item) + SCROLLBAR_SLIDER_HEIGHT(item);
+
+ if (Rect_ContainsPoint(&r, x, y))
+ return WINDOW_LB_DOWNARROW;
+
+ thumbstart = Item_ListBox_ThumbPosition(item);
+ r.y = thumbstart;
+
+ if (Rect_ContainsPoint(&r, x, y))
+ return WINDOW_LB_THUMB;
+
+ r.y = SCROLLBAR_SLIDER_Y(item);
+ r.h = thumbstart - r.y;
+
+ if (Rect_ContainsPoint(&r, x, y))
+ return WINDOW_LB_PGUP;
+
+ r.y = thumbstart + SCROLLBAR_ARROW_HEIGHT;
+ r.h = (SCROLLBAR_SLIDER_Y(item) + SCROLLBAR_SLIDER_HEIGHT(item)) - r.y;
+
+ if (Rect_ContainsPoint(&r, x, y))
+ return WINDOW_LB_PGDN;
+
+ return 0;
+}
+
+void Item_ListBox_MouseEnter(itemDef_t *item, float x, float y)
+{
+ rectDef_t r;
+ listBoxDef_t *listPtr = item->typeData.list;
+ int listBoxFlags = (WINDOW_LB_UPARROW | WINDOW_LB_DOWNARROW | WINDOW_LB_THUMB | WINDOW_LB_PGUP | WINDOW_LB_PGDN);
+ int total = DC->feederCount(item->feederID);
+
+ item->window.flags &= ~listBoxFlags;
+ item->window.flags |= Item_ListBox_OverLB(item, x, y);
+
+ if (!(item->window.flags & listBoxFlags))
+ {
+ r.x = SCROLLBAR_X(item);
+ r.y = SCROLLBAR_Y(item);
+ r.w = SCROLLBAR_W(item);
+ r.h = listPtr->elementHeight * MIN(Item_ListBox_NumItemsForItemHeight(item), total);
+
+ if (Rect_ContainsPoint(&r, x, y))
+ {
+ listPtr->cursorPos = (int)((y - r.y) / listPtr->elementHeight) + listPtr->startPos;
+
+ if (listPtr->cursorPos >= listPtr->endPos)
+ listPtr->cursorPos = listPtr->endPos - 1;
}
- if (listPtr->cursorPos >= count) {
- listPtr->cursorPos = count-1;
+ else
+ listPtr->cursorPos = -1;
+ }
+}
+
+void Item_MouseEnter(itemDef_t *item, float x, float y)
+{
+ rectDef_t r;
+
+ if (item)
+ {
+ r = item->textRect;
+ r.y -= r.h;
+ // in the text rect?
+
+ // items can be enabled and disabled based on cvars
+
+ if (item->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(item, CVAR_ENABLE))
+ return;
+
+ if (item->cvarFlags & (CVAR_SHOW | CVAR_HIDE) && !Item_EnableShowViaCvar(item, CVAR_SHOW))
+ return;
+
+ if (Rect_ContainsPoint(&r, x, y))
+ {
+ if (!(item->window.flags & WINDOW_MOUSEOVERTEXT))
+ {
+ Item_RunScript(item, item->mouseEnterText);
+ item->window.flags |= WINDOW_MOUSEOVERTEXT;
+ }
+
+ if (!(item->window.flags & WINDOW_MOUSEOVER))
+ {
+ Item_RunScript(item, item->mouseEnter);
+ item->window.flags |= WINDOW_MOUSEOVER;
+ }
}
- if (listPtr->cursorPos >= listPtr->startPos + viewmax) {
- listPtr->startPos = listPtr->cursorPos - viewmax + 1;
+ else
+ {
+ // not in the text rect
+
+ if (item->window.flags & WINDOW_MOUSEOVERTEXT)
+ {
+ // if we were
+ Item_RunScript(item, item->mouseExitText);
+ item->window.flags &= ~WINDOW_MOUSEOVERTEXT;
+ }
+
+ if (!(item->window.flags & WINDOW_MOUSEOVER))
+ {
+ Item_RunScript(item, item->mouseEnter);
+ item->window.flags |= WINDOW_MOUSEOVER;
+ }
+
+ if (item->type == ITEM_TYPE_LISTBOX)
+ Item_ListBox_MouseEnter(item, x, y);
}
- item->cursorPos = listPtr->cursorPos;
- DC->feederSelection(item->special, item->cursorPos);
- }
- else {
- listPtr->startPos += viewmax;
- if (listPtr->startPos > max) {
- listPtr->startPos = max;
+ }
+}
+
+void Item_MouseLeave(itemDef_t *item)
+{
+ if (item)
+ {
+ if (item->window.flags & WINDOW_MOUSEOVERTEXT)
+ {
+ Item_RunScript(item, item->mouseExitText);
+ item->window.flags &= ~WINDOW_MOUSEOVERTEXT;
}
- }
- return qtrue;
+
+ Item_RunScript(item, item->mouseExit);
+ item->window.flags &= ~(WINDOW_LB_DOWNARROW | WINDOW_LB_UPARROW);
}
- }
- return qfalse;
}
-qboolean Item_YesNo_HandleKey(itemDef_t *item, int key) {
+itemDef_t *Menu_HitTest(menuDef_t *menu, float x, float y)
+{
+ int i;
- if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS && item->cvar) {
- if (key == K_MOUSE1 || key == K_ENTER || key == K_MOUSE2 || key == K_MOUSE3) {
- DC->setCVar(item->cvar, va("%i", !DC->getCVarValue(item->cvar)));
- return qtrue;
+ for (i = 0; i < menu->itemCount; i++)
+ {
+ if (Rect_ContainsPoint(&menu->items[i]->window.rect, x, y))
+ return menu->items[i];
}
- }
- return qfalse;
+ return NULL;
+}
+void Item_SetMouseOver(itemDef_t *item, qboolean focus)
+{
+ if (item)
+ {
+ if (focus)
+ item->window.flags |= WINDOW_MOUSEOVER;
+ else
+ item->window.flags &= ~WINDOW_MOUSEOVER;
+ }
}
-int Item_Multi_CountSettings(itemDef_t *item) {
- multiDef_t *multiPtr = (multiDef_t*)item->typeData;
- if (multiPtr == NULL) {
- return 0;
- }
- return multiPtr->count;
-}
-
-int Item_Multi_FindCvarByValue(itemDef_t *item) {
- char buff[1024];
- float value = 0;
- int i;
- multiDef_t *multiPtr = (multiDef_t*)item->typeData;
- if (multiPtr) {
- if (multiPtr->strDef) {
- DC->getCVarString(item->cvar, buff, sizeof(buff));
- } else {
- value = DC->getCVarValue(item->cvar);
- }
- for (i = 0; i < multiPtr->count; i++) {
- if (multiPtr->strDef) {
- if (Q_stricmp(buff, multiPtr->cvarStr[i]) == 0) {
- return i;
- }
- } else {
- if (multiPtr->cvarValue[i] == value) {
- return i;
- }
- }
- }
- }
- return 0;
-}
-
-const char *Item_Multi_Setting(itemDef_t *item) {
- char buff[1024];
- float value = 0;
- int i;
- multiDef_t *multiPtr = (multiDef_t*)item->typeData;
- if (multiPtr) {
- if (multiPtr->strDef) {
- DC->getCVarString(item->cvar, buff, sizeof(buff));
- } else {
- value = DC->getCVarValue(item->cvar);
- }
- for (i = 0; i < multiPtr->count; i++) {
- if (multiPtr->strDef) {
- if (Q_stricmp(buff, multiPtr->cvarStr[i]) == 0) {
- return multiPtr->cvarList[i];
- }
- } else {
- if (multiPtr->cvarValue[i] == value) {
- return multiPtr->cvarList[i];
- }
- }
- }
- }
- return "";
-}
-
-qboolean Item_Multi_HandleKey(itemDef_t *item, int key) {
- multiDef_t *multiPtr = (multiDef_t*)item->typeData;
- if (multiPtr) {
- if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS && item->cvar) {
- if (key == K_MOUSE1 || key == K_ENTER || key == K_MOUSE2 || key == K_MOUSE3) {
- int current = Item_Multi_FindCvarByValue(item) + 1;
- int max = Item_Multi_CountSettings(item);
- if ( current < 0 || current >= max ) {
- current = 0;
- }
- if (multiPtr->strDef) {
- DC->setCVar(item->cvar, multiPtr->cvarStr[current]);
- } else {
- float value = multiPtr->cvarValue[current];
- if (((float)((int) value)) == value) {
- DC->setCVar(item->cvar, va("%i", (int) value ));
- }
- else {
- DC->setCVar(item->cvar, va("%f", value ));
- }
+qboolean Item_OwnerDraw_HandleKey(itemDef_t *item, int key)
+{
+ if (item && DC->ownerDrawHandleKey)
+ return DC->ownerDrawHandleKey(item->window.ownerDraw, key);
+
+ return qfalse;
+}
+
+qboolean Item_ListBox_HandleKey(itemDef_t *item, int key, qboolean down, qboolean force)
+{
+ listBoxDef_t *listPtr = item->typeData.list;
+ int count = DC->feederCount(item->feederID);
+ int viewmax;
+
+ if (force ||
+ (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS))
+ {
+ viewmax = Item_ListBox_NumItemsForItemHeight(item);
+
+ switch (key)
+ {
+ case K_MOUSE1:
+ case K_MOUSE2:
+ if (item->window.flags & WINDOW_LB_UPARROW)
+ Item_ListBox_SetStartPos(item, listPtr->startPos - 1);
+ else if (item->window.flags & WINDOW_LB_DOWNARROW)
+ Item_ListBox_SetStartPos(item, listPtr->startPos + 1);
+ else if (item->window.flags & WINDOW_LB_PGUP)
+ Item_ListBox_SetStartPos(item, listPtr->startPos - viewmax);
+ else if (item->window.flags & WINDOW_LB_PGDN)
+ Item_ListBox_SetStartPos(item, listPtr->startPos + viewmax);
+ else if (item->window.flags & WINDOW_LB_THUMB)
+ break; // Handled by capture function
+ else
+ {
+ // Select an item
+ qboolean runDoubleClick = qfalse;
+
+ // Mouse isn't over an item
+ if (listPtr->cursorPos < 0)
+ break;
+
+ if (item->cursorPos != listPtr->cursorPos)
+ {
+ item->cursorPos = listPtr->cursorPos;
+ DC->feederSelection(item->feederID, item->cursorPos);
+ }
+
+ runDoubleClick = DC->realTime < lastListBoxClickTime && listPtr->doubleClick;
+ lastListBoxClickTime = DC->realTime + DOUBLE_CLICK_DELAY;
+
+ // Made a selection, so close combobox
+ if (g_comboBoxItem != NULL)
+ {
+ if (listPtr->doubleClick)
+ runDoubleClick = qtrue;
+
+ g_comboBoxItem = NULL;
+ }
+
+ if (runDoubleClick)
+ Item_RunScript(item, listPtr->doubleClick);
+ }
+
+ break;
+
+ case K_MWHEELUP:
+ Item_ListBox_SetStartPos(item, listPtr->startPos - 1);
+ break;
+
+ case K_MWHEELDOWN:
+ Item_ListBox_SetStartPos(item, listPtr->startPos + 1);
+ break;
+
+ case K_ENTER:
+ // Invoke the doubleClick handler when enter is pressed
+ if (listPtr->doubleClick)
+ Item_RunScript(item, listPtr->doubleClick);
+
+ break;
+
+ case K_PGUP:
+ case K_KP_PGUP:
+ if (!listPtr->notselectable)
+ {
+ listPtr->cursorPos -= viewmax;
+
+ if (listPtr->cursorPos < 0)
+ listPtr->cursorPos = 0;
+
+ if (listPtr->cursorPos < listPtr->startPos)
+ Item_ListBox_SetStartPos(item, listPtr->cursorPos);
+
+ if (listPtr->cursorPos >= listPtr->startPos + viewmax)
+ Item_ListBox_SetStartPos(item, listPtr->cursorPos - viewmax + 1);
+
+ item->cursorPos = listPtr->cursorPos;
+ DC->feederSelection(item->feederID, item->cursorPos);
+ }
+ else
+ Item_ListBox_SetStartPos(item, listPtr->startPos - viewmax);
+
+ break;
+
+ case K_PGDN:
+ case K_KP_PGDN:
+ if (!listPtr->notselectable)
+ {
+ listPtr->cursorPos += viewmax;
+
+ if (listPtr->cursorPos < listPtr->startPos)
+ Item_ListBox_SetStartPos(item, listPtr->cursorPos);
+
+ if (listPtr->cursorPos >= count)
+ listPtr->cursorPos = count - 1;
+
+ if (listPtr->cursorPos >= listPtr->startPos + viewmax)
+ Item_ListBox_SetStartPos(item, listPtr->cursorPos - viewmax + 1);
+
+ item->cursorPos = listPtr->cursorPos;
+ DC->feederSelection(item->feederID, item->cursorPos);
+ }
+ else
+ Item_ListBox_SetStartPos(item, listPtr->startPos + viewmax);
+
+ break;
+
+ default:
+ // Not handled
+ return qfalse;
}
+
return qtrue;
- }
}
- }
- return qfalse;
+
+ return qfalse;
}
-qboolean Item_TextField_HandleKey(itemDef_t *item, int key) {
- char buff[1024];
- int len;
- itemDef_t *newItem = NULL;
- editFieldDef_t *editPtr = (editFieldDef_t*)item->typeData;
+qboolean Item_ComboBox_HandleKey(itemDef_t *item, int key, qboolean down, qboolean force)
+{
+ if (g_comboBoxItem != NULL)
+ {
+ qboolean result;
- if (item->cvar) {
+ qboolean cast = Item_ComboBox_MaybeCastToListBox(item);
+ result = Item_ListBox_HandleKey(item, key, down, force);
+ Item_ComboBox_MaybeUnCastFromListBox(item, cast);
- memset(buff, 0, sizeof(buff));
- DC->getCVarString(item->cvar, buff, sizeof(buff));
- len = strlen(buff);
- if (editPtr->maxChars && len > editPtr->maxChars) {
- len = editPtr->maxChars;
- }
- if ( key & K_CHAR_FLAG ) {
- key &= ~K_CHAR_FLAG;
+ if (!result)
+ g_comboBoxItem = NULL;
+ return result;
+ }
+ else
+ {
+ if (force ||
+ (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS))
+ {
+ if (key == K_MOUSE1 || key == K_MOUSE2)
+ {
+ g_comboBoxItem = item;
- if (key == 'h' - 'a' + 1 ) { // ctrl-h is backspace
- if ( item->cursorPos > 0 ) {
- memmove( &buff[item->cursorPos - 1], &buff[item->cursorPos], len + 1 - item->cursorPos);
- item->cursorPos--;
- if (item->cursorPos < editPtr->paintOffset) {
- editPtr->paintOffset--;
- }
+ return qtrue;
+ }
}
- DC->setCVar(item->cvar, buff);
- return qtrue;
- }
+ }
+ return qfalse;
+}
- //
- // ignore any non printable chars
- //
- if ( key < 32 || !item->cvar) {
- return qtrue;
+qboolean Item_YesNo_HandleKey(itemDef_t *item, int key)
+{
+ if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && item->window.flags & WINDOW_HASFOCUS &&
+ item->cvar)
+ {
+ if (key == K_MOUSE1 || key == K_ENTER || key == K_MOUSE2 || key == K_MOUSE3)
+ {
+ DC->setCVar(item->cvar, va("%i", !DC->getCVarValue(item->cvar)));
+ return qtrue;
}
+ }
+
+ return qfalse;
+}
+
+int Item_Multi_CountSettings(itemDef_t *item)
+{
+ if (item->typeData.multi == NULL)
+ return 0;
+
+ return item->typeData.multi->count;
+}
+
+int Item_Multi_FindCvarByValue(itemDef_t *item)
+{
+ char buff[1024];
+ float value = 0;
+ int i;
+ multiDef_t *multiPtr = item->typeData.multi;
+
+ if (multiPtr)
+ {
+ if (multiPtr->strDef)
+ DC->getCVarString(item->cvar, buff, sizeof(buff));
+ else
+ value = DC->getCVarValue(item->cvar);
- if (item->type == ITEM_TYPE_NUMERICFIELD) {
- if (key < '0' || key > '9') {
- return qfalse;
+ for (i = 0; i < multiPtr->count; i++)
+ {
+ if (multiPtr->strDef)
+ {
+ if (Q_stricmp(buff, multiPtr->cvarStr[i]) == 0)
+ return i;
+ }
+ else
+ {
+ if (multiPtr->cvarValue[i] == value)
+ return i;
+ }
}
- }
+ }
- if (!DC->getOverstrikeMode()) {
- if (( len == MAX_EDITFIELD - 1 ) || (editPtr->maxChars && len >= editPtr->maxChars)) {
- return qtrue;
+ return 0;
+}
+
+const char *Item_Multi_Setting(itemDef_t *item)
+{
+ char buff[1024];
+ float value = 0;
+ int i;
+ multiDef_t *multiPtr = item->typeData.multi;
+
+ if (multiPtr)
+ {
+ if (multiPtr->strDef)
+ DC->getCVarString(item->cvar, buff, sizeof(buff));
+ else
+ value = DC->getCVarValue(item->cvar);
+
+ for (i = 0; i < multiPtr->count; i++)
+ {
+ if (multiPtr->strDef)
+ {
+ if (Q_stricmp(buff, multiPtr->cvarStr[i]) == 0)
+ return multiPtr->cvarList[i];
+ }
+ else
+ {
+ if (multiPtr->cvarValue[i] == value)
+ return multiPtr->cvarList[i];
+ }
}
- memmove( &buff[item->cursorPos + 1], &buff[item->cursorPos], len + 1 - item->cursorPos );
- } else {
- if (editPtr->maxChars && item->cursorPos >= editPtr->maxChars) {
- return qtrue;
+ }
+
+ return "";
+}
+
+qboolean Item_Cycle_HandleKey(itemDef_t *item, int key)
+{
+ cycleDef_t *cyclePtr = item->typeData.cycle;
+ qboolean mouseOver = Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory);
+ int count = DC->feederCount(item->feederID);
+
+ if (cyclePtr)
+ {
+ if (item->window.flags & WINDOW_HASFOCUS)
+ {
+ if ((mouseOver && key == K_MOUSE1) || key == K_ENTER || key == K_RIGHTARROW || key == K_DOWNARROW)
+ {
+ if (count > 0)
+ cyclePtr->cursorPos = (cyclePtr->cursorPos + 1) % count;
+
+ DC->feederSelection(item->feederID, cyclePtr->cursorPos);
+
+ return qtrue;
+ }
+ else if ((mouseOver && key == K_MOUSE2) || key == K_LEFTARROW || key == K_UPARROW)
+ {
+ if (count > 0)
+ cyclePtr->cursorPos = (count + cyclePtr->cursorPos - 1) % count;
+
+ DC->feederSelection(item->feederID, cyclePtr->cursorPos);
+
+ return qtrue;
+ }
}
- }
+ }
+
+ return qfalse;
+}
- buff[item->cursorPos] = key;
+qboolean Item_Multi_HandleKey(itemDef_t *item, int key)
+{
+ qboolean mouseOver = Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory);
+ int max = Item_Multi_CountSettings(item);
+ qboolean changed = qfalse;
- DC->setCVar(item->cvar, buff);
+ if (item->typeData.multi)
+ {
+ if (item->window.flags & WINDOW_HASFOCUS && item->cvar && max > 0)
+ {
+ int current;
+
+ if ((mouseOver && key == K_MOUSE1) || key == K_ENTER || key == K_RIGHTARROW || key == K_DOWNARROW)
+ {
+ current = (Item_Multi_FindCvarByValue(item) + 1) % max;
+ changed = qtrue;
+ }
+ else if ((mouseOver && key == K_MOUSE2) || key == K_LEFTARROW || key == K_UPARROW)
+ {
+ current = (Item_Multi_FindCvarByValue(item) + max - 1) % max;
+ changed = qtrue;
+ }
- if (item->cursorPos < len + 1) {
- item->cursorPos++;
- if (editPtr->maxPaintChars && item->cursorPos > editPtr->maxPaintChars) {
- editPtr->paintOffset++;
+ if (changed)
+ {
+ if (item->typeData.multi->strDef)
+ DC->setCVar(item->cvar, item->typeData.multi->cvarStr[current]);
+ else
+ {
+ float value = item->typeData.multi->cvarValue[current];
+
+ if (((float)((int)value)) == value)
+ DC->setCVar(item->cvar, va("%i", (int)value));
+ else
+ DC->setCVar(item->cvar, va("%f", value));
+ }
+
+ return qtrue;
+ }
}
- }
+ }
+
+ return qfalse;
+}
- } else {
+#define MIN_FIELD_WIDTH 10
+#define EDIT_CURSOR_WIDTH 10
+
+static void Item_TextField_CalcPaintOffset(itemDef_t *item, char *buff)
+{
+ editFieldDef_t *editPtr = item->typeData.edit;
+
+ if (item->cursorPos < editPtr->paintOffset)
+ editPtr->paintOffset = item->cursorPos;
+ else
+ {
+ // If there is a maximum field width
- if ( key == K_DEL || key == K_KP_DEL ) {
- if ( item->cursorPos < len ) {
- memmove( buff + item->cursorPos, buff + item->cursorPos + 1, len - item->cursorPos);
- DC->setCVar(item->cvar, buff);
+ if (editPtr->maxFieldWidth > 0)
+ {
+ // If the cursor is at the end of the string, maximise the amount of the
+ // string that's visible
+
+ if (buff[item->cursorPos + 1] == '\0')
+ {
+ while (UI_Text_Width(&buff[editPtr->paintOffset], item->textscale) <=
+ (editPtr->maxFieldWidth - EDIT_CURSOR_WIDTH) &&
+ editPtr->paintOffset > 0)
+ editPtr->paintOffset--;
+ }
+
+ buff[item->cursorPos + 1] = '\0';
+
+ // Shift paintOffset so that the cursor is visible
+
+ while (UI_Text_Width(&buff[editPtr->paintOffset], item->textscale) >
+ (editPtr->maxFieldWidth - EDIT_CURSOR_WIDTH))
+ editPtr->paintOffset++;
}
- return qtrue;
- }
+ }
+}
- if ( key == K_RIGHTARROW || key == K_KP_RIGHTARROW )
- {
- if (editPtr->maxPaintChars && item->cursorPos >= editPtr->maxPaintChars && item->cursorPos < len) {
- item->cursorPos++;
- editPtr->paintOffset++;
- return qtrue;
+qboolean Item_TextField_HandleKey(itemDef_t *item, int key)
+{
+ char buff[1024];
+ int len;
+ itemDef_t *newItem = NULL;
+ editFieldDef_t *editPtr = item->typeData.edit;
+ qboolean releaseFocus = qtrue;
+
+ if (item->cvar)
+ {
+ Com_Memset(buff, 0, sizeof(buff));
+ DC->getCVarString(item->cvar, buff, sizeof(buff));
+ len = strlen(buff);
+
+ if (len < item->cursorPos)
+ item->cursorPos = len;
+
+ if (editPtr->maxChars && len > editPtr->maxChars)
+ len = editPtr->maxChars;
+
+ if (key & K_CHAR_FLAG)
+ {
+ key &= ~K_CHAR_FLAG;
+
+ if (key == 'h' - 'a' + 1)
+ {
+ // ctrl-h is backspace
+
+ if (item->cursorPos > 0)
+ {
+ memmove(&buff[item->cursorPos - 1], &buff[item->cursorPos], len + 1 - item->cursorPos);
+ item->cursorPos--;
+ }
+
+ DC->setCVar(item->cvar, buff);
+ }
+ else if (key < 32 || !item->cvar)
+ {
+ // Ignore any non printable chars
+ releaseFocus = qfalse;
+ goto exit;
+ }
+ else if (item->type == ITEM_TYPE_NUMERICFIELD && (key < '0' || key > '9'))
+ {
+ // Ignore non-numeric characters
+ releaseFocus = qfalse;
+ goto exit;
+ }
+ else
+ {
+ if (!DC->getOverstrikeMode())
+ {
+ if ((len == MAX_EDITFIELD - 1) || (editPtr->maxChars && len >= editPtr->maxChars))
+ {
+ // Reached maximum field length
+ releaseFocus = qfalse;
+ goto exit;
+ }
+
+ memmove(&buff[item->cursorPos + 1], &buff[item->cursorPos], len + 1 - item->cursorPos);
+ }
+ else
+ {
+ // Reached maximum field length
+ if (editPtr->maxChars && item->cursorPos >= editPtr->maxChars)
+ {
+ releaseFocus = qfalse;
+ goto exit;
+ }
+ }
+
+ buff[item->cursorPos] = key;
+
+ DC->setCVar(item->cvar, buff);
+
+ if (item->cursorPos < len + 1)
+ item->cursorPos++;
+ }
}
- if (item->cursorPos < len) {
- item->cursorPos++;
+ else
+ {
+ switch (key)
+ {
+ case K_DEL:
+ case K_KP_DEL:
+ if (item->cursorPos < len)
+ {
+ memmove(buff + item->cursorPos, buff + item->cursorPos + 1, len - item->cursorPos);
+ DC->setCVar(item->cvar, buff);
+ }
+
+ break;
+
+ case K_RIGHTARROW:
+ case K_KP_RIGHTARROW:
+ if (item->cursorPos < len)
+ item->cursorPos++;
+
+ break;
+
+ case K_LEFTARROW:
+ case K_KP_LEFTARROW:
+ if (item->cursorPos > 0)
+ item->cursorPos--;
+
+ break;
+
+ case K_HOME:
+ case K_KP_HOME:
+ item->cursorPos = 0;
+
+ break;
+
+ case K_END:
+ case K_KP_END:
+ item->cursorPos = len;
+
+ break;
+
+ case K_INS:
+ case K_KP_INS:
+ DC->setOverstrikeMode(!DC->getOverstrikeMode());
+
+ break;
+
+ case K_TAB:
+ case K_DOWNARROW:
+ case K_KP_DOWNARROW:
+ case K_UPARROW:
+ case K_KP_UPARROW:
+ // Ignore these keys from the say field
+ if (item->type == ITEM_TYPE_SAYFIELD)
+ break;
+
+ newItem = Menu_SetNextCursorItem(item->parent);
+
+ if (newItem && Item_IsEditField(newItem))
+ {
+ g_editItem = newItem;
+ }
+ else
+ {
+ releaseFocus = qtrue;
+ goto exit;
+ }
+
+ break;
+
+ case K_MOUSE1:
+ case K_MOUSE2:
+ case K_MOUSE3:
+ case K_MOUSE4:
+ // Ignore these buttons from the say field
+ if (item->type == ITEM_TYPE_SAYFIELD)
+ break;
+ // FALLTHROUGH
+ case K_ENTER:
+ case K_KP_ENTER:
+ case K_ESCAPE:
+ releaseFocus = qtrue;
+ goto exit;
+
+ default:
+ break;
+ }
}
- return qtrue;
- }
- if ( key == K_LEFTARROW || key == K_KP_LEFTARROW )
- {
- if ( item->cursorPos > 0 ) {
- item->cursorPos--;
+ releaseFocus = qfalse;
+ }
+
+exit:
+ Item_TextField_CalcPaintOffset(item, buff);
+
+ return !releaseFocus;
+}
+
+static void _Scroll_ListBox_AutoFunc(scrollInfo_t *si)
+{
+ if (DC->realTime > si->nextScrollTime)
+ {
+ // need to scroll which is done by simulating a click to the item
+ // this is done a bit sideways as the autoscroll "knows" that the item is a listbox
+ // so it calls it directly
+ Item_ListBox_HandleKey(si->item, si->scrollKey, qtrue, qfalse);
+
+ si->nextScrollTime = DC->realTime + si->adjustValue;
+ }
+
+ if (DC->realTime > si->nextAdjustTime)
+ {
+ si->nextAdjustTime = DC->realTime + SCROLL_TIME_ADJUST;
+
+ if (si->adjustValue > SCROLL_TIME_FLOOR)
+ si->adjustValue -= SCROLL_TIME_ADJUSTOFFSET;
+ }
+}
+
+static void Scroll_ListBox_AutoFunc(void *p)
+{
+ scrollInfo_t *si = (scrollInfo_t *)p;
+
+ qboolean cast = Item_ComboBox_MaybeCastToListBox(si->item);
+ _Scroll_ListBox_AutoFunc(si);
+ Item_ComboBox_MaybeUnCastFromListBox(si->item, cast);
+}
+
+static void _Scroll_ListBox_ThumbFunc(scrollInfo_t *si)
+{
+ rectDef_t r;
+ int pos, max;
+
+ if (DC->cursory != si->yStart)
+ {
+ r.x = si->item->window.rect.x + si->item->window.rect.w - SCROLLBAR_ARROW_WIDTH - 1;
+ r.y = si->item->window.rect.y + SCROLLBAR_ARROW_HEIGHT + 1;
+ r.w = SCROLLBAR_ARROW_WIDTH;
+ r.h = si->item->window.rect.h - (SCROLLBAR_ARROW_HEIGHT * 2) - 2;
+ max = Item_ListBox_MaxScroll(si->item);
+ //
+ pos = (DC->cursory - r.y - SCROLLBAR_ARROW_HEIGHT / 2) * max / (r.h - SCROLLBAR_ARROW_HEIGHT);
+
+ if (pos < 0)
+ pos = 0;
+ else if (pos > max)
+ pos = max;
+
+ Item_ListBox_SetStartPos(si->item, pos);
+ si->yStart = DC->cursory;
+ }
+
+ if (DC->realTime > si->nextScrollTime)
+ {
+ // need to scroll which is done by simulating a click to the item
+ // this is done a bit sideways as the autoscroll "knows" that the item is a listbox
+ // so it calls it directly
+ Item_ListBox_HandleKey(si->item, si->scrollKey, qtrue, qfalse);
+
+ si->nextScrollTime = DC->realTime + si->adjustValue;
+ }
+
+ if (DC->realTime > si->nextAdjustTime)
+ {
+ si->nextAdjustTime = DC->realTime + SCROLL_TIME_ADJUST;
+
+ if (si->adjustValue > SCROLL_TIME_FLOOR)
+ si->adjustValue -= SCROLL_TIME_ADJUSTOFFSET;
+ }
+}
+
+static void Scroll_ListBox_ThumbFunc(void *p)
+{
+ scrollInfo_t *si = (scrollInfo_t *)p;
+
+ qboolean cast = Item_ComboBox_MaybeCastToListBox(si->item);
+ _Scroll_ListBox_ThumbFunc(si);
+ Item_ComboBox_MaybeUnCastFromListBox(si->item, cast);
+}
+
+static void Scroll_Slider_ThumbFunc(void *p)
+{
+ float x, value, cursorx;
+ scrollInfo_t *si = (scrollInfo_t *)p;
+
+ if (si->item->text)
+ x = si->item->textRect.x + si->item->textRect.w + ITEM_VALUE_OFFSET;
+ else
+ x = si->item->window.rect.x;
+
+ cursorx = DC->cursorx;
+
+ if (cursorx < x)
+ cursorx = x;
+ else if (cursorx > x + SLIDER_WIDTH)
+ cursorx = x + SLIDER_WIDTH;
+
+ value = cursorx - x;
+ value /= SLIDER_WIDTH;
+ value *= si->item->typeData.edit->maxVal - si->item->typeData.edit->minVal;
+ value += si->item->typeData.edit->minVal;
+ DC->setCVar(si->item->cvar, va("%f", value));
+}
+
+void Item_StartCapture(itemDef_t *item, int key)
+{
+ int flags;
+
+ // Don't allow captureFunc to be overridden
+
+ if (captureFunc != voidFunction)
+ return;
+
+ switch (item->type)
+ {
+ case ITEM_TYPE_LISTBOX:
+ case ITEM_TYPE_COMBOBOX:
+ {
+ qboolean cast = Item_ComboBox_MaybeCastToListBox(item);
+ flags = Item_ListBox_OverLB(item, DC->cursorx, DC->cursory);
+ Item_ComboBox_MaybeUnCastFromListBox(item, cast);
+
+ if (flags & (WINDOW_LB_UPARROW | WINDOW_LB_DOWNARROW))
+ {
+ scrollInfo.nextScrollTime = DC->realTime + SCROLL_TIME_START;
+ scrollInfo.nextAdjustTime = DC->realTime + SCROLL_TIME_ADJUST;
+ scrollInfo.adjustValue = SCROLL_TIME_START;
+ scrollInfo.scrollKey = key;
+ scrollInfo.scrollDir = (flags & WINDOW_LB_UPARROW) ? qtrue : qfalse;
+ scrollInfo.item = item;
+ UI_InstallCaptureFunc(Scroll_ListBox_AutoFunc, &scrollInfo, 0);
+ itemCapture = item;
+ }
+ else if (flags & WINDOW_LB_THUMB)
+ {
+ scrollInfo.scrollKey = key;
+ scrollInfo.item = item;
+ scrollInfo.xStart = DC->cursorx;
+ scrollInfo.yStart = DC->cursory;
+ UI_InstallCaptureFunc(Scroll_ListBox_ThumbFunc, &scrollInfo, 0);
+ itemCapture = item;
+ }
+
+ break;
}
- if (item->cursorPos < editPtr->paintOffset) {
- editPtr->paintOffset--;
+
+ case ITEM_TYPE_SLIDER:
+ {
+ flags = Item_Slider_OverSlider(item, DC->cursorx, DC->cursory);
+
+ if (flags & WINDOW_LB_THUMB)
+ {
+ scrollInfo.scrollKey = key;
+ scrollInfo.item = item;
+ scrollInfo.xStart = DC->cursorx;
+ scrollInfo.yStart = DC->cursory;
+ UI_InstallCaptureFunc(Scroll_Slider_ThumbFunc, &scrollInfo, 0);
+ itemCapture = item;
+ }
+
+ break;
}
- return qtrue;
- }
+ }
+}
- if ( key == K_HOME || key == K_KP_HOME) {// || ( tolower(key) == 'a' && trap_Key_IsDown( K_CTRL ) ) ) {
- item->cursorPos = 0;
- editPtr->paintOffset = 0;
- return qtrue;
- }
+void Item_StopCapture(itemDef_t *item) {}
+
+qboolean Item_Slider_HandleKey(itemDef_t *item, int key, qboolean down)
+{
+ float x, value, width;
- if ( key == K_END || key == K_KP_END) {// ( tolower(key) == 'e' && trap_Key_IsDown( K_CTRL ) ) ) {
- item->cursorPos = len;
- if(item->cursorPos > editPtr->maxPaintChars) {
- editPtr->paintOffset = len - editPtr->maxPaintChars;
+ if (item->window.flags & WINDOW_HASFOCUS && item->cvar &&
+ Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory))
+ {
+ if (item->typeData.edit && (key == K_ENTER || key == K_MOUSE1 || key == K_MOUSE2 || key == K_MOUSE3))
+ {
+ rectDef_t testRect;
+ width = SLIDER_WIDTH;
+
+ if (item->text)
+ x = item->textRect.x + item->textRect.w + ITEM_VALUE_OFFSET;
+ else
+ x = item->window.rect.x;
+
+ testRect = item->window.rect;
+ value = (float)SLIDER_THUMB_WIDTH / 2;
+ testRect.x = x - value;
+ testRect.w = SLIDER_WIDTH + value;
+
+ if (Rect_ContainsPoint(&testRect, DC->cursorx, DC->cursory))
+ {
+ value = (float)(DC->cursorx - x) / width;
+ value *= (item->typeData.edit->maxVal - item->typeData.edit->minVal);
+ value += item->typeData.edit->minVal;
+ DC->setCVar(item->cvar, va("%f", value));
+ return qtrue;
+ }
}
- return qtrue;
- }
+ }
- if ( key == K_INS || key == K_KP_INS ) {
- DC->setOverstrikeMode(!DC->getOverstrikeMode());
- return qtrue;
- }
+ return qfalse;
+}
+
+qboolean Item_HandleKey(itemDef_t *item, int key, qboolean down)
+{
+ if (itemCapture)
+ {
+ Item_StopCapture(itemCapture);
+ itemCapture = NULL;
+ UI_RemoveCaptureFunc();
+ }
+ else
+ {
+ if (down && (key == K_MOUSE1 || key == K_MOUSE2 || key == K_MOUSE3))
+ Item_StartCapture(item, key);
}
- if (key == K_TAB || key == K_DOWNARROW || key == K_KP_DOWNARROW) {
- if (item->type == ITEM_TYPE_SAYFIELD) {
- return qtrue;
- }
+ if (!down)
+ return qfalse;
+
+ // Edit fields are handled specially
+ if (Item_IsEditField(item))
+ return qfalse;
+
+ switch (item->type)
+ {
+ case ITEM_TYPE_BUTTON:
+ return qfalse;
+
+ case ITEM_TYPE_RADIOBUTTON:
+ return qfalse;
+
+ case ITEM_TYPE_CHECKBOX:
+ return qfalse;
+
+ case ITEM_TYPE_CYCLE:
+ return Item_Cycle_HandleKey(item, key);
- newItem = Menu_SetNextCursorItem(item->parent);
- if (newItem && (newItem->type == ITEM_TYPE_EDITFIELD || newItem->type == ITEM_TYPE_SAYFIELD || newItem->type == ITEM_TYPE_NUMERICFIELD)) {
- g_editItem = newItem;
- }
+ case ITEM_TYPE_LISTBOX:
+ return Item_ListBox_HandleKey(item, key, down, qfalse);
+
+ case ITEM_TYPE_COMBOBOX:
+ return Item_ComboBox_HandleKey(item, key, down, qfalse);
+
+ case ITEM_TYPE_YESNO:
+ return Item_YesNo_HandleKey(item, key);
+
+ case ITEM_TYPE_MULTI:
+ return Item_Multi_HandleKey(item, key);
+
+ case ITEM_TYPE_OWNERDRAW:
+ return Item_OwnerDraw_HandleKey(item, key);
+
+ case ITEM_TYPE_BIND:
+ return Item_Bind_HandleKey(item, key, down);
+
+ case ITEM_TYPE_SLIDER:
+ return Item_Slider_HandleKey(item, key, down);
+
+ default:
+ return qfalse;
}
+}
- if (key == K_UPARROW || key == K_KP_UPARROW) {
- if (item->type == ITEM_TYPE_SAYFIELD) {
- return qtrue;
- }
+void Item_Action(itemDef_t *item)
+{
+ if (item)
+ Item_RunScript(item, item->action);
+}
+
+itemDef_t *Menu_SetPrevCursorItem(menuDef_t *menu)
+{
+ qboolean wrapped = qfalse;
+ int oldCursor = menu->cursorItem;
- newItem = Menu_SetPrevCursorItem(item->parent);
- if (newItem && (newItem->type == ITEM_TYPE_EDITFIELD || newItem->type == ITEM_TYPE_SAYFIELD || newItem->type == ITEM_TYPE_NUMERICFIELD)) {
- g_editItem = newItem;
- }
+ if (menu->cursorItem < 0)
+ {
+ menu->cursorItem = menu->itemCount - 1;
+ wrapped = qtrue;
}
- if (key == K_MOUSE1 || key == K_MOUSE2 || key == K_MOUSE3 || key == K_MOUSE4) {
- if (item->type == ITEM_TYPE_SAYFIELD) {
- return qtrue;
- }
- return qfalse;
+ while (menu->cursorItem > -1)
+ {
+ menu->cursorItem--;
+
+ if (menu->cursorItem < 0 && !wrapped)
+ {
+ wrapped = qtrue;
+ menu->cursorItem = menu->itemCount - 1;
+ }
+
+ if (Item_SetFocus(menu->items[menu->cursorItem], DC->cursorx, DC->cursory))
+ {
+ Menu_HandleMouseMove(menu, menu->items[menu->cursorItem]->window.rect.x + 1,
+ menu->items[menu->cursorItem]->window.rect.y + 1);
+ return menu->items[menu->cursorItem];
+ }
}
- if ( key == K_ENTER || key == K_KP_ENTER || key == K_ESCAPE) {
- return qfalse;
+ menu->cursorItem = oldCursor;
+ return NULL;
+}
+
+itemDef_t *Menu_SetNextCursorItem(menuDef_t *menu)
+{
+ qboolean wrapped = qfalse;
+ int oldCursor = menu->cursorItem;
+
+ if (menu->cursorItem == -1)
+ {
+ menu->cursorItem = 0;
+ wrapped = qtrue;
}
- return qtrue;
- }
- return qfalse;
-
-}
-
-static void Scroll_ListBox_AutoFunc(void *p) {
- scrollInfo_t *si = (scrollInfo_t*)p;
- if (DC->realTime > si->nextScrollTime) {
- // need to scroll which is done by simulating a click to the item
- // this is done a bit sideways as the autoscroll "knows" that the item is a listbox
- // so it calls it directly
- Item_ListBox_HandleKey(si->item, si->scrollKey, qtrue, qfalse);
- si->nextScrollTime = DC->realTime + si->adjustValue;
- }
-
- if (DC->realTime > si->nextAdjustTime) {
- si->nextAdjustTime = DC->realTime + SCROLL_TIME_ADJUST;
- if (si->adjustValue > SCROLL_TIME_FLOOR) {
- si->adjustValue -= SCROLL_TIME_ADJUSTOFFSET;
- }
- }
-}
-
-static void Scroll_ListBox_ThumbFunc(void *p) {
- scrollInfo_t *si = (scrollInfo_t*)p;
- rectDef_t r;
- int pos, max;
-
- listBoxDef_t *listPtr = (listBoxDef_t*)si->item->typeData;
- if (si->item->window.flags & WINDOW_HORIZONTAL) {
- if (DC->cursorx == si->xStart) {
- return;
- }
- r.x = si->item->window.rect.x + SCROLLBAR_SIZE + 1;
- r.y = si->item->window.rect.y + si->item->window.rect.h - SCROLLBAR_SIZE - 1;
- r.h = SCROLLBAR_SIZE;
- r.w = si->item->window.rect.w - (SCROLLBAR_SIZE*2) - 2;
- max = Item_ListBox_MaxScroll(si->item);
- //
- pos = (DC->cursorx - r.x - SCROLLBAR_SIZE/2) * max / (r.w - SCROLLBAR_SIZE);
- if (pos < 0) {
- pos = 0;
- }
- else if (pos > max) {
- pos = max;
- }
- listPtr->startPos = pos;
- si->xStart = DC->cursorx;
- }
- else if (DC->cursory != si->yStart) {
-
- r.x = si->item->window.rect.x + si->item->window.rect.w - SCROLLBAR_SIZE - 1;
- r.y = si->item->window.rect.y + SCROLLBAR_SIZE + 1;
- r.h = si->item->window.rect.h - (SCROLLBAR_SIZE*2) - 2;
- r.w = SCROLLBAR_SIZE;
- max = Item_ListBox_MaxScroll(si->item);
- //
- pos = (DC->cursory - r.y - SCROLLBAR_SIZE/2) * max / (r.h - SCROLLBAR_SIZE);
- if (pos < 0) {
- pos = 0;
- }
- else if (pos > max) {
- pos = max;
- }
- listPtr->startPos = pos;
- si->yStart = DC->cursory;
- }
-
- if (DC->realTime > si->nextScrollTime) {
- // need to scroll which is done by simulating a click to the item
- // this is done a bit sideways as the autoscroll "knows" that the item is a listbox
- // so it calls it directly
- Item_ListBox_HandleKey(si->item, si->scrollKey, qtrue, qfalse);
- si->nextScrollTime = DC->realTime + si->adjustValue;
- }
-
- if (DC->realTime > si->nextAdjustTime) {
- si->nextAdjustTime = DC->realTime + SCROLL_TIME_ADJUST;
- if (si->adjustValue > SCROLL_TIME_FLOOR) {
- si->adjustValue -= SCROLL_TIME_ADJUSTOFFSET;
- }
- }
-}
-
-static void Scroll_Slider_ThumbFunc(void *p) {
- float x, value, cursorx;
- scrollInfo_t *si = (scrollInfo_t*)p;
- editFieldDef_t *editDef = si->item->typeData;
-
- if (si->item->text) {
- x = si->item->textRect.x + si->item->textRect.w + 8;
- } else {
- x = si->item->window.rect.x;
- }
-
- cursorx = DC->cursorx;
-
- if (cursorx < x) {
- cursorx = x;
- } else if (cursorx > x + SLIDER_WIDTH) {
- cursorx = x + SLIDER_WIDTH;
- }
- value = cursorx - x;
- value /= SLIDER_WIDTH;
- value *= (editDef->maxVal - editDef->minVal);
- value += editDef->minVal;
- DC->setCVar(si->item->cvar, va("%f", value));
-}
-
-void Item_StartCapture(itemDef_t *item, int key) {
- int flags;
- switch (item->type) {
- case ITEM_TYPE_EDITFIELD:
- case ITEM_TYPE_SAYFIELD:
- case ITEM_TYPE_NUMERICFIELD:
-
- case ITEM_TYPE_LISTBOX:
- {
- flags = Item_ListBox_OverLB(item, DC->cursorx, DC->cursory);
- if (flags & (WINDOW_LB_LEFTARROW | WINDOW_LB_RIGHTARROW)) {
- scrollInfo.nextScrollTime = DC->realTime + SCROLL_TIME_START;
- scrollInfo.nextAdjustTime = DC->realTime + SCROLL_TIME_ADJUST;
- scrollInfo.adjustValue = SCROLL_TIME_START;
- scrollInfo.scrollKey = key;
- scrollInfo.scrollDir = (flags & WINDOW_LB_LEFTARROW) ? qtrue : qfalse;
- scrollInfo.item = item;
- captureData = &scrollInfo;
- captureFunc = &Scroll_ListBox_AutoFunc;
- itemCapture = item;
- } else if (flags & WINDOW_LB_THUMB) {
- scrollInfo.scrollKey = key;
- scrollInfo.item = item;
- scrollInfo.xStart = DC->cursorx;
- scrollInfo.yStart = DC->cursory;
- captureData = &scrollInfo;
- captureFunc = &Scroll_ListBox_ThumbFunc;
- itemCapture = item;
- }
- break;
- }
- case ITEM_TYPE_SLIDER:
- {
- flags = Item_Slider_OverSlider(item, DC->cursorx, DC->cursory);
- if (flags & WINDOW_LB_THUMB) {
- scrollInfo.scrollKey = key;
- scrollInfo.item = item;
- scrollInfo.xStart = DC->cursorx;
- scrollInfo.yStart = DC->cursory;
- captureData = &scrollInfo;
- captureFunc = &Scroll_Slider_ThumbFunc;
- itemCapture = item;
- }
- break;
- }
- }
-}
-
-void Item_StopCapture(itemDef_t *item) {
-
-}
-
-qboolean Item_Slider_HandleKey(itemDef_t *item, int key, qboolean down) {
- float x, value, width, work;
-
- if (item->window.flags & WINDOW_HASFOCUS && item->cvar && Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory)) {
- if (key == K_MOUSE1 || key == K_ENTER || key == K_MOUSE2 || key == K_MOUSE3) {
- editFieldDef_t *editDef = item->typeData;
- if (editDef) {
- rectDef_t testRect;
- width = SLIDER_WIDTH;
- if (item->text) {
- x = item->textRect.x + item->textRect.w + 8;
- } else {
- x = item->window.rect.x;
- }
-
- testRect = item->window.rect;
- testRect.x = x;
- value = (float)SLIDER_THUMB_WIDTH / 2;
- testRect.x -= value;
- testRect.w = (SLIDER_WIDTH + (float)SLIDER_THUMB_WIDTH / 2);
- if (Rect_ContainsPoint(&testRect, DC->cursorx, DC->cursory)) {
- work = DC->cursorx - x;
- value = work / width;
- value *= (editDef->maxVal - editDef->minVal);
- // vm fuckage
- // value = (((float)(DC->cursorx - x)/ SLIDER_WIDTH) * (editDef->maxVal - editDef->minVal));
- value += editDef->minVal;
- DC->setCVar(item->cvar, va("%f", value));
- return qtrue;
- }
- }
- }
- }
- return qfalse;
-}
-
-
-qboolean Item_HandleKey(itemDef_t *item, int key, qboolean down) {
-
- if (itemCapture) {
- Item_StopCapture(itemCapture);
- itemCapture = NULL;
- captureFunc = voidFunction;
- captureData = NULL;
- } else {
- // bk001206 - parentheses
- if ( down && ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_MOUSE3 ) ) {
- Item_StartCapture(item, key);
+ while (menu->cursorItem < menu->itemCount)
+ {
+ menu->cursorItem++;
+
+ if (menu->cursorItem >= menu->itemCount && !wrapped)
+ {
+ wrapped = qtrue;
+ menu->cursorItem = 0;
+ }
+
+ if (Item_SetFocus(menu->items[menu->cursorItem], DC->cursorx, DC->cursory))
+ {
+ Menu_HandleMouseMove(menu, menu->items[menu->cursorItem]->window.rect.x + 1,
+ menu->items[menu->cursorItem]->window.rect.y + 1);
+ return menu->items[menu->cursorItem];
+ }
}
- }
- if (!down) {
- return qfalse;
- }
-
- switch (item->type) {
- case ITEM_TYPE_BUTTON:
- return qfalse;
- break;
- case ITEM_TYPE_RADIOBUTTON:
- return qfalse;
- break;
- case ITEM_TYPE_CHECKBOX:
- return qfalse;
- break;
- case ITEM_TYPE_EDITFIELD:
- case ITEM_TYPE_SAYFIELD:
- case ITEM_TYPE_NUMERICFIELD:
- //return Item_TextField_HandleKey(item, key);
- return qfalse;
- break;
- case ITEM_TYPE_COMBO:
- return qfalse;
- break;
- case ITEM_TYPE_LISTBOX:
- return Item_ListBox_HandleKey(item, key, down, qfalse);
- break;
- case ITEM_TYPE_YESNO:
- return Item_YesNo_HandleKey(item, key);
- break;
- case ITEM_TYPE_MULTI:
- return Item_Multi_HandleKey(item, key);
- break;
- case ITEM_TYPE_OWNERDRAW:
- return Item_OwnerDraw_HandleKey(item, key);
- break;
- case ITEM_TYPE_BIND:
- return Item_Bind_HandleKey(item, key, down);
- break;
- case ITEM_TYPE_SLIDER:
- return Item_Slider_HandleKey(item, key, down);
- break;
- //case ITEM_TYPE_IMAGE:
- // Item_Image_Paint(item);
- // break;
- default:
- return qfalse;
- break;
- }
-
- //return qfalse;
-}
-
-void Item_Action(itemDef_t *item) {
- if (item) {
- Item_RunScript(item, item->action);
- }
-}
-
-itemDef_t *Menu_SetPrevCursorItem(menuDef_t *menu) {
- qboolean wrapped = qfalse;
- int oldCursor = menu->cursorItem;
-
- if (menu->cursorItem < 0) {
- menu->cursorItem = menu->itemCount-1;
- wrapped = qtrue;
- }
-
- while (menu->cursorItem > -1) {
-
- menu->cursorItem--;
- if (menu->cursorItem < 0 && !wrapped) {
- wrapped = qtrue;
- menu->cursorItem = menu->itemCount -1;
- }
-
- if (Item_SetFocus(menu->items[menu->cursorItem], DC->cursorx, DC->cursory)) {
- Menu_HandleMouseMove(menu, menu->items[menu->cursorItem]->window.rect.x + 1, menu->items[menu->cursorItem]->window.rect.y + 1);
- return menu->items[menu->cursorItem];
- }
- }
- menu->cursorItem = oldCursor;
- return NULL;
-
-}
-
-itemDef_t *Menu_SetNextCursorItem(menuDef_t *menu) {
-
- qboolean wrapped = qfalse;
- int oldCursor = menu->cursorItem;
-
-
- if (menu->cursorItem == -1) {
- menu->cursorItem = 0;
- wrapped = qtrue;
- }
-
- while (menu->cursorItem < menu->itemCount) {
-
- menu->cursorItem++;
- if (menu->cursorItem >= menu->itemCount && !wrapped) {
- wrapped = qtrue;
- menu->cursorItem = 0;
- }
- if (Item_SetFocus(menu->items[menu->cursorItem], DC->cursorx, DC->cursory)) {
- Menu_HandleMouseMove(menu, menu->items[menu->cursorItem]->window.rect.x + 1, menu->items[menu->cursorItem]->window.rect.y + 1);
- return menu->items[menu->cursorItem];
- }
-
- }
-
- menu->cursorItem = oldCursor;
- return NULL;
+ menu->cursorItem = oldCursor;
+ return NULL;
}
-static void Window_CloseCinematic(windowDef_t *window) {
- if (window->style == WINDOW_STYLE_CINEMATIC && window->cinematic >= 0) {
- DC->stopCinematic(window->cinematic);
- window->cinematic = -1;
- }
+static void Window_CloseCinematic(Window *window)
+{
+ if (window->style == WINDOW_STYLE_CINEMATIC && window->cinematic >= 0)
+ {
+ DC->stopCinematic(window->cinematic);
+ window->cinematic = -1;
+ }
}
-static void Menu_CloseCinematics(menuDef_t *menu) {
- if (menu) {
- int i;
- Window_CloseCinematic(&menu->window);
- for (i = 0; i < menu->itemCount; i++) {
- Window_CloseCinematic(&menu->items[i]->window);
- if (menu->items[i]->type == ITEM_TYPE_OWNERDRAW) {
- DC->stopCinematic(0-menu->items[i]->window.ownerDraw);
- }
+static void Menu_CloseCinematics(menuDef_t *menu)
+{
+ if (menu)
+ {
+ int i;
+ Window_CloseCinematic(&menu->window);
+
+ for (i = 0; i < menu->itemCount; i++)
+ {
+ Window_CloseCinematic(&menu->items[i]->window);
+
+ if (menu->items[i]->type == ITEM_TYPE_OWNERDRAW)
+ DC->stopCinematic(0 - menu->items[i]->window.ownerDraw);
+ }
}
- }
}
-static void Display_CloseCinematics( void ) {
- int i;
- for (i = 0; i < menuCount; i++) {
- Menu_CloseCinematics(&Menus[i]);
- }
+static void Display_CloseCinematics(void)
+{
+ int i;
+
+ for (i = 0; i < menuCount; i++)
+ Menu_CloseCinematics(&Menus[i]);
}
-void Menus_Activate(menuDef_t *menu) {
- menu->window.flags |= (WINDOW_HASFOCUS | WINDOW_VISIBLE);
- if (menu->onOpen) {
- itemDef_t item;
- item.parent = menu;
- Item_RunScript(&item, menu->onOpen);
- }
+void Menus_Activate(menuDef_t *menu)
+{
+ int i;
+ qboolean onTopOfMenuStack = qfalse;
- if (menu->soundName && *menu->soundName) {
-// DC->stopBackgroundTrack(); // you don't want to do this since it will reset s_rawend
- DC->startBackgroundTrack(menu->soundName, menu->soundName);
- }
+ if (openMenuCount > 0 && menuStack[openMenuCount - 1] == menu)
+ onTopOfMenuStack = qtrue;
- Display_CloseCinematics();
+ menu->window.flags |= (WINDOW_HASFOCUS | WINDOW_VISIBLE);
-}
+ // If being opened for the first time
+ if (!onTopOfMenuStack)
+ {
+ if (menu->onOpen)
+ {
+ itemDef_t item;
+ item.parent = menu;
+ Item_RunScript(&item, menu->onOpen);
+ }
+
+ if (menu->soundName && *menu->soundName)
+ DC->startBackgroundTrack(menu->soundName, menu->soundName);
+
+ Display_CloseCinematics();
-int Display_VisibleMenuCount( void ) {
- int i, count;
- count = 0;
- for (i = 0; i < menuCount; i++) {
- if (Menus[i].window.flags & (WINDOW_FORCED | WINDOW_VISIBLE)) {
- count++;
+ Menu_HandleMouseMove(menu, DC->cursorx, DC->cursory); // force the item under the cursor to focus
+
+ for (i = 0; i < menu->itemCount; i++) // reset selection in listboxes when opened
+ {
+ if (Item_IsListBox(menu->items[i]))
+ {
+ menu->items[i]->cursorPos = DC->feederInitialise(menu->items[i]->feederID);
+ Item_ListBox_SetStartPos(menu->items[i], 0);
+ DC->feederSelection(menu->items[i]->feederID, menu->items[i]->cursorPos);
+ }
+ else if (menu->items[i]->type == ITEM_TYPE_CYCLE)
+ {
+ menu->items[i]->typeData.cycle->cursorPos = DC->feederInitialise(menu->items[i]->feederID);
+ }
+ }
+
+ if (openMenuCount < MAX_OPEN_MENUS)
+ menuStack[openMenuCount++] = menu;
}
- }
- return count;
}
-void Menus_HandleOOBClick(menuDef_t *menu, int key, qboolean down) {
- if (menu) {
+qboolean Menus_ReplaceActive(menuDef_t *menu)
+{
int i;
- // basically the behaviour we are looking for is if there are windows in the stack.. see if
- // the cursor is within any of them.. if not close them otherwise activate them and pass the
- // key on.. force a mouse move to activate focus and script stuff
- if (down && menu->window.flags & WINDOW_OOB_CLICK) {
- Menu_RunCloseScript(menu);
- menu->window.flags &= ~(WINDOW_HASFOCUS | WINDOW_VISIBLE);
+ menuDef_t *active;
+
+ if (openMenuCount < 1)
+ return qfalse;
+
+ active = menuStack[openMenuCount - 1];
+
+ if (!(active->window.flags & WINDOW_HASFOCUS) || !(active->window.flags & WINDOW_VISIBLE))
+ {
+ return qfalse;
}
- for (i = 0; i < menuCount; i++) {
- if (Menu_OverActiveItem(&Menus[i], DC->cursorx, DC->cursory)) {
- Menu_RunCloseScript(menu);
- menu->window.flags &= ~(WINDOW_HASFOCUS | WINDOW_VISIBLE);
- Menus_Activate(&Menus[i]);
- Menu_HandleMouseMove(&Menus[i], DC->cursorx, DC->cursory);
- Menu_HandleKey(&Menus[i], key, down);
- }
+ if (menu == active)
+ return qfalse;
+
+ if (menu->itemCount != active->itemCount)
+ {
+ Com_Printf(S_COLOR_YELLOW "WARNING: Menus_ReplaceActive: expecting %i menu items, found %i\n", menu->itemCount,
+ active->itemCount);
+ return qfalse;
}
- if (Display_VisibleMenuCount() == 0) {
- if (DC->Pause) {
- DC->Pause(qfalse);
- }
+ for (i = 0; i < menu->itemCount; i++)
+ {
+ if (menu->items[i]->type != active->items[i]->type)
+ {
+ Com_Printf(S_COLOR_YELLOW "WARNING: Menus_ReplaceActive: type mismatch on item %i\n", i + 1);
+ return qfalse;
+ }
}
- Display_CloseCinematics();
- }
+
+ active->window.flags &= ~(WINDOW_FADINGOUT | WINDOW_VISIBLE);
+ menu->window.flags |= (WINDOW_HASFOCUS | WINDOW_VISIBLE);
+
+ menuStack[openMenuCount - 1] = menu;
+ if (menu->onOpen)
+ {
+ itemDef_t item;
+ item.parent = menu;
+ Item_RunScript(&item, menu->onOpen);
+ }
+
+ // set the cursor position on the new menu to match the active one
+ for (i = 0; i < menu->itemCount; i++)
+ {
+ menu->items[i]->cursorPos = active->items[i]->cursorPos;
+ menu->items[i]->feederID = active->items[i]->feederID;
+ switch (Item_DataType(menu->items[i]))
+ {
+ case TYPE_LIST:
+ menu->items[i]->typeData.list->startPos = active->items[i]->typeData.list->startPos;
+ menu->items[i]->typeData.list->cursorPos = active->items[i]->typeData.list->cursorPos;
+ break;
+ case TYPE_COMBO:
+ menu->items[i]->typeData.cycle->cursorPos = active->items[i]->typeData.cycle->cursorPos;
+ break;
+ default:
+ break;
+ }
+ }
+ return qtrue;
}
-static rectDef_t *Item_CorrectedTextRect(itemDef_t *item) {
- static rectDef_t rect;
- memset(&rect, 0, sizeof(rectDef_t));
- if (item) {
- rect = item->textRect;
- if (rect.w) {
- rect.y -= rect.h;
+int Display_VisibleMenuCount(void)
+{
+ int i, count;
+ count = 0;
+
+ for (i = 0; i < menuCount; i++)
+ {
+ if (Menus[i].window.flags & (WINDOW_FORCED | WINDOW_VISIBLE))
+ count++;
}
- }
- return &rect;
+
+ return count;
}
-void Menu_HandleKey(menuDef_t *menu, int key, qboolean down) {
- int i;
- itemDef_t *item = NULL;
- qboolean inHandler = qfalse;
+void Menus_HandleOOBClick(menuDef_t *menu, int key, qboolean down)
+{
+ if (menu)
+ {
+ int i;
+ // basically the behaviour we are looking for is if there are windows in the stack.. see if
+ // the cursor is within any of them.. if not close them otherwise activate them and pass the
+ // key on.. force a mouse move to activate focus and script stuff
+
+ if (down && menu->window.flags & WINDOW_OOB_CLICK)
+ Menus_Close(menu);
- if (inHandler) {
- return;
- }
+ for (i = 0; i < menuCount; i++)
+ {
+ if (Menu_OverActiveItem(&Menus[i], DC->cursorx, DC->cursory))
+ {
+ Menus_Close(menu);
+ Menus_Activate(&Menus[i]);
+ Menu_HandleMouseMove(&Menus[i], DC->cursorx, DC->cursory);
+ Menu_HandleKey(&Menus[i], key, down);
+ }
+ }
- inHandler = qtrue;
- if (g_waitingForKey && down) {
- Item_Bind_HandleKey(g_bindItem, key, down);
- inHandler = qfalse;
- return;
- }
+ if (Display_VisibleMenuCount() == 0)
+ {
+ if (DC->Pause)
+ DC->Pause(qfalse);
+ }
- if (g_editingField && down) {
- if (!Item_TextField_HandleKey(g_editItem, key)) {
- g_editingField = qfalse;
- Item_RunScript(g_editItem, g_editItem->onTextEntry);
- g_editItem = NULL;
- inHandler = qfalse;
- return;
+ Display_CloseCinematics();
}
- }
+}
- if (menu == NULL) {
- inHandler = qfalse;
- return;
- }
+static rectDef_t *Item_CorrectedTextRect(itemDef_t *item)
+{
+ static rectDef_t rect;
+ memset(&rect, 0, sizeof(rectDef_t));
- // see if the mouse is within the window bounds and if so is this a mouse click
- if (down && !(menu->window.flags & WINDOW_POPUP) && !Rect_ContainsPoint(&menu->window.rect, DC->cursorx, DC->cursory)) {
- static qboolean inHandleKey = qfalse;
- // bk001206 - parentheses
- if (!inHandleKey && ( key == K_MOUSE1 || key == K_MOUSE2 || key == K_MOUSE3 ) ) {
- inHandleKey = qtrue;
- Menus_HandleOOBClick(menu, key, down);
- inHandleKey = qfalse;
- inHandler = qfalse;
- return;
- }
- }
-
- // get the item with focus
- for (i = 0; i < menu->itemCount; i++) {
- if (menu->items[i]->window.flags & WINDOW_HASFOCUS) {
- item = menu->items[i];
- }
- }
-
- if (item != NULL) {
- if (Item_HandleKey(item, key, down)) {
- Item_Action(item);
- inHandler = qfalse;
- return;
- }
- }
-
- if (!down) {
- inHandler = qfalse;
- return;
- }
-
- // default handling
- switch ( key ) {
-
- case K_F11:
- if (DC->getCVarValue("developer")) {
- debugMode ^= 1;
- }
- break;
-
- case K_F12:
- if (DC->getCVarValue("developer")) {
- DC->executeText(EXEC_APPEND, "screenshot\n");
- }
- break;
- case K_KP_UPARROW:
- case K_UPARROW:
- Menu_SetPrevCursorItem(menu);
- break;
-
- case K_ESCAPE:
- if (!g_waitingForKey && menu->onESC) {
- itemDef_t it;
- it.parent = menu;
- Item_RunScript(&it, menu->onESC);
- }
- break;
- case K_TAB:
- case K_KP_DOWNARROW:
- case K_DOWNARROW:
- Menu_SetNextCursorItem(menu);
- break;
-
- case K_MOUSE1:
- case K_MOUSE2:
- if (item) {
- if (item->type == ITEM_TYPE_TEXT) {
- if (Rect_ContainsPoint(Item_CorrectedTextRect(item), DC->cursorx, DC->cursory)) {
- Item_Action(item);
- }
- } else if (item->type == ITEM_TYPE_EDITFIELD || item->type == ITEM_TYPE_NUMERICFIELD) {
- if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory)) {
- item->cursorPos = 0;
- g_editingField = qtrue;
- g_editItem = item;
- DC->setOverstrikeMode(qtrue);
- }
- } else if (item->type == ITEM_TYPE_SAYFIELD) {
- // do nothing
- } else {
- if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory)) {
- Item_Action(item);
- }
- }
- }
- break;
-
- case K_JOY1:
- case K_JOY2:
- case K_JOY3:
- case K_JOY4:
- case K_AUX1:
- case K_AUX2:
- case K_AUX3:
- case K_AUX4:
- case K_AUX5:
- case K_AUX6:
- case K_AUX7:
- case K_AUX8:
- case K_AUX9:
- case K_AUX10:
- case K_AUX11:
- case K_AUX12:
- case K_AUX13:
- case K_AUX14:
- case K_AUX15:
- case K_AUX16:
- break;
- case K_KP_ENTER:
- case K_ENTER:
- if (item) {
- if (item->type == ITEM_TYPE_EDITFIELD || item->type == ITEM_TYPE_SAYFIELD || item->type == ITEM_TYPE_NUMERICFIELD) {
- item->cursorPos = 0;
- g_editingField = qtrue;
- g_editItem = item;
- DC->setOverstrikeMode(qtrue);
- } else {
- Item_Action(item);
- }
- }
- break;
- }
- inHandler = qfalse;
-}
-
-void ToWindowCoords(float *x, float *y, windowDef_t *window) {
- if (window->border != 0) {
- *x += window->borderSize;
- *y += window->borderSize;
- }
- *x += window->rect.x;
- *y += window->rect.y;
-}
-
-void Rect_ToWindowCoords(rectDef_t *rect, windowDef_t *window) {
- ToWindowCoords(&rect->x, &rect->y, window);
-}
-
-void Item_SetTextExtents(itemDef_t *item, int *width, int *height, const char *text) {
- const char *textPtr = (text) ? text : item->text;
-
- if (textPtr == NULL ) {
- return;
- }
-
- *width = item->textRect.w;
- *height = item->textRect.h;
-
- // keeps us from computing the widths and heights more than once
- if (*width == 0 || (item->type == ITEM_TYPE_OWNERDRAW && item->textalignment == ITEM_ALIGN_CENTER)) {
- int originalWidth = DC->textWidth(item->text, item->textscale, 0);
-
- if (item->type == ITEM_TYPE_OWNERDRAW && (item->textalignment == ITEM_ALIGN_CENTER || item->textalignment == ITEM_ALIGN_RIGHT)) {
- originalWidth += DC->ownerDrawWidth(item->window.ownerDraw, item->textscale);
- } else if (item->type == ITEM_TYPE_EDITFIELD && item->textalignment == ITEM_ALIGN_CENTER && item->cvar) {
- char buff[256];
- DC->getCVarString(item->cvar, buff, 256);
- originalWidth += DC->textWidth(buff, item->textscale, 0);
- }
-
- *width = DC->textWidth(textPtr, item->textscale, 0);
- *height = DC->textHeight(textPtr, item->textscale, 0);
- item->textRect.w = *width;
- item->textRect.h = *height;
- item->textRect.x = item->textalignx;
- item->textRect.y = item->textaligny;
- if (item->textalignment == ITEM_ALIGN_RIGHT) {
- item->textRect.x = item->textalignx - originalWidth;
- } else if (item->textalignment == ITEM_ALIGN_CENTER) {
- item->textRect.x = item->textalignx - originalWidth / 2;
- }
-
- ToWindowCoords(&item->textRect.x, &item->textRect.y, &item->window);
- }
-}
-
-void Item_TextColor(itemDef_t *item, vec4_t *newColor) {
- vec4_t lowLight;
- menuDef_t *parent = (menuDef_t*)item->parent;
-
- Fade(&item->window.flags, &item->window.foreColor[3], parent->fadeClamp, &item->window.nextTime, parent->fadeCycle, qtrue, parent->fadeAmount);
-
- if (item->window.flags & WINDOW_HASFOCUS) {
-/* lowLight[0] = 0.8 * parent->focusColor[0];
- lowLight[1] = 0.8 * parent->focusColor[1];
- lowLight[2] = 0.8 * parent->focusColor[2];
- lowLight[3] = 0.8 * parent->focusColor[3];
- LerpColor(parent->focusColor,lowLight,*newColor,0.5+0.5*sin(DC->realTime / PULSE_DIVISOR));*/
- //TA:
- memcpy(newColor, &parent->focusColor, sizeof(vec4_t));
- } else if (item->textStyle == ITEM_TEXTSTYLE_BLINK && !((DC->realTime/BLINK_DIVISOR) & 1)) {
- lowLight[0] = 0.8 * item->window.foreColor[0];
- lowLight[1] = 0.8 * item->window.foreColor[1];
- lowLight[2] = 0.8 * item->window.foreColor[2];
- lowLight[3] = 0.8 * item->window.foreColor[3];
- LerpColor(item->window.foreColor,lowLight,*newColor,0.5+0.5*sin(DC->realTime / PULSE_DIVISOR));
- } else {
- memcpy(newColor, &item->window.foreColor, sizeof(vec4_t));
- // items can be enabled and disabled based on cvars
- }
+ if (item)
+ {
+ rect = item->textRect;
- if (item->enableCvar != NULL && *item->enableCvar && item->cvarTest != NULL && *item->cvarTest) {
- if (item->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(item, CVAR_ENABLE)) {
- memcpy(newColor, &parent->disableColor, sizeof(vec4_t));
+ if (rect.w)
+ rect.y -= rect.h;
}
- }
+
+ return &rect;
}
-int Item_Text_AutoWrapped_Lines( itemDef_t *item )
+void Menu_HandleKey(menuDef_t *menu, int key, qboolean down)
{
- char text[ 1024 ];
- const char *p, *textPtr, *newLinePtr;
- char buff[ 1024 ];
- int len, textWidth, newLine;
- int lines = 0;
+ int i;
+ itemDef_t *item = NULL;
- textWidth = 0;
- newLinePtr = NULL;
+ if (g_waitingForKey && down)
+ {
+ Item_Bind_HandleKey(g_bindItem, key, down);
+ return;
+ }
- if( item->text == NULL )
- {
- if( item->cvar == NULL )
- return 0;
- else
+ if (g_editingField && down)
{
- DC->getCVarString( item->cvar, text, sizeof( text ) );
- textPtr = text;
+ if (!Item_TextField_HandleKey(g_editItem, key))
+ {
+ g_editingField = qfalse;
+ Item_RunScript(g_editItem, g_editItem->onTextEntry);
+ g_editItem = NULL;
+ return;
+ }
+ else
+ {
+ Item_RunScript(g_editItem, g_editItem->onCharEntry);
+ }
}
- }
- else
- textPtr = item->text;
- if( *textPtr == '\0' )
- return 0;
+ if (menu == NULL)
+ return;
- len = 0;
- buff[ 0 ] = '\0';
- newLine = 0;
- p = textPtr;
+ // see if the mouse is within the window bounds and if so is this a mouse click
+ if (down && !(menu->window.flags & WINDOW_POPUP) &&
+ !Rect_ContainsPoint(&menu->window.rect, DC->cursorx, DC->cursory))
+ {
+ static qboolean inHandleKey = qfalse;
- while( p )
- {
- textWidth = DC->textWidth( buff, item->textscale, 0 );
+ if (!inHandleKey && (key == K_MOUSE1 || key == K_MOUSE2 || key == K_MOUSE3))
+ {
+ inHandleKey = qtrue;
+ Menus_HandleOOBClick(menu, key, down);
+ inHandleKey = qfalse;
+ return;
+ }
+ }
- if( *p == ' ' || *p == '\t' || *p == '\n' || *p == '\0' )
+ if (g_comboBoxItem == NULL)
{
- newLine = len;
- newLinePtr = p + 1;
+ // get the item with focus
+ for (i = 0; i < menu->itemCount; i++)
+ {
+ if (menu->items[i]->window.flags & WINDOW_HASFOCUS)
+ item = menu->items[i];
+ }
}
+ else
+ item = g_comboBoxItem;
- //TA: forceably split lines that are too long (where normal splitage has failed)
- if( textWidth > item->window.rect.w && newLine == 0 && *p != '\n' )
+ if (item != NULL)
{
- newLine = len;
- newLinePtr = p;
+ if (Item_HandleKey(item, key, down))
+ {
+ Item_Action(item);
+ return;
+ }
}
- if( ( newLine && textWidth > item->window.rect.w ) || *p == '\n' || *p == '\0' )
- {
- if( len )
- buff[ newLine ] = '\0';
+ if (!down)
+ return;
- if( !( *p == '\n' && !*( p + 1 ) ) )
- lines++;
+ // default handling
+ switch (key)
+ {
+ case K_F12:
+ if (DC->getCVarValue("developer"))
+ DC->executeText(EXEC_APPEND, "screenshot\n");
+
+ break;
+
+ case K_KP_UPARROW:
+ case K_UPARROW:
+ Menu_SetPrevCursorItem(menu);
+ break;
+
+ case K_ESCAPE:
+ if (!g_waitingForKey && menu->onESC)
+ {
+ itemDef_t it;
+ it.parent = menu;
+ Item_RunScript(&it, menu->onESC);
+ }
- if( *p == '\0' )
- break;
+ break;
+
+ case K_TAB:
+ case K_KP_DOWNARROW:
+ case K_DOWNARROW:
+ Menu_SetNextCursorItem(menu);
+ break;
+
+ case K_MOUSE1:
+ case K_MOUSE2:
+ if (item)
+ {
+ if (item->type == ITEM_TYPE_TEXT)
+ {
+ if (Rect_ContainsPoint(Item_CorrectedTextRect(item), DC->cursorx, DC->cursory))
+ Item_Action(item);
+ }
+ else if (Item_IsEditField(item))
+ {
+ if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory))
+ {
+ char buffer[MAX_STRING_CHARS] = {0};
+
+ if (item->cvar)
+ DC->getCVarString(item->cvar, buffer, sizeof(buffer));
+
+ item->cursorPos = strlen(buffer);
+
+ Item_TextField_CalcPaintOffset(item, buffer);
+
+ g_editingField = qtrue;
+
+ g_editItem = item;
+ }
+ }
+ else
+ {
+ if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory))
+ Item_Action(item);
+ }
+ }
- //
- p = newLinePtr;
- len = 0;
- newLine = 0;
+ break;
+
+ case K_JOY1:
+ case K_JOY2:
+ case K_JOY3:
+ case K_JOY4:
+ case K_AUX1:
+ case K_AUX2:
+ case K_AUX3:
+ case K_AUX4:
+ case K_AUX5:
+ case K_AUX6:
+ case K_AUX7:
+ case K_AUX8:
+ case K_AUX9:
+ case K_AUX10:
+ case K_AUX11:
+ case K_AUX12:
+ case K_AUX13:
+ case K_AUX14:
+ case K_AUX15:
+ case K_AUX16:
+ break;
+
+ case K_KP_ENTER:
+ case K_ENTER:
+ if (item)
+ {
+ if (Item_IsEditField(item))
+ {
+ char buffer[MAX_STRING_CHARS] = {0};
+
+ if (item->cvar)
+ DC->getCVarString(item->cvar, buffer, sizeof(buffer));
+
+ item->cursorPos = strlen(buffer);
+
+ Item_TextField_CalcPaintOffset(item, buffer);
+
+ g_editingField = qtrue;
+
+ g_editItem = item;
+ }
+ else
+ Item_Action(item);
+ }
- continue;
+ break;
}
+}
- buff[ len++ ] = *p++;
- buff[ len ] = '\0';
- }
+void ToWindowCoords(float *x, float *y, Window *window)
+{
+ if (window->border != 0)
+ {
+ *x += window->borderSize;
+ *y += window->borderSize;
+ }
- return lines;
+ *x += window->rect.x;
+ *y += window->rect.y;
}
-#define MAX_AUTOWRAP_CACHE 16
-#define MAX_AUTOWRAP_LINES 32
-#define MAX_AUTOWRAP_TEXT 512
+void Rect_ToWindowCoords(rectDef_t *rect, Window *window) { ToWindowCoords(&rect->x, &rect->y, window); }
-typedef struct
+void Item_SetTextExtents(itemDef_t *item, const char *text)
{
- //this is used purely for checking for cache hits
- char text[ MAX_AUTOWRAP_TEXT * MAX_AUTOWRAP_LINES ];
- rectDef_t rect;
- int textWidth, textHeight;
- char lines[ MAX_AUTOWRAP_LINES ][ MAX_AUTOWRAP_TEXT ];
- int lineOffsets[ MAX_AUTOWRAP_LINES ][ 2 ];
- int numLines;
-} autoWrapCache_t;
+ const char *textPtr = (text) ? text : item->text;
+ qboolean cvarContent;
-static int cacheIndex = 0;
-static autoWrapCache_t awc[ MAX_AUTOWRAP_CACHE ];
+ // It's hard to make a policy on what should be aligned statically and what
+ // should be aligned dynamically; there are reasonable cases for both. If
+ // it continues to be a problem then there should probably be an item keyword
+ // for it; but for the moment only adjusting the alignment of ITEM_TYPE_TEXT
+ // seems to suffice.
+ cvarContent = (item->cvar && item->textalignment != ALIGN_LEFT && item->type == ITEM_TYPE_TEXT);
-static int checkCache( const char *text, rectDef_t *rect, int width, int height )
-{
- int i;
+ if (textPtr == NULL)
+ return;
- for( i = 0; i < MAX_AUTOWRAP_CACHE; i++ )
- {
- if( Q_stricmp( text, awc[ i ].text ) )
- continue;
+ // as long as the item isn't dynamic content (ownerdraw or cvar), this
+ // keeps us from computing the widths and heights more than once
+ if (item->textRect.w == 0.0f || cvarContent ||
+ (item->type == ITEM_TYPE_OWNERDRAW && item->textalignment != ALIGN_LEFT))
+ {
+ float originalWidth = 0.0f;
+
+ if (item->textalignment == ALIGN_CENTER || item->textalignment == ALIGN_RIGHT)
+ {
+ if (cvarContent)
+ {
+ char buff[MAX_CVAR_VALUE_STRING];
+ DC->getCVarString(item->cvar, buff, sizeof(buff));
+ originalWidth = UI_Text_Width(item->text, item->textscale) + UI_Text_Width(buff, item->textscale);
+ }
+ else
+ originalWidth = UI_Text_Width(item->text, item->textscale);
+ }
- if( rect->x != awc[ i ].rect.x ||
- rect->y != awc[ i ].rect.y ||
- rect->w != awc[ i ].rect.w ||
- rect->h != awc[ i ].rect.h )
- continue;
+ item->textRect.w = UI_Text_Width(textPtr, item->textscale);
+ item->textRect.h = UI_Text_Height(textPtr, item->textscale);
- if( awc[ i ].textWidth != width || awc[ i ].textHeight != height )
- continue;
+ if (item->textvalignment == VALIGN_BOTTOM)
+ item->textRect.y = item->textaligny + item->window.rect.h;
+ else if (item->textvalignment == VALIGN_CENTER)
+ item->textRect.y = item->textaligny + ((item->textRect.h + item->window.rect.h) / 2.0f);
+ else if (item->textvalignment == VALIGN_TOP)
+ item->textRect.y = item->textaligny + item->textRect.h;
- //this is a match
- return i;
- }
+ if (item->textalignment == ALIGN_LEFT)
+ item->textRect.x = item->textalignx;
+ else if (item->textalignment == ALIGN_CENTER)
+ item->textRect.x = item->textalignx + ((item->window.rect.w - originalWidth) / 2.0f);
+ else if (item->textalignment == ALIGN_RIGHT)
+ item->textRect.x = item->textalignx + item->window.rect.w - originalWidth;
- //no match - autowrap isn't cached
- return -1;
+ ToWindowCoords(&item->textRect.x, &item->textRect.y, &item->window);
+ }
}
-void Item_Text_AutoWrapped_Paint( itemDef_t *item )
+void Item_TextColor(itemDef_t *item, vec4_t *newColor)
{
- char text[ 1024 ];
- const char *p, *textPtr, *newLinePtr;
- char buff[ 1024 ];
- char lastCMod[ 2 ] = { 0, 0 };
- qboolean forwardColor = qfalse;
- int width, height, len, textWidth, newLine, newLineWidth;
- int skipLines, totalLines, lineNum = 0;
- float y, totalY, diffY;
- vec4_t color;
- int cache, i;
+ vec4_t lowLight;
+ menuDef_t *parent = (menuDef_t *)item->parent;
- textWidth = 0;
- newLinePtr = NULL;
+ Fade(&item->window.flags, &item->window.foreColor[3], parent->fadeClamp, &item->window.nextTime, parent->fadeCycle,
+ qtrue, parent->fadeAmount);
- if( item->text == NULL )
- {
- if( item->cvar == NULL )
- return;
+ if (item->window.flags & WINDOW_HASFOCUS)
+ memcpy(newColor, &parent->focusColor, sizeof(vec4_t));
+ else if (item->textStyle == ITEM_TEXTSTYLE_BLINK && !((DC->realTime / BLINK_DIVISOR) & 1))
+ {
+ lowLight[0] = 0.8 * item->window.foreColor[0];
+ lowLight[1] = 0.8 * item->window.foreColor[1];
+ lowLight[2] = 0.8 * item->window.foreColor[2];
+ lowLight[3] = 0.8 * item->window.foreColor[3];
+ LerpColor(item->window.foreColor, lowLight, *newColor, 0.5 + 0.5 * sin(DC->realTime / PULSE_DIVISOR));
+ }
else
{
- DC->getCVarString( item->cvar, text, sizeof( text ) );
- textPtr = text;
+ memcpy(newColor, &item->window.foreColor, sizeof(vec4_t));
+ // items can be enabled and disabled based on cvars
}
- }
- else
- textPtr = item->text;
- if( *textPtr == '\0' )
- return;
-
- Item_TextColor( item, &color );
- Item_SetTextExtents( item, &width, &height, textPtr );
+ if (item->enableCvar != NULL && *item->enableCvar && item->cvarTest != NULL && *item->cvarTest)
+ {
+ if (item->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(item, CVAR_ENABLE))
+ memcpy(newColor, &parent->disableColor, sizeof(vec4_t));
+ }
+}
- //check if this block is cached
- cache = checkCache( textPtr, &item->window.rect, width, height );
- if( cache >= 0 )
- {
- lineNum = awc[ cache ].numLines;
+static void SkipColorCodes(const char **text, char *lastColor)
+{
+ while (Q_IsColorString(*text))
+ {
+ lastColor[0] = (*text)[0];
+ lastColor[1] = (*text)[1];
+ (*text) += 2;
+ }
+}
- for( i = 0; i < lineNum; i++ )
+static void SkipWhiteSpace(const char **text, char *lastColor)
+{
+ while (**text)
{
- item->textRect.x = awc[ cache ].lineOffsets[ i ][ 0 ];
- item->textRect.y = awc[ cache ].lineOffsets[ i ][ 1 ];
+ SkipColorCodes(text, lastColor);
- DC->drawText( item->textRect.x, item->textRect.y, item->textscale, color,
- awc[ cache ].lines[ i ], 0, 0, item->textStyle );
+ if (**text != '\n' && isspace(**text))
+ (*text)++;
+ else
+ break;
}
- }
- else
- {
- y = item->textaligny;
- len = 0;
- buff[ 0 ] = '\0';
- newLine = 0;
- newLineWidth = 0;
- p = textPtr;
+}
- totalLines = Item_Text_AutoWrapped_Lines( item );
+const char *Item_Text_Wrap(const char *text, float scale, float width)
+{
+ static char out[8192] = "";
+ char *paint = out;
+ char c[3] = "";
+ const char *p;
+ const char *eos;
+ float indentWidth = 0.0f;
- totalY = totalLines * ( height + 5 );
- diffY = totalY - item->window.rect.h;
+ if (!text)
+ return NULL;
- if( diffY > 0.0f )
- skipLines = (int)( diffY / ( (float)height + 5.0f ) );
- else
- skipLines = 0;
-
- //set up a cache entry
- strcpy( awc[ cacheIndex ].text, textPtr );
- awc[ cacheIndex ].rect.x = item->window.rect.x;
- awc[ cacheIndex ].rect.y = item->window.rect.y;
- awc[ cacheIndex ].rect.w = item->window.rect.w;
- awc[ cacheIndex ].rect.h = item->window.rect.h;
- awc[ cacheIndex ].textWidth = width;
- awc[ cacheIndex ].textHeight = height;
-
- while( p )
- {
- textWidth = DC->textWidth( buff, item->textscale, 0 );
-
- if( *p == '^' )
- {
- lastCMod[ 0 ] = p[ 0 ];
- lastCMod[ 1 ] = p[ 1 ];
- }
-
- if( *p == ' ' || *p == '\t' || *p == '\n' || *p == '\0' )
- {
- newLine = len;
- newLinePtr = p+1;
- newLineWidth = textWidth;
-
- if( *p == '\n' ) //don't forward colours past deilberate \n's
- lastCMod[ 0 ] = lastCMod[ 1 ] = 0;
- else
- forwardColor = qtrue;
- }
+ p = text;
+ eos = p + strlen(p);
+
+ if ((eos - p) >= sizeof(out))
+ return NULL;
- //TA: forceably split lines that are too long (where normal splitage has failed)
- if( textWidth > item->window.rect.w && newLine == 0 && *p != '\n' )
- {
- newLine = len;
- newLinePtr = p;
- newLineWidth = textWidth;
+ *paint = '\0';
+
+ while (*p)
+ {
+ float textWidth = 0.0f;
+ const char *eol = p;
+ const char *q = p;
+ float testWidth = width - indentWidth;
- forwardColor = qtrue;
- }
+ SkipColorCodes(&q, c);
- if( ( newLine && textWidth > item->window.rect.w ) || *p == '\n' || *p == '\0' )
- {
- if( len )
+ while (q && textWidth < testWidth)
{
- if( item->textalignment == ITEM_ALIGN_LEFT )
- item->textRect.x = item->textalignx;
- else if( item->textalignment == ITEM_ALIGN_RIGHT )
- item->textRect.x = item->textalignx - newLineWidth;
- else if( item->textalignment == ITEM_ALIGN_CENTER )
- item->textRect.x = item->textalignx - newLineWidth / 2;
+ qboolean previousCharIsSpace = qfalse;
+
+ // Remaining string is too short to wrap
+ if (q >= eos)
+ {
+ eol = eos;
+ break;
+ }
+
+ if (q > p && *q == INDENT_MARKER)
+ {
+ indentWidth = textWidth;
+ eol = p;
+ }
- item->textRect.y = y;
- ToWindowCoords( &item->textRect.x, &item->textRect.y, &item->window );
- //
- buff[ newLine ] = '\0';
+ // Some color escapes might still be present
+ SkipColorCodes(&q, c);
- if( !skipLines )
- {
- DC->drawText( item->textRect.x, item->textRect.y, item->textscale, color, buff, 0, 0, item->textStyle );
+ // Manual line break
+ if (*q == '\n')
+ {
+ eol = q + 1;
+ break;
+ }
- strcpy( awc[ cacheIndex ].lines[ lineNum ], buff );
- awc[ cacheIndex ].lineOffsets[ lineNum ][ 0 ] = item->textRect.x;
- awc[ cacheIndex ].lineOffsets[ lineNum ][ 1 ] = item->textRect.y;
+ if (!previousCharIsSpace && isspace(*q))
+ eol = q;
- lineNum++;
- }
+ textWidth += UI_Char_Width(&q, scale);
}
- if( *p == '\0' )
- break;
- //
- if( !skipLines )
- y += height + 5;
+ // No split has taken place, so just split mid-word
+ if (eol == p)
+ eol = q;
+
+ // Note that usage of strcat and strlen is deliberately being
+ // avoided here as it becomes surprisingly expensive on larger
+ // blocks of text
- if( skipLines )
- skipLines--;
-
- p = newLinePtr;
- len = 0;
- newLine = 0;
- newLineWidth = 0;
+ // Copy text
+ strncpy(paint, p, eol - p);
+ paint += (eol - p);
+ *paint = '\0';
- if( forwardColor && lastCMod[ 0 ] != 0 )
- {
- buff[ len++ ] = lastCMod[ 0 ];
- buff[ len++ ] = lastCMod[ 1 ];
- buff[ len ] = '\0';
+ p = eol;
- forwardColor = qfalse;
+ if (paint - out > 0 && *(paint - 1) == '\n')
+ {
+ // The line is deliberately broken, clear the color and
+ // any current indent
+ c[0] = '\0';
+ indentWidth = 0.0f;
}
+ else
+ {
+ // Add a \n if it's not there already
+ *paint++ = '\n';
+ *paint = '\0';
+
+ // Insert a pixel indent on the next line
+ if (indentWidth > 0.0f)
+ {
+ const char *indentMarkerText = va("%f%c", indentWidth, INDENT_MARKER);
+ int indentMarkerTextLength = strlen(indentMarkerText);
+
+ strncpy(paint, indentMarkerText, indentMarkerTextLength);
+ paint += indentMarkerTextLength;
+ *paint = '\0';
+ }
- continue;
- }
+ // Skip leading whitespace on next line and save the
+ // last color code
+ SkipWhiteSpace(&p, c);
+ }
- buff[ len++ ] = *p++;
- buff[ len ] = '\0';
+ if (c[0])
+ {
+ *paint++ = c[0];
+ *paint++ = c[1];
+ *paint = '\0';
+ }
}
- //mark the end of the lines list
- awc[ cacheIndex ].numLines = lineNum;
+ return out;
+}
+
+#define MAX_WRAP_CACHE 16
+#define MAX_WRAP_LINES 32
+#define MAX_WRAP_TEXT 512
+
+typedef struct {
+ char text[MAX_WRAP_TEXT * MAX_WRAP_LINES];
+ rectDef_t rect;
+ float scale;
+ char lines[MAX_WRAP_LINES][MAX_WRAP_TEXT];
+ float lineCoords[MAX_WRAP_LINES][2];
+ int numLines;
+} wrapCache_t;
+
+static wrapCache_t wrapCache[MAX_WRAP_CACHE];
+static qboolean cacheCreationFailed = qfalse;
+static int cacheWriteIndex = 0;
+static int cacheReadIndex = 0;
+static int cacheReadLineNum = 0;
+
+static void UI_CreateCacheEntry(const char *text, const rectDef_t *rect, float scale)
+{
+ wrapCache_t *cacheEntry = &wrapCache[cacheWriteIndex];
- //increment cacheIndex
- cacheIndex = ( cacheIndex + 1 ) % MAX_AUTOWRAP_CACHE;
- }
+ if (strlen(text) >= sizeof(cacheEntry->text))
+ {
+ cacheCreationFailed = qtrue;
+ return;
+ }
+
+ strcpy(cacheEntry->text, text);
+ cacheEntry->rect = *rect;
+ cacheEntry->scale = scale;
+ cacheEntry->numLines = 0;
}
-void Item_Text_Wrapped_Paint(itemDef_t *item) {
- char text[1024];
- const char *p, *start, *textPtr;
- char buff[1024];
- int width, height;
- float x, y;
- vec4_t color;
+static void UI_AddCacheEntryLine(const char *text, float x, float y)
+{
+ wrapCache_t *cacheEntry = &wrapCache[cacheWriteIndex];
- // now paint the text and/or any optional images
- // default to left
+ if (cacheCreationFailed)
+ return;
- if (item->text == NULL) {
- if (item->cvar == NULL) {
- return;
+ if (cacheEntry->numLines >= MAX_WRAP_LINES || strlen(text) >= sizeof(cacheEntry->lines[0]))
+ {
+ cacheCreationFailed = qtrue;
+ return;
}
- else {
- DC->getCVarString(item->cvar, text, sizeof(text));
- textPtr = text;
+
+ strcpy(cacheEntry->lines[cacheEntry->numLines], text);
+ cacheEntry->lineCoords[cacheEntry->numLines][0] = x;
+ cacheEntry->lineCoords[cacheEntry->numLines][1] = y;
+ cacheEntry->numLines++;
+}
+
+static void UI_FinishCacheEntry(void)
+{
+ if (cacheCreationFailed)
+ {
+ wrapCache[cacheWriteIndex].text[0] = '\0';
+ wrapCache[cacheWriteIndex].numLines = 0;
+ cacheCreationFailed = qfalse;
}
- }
- else {
- textPtr = item->text;
- }
- if (*textPtr == '\0') {
- return;
- }
+ else
+ cacheWriteIndex = (cacheWriteIndex + 1) % MAX_WRAP_CACHE;
+}
- Item_TextColor(item, &color);
- Item_SetTextExtents(item, &width, &height, textPtr);
+static qboolean UI_CheckWrapCache(const char *text, const rectDef_t *rect, float scale)
+{
+ int i;
+
+ for (i = 0; i < MAX_WRAP_CACHE; i++)
+ {
+ wrapCache_t *cacheEntry = &wrapCache[i];
+
+ if (rect->x != cacheEntry->rect.x || rect->y != cacheEntry->rect.y || rect->w != cacheEntry->rect.w ||
+ rect->h != cacheEntry->rect.h)
+ continue;
+
+ if (strcmp(text, cacheEntry->text))
+ continue;
+
+ if (cacheEntry->scale != scale)
+ continue;
+
+ cacheReadIndex = i;
+ cacheReadLineNum = 0;
+
+ return qtrue;
+ }
- x = item->textRect.x;
- y = item->textRect.y;
- start = textPtr;
- p = strchr(textPtr, '\r');
- while (p && *p) {
- strncpy(buff, start, p-start+1);
- buff[p-start] = '\0';
- DC->drawText(x, y, item->textscale, color, buff, 0, 0, item->textStyle);
- y += height + 5;
- start += p - start + 1;
- p = strchr(p+1, '\r');
- }
- DC->drawText(x, y, item->textscale, color, start, 0, 0, item->textStyle);
+ return qfalse;
}
-void Item_Text_Paint(itemDef_t *item) {
- char text[1024];
- const char *textPtr;
- int height, width;
- vec4_t color;
+static qboolean UI_NextWrapLine(const char **text, float *x, float *y)
+{
+ wrapCache_t *cacheEntry = &wrapCache[cacheReadIndex];
+
+ if (cacheReadLineNum >= cacheEntry->numLines)
+ return qfalse;
+
+ *text = cacheEntry->lines[cacheReadLineNum];
+ *x = cacheEntry->lineCoords[cacheReadLineNum][0];
+ *y = cacheEntry->lineCoords[cacheReadLineNum][1];
- if (item->window.flags & WINDOW_WRAPPED) {
- Item_Text_Wrapped_Paint(item);
- return;
- }
- if (item->window.flags & WINDOW_AUTOWRAPPED) {
- Item_Text_AutoWrapped_Paint(item);
- return;
- }
+ cacheReadLineNum++;
+
+ return qtrue;
+}
+
+void Item_Text_Wrapped_Paint(itemDef_t *item)
+{
+ char text[1024];
+ const char *p, *textPtr;
+ float x, y, w, h;
+ vec4_t color;
+ qboolean useWrapCache = (qboolean)DC->getCVarValue("ui_textWrapCache");
- if (item->text == NULL) {
- if (item->cvar == NULL) {
- return;
+ if (item->text == NULL)
+ {
+ if (item->cvar == NULL)
+ return;
+ else
+ {
+ DC->getCVarString(item->cvar, text, sizeof(text));
+ textPtr = text;
+ }
}
- else {
- DC->getCVarString(item->cvar, text, sizeof(text));
- textPtr = text;
+ else
+ textPtr = item->text;
+
+ if (*textPtr == '\0')
+ return;
+
+ Item_TextColor(item, &color);
+
+ // Check if this block is cached
+ if (useWrapCache && UI_CheckWrapCache(textPtr, &item->window.rect, item->textscale))
+ {
+ while (UI_NextWrapLine(&p, &x, &y))
+ {
+ UI_Text_Paint(x, y, item->textscale, color, p, 0, 0, item->textStyle);
+ }
}
- }
- else {
- textPtr = item->text;
- }
+ else
+ {
+ char buff[1024];
+ float fontHeight = UI_Text_EmHeight(item->textscale);
+ const float lineSpacing = fontHeight * 0.4f;
+ float lineHeight = fontHeight + lineSpacing;
+ float textHeight;
+ int textLength;
+ int firstLine, paintLines, totalLines, lineNum;
+ float paintY;
+ int i;
+
+ if (useWrapCache)
+ UI_CreateCacheEntry(textPtr, &item->window.rect, item->textscale);
+
+ x = item->window.rect.x + item->textalignx;
+ y = item->window.rect.y + item->textaligny;
+ w = item->window.rect.w - (2.0f * item->textalignx);
+ h = item->window.rect.h - (2.0f * item->textaligny);
+
+ textPtr = Item_Text_Wrap(textPtr, item->textscale, w);
+ textLength = strlen(textPtr);
+
+ // Count lines
+ totalLines = 0;
+
+ for (i = 0; i < textLength; i++)
+ {
+ if (textPtr[i] == '\n')
+ totalLines++;
+ }
+ if (textLength && textPtr[textLength - 1] != '\n')
+ {
+ totalLines++; // count the last, non-newline-terminated line
+ textLength++; // a '\0' will mark the end of the last line
+ }
- // this needs to go here as it sets extents for cvar types as well
- Item_SetTextExtents(item, &width, &height, textPtr);
+ paintLines = (int)floor((h + lineSpacing) / lineHeight);
- if (*textPtr == '\0') {
- return;
- }
+ if (totalLines > paintLines)
+ firstLine = totalLines - paintLines;
+ else
+ {
+ firstLine = 0;
+ paintLines = totalLines;
+ }
+
+ textHeight = (paintLines * lineHeight) - lineSpacing;
+
+ switch (item->textvalignment)
+ {
+ default:
+
+ case VALIGN_BOTTOM:
+ paintY = y + (h - textHeight);
+ break;
+
+ case VALIGN_CENTER:
+ paintY = y + ((h - textHeight) / 2.0f);
+ break;
+
+ case VALIGN_TOP:
+ paintY = y;
+ break;
+ }
+
+ p = textPtr;
+ // skip the first few lines
+ for (lineNum = 0; lineNum < firstLine; lineNum++)
+ p = strchr(p, '\n') + 1;
- Item_TextColor(item, &color);
+ for (i = p - textPtr; i < textLength && lineNum < firstLine + paintLines; i++)
+ {
+ unsigned long lineLength = &textPtr[i] - p;
+
+ if (lineLength >= sizeof(buff))
+ break;
+
+ if (textPtr[i] == '\n' || textPtr[i] == '\0')
+ {
+ itemDef_t lineItem;
+
+ memset(&lineItem, 0, sizeof(itemDef_t));
+ strncpy(buff, p, lineLength);
+ buff[lineLength] = '\0';
+ p = &textPtr[i + 1];
+
+ lineItem.type = ITEM_TYPE_TEXT;
+ lineItem.textscale = item->textscale;
+ lineItem.textStyle = item->textStyle;
+ lineItem.text = buff;
+ lineItem.textalignment = item->textalignment;
+ lineItem.textvalignment = VALIGN_TOP;
+ lineItem.textalignx = 0.0f;
+ lineItem.textaligny = 0.0f;
+
+ lineItem.textRect.w = 0.0f;
+ lineItem.textRect.h = 0.0f;
+ lineItem.window.rect.x = x;
+ lineItem.window.rect.y = paintY + ((lineNum - firstLine) * lineHeight);
+ lineItem.window.rect.w = w;
+ lineItem.window.rect.h = lineHeight;
+ lineItem.window.border = item->window.border;
+ lineItem.window.borderSize = item->window.borderSize;
+
+ if (DC->getCVarValue("ui_developer"))
+ {
+ vec4_t color;
+ color[0] = color[2] = color[3] = 1.0f;
+ color[1] = 0.0f;
+ DC->drawRect(lineItem.window.rect.x, lineItem.window.rect.y, lineItem.window.rect.w,
+ lineItem.window.rect.h, 1, color);
+ }
+
+ Item_SetTextExtents(&lineItem, buff);
+ UI_Text_Paint(lineItem.textRect.x, lineItem.textRect.y, lineItem.textscale, color, buff, 0, 0,
+ lineItem.textStyle);
+
+ if (useWrapCache)
+ UI_AddCacheEntryLine(buff, lineItem.textRect.x, lineItem.textRect.y);
+
+ lineNum++;
+ }
+ }
+
+ if (useWrapCache)
+ UI_FinishCacheEntry();
+ }
+}
- //FIXME: this is a fucking mess
/*
- adjust = 0;
- if (item->textStyle == ITEM_TEXTSTYLE_OUTLINED || item->textStyle == ITEM_TEXTSTYLE_OUTLINESHADOWED) {
- adjust = 0.5;
- }
-
- if (item->textStyle == ITEM_TEXTSTYLE_SHADOWED || item->textStyle == ITEM_TEXTSTYLE_OUTLINESHADOWED) {
- Fade(&item->window.flags, &DC->Assets.shadowColor[3], DC->Assets.fadeClamp, &item->window.nextTime, DC->Assets.fadeCycle, qfalse);
- DC->drawText(item->textRect.x + DC->Assets.shadowX, item->textRect.y + DC->Assets.shadowY, item->textscale, DC->Assets.shadowColor, textPtr, adjust);
- }
+==============
+UI_DrawTextBlock
+==============
*/
+void UI_DrawTextBlock(rectDef_t *rect, float text_x, float text_y, vec4_t color, float scale, int textalign,
+ int textvalign, int textStyle, const char *text)
+{
+ static menuDef_t dummyParent;
+ static itemDef_t textItem;
+
+ textItem.text = text;
+
+ textItem.parent = &dummyParent;
+ memcpy(textItem.window.foreColor, color, sizeof(vec4_t));
+ textItem.window.flags = 0;
+
+ textItem.window.rect.x = rect->x;
+ textItem.window.rect.y = rect->y;
+ textItem.window.rect.w = rect->w;
+ textItem.window.rect.h = rect->h;
+ textItem.window.border = 0;
+ textItem.window.borderSize = 0.0f;
+ textItem.textRect.x = 0.0f;
+ textItem.textRect.y = 0.0f;
+ textItem.textRect.w = 0.0f;
+ textItem.textRect.h = 0.0f;
+ textItem.textalignment = textalign;
+ textItem.textvalignment = textvalign;
+ textItem.textalignx = text_x;
+ textItem.textaligny = text_y;
+ textItem.textscale = scale;
+ textItem.textStyle = textStyle;
+
+ // Utilise existing wrap code
+ Item_Text_Wrapped_Paint(&textItem);
+}
+
+void Item_Text_Paint(itemDef_t *item)
+{
+ char text[1024];
+ const char *textPtr;
+ vec4_t color;
+
+ if (item->window.flags & WINDOW_WRAPPED)
+ {
+ Item_Text_Wrapped_Paint(item);
+ return;
+ }
+ if (item->text == NULL)
+ {
+ if (item->cvar == NULL)
+ return;
+ else
+ {
+ DC->getCVarString(item->cvar, text, sizeof(text));
+ textPtr = text;
+ }
+ }
+ else
+ textPtr = item->text;
-// if (item->textStyle == ITEM_TEXTSTYLE_OUTLINED || item->textStyle == ITEM_TEXTSTYLE_OUTLINESHADOWED) {
-// Fade(&item->window.flags, &item->window.outlineColor[3], DC->Assets.fadeClamp, &item->window.nextTime, DC->Assets.fadeCycle, qfalse);
-// /*
-// Text_Paint(item->textRect.x-1, item->textRect.y-1, item->textscale, item->window.foreColor, textPtr, adjust);
-// Text_Paint(item->textRect.x, item->textRect.y-1, item->textscale, item->window.foreColor, textPtr, adjust);
-// Text_Paint(item->textRect.x+1, item->textRect.y-1, item->textscale, item->window.foreColor, textPtr, adjust);
-// Text_Paint(item->textRect.x-1, item->textRect.y, item->textscale, item->window.foreColor, textPtr, adjust);
-// Text_Paint(item->textRect.x+1, item->textRect.y, item->textscale, item->window.foreColor, textPtr, adjust);
-// Text_Paint(item->textRect.x-1, item->textRect.y+1, item->textscale, item->window.foreColor, textPtr, adjust);
-// Text_Paint(item->textRect.x, item->textRect.y+1, item->textscale, item->window.foreColor, textPtr, adjust);
-// Text_Paint(item->textRect.x+1, item->textRect.y+1, item->textscale, item->window.foreColor, textPtr, adjust);
-// */
-// DC->drawText(item->textRect.x - 1, item->textRect.y + 1, item->textscale * 1.02, item->window.outlineColor, textPtr, adjust);
-// }
-
- DC->drawText(item->textRect.x, item->textRect.y, item->textscale, color, textPtr, 0, 0, item->textStyle);
-}
-
-
-
-//float trap_Cvar_VariableValue( const char *var_name );
-//void trap_Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize );
-
-void Item_TextField_Paint(itemDef_t *item) {
- char buff[1024];
- vec4_t newColor;
- int offset;
- menuDef_t *parent = (menuDef_t*)item->parent;
- editFieldDef_t *editPtr = (editFieldDef_t*)item->typeData;
-
- Item_Text_Paint(item);
-
- buff[0] = '\0';
-
- if (item->cvar) {
- DC->getCVarString(item->cvar, buff, sizeof(buff));
- }
-
- parent = (menuDef_t*)item->parent;
-
- if (item->window.flags & WINDOW_HASFOCUS) {
-/* lowLight[0] = 0.8 * parent->focusColor[0];
- lowLight[1] = 0.8 * parent->focusColor[1];
- lowLight[2] = 0.8 * parent->focusColor[2];
- lowLight[3] = 0.8 * parent->focusColor[3];
- LerpColor(parent->focusColor,lowLight,newColor,0.5+0.5*sin(DC->realTime / PULSE_DIVISOR));*/
- //TA:
- memcpy(newColor, &parent->focusColor, sizeof(vec4_t));
- } else {
- memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t));
- }
-
- offset = (item->text && *item->text) ? 8 : 0;
- if (item->window.flags & WINDOW_HASFOCUS && g_editingField) {
- char cursor = DC->getOverstrikeMode() ? '_' : '|';
- DC->drawTextWithCursor(item->textRect.x + item->textRect.w + offset, item->textRect.y, item->textscale, newColor, buff + editPtr->paintOffset, item->cursorPos - editPtr->paintOffset , cursor, editPtr->maxPaintChars, item->textStyle);
- } else {
- DC->drawText(item->textRect.x + item->textRect.w + offset, item->textRect.y, item->textscale, newColor, buff + editPtr->paintOffset, 0, editPtr->maxPaintChars, item->textStyle);
- }
-
-}
-
-void Item_YesNo_Paint(itemDef_t *item) {
- vec4_t newColor;
- float value;
- menuDef_t *parent = (menuDef_t*)item->parent;
-
- value = (item->cvar) ? DC->getCVarValue(item->cvar) : 0;
-
- if (item->window.flags & WINDOW_HASFOCUS) {
-/* lowLight[0] = 0.8 * parent->focusColor[0];
- lowLight[1] = 0.8 * parent->focusColor[1];
- lowLight[2] = 0.8 * parent->focusColor[2];
- lowLight[3] = 0.8 * parent->focusColor[3];
- LerpColor(parent->focusColor,lowLight,newColor,0.5+0.5*sin(DC->realTime / PULSE_DIVISOR));*/
- //TA:
- memcpy(newColor, &parent->focusColor, sizeof(vec4_t));
- } else {
- memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t));
- }
-
- if (item->text) {
- Item_Text_Paint(item);
- DC->drawText(item->textRect.x + item->textRect.w + 8, item->textRect.y, item->textscale, newColor, (value != 0) ? "Yes" : "No", 0, 0, item->textStyle);
- } else {
- DC->drawText(item->textRect.x, item->textRect.y, item->textscale, newColor, (value != 0) ? "Yes" : "No", 0, 0, item->textStyle);
- }
-}
-
-void Item_Multi_Paint(itemDef_t *item) {
- vec4_t newColor;
- const char *text = "";
- menuDef_t *parent = (menuDef_t*)item->parent;
-
- if (item->window.flags & WINDOW_HASFOCUS) {
-/* lowLight[0] = 0.8 * parent->focusColor[0];
- lowLight[1] = 0.8 * parent->focusColor[1];
- lowLight[2] = 0.8 * parent->focusColor[2];
- lowLight[3] = 0.8 * parent->focusColor[3];
- LerpColor(parent->focusColor,lowLight,newColor,0.5+0.5*sin(DC->realTime / PULSE_DIVISOR));*/
- //TA:
- memcpy(newColor, &parent->focusColor, sizeof(vec4_t));
- } else {
- memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t));
- }
-
- text = Item_Multi_Setting(item);
-
- if (item->text) {
+ // this needs to go here as it sets extents for cvar types as well
+ Item_SetTextExtents(item, textPtr);
+
+ if (*textPtr == '\0')
+ return;
+
+ Item_TextColor(item, &color);
+
+ UI_Text_Paint(item->textRect.x, item->textRect.y, item->textscale, color, textPtr, 0, 0, item->textStyle);
+}
+
+void Item_TextField_Paint(itemDef_t *item)
+{
+ char buff[1024];
+ vec4_t newColor;
+ menuDef_t *parent;
+ int offset = (item->text && *item->text) ? ITEM_VALUE_OFFSET : 0;
+ editFieldDef_t *editPtr = item->typeData.edit;
+ char cursor = DC->getOverstrikeMode() ? '|' : '_';
+ qboolean editing = (item->window.flags & WINDOW_HASFOCUS && g_editingField);
+ const int cursorWidth = editing ? EDIT_CURSOR_WIDTH : 0;
+
+ // FIXME: causes duplicate printing if item->text is not set (NULL)
Item_Text_Paint(item);
- DC->drawText(item->textRect.x + item->textRect.w + 8, item->textRect.y, item->textscale, newColor, text, 0, 0, item->textStyle);
- } else {
- DC->drawText(item->textRect.x, item->textRect.y, item->textscale, newColor, text, 0, 0, item->textStyle);
- }
+
+ buff[0] = '\0';
+
+ if (item->cvar)
+ DC->getCVarString(item->cvar, buff, sizeof(buff));
+
+ // maxFieldWidth hasn't been set, so use the item's rect
+ if (editPtr->maxFieldWidth == 0)
+ {
+ editPtr->maxFieldWidth =
+ item->window.rect.w - (item->textRect.w + offset + (item->textRect.x - item->window.rect.x));
+
+ if (editPtr->maxFieldWidth < MIN_FIELD_WIDTH)
+ editPtr->maxFieldWidth = MIN_FIELD_WIDTH;
+ }
+
+ if (!editing)
+ editPtr->paintOffset = 0;
+
+ // Shorten string to max viewable
+ while (UI_Text_Width(buff + editPtr->paintOffset, item->textscale) > (editPtr->maxFieldWidth - cursorWidth) &&
+ strlen(buff) > 0)
+ buff[strlen(buff) - 1] = '\0';
+
+ parent = (menuDef_t *)item->parent;
+
+ if (item->window.flags & WINDOW_HASFOCUS)
+ memcpy(newColor, &parent->focusColor, sizeof(vec4_t));
+ else
+ memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t));
+
+ if (editing)
+ {
+ UI_Text_PaintWithCursor(item->textRect.x + item->textRect.w + offset, item->textRect.y, item->textscale,
+ newColor, buff + editPtr->paintOffset, item->cursorPos - editPtr->paintOffset, cursor,
+ editPtr->maxPaintChars, item->textStyle);
+ }
+ else
+ {
+ UI_Text_Paint(item->textRect.x + item->textRect.w + offset, item->textRect.y, item->textscale, newColor,
+ buff + editPtr->paintOffset, 0, editPtr->maxPaintChars, item->textStyle);
+ }
}
+void Item_YesNo_Paint(itemDef_t *item)
+{
+ vec4_t newColor;
+ float value;
+ int offset;
+ menuDef_t *parent = (menuDef_t *)item->parent;
-typedef struct {
- char *command;
- int id;
- int defaultbind1;
- int defaultbind2;
- int bind1;
- int bind2;
-} bind_t;
+ value = (item->cvar) ? DC->getCVarValue(item->cvar) : 0;
-typedef struct
-{
- char* name;
- float defaultvalue;
- float value;
-} configcvar_t;
-
-
-static bind_t g_bindings[] =
-{
- { "+scores", K_TAB, -1, -1, -1 },
- { "+button2", K_ENTER, -1, -1, -1 },
- { "+speed", K_SHIFT, -1, -1, -1 },
- { "boost", 'x', -1, -1, -1 }, //TA: human sprinting
- { "+forward", K_UPARROW, -1, -1, -1 },
- { "+back", K_DOWNARROW, -1, -1, -1 },
- { "+moveleft", ',', -1, -1, -1 },
- { "+moveright", '.', -1, -1, -1 },
- { "+moveup", K_SPACE, -1, -1, -1 },
- { "+movedown", 'c', -1, -1, -1 },
- { "+left", K_LEFTARROW, -1, -1, -1 },
- { "+right", K_RIGHTARROW, -1, -1, -1 },
- { "+strafe", K_ALT, -1, -1, -1 },
- { "+lookup", K_PGDN, -1, -1, -1 },
- { "+lookdown", K_DEL, -1, -1, -1 },
- { "+mlook", '/', -1, -1, -1 },
- { "centerview", K_END, -1, -1, -1 },
- { "+zoom", -1, -1, -1, -1 },
- { "weapon 1", '1', -1, -1, -1 },
- { "weapon 2", '2', -1, -1, -1 },
- { "weapon 3", '3', -1, -1, -1 },
- { "weapon 4", '4', -1, -1, -1 },
- { "weapon 5", '5', -1, -1, -1 },
- { "weapon 6", '6', -1, -1, -1 },
- { "weapon 7", '7', -1, -1, -1 },
- { "weapon 8", '8', -1, -1, -1 },
- { "weapon 9", '9', -1, -1, -1 },
- { "weapon 10", '0', -1, -1, -1 },
- { "weapon 11", -1, -1, -1, -1 },
- { "weapon 12", -1, -1, -1, -1 },
- { "weapon 13", -1, -1, -1, -1 },
- { "+attack", K_MOUSE1, -1, -1, -1 },
- { "+button5", K_MOUSE2, -1, -1, -1 }, //TA: secondary attack
- { "reload", 'r', -1, -1, -1 }, //TA: reload
- { "buy ammo", 'b', -1, -1, -1 }, //TA: buy ammo
- { "itemact medkit", 'm', -1, -1, -1 }, //TA: use medkit
- { "+button7", 'q', -1, -1, -1 }, //TA: buildable use
- { "deconstruct", 'e', -1, -1, -1 }, //TA: buildable destroy
- { "weapprev", '[', -1, -1, -1 },
- { "weapnext", ']', -1, -1, -1 },
- { "+button3", K_MOUSE3, -1, -1, -1 },
- { "+button4", K_MOUSE4, -1, -1, -1 },
- { "vote yes", K_F1, -1, -1, -1 },
- { "vote no", K_F2, -1, -1, -1 },
- { "teamvote yes", K_F3, -1, -1, -1 },
- { "teamvote no", K_F4, -1, -1, -1 },
- { "scoresUp", K_KP_PGUP, -1, -1, -1 },
- { "scoresDown", K_KP_PGDN, -1, -1, -1 },
- // bk001205 - this one below was: '-1'
- { "messagemode", -1, -1, -1, -1 },
- { "messagemode2", -1, -1, -1, -1 },
- { "messagemode3", -1, -1, -1, -1 },
- { "messagemode4", -1, -1, -1, -1 }
-};
+ if (item->window.flags & WINDOW_HASFOCUS)
+ memcpy(newColor, &parent->focusColor, sizeof(vec4_t));
+ else
+ memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t));
+ offset = (item->text && *item->text) ? ITEM_VALUE_OFFSET : 0;
-static const int g_bindCount = sizeof(g_bindings) / sizeof(bind_t);
+ if (item->text)
+ {
+ Item_Text_Paint(item);
+ UI_Text_Paint(item->textRect.x + item->textRect.w + offset, item->textRect.y, item->textscale, newColor,
+ (value != 0) ? "Yes" : "No", 0, 0, item->textStyle);
+ }
+ else
+ UI_Text_Paint(item->textRect.x, item->textRect.y, item->textscale, newColor, (value != 0) ? "Yes" : "No", 0, 0,
+ item->textStyle);
+}
+
+void Item_Multi_Paint(itemDef_t *item)
+{
+ vec4_t newColor;
+ const char *text = "";
+ menuDef_t *parent = (menuDef_t *)item->parent;
+
+ if (item->window.flags & WINDOW_HASFOCUS)
+ memcpy(newColor, &parent->focusColor, sizeof(vec4_t));
+ else
+ memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t));
+
+ text = Item_Multi_Setting(item);
+
+ if (item->text)
+ {
+ Item_Text_Paint(item);
+ UI_Text_Paint(item->textRect.x + item->textRect.w + ITEM_VALUE_OFFSET, item->textRect.y, item->textscale,
+ newColor, text, 0, 0, item->textStyle);
+ }
+ else
+ UI_Text_Paint(item->textRect.x, item->textRect.y, item->textscale, newColor, text, 0, 0, item->textStyle);
+}
+
+void Item_Cycle_Paint(itemDef_t *item)
+{
+ vec4_t newColor;
+ const char *text = "";
+ menuDef_t *parent = (menuDef_t *)item->parent;
+
+ if (item->window.flags & WINDOW_HASFOCUS)
+ memcpy(newColor, &parent->focusColor, sizeof(vec4_t));
+ else
+ memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t));
+
+ if (item->typeData.cycle)
+ text = DC->feederItemText(item->feederID, item->typeData.cycle->cursorPos, 0, NULL);
+
+ if (item->text)
+ {
+ Item_Text_Paint(item);
+ UI_Text_Paint(item->textRect.x + item->textRect.w + ITEM_VALUE_OFFSET, item->textRect.y, item->textscale,
+ newColor, text, 0, 0, item->textStyle);
+ }
+ else
+ UI_Text_Paint(item->textRect.x, item->textRect.y, item->textscale, newColor, text, 0, 0, item->textStyle);
+}
+
+typedef struct {
+ char *command;
+ int id;
+ int defaultbind1;
+ int defaultbind2;
+ int bind1;
+ int bind2;
+} bind_t;
+
+static bind_t g_bindings[] = {{"+scores", K_TAB, -1, -1, -1, -1}, {"+button2", K_ENTER, -1, -1, -1, -1},
+ {"+speed", K_SHIFT, -1, -1, -1, -1}, {"+button6", 'z', -1, -1, -1, -1}, // human dodging
+ {"+button8", 'x', -1, -1, -1, -1}, {"+forward", K_UPARROW, -1, -1, -1, -1}, {"+back", K_DOWNARROW, -1, -1, -1, -1},
+ {"+moveleft", ',', -1, -1, -1, -1}, {"+moveright", '.', -1, -1, -1, -1}, {"+moveup", K_SPACE, -1, -1, -1, -1},
+ {"+movedown", 'c', -1, -1, -1, -1}, {"+left", K_LEFTARROW, -1, -1, -1, -1},
+ {"+right", K_RIGHTARROW, -1, -1, -1, -1}, {"+strafe", K_ALT, -1, -1, -1, -1}, {"+lookup", K_PGDN, -1, -1, -1, -1},
+ {"+lookdown", K_DEL, -1, -1, -1, -1}, {"+mlook", '/', -1, -1, -1, -1}, {"centerview", K_END, -1, -1, -1, -1},
+ {"+zoom", -1, -1, -1, -1, -1}, {"weapon 1", '1', -1, -1, -1, -1}, {"weapon 2", '2', -1, -1, -1, -1},
+ {"weapon 3", '3', -1, -1, -1, -1}, {"weapon 4", '4', -1, -1, -1, -1}, {"weapon 5", '5', -1, -1, -1, -1},
+ {"weapon 6", '6', -1, -1, -1, -1}, {"weapon 7", '7', -1, -1, -1, -1}, {"weapon 8", '8', -1, -1, -1, -1},
+ {"weapon 9", '9', -1, -1, -1, -1}, {"weapon 10", '0', -1, -1, -1, -1}, {"weapon 11", -1, -1, -1, -1, -1},
+ {"weapon 12", -1, -1, -1, -1, -1}, {"weapon 13", -1, -1, -1, -1, -1}, {"+attack", K_MOUSE1, -1, -1, -1, -1},
+ {"+button5", K_MOUSE2, -1, -1, -1, -1}, // secondary attack
+ {"reload", 'r', -1, -1, -1, -1}, // reload
+ {"buy ammo", 'b', -1, -1, -1, -1}, // buy ammo
+ {"itemact medkit", 'm', -1, -1, -1, -1}, // use medkit
+ {"+button7", 'q', -1, -1, -1, -1}, // buildable use
+ {"deconstruct", 'e', -1, -1, -1, -1}, // buildable destroy
+ {"weapprev", '[', -1, -1, -1, -1}, {"weapnext", ']', -1, -1, -1, -1}, {"+button3", K_MOUSE3, -1, -1, -1, -1},
+ {"+button4", K_MOUSE4, -1, -1, -1, -1}, {"vote yes", K_F1, -1, -1, -1, -1}, {"vote no", K_F2, -1, -1, -1, -1},
+ {"teamvote yes", K_F3, -1, -1, -1, -1}, {"teamvote no", K_F4, -1, -1, -1, -1},
+ {"scoresUp", K_KP_PGUP, -1, -1, -1, -1}, {"scoresDown", K_KP_PGDN, -1, -1, -1, -1},
+ {"screenshotJPEG", -1, -1, -1, -1, -1}, {"messagemode", -1, -1, -1, -1, -1}, {"messagemode2", -1, -1, -1, -1, -1}};
+
+static const size_t g_bindCount = ARRAY_LEN(g_bindings);
/*
=================
Controls_GetKeyAssignment
=================
*/
-static void Controls_GetKeyAssignment (char *command, int *twokeys)
+static void Controls_GetKeyAssignment(char *command, int *twokeys)
{
- int count;
- int j;
- char b[256];
+ int count;
+ int j;
+ char b[256];
- twokeys[0] = twokeys[1] = -1;
- count = 0;
+ twokeys[0] = twokeys[1] = -1;
+ count = 0;
- for ( j = 0; j < 256; j++ )
- {
- DC->getBindingBuf( j, b, 256 );
- if ( *b == 0 ) {
- continue;
- }
- if ( !Q_stricmp( b, command ) ) {
- twokeys[count] = j;
- count++;
- if (count == 2) {
- break;
- }
+ for (j = 0; j < 256; j++)
+ {
+ DC->getBindingBuf(j, b, 256);
+
+ if (*b == 0)
+ continue;
+
+ if (!Q_stricmp(b, command))
+ {
+ twokeys[count] = j;
+ count++;
+
+ if (count == 2)
+ break;
+ }
}
- }
}
/*
=================
Controls_GetConfig
+
+Iterate each command, get its numeric binding
=================
*/
-void Controls_GetConfig( void )
+void Controls_GetConfig(void)
{
- int i;
- int twokeys[ 2 ];
-
- // iterate each command, get its numeric binding
- for( i = 0; i < g_bindCount; i++ )
- {
- Controls_GetKeyAssignment( g_bindings[ i ].command, twokeys );
+ size_t i;
+ int twokeys[2];
- g_bindings[ i ].bind1 = twokeys[ 0 ];
- g_bindings[ i ].bind2 = twokeys[ 1 ];
- }
+ for (i = 0; i < g_bindCount; i++)
+ {
+ Controls_GetKeyAssignment(g_bindings[i].command, twokeys);
- //s_controls.invertmouse.curvalue = DC->getCVarValue( "m_pitch" ) < 0;
- //s_controls.smoothmouse.curvalue = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "m_filter" ) );
- //s_controls.alwaysrun.curvalue = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "cl_run" ) );
- //s_controls.autoswitch.curvalue = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "cg_autoswitch" ) );
- //s_controls.sensitivity.curvalue = UI_ClampCvar( 2, 30, Controls_GetCvarValue( "sensitivity" ) );
- //s_controls.joyenable.curvalue = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "in_joystick" ) );
- //s_controls.joythreshold.curvalue = UI_ClampCvar( 0.05, 0.75, Controls_GetCvarValue( "joy_threshold" ) );
- //s_controls.freelook.curvalue = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "cl_freelook" ) );
+ g_bindings[i].bind1 = twokeys[0];
+ g_bindings[i].bind2 = twokeys[1];
+ }
}
/*
=================
Controls_SetConfig
+
+Iterate each command, get its numeric binding
=================
*/
void Controls_SetConfig(qboolean restart)
{
- int i;
+ unsigned int i;
- // iterate each command, get its numeric binding
- for (i=0; i < g_bindCount; i++)
- {
+ (void)restart;
- if (g_bindings[i].bind1 != -1)
+ for (i = 0; i < g_bindCount; i++)
{
- DC->setBinding( g_bindings[i].bind1, g_bindings[i].command );
-
- if (g_bindings[i].bind2 != -1)
- DC->setBinding( g_bindings[i].bind2, g_bindings[i].command );
+ if (g_bindings[i].bind1 != -1)
+ {
+ DC->setBinding(g_bindings[i].bind1, g_bindings[i].command);
+ if (g_bindings[i].bind2 != -1)
+ DC->setBinding(g_bindings[i].bind2, g_bindings[i].command);
+ }
}
- }
-
- //if ( s_controls.invertmouse.curvalue )
- // DC->setCVar("m_pitch", va("%f),-fabs( DC->getCVarValue( "m_pitch" ) ) );
- //else
- // trap_Cvar_SetValue( "m_pitch", fabs( trap_Cvar_VariableValue( "m_pitch" ) ) );
- //trap_Cvar_SetValue( "m_filter", s_controls.smoothmouse.curvalue );
- //trap_Cvar_SetValue( "cl_run", s_controls.alwaysrun.curvalue );
- //trap_Cvar_SetValue( "cg_autoswitch", s_controls.autoswitch.curvalue );
- //trap_Cvar_SetValue( "sensitivity", s_controls.sensitivity.curvalue );
- //trap_Cvar_SetValue( "in_joystick", s_controls.joyenable.curvalue );
- //trap_Cvar_SetValue( "joy_threshold", s_controls.joythreshold.curvalue );
- //trap_Cvar_SetValue( "cl_freelook", s_controls.freelook.curvalue );
- DC->executeText(EXEC_APPEND, "in_restart\n");
- //trap_Cmd_ExecuteText( EXEC_APPEND, "in_restart\n" );
+ DC->executeText(EXEC_APPEND, "in_restart\n");
}
/*
=================
Controls_SetDefaults
+
+Iterate each command, set its default binding
=================
*/
-void Controls_SetDefaults( void )
+void Controls_SetDefaults(void)
{
- int i;
-
- // iterate each command, set its default binding
- for (i=0; i < g_bindCount; i++)
- {
- g_bindings[i].bind1 = g_bindings[i].defaultbind1;
- g_bindings[i].bind2 = g_bindings[i].defaultbind2;
- }
-
- //s_controls.invertmouse.curvalue = Controls_GetCvarDefault( "m_pitch" ) < 0;
- //s_controls.smoothmouse.curvalue = Controls_GetCvarDefault( "m_filter" );
- //s_controls.alwaysrun.curvalue = Controls_GetCvarDefault( "cl_run" );
- //s_controls.autoswitch.curvalue = Controls_GetCvarDefault( "cg_autoswitch" );
- //s_controls.sensitivity.curvalue = Controls_GetCvarDefault( "sensitivity" );
- //s_controls.joyenable.curvalue = Controls_GetCvarDefault( "in_joystick" );
- //s_controls.joythreshold.curvalue = Controls_GetCvarDefault( "joy_threshold" );
- //s_controls.freelook.curvalue = Controls_GetCvarDefault( "cl_freelook" );
+ unsigned int i;
+ for (i = 0; i < g_bindCount; i++)
+ {
+ g_bindings[i].bind1 = g_bindings[i].defaultbind1;
+ g_bindings[i].bind2 = g_bindings[i].defaultbind2;
+ }
}
-int BindingIDFromName(const char *name) {
- int i;
- for (i=0; i < g_bindCount; i++)
- {
- if (Q_stricmp(name, g_bindings[i].command) == 0) {
- return i;
+int BindingIDFromName(const char *name)
+{
+ size_t i;
+ for (i = 0; i < g_bindCount; i++)
+ {
+ if (Q_stricmp(name, g_bindings[i].command) == 0)
+ return i;
}
- }
- return -1;
+
+ return -1;
}
char g_nameBind1[32];
char g_nameBind2[32];
-void BindingFromName(const char *cvar) {
- int i, b1, b2;
-
- // iterate each command, set its default binding
- for (i=0; i < g_bindCount; i++)
- {
- if (Q_stricmp(cvar, g_bindings[i].command) == 0) {
- b1 = g_bindings[i].bind1;
- if (b1 == -1) {
- break;
- }
- DC->keynumToStringBuf( b1, g_nameBind1, 32 );
- Q_strupr(g_nameBind1);
-
- b2 = g_bindings[i].bind2;
- if (b2 != -1)
- {
- DC->keynumToStringBuf( b2, g_nameBind2, 32 );
- Q_strupr(g_nameBind2);
- strcat( g_nameBind1, " or " );
- strcat( g_nameBind1, g_nameBind2 );
- }
- return;
- }
- }
- strcpy(g_nameBind1, "???");
-}
-
-void Item_Slider_Paint(itemDef_t *item) {
- vec4_t newColor;
- float x, y, value;
- menuDef_t *parent = (menuDef_t*)item->parent;
-
- value = (item->cvar) ? DC->getCVarValue(item->cvar) : 0;
-
- if (item->window.flags & WINDOW_HASFOCUS) {
-/* lowLight[0] = 0.8 * parent->focusColor[0];
- lowLight[1] = 0.8 * parent->focusColor[1];
- lowLight[2] = 0.8 * parent->focusColor[2];
- lowLight[3] = 0.8 * parent->focusColor[3];
- LerpColor(parent->focusColor,lowLight,newColor,0.5+0.5*sin(DC->realTime / PULSE_DIVISOR));*/
- //TA:
- memcpy(newColor, &parent->focusColor, sizeof(vec4_t));
- } else {
- memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t));
- }
-
- y = item->window.rect.y;
- if (item->text) {
- Item_Text_Paint(item);
- x = item->textRect.x + item->textRect.w + 8;
- } else {
- x = item->window.rect.x;
- }
- DC->setColor(newColor);
- DC->drawHandlePic( x, y, SLIDER_WIDTH, SLIDER_HEIGHT, DC->Assets.sliderBar );
-
- x = Item_Slider_ThumbPosition(item);
- DC->drawHandlePic( x - (SLIDER_THUMB_WIDTH / 2), y - 2, SLIDER_THUMB_WIDTH, SLIDER_THUMB_HEIGHT, DC->Assets.sliderThumb );
-
-}
-
-void Item_Bind_Paint(itemDef_t *item) {
- vec4_t newColor, lowLight;
- float value;
- int maxChars = 0;
- menuDef_t *parent = (menuDef_t*)item->parent;
- editFieldDef_t *editPtr = (editFieldDef_t*)item->typeData;
- if (editPtr) {
- maxChars = editPtr->maxPaintChars;
- }
-
- value = (item->cvar) ? DC->getCVarValue(item->cvar) : 0;
-
- if (item->window.flags & WINDOW_HASFOCUS) {
- if (g_bindItem == item) {
- lowLight[0] = 0.8f * 1.0f;
- lowLight[1] = 0.8f * 0.0f;
- lowLight[2] = 0.8f * 0.0f;
- lowLight[3] = 0.8f * 1.0f;
- } else {
- lowLight[0] = 0.8f * parent->focusColor[0];
- lowLight[1] = 0.8f * parent->focusColor[1];
- lowLight[2] = 0.8f * parent->focusColor[2];
- lowLight[3] = 0.8f * parent->focusColor[3];
- }
- /*LerpColor(parent->focusColor,lowLight,newColor,0.5+0.5*sin(DC->realTime / PULSE_DIVISOR));*/
- //TA:
- memcpy(newColor, &parent->focusColor, sizeof(vec4_t));
- } else {
- memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t));
- }
-
- if (item->text) {
- Item_Text_Paint(item);
- BindingFromName(item->cvar);
- DC->drawText(item->textRect.x + item->textRect.w + 8, item->textRect.y, item->textscale, newColor, g_nameBind1, 0, maxChars, item->textStyle);
- } else {
- DC->drawText(item->textRect.x, item->textRect.y, item->textscale, newColor, (value != 0) ? "FIXME" : "FIXME", 0, maxChars, item->textStyle);
- }
-}
+void BindingFromName(const char *cvar)
+{
+ int i, b1, b2;
+
+ // iterate each command, set its default binding
+
+ for (i = 0; i < g_bindCount; i++)
+ {
+ if (Q_stricmp(cvar, g_bindings[i].command) == 0)
+ {
+ b1 = g_bindings[i].bind1;
-qboolean Display_KeyBindPending( void ) {
- return g_waitingForKey;
+ if (b1 == -1)
+ break;
+
+ DC->keynumToStringBuf(b1, g_nameBind1, 32);
+ Q_strupr(g_nameBind1);
+
+ b2 = g_bindings[i].bind2;
+
+ if (b2 != -1)
+ {
+ DC->keynumToStringBuf(b2, g_nameBind2, 32);
+ Q_strupr(g_nameBind2);
+ strcat(g_nameBind1, " or ");
+ strcat(g_nameBind1, g_nameBind2);
+ }
+
+ return;
+ }
+ }
+
+ strcpy(g_nameBind1, "???");
}
-qboolean Item_Bind_HandleKey(itemDef_t *item, int key, qboolean down) {
- int id;
- int i;
+void Item_Slider_Paint(itemDef_t *item)
+{
+ vec4_t newColor;
+ float x, y;
+
+ menuDef_t *parent = (menuDef_t *)item->parent;
+ float vScale = Item_Slider_VScale(item);
+
+ if (item->window.flags & WINDOW_HASFOCUS)
+ memcpy(newColor, &parent->focusColor, sizeof(vec4_t));
+ else
+ memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t));
- if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && !g_waitingForKey)
- {
- if (down && (key == K_MOUSE1 || key == K_ENTER)) {
- g_waitingForKey = qtrue;
- g_bindItem = item;
+ if (item->text)
+ {
+ Item_Text_Paint(item);
+ x = item->textRect.x + item->textRect.w + ITEM_VALUE_OFFSET;
+ y = item->textRect.y - item->textRect.h + ((item->textRect.h - (SLIDER_HEIGHT * vScale)) / 2.0f);
}
- return qtrue;
- }
- else
- {
- if (!g_waitingForKey || g_bindItem == NULL) {
- return qtrue;
+ else
+ {
+ x = item->window.rect.x;
+ y = item->window.rect.y;
}
- if (key & K_CHAR_FLAG) {
- return qtrue;
+ DC->setColor(newColor);
+ DC->drawHandlePic(x, y, SLIDER_WIDTH, SLIDER_HEIGHT * vScale, DC->Assets.sliderBar);
+
+ y = item->textRect.y - item->textRect.h + ((item->textRect.h - (SLIDER_THUMB_HEIGHT * vScale)) / 2.0f);
+
+ x = Item_Slider_ThumbPosition(item);
+ DC->drawHandlePic(
+ x - (SLIDER_THUMB_WIDTH / 2), y, SLIDER_THUMB_WIDTH, SLIDER_THUMB_HEIGHT * vScale, DC->Assets.sliderThumb);
+}
+
+void Item_Bind_Paint(itemDef_t *item)
+{
+ vec4_t newColor, lowLight;
+ float value;
+ int maxChars = 0;
+ menuDef_t *parent = (menuDef_t *)item->parent;
+
+ if (item->typeData.edit)
+ maxChars = item->typeData.edit->maxPaintChars;
+
+ value = (item->cvar) ? DC->getCVarValue(item->cvar) : 0;
+
+ if (item->window.flags & WINDOW_HASFOCUS)
+ {
+ if (g_bindItem == item)
+ {
+ lowLight[0] = 0.8f * parent->focusColor[0];
+ lowLight[1] = 0.8f * parent->focusColor[1];
+ lowLight[2] = 0.8f * parent->focusColor[2];
+ lowLight[3] = 0.8f * parent->focusColor[3];
+
+ LerpColor(parent->focusColor, lowLight, newColor, 0.5 + 0.5 * sin(DC->realTime / PULSE_DIVISOR));
+ }
+ else
+ memcpy(&newColor, &parent->focusColor, sizeof(vec4_t));
}
+ else
+ memcpy(&newColor, &item->window.foreColor, sizeof(vec4_t));
- switch (key)
+ if (item->text)
{
- case K_ESCAPE:
- g_waitingForKey = qfalse;
- return qtrue;
+ Item_Text_Paint(item);
- case K_BACKSPACE:
- id = BindingIDFromName(item->cvar);
- if (id != -1) {
- g_bindings[id].bind1 = -1;
- g_bindings[id].bind2 = -1;
+ if (g_bindItem == item && g_waitingForKey)
+ {
+ UI_Text_Paint(item->textRect.x + item->textRect.w + ITEM_VALUE_OFFSET, item->textRect.y, item->textscale,
+ newColor, "Press key", 0, maxChars, item->textStyle);
+ }
+ else
+ {
+ BindingFromName(item->cvar);
+ UI_Text_Paint(item->textRect.x + item->textRect.w + ITEM_VALUE_OFFSET, item->textRect.y, item->textscale,
+ newColor, g_nameBind1, 0, maxChars, item->textStyle);
+ }
+ }
+ else
+ UI_Text_Paint(item->textRect.x, item->textRect.y, item->textscale, newColor, (value != 0) ? "FIXME" : "FIXME",
+ 0, maxChars, item->textStyle);
+}
+
+qboolean Display_KeyBindPending(void) { return g_waitingForKey; }
+
+qboolean Item_Bind_HandleKey(itemDef_t *item, int key, qboolean down)
+{
+ int id;
+
+ if (Rect_ContainsPoint(&item->window.rect, DC->cursorx, DC->cursory) && !g_waitingForKey)
+ {
+ if (down && (key == K_MOUSE1 || key == K_ENTER))
+ {
+ g_waitingForKey = qtrue;
+ g_bindItem = item;
}
- Controls_SetConfig(qtrue);
- g_waitingForKey = qfalse;
- g_bindItem = NULL;
- return qtrue;
- case '`':
return qtrue;
}
- }
+ else
+ {
+ if (!g_waitingForKey || g_bindItem == NULL)
+ return qtrue;
- if (key != -1)
- {
+ if (key & K_CHAR_FLAG)
+ return qtrue;
- for (i=0; i < g_bindCount; i++)
- {
+ switch (key)
+ {
+ case K_ESCAPE:
+ g_waitingForKey = qfalse;
+ return qtrue;
+
+ case K_BACKSPACE:
+ id = BindingIDFromName(item->cvar);
+
+ if (id != -1)
+ {
+ g_bindings[id].bind1 = -1;
+ g_bindings[id].bind2 = -1;
+ }
+
+ Controls_SetConfig(qtrue);
+ g_waitingForKey = qfalse;
+ g_bindItem = NULL;
+ return qtrue;
+
+ case '`':
+ return qtrue;
+ }
+ }
- if (g_bindings[i].bind2 == key) {
- g_bindings[i].bind2 = -1;
- }
+ if (key != -1)
+ {
+ unsigned int i;
+ for (i = 0; i < g_bindCount; i++)
+ {
+ if (g_bindings[i].bind2 == key)
+ g_bindings[i].bind2 = -1;
- if (g_bindings[i].bind1 == key)
- {
- g_bindings[i].bind1 = g_bindings[i].bind2;
- g_bindings[i].bind2 = -1;
- }
+ if (g_bindings[i].bind1 == key)
+ {
+ g_bindings[i].bind1 = g_bindings[i].bind2;
+ g_bindings[i].bind2 = -1;
+ }
+ }
}
- }
+ id = BindingIDFromName(item->cvar);
- id = BindingIDFromName(item->cvar);
+ if (id != -1)
+ {
+ if (key == -1)
+ {
+ if (g_bindings[id].bind1 != -1)
+ {
+ DC->setBinding(g_bindings[id].bind1, "");
+ g_bindings[id].bind1 = -1;
+ }
- if (id != -1) {
- if (key == -1) {
- if( g_bindings[id].bind1 != -1 ) {
- DC->setBinding( g_bindings[id].bind1, "" );
- g_bindings[id].bind1 = -1;
- }
- if( g_bindings[id].bind2 != -1 ) {
- DC->setBinding( g_bindings[id].bind2, "" );
- g_bindings[id].bind2 = -1;
- }
- }
- else if (g_bindings[id].bind1 == -1) {
- g_bindings[id].bind1 = key;
+ if (g_bindings[id].bind2 != -1)
+ {
+ DC->setBinding(g_bindings[id].bind2, "");
+ g_bindings[id].bind2 = -1;
+ }
+ }
+ else if (g_bindings[id].bind1 == -1)
+ g_bindings[id].bind1 = key;
+ else if (g_bindings[id].bind1 != key && g_bindings[id].bind2 == -1)
+ g_bindings[id].bind2 = key;
+ else
+ {
+ DC->setBinding(g_bindings[id].bind1, "");
+ DC->setBinding(g_bindings[id].bind2, "");
+ g_bindings[id].bind1 = key;
+ g_bindings[id].bind2 = -1;
+ }
}
- else if (g_bindings[id].bind1 != key && g_bindings[id].bind2 == -1) {
- g_bindings[id].bind2 = key;
+
+ Controls_SetConfig(qtrue);
+ g_waitingForKey = qfalse;
+
+ return qtrue;
+}
+
+void Item_Model_Paint(itemDef_t *item)
+{
+ float x, y, w, h;
+ refdef_t refdef;
+ refEntity_t ent;
+ vec3_t mins, maxs, origin;
+ vec3_t angles;
+
+ modelDef_t *modelPtr = item->typeData.model;
+ if (modelPtr == NULL)
+ return;
+
+ // setup the refdef
+ memset(&refdef, 0, sizeof(refdef));
+
+ refdef.rdflags = RDF_NOWORLDMODEL;
+
+ AxisClear(refdef.viewaxis);
+
+ x = item->window.rect.x + 1;
+ y = item->window.rect.y + 1;
+ w = item->window.rect.w - 2;
+ h = item->window.rect.h - 2;
+
+ UI_AdjustFrom640(&x, &y, &w, &h);
+
+ refdef.x = x;
+ refdef.y = y;
+ refdef.width = w;
+ refdef.height = h;
+
+ DC->modelBounds(item->asset, mins, maxs);
+
+ origin[2] = -0.5 * (mins[2] + maxs[2]);
+ origin[1] = 0.5 * (mins[1] + maxs[1]);
+
+ // calculate distance so the model nearly fills the box
+ if (qtrue)
+ {
+ float len = 0.5 * (maxs[2] - mins[2]);
+ origin[0] = len / 0.268; // len / tan( fov/2 )
+ // origin[0] = len / tan(w/2);
}
- else {
- DC->setBinding( g_bindings[id].bind1, "" );
- DC->setBinding( g_bindings[id].bind2, "" );
- g_bindings[id].bind1 = key;
- g_bindings[id].bind2 = -1;
+ else
+ origin[0] = item->textscale;
+
+ refdef.fov_x = (modelPtr->fov_x) ? modelPtr->fov_x : w;
+ refdef.fov_y = (modelPtr->fov_y) ? modelPtr->fov_y : h;
+
+ // refdef.fov_x = (int)((float)refdef.width / 640.0f * 90.0f);
+ // xx = refdef.width / tan( refdef.fov_x / 360 * M_PI );
+ // refdef.fov_y = atan2( refdef.height, xx );
+ // refdef.fov_y *= ( 360 / M_PI );
+
+ DC->clearScene();
+
+ refdef.time = DC->realTime;
+
+ // add the model
+
+ memset(&ent, 0, sizeof(ent));
+
+ // adjust = 5.0 * sin( (float)uis.realtime / 500 );
+ // adjust = 360 % (int)((float)uis.realtime / 1000);
+ // VectorSet( angles, 0, 0, 1 );
+
+ // use item storage to track
+
+ if (modelPtr->rotationSpeed)
+ {
+ if (DC->realTime > item->window.nextTime)
+ {
+ item->window.nextTime = DC->realTime + modelPtr->rotationSpeed;
+ modelPtr->angle = (int)(modelPtr->angle + 1) % 360;
+ }
}
- }
- Controls_SetConfig(qtrue);
- g_waitingForKey = qfalse;
+ VectorSet(angles, 0, modelPtr->angle, 0);
+ AnglesToAxis(angles, ent.axis);
+
+ ent.hModel = item->asset;
+ VectorCopy(origin, ent.origin);
+ VectorCopy(origin, ent.lightingOrigin);
+ ent.renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW;
+ VectorCopy(ent.origin, ent.oldorigin);
- return qtrue;
+ DC->addRefEntityToScene(&ent);
+ DC->renderScene(&refdef);
}
+void Item_ListBoxRow_Paint(itemDef_t *item, int row, int renderPos, qboolean highlight, qboolean scrollbar)
+{
+ float x, y, w;
+ listBoxDef_t *listPtr = item->typeData.list;
+ menuDef_t *menu = (menuDef_t *)item->parent;
+ float one, two;
+ one = 1.0f * DC->aspectScale;
+ two = 2.0f * DC->aspectScale;
-void AdjustFrom640(float *x, float *y, float *w, float *h) {
- //*x = *x * DC->scale + DC->bias;
- *x *= DC->xscale;
- *y *= DC->yscale;
- *w *= DC->xscale;
- *h *= DC->yscale;
-}
+ x = SCROLLBAR_X(item);
+ y = SCROLLBAR_Y(item) + (listPtr->elementHeight * renderPos);
+ w = item->window.rect.w - (two * item->window.borderSize);
-void Item_Model_Paint(itemDef_t *item) {
- float x, y, w, h;
- refdef_t refdef;
- refEntity_t ent;
- vec3_t mins, maxs, origin;
- vec3_t angles;
- modelDef_t *modelPtr = (modelDef_t*)item->typeData;
+ if (scrollbar)
+ w -= SCROLLBAR_ARROW_WIDTH;
- if (modelPtr == NULL) {
- return;
- }
+ if (listPtr->elementStyle == LISTBOX_IMAGE)
+ {
+ qhandle_t image = DC->feederItemImage(item->feederID, row);
- // setup the refdef
- memset( &refdef, 0, sizeof( refdef ) );
- refdef.rdflags = RDF_NOWORLDMODEL;
- AxisClear( refdef.viewaxis );
- x = item->window.rect.x+1;
- y = item->window.rect.y+1;
- w = item->window.rect.w-2;
- h = item->window.rect.h-2;
+ UI_SetClipRegion(x, y, listPtr->elementWidth, listPtr->elementHeight);
- AdjustFrom640( &x, &y, &w, &h );
+ if (image)
+ DC->drawHandlePic(x + one, y + 1.0f, listPtr->elementWidth - two, listPtr->elementHeight - 2.0f, image);
- refdef.x = x;
- refdef.y = y;
- refdef.width = w;
- refdef.height = h;
+ if (highlight && row == item->cursorPos)
+ {
+ DC->drawRect(
+ x, y, listPtr->elementWidth, listPtr->elementHeight, item->window.borderSize, item->window.borderColor);
+ }
- DC->modelBounds( item->asset, mins, maxs );
+ UI_ClearClipRegion();
+ }
+ else
+ {
+ const float m = UI_Text_EmHeight(item->textscale);
+ char text[MAX_STRING_CHARS];
+ qhandle_t optionalImage;
- origin[2] = -0.5 * ( mins[2] + maxs[2] );
- origin[1] = 0.5 * ( mins[1] + maxs[1] );
+ if (listPtr->numColumns > 0)
+ {
+ int j;
+
+ for (j = 0; j < listPtr->numColumns; j++)
+ {
+ float columnPos;
+ float width, height, yOffset;
+
+ if (menu->window.aspectBias != ASPECT_NONE || item->window.aspectBias != ASPECT_NONE)
+ {
+ columnPos = (listPtr->columnInfo[j].pos + 4.0f) * DC->aspectScale;
+ width = listPtr->columnInfo[j].width * DC->aspectScale;
+ }
+ else
+ {
+ columnPos = (listPtr->columnInfo[j].pos + 4.0f);
+ width = listPtr->columnInfo[j].width;
+ }
+
+ height = listPtr->columnInfo[j].width;
+ yOffset = y + ((listPtr->elementHeight - height) / 2.0f);
+
+ Q_strncpyz(text, DC->feederItemText(item->feederID, row, j, &optionalImage), sizeof(text));
+
+ UI_SetClipRegion(x + columnPos, yOffset, width, height);
+
+ if (optionalImage >= 0)
+ DC->drawHandlePic(x + columnPos, yOffset, width, height, optionalImage);
+ else if (text[0])
+ {
+ float alignOffset = 0.0f, tw;
+
+ tw = UI_Text_Width(text, item->textscale);
+
+ switch (listPtr->columnInfo[j].align)
+ {
+ case ALIGN_LEFT:
+ alignOffset = 0.0f;
+ break;
+
+ case ALIGN_RIGHT:
+ alignOffset = width - tw;
+ break;
+
+ case ALIGN_CENTER:
+ alignOffset = (width / 2.0f) - (tw / 2.0f);
+ break;
+
+ default:
+ alignOffset = 0.0f;
+ }
+
+ UI_Text_Paint(x + columnPos + alignOffset, y + m + ((listPtr->elementHeight - m) / 2.0f),
+ item->textscale, item->window.foreColor, text, 0, 0, item->textStyle);
+ }
+
+ UI_ClearClipRegion();
+ }
+ }
+ else
+ {
+ float offset;
- // calculate distance so the model nearly fills the box
- if (qtrue) {
- float len = 0.5 * ( maxs[2] - mins[2] );
- origin[0] = len / 0.268; // len / tan( fov/2 )
- //origin[0] = len / tan(w/2);
- } else {
- origin[0] = item->textscale;
- }
- refdef.fov_x = (modelPtr->fov_x) ? modelPtr->fov_x : w;
- refdef.fov_y = (modelPtr->fov_y) ? modelPtr->fov_y : h;
+ if (menu->window.aspectBias != ASPECT_NONE || item->window.aspectBias != ASPECT_NONE)
+ offset = 4.0f * DC->aspectScale;
+ else
+ offset = 4.0f;
- //refdef.fov_x = (int)((float)refdef.width / 640.0f * 90.0f);
- //xx = refdef.width / tan( refdef.fov_x / 360 * M_PI );
- //refdef.fov_y = atan2( refdef.height, xx );
- //refdef.fov_y *= ( 360 / M_PI );
+ Q_strncpyz(text, DC->feederItemText(item->feederID, row, 0, &optionalImage), sizeof(text));
- DC->clearScene();
+ UI_SetClipRegion(x, y, w, listPtr->elementHeight);
- refdef.time = DC->realTime;
+ if (optionalImage >= 0)
+ DC->drawHandlePic(x + offset, y, listPtr->elementHeight, listPtr->elementHeight, optionalImage);
+ else if (text[0])
+ {
+ UI_Text_Paint(x + offset, y + m + ((listPtr->elementHeight - m) / 2.0f), item->textscale,
+ item->window.foreColor, text, 0, 0, item->textStyle);
+ }
+
+ UI_ClearClipRegion();
+ }
- // add the model
+ if (highlight && row == item->cursorPos)
+ DC->fillRect(x, y, w, listPtr->elementHeight, item->window.outlineColor);
+ }
+}
- memset( &ent, 0, sizeof(ent) );
+void Item_ListBox_Paint(itemDef_t *item)
+{
+ float size;
+ int i;
+ listBoxDef_t *listPtr = item->typeData.list;
+ int count = DC->feederCount(item->feederID);
+ qboolean scrollbar = !(listPtr->noscrollbar && count > Item_ListBox_NumItemsForItemHeight(item));
+ if (scrollbar)
+ {
+ float x = SCROLLBAR_SLIDER_X(item);
+ float y = SCROLLBAR_Y(item);
+ float thumbY = Item_ListBox_ThumbDrawPosition(item);
- //adjust = 5.0 * sin( (float)uis.realtime / 500 );
- //adjust = 360 % (int)((float)uis.realtime / 1000);
- //VectorSet( angles, 0, 0, 1 );
+ // Up arrow
+ DC->drawHandlePic(x, y, SCROLLBAR_ARROW_WIDTH, SCROLLBAR_ARROW_HEIGHT, DC->Assets.scrollBarArrowUp);
+ y = SCROLLBAR_SLIDER_Y(item);
- // use item storage to track
- if (modelPtr->rotationSpeed) {
- if (DC->realTime > item->window.nextTime) {
- item->window.nextTime = DC->realTime + modelPtr->rotationSpeed;
- modelPtr->angle = (int)(modelPtr->angle + 1) % 360;
+ // Scroll bar
+ size = SCROLLBAR_SLIDER_HEIGHT(item);
+ DC->drawHandlePic(x, y, SCROLLBAR_ARROW_WIDTH, size, DC->Assets.scrollBar);
+ y = SCROLLBAR_SLIDER_Y(item) + size;
+
+ // Down arrow
+ DC->drawHandlePic(x, y, SCROLLBAR_ARROW_WIDTH, SCROLLBAR_ARROW_HEIGHT, DC->Assets.scrollBarArrowDown);
+
+ // Thumb
+ DC->drawHandlePic(x, thumbY, SCROLLBAR_ARROW_WIDTH, SCROLLBAR_ARROW_HEIGHT, DC->Assets.scrollBarThumb);
}
- }
- VectorSet( angles, 0, modelPtr->angle, 0 );
- AnglesToAxis( angles, ent.axis );
- ent.hModel = item->asset;
- VectorCopy( origin, ent.origin );
- VectorCopy( origin, ent.lightingOrigin );
- ent.renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW;
- VectorCopy( ent.origin, ent.oldorigin );
+ // Paint rows
+ for (i = listPtr->startPos; i < listPtr->endPos; i++)
+ Item_ListBoxRow_Paint(item, i, i - listPtr->startPos, qtrue, scrollbar);
+}
+
+void Item_Paint(itemDef_t *item);
+
+void Item_ComboBox_Paint(itemDef_t *item)
+{
+ float x, y, h;
- DC->addRefEntityToScene( &ent );
- DC->renderScene( &refdef );
+ x = SCROLLBAR_SLIDER_X(item);
+ y = SCROLLBAR_Y(item);
+ h = item->window.rect.h - 2.0f;
+ // Down arrow
+ DC->drawHandlePic(x, y, SCROLLBAR_ARROW_WIDTH, h, DC->Assets.scrollBarArrowDown);
+ Item_ListBoxRow_Paint(item, item->cursorPos, 0, qfalse, qtrue);
+ if (g_comboBoxItem != NULL)
+ {
+ qboolean cast = Item_ComboBox_MaybeCastToListBox(item);
+ Item_Paint(item);
+ Item_ComboBox_MaybeUnCastFromListBox(item, cast);
+ }
}
+void Item_ListBox_Update(itemDef_t *item)
+{
+ listBoxDef_t *listPtr = item->typeData.list;
+ int feederCount = DC->feederCount(item->feederID);
+
+ if (listPtr->lastFeederCount != feederCount)
+ {
+ if (listPtr->resetonfeederchange)
+ {
+ item->cursorPos = DC->feederInitialise(item->feederID);
+ Item_ListBox_SetStartPos(item, 0);
+ DC->feederSelection(item->feederID, item->cursorPos);
+ }
+ else
+ {
+ // Make sure endPos is up-to-date
+ Item_ListBox_SetStartPos(item, listPtr->startPos);
-void Item_Image_Paint(itemDef_t *item) {
- if (item == NULL) {
- return;
- }
- DC->drawHandlePic(item->window.rect.x+1, item->window.rect.y+1, item->window.rect.w-2, item->window.rect.h-2, item->asset);
+ // If the selection is off the end now, select the last element
+ if (item->cursorPos >= feederCount)
+ item->cursorPos = feederCount - 1;
+ }
+ }
+
+ listPtr->lastFeederCount = feederCount;
}
-void Item_ListBox_Paint(itemDef_t *item) {
- float x, y, size, thumb;
- int i, count;
- qhandle_t image;
- qhandle_t optionalImage;
- listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
-
- // the listbox is horizontal or vertical and has a fixed size scroll bar going either direction
- // elements are enumerated from the DC and either text or image handles are acquired from the DC as well
- // textscale is used to size the text, textalignx and textaligny are used to size image elements
- // there is no clipping available so only the last completely visible item is painted
- count = DC->feederCount(item->special);
- // default is vertical if horizontal flag is not here
- if (item->window.flags & WINDOW_HORIZONTAL) {
- // draw scrollbar in bottom of the window
- // bar
- x = item->window.rect.x + 1;
- y = item->window.rect.y + item->window.rect.h - SCROLLBAR_SIZE - 1;
- DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowLeft);
- x += SCROLLBAR_SIZE - 1;
- size = item->window.rect.w - (SCROLLBAR_SIZE * 2);
- DC->drawHandlePic(x, y, size+1, SCROLLBAR_SIZE, DC->Assets.scrollBar);
- x += size - 1;
- DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowRight);
- // thumb
- thumb = Item_ListBox_ThumbDrawPosition(item);//Item_ListBox_ThumbPosition(item);
- if (thumb > x - SCROLLBAR_SIZE - 1) {
- thumb = x - SCROLLBAR_SIZE - 1;
- }
- DC->drawHandlePic(thumb, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarThumb);
- //
- listPtr->endPos = listPtr->startPos;
- size = item->window.rect.w - 2;
- // items
- // size contains max available space
- if (listPtr->elementStyle == LISTBOX_IMAGE) {
- // fit = 0;
- x = item->window.rect.x + 1;
- y = item->window.rect.y + 1;
- for (i = listPtr->startPos; i < count; i++) {
- // always draw at least one
- // which may overdraw the box if it is too small for the element
- image = DC->feederItemImage(item->special, i);
- if (image) {
- DC->drawHandlePic(x+1, y+1, listPtr->elementWidth - 2, listPtr->elementHeight - 2, image);
- }
-
- if (i == item->cursorPos) {
- DC->drawRect(x, y, listPtr->elementWidth-1, listPtr->elementHeight-1, item->window.borderSize, item->window.borderColor);
- }
-
- listPtr->endPos++;
- size -= listPtr->elementWidth;
- if (size < listPtr->elementWidth) {
- listPtr->drawPadding = size; //listPtr->elementWidth - size;
- break;
- }
- x += listPtr->elementWidth;
- // fit++;
- }
- } else {
- //
- }
- } else {
- // draw scrollbar to right side of the window
- x = item->window.rect.x + item->window.rect.w - SCROLLBAR_SIZE - 1;
- y = item->window.rect.y + 1;
- DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowUp);
- y += SCROLLBAR_SIZE - 1;
-
- listPtr->endPos = listPtr->startPos;
- size = item->window.rect.h - (SCROLLBAR_SIZE * 2);
- DC->drawHandlePic(x, y, SCROLLBAR_SIZE, size+1, DC->Assets.scrollBar);
- y += size - 1;
- DC->drawHandlePic(x, y, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarArrowDown);
- // thumb
- thumb = Item_ListBox_ThumbDrawPosition(item);//Item_ListBox_ThumbPosition(item);
- if (thumb > y - SCROLLBAR_SIZE - 1) {
- thumb = y - SCROLLBAR_SIZE - 1;
- }
- DC->drawHandlePic(x, thumb, SCROLLBAR_SIZE, SCROLLBAR_SIZE, DC->Assets.scrollBarThumb);
-
- // adjust size for item painting
- size = item->window.rect.h - 2;
- if (listPtr->elementStyle == LISTBOX_IMAGE) {
- // fit = 0;
- x = item->window.rect.x + 1;
- y = item->window.rect.y + 1;
- for (i = listPtr->startPos; i < count; i++) {
- // always draw at least one
- // which may overdraw the box if it is too small for the element
- image = DC->feederItemImage(item->special, i);
- if (image) {
- DC->drawHandlePic(x+1, y+1, listPtr->elementWidth - 2, listPtr->elementHeight - 2, image);
- }
-
- if (i == item->cursorPos) {
- DC->drawRect(x, y, listPtr->elementWidth - 1, listPtr->elementHeight - 1, item->window.borderSize, item->window.borderColor);
- }
-
- listPtr->endPos++;
- size -= listPtr->elementWidth;
- if (size < listPtr->elementHeight) {
- listPtr->drawPadding = listPtr->elementHeight - size;
- break;
- }
- y += listPtr->elementHeight;
- // fit++;
- }
- } else {
- x = item->window.rect.x + 1;
- y = item->window.rect.y + 1;
- for (i = listPtr->startPos; i < count; i++) {
- const char *text;
- // always draw at least one
- // which may overdraw the box if it is too small for the element
-
- if (listPtr->numColumns > 0) {
- int j;
- for (j = 0; j < listPtr->numColumns; j++) {
- text = DC->feederItemText(item->special, i, j, &optionalImage);
- if (optionalImage >= 0) {
- DC->drawHandlePic(x + 4 + listPtr->columnInfo[j].pos, y - 1 + listPtr->elementHeight / 2, listPtr->columnInfo[j].width, listPtr->columnInfo[j].width, optionalImage);
- } else if (text) {
- //TA:
- int alignOffset = 0.0f, tw;
-
- tw = DC->textWidth( text, item->textscale, 0 );
-
- switch( listPtr->columnInfo[ j ].align )
- {
- case ITEM_ALIGN_LEFT:
- alignOffset = 0.0f;
- break;
-
- case ITEM_ALIGN_RIGHT:
- alignOffset = listPtr->columnInfo[ j ].width - tw;
- break;
-
- case ITEM_ALIGN_CENTER:
- alignOffset = ( listPtr->columnInfo[ j ].width / 2.0f ) - ( tw / 2.0f );
- break;
+void Item_OwnerDraw_Paint(itemDef_t *item)
+{
+ menuDef_t *parent;
+ const char *text;
- default:
- alignOffset = 0.0f;
- }
+ if (item == NULL)
+ return;
+
+ parent = (menuDef_t *)item->parent;
+
+ if (DC->ownerDrawItem)
+ {
+ vec4_t color, lowLight;
+ Fade(&item->window.flags, &item->window.foreColor[3], parent->fadeClamp, &item->window.nextTime,
+ parent->fadeCycle, qtrue, parent->fadeAmount);
+ memcpy(&color, &item->window.foreColor, sizeof(color));
- DC->drawText( x + 4 + listPtr->columnInfo[j].pos + alignOffset, y + listPtr->elementHeight,
- item->textscale, item->window.foreColor, text, 0,
- listPtr->columnInfo[j].maxChars, item->textStyle );
+ if (item->numColors > 0 && DC->getValue)
+ {
+ // if the value is within one of the ranges then set color to that, otherwise leave at default
+ int i;
+ float f = DC->getValue(item->window.ownerDraw);
+
+ for (i = 0; i < item->numColors; i++)
+ {
+ if (f >= item->colorRanges[i].low && f <= item->colorRanges[i].high)
+ {
+ memcpy(&color, &item->colorRanges[i].color, sizeof(color));
+ break;
+ }
}
- }
- } else {
- text = DC->feederItemText(item->special, i, 0, &optionalImage);
- if (optionalImage >= 0) {
- //DC->drawHandlePic(x + 4 + listPtr->elementHeight, y, listPtr->columnInfo[j].width, listPtr->columnInfo[j].width, optionalImage);
- } else if (text) {
- DC->drawText(x + 4, y + listPtr->elementHeight, item->textscale, item->window.foreColor, text, 0, 0, item->textStyle);
- }
}
- if (i == item->cursorPos) {
- DC->fillRect(x + 2, y + 2, item->window.rect.w - SCROLLBAR_SIZE - 4, listPtr->elementHeight, item->window.outlineColor);
- }
-
- listPtr->endPos++;
- size -= listPtr->elementHeight;
- if (size < listPtr->elementHeight) {
- listPtr->drawPadding = listPtr->elementHeight - size;
- break;
- }
- y += listPtr->elementHeight;
- // fit++;
- }
+ if (item->window.flags & WINDOW_HASFOCUS)
+ memcpy(color, &parent->focusColor, sizeof(vec4_t));
+ else if (item->textStyle == ITEM_TEXTSTYLE_BLINK && !((DC->realTime / BLINK_DIVISOR) & 1))
+ {
+ lowLight[0] = 0.8 * item->window.foreColor[0];
+ lowLight[1] = 0.8 * item->window.foreColor[1];
+ lowLight[2] = 0.8 * item->window.foreColor[2];
+ lowLight[3] = 0.8 * item->window.foreColor[3];
+ LerpColor(item->window.foreColor, lowLight, color, 0.5 + 0.5 * sin(DC->realTime / PULSE_DIVISOR));
+ }
+
+ if (item->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(item, CVAR_ENABLE))
+ Com_Memcpy(color, parent->disableColor, sizeof(vec4_t));
+
+ if (DC->ownerDrawText && (text = DC->ownerDrawText(item->window.ownerDraw)))
+ {
+ if (item->text && *item->text)
+ {
+ Item_Text_Paint(item);
+
+ UI_Text_Paint(item->textRect.x + item->textRect.w + ITEM_VALUE_OFFSET, item->textRect.y,
+ item->textscale, color, text, 0, 0, item->textStyle);
+ }
+ else
+ {
+ item->text = text;
+ Item_Text_Paint(item);
+ item->text = NULL;
+ }
+ }
+ else
+ {
+ DC->ownerDrawItem(item->window.rect.x, item->window.rect.y, item->window.rect.w, item->window.rect.h,
+ item->textalignx, item->textaligny, item->window.ownerDraw, item->window.ownerDrawFlags,
+ item->alignment, item->textalignment, item->textvalignment, item->window.borderSize, item->textscale,
+ color, item->window.backColor, item->window.background, item->textStyle);
+ }
}
- }
+}
- //TA: FIXME: hacky fix to off-by-one bug
- listPtr->endPos--;
-}
-
-
-void Item_OwnerDraw_Paint(itemDef_t *item) {
- menuDef_t *parent;
-
- if (item == NULL) {
- return;
- }
- parent = (menuDef_t*)item->parent;
-
- if (DC->ownerDrawItem) {
- vec4_t color, lowLight;
- menuDef_t *parent = (menuDef_t*)item->parent;
- Fade(&item->window.flags, &item->window.foreColor[3], parent->fadeClamp, &item->window.nextTime, parent->fadeCycle, qtrue, parent->fadeAmount);
- memcpy(&color, &item->window.foreColor, sizeof(color));
- if (item->numColors > 0 && DC->getValue) {
- // if the value is within one of the ranges then set color to that, otherwise leave at default
- int i;
- float f = DC->getValue(item->window.ownerDraw);
- for (i = 0; i < item->numColors; i++) {
- if (f >= item->colorRanges[i].low && f <= item->colorRanges[i].high) {
- memcpy(&color, &item->colorRanges[i].color, sizeof(color));
- break;
- }
- }
- }
-
- if (item->window.flags & WINDOW_HASFOCUS) {
-/* lowLight[0] = 0.8 * parent->focusColor[0];
- lowLight[1] = 0.8 * parent->focusColor[1];
- lowLight[2] = 0.8 * parent->focusColor[2];
- lowLight[3] = 0.8 * parent->focusColor[3];
- LerpColor(parent->focusColor,lowLight,color,0.5+0.5*sin(DC->realTime / PULSE_DIVISOR));*/
- //TA:
- memcpy(color, &parent->focusColor, sizeof(vec4_t));
- } else if (item->textStyle == ITEM_TEXTSTYLE_BLINK && !((DC->realTime/BLINK_DIVISOR) & 1)) {
- lowLight[0] = 0.8 * item->window.foreColor[0];
- lowLight[1] = 0.8 * item->window.foreColor[1];
- lowLight[2] = 0.8 * item->window.foreColor[2];
- lowLight[3] = 0.8 * item->window.foreColor[3];
- LerpColor(item->window.foreColor,lowLight,color,0.5+0.5*sin(DC->realTime / PULSE_DIVISOR));
- }
-
- if (item->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(item, CVAR_ENABLE)) {
- memcpy(color, parent->disableColor, sizeof(vec4_t)); // bk001207 - FIXME: Com_Memcpy
- }
-
- if (item->text) {
- Item_Text_Paint(item);
- if (item->text[0]) {
- // +8 is an offset kludge to properly align owner draw items that have text combined with them
- DC->ownerDrawItem(item->textRect.x + item->textRect.w + 8, item->window.rect.y, item->window.rect.w, item->window.rect.h, 0, item->textaligny, item->window.ownerDraw, item->window.ownerDrawFlags, item->alignment, item->special, item->textscale, color, item->window.background, item->textStyle );
- } else {
- DC->ownerDrawItem(item->textRect.x + item->textRect.w, item->window.rect.y, item->window.rect.w, item->window.rect.h, 0, item->textaligny, item->window.ownerDraw, item->window.ownerDrawFlags, item->alignment, item->special, item->textscale, color, item->window.background, item->textStyle );
- }
- } else {
- DC->ownerDrawItem(item->window.rect.x, item->window.rect.y, item->window.rect.w, item->window.rect.h, item->textalignx, item->textaligny, item->window.ownerDraw, item->window.ownerDrawFlags, item->alignment, item->special, item->textscale, color, item->window.background, item->textStyle );
- }
- }
-}
-
-
-void Item_Paint(itemDef_t *item) {
- vec4_t red;
- menuDef_t *parent = (menuDef_t*)item->parent;
- red[0] = red[3] = 1;
- red[1] = red[2] = 0;
-
- if (item == NULL) {
- return;
- }
-
- if (item->window.flags & WINDOW_ORBITING) {
- if (DC->realTime > item->window.nextTime) {
- float rx, ry, a, c, s, w, h;
-
- item->window.nextTime = DC->realTime + item->window.offsetTime;
- // translate
- w = item->window.rectClient.w / 2;
- h = item->window.rectClient.h / 2;
- rx = item->window.rectClient.x + w - item->window.rectEffects.x;
- ry = item->window.rectClient.y + h - item->window.rectEffects.y;
- a = 3 * M_PI / 180;
- c = cos(a);
- s = sin(a);
- item->window.rectClient.x = (rx * c - ry * s) + item->window.rectEffects.x - w;
- item->window.rectClient.y = (rx * s + ry * c) + item->window.rectEffects.y - h;
- Item_UpdatePosition(item);
-
- }
- }
-
-
- if (item->window.flags & WINDOW_INTRANSITION) {
- if (DC->realTime > item->window.nextTime) {
- int done = 0;
- item->window.nextTime = DC->realTime + item->window.offsetTime;
- // transition the x,y
- if (item->window.rectClient.x == item->window.rectEffects.x) {
- done++;
- } else {
- if (item->window.rectClient.x < item->window.rectEffects.x) {
- item->window.rectClient.x += item->window.rectEffects2.x;
- if (item->window.rectClient.x > item->window.rectEffects.x) {
- item->window.rectClient.x = item->window.rectEffects.x;
- done++;
- }
- } else {
- item->window.rectClient.x -= item->window.rectEffects2.x;
- if (item->window.rectClient.x < item->window.rectEffects.x) {
- item->window.rectClient.x = item->window.rectEffects.x;
- done++;
- }
- }
- }
- if (item->window.rectClient.y == item->window.rectEffects.y) {
- done++;
- } else {
- if (item->window.rectClient.y < item->window.rectEffects.y) {
- item->window.rectClient.y += item->window.rectEffects2.y;
- if (item->window.rectClient.y > item->window.rectEffects.y) {
- item->window.rectClient.y = item->window.rectEffects.y;
- done++;
- }
- } else {
- item->window.rectClient.y -= item->window.rectEffects2.y;
- if (item->window.rectClient.y < item->window.rectEffects.y) {
- item->window.rectClient.y = item->window.rectEffects.y;
- done++;
- }
- }
- }
- if (item->window.rectClient.w == item->window.rectEffects.w) {
- done++;
- } else {
- if (item->window.rectClient.w < item->window.rectEffects.w) {
- item->window.rectClient.w += item->window.rectEffects2.w;
- if (item->window.rectClient.w > item->window.rectEffects.w) {
- item->window.rectClient.w = item->window.rectEffects.w;
- done++;
- }
- } else {
- item->window.rectClient.w -= item->window.rectEffects2.w;
- if (item->window.rectClient.w < item->window.rectEffects.w) {
- item->window.rectClient.w = item->window.rectEffects.w;
- done++;
- }
- }
- }
- if (item->window.rectClient.h == item->window.rectEffects.h) {
- done++;
- } else {
- if (item->window.rectClient.h < item->window.rectEffects.h) {
- item->window.rectClient.h += item->window.rectEffects2.h;
- if (item->window.rectClient.h > item->window.rectEffects.h) {
- item->window.rectClient.h = item->window.rectEffects.h;
- done++;
- }
- } else {
- item->window.rectClient.h -= item->window.rectEffects2.h;
- if (item->window.rectClient.h < item->window.rectEffects.h) {
- item->window.rectClient.h = item->window.rectEffects.h;
- done++;
- }
- }
- }
-
- Item_UpdatePosition(item);
-
- if (done == 4) {
- item->window.flags &= ~WINDOW_INTRANSITION;
- }
-
- }
- }
-
- if (item->window.ownerDrawFlags && DC->ownerDrawVisible) {
- if (!DC->ownerDrawVisible(item->window.ownerDrawFlags)) {
- item->window.flags &= ~WINDOW_VISIBLE;
- } else {
- item->window.flags |= WINDOW_VISIBLE;
- }
- }
-
- if (item->cvarFlags & (CVAR_SHOW | CVAR_HIDE)) {
- if (!Item_EnableShowViaCvar(item, CVAR_SHOW)) {
- return;
- }
- }
-
- if (item->window.flags & WINDOW_TIMEDVISIBLE) {
-
- }
-
- if (!(item->window.flags & WINDOW_VISIBLE)) {
- return;
- }
-
- // paint the rect first..
- Window_Paint(&item->window, parent->fadeAmount , parent->fadeClamp, parent->fadeCycle);
-
- if (debugMode) {
- vec4_t color;
- rectDef_t *r = Item_CorrectedTextRect(item);
- color[1] = color[3] = 1;
- color[0] = color[2] = 0;
- DC->drawRect(r->x, r->y, r->w, r->h, 1, color);
- }
-
- //DC->drawRect(item->window.rect.x, item->window.rect.y, item->window.rect.w, item->window.rect.h, 1, red);
-
- switch (item->type) {
- case ITEM_TYPE_OWNERDRAW:
- Item_OwnerDraw_Paint(item);
- break;
- case ITEM_TYPE_TEXT:
- case ITEM_TYPE_BUTTON:
- Item_Text_Paint(item);
- break;
- case ITEM_TYPE_RADIOBUTTON:
- break;
- case ITEM_TYPE_CHECKBOX:
- break;
- case ITEM_TYPE_EDITFIELD:
- case ITEM_TYPE_SAYFIELD:
- case ITEM_TYPE_NUMERICFIELD:
- Item_TextField_Paint(item);
- break;
- case ITEM_TYPE_COMBO:
- break;
- case ITEM_TYPE_LISTBOX:
- Item_ListBox_Paint(item);
- break;
- //case ITEM_TYPE_IMAGE:
- // Item_Image_Paint(item);
- // break;
- case ITEM_TYPE_MODEL:
- Item_Model_Paint(item);
- break;
- case ITEM_TYPE_YESNO:
- Item_YesNo_Paint(item);
- break;
- case ITEM_TYPE_MULTI:
- Item_Multi_Paint(item);
- break;
- case ITEM_TYPE_BIND:
- Item_Bind_Paint(item);
- break;
- case ITEM_TYPE_SLIDER:
- Item_Slider_Paint(item);
- break;
- default:
- break;
- }
-
-}
-
-void Menu_Init(menuDef_t *menu) {
- memset(menu, 0, sizeof(menuDef_t));
- menu->cursorItem = -1;
- menu->fadeAmount = DC->Assets.fadeAmount;
- menu->fadeClamp = DC->Assets.fadeClamp;
- menu->fadeCycle = DC->Assets.fadeCycle;
- Window_Init(&menu->window);
-}
-
-itemDef_t *Menu_GetFocusedItem(menuDef_t *menu) {
- int i;
- if (menu) {
- for (i = 0; i < menu->itemCount; i++) {
- if (menu->items[i]->window.flags & WINDOW_HASFOCUS) {
- return menu->items[i];
- }
- }
- }
- return NULL;
-}
-
-menuDef_t *Menu_GetFocused( void ) {
- int i;
- for (i = 0; i < menuCount; i++) {
- if (Menus[i].window.flags & WINDOW_HASFOCUS && Menus[i].window.flags & WINDOW_VISIBLE) {
- return &Menus[i];
- }
- }
- return NULL;
-}
-
-void Menu_ScrollFeeder(menuDef_t *menu, int feeder, qboolean down) {
- if (menu) {
- int i;
- for (i = 0; i < menu->itemCount; i++) {
- if (menu->items[i]->special == feeder) {
- Item_ListBox_HandleKey(menu->items[i], (down) ? K_DOWNARROW : K_UPARROW, qtrue, qtrue);
+void Item_Update(itemDef_t *item)
+{
+ if (item == NULL)
return;
- }
- }
- }
+
+ if (Item_IsListBox(item))
+ Item_ListBox_Update(item);
}
+void Item_Paint(itemDef_t *item)
+{
+ vec4_t red;
+ menuDef_t *parent = (menuDef_t *)item->parent;
+ red[0] = red[3] = 1;
+ red[1] = red[2] = 0;
+ if (item == NULL)
+ return;
-void Menu_SetFeederSelection(menuDef_t *menu, int feeder, int index, const char *name) {
- if (menu == NULL) {
- if (name == NULL) {
- menu = Menu_GetFocused();
- } else {
- menu = Menus_FindByName(name);
+ if (item->window.flags & WINDOW_ORBITING)
+ {
+ if (DC->realTime > item->window.nextTime)
+ {
+ float rx, ry, a, c, s, w, h;
+
+ item->window.nextTime = DC->realTime + item->window.offsetTime;
+ // translate
+ w = item->window.rectClient.w / 2;
+ h = item->window.rectClient.h / 2;
+ rx = item->window.rectClient.x + w - item->window.rectEffects.x;
+ ry = item->window.rectClient.y + h - item->window.rectEffects.y;
+ a = 3 * M_PI / 180;
+ c = cos(a);
+ s = sin(a);
+ item->window.rectClient.x = (rx * c - ry * s) + item->window.rectEffects.x - w;
+ item->window.rectClient.y = (rx * s + ry * c) + item->window.rectEffects.y - h;
+ Item_UpdatePosition(item);
+ }
}
- }
- if (menu) {
- int i;
- for (i = 0; i < menu->itemCount; i++) {
- if (menu->items[i]->special == feeder) {
- if (index == 0) {
- listBoxDef_t *listPtr = (listBoxDef_t*)menu->items[i]->typeData;
- listPtr->cursorPos = 0;
- listPtr->startPos = 0;
- }
- menu->items[i]->cursorPos = index;
- DC->feederSelection(menu->items[i]->special, menu->items[i]->cursorPos);
+ if (item->window.flags & WINDOW_INTRANSITION)
+ {
+ if (DC->realTime > item->window.nextTime)
+ {
+ int done = 0;
+ item->window.nextTime = DC->realTime + item->window.offsetTime;
+ // transition the x,y
+
+ if (item->window.rectClient.x == item->window.rectEffects.x)
+ done++;
+ else
+ {
+ if (item->window.rectClient.x < item->window.rectEffects.x)
+ {
+ item->window.rectClient.x += item->window.rectEffects2.x;
+
+ if (item->window.rectClient.x > item->window.rectEffects.x)
+ {
+ item->window.rectClient.x = item->window.rectEffects.x;
+ done++;
+ }
+ }
+ else
+ {
+ item->window.rectClient.x -= item->window.rectEffects2.x;
+
+ if (item->window.rectClient.x < item->window.rectEffects.x)
+ {
+ item->window.rectClient.x = item->window.rectEffects.x;
+ done++;
+ }
+ }
+ }
+
+ if (item->window.rectClient.y == item->window.rectEffects.y)
+ done++;
+ else
+ {
+ if (item->window.rectClient.y < item->window.rectEffects.y)
+ {
+ item->window.rectClient.y += item->window.rectEffects2.y;
+
+ if (item->window.rectClient.y > item->window.rectEffects.y)
+ {
+ item->window.rectClient.y = item->window.rectEffects.y;
+ done++;
+ }
+ }
+ else
+ {
+ item->window.rectClient.y -= item->window.rectEffects2.y;
+
+ if (item->window.rectClient.y < item->window.rectEffects.y)
+ {
+ item->window.rectClient.y = item->window.rectEffects.y;
+ done++;
+ }
+ }
+ }
+
+ if (item->window.rectClient.w == item->window.rectEffects.w)
+ done++;
+ else
+ {
+ if (item->window.rectClient.w < item->window.rectEffects.w)
+ {
+ item->window.rectClient.w += item->window.rectEffects2.w;
+
+ if (item->window.rectClient.w > item->window.rectEffects.w)
+ {
+ item->window.rectClient.w = item->window.rectEffects.w;
+ done++;
+ }
+ }
+ else
+ {
+ item->window.rectClient.w -= item->window.rectEffects2.w;
+
+ if (item->window.rectClient.w < item->window.rectEffects.w)
+ {
+ item->window.rectClient.w = item->window.rectEffects.w;
+ done++;
+ }
+ }
+ }
+
+ if (item->window.rectClient.h == item->window.rectEffects.h)
+ done++;
+ else
+ {
+ if (item->window.rectClient.h < item->window.rectEffects.h)
+ {
+ item->window.rectClient.h += item->window.rectEffects2.h;
+
+ if (item->window.rectClient.h > item->window.rectEffects.h)
+ {
+ item->window.rectClient.h = item->window.rectEffects.h;
+ done++;
+ }
+ }
+ else
+ {
+ item->window.rectClient.h -= item->window.rectEffects2.h;
+
+ if (item->window.rectClient.h < item->window.rectEffects.h)
+ {
+ item->window.rectClient.h = item->window.rectEffects.h;
+ done++;
+ }
+ }
+ }
+
+ Item_UpdatePosition(item);
+
+ if (done == 4)
+ item->window.flags &= ~WINDOW_INTRANSITION;
+ }
+ }
+
+ if (item->window.ownerDrawFlags && DC->ownerDrawVisible)
+ {
+ if (!DC->ownerDrawVisible(item->window.ownerDrawFlags))
+ item->window.flags &= ~WINDOW_VISIBLE;
+ else
+ item->window.flags |= WINDOW_VISIBLE;
+ }
+
+ if (item->cvarFlags & (CVAR_SHOW | CVAR_HIDE))
+ {
+ if (!Item_EnableShowViaCvar(item, CVAR_SHOW))
+ return;
+ }
+
+ if (item->window.flags & WINDOW_TIMEDVISIBLE)
+ {
+ }
+
+ if (!(item->window.flags & WINDOW_VISIBLE))
return;
- }
+
+ Window_Paint(&item->window, parent->fadeAmount, parent->fadeClamp, parent->fadeCycle);
+
+ if (DC->getCVarValue("ui_developer"))
+ {
+ vec4_t color;
+ rectDef_t *r = Item_CorrectedTextRect(item);
+ color[1] = color[3] = 1;
+ color[0] = color[2] = 0;
+ DC->drawRect(r->x, r->y, r->w, r->h, 1, color);
}
- }
+
+ switch (item->type)
+ {
+ case ITEM_TYPE_OWNERDRAW:
+ Item_OwnerDraw_Paint(item);
+ break;
+
+ case ITEM_TYPE_TEXT:
+ case ITEM_TYPE_BUTTON:
+ Item_Text_Paint(item);
+ break;
+
+ case ITEM_TYPE_RADIOBUTTON:
+ break;
+
+ case ITEM_TYPE_CHECKBOX:
+ break;
+
+ case ITEM_TYPE_CYCLE:
+ Item_Cycle_Paint(item);
+ break;
+
+ case ITEM_TYPE_LISTBOX:
+ Item_ListBox_Paint(item);
+ break;
+
+ case ITEM_TYPE_COMBOBOX:
+ Item_ComboBox_Paint(item);
+ break;
+
+ case ITEM_TYPE_MODEL:
+ Item_Model_Paint(item);
+ break;
+
+ case ITEM_TYPE_YESNO:
+ Item_YesNo_Paint(item);
+ break;
+
+ case ITEM_TYPE_MULTI:
+ Item_Multi_Paint(item);
+ break;
+
+ case ITEM_TYPE_BIND:
+ Item_Bind_Paint(item);
+ break;
+
+ case ITEM_TYPE_SLIDER:
+ Item_Slider_Paint(item);
+ break;
+
+ default:
+ if (Item_IsEditField(item))
+ Item_TextField_Paint(item);
+
+ break;
+ }
+
+ Border_Paint(&item->window);
+}
+
+void Menu_Init(menuDef_t *menu)
+{
+ memset(menu, 0, sizeof(menuDef_t));
+ menu->cursorItem = -1;
+ menu->fadeAmount = DC->Assets.fadeAmount;
+ menu->fadeClamp = DC->Assets.fadeClamp;
+ menu->fadeCycle = DC->Assets.fadeCycle;
+ Window_Init(&menu->window);
+ menu->window.aspectBias = ALIGN_CENTER;
}
-qboolean Menus_AnyFullScreenVisible( void ) {
- int i;
- for (i = 0; i < menuCount; i++) {
- if (Menus[i].window.flags & WINDOW_VISIBLE && Menus[i].fullScreen) {
- return qtrue;
+itemDef_t *Menu_GetFocusedItem(menuDef_t *menu)
+{
+ int i;
+
+ if (menu)
+ {
+ for (i = 0; i < menu->itemCount; i++)
+ {
+ if (menu->items[i]->window.flags & WINDOW_HASFOCUS)
+ return menu->items[i];
+ }
}
- }
- return qfalse;
+
+ return NULL;
}
-menuDef_t *Menus_ActivateByName(const char *p) {
- int i, j;
- menuDef_t *m = NULL;
- menuDef_t *focus = Menu_GetFocused();
+menuDef_t *Menu_GetFocused(void)
+{
+ int i;
- for (i = 0; i < menuCount; i++) {
- if (Q_stricmp(Menus[i].window.name, p) == 0) {
- m = &Menus[i];
- Menus_Activate(m);
- Menu_HandleMouseMove( m, DC->cursorx, DC->cursory ); //TA: force the item under the cursor to focus
+ for (i = 0; i < menuCount; i++)
+ {
+ if (Menus[i].window.flags & WINDOW_HASFOCUS && Menus[i].window.flags & WINDOW_VISIBLE)
+ return &Menus[i];
+ }
- for( j = 0; j < m->itemCount; j++ ) //TA: reset selection in listboxes when opened
- {
- if( m->items[ j ]->type == ITEM_TYPE_LISTBOX )
+ return NULL;
+}
+
+void Menu_ScrollFeeder(menuDef_t *menu, int feeder, qboolean down)
+{
+ if (menu)
+ {
+ int i;
+
+ for (i = 0; i < menu->itemCount; i++)
{
- listBoxDef_t *listPtr = (listBoxDef_t*)m->items[ j ]->typeData;
- m->items[ j ]->cursorPos = 0;
- listPtr->startPos = 0;
- DC->feederSelection( m->items[ j ]->special, 0 );
+ itemDef_t *item = menu->items[i];
+
+ if (item->feederID == feeder)
+ {
+ qboolean cast = Item_ComboBox_MaybeCastToListBox(item);
+ Item_ListBox_HandleKey(item, down ? K_DOWNARROW : K_UPARROW, qtrue, qtrue);
+ Item_ComboBox_MaybeUnCastFromListBox(item, cast);
+
+ return;
+ }
}
- }
+ }
+}
- if (openMenuCount < MAX_OPEN_MENUS && focus != NULL) {
- menuStack[openMenuCount++] = focus;
- }
- } else {
- Menus[i].window.flags &= ~WINDOW_HASFOCUS;
+void Menu_SetFeederSelection(menuDef_t *menu, int feeder, int index, const char *name)
+{
+ if (menu == NULL)
+ {
+ if (name == NULL)
+ menu = Menu_GetFocused();
+ else
+ menu = Menus_FindByName(name);
+ }
+
+ if (menu)
+ {
+ int i;
+
+ for (i = 0; i < menu->itemCount; i++)
+ {
+ if (menu->items[i]->feederID == feeder)
+ {
+ if (Item_IsListBox(menu->items[i]) && index == 0)
+ {
+ menu->items[i]->typeData.list->cursorPos = 0;
+ Item_ListBox_SetStartPos(menu->items[i], 0);
+ }
+
+ menu->items[i]->cursorPos = index;
+ DC->feederSelection(menu->items[i]->feederID, menu->items[i]->cursorPos);
+ return;
+ }
+ }
}
- }
- Display_CloseCinematics();
- return m;
}
+qboolean Menus_AnyFullScreenVisible(void)
+{
+ int i;
+
+ for (i = 0; i < menuCount; i++)
+ {
+ if (Menus[i].window.flags & WINDOW_VISIBLE && Menus[i].fullScreen)
+ return qtrue;
+ }
-void Item_Init(itemDef_t *item) {
- memset(item, 0, sizeof(itemDef_t));
- item->textscale = 0.55f;
- Window_Init(&item->window);
+ return qfalse;
}
-void Menu_HandleMouseMove(menuDef_t *menu, float x, float y) {
- int i, pass;
- qboolean focusSet = qfalse;
+menuDef_t *Menus_ActivateByName(const char *p)
+{
+ int i;
+ menuDef_t *m = NULL;
- itemDef_t *overItem;
- if (menu == NULL) {
- return;
- }
+ // Activate one menu
- if (!(menu->window.flags & (WINDOW_VISIBLE | WINDOW_FORCED))) {
- return;
- }
+ for (i = 0; i < menuCount; i++)
+ {
+ if (Q_stricmp(Menus[i].window.name, p) == 0)
+ {
+ m = &Menus[i];
+ Menus_Activate(m);
+ break;
+ }
+ }
- if (itemCapture) {
- //Item_MouseMove(itemCapture, x, y);
- return;
- }
+ // Defocus the others
+ for (i = 0; i < menuCount; i++)
+ {
+ if (Q_stricmp(Menus[i].window.name, p) != 0)
+ Menus[i].window.flags &= ~WINDOW_HASFOCUS;
+ }
- if (g_waitingForKey || g_editingField) {
- return;
- }
+ return m;
+}
- // FIXME: this is the whole issue of focus vs. mouse over..
- // need a better overall solution as i don't like going through everything twice
- for (pass = 0; pass < 2; pass++) {
- for (i = 0; i < menu->itemCount; i++) {
- // turn off focus each item
- // menu->items[i].window.flags &= ~WINDOW_HASFOCUS;
+menuDef_t *Menus_ReplaceActiveByName(const char *p)
+{
+ int i;
+ menuDef_t *m = NULL;
- if (!(menu->items[i]->window.flags & (WINDOW_VISIBLE | WINDOW_FORCED))) {
- continue;
- }
+ // Activate one menu
- // items can be enabled and disabled based on cvars
- if (menu->items[i]->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(menu->items[i], CVAR_ENABLE)) {
- continue;
- }
+ for (i = 0; i < menuCount; i++)
+ {
+ if (Q_stricmp(Menus[i].window.name, p) == 0)
+ {
+ m = &Menus[i];
+ if (!Menus_ReplaceActive(m))
+ return NULL;
+ break;
+ }
+ }
+ return m;
+}
- if (menu->items[i]->cvarFlags & (CVAR_SHOW | CVAR_HIDE) && !Item_EnableShowViaCvar(menu->items[i], CVAR_SHOW)) {
- continue;
- }
+void Item_Init(itemDef_t *item)
+{
+ memset(item, 0, sizeof(itemDef_t));
+ item->textscale = 0.55f;
+ Window_Init(&item->window);
+ item->window.aspectBias = ASPECT_NONE;
+}
+static qboolean Item_HandleMouseMove(itemDef_t *item, float x, float y, int pass, qboolean focusSet)
+{
+ if (Rect_ContainsPoint(&item->window.rect, x, y))
+ {
+ if (pass == 1)
+ {
+ if (item->type == ITEM_TYPE_TEXT && item->text)
+ {
+ if (!Rect_ContainsPoint(Item_CorrectedTextRect(item), x, y))
+ return qtrue;
+ }
+ // if we are over an item
+ if (IsVisible(item->window.flags))
+ {
+ // different one
+ Item_MouseEnter(item, x, y);
- if (Rect_ContainsPoint(&menu->items[i]->window.rect, x, y)) {
- if (pass == 1) {
- overItem = menu->items[i];
- if (overItem->type == ITEM_TYPE_TEXT && overItem->text) {
- if (!Rect_ContainsPoint(Item_CorrectedTextRect(overItem), x, y)) {
- continue;
+ if (!focusSet)
+ focusSet = Item_SetFocus(item, x, y);
}
- }
- // if we are over an item
- if (IsVisible(overItem->window.flags)) {
- // different one
- Item_MouseEnter(overItem, x, y);
- // Item_SetMouseOver(overItem, qtrue);
-
- // if item is not a decoration see if it can take focus
- if (!focusSet) {
- focusSet = Item_SetFocus(overItem, x, y);
+ }
+
+ return qtrue;
+ }
+
+ return qfalse;
+}
+
+void Menu_HandleMouseMove(menuDef_t *menu, float x, float y)
+{
+ int i, pass;
+ qboolean focusSet = qfalse;
+ qboolean result;
+ qboolean cast;
+
+ if (menu == NULL)
+ return;
+
+ if (!(menu->window.flags & (WINDOW_VISIBLE | WINDOW_FORCED)))
+ return;
+
+ if (itemCapture)
+ {
+ // Item_MouseMove(itemCapture, x, y);
+ return;
+ }
+
+ if (g_waitingForKey || g_editingField)
+ return;
+
+ if (g_comboBoxItem != NULL)
+ {
+ Item_SetFocus(g_comboBoxItem, x, y);
+ focusSet = qtrue;
+ }
+
+ // FIXME: this is the whole issue of focus vs. mouse over..
+ // need a better overall solution as i don't like going through everything twice
+ for (pass = 0; pass < 2; pass++)
+ {
+ for (i = 0; i < menu->itemCount; i++)
+ {
+ itemDef_t *item = menu->items[i];
+
+ // turn off focus each item
+ // menu->items[i].window.flags &= ~WINDOW_HASFOCUS;
+
+ if (!(item->window.flags & (WINDOW_VISIBLE | WINDOW_FORCED)))
+ continue;
+
+ // items can be enabled and disabled based on cvars
+ if (item->cvarFlags & (CVAR_ENABLE | CVAR_DISABLE) && !Item_EnableShowViaCvar(item, CVAR_ENABLE))
+ continue;
+
+ if (item->cvarFlags & (CVAR_SHOW | CVAR_HIDE) && !Item_EnableShowViaCvar(item, CVAR_SHOW))
+ continue;
+
+ cast = Item_ComboBox_MaybeCastToListBox(item);
+ result = Item_HandleMouseMove(item, x, y, pass, focusSet);
+ Item_ComboBox_MaybeUnCastFromListBox(item, cast);
+
+ if (!result && item->window.flags & WINDOW_MOUSEOVER)
+ {
+ Item_MouseLeave(item);
+ Item_SetMouseOver(item, qfalse);
}
- }
}
- } else if (menu->items[i]->window.flags & WINDOW_MOUSEOVER) {
- Item_MouseLeave(menu->items[i]);
- Item_SetMouseOver(menu->items[i], qfalse);
- }
}
- }
+}
+void Menu_Update(menuDef_t *menu)
+{
+ int i;
+
+ if (menu == NULL)
+ return;
+
+ for (i = 0; i < menu->itemCount; i++)
+ Item_Update(menu->items[i]);
}
-void Menu_Paint(menuDef_t *menu, qboolean forcePaint) {
- int i;
+void Menu_Paint(menuDef_t *menu, qboolean forcePaint)
+{
+ int i;
- if (menu == NULL) {
- return;
- }
+ if (menu == NULL)
+ return;
- if (!(menu->window.flags & WINDOW_VISIBLE) && !forcePaint) {
- return;
- }
+ if (!(menu->window.flags & WINDOW_VISIBLE) && !forcePaint)
+ return;
- if (menu->window.ownerDrawFlags && DC->ownerDrawVisible && !DC->ownerDrawVisible(menu->window.ownerDrawFlags)) {
- return;
- }
+ if (menu->window.ownerDrawFlags && DC->ownerDrawVisible && !DC->ownerDrawVisible(menu->window.ownerDrawFlags))
+ return;
- if (forcePaint) {
- menu->window.flags |= WINDOW_FORCED;
- }
+ if (forcePaint)
+ menu->window.flags |= WINDOW_FORCED;
- // draw the background if necessary
- if (menu->fullScreen) {
- // implies a background shader
- // FIXME: make sure we have a default shader if fullscreen is set with no background
- DC->drawHandlePic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, menu->window.background );
- } else if (menu->window.background) {
- // this allows a background shader without being full screen
- //UI_DrawHandlePic(menu->window.rect.x, menu->window.rect.y, menu->window.rect.w, menu->window.rect.h, menu->backgroundShader);
- }
+ // draw the background if necessary
+ if (menu->fullScreen)
+ {
+ // implies a background shader
+ // FIXME: make sure we have a default shader if fullscreen is set with no background
+ DC->drawHandlePic(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, menu->window.background);
+ }
- // paint the background and or border
- Window_Paint(&menu->window, menu->fadeAmount, menu->fadeClamp, menu->fadeCycle );
+ // paint the background and or border
+ Window_Paint(&menu->window, menu->fadeAmount, menu->fadeClamp, menu->fadeCycle);
- for (i = 0; i < menu->itemCount; i++) {
- Item_Paint(menu->items[i]);
- }
+ Border_Paint(&menu->window);
- if (debugMode) {
- vec4_t color;
- color[0] = color[2] = color[3] = 1;
- color[1] = 0;
- DC->drawRect(menu->window.rect.x, menu->window.rect.y, menu->window.rect.w, menu->window.rect.h, 1, color);
- }
+ for (i = 0; i < menu->itemCount; i++)
+ Item_Paint(menu->items[i]);
+
+ if (DC->getCVarValue("ui_developer"))
+ {
+ vec4_t color;
+ color[0] = color[2] = color[3] = 1;
+ color[1] = 0;
+ DC->drawRect(menu->window.rect.x, menu->window.rect.y, menu->window.rect.w, menu->window.rect.h, 1, color);
+ }
}
-/*
-===============
-Item_ValidateTypeData
-===============
-*/
-void Item_ValidateTypeData(itemDef_t *item) {
- if (item->typeData) {
- return;
- }
-
- if (item->type == ITEM_TYPE_LISTBOX) {
- item->typeData = UI_Alloc(sizeof(listBoxDef_t));
- memset(item->typeData, 0, sizeof(listBoxDef_t));
- } else if (item->type == ITEM_TYPE_EDITFIELD || item->type == ITEM_TYPE_SAYFIELD || item->type == ITEM_TYPE_NUMERICFIELD || item->type == ITEM_TYPE_YESNO || item->type == ITEM_TYPE_BIND || item->type == ITEM_TYPE_SLIDER || item->type == ITEM_TYPE_TEXT) {
- item->typeData = UI_Alloc(sizeof(editFieldDef_t));
- memset(item->typeData, 0, sizeof(editFieldDef_t));
- if (item->type == ITEM_TYPE_EDITFIELD || item->type == ITEM_TYPE_SAYFIELD) {
- if (!((editFieldDef_t *) item->typeData)->maxPaintChars) {
- ((editFieldDef_t *) item->typeData)->maxPaintChars = MAX_EDITFIELD;
- }
- }
- } else if (item->type == ITEM_TYPE_MULTI) {
- item->typeData = UI_Alloc(sizeof(multiDef_t));
- } else if (item->type == ITEM_TYPE_MODEL) {
- item->typeData = UI_Alloc(sizeof(modelDef_t));
- }
+ /*
+ ===============
+ Keyword Hash
+ ===============
+ */
+
+#define KEYWORDHASH_SIZE 512
+
+typedef struct keywordHash_s {
+ char *keyword;
+ qboolean (*func)(itemDef_t *item, int handle);
+ int param;
+ struct keywordHash_s *next;
+} keywordHash_t;
+
+int KeywordHash_Key(char *keyword)
+{
+ int register hash, i;
+
+ hash = 0;
+
+ for (i = 0; keyword[i] != '\0'; i++)
+ {
+ if (keyword[i] >= 'A' && keyword[i] <= 'Z')
+ hash += (keyword[i] + ('a' - 'A')) * (119 + i);
+ else
+ hash += keyword[i] * (119 + i);
+ }
+
+ hash = (hash ^ (hash >> 10) ^ (hash >> 20)) & (KEYWORDHASH_SIZE - 1);
+ return hash;
+}
+
+void KeywordHash_Add(keywordHash_t *table[], keywordHash_t *key)
+{
+ int hash;
+
+ hash = KeywordHash_Key(key->keyword);
+ /*
+ if(table[hash]) int collision = qtrue;
+ */
+ key->next = table[hash];
+ table[hash] = key;
+}
+
+keywordHash_t *KeywordHash_Find(keywordHash_t *table[], char *keyword)
+{
+ keywordHash_t *key;
+ int hash;
+
+ hash = KeywordHash_Key(keyword);
+
+ for (key = table[hash]; key; key = key->next)
+ {
+ if (!Q_stricmp(key->keyword, keyword))
+ return key;
+ }
+
+ return NULL;
}
/*
===============
-Keyword Hash
+Item_DataType
+
+Give a numeric representation of which typeData union element this item uses
===============
*/
+itemDataType_t Item_DataType(itemDef_t *item)
+{
+ switch (item->type)
+ {
+ default:
+ case ITEM_TYPE_NONE:
+ return TYPE_NONE;
-#define KEYWORDHASH_SIZE 512
+ case ITEM_TYPE_LISTBOX:
+ case ITEM_TYPE_COMBOBOX:
+ return TYPE_LIST;
-typedef struct keywordHash_s
-{
- char *keyword;
- qboolean (*func)(itemDef_t *item, int handle);
- struct keywordHash_s *next;
-} keywordHash_t;
+ case ITEM_TYPE_CYCLE:
+ return TYPE_COMBO;
-int KeywordHash_Key(char *keyword) {
- int register hash, i;
+ case ITEM_TYPE_EDITFIELD:
+ case ITEM_TYPE_NUMERICFIELD:
+ case ITEM_TYPE_SAYFIELD:
+ case ITEM_TYPE_YESNO:
+ case ITEM_TYPE_BIND:
+ case ITEM_TYPE_SLIDER:
+ case ITEM_TYPE_TEXT:
+ return TYPE_EDIT;
- hash = 0;
- for (i = 0; keyword[i] != '\0'; i++) {
- if (keyword[i] >= 'A' && keyword[i] <= 'Z')
- hash += (keyword[i] + ('a' - 'A')) * (119 + i);
- else
- hash += keyword[i] * (119 + i);
- }
- hash = (hash ^ (hash >> 10) ^ (hash >> 20)) & (KEYWORDHASH_SIZE-1);
- return hash;
-}
+ case ITEM_TYPE_MULTI:
+ return TYPE_MULTI;
-void KeywordHash_Add(keywordHash_t *table[], keywordHash_t *key) {
- int hash;
+ case ITEM_TYPE_MODEL:
+ return TYPE_MODEL;
+ }
+}
- hash = KeywordHash_Key(key->keyword);
/*
- if (table[hash]) {
- int collision = qtrue;
- }
+===============
+Item_IsEditField
+===============
*/
- key->next = table[hash];
- table[hash] = key;
+static ID_INLINE qboolean Item_IsEditField(itemDef_t *item)
+{
+ switch (item->type)
+ {
+ case ITEM_TYPE_EDITFIELD:
+ case ITEM_TYPE_NUMERICFIELD:
+ case ITEM_TYPE_SAYFIELD:
+ return qtrue;
+
+ default:
+ return qfalse;
+ }
}
-keywordHash_t *KeywordHash_Find(keywordHash_t *table[], char *keyword)
+/*
+===============
+Item_IsListBox
+===============
+*/
+static ID_INLINE qboolean Item_IsListBox(itemDef_t *item)
{
- keywordHash_t *key;
- int hash;
+ switch (item->type)
+ {
+ case ITEM_TYPE_LISTBOX:
+ case ITEM_TYPE_COMBOBOX:
+ return qtrue;
- hash = KeywordHash_Key(keyword);
- for (key = table[hash]; key; key = key->next) {
- if (!Q_stricmp(key->keyword, keyword))
- return key;
- }
- return NULL;
+ default:
+ return qfalse;
+ }
}
/*
@@ -4681,787 +6206,827 @@ Item Keyword Parse functions
*/
// name <string>
-qboolean ItemParse_name( itemDef_t *item, int handle ) {
- if (!PC_String_Parse(handle, &item->window.name)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_name(itemDef_t *item, int handle)
+{
+ if (!PC_String_Parse(handle, &item->window.name))
+ return qfalse;
+
+ return qtrue;
}
// name <string>
-qboolean ItemParse_focusSound( itemDef_t *item, int handle ) {
- const char *temp;
- if (!PC_String_Parse(handle, &temp)) {
- return qfalse;
- }
- item->focusSound = DC->registerSound(temp, qfalse);
- return qtrue;
-}
+qboolean ItemParse_focusSound(itemDef_t *item, int handle)
+{
+ const char *temp;
+ if (!PC_String_Parse(handle, &temp))
+ return qfalse;
+
+ item->focusSound = DC->registerSound(temp, qfalse);
+ return qtrue;
+}
// text <string>
-qboolean ItemParse_text( itemDef_t *item, int handle ) {
- if (!PC_String_Parse(handle, &item->text)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_text(itemDef_t *item, int handle)
+{
+ if (!PC_String_Parse(handle, &item->text))
+ return qfalse;
+
+ return qtrue;
}
// group <string>
-qboolean ItemParse_group( itemDef_t *item, int handle ) {
- if (!PC_String_Parse(handle, &item->window.group)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_group(itemDef_t *item, int handle)
+{
+ if (!PC_String_Parse(handle, &item->window.group))
+ return qfalse;
+
+ return qtrue;
}
// asset_model <string>
-qboolean ItemParse_asset_model( itemDef_t *item, int handle ) {
- const char *temp;
- modelDef_t *modelPtr;
- Item_ValidateTypeData(item);
- modelPtr = (modelDef_t*)item->typeData;
+qboolean ItemParse_asset_model(itemDef_t *item, int handle)
+{
+ const char *temp;
- if (!PC_String_Parse(handle, &temp)) {
- return qfalse;
- }
- item->asset = DC->registerModel(temp);
- modelPtr->angle = rand() % 360;
- return qtrue;
+ if (!PC_String_Parse(handle, &temp))
+ return qfalse;
+
+ item->asset = DC->registerModel(temp);
+ item->typeData.model->angle = rand() % 360;
+ return qtrue;
}
// asset_shader <string>
-qboolean ItemParse_asset_shader( itemDef_t *item, int handle ) {
- const char *temp;
+qboolean ItemParse_asset_shader(itemDef_t *item, int handle)
+{
+ const char *temp;
- if (!PC_String_Parse(handle, &temp)) {
- return qfalse;
- }
- item->asset = DC->registerShaderNoMip(temp);
- return qtrue;
+ if (!PC_String_Parse(handle, &temp))
+ return qfalse;
+
+ item->asset = DC->registerShaderNoMip(temp);
+ return qtrue;
}
// model_origin <number> <number> <number>
-qboolean ItemParse_model_origin( itemDef_t *item, int handle ) {
- modelDef_t *modelPtr;
- Item_ValidateTypeData(item);
- modelPtr = (modelDef_t*)item->typeData;
-
- if (PC_Float_Parse(handle, &modelPtr->origin[0])) {
- if (PC_Float_Parse(handle, &modelPtr->origin[1])) {
- if (PC_Float_Parse(handle, &modelPtr->origin[2])) {
- return qtrue;
- }
- }
- }
- return qfalse;
+qboolean ItemParse_model_origin(itemDef_t *item, int handle)
+{
+ return (PC_Float_Parse(handle, &item->typeData.model->origin[0]) &&
+ PC_Float_Parse(handle, &item->typeData.model->origin[1]) &&
+ PC_Float_Parse(handle, &item->typeData.model->origin[2]));
}
// model_fovx <number>
-qboolean ItemParse_model_fovx( itemDef_t *item, int handle ) {
- modelDef_t *modelPtr;
- Item_ValidateTypeData(item);
- modelPtr = (modelDef_t*)item->typeData;
-
- if (!PC_Float_Parse(handle, &modelPtr->fov_x)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_model_fovx(itemDef_t *item, int handle)
+{
+ return PC_Float_Parse(handle, &item->typeData.model->fov_x);
}
// model_fovy <number>
-qboolean ItemParse_model_fovy( itemDef_t *item, int handle ) {
- modelDef_t *modelPtr;
- Item_ValidateTypeData(item);
- modelPtr = (modelDef_t*)item->typeData;
-
- if (!PC_Float_Parse(handle, &modelPtr->fov_y)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_model_fovy(itemDef_t *item, int handle)
+{
+ return PC_Float_Parse(handle, &item->typeData.model->fov_y);
}
// model_rotation <integer>
-qboolean ItemParse_model_rotation( itemDef_t *item, int handle ) {
- modelDef_t *modelPtr;
- Item_ValidateTypeData(item);
- modelPtr = (modelDef_t*)item->typeData;
-
- if (!PC_Int_Parse(handle, &modelPtr->rotationSpeed)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_model_rotation(itemDef_t *item, int handle)
+{
+ return PC_Int_Parse(handle, &item->typeData.model->rotationSpeed);
}
// model_angle <integer>
-qboolean ItemParse_model_angle( itemDef_t *item, int handle ) {
- modelDef_t *modelPtr;
- Item_ValidateTypeData(item);
- modelPtr = (modelDef_t*)item->typeData;
-
- if (!PC_Int_Parse(handle, &modelPtr->angle)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_model_angle(itemDef_t *item, int handle)
+{
+ return PC_Int_Parse(handle, &item->typeData.model->angle);
}
// rect <rectangle>
-qboolean ItemParse_rect( itemDef_t *item, int handle ) {
- if (!PC_Rect_Parse(handle, &item->window.rectClient)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_rect(itemDef_t *item, int handle)
+{
+ if (!PC_Rect_Parse(handle, &item->window.rectClient))
+ return qfalse;
+
+ return qtrue;
+}
+
+// aspectBias <bias>
+qboolean ItemParse_aspectBias(itemDef_t *item, int handle)
+{
+ if (!PC_Int_Parse(handle, &item->window.aspectBias))
+ return qfalse;
+
+ return qtrue;
}
// style <integer>
-qboolean ItemParse_style( itemDef_t *item, int handle ) {
- if (!PC_Int_Parse(handle, &item->window.style)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_style(itemDef_t *item, int handle)
+{
+ if (!PC_Int_Parse(handle, &item->window.style))
+ return qfalse;
+
+ return qtrue;
}
// decoration
-qboolean ItemParse_decoration( itemDef_t *item, int handle ) {
- item->window.flags |= WINDOW_DECORATION;
- return qtrue;
+qboolean ItemParse_decoration(itemDef_t *item, int handle)
+{
+ (void)handle;
+
+ item->window.flags |= WINDOW_DECORATION;
+ return qtrue;
}
// notselectable
-qboolean ItemParse_notselectable( itemDef_t *item, int handle ) {
- listBoxDef_t *listPtr;
- Item_ValidateTypeData(item);
- listPtr = (listBoxDef_t*)item->typeData;
- if (item->type == ITEM_TYPE_LISTBOX && listPtr) {
- listPtr->notselectable = qtrue;
- }
- return qtrue;
+qboolean ItemParse_notselectable(itemDef_t *item, int handle)
+{
+ (void)handle;
+
+ item->typeData.list->notselectable = qtrue;
+ return qtrue;
}
-// manually wrapped
-qboolean ItemParse_wrapped( itemDef_t *item, int handle ) {
- item->window.flags |= WINDOW_WRAPPED;
- return qtrue;
+// noscrollbar
+qboolean ItemParse_noscrollbar(itemDef_t *item, int handle)
+{
+ (void)handle;
+
+ item->typeData.list->noscrollbar = qtrue;
+ return qtrue;
}
-// auto wrapped
-qboolean ItemParse_autowrapped( itemDef_t *item, int handle ) {
- item->window.flags |= WINDOW_AUTOWRAPPED;
- return qtrue;
+// resetonfeederchange
+qboolean ItemParse_resetonfeederchange(itemDef_t *item, int handle)
+{
+ (void)handle;
+
+ item->typeData.list->resetonfeederchange = qtrue;
+ return qtrue;
}
+// auto wrapped
+qboolean ItemParse_wrapped(itemDef_t *item, int handle)
+{
+ (void)handle;
-// horizontalscroll
-qboolean ItemParse_horizontalscroll( itemDef_t *item, int handle ) {
- item->window.flags |= WINDOW_HORIZONTAL;
- return qtrue;
+ item->window.flags |= WINDOW_WRAPPED;
+ return qtrue;
}
// type <integer>
-qboolean ItemParse_type( itemDef_t *item, int handle ) {
- if (!PC_Int_Parse(handle, &item->type)) {
- return qfalse;
- }
- Item_ValidateTypeData(item);
- return qtrue;
+qboolean ItemParse_type(itemDef_t *item, int handle)
+{
+ if (item->type != ITEM_TYPE_NONE)
+ {
+ PC_SourceError(handle, "item already has a type");
+ return qfalse;
+ }
+
+ if (!PC_Int_Parse(handle, &item->type))
+ return qfalse;
+
+ if (item->type == ITEM_TYPE_NONE)
+ {
+ PC_SourceError(handle, "type must not be none");
+ return qfalse;
+ }
+
+ // allocate the relevant type data
+ switch (item->type)
+ {
+ case ITEM_TYPE_LISTBOX:
+ case ITEM_TYPE_COMBOBOX:
+ item->typeData.list = UI_Alloc(sizeof(listBoxDef_t));
+ memset(item->typeData.list, 0, sizeof(listBoxDef_t));
+ break;
+
+ case ITEM_TYPE_CYCLE:
+ item->typeData.cycle = UI_Alloc(sizeof(cycleDef_t));
+ memset(item->typeData.cycle, 0, sizeof(cycleDef_t));
+ break;
+
+ case ITEM_TYPE_EDITFIELD:
+ case ITEM_TYPE_SAYFIELD:
+ case ITEM_TYPE_NUMERICFIELD:
+ case ITEM_TYPE_YESNO:
+ case ITEM_TYPE_BIND:
+ case ITEM_TYPE_SLIDER:
+ case ITEM_TYPE_TEXT:
+ item->typeData.edit = UI_Alloc(sizeof(editFieldDef_t));
+ memset(item->typeData.edit, 0, sizeof(editFieldDef_t));
+
+ if (item->type == ITEM_TYPE_EDITFIELD || item->type == ITEM_TYPE_SAYFIELD)
+ item->typeData.edit->maxPaintChars = MAX_EDITFIELD;
+ break;
+
+ case ITEM_TYPE_MULTI:
+ item->typeData.multi = UI_Alloc(sizeof(multiDef_t));
+ memset(item->typeData.multi, 0, sizeof(multiDef_t));
+ break;
+
+ case ITEM_TYPE_MODEL:
+ item->typeData.model = UI_Alloc(sizeof(modelDef_t));
+ memset(item->typeData.model, 0, sizeof(modelDef_t));
+ break;
+
+ default:
+ break;
+ }
+
+ return qtrue;
}
// elementwidth, used for listbox image elements
-// uses textalignx for storage
-qboolean ItemParse_elementwidth( itemDef_t *item, int handle ) {
- listBoxDef_t *listPtr;
-
- Item_ValidateTypeData(item);
- listPtr = (listBoxDef_t*)item->typeData;
- if (!PC_Float_Parse(handle, &listPtr->elementWidth)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_elementwidth(itemDef_t *item, int handle)
+{
+ return PC_Float_Parse(handle, &item->typeData.list->elementWidth);
}
// elementheight, used for listbox image elements
-// uses textaligny for storage
-qboolean ItemParse_elementheight( itemDef_t *item, int handle ) {
- listBoxDef_t *listPtr;
+qboolean ItemParse_elementheight(itemDef_t *item, int handle)
+{
+ return PC_Float_Parse(handle, &item->typeData.list->elementHeight);
+}
- Item_ValidateTypeData(item);
- listPtr = (listBoxDef_t*)item->typeData;
- if (!PC_Float_Parse(handle, &listPtr->elementHeight)) {
- return qfalse;
- }
- return qtrue;
+// dropitems, number of items to drop from a combobox
+qboolean ItemParse_dropitems(itemDef_t *item, int handle)
+{
+ return PC_Int_Parse(handle, &item->typeData.list->dropItems);
}
-// feeder <float>
-qboolean ItemParse_feeder( itemDef_t *item, int handle ) {
- if (!PC_Float_Parse(handle, &item->special)) {
- return qfalse;
- }
- return qtrue;
+// feeder <int>
+qboolean ItemParse_feeder(itemDef_t *item, int handle)
+{
+ if (!PC_Int_Parse(handle, &item->feederID))
+ return qfalse;
+
+ return qtrue;
}
// elementtype, used to specify what type of elements a listbox contains
// uses textstyle for storage
-qboolean ItemParse_elementtype( itemDef_t *item, int handle ) {
- listBoxDef_t *listPtr;
-
- Item_ValidateTypeData(item);
- if (!item->typeData)
- return qfalse;
- listPtr = (listBoxDef_t*)item->typeData;
- if (!PC_Int_Parse(handle, &listPtr->elementStyle)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_elementtype(itemDef_t *item, int handle)
+{
+ return PC_Int_Parse(handle, &item->typeData.list->elementStyle);
}
// columns sets a number of columns and an x pos and width per..
-qboolean ItemParse_columns( itemDef_t *item, int handle ) {
- int num, i;
- listBoxDef_t *listPtr;
+qboolean ItemParse_columns(itemDef_t *item, int handle)
+{
+ int i;
- Item_ValidateTypeData(item);
- if (!item->typeData)
- return qfalse;
- listPtr = (listBoxDef_t*)item->typeData;
- if (PC_Int_Parse(handle, &num)) {
- if (num > MAX_LB_COLUMNS) {
- num = MAX_LB_COLUMNS;
- }
- listPtr->numColumns = num;
- for (i = 0; i < num; i++) {
- int pos, width, maxChars, align;
-
- if( PC_Int_Parse( handle, &pos ) &&
- PC_Int_Parse( handle, &width ) &&
- PC_Int_Parse( handle, &maxChars ) &&
- PC_Int_Parse( handle, &align ) )
- {
- listPtr->columnInfo[i].pos = pos;
- listPtr->columnInfo[i].width = width;
- listPtr->columnInfo[i].maxChars = maxChars;
- listPtr->columnInfo[i].align = align;
- } else {
+ if (!PC_Int_Parse(handle, &item->typeData.list->numColumns))
+ return qfalse;
+
+ if (item->typeData.list->numColumns > MAX_LB_COLUMNS)
+ {
+ PC_SourceError(handle, "exceeded maximum allowed columns (%d)", MAX_LB_COLUMNS);
return qfalse;
- }
}
- } else {
- return qfalse;
- }
- return qtrue;
+
+ for (i = 0; i < item->typeData.list->numColumns; i++)
+ {
+ int pos, width, align;
+
+ if (!PC_Int_Parse(handle, &pos) || !PC_Int_Parse(handle, &width) || !PC_Int_Parse(handle, &align))
+ return qfalse;
+
+ item->typeData.list->columnInfo[i].pos = pos;
+ item->typeData.list->columnInfo[i].width = width;
+ item->typeData.list->columnInfo[i].align = align;
+ }
+
+ return qtrue;
}
-qboolean ItemParse_border( itemDef_t *item, int handle ) {
- if (!PC_Int_Parse(handle, &item->window.border)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_border(itemDef_t *item, int handle)
+{
+ if (!PC_Int_Parse(handle, &item->window.border))
+ return qfalse;
+
+ return qtrue;
}
-qboolean ItemParse_bordersize( itemDef_t *item, int handle ) {
- if (!PC_Float_Parse(handle, &item->window.borderSize)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_bordersize(itemDef_t *item, int handle)
+{
+ if (!PC_Float_Parse(handle, &item->window.borderSize))
+ return qfalse;
+
+ return qtrue;
}
-qboolean ItemParse_visible( itemDef_t *item, int handle ) {
- int i;
+// FIXME: why does this require a parameter? visible MENU_FALSE does nothing
+qboolean ItemParse_visible(itemDef_t *item, int handle)
+{
+ int i;
- if (!PC_Int_Parse(handle, &i)) {
- return qfalse;
- }
- if (i) {
- item->window.flags |= WINDOW_VISIBLE;
- }
- return qtrue;
+ if (!PC_Int_Parse(handle, &i))
+ return qfalse;
+
+ if (i)
+ item->window.flags |= WINDOW_VISIBLE;
+
+ return qtrue;
}
-qboolean ItemParse_ownerdraw( itemDef_t *item, int handle ) {
- if (!PC_Int_Parse(handle, &item->window.ownerDraw)) {
- return qfalse;
- }
- item->type = ITEM_TYPE_OWNERDRAW;
- return qtrue;
+// ownerdraw <number>, implies ITEM_TYPE_OWNERDRAW
+qboolean ItemParse_ownerdraw(itemDef_t *item, int handle)
+{
+ if (!PC_Int_Parse(handle, &item->window.ownerDraw))
+ return qfalse;
+
+ if (item->type != ITEM_TYPE_NONE && item->type != ITEM_TYPE_OWNERDRAW)
+ {
+ PC_SourceError(handle, "ownerdraws cannot have an item type");
+ return qfalse;
+ }
+
+ item->type = ITEM_TYPE_OWNERDRAW;
+
+ return qtrue;
}
-qboolean ItemParse_align( itemDef_t *item, int handle ) {
- if (!PC_Int_Parse(handle, &item->alignment)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_align(itemDef_t *item, int handle)
+{
+ if (!PC_Int_Parse(handle, &item->alignment))
+ return qfalse;
+
+ return qtrue;
}
-qboolean ItemParse_textalign( itemDef_t *item, int handle ) {
- if (!PC_Int_Parse(handle, &item->textalignment)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_textalign(itemDef_t *item, int handle)
+{
+ if (!PC_Int_Parse(handle, &item->textalignment))
+ return qfalse;
+
+ return qtrue;
}
-qboolean ItemParse_textalignx( itemDef_t *item, int handle ) {
- if (!PC_Float_Parse(handle, &item->textalignx)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_textvalign(itemDef_t *item, int handle)
+{
+ if (!PC_Int_Parse(handle, &item->textvalignment))
+ return qfalse;
+
+ return qtrue;
}
-qboolean ItemParse_textaligny( itemDef_t *item, int handle ) {
- if (!PC_Float_Parse(handle, &item->textaligny)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_textalignx(itemDef_t *item, int handle)
+{
+ if (!PC_Float_Parse(handle, &item->textalignx))
+ return qfalse;
+
+ return qtrue;
}
-qboolean ItemParse_textscale( itemDef_t *item, int handle ) {
- if (!PC_Float_Parse(handle, &item->textscale)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_textaligny(itemDef_t *item, int handle)
+{
+ if (!PC_Float_Parse(handle, &item->textaligny))
+ return qfalse;
+
+ return qtrue;
}
-qboolean ItemParse_textstyle( itemDef_t *item, int handle ) {
- if (!PC_Int_Parse(handle, &item->textStyle)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_textscale(itemDef_t *item, int handle)
+{
+ if (!PC_Float_Parse(handle, &item->textscale))
+ return qfalse;
+
+ return qtrue;
}
-qboolean ItemParse_backcolor( itemDef_t *item, int handle ) {
- int i;
- float f;
+qboolean ItemParse_textstyle(itemDef_t *item, int handle)
+{
+ if (!PC_Int_Parse(handle, &item->textStyle))
+ return qfalse;
- for (i = 0; i < 4; i++) {
- if (!PC_Float_Parse(handle, &f)) {
- return qfalse;
- }
- item->window.backColor[i] = f;
- }
- return qtrue;
+ return qtrue;
}
-qboolean ItemParse_forecolor( itemDef_t *item, int handle ) {
- int i;
- float f;
+qboolean ItemParse_backcolor(itemDef_t *item, int handle)
+{
+ int i;
+ float f;
- for (i = 0; i < 4; i++) {
- if (!PC_Float_Parse(handle, &f)) {
- return qfalse;
+ for (i = 0; i < 4; i++)
+ {
+ if (!PC_Float_Parse(handle, &f))
+ return qfalse;
+
+ item->window.backColor[i] = f;
}
- item->window.foreColor[i] = f;
- item->window.flags |= WINDOW_FORECOLORSET;
- }
- return qtrue;
+
+ return qtrue;
}
-qboolean ItemParse_bordercolor( itemDef_t *item, int handle ) {
- int i;
- float f;
+qboolean ItemParse_forecolor(itemDef_t *item, int handle)
+{
+ int i;
+ float f;
+
+ for (i = 0; i < 4; i++)
+ {
+ if (!PC_Float_Parse(handle, &f))
+ return qfalse;
- for (i = 0; i < 4; i++) {
- if (!PC_Float_Parse(handle, &f)) {
- return qfalse;
+ item->window.foreColor[i] = f;
+ item->window.flags |= WINDOW_FORECOLORSET;
}
- item->window.borderColor[i] = f;
- }
- return qtrue;
-}
-qboolean ItemParse_outlinecolor( itemDef_t *item, int handle ) {
- if (!PC_Color_Parse(handle, &item->window.outlineColor)){
- return qfalse;
- }
- return qtrue;
+ return qtrue;
}
-qboolean ItemParse_background( itemDef_t *item, int handle ) {
- const char *temp;
+qboolean ItemParse_bordercolor(itemDef_t *item, int handle)
+{
+ int i;
+ float f;
- if (!PC_String_Parse(handle, &temp)) {
- return qfalse;
- }
- item->window.background = DC->registerShaderNoMip(temp);
- return qtrue;
-}
+ for (i = 0; i < 4; i++)
+ {
+ if (!PC_Float_Parse(handle, &f))
+ return qfalse;
-qboolean ItemParse_cinematic( itemDef_t *item, int handle ) {
- if (!PC_String_Parse(handle, &item->window.cinematicName)) {
- return qfalse;
- }
- return qtrue;
+ item->window.borderColor[i] = f;
+ }
+
+ return qtrue;
}
-qboolean ItemParse_doubleClick( itemDef_t *item, int handle ) {
- listBoxDef_t *listPtr;
+qboolean ItemParse_outlinecolor(itemDef_t *item, int handle)
+{
+ if (!PC_Color_Parse(handle, &item->window.outlineColor))
+ return qfalse;
- Item_ValidateTypeData(item);
- if (!item->typeData) {
- return qfalse;
- }
+ return qtrue;
+}
- listPtr = (listBoxDef_t*)item->typeData;
+qboolean ItemParse_background(itemDef_t *item, int handle)
+{
+ const char *temp;
- if (!PC_Script_Parse(handle, &listPtr->doubleClick)) {
- return qfalse;
- }
- return qtrue;
+ if (!PC_String_Parse(handle, &temp))
+ return qfalse;
+
+ item->window.background = DC->registerShaderNoMip(temp);
+ return qtrue;
}
-qboolean ItemParse_onFocus( itemDef_t *item, int handle ) {
- if (!PC_Script_Parse(handle, &item->onFocus)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_cinematic(itemDef_t *item, int handle)
+{
+ if (!PC_String_Parse(handle, &item->window.cinematicName))
+ return qfalse;
+
+ return qtrue;
}
-qboolean ItemParse_leaveFocus( itemDef_t *item, int handle ) {
- if (!PC_Script_Parse(handle, &item->leaveFocus)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_doubleClick(itemDef_t *item, int handle)
+{
+ return (item->typeData.list && PC_Script_Parse(handle, &item->typeData.list->doubleClick));
}
-qboolean ItemParse_mouseEnter( itemDef_t *item, int handle ) {
- if (!PC_Script_Parse(handle, &item->mouseEnter)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_onFocus(itemDef_t *item, int handle)
+{
+ if (!PC_Script_Parse(handle, &item->onFocus))
+ return qfalse;
+
+ return qtrue;
}
-qboolean ItemParse_mouseExit( itemDef_t *item, int handle ) {
- if (!PC_Script_Parse(handle, &item->mouseExit)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_leaveFocus(itemDef_t *item, int handle)
+{
+ if (!PC_Script_Parse(handle, &item->leaveFocus))
+ return qfalse;
+
+ return qtrue;
}
-qboolean ItemParse_mouseEnterText( itemDef_t *item, int handle ) {
- if (!PC_Script_Parse(handle, &item->mouseEnterText)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_mouseEnter(itemDef_t *item, int handle)
+{
+ if (!PC_Script_Parse(handle, &item->mouseEnter))
+ return qfalse;
+
+ return qtrue;
}
-qboolean ItemParse_mouseExitText( itemDef_t *item, int handle ) {
- if (!PC_Script_Parse(handle, &item->mouseExitText)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_mouseExit(itemDef_t *item, int handle)
+{
+ if (!PC_Script_Parse(handle, &item->mouseExit))
+ return qfalse;
+
+ return qtrue;
}
-qboolean ItemParse_onTextEntry( itemDef_t *item, int handle ) {
- if (!PC_Script_Parse(handle, &item->onTextEntry)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_mouseEnterText(itemDef_t *item, int handle)
+{
+ if (!PC_Script_Parse(handle, &item->mouseEnterText))
+ return qfalse;
+
+ return qtrue;
}
-qboolean ItemParse_action( itemDef_t *item, int handle ) {
- if (!PC_Script_Parse(handle, &item->action)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_mouseExitText(itemDef_t *item, int handle)
+{
+ if (!PC_Script_Parse(handle, &item->mouseExitText))
+ return qfalse;
+
+ return qtrue;
}
-qboolean ItemParse_special( itemDef_t *item, int handle ) {
- if (!PC_Float_Parse(handle, &item->special)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_onTextEntry(itemDef_t *item, int handle)
+{
+ if (!PC_Script_Parse(handle, &item->onTextEntry))
+ return qfalse;
+
+ return qtrue;
}
-qboolean ItemParse_cvarTest( itemDef_t *item, int handle ) {
- if (!PC_String_Parse(handle, &item->cvarTest)) {
- return qfalse;
- }
- return qtrue;
+qboolean ItemParse_onCharEntry(itemDef_t *item, int handle)
+{
+ if (!PC_Script_Parse(handle, &item->onCharEntry))
+ return qfalse;
+
+ return qtrue;
}
-qboolean ItemParse_cvar( itemDef_t *item, int handle ) {
- editFieldDef_t *editPtr;
+qboolean ItemParse_action(itemDef_t *item, int handle)
+{
+ if (!PC_Script_Parse(handle, &item->action))
+ return qfalse;
- Item_ValidateTypeData(item);
- if (!PC_String_Parse(handle, &item->cvar)) {
- return qfalse;
- }
- if (item->typeData) {
- editPtr = (editFieldDef_t*)item->typeData;
- editPtr->minVal = -1;
- editPtr->maxVal = -1;
- editPtr->defVal = -1;
- }
- return qtrue;
-}
-
-qboolean ItemParse_maxChars( itemDef_t *item, int handle ) {
- editFieldDef_t *editPtr;
- int maxChars;
-
- Item_ValidateTypeData(item);
- if (!item->typeData)
- return qfalse;
+ return qtrue;
+}
- if (!PC_Int_Parse(handle, &maxChars)) {
- return qfalse;
- }
- editPtr = (editFieldDef_t*)item->typeData;
- editPtr->maxChars = maxChars;
- return qtrue;
+qboolean ItemParse_cvarTest(itemDef_t *item, int handle)
+{
+ if (!PC_String_Parse(handle, &item->cvarTest))
+ return qfalse;
+
+ return qtrue;
}
-qboolean ItemParse_maxPaintChars( itemDef_t *item, int handle ) {
- editFieldDef_t *editPtr;
- int maxChars;
+qboolean ItemParse_cvar(itemDef_t *item, int handle)
+{
+ if (!PC_String_Parse(handle, &item->cvar))
+ return qfalse;
- Item_ValidateTypeData(item);
- if (!item->typeData)
- return qfalse;
+ if (Item_DataType(item) == TYPE_EDIT)
+ {
+ item->typeData.edit->minVal = -1;
+ item->typeData.edit->maxVal = -1;
+ item->typeData.edit->defVal = -1;
+ }
- if (!PC_Int_Parse(handle, &maxChars)) {
- return qfalse;
- }
- editPtr = (editFieldDef_t*)item->typeData;
- editPtr->maxPaintChars = maxChars;
- return qtrue;
+ return qtrue;
+}
+
+qboolean ItemParse_maxChars(itemDef_t *item, int handle)
+{
+ return PC_Int_Parse(handle, &item->typeData.edit->maxChars);
}
+qboolean ItemParse_maxPaintChars(itemDef_t *item, int handle)
+{
+ return PC_Int_Parse(handle, &item->typeData.edit->maxPaintChars);
+}
+qboolean ItemParse_maxFieldWidth(itemDef_t *item, int handle)
+{
+ if (!PC_Int_Parse(handle, &item->typeData.edit->maxFieldWidth))
+ return qfalse;
-qboolean ItemParse_cvarFloat( itemDef_t *item, int handle ) {
- editFieldDef_t *editPtr;
+ if (item->typeData.edit->maxFieldWidth < MIN_FIELD_WIDTH)
+ {
+ PC_SourceError(handle, "max field width must be at least %d", MIN_FIELD_WIDTH);
+ return qfalse;
+ }
- Item_ValidateTypeData(item);
- if (!item->typeData)
- return qfalse;
- editPtr = (editFieldDef_t*)item->typeData;
- if (PC_String_Parse(handle, &item->cvar) &&
- PC_Float_Parse(handle, &editPtr->defVal) &&
- PC_Float_Parse(handle, &editPtr->minVal) &&
- PC_Float_Parse(handle, &editPtr->maxVal)) {
return qtrue;
- }
- return qfalse;
}
-qboolean ItemParse_cvarStrList( itemDef_t *item, int handle ) {
- pc_token_t token;
- multiDef_t *multiPtr;
- int pass;
+qboolean ItemParse_cvarFloat(itemDef_t *item, int handle)
+{
+ return (PC_String_Parse(handle, &item->cvar) && PC_Float_Parse(handle, &item->typeData.edit->defVal) &&
+ PC_Float_Parse(handle, &item->typeData.edit->minVal) &&
+ PC_Float_Parse(handle, &item->typeData.edit->maxVal));
+}
- Item_ValidateTypeData(item);
- if (!item->typeData)
- return qfalse;
- multiPtr = (multiDef_t*)item->typeData;
- multiPtr->count = 0;
- multiPtr->strDef = qtrue;
+qboolean ItemParse_cvarStrList(itemDef_t *item, int handle)
+{
+ pc_token_t token;
+ multiDef_t *multiPtr;
+ int pass;
- if (!trap_Parse_ReadToken(handle, &token))
- return qfalse;
- if (*token.string != '{') {
- return qfalse;
- }
+ multiPtr = item->typeData.multi;
+ multiPtr->count = 0;
+ multiPtr->strDef = qtrue;
- pass = 0;
- while ( 1 ) {
- if (!trap_Parse_ReadToken(handle, &token)) {
- PC_SourceError(handle, "end of file inside menu item\n");
- return qfalse;
- }
+ if (!trap_Parse_ReadToken(handle, &token))
+ return qfalse;
- if (*token.string == '}') {
- return qtrue;
- }
+ if (*token.string != '{')
+ return qfalse;
- if (*token.string == ',' || *token.string == ';') {
- continue;
- }
+ pass = 0;
- if (pass == 0) {
- multiPtr->cvarList[multiPtr->count] = String_Alloc(token.string);
- pass = 1;
- } else {
- multiPtr->cvarStr[multiPtr->count] = String_Alloc(token.string);
- pass = 0;
- multiPtr->count++;
- if (multiPtr->count >= MAX_MULTI_CVARS) {
- return qfalse;
- }
+ while (1)
+ {
+ if (!trap_Parse_ReadToken(handle, &token))
+ {
+ PC_SourceError(handle, "end of file inside menu item\n");
+ return qfalse;
+ }
+
+ if (*token.string == '}')
+ return qtrue;
+
+ if (*token.string == ',' || *token.string == ';')
+ continue;
+
+ if (pass == 0)
+ {
+ multiPtr->cvarList[multiPtr->count] = String_Alloc(token.string);
+ pass = 1;
+ }
+ else
+ {
+ multiPtr->cvarStr[multiPtr->count] = String_Alloc(token.string);
+ pass = 0;
+ multiPtr->count++;
+
+ if (multiPtr->count >= MAX_MULTI_CVARS)
+ {
+ PC_SourceError(handle, "cvar string list may not exceed %d cvars", MAX_MULTI_CVARS);
+ return qfalse;
+ }
+ }
}
- }
- return qfalse; // bk001205 - LCC missing return value
+ return qfalse;
}
-qboolean ItemParse_cvarFloatList( itemDef_t *item, int handle ) {
- pc_token_t token;
- multiDef_t *multiPtr;
+qboolean ItemParse_cvarFloatList(itemDef_t *item, int handle)
+{
+ pc_token_t token;
+ multiDef_t *multiPtr;
- Item_ValidateTypeData(item);
- if (!item->typeData)
- return qfalse;
- multiPtr = (multiDef_t*)item->typeData;
- multiPtr->count = 0;
- multiPtr->strDef = qfalse;
+ multiPtr = item->typeData.multi;
+ multiPtr->count = 0;
+ multiPtr->strDef = qfalse;
- if (!trap_Parse_ReadToken(handle, &token))
- return qfalse;
- if (*token.string != '{') {
- return qfalse;
- }
+ if (!trap_Parse_ReadToken(handle, &token))
+ return qfalse;
- while ( 1 ) {
- if (!trap_Parse_ReadToken(handle, &token)) {
- PC_SourceError(handle, "end of file inside menu item\n");
- return qfalse;
- }
+ if (*token.string != '{')
+ return qfalse;
- if (*token.string == '}') {
- return qtrue;
- }
+ while (1)
+ {
+ if (!trap_Parse_ReadToken(handle, &token))
+ {
+ PC_SourceError(handle, "end of file inside menu item\n");
+ return qfalse;
+ }
- if (*token.string == ',' || *token.string == ';') {
- continue;
- }
+ if (*token.string == '}')
+ return qtrue;
- multiPtr->cvarList[multiPtr->count] = String_Alloc(token.string);
- if (!PC_Float_Parse(handle, &multiPtr->cvarValue[multiPtr->count])) {
- return qfalse;
- }
+ if (*token.string == ',' || *token.string == ';')
+ continue;
- multiPtr->count++;
- if (multiPtr->count >= MAX_MULTI_CVARS) {
- return qfalse;
+ multiPtr->cvarList[multiPtr->count] = String_Alloc(token.string);
+
+ if (!PC_Float_Parse(handle, &multiPtr->cvarValue[multiPtr->count]))
+ return qfalse;
+
+ multiPtr->count++;
+
+ if (multiPtr->count >= MAX_MULTI_CVARS)
+ {
+ PC_SourceError(handle, "cvar string list may not exceed %d cvars", MAX_MULTI_CVARS);
+ return qfalse;
+ }
}
- }
- return qfalse; // bk001205 - LCC missing return value
+ return qfalse;
}
+qboolean ItemParse_addColorRange(itemDef_t *item, int handle)
+{
+ colorRangeDef_t color;
+ if (PC_Float_Parse(handle, &color.low) && PC_Float_Parse(handle, &color.high) &&
+ PC_Color_Parse(handle, &color.color))
+ {
+ if (item->numColors < MAX_COLOR_RANGES)
+ {
+ memcpy(&item->colorRanges[item->numColors], &color, sizeof(color));
+ item->numColors++;
+ }
+ else
+ {
+ PC_SourceError(handle, "may not exceed %d color ranges", MAX_COLOR_RANGES);
+ return qfalse;
+ }
-qboolean ItemParse_addColorRange( itemDef_t *item, int handle ) {
- colorRangeDef_t color;
-
- if (PC_Float_Parse(handle, &color.low) &&
- PC_Float_Parse(handle, &color.high) &&
- PC_Color_Parse(handle, &color.color) ) {
- if (item->numColors < MAX_COLOR_RANGES) {
- memcpy(&item->colorRanges[item->numColors], &color, sizeof(color));
- item->numColors++;
+ return qtrue;
}
+
+ return qfalse;
+}
+
+qboolean ItemParse_ownerdrawFlag(itemDef_t *item, int handle)
+{
+ int i;
+
+ if (!PC_Int_Parse(handle, &i))
+ return qfalse;
+
+ item->window.ownerDrawFlags |= i;
return qtrue;
- }
- return qfalse;
}
-qboolean ItemParse_ownerdrawFlag( itemDef_t *item, int handle ) {
- int i;
- if (!PC_Int_Parse(handle, &i)) {
+qboolean ItemParse_enableCvar(itemDef_t *item, int handle)
+{
+ if (PC_Script_Parse(handle, &item->enableCvar))
+ {
+ item->cvarFlags = CVAR_ENABLE;
+ return qtrue;
+ }
+
return qfalse;
- }
- item->window.ownerDrawFlags |= i;
- return qtrue;
}
-qboolean ItemParse_enableCvar( itemDef_t *item, int handle ) {
- if (PC_Script_Parse(handle, &item->enableCvar)) {
- item->cvarFlags = CVAR_ENABLE;
- return qtrue;
- }
- return qfalse;
+qboolean ItemParse_disableCvar(itemDef_t *item, int handle)
+{
+ if (PC_Script_Parse(handle, &item->enableCvar))
+ {
+ item->cvarFlags = CVAR_DISABLE;
+ return qtrue;
+ }
+
+ return qfalse;
}
-qboolean ItemParse_disableCvar( itemDef_t *item, int handle ) {
- if (PC_Script_Parse(handle, &item->enableCvar)) {
- item->cvarFlags = CVAR_DISABLE;
- return qtrue;
- }
- return qfalse;
+qboolean ItemParse_showCvar(itemDef_t *item, int handle)
+{
+ if (PC_Script_Parse(handle, &item->enableCvar))
+ {
+ item->cvarFlags = CVAR_SHOW;
+ return qtrue;
+ }
+
+ return qfalse;
}
-qboolean ItemParse_showCvar( itemDef_t *item, int handle ) {
- if (PC_Script_Parse(handle, &item->enableCvar)) {
- item->cvarFlags = CVAR_SHOW;
- return qtrue;
- }
- return qfalse;
+qboolean ItemParse_hideCvar(itemDef_t *item, int handle)
+{
+ if (PC_Script_Parse(handle, &item->enableCvar))
+ {
+ item->cvarFlags = CVAR_HIDE;
+ return qtrue;
+ }
+
+ return qfalse;
}
-qboolean ItemParse_hideCvar( itemDef_t *item, int handle ) {
- if (PC_Script_Parse(handle, &item->enableCvar)) {
- item->cvarFlags = CVAR_HIDE;
- return qtrue;
- }
- return qfalse;
-}
-
-
-keywordHash_t itemParseKeywords[] = {
- {"name", ItemParse_name, NULL},
- {"text", ItemParse_text, NULL},
- {"group", ItemParse_group, NULL},
- {"asset_model", ItemParse_asset_model, NULL},
- {"asset_shader", ItemParse_asset_shader, NULL},
- {"model_origin", ItemParse_model_origin, NULL},
- {"model_fovx", ItemParse_model_fovx, NULL},
- {"model_fovy", ItemParse_model_fovy, NULL},
- {"model_rotation", ItemParse_model_rotation, NULL},
- {"model_angle", ItemParse_model_angle, NULL},
- {"rect", ItemParse_rect, NULL},
- {"style", ItemParse_style, NULL},
- {"decoration", ItemParse_decoration, NULL},
- {"notselectable", ItemParse_notselectable, NULL},
- {"wrapped", ItemParse_wrapped, NULL},
- {"autowrapped", ItemParse_autowrapped, NULL},
- {"horizontalscroll", ItemParse_horizontalscroll, NULL},
- {"type", ItemParse_type, NULL},
- {"elementwidth", ItemParse_elementwidth, NULL},
- {"elementheight", ItemParse_elementheight, NULL},
- {"feeder", ItemParse_feeder, NULL},
- {"elementtype", ItemParse_elementtype, NULL},
- {"columns", ItemParse_columns, NULL},
- {"border", ItemParse_border, NULL},
- {"bordersize", ItemParse_bordersize, NULL},
- {"visible", ItemParse_visible, NULL},
- {"ownerdraw", ItemParse_ownerdraw, NULL},
- {"align", ItemParse_align, NULL},
- {"textalign", ItemParse_textalign, NULL},
- {"textalignx", ItemParse_textalignx, NULL},
- {"textaligny", ItemParse_textaligny, NULL},
- {"textscale", ItemParse_textscale, NULL},
- {"textstyle", ItemParse_textstyle, NULL},
- {"backcolor", ItemParse_backcolor, NULL},
- {"forecolor", ItemParse_forecolor, NULL},
- {"bordercolor", ItemParse_bordercolor, NULL},
- {"outlinecolor", ItemParse_outlinecolor, NULL},
- {"background", ItemParse_background, NULL},
- {"onFocus", ItemParse_onFocus, NULL},
- {"leaveFocus", ItemParse_leaveFocus, NULL},
- {"mouseEnter", ItemParse_mouseEnter, NULL},
- {"mouseExit", ItemParse_mouseExit, NULL},
- {"mouseEnterText", ItemParse_mouseEnterText, NULL},
- {"mouseExitText", ItemParse_mouseExitText, NULL},
- {"onTextEntry", ItemParse_onTextEntry, NULL},
- {"action", ItemParse_action, NULL},
- {"special", ItemParse_special, NULL},
- {"cvar", ItemParse_cvar, NULL},
- {"maxChars", ItemParse_maxChars, NULL},
- {"maxPaintChars", ItemParse_maxPaintChars, NULL},
- {"focusSound", ItemParse_focusSound, NULL},
- {"cvarFloat", ItemParse_cvarFloat, NULL},
- {"cvarStrList", ItemParse_cvarStrList, NULL},
- {"cvarFloatList", ItemParse_cvarFloatList, NULL},
- {"addColorRange", ItemParse_addColorRange, NULL},
- {"ownerdrawFlag", ItemParse_ownerdrawFlag, NULL},
- {"enableCvar", ItemParse_enableCvar, NULL},
- {"cvarTest", ItemParse_cvarTest, NULL},
- {"disableCvar", ItemParse_disableCvar, NULL},
- {"showCvar", ItemParse_showCvar, NULL},
- {"hideCvar", ItemParse_hideCvar, NULL},
- {"cinematic", ItemParse_cinematic, NULL},
- {"doubleclick", ItemParse_doubleClick, NULL},
- {NULL, voidFunction2, NULL}
-};
+keywordHash_t itemParseKeywords[] = {{"name", ItemParse_name, TYPE_ANY, NULL}, {"type", ItemParse_type, TYPE_ANY, NULL},
+ {"text", ItemParse_text, TYPE_ANY, NULL}, {"group", ItemParse_group, TYPE_ANY, NULL},
+ {"asset_model", ItemParse_asset_model, TYPE_MODEL, NULL},
+ {"asset_shader", ItemParse_asset_shader, TYPE_ANY, NULL}, // ?
+ {"model_origin", ItemParse_model_origin, TYPE_MODEL, NULL}, {"model_fovx", ItemParse_model_fovx, TYPE_MODEL, NULL},
+ {"model_fovy", ItemParse_model_fovy, TYPE_MODEL, NULL},
+ {"model_rotation", ItemParse_model_rotation, TYPE_MODEL, NULL},
+ {"model_angle", ItemParse_model_angle, TYPE_MODEL, NULL}, {"rect", ItemParse_rect, TYPE_ANY, NULL},
+ {"aspectBias", ItemParse_aspectBias, TYPE_ANY, NULL}, {"style", ItemParse_style, TYPE_ANY, NULL},
+ {"decoration", ItemParse_decoration, TYPE_ANY, NULL}, {"notselectable", ItemParse_notselectable, TYPE_LIST, NULL},
+ {"noscrollbar", ItemParse_noscrollbar, TYPE_LIST, NULL},
+ {"resetonfeederchange", ItemParse_resetonfeederchange, TYPE_LIST, NULL},
+ {"wrapped", ItemParse_wrapped, TYPE_ANY, NULL}, {"elementwidth", ItemParse_elementwidth, TYPE_LIST, NULL},
+ {"elementheight", ItemParse_elementheight, TYPE_LIST, NULL}, {"dropitems", ItemParse_dropitems, TYPE_LIST, NULL},
+ {"feeder", ItemParse_feeder, TYPE_ANY, NULL}, {"elementtype", ItemParse_elementtype, TYPE_LIST, NULL},
+ {"columns", ItemParse_columns, TYPE_LIST, NULL}, {"border", ItemParse_border, TYPE_ANY, NULL},
+ {"bordersize", ItemParse_bordersize, TYPE_ANY, NULL}, {"visible", ItemParse_visible, TYPE_ANY, NULL},
+ {"ownerdraw", ItemParse_ownerdraw, TYPE_ANY, NULL}, {"align", ItemParse_align, TYPE_ANY, NULL},
+ {"textalign", ItemParse_textalign, TYPE_ANY, NULL}, {"textvalign", ItemParse_textvalign, TYPE_ANY, NULL},
+ {"textalignx", ItemParse_textalignx, TYPE_ANY, NULL}, {"textaligny", ItemParse_textaligny, TYPE_ANY, NULL},
+ {"textscale", ItemParse_textscale, TYPE_ANY, NULL}, {"textstyle", ItemParse_textstyle, TYPE_ANY, NULL},
+ {"backcolor", ItemParse_backcolor, TYPE_ANY, NULL}, {"forecolor", ItemParse_forecolor, TYPE_ANY, NULL},
+ {"bordercolor", ItemParse_bordercolor, TYPE_ANY, NULL}, {"outlinecolor", ItemParse_outlinecolor, TYPE_ANY, NULL},
+ {"background", ItemParse_background, TYPE_ANY, NULL}, {"onFocus", ItemParse_onFocus, TYPE_ANY, NULL},
+ {"leaveFocus", ItemParse_leaveFocus, TYPE_ANY, NULL}, {"mouseEnter", ItemParse_mouseEnter, TYPE_ANY, NULL},
+ {"mouseExit", ItemParse_mouseExit, TYPE_ANY, NULL}, {"mouseEnterText", ItemParse_mouseEnterText, TYPE_ANY, NULL},
+ {"mouseExitText", ItemParse_mouseExitText, TYPE_ANY, NULL}, {"onTextEntry", ItemParse_onTextEntry, TYPE_ANY, NULL},
+ {"onCharEntry", ItemParse_onCharEntry, TYPE_ANY, NULL}, {"action", ItemParse_action, TYPE_ANY, NULL},
+ {"cvar", ItemParse_cvar, TYPE_ANY, NULL}, {"maxChars", ItemParse_maxChars, TYPE_EDIT, NULL},
+ {"maxPaintChars", ItemParse_maxPaintChars, TYPE_EDIT, NULL},
+ {"maxFieldWidth", ItemParse_maxFieldWidth, TYPE_EDIT, NULL}, {"focusSound", ItemParse_focusSound, TYPE_ANY, NULL},
+ {"cvarFloat", ItemParse_cvarFloat, TYPE_EDIT, NULL}, {"cvarStrList", ItemParse_cvarStrList, TYPE_MULTI, NULL},
+ {"cvarFloatList", ItemParse_cvarFloatList, TYPE_MULTI, NULL},
+ {"addColorRange", ItemParse_addColorRange, TYPE_ANY, NULL},
+ {"ownerdrawFlag", ItemParse_ownerdrawFlag, TYPE_ANY, NULL}, // hm.
+ {"enableCvar", ItemParse_enableCvar, TYPE_ANY, NULL}, {"cvarTest", ItemParse_cvarTest, TYPE_ANY, NULL},
+ {"disableCvar", ItemParse_disableCvar, TYPE_ANY, NULL}, {"showCvar", ItemParse_showCvar, TYPE_ANY, NULL},
+ {"hideCvar", ItemParse_hideCvar, TYPE_ANY, NULL}, {"cinematic", ItemParse_cinematic, TYPE_ANY, NULL},
+ {"doubleclick", ItemParse_doubleClick, TYPE_LIST, NULL}, {NULL, voidFunction2, 0, NULL}};
keywordHash_t *itemParseKeywordHash[KEYWORDHASH_SIZE];
@@ -5470,14 +7035,14 @@ keywordHash_t *itemParseKeywordHash[KEYWORDHASH_SIZE];
Item_SetupKeywordHash
===============
*/
-void Item_SetupKeywordHash( void )
+void Item_SetupKeywordHash(void)
{
- int i;
+ int i;
- memset( itemParseKeywordHash, 0, sizeof( itemParseKeywordHash ) );
+ memset(itemParseKeywordHash, 0, sizeof(itemParseKeywordHash));
- for( i = 0; itemParseKeywords[ i ].keyword; i++ )
- KeywordHash_Add( itemParseKeywordHash, &itemParseKeywords[ i ] );
+ for (i = 0; itemParseKeywords[i].keyword; i++)
+ KeywordHash_Add(itemParseKeywordHash, &itemParseKeywords[i]);
}
/*
@@ -5485,56 +7050,85 @@ void Item_SetupKeywordHash( void )
Item_Parse
===============
*/
-qboolean Item_Parse(int handle, itemDef_t *item) {
- pc_token_t token;
- keywordHash_t *key;
+qboolean Item_Parse(int handle, itemDef_t *item)
+{
+ pc_token_t token;
+ keywordHash_t *key;
+ if (!trap_Parse_ReadToken(handle, &token))
+ return qfalse;
- if (!trap_Parse_ReadToken(handle, &token))
- return qfalse;
- if (*token.string != '{') {
- return qfalse;
- }
- while ( 1 ) {
- if (!trap_Parse_ReadToken(handle, &token)) {
- PC_SourceError(handle, "end of file inside menu item\n");
- return qfalse;
- }
+ if (*token.string != '{')
+ return qfalse;
- if (*token.string == '}') {
- return qtrue;
- }
+ while (1)
+ {
+ if (!trap_Parse_ReadToken(handle, &token))
+ {
+ PC_SourceError(handle, "end of file inside menu item\n");
+ return qfalse;
+ }
- key = KeywordHash_Find(itemParseKeywordHash, token.string);
- if (!key) {
- PC_SourceError(handle, "unknown menu item keyword %s", token.string);
- continue;
- }
- if ( !key->func(item, handle) ) {
- PC_SourceError(handle, "couldn't parse menu item keyword %s", token.string);
- return qfalse;
+ if (*token.string == '}')
+ return qtrue;
+
+ key = KeywordHash_Find(itemParseKeywordHash, token.string);
+
+ if (!key)
+ {
+ PC_SourceError(handle, "unknown menu item keyword %s", token.string);
+ continue;
+ }
+
+ // do type-checks
+ if (key->param != TYPE_ANY)
+ {
+ itemDataType_t test = Item_DataType(item);
+
+ if (test != key->param)
+ {
+ if (test == TYPE_NONE)
+ PC_SourceError(handle,
+ "menu item keyword %s requires "
+ "type specification",
+ token.string);
+ else
+ PC_SourceError(handle,
+ "menu item keyword %s is incompatible with "
+ "specified item type",
+ token.string);
+ continue;
+ }
+ }
+
+ if (!key->func(item, handle))
+ {
+ PC_SourceError(handle, "couldn't parse menu item keyword %s", token.string);
+ return qfalse;
+ }
}
- }
- return qfalse; // bk001205 - LCC missing return value
-}
+ return qfalse;
+}
// Item_InitControls
// init's special control types
-void Item_InitControls(itemDef_t *item) {
- if (item == NULL) {
- return;
- }
- if (item->type == ITEM_TYPE_LISTBOX) {
- listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData;
- item->cursorPos = 0;
- if (listPtr) {
- listPtr->cursorPos = 0;
- listPtr->startPos = 0;
- listPtr->endPos = 0;
- listPtr->cursorPos = 0;
- }
- }
+void Item_InitControls(itemDef_t *item)
+{
+ if (item == NULL)
+ return;
+
+ if (Item_IsListBox(item))
+ {
+ item->cursorPos = 0;
+
+ if (item->typeData.list)
+ {
+ item->typeData.list->cursorPos = 0;
+ Item_ListBox_SetStartPos(item, 0);
+ item->typeData.list->cursorPos = 0;
+ }
+ }
}
/*
@@ -5543,327 +7137,376 @@ Menu Keyword Parse functions
===============
*/
-qboolean MenuParse_font( itemDef_t *item, int handle ) {
- menuDef_t *menu = (menuDef_t*)item;
- if (!PC_String_Parse(handle, &menu->font)) {
- return qfalse;
- }
- if (!DC->Assets.fontRegistered) {
- DC->registerFont(menu->font, 48, &DC->Assets.textFont);
- DC->Assets.fontRegistered = qtrue;
- }
- return qtrue;
+qboolean MenuParse_font(itemDef_t *item, int handle)
+{
+ menuDef_t *menu = (menuDef_t *)item;
+
+ if (!PC_String_Parse(handle, &menu->font))
+ return qfalse;
+
+ if (!DC->Assets.fontRegistered)
+ {
+ DC->registerFont(menu->font, 48, &DC->Assets.textFont);
+ DC->Assets.fontRegistered = qtrue;
+ }
+
+ return qtrue;
}
-qboolean MenuParse_name( itemDef_t *item, int handle ) {
- menuDef_t *menu = (menuDef_t*)item;
- if (!PC_String_Parse(handle, &menu->window.name)) {
- return qfalse;
- }
- if (Q_stricmp(menu->window.name, "main") == 0) {
- // default main as having focus
- //menu->window.flags |= WINDOW_HASFOCUS;
- }
- return qtrue;
+qboolean MenuParse_name(itemDef_t *item, int handle)
+{
+ menuDef_t *menu = (menuDef_t *)item;
+
+ if (!PC_String_Parse(handle, &menu->window.name))
+ return qfalse;
+
+ return qtrue;
}
-qboolean MenuParse_fullscreen( itemDef_t *item, int handle ) {
- menuDef_t *menu = (menuDef_t*)item;
- if (!PC_Int_Parse(handle, (int*) &menu->fullScreen)) { // bk001206 - cast qboolean
- return qfalse;
- }
- return qtrue;
+qboolean MenuParse_fullscreen(itemDef_t *item, int handle)
+{
+ menuDef_t *menu = (menuDef_t *)item;
+
+ if (!PC_Int_Parse(handle, (int *)&menu->fullScreen))
+ return qfalse;
+
+ return qtrue;
}
-qboolean MenuParse_rect( itemDef_t *item, int handle ) {
- menuDef_t *menu = (menuDef_t*)item;
- if (!PC_Rect_Parse(handle, &menu->window.rect)) {
- return qfalse;
- }
- return qtrue;
+qboolean MenuParse_rect(itemDef_t *item, int handle)
+{
+ menuDef_t *menu = (menuDef_t *)item;
+
+ if (!PC_Rect_Parse(handle, &menu->window.rect))
+ return qfalse;
+
+ return qtrue;
}
-qboolean MenuParse_style( itemDef_t *item, int handle ) {
- menuDef_t *menu = (menuDef_t*)item;
- if (!PC_Int_Parse(handle, &menu->window.style)) {
- return qfalse;
- }
- return qtrue;
+qboolean MenuParse_aspectBias(itemDef_t *item, int handle)
+{
+ menuDef_t *menu = (menuDef_t *)item;
+
+ if (!PC_Int_Parse(handle, &menu->window.aspectBias))
+ return qfalse;
+
+ return qtrue;
}
-qboolean MenuParse_visible( itemDef_t *item, int handle ) {
- int i;
- menuDef_t *menu = (menuDef_t*)item;
+qboolean MenuParse_style(itemDef_t *item, int handle)
+{
+ menuDef_t *menu = (menuDef_t *)item;
- if (!PC_Int_Parse(handle, &i)) {
- return qfalse;
- }
- if (i) {
- menu->window.flags |= WINDOW_VISIBLE;
- }
- return qtrue;
+ if (!PC_Int_Parse(handle, &menu->window.style))
+ return qfalse;
+
+ return qtrue;
}
-qboolean MenuParse_onOpen( itemDef_t *item, int handle ) {
- menuDef_t *menu = (menuDef_t*)item;
- if (!PC_Script_Parse(handle, &menu->onOpen)) {
- return qfalse;
- }
- return qtrue;
+qboolean MenuParse_visible(itemDef_t *item, int handle)
+{
+ int i;
+ menuDef_t *menu = (menuDef_t *)item;
+
+ if (!PC_Int_Parse(handle, &i))
+ return qfalse;
+
+ if (i)
+ menu->window.flags |= WINDOW_VISIBLE;
+
+ return qtrue;
}
-qboolean MenuParse_onClose( itemDef_t *item, int handle ) {
- menuDef_t *menu = (menuDef_t*)item;
- if (!PC_Script_Parse(handle, &menu->onClose)) {
- return qfalse;
- }
- return qtrue;
+qboolean MenuParse_onOpen(itemDef_t *item, int handle)
+{
+ menuDef_t *menu = (menuDef_t *)item;
+
+ if (!PC_Script_Parse(handle, &menu->onOpen))
+ return qfalse;
+
+ return qtrue;
}
-qboolean MenuParse_onESC( itemDef_t *item, int handle ) {
- menuDef_t *menu = (menuDef_t*)item;
- if (!PC_Script_Parse(handle, &menu->onESC)) {
- return qfalse;
- }
- return qtrue;
+qboolean MenuParse_onClose(itemDef_t *item, int handle)
+{
+ menuDef_t *menu = (menuDef_t *)item;
+
+ if (!PC_Script_Parse(handle, &menu->onClose))
+ return qfalse;
+
+ return qtrue;
}
+qboolean MenuParse_onESC(itemDef_t *item, int handle)
+{
+ menuDef_t *menu = (menuDef_t *)item;
+ if (!PC_Script_Parse(handle, &menu->onESC))
+ return qfalse;
-qboolean MenuParse_border( itemDef_t *item, int handle ) {
- menuDef_t *menu = (menuDef_t*)item;
- if (!PC_Int_Parse(handle, &menu->window.border)) {
- return qfalse;
- }
- return qtrue;
+ return qtrue;
}
-qboolean MenuParse_borderSize( itemDef_t *item, int handle ) {
- menuDef_t *menu = (menuDef_t*)item;
- if (!PC_Float_Parse(handle, &menu->window.borderSize)) {
- return qfalse;
- }
- return qtrue;
+qboolean MenuParse_border(itemDef_t *item, int handle)
+{
+ menuDef_t *menu = (menuDef_t *)item;
+
+ if (!PC_Int_Parse(handle, &menu->window.border))
+ return qfalse;
+
+ return qtrue;
}
-qboolean MenuParse_backcolor( itemDef_t *item, int handle ) {
- int i;
- float f;
- menuDef_t *menu = (menuDef_t*)item;
+qboolean MenuParse_borderSize(itemDef_t *item, int handle)
+{
+ menuDef_t *menu = (menuDef_t *)item;
+
+ if (!PC_Float_Parse(handle, &menu->window.borderSize))
+ return qfalse;
- for (i = 0; i < 4; i++) {
- if (!PC_Float_Parse(handle, &f)) {
- return qfalse;
- }
- menu->window.backColor[i] = f;
- }
- return qtrue;
+ return qtrue;
}
-qboolean MenuParse_forecolor( itemDef_t *item, int handle ) {
- int i;
- float f;
- menuDef_t *menu = (menuDef_t*)item;
+qboolean MenuParse_backcolor(itemDef_t *item, int handle)
+{
+ int i;
+ float f;
+ menuDef_t *menu = (menuDef_t *)item;
- for (i = 0; i < 4; i++) {
- if (!PC_Float_Parse(handle, &f)) {
- return qfalse;
+ for (i = 0; i < 4; i++)
+ {
+ if (!PC_Float_Parse(handle, &f))
+ return qfalse;
+
+ menu->window.backColor[i] = f;
}
- menu->window.foreColor[i] = f;
- menu->window.flags |= WINDOW_FORECOLORSET;
- }
- return qtrue;
+
+ return qtrue;
}
-qboolean MenuParse_bordercolor( itemDef_t *item, int handle ) {
- int i;
- float f;
- menuDef_t *menu = (menuDef_t*)item;
+qboolean MenuParse_forecolor(itemDef_t *item, int handle)
+{
+ int i;
+ float f;
+ menuDef_t *menu = (menuDef_t *)item;
+
+ for (i = 0; i < 4; i++)
+ {
+ if (!PC_Float_Parse(handle, &f))
+ return qfalse;
- for (i = 0; i < 4; i++) {
- if (!PC_Float_Parse(handle, &f)) {
- return qfalse;
+ menu->window.foreColor[i] = f;
+ menu->window.flags |= WINDOW_FORECOLORSET;
}
- menu->window.borderColor[i] = f;
- }
- return qtrue;
+
+ return qtrue;
}
-qboolean MenuParse_focuscolor( itemDef_t *item, int handle ) {
- int i;
- float f;
- menuDef_t *menu = (menuDef_t*)item;
+qboolean MenuParse_bordercolor(itemDef_t *item, int handle)
+{
+ int i;
+ float f;
+ menuDef_t *menu = (menuDef_t *)item;
- for (i = 0; i < 4; i++) {
- if (!PC_Float_Parse(handle, &f)) {
- return qfalse;
+ for (i = 0; i < 4; i++)
+ {
+ if (!PC_Float_Parse(handle, &f))
+ return qfalse;
+
+ menu->window.borderColor[i] = f;
}
- menu->focusColor[i] = f;
- }
- return qtrue;
+
+ return qtrue;
}
-qboolean MenuParse_disablecolor( itemDef_t *item, int handle ) {
- int i;
- float f;
- menuDef_t *menu = (menuDef_t*)item;
- for (i = 0; i < 4; i++) {
- if (!PC_Float_Parse(handle, &f)) {
- return qfalse;
+qboolean MenuParse_focuscolor(itemDef_t *item, int handle)
+{
+ int i;
+ float f;
+ menuDef_t *menu = (menuDef_t *)item;
+
+ for (i = 0; i < 4; i++)
+ {
+ if (!PC_Float_Parse(handle, &f))
+ return qfalse;
+
+ menu->focusColor[i] = f;
}
- menu->disableColor[i] = f;
- }
- return qtrue;
+
+ return qtrue;
}
+qboolean MenuParse_disablecolor(itemDef_t *item, int handle)
+{
+ int i;
+ float f;
+ menuDef_t *menu = (menuDef_t *)item;
+
+ for (i = 0; i < 4; i++)
+ {
+ if (!PC_Float_Parse(handle, &f))
+ return qfalse;
-qboolean MenuParse_outlinecolor( itemDef_t *item, int handle ) {
- menuDef_t *menu = (menuDef_t*)item;
- if (!PC_Color_Parse(handle, &menu->window.outlineColor)){
- return qfalse;
- }
- return qtrue;
+ menu->disableColor[i] = f;
+ }
+
+ return qtrue;
}
-qboolean MenuParse_background( itemDef_t *item, int handle ) {
- const char *buff;
- menuDef_t *menu = (menuDef_t*)item;
+qboolean MenuParse_outlinecolor(itemDef_t *item, int handle)
+{
+ menuDef_t *menu = (menuDef_t *)item;
- if (!PC_String_Parse(handle, &buff)) {
- return qfalse;
- }
- menu->window.background = DC->registerShaderNoMip(buff);
- return qtrue;
+ if (!PC_Color_Parse(handle, &menu->window.outlineColor))
+ return qfalse;
+
+ return qtrue;
}
-qboolean MenuParse_cinematic( itemDef_t *item, int handle ) {
- menuDef_t *menu = (menuDef_t*)item;
+qboolean MenuParse_background(itemDef_t *item, int handle)
+{
+ const char *buff;
+ menuDef_t *menu = (menuDef_t *)item;
- if (!PC_String_Parse(handle, &menu->window.cinematicName)) {
- return qfalse;
- }
- return qtrue;
+ if (!PC_String_Parse(handle, &buff))
+ return qfalse;
+
+ menu->window.background = DC->registerShaderNoMip(buff);
+ return qtrue;
}
-qboolean MenuParse_ownerdrawFlag( itemDef_t *item, int handle ) {
- int i;
- menuDef_t *menu = (menuDef_t*)item;
+qboolean MenuParse_cinematic(itemDef_t *item, int handle)
+{
+ menuDef_t *menu = (menuDef_t *)item;
- if (!PC_Int_Parse(handle, &i)) {
- return qfalse;
- }
- menu->window.ownerDrawFlags |= i;
- return qtrue;
+ if (!PC_String_Parse(handle, &menu->window.cinematicName))
+ return qfalse;
+
+ return qtrue;
}
-qboolean MenuParse_ownerdraw( itemDef_t *item, int handle ) {
- menuDef_t *menu = (menuDef_t*)item;
+qboolean MenuParse_ownerdrawFlag(itemDef_t *item, int handle)
+{
+ int i;
+ menuDef_t *menu = (menuDef_t *)item;
- if (!PC_Int_Parse(handle, &menu->window.ownerDraw)) {
- return qfalse;
- }
- return qtrue;
+ if (!PC_Int_Parse(handle, &i))
+ return qfalse;
+
+ menu->window.ownerDrawFlags |= i;
+ return qtrue;
}
+qboolean MenuParse_ownerdraw(itemDef_t *item, int handle)
+{
+ menuDef_t *menu = (menuDef_t *)item;
+
+ if (!PC_Int_Parse(handle, &menu->window.ownerDraw))
+ return qfalse;
+
+ return qtrue;
+}
// decoration
-qboolean MenuParse_popup( itemDef_t *item, int handle ) {
- menuDef_t *menu = (menuDef_t*)item;
- menu->window.flags |= WINDOW_POPUP;
- return qtrue;
+qboolean MenuParse_popup(itemDef_t *item, int handle)
+{
+ menuDef_t *menu = (menuDef_t *)item;
+ menu->window.flags |= WINDOW_POPUP;
+
+ (void)handle;
+
+ return qtrue;
}
+qboolean MenuParse_outOfBounds(itemDef_t *item, int handle)
+{
+ menuDef_t *menu = (menuDef_t *)item;
+ menu->window.flags |= WINDOW_OOB_CLICK;
-qboolean MenuParse_outOfBounds( itemDef_t *item, int handle ) {
- menuDef_t *menu = (menuDef_t*)item;
+ (void)handle;
- menu->window.flags |= WINDOW_OOB_CLICK;
- return qtrue;
+ return qtrue;
}
-qboolean MenuParse_soundLoop( itemDef_t *item, int handle ) {
- menuDef_t *menu = (menuDef_t*)item;
+qboolean MenuParse_soundLoop(itemDef_t *item, int handle)
+{
+ menuDef_t *menu = (menuDef_t *)item;
- if (!PC_String_Parse(handle, &menu->soundName)) {
- return qfalse;
- }
- return qtrue;
+ if (!PC_String_Parse(handle, &menu->soundName))
+ return qfalse;
+
+ return qtrue;
}
-qboolean MenuParse_fadeClamp( itemDef_t *item, int handle ) {
- menuDef_t *menu = (menuDef_t*)item;
+qboolean MenuParse_fadeClamp(itemDef_t *item, int handle)
+{
+ menuDef_t *menu = (menuDef_t *)item;
- if (!PC_Float_Parse(handle, &menu->fadeClamp)) {
- return qfalse;
- }
- return qtrue;
+ if (!PC_Float_Parse(handle, &menu->fadeClamp))
+ return qfalse;
+
+ return qtrue;
}
-qboolean MenuParse_fadeAmount( itemDef_t *item, int handle ) {
- menuDef_t *menu = (menuDef_t*)item;
+qboolean MenuParse_fadeAmount(itemDef_t *item, int handle)
+{
+ menuDef_t *menu = (menuDef_t *)item;
- if (!PC_Float_Parse(handle, &menu->fadeAmount)) {
- return qfalse;
- }
- return qtrue;
+ if (!PC_Float_Parse(handle, &menu->fadeAmount))
+ return qfalse;
+
+ return qtrue;
}
+qboolean MenuParse_fadeCycle(itemDef_t *item, int handle)
+{
+ menuDef_t *menu = (menuDef_t *)item;
-qboolean MenuParse_fadeCycle( itemDef_t *item, int handle ) {
- menuDef_t *menu = (menuDef_t*)item;
+ if (!PC_Int_Parse(handle, &menu->fadeCycle))
+ return qfalse;
- if (!PC_Int_Parse(handle, &menu->fadeCycle)) {
- return qfalse;
- }
- return qtrue;
-}
-
-
-qboolean MenuParse_itemDef( itemDef_t *item, int handle ) {
- menuDef_t *menu = (menuDef_t*)item;
- if (menu->itemCount < MAX_MENUITEMS) {
- menu->items[menu->itemCount] = UI_Alloc(sizeof(itemDef_t));
- Item_Init(menu->items[menu->itemCount]);
- if (!Item_Parse(handle, menu->items[menu->itemCount])) {
- return qfalse;
- }
- Item_InitControls(menu->items[menu->itemCount]);
- menu->items[menu->itemCount++]->parent = menu;
- }
- return qtrue;
-}
-
-keywordHash_t menuParseKeywords[] = {
- {"font", MenuParse_font, NULL},
- {"name", MenuParse_name, NULL},
- {"fullscreen", MenuParse_fullscreen, NULL},
- {"rect", MenuParse_rect, NULL},
- {"style", MenuParse_style, NULL},
- {"visible", MenuParse_visible, NULL},
- {"onOpen", MenuParse_onOpen, NULL},
- {"onClose", MenuParse_onClose, NULL},
- {"onESC", MenuParse_onESC, NULL},
- {"border", MenuParse_border, NULL},
- {"borderSize", MenuParse_borderSize, NULL},
- {"backcolor", MenuParse_backcolor, NULL},
- {"forecolor", MenuParse_forecolor, NULL},
- {"bordercolor", MenuParse_bordercolor, NULL},
- {"focuscolor", MenuParse_focuscolor, NULL},
- {"disablecolor", MenuParse_disablecolor, NULL},
- {"outlinecolor", MenuParse_outlinecolor, NULL},
- {"background", MenuParse_background, NULL},
- {"ownerdraw", MenuParse_ownerdraw, NULL},
- {"ownerdrawFlag", MenuParse_ownerdrawFlag, NULL},
- {"outOfBoundsClick", MenuParse_outOfBounds, NULL},
- {"soundLoop", MenuParse_soundLoop, NULL},
- {"itemDef", MenuParse_itemDef, NULL},
- {"cinematic", MenuParse_cinematic, NULL},
- {"popup", MenuParse_popup, NULL},
- {"fadeClamp", MenuParse_fadeClamp, NULL},
- {"fadeCycle", MenuParse_fadeCycle, NULL},
- {"fadeAmount", MenuParse_fadeAmount, NULL},
- {NULL, voidFunction2, NULL}
-};
+ return qtrue;
+}
+
+qboolean MenuParse_itemDef(itemDef_t *item, int handle)
+{
+ menuDef_t *menu = (menuDef_t *)item;
+
+ if (menu->itemCount < MAX_MENUITEMS)
+ {
+ menu->items[menu->itemCount] = UI_Alloc(sizeof(itemDef_t));
+ Item_Init(menu->items[menu->itemCount]);
+
+ if (!Item_Parse(handle, menu->items[menu->itemCount]))
+ return qfalse;
+
+ Item_InitControls(menu->items[menu->itemCount]);
+ menu->items[menu->itemCount++]->parent = menu;
+ }
+ else
+ {
+ PC_SourceError(handle, "itemDefs per menu may not exceed %d", MAX_MENUITEMS);
+ return qfalse;
+ }
+
+ return qtrue;
+}
+
+keywordHash_t menuParseKeywords[] = {{"font", MenuParse_font, 0, NULL}, {"name", MenuParse_name, 0, NULL},
+ {"fullscreen", MenuParse_fullscreen, 0, NULL}, {"rect", MenuParse_rect, 0, NULL},
+ {"aspectBias", MenuParse_aspectBias, 0, NULL}, {"style", MenuParse_style, 0, NULL},
+ {"visible", MenuParse_visible, 0, NULL}, {"onOpen", MenuParse_onOpen, 0, NULL},
+ {"onClose", MenuParse_onClose, 0, NULL}, {"onESC", MenuParse_onESC, 0, NULL}, {"border", MenuParse_border, 0, NULL},
+ {"borderSize", MenuParse_borderSize, 0, NULL}, {"backcolor", MenuParse_backcolor, 0, NULL},
+ {"forecolor", MenuParse_forecolor, 0, NULL}, {"bordercolor", MenuParse_bordercolor, 0, NULL},
+ {"focuscolor", MenuParse_focuscolor, 0, NULL}, {"disablecolor", MenuParse_disablecolor, 0, NULL},
+ {"outlinecolor", MenuParse_outlinecolor, 0, NULL}, {"background", MenuParse_background, 0, NULL},
+ {"ownerdraw", MenuParse_ownerdraw, 0, NULL}, {"ownerdrawFlag", MenuParse_ownerdrawFlag, 0, NULL},
+ {"outOfBoundsClick", MenuParse_outOfBounds, 0, NULL}, {"soundLoop", MenuParse_soundLoop, 0, NULL},
+ {"itemDef", MenuParse_itemDef, 0, NULL}, {"cinematic", MenuParse_cinematic, 0, NULL},
+ {"popup", MenuParse_popup, 0, NULL}, {"fadeClamp", MenuParse_fadeClamp, 0, NULL},
+ {"fadeCycle", MenuParse_fadeCycle, 0, NULL}, {"fadeAmount", MenuParse_fadeAmount, 0, NULL},
+ {NULL, voidFunction2, 0, NULL}};
keywordHash_t *menuParseKeywordHash[KEYWORDHASH_SIZE];
@@ -5872,14 +7515,14 @@ keywordHash_t *menuParseKeywordHash[KEYWORDHASH_SIZE];
Menu_SetupKeywordHash
===============
*/
-void Menu_SetupKeywordHash( void )
+void Menu_SetupKeywordHash(void)
{
- int i;
+ int i;
- memset( menuParseKeywordHash, 0, sizeof( menuParseKeywordHash ) );
+ memset(menuParseKeywordHash, 0, sizeof(menuParseKeywordHash));
- for(i = 0; menuParseKeywords[ i ].keyword; i++ )
- KeywordHash_Add( menuParseKeywordHash, &menuParseKeywords[ i ] );
+ for (i = 0; menuParseKeywords[i].keyword; i++)
+ KeywordHash_Add(menuParseKeywordHash, &menuParseKeywords[i]);
}
/*
@@ -5887,39 +7530,46 @@ void Menu_SetupKeywordHash( void )
Menu_Parse
===============
*/
-qboolean Menu_Parse(int handle, menuDef_t *menu) {
- pc_token_t token;
- keywordHash_t *key;
+qboolean Menu_Parse(int handle, menuDef_t *menu)
+{
+ pc_token_t token;
+ keywordHash_t *key;
- if (!trap_Parse_ReadToken(handle, &token))
- return qfalse;
- if (*token.string != '{') {
- return qfalse;
- }
+ if (!trap_Parse_ReadToken(handle, &token))
+ return qfalse;
+
+ if (*token.string != '{')
+ return qfalse;
- while ( 1 ) {
+ while (1)
+ {
+ memset(&token, 0, sizeof(pc_token_t));
- memset(&token, 0, sizeof(pc_token_t));
- if (!trap_Parse_ReadToken(handle, &token)) {
- PC_SourceError(handle, "end of file inside menu\n");
- return qfalse;
- }
+ if (!trap_Parse_ReadToken(handle, &token))
+ {
+ PC_SourceError(handle, "end of file inside menu\n");
+ return qfalse;
+ }
- if (*token.string == '}') {
- return qtrue;
- }
+ if (*token.string == '}')
+ return qtrue;
- key = KeywordHash_Find(menuParseKeywordHash, token.string);
- if (!key) {
- PC_SourceError(handle, "unknown menu keyword %s", token.string);
- continue;
- }
- if ( !key->func((itemDef_t*)menu, handle) ) {
- PC_SourceError(handle, "couldn't parse menu keyword %s", token.string);
- return qfalse;
+ key = KeywordHash_Find(menuParseKeywordHash, token.string);
+
+ if (!key)
+ {
+ PC_SourceError(handle, "unknown menu keyword %s", token.string);
+ continue;
+ }
+
+ if (!key->func((itemDef_t *)menu, handle))
+ {
+ PC_SourceError(handle, "couldn't parse menu keyword %s", token.string);
+ return qfalse;
+ }
}
- }
- return qfalse; // bk001205 - LCC missing return value
+
+ return qfalse;
}
/*
@@ -5927,189 +7577,211 @@ qboolean Menu_Parse(int handle, menuDef_t *menu) {
Menu_New
===============
*/
-void Menu_New(int handle) {
- menuDef_t *menu = &Menus[menuCount];
+void Menu_New(int handle)
+{
+ menuDef_t *menu = &Menus[menuCount];
+
+ if (menuCount < MAX_MENUS)
+ {
+ Menu_Init(menu);
- if (menuCount < MAX_MENUS) {
- Menu_Init(menu);
- if (Menu_Parse(handle, menu)) {
- Menu_PostParse(menu);
- menuCount++;
+ if (Menu_Parse(handle, menu))
+ {
+ Menu_PostParse(menu);
+ menuCount++;
+ }
}
- }
}
-int Menu_Count( void ) {
- return menuCount;
+int Menu_Count(void) { return menuCount; }
+
+void Menu_UpdateAll(void)
+{
+ int i;
+
+ for (i = 0; i < openMenuCount; i++)
+ Menu_Update(menuStack[i]);
}
-void Menu_PaintAll( void ) {
- int i;
+void Menu_PaintAll(void)
+{
+ int i;
- if( g_editingField || g_waitingForKey )
- DC->setCVar( "ui_hideCursor", "1" );
- else
- DC->setCVar( "ui_hideCursor", "0" );
+ if (g_editingField || g_waitingForKey)
+ DC->setCVar("ui_hideCursor", "1");
+ else
+ DC->setCVar("ui_hideCursor", "0");
- if (captureFunc) {
- captureFunc(captureData);
- }
+ if (captureFunc != voidFunction)
+ {
+ if (captureFuncExpiry > 0 && DC->realTime > captureFuncExpiry)
+ UI_RemoveCaptureFunc();
+ else
+ captureFunc(captureData);
+ }
- for (i = 0; i < Menu_Count(); i++) {
- Menu_Paint(&Menus[i], qfalse);
- }
+ for (i = 0; i < openMenuCount; i++)
+ Menu_Paint(menuStack[i], qfalse);
- if (debugMode) {
- vec4_t v = {1, 1, 1, 1};
- DC->drawText(5, 25, .5, v, va("fps: %f", DC->FPS), 0, 0, 0);
- }
+ if (DC->getCVarValue("ui_developer"))
+ {
+ vec4_t v = {1, 1, 1, 1};
+ UI_Text_Paint(5, 25, .5, v, va("fps: %f", DC->FPS), 0, 0, 0);
+ }
}
-void Menu_Reset( void )
-{
- menuCount = 0;
-}
+void Menu_Reset(void) { menuCount = 0; }
-displayContextDef_t *Display_GetContext( void ) {
- return DC;
-}
+displayContextDef_t *Display_GetContext(void) { return DC; }
-void *Display_CaptureItem(int x, int y) {
- int i;
+void *Display_CaptureItem(int x, int y)
+{
+ int i;
- for (i = 0; i < menuCount; i++) {
- // turn off focus each item
- // menu->items[i].window.flags &= ~WINDOW_HASFOCUS;
- if (Rect_ContainsPoint(&Menus[i].window.rect, x, y)) {
- return &Menus[i];
+ for (i = 0; i < menuCount; i++)
+ {
+ if (Rect_ContainsPoint(&Menus[i].window.rect, x, y))
+ return &Menus[i];
}
- }
- return NULL;
-}
+ return NULL;
+}
// FIXME:
-qboolean Display_MouseMove(void *p, int x, int y) {
- int i;
- menuDef_t *menu = p;
-
- if (menu == NULL) {
- menu = Menu_GetFocused();
- if (menu) {
- if (menu->window.flags & WINDOW_POPUP) {
- Menu_HandleMouseMove(menu, x, y);
- return qtrue;
- }
- }
- for (i = 0; i < menuCount; i++) {
- Menu_HandleMouseMove(&Menus[i], x, y);
- }
- } else {
- menu->window.rect.x += x;
- menu->window.rect.y += y;
- Menu_UpdatePosition(menu);
- }
- return qtrue;
+qboolean Display_MouseMove(void *p, float x, float y)
+{
+ int i;
+ menuDef_t *menu = p;
-}
+ if (menu == NULL)
+ {
+ menu = Menu_GetFocused();
+
+ if (menu)
+ {
+ if (menu->window.flags & WINDOW_POPUP)
+ {
+ Menu_HandleMouseMove(menu, x, y);
+ return qtrue;
+ }
+ }
-int Display_CursorType(int x, int y) {
- int i;
- for (i = 0; i < menuCount; i++) {
- rectDef_t r2;
- r2.x = Menus[i].window.rect.x - 3;
- r2.y = Menus[i].window.rect.y - 3;
- r2.w = r2.h = 7;
- if (Rect_ContainsPoint(&r2, x, y)) {
- return CURSOR_SIZER;
+ for (i = 0; i < menuCount; i++)
+ Menu_HandleMouseMove(&Menus[i], x, y);
+ }
+ else
+ {
+ menu->window.rect.x += x;
+ menu->window.rect.y += y;
+ Menu_UpdatePosition(menu);
}
- }
- return CURSOR_ARROW;
+
+ return qtrue;
}
+int Display_CursorType(int x, int y)
+{
+ int i;
-void Display_HandleKey(int key, qboolean down, int x, int y) {
- menuDef_t *menu = Display_CaptureItem(x, y);
- if (menu == NULL) {
- menu = Menu_GetFocused();
- }
- if (menu) {
- Menu_HandleKey(menu, key, down );
- }
-}
+ for (i = 0; i < menuCount; i++)
+ {
+ rectDef_t r2;
+ r2.x = Menus[i].window.rect.x - 3;
+ r2.y = Menus[i].window.rect.y - 3;
+ r2.w = r2.h = 7;
-static void Window_CacheContents(windowDef_t *window) {
- if (window) {
- if (window->cinematicName) {
- int cin = DC->playCinematic(window->cinematicName, 0, 0, 0, 0);
- DC->stopCinematic(cin);
+ if (Rect_ContainsPoint(&r2, x, y))
+ return CURSOR_SIZER;
}
- }
+
+ return CURSOR_ARROW;
}
+void Display_HandleKey(int key, qboolean down, int x, int y)
+{
+ menuDef_t *menu = Display_CaptureItem(x, y);
-static void Item_CacheContents(itemDef_t *item) {
- if (item) {
- Window_CacheContents(&item->window);
- }
+ if (menu == NULL)
+ menu = Menu_GetFocused();
+ if (menu)
+ Menu_HandleKey(menu, key, down);
}
-static void Menu_CacheContents(menuDef_t *menu) {
- if (menu) {
- int i;
- Window_CacheContents(&menu->window);
- for (i = 0; i < menu->itemCount; i++) {
- Item_CacheContents(menu->items[i]);
- }
-
- if (menu->soundName && *menu->soundName) {
- DC->registerSound(menu->soundName, qfalse);
+static void Window_CacheContents(Window *window)
+{
+ if (window)
+ {
+ if (window->cinematicName)
+ {
+ int cin = DC->playCinematic(window->cinematicName, 0, 0, 0, 0);
+ DC->stopCinematic(cin);
+ }
}
- }
-
}
-void Display_CacheAll( void ) {
- int i;
- for (i = 0; i < menuCount; i++) {
- Menu_CacheContents(&Menus[i]);
- }
+static void Item_CacheContents(itemDef_t *item)
+{
+ if (item)
+ Window_CacheContents(&item->window);
}
+static void Menu_CacheContents(menuDef_t *menu)
+{
+ if (menu)
+ {
+ int i;
+ Window_CacheContents(&menu->window);
-static qboolean Menu_OverActiveItem(menuDef_t *menu, float x, float y) {
- if (menu && menu->window.flags & (WINDOW_VISIBLE | WINDOW_FORCED)) {
- if (Rect_ContainsPoint(&menu->window.rect, x, y)) {
- int i;
- for (i = 0; i < menu->itemCount; i++) {
- // turn off focus each item
- // menu->items[i].window.flags &= ~WINDOW_HASFOCUS;
+ for (i = 0; i < menu->itemCount; i++)
+ Item_CacheContents(menu->items[i]);
- if (!(menu->items[i]->window.flags & (WINDOW_VISIBLE | WINDOW_FORCED))) {
- continue;
- }
+ if (menu->soundName && *menu->soundName)
+ DC->registerSound(menu->soundName, qfalse);
+ }
+}
- if (menu->items[i]->window.flags & WINDOW_DECORATION) {
- continue;
- }
+void Display_CacheAll(void)
+{
+ int i;
- if (Rect_ContainsPoint(&menu->items[i]->window.rect, x, y)) {
- itemDef_t *overItem = menu->items[i];
- if (overItem->type == ITEM_TYPE_TEXT && overItem->text) {
- if (Rect_ContainsPoint(Item_CorrectedTextRect(overItem), x, y)) {
- return qtrue;
- } else {
- continue;
+ for (i = 0; i < menuCount; i++)
+ Menu_CacheContents(&Menus[i]);
+}
+
+static qboolean Menu_OverActiveItem(menuDef_t *menu, float x, float y)
+{
+ if (menu && menu->window.flags & (WINDOW_VISIBLE | WINDOW_FORCED))
+ {
+ if (Rect_ContainsPoint(&menu->window.rect, x, y))
+ {
+ int i;
+
+ for (i = 0; i < menu->itemCount; i++)
+ {
+ if (!(menu->items[i]->window.flags & (WINDOW_VISIBLE | WINDOW_FORCED)))
+ continue;
+
+ if (menu->items[i]->window.flags & WINDOW_DECORATION)
+ continue;
+
+ if (Rect_ContainsPoint(&menu->items[i]->window.rect, x, y))
+ {
+ itemDef_t *overItem = menu->items[i];
+
+ if (overItem->type == ITEM_TYPE_TEXT && overItem->text)
+ {
+ if (Rect_ContainsPoint(Item_CorrectedTextRect(overItem), x, y))
+ return qtrue;
+ else
+ continue;
+ }
+ else
+ return qtrue;
+ }
}
- } else {
- return qtrue;
- }
}
- }
-
}
- }
- return qfalse;
-}
+ return qfalse;
+}
diff --git a/src/ui/ui_shared.h b/src/ui/ui_shared.h
index 210899e..470792c 100644
--- a/src/ui/ui_shared.h
+++ b/src/ui/ui_shared.h
@@ -1,13 +1,14 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
-Copyright (C) 2000-2006 Tim Angus
+Copyright (C) 2000-2013 Darklegion Development
+Copyright (C) 2015-2019 GrangerHub
This file is part of Tremulous.
Tremulous 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,
+published by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
Tremulous is distributed in the hope that it will be
@@ -16,20 +17,19 @@ 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 Tremulous; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+along with Tremulous; if not, see <https://www.gnu.org/licenses/>
+
===========================================================================
*/
#ifndef __UI_SHARED_H
#define __UI_SHARED_H
+#include "client/keycodes.h"
+#include "qcommon/q_shared.h"
+#include "renderercommon/tr_types.h"
-#include "../qcommon/q_shared.h"
-#include "../renderer/tr_types.h"
-#include "../client/keycodes.h"
-
-#include "../ui/menudef.h"
+#include "../../assets/ui/menudef.h"
#define MAX_MENUNAME 32
#define MAX_ITEMTEXT 64
@@ -41,118 +41,128 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define MAX_COLOR_RANGES 10
#define MAX_OPEN_MENUS 16
-#define WINDOW_MOUSEOVER 0x00000001 // mouse is over it, non exclusive
-#define WINDOW_HASFOCUS 0x00000002 // has cursor focus, exclusive
-#define WINDOW_VISIBLE 0x00000004 // is visible
-#define WINDOW_GREY 0x00000008 // is visible but grey ( non-active )
-#define WINDOW_DECORATION 0x00000010 // for decoration only, no mouse, keyboard, etc..
-#define WINDOW_FADINGOUT 0x00000020 // fading out, non-active
-#define WINDOW_FADINGIN 0x00000040 // fading in
-#define WINDOW_MOUSEOVERTEXT 0x00000080 // mouse is over it, non exclusive
-#define WINDOW_INTRANSITION 0x00000100 // window is in transition
-#define WINDOW_FORECOLORSET 0x00000200 // forecolor was explicitly set ( used to color alpha images or not )
-#define WINDOW_HORIZONTAL 0x00000400 // for list boxes and sliders, vertical is default this is set of horizontal
-#define WINDOW_LB_LEFTARROW 0x00000800 // mouse is over left/up arrow
-#define WINDOW_LB_RIGHTARROW 0x00001000 // mouse is over right/down arrow
-#define WINDOW_LB_THUMB 0x00002000 // mouse is over thumb
-#define WINDOW_LB_PGUP 0x00004000 // mouse is over page up
-#define WINDOW_LB_PGDN 0x00008000 // mouse is over page down
-#define WINDOW_ORBITING 0x00010000 // item is in orbit
-#define WINDOW_OOB_CLICK 0x00020000 // close on out of bounds click
-#define WINDOW_WRAPPED 0x00040000 // manually wrap text
-#define WINDOW_AUTOWRAPPED 0x00080000 // auto wrap text
-#define WINDOW_FORCED 0x00100000 // forced open
-#define WINDOW_POPUP 0x00200000 // popup
-#define WINDOW_BACKCOLORSET 0x00400000 // backcolor was explicitly set
-#define WINDOW_TIMEDVISIBLE 0x00800000 // visibility timing ( NOT implemented )
-
+#define WINDOW_MOUSEOVER 0x00000001 // mouse is over it, non exclusive
+#define WINDOW_HASFOCUS 0x00000002 // has cursor focus, exclusive
+#define WINDOW_VISIBLE 0x00000004 // is visible
+#define WINDOW_GREY 0x00000008 // is visible but grey ( non-active )
+#define WINDOW_DECORATION 0x00000010 // for decoration only, no mouse, keyboard, etc..
+#define WINDOW_FADINGOUT 0x00000020 // fading out, non-active
+#define WINDOW_FADINGIN 0x00000040 // fading in
+#define WINDOW_MOUSEOVERTEXT 0x00000080 // mouse is over it, non exclusive
+#define WINDOW_INTRANSITION 0x00000100 // window is in transition
+#define WINDOW_FORECOLORSET 0x00000200 // forecolor was explicitly set ( used to color alpha images or not )
+#define WINDOW_HORIZONTAL 0x00000400 // for list boxes and sliders, vertical is default this is set of horizontal
+#define WINDOW_LB_UPARROW 0x00000800 // mouse is over up arrow
+#define WINDOW_LB_DOWNARROW 0x00001000 // mouse is over down arrow
+#define WINDOW_LB_THUMB 0x00002000 // mouse is over thumb
+#define WINDOW_LB_PGUP 0x00004000 // mouse is over page up
+#define WINDOW_LB_PGDN 0x00008000 // mouse is over page down
+#define WINDOW_ORBITING 0x00010000 // item is in orbit
+#define WINDOW_OOB_CLICK 0x00020000 // close on out of bounds click
+#define WINDOW_WRAPPED 0x00080000 // wrap text
+#define WINDOW_FORCED 0x00100000 // forced open
+#define WINDOW_POPUP 0x00200000 // popup
+#define WINDOW_BACKCOLORSET 0x00400000 // backcolor was explicitly set
+#define WINDOW_TIMEDVISIBLE 0x00800000 // visibility timing ( NOT implemented )
// CGAME cursor type bits
-#define CURSOR_NONE 0x00000001
-#define CURSOR_ARROW 0x00000002
-#define CURSOR_SIZER 0x00000004
+#define CURSOR_NONE 0x00000001
+#define CURSOR_ARROW 0x00000002
+#define CURSOR_SIZER 0x00000004
#ifdef CGAME
-#define STRING_POOL_SIZE 128*1024
+#define STRING_POOL_SIZE 128 * 1024
#else
-#define STRING_POOL_SIZE 384*1024
+#define STRING_POOL_SIZE 384 * 1024
#endif
#define MAX_STRING_HANDLES 4096
#define MAX_SCRIPT_ARGS 12
#define MAX_EDITFIELD 256
+#define ITEM_VALUE_OFFSET 8
-#define ART_FX_BASE "menu/art/fx_base"
-#define ART_FX_BLUE "menu/art/fx_blue"
-#define ART_FX_CYAN "menu/art/fx_cyan"
-#define ART_FX_GREEN "menu/art/fx_grn"
-#define ART_FX_RED "menu/art/fx_red"
-#define ART_FX_TEAL "menu/art/fx_teal"
-#define ART_FX_WHITE "menu/art/fx_white"
-#define ART_FX_YELLOW "menu/art/fx_yel"
+#define ART_FX_BASE "menu/art/fx_base"
+#define ART_FX_BLUE "menu/art/fx_blue"
+#define ART_FX_CYAN "menu/art/fx_cyan"
+#define ART_FX_GREEN "menu/art/fx_grn"
+#define ART_FX_RED "menu/art/fx_red"
+#define ART_FX_TEAL "menu/art/fx_teal"
+#define ART_FX_WHITE "menu/art/fx_white"
+#define ART_FX_YELLOW "menu/art/fx_yel"
#define ASSET_GRADIENTBAR "ui/assets/gradientbar2.tga"
-#define ASSET_SCROLLBAR "ui/assets/scrollbar.tga"
-#define ASSET_SCROLLBAR_ARROWDOWN "ui/assets/scrollbar_arrow_dwn_a.tga"
-#define ASSET_SCROLLBAR_ARROWUP "ui/assets/scrollbar_arrow_up_a.tga"
-#define ASSET_SCROLLBAR_ARROWLEFT "ui/assets/scrollbar_arrow_left.tga"
-#define ASSET_SCROLLBAR_ARROWRIGHT "ui/assets/scrollbar_arrow_right.tga"
-#define ASSET_SCROLL_THUMB "ui/assets/scrollbar_thumb.tga"
-#define ASSET_SLIDER_BAR "ui/assets/slider2.tga"
-#define ASSET_SLIDER_THUMB "ui/assets/sliderbutt_1.tga"
-#define SCROLLBAR_SIZE 16.0
-#define SLIDER_WIDTH 96.0
-#define SLIDER_HEIGHT 16.0
-#define SLIDER_THUMB_WIDTH 12.0
-#define SLIDER_THUMB_HEIGHT 20.0
-#define NUM_CROSSHAIRS 10
+#define ASSET_SCROLLBAR "ui/assets/scrollbar.tga"
+#define ASSET_SCROLLBAR_ARROWDOWN "ui/assets/scrollbar_arrow_dwn_a.tga"
+#define ASSET_SCROLLBAR_ARROWUP "ui/assets/scrollbar_arrow_up_a.tga"
+#define ASSET_SCROLLBAR_ARROWLEFT "ui/assets/scrollbar_arrow_left.tga"
+#define ASSET_SCROLLBAR_ARROWRIGHT "ui/assets/scrollbar_arrow_right.tga"
+#define ASSET_SCROLL_THUMB "ui/assets/scrollbar_thumb.tga"
+#define ASSET_SLIDER_BAR "ui/assets/slider2.tga"
+#define ASSET_SLIDER_THUMB "ui/assets/sliderbutt_1.tga"
+
+#define SCROLLBAR_ARROW_SIZE 16.0f
+#define SCROLLBAR_ARROW_WIDTH (SCROLLBAR_ARROW_SIZE * DC->aspectScale)
+#define SCROLLBAR_ARROW_HEIGHT SCROLLBAR_ARROW_SIZE
+#define SCROLLBAR_SLIDER_X(_item) \
+ (_item->window.rect.x + _item->window.rect.w - SCROLLBAR_ARROW_WIDTH - DC->aspectScale)
+#define SCROLLBAR_SLIDER_Y(_item) (SCROLLBAR_Y(_item) + SCROLLBAR_ARROW_HEIGHT)
+#define SCROLLBAR_SLIDER_HEIGHT(_item) (_item->window.rect.h - (SCROLLBAR_ARROW_HEIGHT * 2.0f) - 2.0f)
+#define SCROLLBAR_X(_item) (_item->window.rect.x + DC->aspectScale)
+#define SCROLLBAR_Y(_item) (_item->window.rect.y + 1.0f)
+#define SCROLLBAR_W(_item) (SCROLLBAR_SLIDER_X(_item) - SCROLLBAR_X(_item))
+#define SCROLLBAR_H(_item) (_item->window.rect.h - 2.0f)
+
+#define SLIDER_WIDTH (96.0f * DC->aspectScale)
+#define SLIDER_HEIGHT 16.0f
+#define SLIDER_THUMB_WIDTH (12.0f * DC->aspectScale)
+#define SLIDER_THUMB_HEIGHT 20.0f
+#define NUM_CROSSHAIRS 10
typedef struct {
- const char *command;
- const char *args[MAX_SCRIPT_ARGS];
+ const char *command;
+ const char *args[MAX_SCRIPT_ARGS];
} scriptDef_t;
-
typedef struct {
- float x; // horiz position
- float y; // vert position
- float w; // width
- float h; // height;
+ float x; // horiz position
+ float y; // vert position
+ float w; // width
+ float h; // height;
} rectDef_t;
typedef rectDef_t Rectangle;
// FIXME: do something to separate text vs window stuff
+
typedef struct {
- Rectangle rect; // client coord rectangle
- Rectangle rectClient; // screen coord rectangle
- const char *name; //
- const char *group; // if it belongs to a group
- const char *cinematicName; // cinematic name
- int cinematic; // cinematic handle
- int style; //
- int border; //
- int ownerDraw; // ownerDraw style
- int ownerDrawFlags; // show flags for ownerdraw items
- float borderSize; //
- int flags; // visible, focus, mouseover, cursor
- Rectangle rectEffects; // for various effects
- Rectangle rectEffects2; // for various effects
- int offsetTime; // time based value for various effects
- int nextTime; // time next effect should cycle
- vec4_t foreColor; // text color
- vec4_t backColor; // border color
- vec4_t borderColor; // border color
- vec4_t outlineColor; // border color
- qhandle_t background; // background asset
-} windowDef_t;
-
-typedef windowDef_t Window;
+ Rectangle rect; // client coord rectangle
+ int aspectBias; // direction in which to aspect compensate
+ Rectangle rectClient; // screen coord rectangle
+ const char *name; //
+ const char *group; // if it belongs to a group
+ const char *cinematicName; // cinematic name
+ int cinematic; // cinematic handle
+ int style; //
+ int border; //
+ int ownerDraw; // ownerDraw style
+ int ownerDrawFlags; // show flags for ownerdraw items
+ float borderSize; //
+ int flags; // visible, focus, mouseover, cursor
+ Rectangle rectEffects; // for various effects
+ Rectangle rectEffects2; // for various effects
+ int offsetTime; // time based value for various effects
+ int nextTime; // time next effect should cycle
+ vec4_t foreColor; // text color
+ vec4_t backColor; // border color
+ vec4_t borderColor; // border color
+ vec4_t outlineColor; // border color
+ qhandle_t background; // background asset
+} Window;
typedef struct {
- vec4_t color;
- float low;
- float high;
+ vec4_t color;
+ float low;
+ float high;
} colorRangeDef_t;
// FIXME: combine flags into bitfields to save space
@@ -168,231 +178,259 @@ typedef struct {
#define MAX_LB_COLUMNS 16
typedef struct columnInfo_s {
- int pos;
- int width;
- int maxChars;
- int align;
+ int pos;
+ int width;
+ int align;
} columnInfo_t;
typedef struct listBoxDef_s {
- int startPos;
- int endPos;
- int drawPadding;
- int cursorPos;
- float elementWidth;
- float elementHeight;
- int elementStyle;
- int numColumns;
- columnInfo_t columnInfo[MAX_LB_COLUMNS];
- const char *doubleClick;
- qboolean notselectable;
+ int startPos;
+ int endPos;
+ int cursorPos;
+
+ float elementWidth;
+ float elementHeight;
+ int elementStyle;
+ int dropItems;
+
+ int numColumns;
+ columnInfo_t columnInfo[MAX_LB_COLUMNS];
+
+ const char *doubleClick;
+
+ qboolean notselectable;
+ qboolean noscrollbar;
+
+ qboolean resetonfeederchange;
+ int lastFeederCount;
} listBoxDef_t;
+typedef struct cycleDef_s {
+ int cursorPos;
+} cycleDef_t;
+
typedef struct editFieldDef_s {
- float minVal; // edit field limits
- float maxVal; //
- float defVal; //
- float range; //
- int maxChars; // for edit fields
- int maxPaintChars; // for edit fields
- int paintOffset; //
+ float minVal; // edit field limits
+ float maxVal; //
+ float defVal; //
+ float range; //
+ int maxChars; // for edit fields
+ int maxPaintChars; // for edit fields
+ int maxFieldWidth; // for edit fields
+ int paintOffset; //
} editFieldDef_t;
#define MAX_MULTI_CVARS 32
typedef struct multiDef_s {
- const char *cvarList[MAX_MULTI_CVARS];
- const char *cvarStr[MAX_MULTI_CVARS];
- float cvarValue[MAX_MULTI_CVARS];
- int count;
- qboolean strDef;
+ const char *cvarList[MAX_MULTI_CVARS];
+ const char *cvarStr[MAX_MULTI_CVARS];
+ float cvarValue[MAX_MULTI_CVARS];
+ int count;
+ qboolean strDef;
} multiDef_t;
typedef struct modelDef_s {
- int angle;
- vec3_t origin;
- float fov_x;
- float fov_y;
- int rotationSpeed;
+ int angle;
+ vec3_t origin;
+ float fov_x;
+ float fov_y;
+ int rotationSpeed;
} modelDef_t;
-#define CVAR_ENABLE 0x00000001
-#define CVAR_DISABLE 0x00000002
-#define CVAR_SHOW 0x00000004
-#define CVAR_HIDE 0x00000008
+#define CVAR_ENABLE 0x00000001
+#define CVAR_DISABLE 0x00000002
+#define CVAR_SHOW 0x00000004
+#define CVAR_HIDE 0x00000008
+
+typedef enum { TYPE_ANY = -1, TYPE_NONE, TYPE_LIST, TYPE_EDIT, TYPE_MULTI, TYPE_COMBO, TYPE_MODEL } itemDataType_t;
typedef struct itemDef_s {
- Window window; // common positional, border, style, layout info
- Rectangle textRect; // rectangle the text ( if any ) consumes
- int type; // text, button, radiobutton, checkbox, textfield, listbox, combo
- int alignment; // left center right
- int textalignment; // ( optional ) alignment for text within rect based on text width
- float textalignx; // ( optional ) text alignment x coord
- float textaligny; // ( optional ) text alignment x coord
- float textscale; // scale percentage from 72pts
- int textStyle; // ( optional ) style, normal and shadowed are it for now
- const char *text; // display text
- void *parent; // menu owner
- qhandle_t asset; // handle to asset
- const char *mouseEnterText; // mouse enter script
- const char *mouseExitText; // mouse exit script
- const char *mouseEnter; // mouse enter script
- const char *mouseExit; // mouse exit script
- const char *action; // select script
- const char *onFocus; // select script
- const char *leaveFocus; // select script
- const char *onTextEntry; // called when text entered
- const char *cvar; // associated cvar
- const char *cvarTest; // associated cvar for enable actions
- const char *enableCvar; // enable, disable, show, or hide based on value, this can contain a list
- int cvarFlags; // what type of action to take on cvarenables
- sfxHandle_t focusSound;
- int numColors; // number of color ranges
- colorRangeDef_t colorRanges[MAX_COLOR_RANGES];
- float special; // used for feeder id's etc.. diff per type
- int cursorPos; // cursor position in characters
- void *typeData; // type specific data ptr's
+ Window window; // common positional, border, style, layout info
+ Rectangle textRect; // rectangle the text ( if any ) consumes
+ int type; // text, button, radiobutton, checkbox, textfield, listbox, combo
+ int alignment; // left center right
+ int textalignment; // ( optional ) alignment for text within rect based on text width
+ int textvalignment; // ( optional ) alignment for text within rect based on text width
+ float textalignx; // ( optional ) text alignment x coord
+ float textaligny; // ( optional ) text alignment x coord
+ float textscale; // scale percentage from 72pts
+ int textStyle; // ( optional ) style, normal and shadowed are it for now
+ const char *text; // display text
+ void *parent; // menu owner
+ qhandle_t asset; // handle to asset
+ const char *mouseEnterText; // mouse enter script
+ const char *mouseExitText; // mouse exit script
+ const char *mouseEnter; // mouse enter script
+ const char *mouseExit; // mouse exit script
+ const char *action; // select script
+ const char *onFocus; // select script
+ const char *leaveFocus; // select script
+ const char *onTextEntry; // called when text entered
+ const char *onCharEntry; // called when text entered
+ const char *cvar; // associated cvar
+ const char *cvarTest; // associated cvar for enable actions
+ const char *enableCvar; // enable, disable, show, or hide based on value, this can contain a list
+ int cvarFlags; // what type of action to take on cvarenables
+ sfxHandle_t focusSound;
+ int numColors; // number of color ranges
+ colorRangeDef_t colorRanges[MAX_COLOR_RANGES];
+ int feederID; // where to get data for this item
+ int cursorPos; // cursor position in characters
+ union {
+ void *data;
+ listBoxDef_t *list;
+ editFieldDef_t *edit;
+ multiDef_t *multi;
+ cycleDef_t *cycle;
+ modelDef_t *model;
+ } typeData; // type specific data pointers
} itemDef_t;
typedef struct {
- Window window;
- const char *font; // font
- qboolean fullScreen; // covers entire screen
- int itemCount; // number of items;
- int fontIndex; //
- int cursorItem; // which item as the cursor
- int fadeCycle; //
- float fadeClamp; //
- float fadeAmount; //
- const char *onOpen; // run when the menu is first opened
- const char *onClose; // run when the menu is closed
- const char *onESC; // run when the menu is closed
- const char *soundName; // background loop sound for menu
-
- vec4_t focusColor; // focus color for items
- vec4_t disableColor; // focus color for items
- itemDef_t *items[MAX_MENUITEMS]; // items this menu contains
+ Window window;
+ const char *font; // font
+ qboolean fullScreen; // covers entire screen
+ int itemCount; // number of items;
+ int fontIndex; //
+ int cursorItem; // which item as the cursor
+ int fadeCycle; //
+ float fadeClamp; //
+ float fadeAmount; //
+ const char *onOpen; // run when the menu is first opened
+ const char *onClose; // run when the menu is closed
+ const char *onESC; // run when the menu is closed
+ const char *soundName; // background loop sound for menu
+
+ vec4_t focusColor; // focus color for items
+ vec4_t disableColor; // focus color for items
+ itemDef_t *items[MAX_MENUITEMS]; // items this menu contains
} menuDef_t;
typedef struct {
- const char *fontStr;
- const char *cursorStr;
- const char *gradientStr;
- fontInfo_t textFont;
- fontInfo_t smallFont;
- fontInfo_t bigFont;
- qhandle_t cursor;
- qhandle_t gradientBar;
- qhandle_t scrollBarArrowUp;
- qhandle_t scrollBarArrowDown;
- qhandle_t scrollBarArrowLeft;
- qhandle_t scrollBarArrowRight;
- qhandle_t scrollBar;
- qhandle_t scrollBarThumb;
- qhandle_t buttonMiddle;
- qhandle_t buttonInside;
- qhandle_t solidBox;
- qhandle_t sliderBar;
- qhandle_t sliderThumb;
- sfxHandle_t menuEnterSound;
- sfxHandle_t menuExitSound;
- sfxHandle_t menuBuzzSound;
- sfxHandle_t itemFocusSound;
- float fadeClamp;
- int fadeCycle;
- float fadeAmount;
- float shadowX;
- float shadowY;
- vec4_t shadowColor;
- float shadowFadeClamp;
- qboolean fontRegistered;
-
+ const char *fontStr;
+ const char *cursorStr;
+ const char *gradientStr;
+ fontInfo_t textFont;
+ fontInfo_t smallFont;
+ fontInfo_t bigFont;
+ qhandle_t cursor;
+ qhandle_t gradientBar;
+ qhandle_t scrollBarArrowUp;
+ qhandle_t scrollBarArrowDown;
+ qhandle_t scrollBarArrowLeft;
+ qhandle_t scrollBarArrowRight;
+ qhandle_t scrollBar;
+ qhandle_t scrollBarThumb;
+ qhandle_t buttonMiddle;
+ qhandle_t buttonInside;
+ qhandle_t solidBox;
+ qhandle_t sliderBar;
+ qhandle_t sliderThumb;
+ sfxHandle_t menuEnterSound;
+ sfxHandle_t menuExitSound;
+ sfxHandle_t menuBuzzSound;
+ sfxHandle_t itemFocusSound;
+ float fadeClamp;
+ int fadeCycle;
+ float fadeAmount;
+ float shadowX;
+ float shadowY;
+ vec4_t shadowColor;
+ float shadowFadeClamp;
+ qboolean fontRegistered;
+ emoticon_t emoticons[MAX_EMOTICONS];
+ int emoticonCount;
} cachedAssets_t;
typedef struct {
- const char *name;
- void (*handler) (itemDef_t *item, char** args);
+ const char *name;
+ void (*handler)(itemDef_t *item, char **args);
} commandDef_t;
typedef struct {
- qhandle_t (*registerShaderNoMip) (const char *p);
- void (*setColor) (const vec4_t v);
- void (*drawHandlePic) (float x, float y, float w, float h, qhandle_t asset);
- void (*drawStretchPic) (float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t hShader );
- void (*drawText) (float x, float y, float scale, vec4_t color, const char *text, float adjust, int limit, int style );
- int (*textWidth) (const char *text, float scale, int limit);
- int (*textHeight) (const char *text, float scale, int limit);
- qhandle_t (*registerModel) (const char *p);
- void (*modelBounds) (qhandle_t model, vec3_t min, vec3_t max);
- void (*fillRect) ( float x, float y, float w, float h, const vec4_t color);
- void (*drawRect) ( float x, float y, float w, float h, float size, const vec4_t color);
- void (*drawSides) (float x, float y, float w, float h, float size);
- void (*drawTopBottom) (float x, float y, float w, float h, float size);
- void (*clearScene) (void);
- void (*addRefEntityToScene) (const refEntity_t *re );
- void (*renderScene) ( const refdef_t *fd );
- void (*registerFont) (const char *pFontname, int pointSize, fontInfo_t *font);
- void (*ownerDrawItem) (float x, float y, float w, float h, float text_x, float text_y, int ownerDraw, int ownerDrawFlags, int align, float special, float scale, vec4_t color, qhandle_t shader, int textStyle);
- float (*getValue) (int ownerDraw);
- qboolean (*ownerDrawVisible) (int flags);
- void (*runScript)(char **p);
- void (*getTeamColor)(vec4_t *color);
- void (*getCVarString)(const char *cvar, char *buffer, int bufsize);
- float (*getCVarValue)(const char *cvar);
- void (*setCVar)(const char *cvar, const char *value);
- void (*drawTextWithCursor)(float x, float y, float scale, vec4_t color, const char *text, int cursorPos, char cursor, int limit, int style);
- void (*setOverstrikeMode)(qboolean b);
- qboolean (*getOverstrikeMode)( void );
- void (*startLocalSound)( sfxHandle_t sfx, int channelNum );
- qboolean (*ownerDrawHandleKey)(int ownerDraw, int flags, float *special, int key);
- int (*feederCount)(float feederID);
- const char *(*feederItemText)(float feederID, int index, int column, qhandle_t *handle);
- qhandle_t (*feederItemImage)(float feederID, int index);
- void (*feederSelection)(float feederID, int index);
- void (*keynumToStringBuf)( int keynum, char *buf, int buflen );
- void (*getBindingBuf)( int keynum, char *buf, int buflen );
- void (*setBinding)( int keynum, const char *binding );
- void (*executeText)(int exec_when, const char *text );
- void (*Error)(int level, const char *error, ...);
- void (*Print)(const char *msg, ...);
- void (*Pause)(qboolean b);
- int (*ownerDrawWidth)(int ownerDraw, float scale);
- sfxHandle_t (*registerSound)(const char *name, qboolean compressed);
- void (*startBackgroundTrack)( const char *intro, const char *loop);
- void (*stopBackgroundTrack)( void );
- int (*playCinematic)(const char *name, float x, float y, float w, float h);
- void (*stopCinematic)(int handle);
- void (*drawCinematic)(int handle, float x, float y, float w, float h);
- void (*runCinematicFrame)(int handle);
-
- float yscale;
- float xscale;
- float bias;
- int realTime;
- int frameTime;
- int cursorx;
- int cursory;
- qboolean debug;
-
- cachedAssets_t Assets;
-
- glconfig_t glconfig;
- qhandle_t whiteShader;
- qhandle_t gradientImage;
- qhandle_t cursor;
- float FPS;
+ qhandle_t (*registerShaderNoMip)(const char *p);
+ void (*setColor)(const vec4_t v);
+ void (*drawHandlePic)(float x, float y, float w, float h, qhandle_t asset);
+ void (*drawStretchPic)(
+ float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t hShader);
+ qhandle_t (*registerModel)(const char *p);
+ void (*modelBounds)(qhandle_t model, vec3_t min, vec3_t max);
+ void (*fillRect)(float x, float y, float w, float h, const vec4_t color);
+ void (*drawRect)(float x, float y, float w, float h, float size, const vec4_t color);
+ void (*drawSides)(float x, float y, float w, float h, float size);
+ void (*drawTopBottom)(float x, float y, float w, float h, float size);
+ void (*clearScene)(void);
+ void (*addRefEntityToScene)(const refEntity_t *re);
+ void (*renderScene)(const refdef_t *fd);
+ void (*registerFont)(const char *pFontname, int pointSize, fontInfo_t *font);
+ void (*ownerDrawItem)(float x, float y, float w, float h, float text_x, float text_y, int ownerDraw,
+ int ownerDrawFlags, int align, int textalign, int textvalign, float borderSize, float scale, vec4_t foreColor,
+ vec4_t backColor, qhandle_t shader, int textStyle);
+ float (*getValue)(int ownerDraw);
+ qboolean (*ownerDrawVisible)(int flags);
+ void (*runScript)(char **p);
+ void (*getCVarString)(const char *cvar, char *buffer, int bufsize);
+ float (*getCVarValue)(const char *cvar);
+ void (*setCVar)(const char *cvar, const char *value);
+ void (*drawTextWithCursor)(float x, float y, float scale, vec4_t color, const char *text, int cursorPos,
+ char cursor, int limit, int style);
+ void (*setOverstrikeMode)(qboolean b);
+ qboolean (*getOverstrikeMode)(void);
+ void (*startLocalSound)(sfxHandle_t sfx, int channelNum);
+ qboolean (*ownerDrawHandleKey)(int ownerDraw, int key);
+ int (*feederCount)(int feederID);
+ const char *(*feederItemText)(int feederID, int index, int column, qhandle_t *handle);
+ qhandle_t (*feederItemImage)(int feederID, int index);
+ void (*feederSelection)(int feederID, int index);
+ int (*feederInitialise)(int feederID);
+ void (*keynumToStringBuf)(int keynum, char *buf, int buflen);
+ void (*getBindingBuf)(int keynum, char *buf, int buflen);
+ void (*setBinding)(int keynum, const char *binding);
+ void (*executeText)(int exec_when, const char *text);
+ void (*Error)(int level, const char *error, ...) __attribute__((noreturn, format(printf, 2, 3)));
+ void (*Print)(const char *msg, ...) __attribute__((format(printf, 1, 2)));
+ void (*Pause)(qboolean b);
+ int (*ownerDrawWidth)(int ownerDraw, float scale);
+ const char *(*ownerDrawText)(int ownerDraw);
+ sfxHandle_t (*registerSound)(const char *name, qboolean compressed);
+ void (*startBackgroundTrack)(const char *intro, const char *loop);
+ void (*stopBackgroundTrack)(void);
+ int (*playCinematic)(const char *name, float x, float y, float w, float h);
+ void (*stopCinematic)(int handle);
+ void (*drawCinematic)(int handle, float x, float y, float w, float h);
+ void (*runCinematicFrame)(int handle);
+
+ float yscale;
+ float xscale;
+ float aspectScale;
+ int realTime;
+ int frameTime;
+ float cursorx;
+ float cursory;
+ float smallFontScale;
+ float bigFontScale;
+ qboolean debug;
+
+ cachedAssets_t Assets;
+
+ glconfig_t glconfig;
+ qhandle_t whiteShader;
+ qhandle_t gradientImage;
+ qhandle_t cursor;
+ float FPS;
} displayContextDef_t;
const char *String_Alloc(const char *p);
-void String_Init( void );
-void String_Report( void );
+void String_Init(void);
+void String_Report(void);
void Init_Display(displayContextDef_t *dc);
-void Display_ExpandMacros(char * buff);
+void Display_ExpandMacros(char *buff);
void Menu_Init(menuDef_t *menu);
void Item_Init(itemDef_t *item);
void Menu_PostParse(menuDef_t *menu);
-menuDef_t *Menu_GetFocused( void );
+menuDef_t *Menu_GetFocused(void);
void Menu_HandleKey(menuDef_t *menu, int key, qboolean down);
void Menu_HandleMouseMove(menuDef_t *menu, float x, float y);
void Menu_ScrollFeeder(menuDef_t *menu, int feeder, qboolean down);
@@ -408,48 +446,69 @@ qboolean PC_Int_Parse(int handle, int *i);
qboolean PC_Rect_Parse(int handle, rectDef_t *r);
qboolean PC_String_Parse(int handle, const char **out);
qboolean PC_Script_Parse(int handle, const char **out);
-int Menu_Count( void );
+int Menu_Count(void);
void Menu_New(int handle);
-void Menu_PaintAll( void );
+void Menu_UpdateAll(void);
+void Menu_PaintAll(void);
menuDef_t *Menus_ActivateByName(const char *p);
-void Menu_Reset( void );
-qboolean Menus_AnyFullScreenVisible( void );
-void Menus_Activate(menuDef_t *menu);
+menuDef_t *Menus_ReplaceActiveByName(const char *p);
+void Menu_Reset(void);
+qboolean Menus_AnyFullScreenVisible(void);
+void Menus_Activate(menuDef_t *menu);
+qboolean Menus_ReplaceActive(menuDef_t *menu);
-displayContextDef_t *Display_GetContext( void );
+displayContextDef_t *Display_GetContext(void);
void *Display_CaptureItem(int x, int y);
-qboolean Display_MouseMove(void *p, int x, int y);
+qboolean Display_MouseMove(void *p, float x, float y);
int Display_CursorType(int x, int y);
-qboolean Display_KeyBindPending( void );
-void Menus_OpenByName(const char *p);
+qboolean Display_KeyBindPending(void);
menuDef_t *Menus_FindByName(const char *p);
-void Menus_ShowByName(const char *p);
void Menus_CloseByName(const char *p);
void Display_HandleKey(int key, qboolean down, int x, int y);
void LerpColor(vec4_t a, vec4_t b, vec4_t c, float t);
-void Menus_CloseAll( void );
+void Menus_CloseAll(void);
+void Menu_Update(menuDef_t *menu);
void Menu_Paint(menuDef_t *menu, qboolean forcePaint);
void Menu_SetFeederSelection(menuDef_t *menu, int feeder, int index, const char *name);
-void Display_CacheAll( void );
-
-void *UI_Alloc( int size );
-void UI_InitMemory( void );
-qboolean UI_OutOfMemory( void );
+void Display_CacheAll(void);
-void Controls_GetConfig( void );
-void Controls_SetConfig(qboolean restart);
-void Controls_SetDefaults( void );
+typedef void(CaptureFunc)(void *p);
-//for cg_draw.c
-void Item_Text_AutoWrapped_Paint( itemDef_t *item );
+void UI_InstallCaptureFunc(CaptureFunc *f, void *data, int timeout);
+void UI_RemoveCaptureFunc(void);
-int trap_Parse_AddGlobalDefine( char *define );
-int trap_Parse_LoadSource( const char *filename );
-int trap_Parse_FreeSource( int handle );
-int trap_Parse_ReadToken( int handle, pc_token_t *pc_token );
-int trap_Parse_SourceFileAndLine( int handle, char *filename, int *line );
+void *UI_Alloc(int size);
+void UI_InitMemory(void);
+qboolean UI_OutOfMemory(void);
-void BindingFromName( const char *cvar );
-extern char g_nameBind1[ 32 ];
-extern char g_nameBind2[ 32 ];
+void Controls_GetConfig(void);
+void Controls_SetConfig(qboolean restart);
+void Controls_SetDefaults(void);
+
+void trap_R_SetClipRegion(const float *region);
+
+// for cg_draw.c
+void Item_Text_Wrapped_Paint(itemDef_t *item);
+const char *Item_Text_Wrap(const char *text, float scale, float width);
+void UI_DrawTextBlock(rectDef_t *rect, float text_x, float text_y, vec4_t color, float scale, int textalign,
+ int textvalign, int textStyle, const char *text);
+void UI_Text_Paint(float x, float y, float scale, vec4_t color, const char *text, float adjust, int limit, int style);
+void UI_Text_Paint_Limit(
+ float *maxX, float x, float y, float scale, vec4_t color, const char *text, float adjust, int limit);
+float UI_Text_Width(const char *text, float scale);
+float UI_Text_Height(const char *text, float scale);
+float UI_Text_EmWidth(float scale);
+float UI_Text_EmHeight(float scale);
+qboolean UI_Text_IsEmoticon(const char *s, qboolean *escaped, int *length, qhandle_t *h, int *width);
+void UI_EscapeEmoticons(char *dest, const char *src, int destsize);
+
+int trap_Parse_AddGlobalDefine(char *define);
+int trap_Parse_LoadSource(const char *filename);
+int trap_Parse_FreeSource(int handle);
+int trap_Parse_ReadToken(int handle, pc_token_t *pc_token);
+int trap_Parse_SourceFileAndLine(int handle, char *filename, int *line);
+
+void BindingFromName(const char *cvar);
+extern char g_nameBind1[32];
+extern char g_nameBind2[32];
#endif
diff --git a/src/ui/ui_syscalls.asm b/src/ui/ui_syscalls.asm
index 1e797a9..b566800 100644
--- a/src/ui/ui_syscalls.asm
+++ b/src/ui/ui_syscalls.asm
@@ -42,7 +42,7 @@ equ trap_Key_GetOverstrikeMode -39
equ trap_Key_SetOverstrikeMode -40
equ trap_Key_ClearStates -41
equ trap_Key_GetCatcher -42
-equ trap_Key_SetCatcher -43
+equ trap_Key_SetCatcher -43
equ trap_GetClipboardData -44
equ trap_GetGlconfig -45
equ trap_GetClientState -46
@@ -99,4 +99,3 @@ equ atan2 -106
equ sqrt -107
equ floor -108
equ ceil -109
-
diff --git a/src/ui/ui_syscalls.c b/src/ui/ui_syscalls.c
index a27e573..11bd93a 100644
--- a/src/ui/ui_syscalls.c
+++ b/src/ui/ui_syscalls.c
@@ -1,13 +1,14 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
-Copyright (C) 2000-2006 Tim Angus
+Copyright (C) 2000-2013 Darklegion Development
+Copyright (C) 2015-2019 GrangerHub
This file is part of Tremulous.
Tremulous 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,
+published by the Free Software Foundation; either version 3 of the License,
or (at your option) any later version.
Tremulous is distributed in the hope that it will be
@@ -16,8 +17,8 @@ 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 Tremulous; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+along with Tremulous; if not, see <https://www.gnu.org/licenses/>
+
===========================================================================
*/
@@ -26,362 +27,284 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// this file is only included when building a dll
// syscalls.asm is included instead when building a qvm
-static intptr_t (QDECL *syscall)( intptr_t arg, ... ) = (intptr_t (QDECL *)( intptr_t, ...))-1;
+static intptr_t(QDECL *syscall)(intptr_t arg, ...) = (intptr_t(QDECL *)(intptr_t, ...)) - 1;
-Q_EXPORT void dllEntry( intptr_t (QDECL *syscallptr)( intptr_t arg,... ) ) {
- syscall = syscallptr;
-}
+Q_EXPORT void dllEntry(intptr_t(QDECL *syscallptr)(intptr_t arg, ...)) { syscall = syscallptr; }
-int PASSFLOAT( float x ) {
- float floatTemp;
- floatTemp = x;
- return *(int *)&floatTemp;
+int PASSFLOAT(float x)
+{
+ floatint_t fi;
+ fi.f = x;
+ return fi.i;
}
-void trap_Print( const char *string ) {
- syscall( UI_PRINT, string );
-}
+void trap_Print(const char *string) { syscall(UI_PRINT, string); }
-void trap_Error( const char *string ) {
- syscall( UI_ERROR, string );
+void trap_Error(const char *string)
+{
+ syscall(UI_ERROR, string);
+ // shut up GCC warning about returning functions, because we know better
+ exit(1);
}
-int trap_Milliseconds( void ) {
- return syscall( UI_MILLISECONDS );
-}
+int trap_Milliseconds(void) { return syscall(UI_MILLISECONDS); }
-void trap_Cvar_Register( vmCvar_t *cvar, const char *var_name, const char *value, int flags ) {
- syscall( UI_CVAR_REGISTER, cvar, var_name, value, flags );
+void trap_Cvar_Register(vmCvar_t *cvar, const char *var_name, const char *value, int flags)
+{
+ syscall(UI_CVAR_REGISTER, cvar, var_name, value, flags);
}
-void trap_Cvar_Update( vmCvar_t *cvar ) {
- syscall( UI_CVAR_UPDATE, cvar );
-}
+void trap_Cvar_Update(vmCvar_t *cvar) { syscall(UI_CVAR_UPDATE, cvar); }
-void trap_Cvar_Set( const char *var_name, const char *value ) {
- syscall( UI_CVAR_SET, var_name, value );
-}
+void trap_Cvar_Set(const char *var_name, const char *value) { syscall(UI_CVAR_SET, var_name, value); }
-float trap_Cvar_VariableValue( const char *var_name ) {
- int temp;
- temp = syscall( UI_CVAR_VARIABLEVALUE, var_name );
- return (*(float*)&temp);
+float trap_Cvar_VariableValue(const char *var_name)
+{
+ floatint_t fi;
+ fi.i = syscall(UI_CVAR_VARIABLEVALUE, var_name);
+ return fi.f;
}
-void trap_Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize ) {
- syscall( UI_CVAR_VARIABLESTRINGBUFFER, var_name, buffer, bufsize );
+void trap_Cvar_VariableStringBuffer(const char *var_name, char *buffer, int bufsize)
+{
+ syscall(UI_CVAR_VARIABLESTRINGBUFFER, var_name, buffer, bufsize);
}
-void trap_Cvar_SetValue( const char *var_name, float value ) {
- syscall( UI_CVAR_SETVALUE, var_name, PASSFLOAT( value ) );
-}
+void trap_Cvar_SetValue(const char *var_name, float value) { syscall(UI_CVAR_SETVALUE, var_name, PASSFLOAT(value)); }
-void trap_Cvar_Reset( const char *name ) {
- syscall( UI_CVAR_RESET, name );
-}
+void trap_Cvar_Reset(const char *name) { syscall(UI_CVAR_RESET, name); }
-void trap_Cvar_Create( const char *var_name, const char *var_value, int flags ) {
- syscall( UI_CVAR_CREATE, var_name, var_value, flags );
+void trap_Cvar_Create(const char *var_name, const char *var_value, int flags)
+{
+ syscall(UI_CVAR_CREATE, var_name, var_value, flags);
}
-void trap_Cvar_InfoStringBuffer( int bit, char *buffer, int bufsize ) {
- syscall( UI_CVAR_INFOSTRINGBUFFER, bit, buffer, bufsize );
+void trap_Cvar_InfoStringBuffer(int bit, char *buffer, int bufsize)
+{
+ syscall(UI_CVAR_INFOSTRINGBUFFER, bit, buffer, bufsize);
}
-int trap_Argc( void ) {
- return syscall( UI_ARGC );
-}
+int trap_Argc(void) { return syscall(UI_ARGC); }
-void trap_Argv( int n, char *buffer, int bufferLength ) {
- syscall( UI_ARGV, n, buffer, bufferLength );
-}
+void trap_Argv(int n, char *buffer, int bufferLength) { syscall(UI_ARGV, n, buffer, bufferLength); }
-void trap_Cmd_ExecuteText( int exec_when, const char *text ) {
- syscall( UI_CMD_EXECUTETEXT, exec_when, text );
-}
+void trap_Cmd_ExecuteText(int exec_when, const char *text) { syscall(UI_CMD_EXECUTETEXT, exec_when, text); }
-int trap_FS_FOpenFile( const char *qpath, fileHandle_t *f, fsMode_t mode ) {
- return syscall( UI_FS_FOPENFILE, qpath, f, mode );
+int trap_FS_FOpenFile(const char *qpath, fileHandle_t *f, enum FS_Mode mode)
+{
+ return syscall(UI_FS_FOPENFILE, qpath, f, mode);
}
-void trap_FS_Read( void *buffer, int len, fileHandle_t f ) {
- syscall( UI_FS_READ, buffer, len, f );
-}
+void trap_FS_Read(void *buffer, int len, fileHandle_t f) { syscall(UI_FS_READ, buffer, len, f); }
-void trap_FS_Write( const void *buffer, int len, fileHandle_t f ) {
- syscall( UI_FS_WRITE, buffer, len, f );
-}
+void trap_FS_Write(const void *buffer, int len, fileHandle_t f) { syscall(UI_FS_WRITE, buffer, len, f); }
-void trap_FS_FCloseFile( fileHandle_t f ) {
- syscall( UI_FS_FCLOSEFILE, f );
-}
+void trap_FS_FCloseFile(fileHandle_t f) { syscall(UI_FS_FCLOSEFILE, f); }
-int trap_FS_GetFileList( const char *path, const char *extension, char *listbuf, int bufsize ) {
- return syscall( UI_FS_GETFILELIST, path, extension, listbuf, bufsize );
+int trap_FS_GetFileList(const char *path, const char *extension, char *listbuf, int bufsize)
+{
+ return syscall(UI_FS_GETFILELIST, path, extension, listbuf, bufsize);
}
-int trap_FS_Seek( fileHandle_t f, long offset, int origin ) {
- return syscall( UI_FS_SEEK, f, offset, origin );
-}
+int trap_FS_Seek(fileHandle_t f, long offset, enum FS_Mode origin) { return syscall(UI_FS_SEEK, f, offset, origin); }
-qhandle_t trap_R_RegisterModel( const char *name ) {
- return syscall( UI_R_REGISTERMODEL, name );
-}
+qhandle_t trap_R_RegisterModel(const char *name) { return syscall(UI_R_REGISTERMODEL, name); }
-qhandle_t trap_R_RegisterSkin( const char *name ) {
- return syscall( UI_R_REGISTERSKIN, name );
-}
+qhandle_t trap_R_RegisterSkin(const char *name) { return syscall(UI_R_REGISTERSKIN, name); }
-void trap_R_RegisterFont(const char *fontName, int pointSize, fontInfo_t *font) {
- syscall( UI_R_REGISTERFONT, fontName, pointSize, font );
+void trap_R_RegisterFont(const char *fontName, int pointSize, fontInfo_t *font)
+{
+ syscall(UI_R_REGISTERFONT, fontName, pointSize, font);
}
-qhandle_t trap_R_RegisterShaderNoMip( const char *name ) {
- return syscall( UI_R_REGISTERSHADERNOMIP, name );
-}
+qhandle_t trap_R_RegisterShaderNoMip(const char *name) { return syscall(UI_R_REGISTERSHADERNOMIP, name); }
-void trap_R_ClearScene( void ) {
- syscall( UI_R_CLEARSCENE );
-}
+void trap_R_ClearScene(void) { syscall(UI_R_CLEARSCENE); }
-void trap_R_AddRefEntityToScene( const refEntity_t *re ) {
- syscall( UI_R_ADDREFENTITYTOSCENE, re );
-}
+void trap_R_AddRefEntityToScene(const refEntity_t *re) { syscall(UI_R_ADDREFENTITYTOSCENE, re); }
-void trap_R_AddPolyToScene( qhandle_t hShader , int numVerts, const polyVert_t *verts ) {
- syscall( UI_R_ADDPOLYTOSCENE, hShader, numVerts, verts );
+void trap_R_AddPolyToScene(qhandle_t hShader, int numVerts, const polyVert_t *verts)
+{
+ syscall(UI_R_ADDPOLYTOSCENE, hShader, numVerts, verts);
}
-void trap_R_AddLightToScene( const vec3_t org, float intensity, float r, float g, float b ) {
- syscall( UI_R_ADDLIGHTTOSCENE, org, PASSFLOAT(intensity), PASSFLOAT(r), PASSFLOAT(g), PASSFLOAT(b) );
+void trap_R_AddLightToScene(const vec3_t org, float intensity, float r, float g, float b)
+{
+ syscall(UI_R_ADDLIGHTTOSCENE, org, PASSFLOAT(intensity), PASSFLOAT(r), PASSFLOAT(g), PASSFLOAT(b));
}
-void trap_R_RenderScene( const refdef_t *fd ) {
- syscall( UI_R_RENDERSCENE, fd );
-}
+void trap_R_RenderScene(const refdef_t *fd) { syscall(UI_R_RENDERSCENE, fd); }
-void trap_R_SetColor( const float *rgba ) {
- syscall( UI_R_SETCOLOR, rgba );
-}
+void trap_R_SetColor(const float *rgba) { syscall(UI_R_SETCOLOR, rgba); }
-void trap_R_DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t hShader ) {
- syscall( UI_R_DRAWSTRETCHPIC, PASSFLOAT(x), PASSFLOAT(y), PASSFLOAT(w), PASSFLOAT(h), PASSFLOAT(s1), PASSFLOAT(t1), PASSFLOAT(s2), PASSFLOAT(t2), hShader );
-}
+#ifndef MODULE_INTERFACE_11
+void trap_R_SetClipRegion(const float *region) { syscall(UI_R_SETCLIPREGION, region); }
+#endif
-void trap_R_ModelBounds( clipHandle_t model, vec3_t mins, vec3_t maxs ) {
- syscall( UI_R_MODELBOUNDS, model, mins, maxs );
+void trap_R_DrawStretchPic(
+ float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t hShader)
+{
+ syscall(UI_R_DRAWSTRETCHPIC, PASSFLOAT(x), PASSFLOAT(y), PASSFLOAT(w), PASSFLOAT(h), PASSFLOAT(s1), PASSFLOAT(t1),
+ PASSFLOAT(s2), PASSFLOAT(t2), hShader);
}
-void trap_UpdateScreen( void ) {
- syscall( UI_UPDATESCREEN );
-}
+void trap_R_ModelBounds(clipHandle_t model, vec3_t mins, vec3_t maxs) { syscall(UI_R_MODELBOUNDS, model, mins, maxs); }
-int trap_CM_LerpTag( orientation_t *tag, clipHandle_t mod, int startFrame, int endFrame, float frac, const char *tagName ) {
- return syscall( UI_CM_LERPTAG, tag, mod, startFrame, endFrame, PASSFLOAT(frac), tagName );
-}
+void trap_UpdateScreen(void) { syscall(UI_UPDATESCREEN); }
-void trap_S_StartLocalSound( sfxHandle_t sfx, int channelNum ) {
- syscall( UI_S_STARTLOCALSOUND, sfx, channelNum );
+int trap_CM_LerpTag(orientation_t *tag, clipHandle_t mod, int startFrame, int endFrame, float frac, const char *tagName)
+{
+ return syscall(UI_CM_LERPTAG, tag, mod, startFrame, endFrame, PASSFLOAT(frac), tagName);
}
-sfxHandle_t trap_S_RegisterSound( const char *sample, qboolean compressed ) {
- return syscall( UI_S_REGISTERSOUND, sample, compressed );
-}
+void trap_S_StartLocalSound(sfxHandle_t sfx, int channelNum) { syscall(UI_S_STARTLOCALSOUND, sfx, channelNum); }
-void trap_Key_KeynumToStringBuf( int keynum, char *buf, int buflen ) {
- syscall( UI_KEY_KEYNUMTOSTRINGBUF, keynum, buf, buflen );
+sfxHandle_t trap_S_RegisterSound(const char *sample, qboolean compressed)
+{
+ return syscall(UI_S_REGISTERSOUND, sample, compressed);
}
-void trap_Key_GetBindingBuf( int keynum, char *buf, int buflen ) {
- syscall( UI_KEY_GETBINDINGBUF, keynum, buf, buflen );
+void trap_Key_KeynumToStringBuf(int keynum, char *buf, int buflen)
+{
+ syscall(UI_KEY_KEYNUMTOSTRINGBUF, keynum, buf, buflen);
}
-void trap_Key_SetBinding( int keynum, const char *binding ) {
- syscall( UI_KEY_SETBINDING, keynum, binding );
-}
+void trap_Key_GetBindingBuf(int keynum, char *buf, int buflen) { syscall(UI_KEY_GETBINDINGBUF, keynum, buf, buflen); }
-qboolean trap_Key_IsDown( int keynum ) {
- return syscall( UI_KEY_ISDOWN, keynum );
-}
+void trap_Key_SetBinding(int keynum, const char *binding) { syscall(UI_KEY_SETBINDING, keynum, binding); }
-qboolean trap_Key_GetOverstrikeMode( void ) {
- return syscall( UI_KEY_GETOVERSTRIKEMODE );
-}
+qboolean trap_Key_IsDown(int keynum) { return syscall(UI_KEY_ISDOWN, keynum); }
-void trap_Key_SetOverstrikeMode( qboolean state ) {
- syscall( UI_KEY_SETOVERSTRIKEMODE, state );
-}
+qboolean trap_Key_GetOverstrikeMode(void) { return syscall(UI_KEY_GETOVERSTRIKEMODE); }
-void trap_Key_ClearStates( void ) {
- syscall( UI_KEY_CLEARSTATES );
-}
+void trap_Key_SetOverstrikeMode(qboolean state) { syscall(UI_KEY_SETOVERSTRIKEMODE, state); }
-int trap_Key_GetCatcher( void ) {
- return syscall( UI_KEY_GETCATCHER );
-}
+void trap_Key_ClearStates(void) { syscall(UI_KEY_CLEARSTATES); }
-void trap_Key_SetCatcher( int catcher ) {
- syscall( UI_KEY_SETCATCHER, catcher );
-}
+int trap_Key_GetCatcher(void) { return syscall(UI_KEY_GETCATCHER); }
-void trap_GetClipboardData( char *buf, int bufsize ) {
- syscall( UI_GETCLIPBOARDDATA, buf, bufsize );
-}
+void trap_Key_SetCatcher(int catcher) { syscall(UI_KEY_SETCATCHER, catcher); }
-void trap_GetClientState( uiClientState_t *state ) {
- syscall( UI_GETCLIENTSTATE, state );
-}
+void trap_GetClipboardData(char *buf, int bufsize) { syscall(UI_GETCLIPBOARDDATA, buf, bufsize); }
-void trap_GetGlconfig( glconfig_t *glconfig ) {
- syscall( UI_GETGLCONFIG, glconfig );
-}
+void trap_GetClientState(uiClientState_t *state) { syscall(UI_GETCLIENTSTATE, state); }
-int trap_GetConfigString( int index, char* buff, int buffsize ) {
- return syscall( UI_GETCONFIGSTRING, index, buff, buffsize );
-}
+void trap_GetGlconfig(glconfig_t *glconfig) { syscall(UI_GETGLCONFIG, glconfig); }
-int trap_LAN_GetServerCount( int source ) {
- return syscall( UI_LAN_GETSERVERCOUNT, source );
+int trap_GetConfigString(int index, char *buff, int buffsize)
+{
+ return syscall(UI_GETCONFIGSTRING, index, buff, buffsize);
}
-void trap_LAN_GetServerAddressString( int source, int n, char *buf, int buflen ) {
- syscall( UI_LAN_GETSERVERADDRESSSTRING, source, n, buf, buflen );
-}
+int trap_LAN_GetServerCount(int source) { return syscall(UI_LAN_GETSERVERCOUNT, source); }
-void trap_LAN_GetServerInfo( int source, int n, char *buf, int buflen ) {
- syscall( UI_LAN_GETSERVERINFO, source, n, buf, buflen );
+void trap_LAN_GetServerAddressString(int source, int n, char *buf, int buflen)
+{
+ syscall(UI_LAN_GETSERVERADDRESSSTRING, source, n, buf, buflen);
}
-int trap_LAN_GetServerPing( int source, int n ) {
- return syscall( UI_LAN_GETSERVERPING, source, n );
+void trap_LAN_GetServerInfo(int source, int n, char *buf, int buflen)
+{
+ syscall(UI_LAN_GETSERVERINFO, source, n, buf, buflen);
}
-int trap_LAN_GetPingQueueCount( void ) {
- return syscall( UI_LAN_GETPINGQUEUECOUNT );
-}
+int trap_LAN_GetServerPing(int source, int n) { return syscall(UI_LAN_GETSERVERPING, source, n); }
-int trap_LAN_ServerStatus( const char *serverAddress, char *serverStatus, int maxLen ) {
- return syscall( UI_LAN_SERVERSTATUS, serverAddress, serverStatus, maxLen );
-}
+int trap_LAN_GetPingQueueCount(void) { return syscall(UI_LAN_GETPINGQUEUECOUNT); }
-void trap_LAN_SaveCachedServers( void ) {
- syscall( UI_LAN_SAVECACHEDSERVERS );
+int trap_LAN_ServerStatus(const char *serverAddress, char *serverStatus, int maxLen)
+{
+ return syscall(UI_LAN_SERVERSTATUS, serverAddress, serverStatus, maxLen);
}
-void trap_LAN_LoadCachedServers( void ) {
- syscall( UI_LAN_LOADCACHEDSERVERS );
-}
+#ifndef MODULE_INTERFACE_11
+qboolean trap_GetNews(qboolean force) { return syscall(UI_GETNEWS, force); }
+#endif
-void trap_LAN_ResetPings(int n) {
- syscall( UI_LAN_RESETPINGS, n );
-}
+void trap_LAN_SaveCachedServers(void) { syscall(UI_LAN_SAVECACHEDSERVERS); }
-void trap_LAN_ClearPing( int n ) {
- syscall( UI_LAN_CLEARPING, n );
-}
+void trap_LAN_LoadCachedServers(void) { syscall(UI_LAN_LOADCACHEDSERVERS); }
-void trap_LAN_GetPing( int n, char *buf, int buflen, int *pingtime ) {
- syscall( UI_LAN_GETPING, n, buf, buflen, pingtime );
-}
+void trap_LAN_ResetPings(int n) { syscall(UI_LAN_RESETPINGS, n); }
-void trap_LAN_GetPingInfo( int n, char *buf, int buflen ) {
- syscall( UI_LAN_GETPINGINFO, n, buf, buflen );
-}
+void trap_LAN_ClearPing(int n) { syscall(UI_LAN_CLEARPING, n); }
-void trap_LAN_MarkServerVisible( int source, int n, qboolean visible ) {
- syscall( UI_LAN_MARKSERVERVISIBLE, source, n, visible );
+void trap_LAN_GetPing(int n, char *buf, int buflen, int *pingtime)
+{
+ syscall(UI_LAN_GETPING, n, buf, buflen, pingtime);
}
-int trap_LAN_ServerIsVisible( int source, int n) {
- return syscall( UI_LAN_SERVERISVISIBLE, source, n );
-}
+void trap_LAN_GetPingInfo(int n, char *buf, int buflen) { syscall(UI_LAN_GETPINGINFO, n, buf, buflen); }
-qboolean trap_LAN_UpdateVisiblePings( int source ) {
- return syscall( UI_LAN_UPDATEVISIBLEPINGS, source );
+void trap_LAN_MarkServerVisible(int source, int n, qboolean visible)
+{
+ syscall(UI_LAN_MARKSERVERVISIBLE, source, n, visible);
}
-int trap_LAN_AddServer(int source, const char *name, const char *addr) {
- return syscall( UI_LAN_ADDSERVER, source, name, addr );
-}
+int trap_LAN_ServerIsVisible(int source, int n) { return syscall(UI_LAN_SERVERISVISIBLE, source, n); }
-void trap_LAN_RemoveServer(int source, const char *addr) {
- syscall( UI_LAN_REMOVESERVER, source, addr );
-}
+qboolean trap_LAN_UpdateVisiblePings(int source) { return syscall(UI_LAN_UPDATEVISIBLEPINGS, source); }
-int trap_LAN_CompareServers( int source, int sortKey, int sortDir, int s1, int s2 ) {
- return syscall( UI_LAN_COMPARESERVERS, source, sortKey, sortDir, s1, s2 );
+int trap_LAN_AddServer(int source, const char *name, const char *addr)
+{
+ return syscall(UI_LAN_ADDSERVER, source, name, addr);
}
-int trap_MemoryRemaining( void ) {
- return syscall( UI_MEMORY_REMAINING );
-}
+void trap_LAN_RemoveServer(int source, const char *addr) { syscall(UI_LAN_REMOVESERVER, source, addr); }
-int trap_Parse_AddGlobalDefine( char *define ) {
- return syscall( UI_PARSE_ADD_GLOBAL_DEFINE, define );
+int trap_LAN_CompareServers(int source, int sortKey, int sortDir, int s1, int s2)
+{
+ return syscall(UI_LAN_COMPARESERVERS, source, sortKey, sortDir, s1, s2);
}
-int trap_Parse_LoadSource( const char *filename ) {
- return syscall( UI_PARSE_LOAD_SOURCE, filename );
-}
+int trap_MemoryRemaining(void) { return syscall(UI_MEMORY_REMAINING); }
-int trap_Parse_FreeSource( int handle ) {
- return syscall( UI_PARSE_FREE_SOURCE, handle );
-}
+int trap_Parse_AddGlobalDefine(char *define) { return syscall(UI_PARSE_ADD_GLOBAL_DEFINE, define); }
-int trap_Parse_ReadToken( int handle, pc_token_t *pc_token ) {
- return syscall( UI_PARSE_READ_TOKEN, handle, pc_token );
-}
+int trap_Parse_LoadSource(const char *filename) { return syscall(UI_PARSE_LOAD_SOURCE, filename); }
-int trap_Parse_SourceFileAndLine( int handle, char *filename, int *line ) {
- return syscall( UI_PARSE_SOURCE_FILE_AND_LINE, handle, filename, line );
-}
+int trap_Parse_FreeSource(int handle) { return syscall(UI_PARSE_FREE_SOURCE, handle); }
-void trap_S_StopBackgroundTrack( void ) {
- syscall( UI_S_STOPBACKGROUNDTRACK );
-}
+int trap_Parse_ReadToken(int handle, pc_token_t *pc_token) { return syscall(UI_PARSE_READ_TOKEN, handle, pc_token); }
-void trap_S_StartBackgroundTrack( const char *intro, const char *loop) {
- syscall( UI_S_STARTBACKGROUNDTRACK, intro, loop );
+int trap_Parse_SourceFileAndLine(int handle, char *filename, int *line)
+{
+ return syscall(UI_PARSE_SOURCE_FILE_AND_LINE, handle, filename, line);
}
-int trap_RealTime(qtime_t *qtime) {
- return syscall( UI_REAL_TIME, qtime );
+void trap_S_StopBackgroundTrack(void) { syscall(UI_S_STOPBACKGROUNDTRACK); }
+
+void trap_S_StartBackgroundTrack(const char *intro, const char *loop)
+{
+ syscall(UI_S_STARTBACKGROUNDTRACK, intro, loop);
}
-// this returns a handle. arg0 is the name in the format "idlogo.roq", set arg1 to NULL, alteredstates to qfalse (do not alter gamestate)
-int trap_CIN_PlayCinematic( const char *arg0, int xpos, int ypos, int width, int height, int bits) {
- return syscall(UI_CIN_PLAYCINEMATIC, arg0, xpos, ypos, width, height, bits);
+int trap_RealTime(qtime_t *qtime) { return syscall(UI_REAL_TIME, qtime); }
+
+// this returns a handle. arg0 is the name in the format "idlogo.roq", set arg1 to NULL, alteredstates to qfalse (do
+// not alter gamestate)
+int trap_CIN_PlayCinematic(const char *arg0, int xpos, int ypos, int width, int height, int bits)
+{
+ return syscall(UI_CIN_PLAYCINEMATIC, arg0, xpos, ypos, width, height, bits);
}
// stops playing the cinematic and ends it. should always return FMV_EOF
// cinematics must be stopped in reverse order of when they are started
-e_status trap_CIN_StopCinematic(int handle) {
- return syscall(UI_CIN_STOPCINEMATIC, handle);
-}
-
-
-// will run a frame of the cinematic but will not draw it. Will return FMV_EOF if the end of the cinematic has been reached.
-e_status trap_CIN_RunCinematic (int handle) {
- return syscall(UI_CIN_RUNCINEMATIC, handle);
-}
+e_status trap_CIN_StopCinematic(int handle) { return syscall(UI_CIN_STOPCINEMATIC, handle); }
+// will run a frame of the cinematic but will not draw it. Will return FMV_EOF if the end of the cinematic has been
+// reached.
+e_status trap_CIN_RunCinematic(int handle) { return syscall(UI_CIN_RUNCINEMATIC, handle); }
// draws the current frame
-void trap_CIN_DrawCinematic (int handle) {
- syscall(UI_CIN_DRAWCINEMATIC, handle);
-}
-
+void trap_CIN_DrawCinematic(int handle) { syscall(UI_CIN_DRAWCINEMATIC, handle); }
// allows you to resize the animation dynamically
-void trap_CIN_SetExtents (int handle, int x, int y, int w, int h) {
- syscall(UI_CIN_SETEXTENTS, handle, x, y, w, h);
-}
+void trap_CIN_SetExtents(int handle, int x, int y, int w, int h) { syscall(UI_CIN_SETEXTENTS, handle, x, y, w, h); }
-
-void trap_R_RemapShader( const char *oldShader, const char *newShader, const char *timeOffset ) {
- syscall( UI_R_REMAP_SHADER, oldShader, newShader, timeOffset );
+void trap_R_RemapShader(const char *oldShader, const char *newShader, const char *timeOffset)
+{
+ syscall(UI_R_REMAP_SHADER, oldShader, newShader, timeOffset);
}
-void trap_SetPbClStatus( int status ) {
- syscall( UI_SET_PBCLSTATUS, status );
-}
+void trap_SetPbClStatus(int status) { syscall(UI_SET_PBCLSTATUS, status); }
diff --git a/src/ui/ui_syscalls_11.asm b/src/ui/ui_syscalls_11.asm
index 64d2ca3..a7a01f2 100644
--- a/src/ui/ui_syscalls_11.asm
+++ b/src/ui/ui_syscalls_11.asm
@@ -96,3 +96,5 @@ equ sqrt -107
equ floor -108
equ ceil -109
+equ trap_CheckForUpdate -200
+equ trap_InstallUpdate -201