cg_info.c (7908B)
1 /* 2 =========================================================================== 3 Copyright (C) 1999-2005 Id Software, Inc. 4 5 This file is part of Quake III Arena source code. 6 7 Quake III Arena source code is free software; you can redistribute it 8 and/or modify it under the terms of the GNU General Public License as 9 published by the Free Software Foundation; either version 2 of the License, 10 or (at your option) any later version. 11 12 Quake III Arena source code is distributed in the hope that it will be 13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with Foobar; if not, write to the Free Software 19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 =========================================================================== 21 */ 22 // 23 // cg_info.c -- display information while data is being loading 24 25 #include "cg_local.h" 26 27 #define MAX_LOADING_PLAYER_ICONS 16 28 #define MAX_LOADING_ITEM_ICONS 26 29 30 static int loadingPlayerIconCount; 31 static int loadingItemIconCount; 32 static qhandle_t loadingPlayerIcons[MAX_LOADING_PLAYER_ICONS]; 33 static qhandle_t loadingItemIcons[MAX_LOADING_ITEM_ICONS]; 34 35 36 /* 37 =================== 38 CG_DrawLoadingIcons 39 =================== 40 */ 41 static void CG_DrawLoadingIcons( void ) { 42 int n; 43 int x, y; 44 45 for( n = 0; n < loadingPlayerIconCount; n++ ) { 46 x = 16 + n * 78; 47 y = 324-40; 48 CG_DrawPic( x, y, 64, 64, loadingPlayerIcons[n] ); 49 } 50 51 for( n = 0; n < loadingItemIconCount; n++ ) { 52 y = 400-40; 53 if( n >= 13 ) { 54 y += 40; 55 } 56 x = 16 + n % 13 * 48; 57 CG_DrawPic( x, y, 32, 32, loadingItemIcons[n] ); 58 } 59 } 60 61 62 /* 63 ====================== 64 CG_LoadingString 65 66 ====================== 67 */ 68 void CG_LoadingString( const char *s ) { 69 Q_strncpyz( cg.infoScreenText, s, sizeof( cg.infoScreenText ) ); 70 71 trap_UpdateScreen(); 72 } 73 74 /* 75 =================== 76 CG_LoadingItem 77 =================== 78 */ 79 void CG_LoadingItem( int itemNum ) { 80 gitem_t *item; 81 82 item = &bg_itemlist[itemNum]; 83 84 if ( item->icon && loadingItemIconCount < MAX_LOADING_ITEM_ICONS ) { 85 loadingItemIcons[loadingItemIconCount++] = trap_R_RegisterShaderNoMip( item->icon ); 86 } 87 88 CG_LoadingString( item->pickup_name ); 89 } 90 91 /* 92 =================== 93 CG_LoadingClient 94 =================== 95 */ 96 void CG_LoadingClient( int clientNum ) { 97 const char *info; 98 char *skin; 99 char personality[MAX_QPATH]; 100 char model[MAX_QPATH]; 101 char iconName[MAX_QPATH]; 102 103 info = CG_ConfigString( CS_PLAYERS + clientNum ); 104 105 if ( loadingPlayerIconCount < MAX_LOADING_PLAYER_ICONS ) { 106 Q_strncpyz( model, Info_ValueForKey( info, "model" ), sizeof( model ) ); 107 skin = Q_strrchr( model, '/' ); 108 if ( skin ) { 109 *skin++ = '\0'; 110 } else { 111 skin = "default"; 112 } 113 114 Com_sprintf( iconName, MAX_QPATH, "models/players/%s/icon_%s.tga", model, skin ); 115 116 loadingPlayerIcons[loadingPlayerIconCount] = trap_R_RegisterShaderNoMip( iconName ); 117 if ( !loadingPlayerIcons[loadingPlayerIconCount] ) { 118 Com_sprintf( iconName, MAX_QPATH, "models/players/characters/%s/icon_%s.tga", model, skin ); 119 loadingPlayerIcons[loadingPlayerIconCount] = trap_R_RegisterShaderNoMip( iconName ); 120 } 121 if ( !loadingPlayerIcons[loadingPlayerIconCount] ) { 122 Com_sprintf( iconName, MAX_QPATH, "models/players/%s/icon_%s.tga", DEFAULT_MODEL, "default" ); 123 loadingPlayerIcons[loadingPlayerIconCount] = trap_R_RegisterShaderNoMip( iconName ); 124 } 125 if ( loadingPlayerIcons[loadingPlayerIconCount] ) { 126 loadingPlayerIconCount++; 127 } 128 } 129 130 Q_strncpyz( personality, Info_ValueForKey( info, "n" ), sizeof(personality) ); 131 Q_CleanStr( personality ); 132 133 if( cgs.gametype == GT_SINGLE_PLAYER ) { 134 trap_S_RegisterSound( va( "sound/player/announce/%s.wav", personality ), qtrue ); 135 } 136 137 CG_LoadingString( personality ); 138 } 139 140 141 /* 142 ==================== 143 CG_DrawInformation 144 145 Draw all the status / pacifier stuff during level loading 146 ==================== 147 */ 148 void CG_DrawInformation( void ) { 149 const char *s; 150 const char *info; 151 const char *sysInfo; 152 int y; 153 int value; 154 qhandle_t levelshot; 155 qhandle_t detail; 156 char buf[1024]; 157 158 info = CG_ConfigString( CS_SERVERINFO ); 159 sysInfo = CG_ConfigString( CS_SYSTEMINFO ); 160 161 s = Info_ValueForKey( info, "mapname" ); 162 levelshot = trap_R_RegisterShaderNoMip( va( "levelshots/%s.tga", s ) ); 163 if ( !levelshot ) { 164 levelshot = trap_R_RegisterShaderNoMip( "menu/art/unknownmap" ); 165 } 166 trap_R_SetColor( NULL ); 167 CG_DrawPic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, levelshot ); 168 169 // blend a detail texture over it 170 detail = trap_R_RegisterShader( "levelShotDetail" ); 171 trap_R_DrawStretchPic( 0, 0, cgs.glconfig.vidWidth, cgs.glconfig.vidHeight, 0, 0, 2.5, 2, detail ); 172 173 // draw the icons of things as they are loaded 174 CG_DrawLoadingIcons(); 175 176 // the first 150 rows are reserved for the client connection 177 // screen to write into 178 if ( cg.infoScreenText[0] ) { 179 UI_DrawProportionalString( 320, 128-32, va("Loading... %s", cg.infoScreenText), 180 UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); 181 } else { 182 UI_DrawProportionalString( 320, 128-32, "Awaiting snapshot...", 183 UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); 184 } 185 186 // draw info string information 187 188 y = 180-32; 189 190 // don't print server lines if playing a local game 191 trap_Cvar_VariableStringBuffer( "sv_running", buf, sizeof( buf ) ); 192 if ( !atoi( buf ) ) { 193 // server hostname 194 Q_strncpyz(buf, Info_ValueForKey( info, "sv_hostname" ), 1024); 195 Q_CleanStr(buf); 196 UI_DrawProportionalString( 320, y, buf, 197 UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); 198 y += PROP_HEIGHT; 199 200 // pure server 201 s = Info_ValueForKey( sysInfo, "sv_pure" ); 202 if ( s[0] == '1' ) { 203 UI_DrawProportionalString( 320, y, "Pure Server", 204 UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); 205 y += PROP_HEIGHT; 206 } 207 208 // server-specific message of the day 209 s = CG_ConfigString( CS_MOTD ); 210 if ( s[0] ) { 211 UI_DrawProportionalString( 320, y, s, 212 UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); 213 y += PROP_HEIGHT; 214 } 215 216 // some extra space after hostname and motd 217 y += 10; 218 } 219 220 // map-specific message (long map name) 221 s = CG_ConfigString( CS_MESSAGE ); 222 if ( s[0] ) { 223 UI_DrawProportionalString( 320, y, s, 224 UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); 225 y += PROP_HEIGHT; 226 } 227 228 // cheats warning 229 s = Info_ValueForKey( sysInfo, "sv_cheats" ); 230 if ( s[0] == '1' ) { 231 UI_DrawProportionalString( 320, y, "CHEATS ARE ENABLED", 232 UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); 233 y += PROP_HEIGHT; 234 } 235 236 // game type 237 switch ( cgs.gametype ) { 238 case GT_FFA: 239 s = "Free For All"; 240 break; 241 case GT_SINGLE_PLAYER: 242 s = "Single Player"; 243 break; 244 case GT_TOURNAMENT: 245 s = "Tournament"; 246 break; 247 case GT_TEAM: 248 s = "Team Deathmatch"; 249 break; 250 case GT_CTF: 251 s = "Capture The Flag"; 252 break; 253 #ifdef MISSIONPACK 254 case GT_1FCTF: 255 s = "One Flag CTF"; 256 break; 257 case GT_OBELISK: 258 s = "Overload"; 259 break; 260 case GT_HARVESTER: 261 s = "Harvester"; 262 break; 263 #endif 264 default: 265 s = "Unknown Gametype"; 266 break; 267 } 268 UI_DrawProportionalString( 320, y, s, 269 UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); 270 y += PROP_HEIGHT; 271 272 value = atoi( Info_ValueForKey( info, "timelimit" ) ); 273 if ( value ) { 274 UI_DrawProportionalString( 320, y, va( "timelimit %i", value ), 275 UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); 276 y += PROP_HEIGHT; 277 } 278 279 if (cgs.gametype < GT_CTF ) { 280 value = atoi( Info_ValueForKey( info, "fraglimit" ) ); 281 if ( value ) { 282 UI_DrawProportionalString( 320, y, va( "fraglimit %i", value ), 283 UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); 284 y += PROP_HEIGHT; 285 } 286 } 287 288 if (cgs.gametype >= GT_CTF) { 289 value = atoi( Info_ValueForKey( info, "capturelimit" ) ); 290 if ( value ) { 291 UI_DrawProportionalString( 320, y, va( "capturelimit %i", value ), 292 UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); 293 y += PROP_HEIGHT; 294 } 295 } 296 } 297