ui_connect.c (9672B)
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 #include "ui_local.h" 24 25 /* 26 =============================================================================== 27 28 CONNECTION SCREEN 29 30 =============================================================================== 31 */ 32 33 qboolean passwordNeeded = qtrue; 34 menufield_s passwordField; 35 36 static connstate_t lastConnState; 37 static char lastLoadingText[MAX_INFO_VALUE]; 38 39 static void UI_ReadableSize ( char *buf, int bufsize, int value ) 40 { 41 if (value > 1024*1024*1024 ) { // gigs 42 Com_sprintf( buf, bufsize, "%d", value / (1024*1024*1024) ); 43 Com_sprintf( buf+strlen(buf), bufsize-strlen(buf), ".%02d GB", 44 (value % (1024*1024*1024))*100 / (1024*1024*1024) ); 45 } else if (value > 1024*1024 ) { // megs 46 Com_sprintf( buf, bufsize, "%d", value / (1024*1024) ); 47 Com_sprintf( buf+strlen(buf), bufsize-strlen(buf), ".%02d MB", 48 (value % (1024*1024))*100 / (1024*1024) ); 49 } else if (value > 1024 ) { // kilos 50 Com_sprintf( buf, bufsize, "%d KB", value / 1024 ); 51 } else { // bytes 52 Com_sprintf( buf, bufsize, "%d bytes", value ); 53 } 54 } 55 56 // Assumes time is in msec 57 static void UI_PrintTime ( char *buf, int bufsize, int time ) { 58 time /= 1000; // change to seconds 59 60 if (time > 3600) { // in the hours range 61 Com_sprintf( buf, bufsize, "%d hr %d min", time / 3600, (time % 3600) / 60 ); 62 } else if (time > 60) { // mins 63 Com_sprintf( buf, bufsize, "%d min %d sec", time / 60, time % 60 ); 64 } else { // secs 65 Com_sprintf( buf, bufsize, "%d sec", time ); 66 } 67 } 68 69 static void UI_DisplayDownloadInfo( const char *downloadName ) { 70 static char dlText[] = "Downloading:"; 71 static char etaText[] = "Estimated time left:"; 72 static char xferText[] = "Transfer rate:"; 73 74 int downloadSize, downloadCount, downloadTime; 75 char dlSizeBuf[64], totalSizeBuf[64], xferRateBuf[64], dlTimeBuf[64]; 76 int xferRate; 77 int width, leftWidth; 78 int style = UI_LEFT|UI_SMALLFONT|UI_DROPSHADOW; 79 const char *s; 80 81 downloadSize = trap_Cvar_VariableValue( "cl_downloadSize" ); 82 downloadCount = trap_Cvar_VariableValue( "cl_downloadCount" ); 83 downloadTime = trap_Cvar_VariableValue( "cl_downloadTime" ); 84 85 #if 0 // bk010104 86 fprintf( stderr, "\n\n-----------------------------------------------\n"); 87 fprintf( stderr, "DB: downloadSize: %16d\n", downloadSize ); 88 fprintf( stderr, "DB: downloadCount: %16d\n", downloadCount ); 89 fprintf( stderr, "DB: downloadTime: %16d\n", downloadTime ); 90 fprintf( stderr, "DB: UI realtime: %16d\n", uis.realtime ); // bk 91 fprintf( stderr, "DB: UI frametime: %16d\n", uis.frametime ); // bk 92 #endif 93 94 leftWidth = width = UI_ProportionalStringWidth( dlText ) * UI_ProportionalSizeScale( style ); 95 width = UI_ProportionalStringWidth( etaText ) * UI_ProportionalSizeScale( style ); 96 if (width > leftWidth) leftWidth = width; 97 width = UI_ProportionalStringWidth( xferText ) * UI_ProportionalSizeScale( style ); 98 if (width > leftWidth) leftWidth = width; 99 leftWidth += 16; 100 101 UI_DrawProportionalString( 8, 128, dlText, style, color_white ); 102 UI_DrawProportionalString( 8, 160, etaText, style, color_white ); 103 UI_DrawProportionalString( 8, 224, xferText, style, color_white ); 104 105 if (downloadSize > 0) { 106 s = va( "%s (%d%%)", downloadName, downloadCount * 100 / downloadSize ); 107 } else { 108 s = downloadName; 109 } 110 111 UI_DrawProportionalString( leftWidth, 128, s, style, color_white ); 112 113 UI_ReadableSize( dlSizeBuf, sizeof dlSizeBuf, downloadCount ); 114 UI_ReadableSize( totalSizeBuf, sizeof totalSizeBuf, downloadSize ); 115 116 if (downloadCount < 4096 || !downloadTime) { 117 UI_DrawProportionalString( leftWidth, 160, "estimating", style, color_white ); 118 UI_DrawProportionalString( leftWidth, 192, 119 va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), style, color_white ); 120 } else { 121 // bk010108 122 //float elapsedTime = (float)(uis.realtime - downloadTime); // current - start (msecs) 123 //elapsedTime = elapsedTime * 0.001f; // in seconds 124 //if ( elapsedTime <= 0.0f ) elapsedTime == 0.0f; 125 if ( (uis.realtime - downloadTime) / 1000) { 126 xferRate = downloadCount / ((uis.realtime - downloadTime) / 1000); 127 //xferRate = (int)( ((float)downloadCount) / elapsedTime); 128 } else { 129 xferRate = 0; 130 } 131 132 //fprintf( stderr, "DB: elapsedTime: %16.8f\n", elapsedTime ); // bk 133 //fprintf( stderr, "DB: xferRate: %16d\n", xferRate ); // bk 134 135 UI_ReadableSize( xferRateBuf, sizeof xferRateBuf, xferRate ); 136 137 // Extrapolate estimated completion time 138 if (downloadSize && xferRate) { 139 int n = downloadSize / xferRate; // estimated time for entire d/l in secs 140 141 // We do it in K (/1024) because we'd overflow around 4MB 142 n = (n - (((downloadCount/1024) * n) / (downloadSize/1024))) * 1000; 143 144 UI_PrintTime ( dlTimeBuf, sizeof dlTimeBuf, n ); // bk010104 145 //(n - (((downloadCount/1024) * n) / (downloadSize/1024))) * 1000); 146 147 UI_DrawProportionalString( leftWidth, 160, 148 dlTimeBuf, style, color_white ); 149 UI_DrawProportionalString( leftWidth, 192, 150 va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), style, color_white ); 151 } else { 152 UI_DrawProportionalString( leftWidth, 160, 153 "estimating", style, color_white ); 154 if (downloadSize) { 155 UI_DrawProportionalString( leftWidth, 192, 156 va("(%s of %s copied)", dlSizeBuf, totalSizeBuf), style, color_white ); 157 } else { 158 UI_DrawProportionalString( leftWidth, 192, 159 va("(%s copied)", dlSizeBuf), style, color_white ); 160 } 161 } 162 163 if (xferRate) { 164 UI_DrawProportionalString( leftWidth, 224, 165 va("%s/Sec", xferRateBuf), style, color_white ); 166 } 167 } 168 } 169 170 /* 171 ======================== 172 UI_DrawConnectScreen 173 174 This will also be overlaid on the cgame info screen during loading 175 to prevent it from blinking away too rapidly on local or lan games. 176 ======================== 177 */ 178 void UI_DrawConnectScreen( qboolean overlay ) { 179 char *s; 180 uiClientState_t cstate; 181 char info[MAX_INFO_VALUE]; 182 183 Menu_Cache(); 184 185 if ( !overlay ) { 186 // draw the dialog background 187 UI_SetColor( color_white ); 188 UI_DrawHandlePic( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, uis.menuBackShader ); 189 } 190 191 // see what information we should display 192 trap_GetClientState( &cstate ); 193 194 info[0] = '\0'; 195 if( trap_GetConfigString( CS_SERVERINFO, info, sizeof(info) ) ) { 196 UI_DrawProportionalString( 320, 16, va( "Loading %s", Info_ValueForKey( info, "mapname" ) ), UI_BIGFONT|UI_CENTER|UI_DROPSHADOW, color_white ); 197 } 198 199 UI_DrawProportionalString( 320, 64, va("Connecting to %s", cstate.servername), UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, menu_text_color ); 200 //UI_DrawProportionalString( 320, 96, "Press Esc to abort", UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, menu_text_color ); 201 202 // display global MOTD at bottom 203 UI_DrawProportionalString( SCREEN_WIDTH/2, SCREEN_HEIGHT-32, 204 Info_ValueForKey( cstate.updateInfoString, "motd" ), UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, menu_text_color ); 205 206 // print any server info (server full, bad version, etc) 207 if ( cstate.connState < CA_CONNECTED ) { 208 UI_DrawProportionalString_AutoWrapped( 320, 192, 630, 20, cstate.messageString, UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, menu_text_color ); 209 } 210 211 #if 0 212 // display password field 213 if ( passwordNeeded ) { 214 s_ingame_menu.x = SCREEN_WIDTH * 0.50 - 128; 215 s_ingame_menu.nitems = 0; 216 s_ingame_menu.wrapAround = qtrue; 217 218 passwordField.generic.type = MTYPE_FIELD; 219 passwordField.generic.name = "Password:"; 220 passwordField.generic.callback = 0; 221 passwordField.generic.x = 10; 222 passwordField.generic.y = 180; 223 Field_Clear( &passwordField.field ); 224 passwordField.width = 256; 225 passwordField.field.widthInChars = 16; 226 Q_strncpyz( passwordField.field.buffer, Cvar_VariableString("password"), 227 sizeof(passwordField.field.buffer) ); 228 229 Menu_AddItem( &s_ingame_menu, ( void * ) &s_customize_player_action ); 230 231 MField_Draw( &passwordField ); 232 } 233 #endif 234 235 if ( lastConnState > cstate.connState ) { 236 lastLoadingText[0] = '\0'; 237 } 238 lastConnState = cstate.connState; 239 240 switch ( cstate.connState ) { 241 case CA_CONNECTING: 242 s = va("Awaiting challenge...%i", cstate.connectPacketCount); 243 break; 244 case CA_CHALLENGING: 245 s = va("Awaiting connection...%i", cstate.connectPacketCount); 246 break; 247 case CA_CONNECTED: { 248 char downloadName[MAX_INFO_VALUE]; 249 250 trap_Cvar_VariableStringBuffer( "cl_downloadName", downloadName, sizeof(downloadName) ); 251 if (*downloadName) { 252 UI_DisplayDownloadInfo( downloadName ); 253 return; 254 } 255 } 256 s = "Awaiting gamestate..."; 257 break; 258 case CA_LOADING: 259 return; 260 case CA_PRIMED: 261 return; 262 default: 263 return; 264 } 265 266 UI_DrawProportionalString( 320, 128, s, UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, color_white ); 267 268 // password required / connection rejected information goes here 269 } 270 271 272 /* 273 =================== 274 UI_KeyConnect 275 =================== 276 */ 277 void UI_KeyConnect( int key ) { 278 if ( key == K_ESCAPE ) { 279 trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect\n" ); 280 return; 281 } 282 }