Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

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 }