/* * UI_Refresh */ void UI_Refresh( unsigned int time, int clientState, int serverState, qboolean demoplaying, qboolean backGround ) { uis.frameTime = ( time - uis.time ) * 0.001f; uis.time = time; uis.clientState = clientState; uis.serverState = serverState; uis.backGround = backGround; uis.demoplaying = demoplaying; if( !m_drawfunc ) // ui is inactive return; // draw background if( uis.backGround ) { trap_R_DrawStretchPic( 0, 0, uis.vidWidth, uis.vidHeight, 0, 0, 1, 1, colorWhite, trap_R_RegisterPic( UI_SHADER_VIDEOBACK ) ); trap_R_DrawStretchPic( 0, 0, uis.vidWidth, uis.vidHeight, 0, 0, 1, 1, colorWhite, trap_R_RegisterPic( UI_SHADER_FXBACK ) ); trap_R_DrawStretchPic( 0, 0, uis.vidWidth, uis.vidHeight, 0, 0, 1, 1, colorWhite, trap_R_RegisterPic( UI_SHADER_BIGLOGO ) ); if( !uis.backGroundTrackStarted ) { trap_S_StartBackgroundTrack( S_PLAYLIST_MENU, "3" ); // shuffle and loop uis.backGroundTrackStarted = qtrue; } } else { uis.backGroundTrackStarted = qfalse; //trap_R_DrawStretchPic( 0, 0, uis.vidWidth, uis.vidHeight, // 0, 0, 1, 1, colorDkGrey, trap_R_RegisterPic( "gfx/ui/novideoback" ) ); //trap_R_DrawStretchPic ( 0, 0, uis.vidWidth, uis.vidHeight, // 0, 0, 1, 1, colorWhite, trap_R_RegisterPic( UI_SHADER_BIGLOGO ) ); } m_drawfunc(); // draw cursor if( !uis.bind_grab ) trap_R_DrawStretchPic( uis.cursorX - 16, uis.cursorY - 16, 32, 32, 0, 0, 1, 1, colorWhite, trap_R_RegisterPic( UI_SHADER_CURSOR ) ); // delay playing the enter sound until after the // menu has been drawn, to avoid delay while // caching images if( m_entersound ) { trap_S_StartLocalSound( menu_in_sound ); m_entersound = qfalse; } }
static void MapsList_ChooseMap( menucommon_t *menuitem ) { char path[MAX_CONFIGSTRING_CHARS + 6]; // wsw: Medar: could do this in not so ugly way m_listitem_t *item; menucommon_t *mapitem; char mapinfo[MAX_CONFIGSTRING_CHARS]; const char *mapname, *fullname; int id = ( menuitem ? menuitem->localdata[1] : mapList_cur_idx ); mapitem = UI_MenuItemByName( "m_startserver_map" ); if( mapitem ) Q_strncpyz( mapitem->title, "initial map", sizeof( mapitem->title ) ); mapList_suggested_gametype = 0; item = UI_FindItemInScrollListWithId( &mapList, id ); if( item && item->name ) { if( !trap_ML_GetMapByNum( (int)((size_t)item->data), mapinfo, sizeof( mapinfo ) ) ) return; mapname = mapinfo; fullname = mapinfo + strlen( mapname ) + 1; if( menuitem ) { mapList_cur_idx = id; trap_Cvar_ForceSet( "ui_startserver_lastselectedmap", "" ); } if( mapitem ) { Q_strncatz( mapitem->title, ": " S_COLOR_WHITE, sizeof( mapitem->title ) ); if( !trap_Cvar_Value( "ui_maplist_sortmethod" ) ) Q_strncatz( mapitem->title, mapname, sizeof( mapitem->title ) ); else Q_strncatz( mapitem->title, *fullname ? fullname : mapname, sizeof( mapitem->title ) ); } #ifdef SUGGEST_MAP_GAMETYPE mapList_suggested_gametype = SuggestGameType( mapname ); // if( m_gametypes_item ) // { // m_gametypes_item->curvalue = mapList_suggested_gametype; // M_GametypeFunc( m_gametypes_item ); // } #endif Q_snprintfz( path, sizeof( path ), "levelshots/%s.jpg", mapname ); s_levelshot = trap_R_RegisterLevelshot( path, trap_R_RegisterPic( PATH_UKNOWN_MAP_PIC ), NULL ); } }
/* * CG_RegisterShaders */ static void CG_RegisterShaders( void ) { int i; char *name; CG_LoadingString( "shaders" ); for( i = 1; i < MAX_IMAGES; i++ ) { name = cgs.configStrings[CS_IMAGES+i]; if( !name[0] ) break; CG_LoadingItemName( name ); cgs.imagePrecache[i] = trap_R_RegisterPic( name ); } CG_RegisterMediaShaders(); }
/* * CG_RegisterMediaShader */ static cgs_media_handle_t *CG_RegisterMediaShader( const char *name, bool precache ) { cgs_media_handle_t *mediashader; for( mediashader = shader_headnode; mediashader; mediashader = mediashader->next ) { if( !Q_stricmp( mediashader->name, name ) ) return mediashader; } mediashader = ( cgs_media_handle_t * )CG_Malloc( sizeof( cgs_media_handle_t ) ); mediashader->name = CG_CopyString( name ); mediashader->next = shader_headnode; shader_headnode = mediashader; if( precache ) mediashader->data = ( void * )trap_R_RegisterPic( mediashader->name ); return mediashader; }
void CG_RegisterLevelMinimap( void ) { int file; char *name, minimap[MAX_QPATH]; cgs.shaderMiniMap = NULL; name = cgs.configStrings[CS_MAPNAME]; Q_snprintfz( minimap, sizeof( minimap ), "minimaps/%s.tga", name ); file = trap_FS_FOpenFile( minimap, NULL, FS_READ ); if( file == -1 ) { Q_snprintfz( minimap, sizeof( minimap ), "minimaps/%s.jpg", name ); file = trap_FS_FOpenFile( minimap, NULL, FS_READ ); } if( file != -1 ) cgs.shaderMiniMap = trap_R_RegisterPic( minimap ); }
//================ //CG_DrawMiniMap //================ void CG_DrawMiniMap( int x, int y, int iw, int ih, qboolean draw_playernames, qboolean draw_itemnames, int align, vec4_t color ) { int i, entnum; centity_t *cent; vec3_t coords; vec4_t tmp_col, tmp_white_alpha, tmp_yellow_alpha; // background color of the map vec3_t mins, maxs, extend; int map_w, map_h, map_z; int x_lefttop, y_lefttop, z_lefttop; // the negative y coordinate (bottom of the map) float map_div_w, map_div_h; qboolean isSelf; if( !cg_showminimap->integer ) return; // if inside a team if( cg.predictedPlayerState.stats[STAT_REALTEAM] >= TEAM_PLAYERS && cg.predictedPlayerState.stats[STAT_REALTEAM] < GS_MAX_TEAMS ) { if( !GS_CanShowMinimap() || !( cg_showminimap->integer & 1 ) ) return; } else if( !( cg_showminimap->integer & 2 ) ) { // allow only when chasing a player and the player is allowed to see it if( !GS_CanShowMinimap() || !( cg_showminimap->integer & 1 ) || cg.predictedPlayerState.stats[STAT_REALTEAM] == cg.predictedPlayerState.stats[STAT_TEAM] ) return; } if( !cgs.shaderMiniMap ) return; x = CG_HorizontalAlignForWidth( x, align, iw ); y = CG_VerticalAlignForHeight( y, align, ih ); Vector4Copy( color, tmp_col ); Vector4Copy( colorWhite, tmp_white_alpha ); Vector4Copy( colorYellow, tmp_yellow_alpha ); tmp_white_alpha[3] = color[3]; tmp_yellow_alpha[3] = color[3]; // Get Worldmodel bounds... trap_R_ModelBounds( NULL, mins, maxs ); // NULL for world model... // make it a square bounding box VectorSubtract( maxs, mins, extend ); if( extend[1] > extend[0] ) { mins[0] -= ( extend[1] - extend[0] ) * 0.5; maxs[0] += ( extend[1] - extend[0] ) * 0.5; } else { mins[1] -= ( extend[0] - extend[1] ) * 0.5; maxs[1] += ( extend[0] - extend[1] ) * 0.5; } map_w = maxs[0] - mins[0]; // map width (in game units) map_h = maxs[1] - mins[1]; map_z = maxs[2] - mins[2]; x_lefttop = -mins[0]; // the negative x coordinate ( left of the map ) y_lefttop = -mins[1]; // the negative y coordinate (bottom of the map) z_lefttop = -mins[2]; // the negative y coordinate (bottom of the map) map_div_w = (float)map_w / (float)iw; map_div_h = (float)map_h / (float)ih; CG_DrawHUDRect( x, y, ALIGN_LEFT_TOP, iw, ih, 1, 1, tmp_col, cgs.shaderMiniMap ); //alignment test, to display green dot at 0,0 //CG_DrawHUDRect( x + x_lefttop/map_div_w -1, y + y_lefttop/map_div_h -1,ALIGN_LEFT_TOP,3,3,1,1, colorGreen, CG_MediaShader( cgs.media.shaderMiniMap ) ); for( i = 0; i < cg.frame.numEntities; i++ ) { entnum = cg.frame.parsedEntities[i&( MAX_PARSE_ENTITIES-1 )].number; // filter invalid ents if( entnum < 1 || entnum >= MAX_EDICTS ) continue; // retrieve the centity_t cent = &cg_entities[entnum]; isSelf = ( (unsigned)entnum == cg.predictedPlayerState.POVnum ); if( ( cent->current.type != ET_PLAYER ) && ( cent->current.type != ET_MINIMAP_ICON ) && !( cent->item ) ) continue; if( isSelf ) VectorCopy( cg.predictedPlayerState.pmove.origin, coords ); else VectorCopy( cent->current.origin, coords ); coords[0] = ( coords[0] + x_lefttop ) / map_div_w; coords[1] = ih - ( coords[1] + y_lefttop ) / map_div_h; coords[2] = ( coords[2] + (float)z_lefttop ) / (float)map_z; // is it a player? if( ( cent->current.type == ET_PLAYER ) ) { int box_size = (int)( 3.0 + coords[2] * 10.0 ); // check if we're allowed to see team members only (coaches, CA) if( cg.predictedPlayerState.stats[STAT_LAYOUTS] & STAT_LAYOUT_SPECTEAMONLY || (cg.predictedPlayerState.stats[STAT_REALTEAM] != TEAM_SPECTATOR && GS_TeamOnlyMinimap()) ) { if( cg.predictedPlayerState.stats[STAT_REALTEAM] != cent->current.team ) continue; } if( cent->current.team == TEAM_SPECTATOR ) { if( entnum != cg.view.POVent ) continue; VectorSet( tmp_col, 1, 1, 1 ); } else { CG_TeamColor( cent->current.team, tmp_col ); } // get color tmp_col[3] = bound( 0, color[3] + 0.3f, 1 ); CG_DrawHUDRect( x + (int)coords[0] -box_size/2, y + (int)coords[1] -box_size/2, ALIGN_LEFT_TOP, box_size, box_size, box_size, box_size, tmp_col, NULL ); // differentiate ourselves with an arrow if( isSelf ) { int thisX, thisY, thisSize; thisSize = max( box_size, 8 ); thisX = CG_VerticalAlignForHeight( x + (int)coords[0], ALIGN_CENTER_MIDDLE, thisSize ); thisY = CG_VerticalAlignForHeight( y + (int)coords[1] - thisSize, ALIGN_CENTER_MIDDLE, thisSize ); trap_R_DrawStretchPic( thisX, thisY, thisSize, thisSize, 0, 0, 1, 1, tmp_yellow_alpha, CG_MediaShader( cgs.media.shaderDownArrow ) ); } // do we want names too? if( draw_playernames == qtrue ) trap_SCR_DrawString( x + (int)coords[0] + 8, y + (int)coords[1] - 4, ALIGN_LEFT_TOP, COM_RemoveColorTokensExt( cgs.clientInfo[cent->current.number-1].name, qtrue ), cgs.fontSystemSmall, tmp_yellow_alpha ); } else if( cent->current.type == ET_MINIMAP_ICON ) { if( cent->ent.customShader ) { vec4_t tmp_this_color; int thisX, thisY, thisSize; thisSize = (float)cent->prev.frame + (float)( cent->current.frame - cent->prev.frame ) * cg.lerpfrac; if( thisSize <= 0 ) thisSize = 18; tmp_this_color[0] = (float)cent->ent.shaderRGBA[0] / 255.0f; tmp_this_color[1] = (float)cent->ent.shaderRGBA[1] / 255.0f; tmp_this_color[2] = (float)cent->ent.shaderRGBA[2] / 255.0f; tmp_this_color[3] = 1.0f; thisX = CG_VerticalAlignForHeight( x + coords[0], ALIGN_CENTER_MIDDLE, thisSize ); thisY = CG_VerticalAlignForHeight( y + coords[1], ALIGN_CENTER_MIDDLE, thisSize ); trap_R_DrawStretchPic( thisX, thisY, thisSize, thisSize, 0, 0, 1, 1, tmp_this_color, cent->ent.customShader ); } } else if( cent->item && cent->item->icon ) { // if ALIGN_CENTER_MIDDLE or something is used, images are f****d // so thats why they are set manually at the correct pos with -n CG_DrawHUDRect( x+(int)coords[0]-8, y+(int)coords[1]-8, ALIGN_LEFT_TOP, 15, 15, 1, 1, tmp_white_alpha, trap_R_RegisterPic( cent->item->icon ) ); if( draw_itemnames == qtrue ) trap_SCR_DrawString( x + (int)coords[0] + 16, y + (int)coords[1] - 8, ALIGN_LEFT_TOP, cent->item->shortname, cgs.fontSystemSmall, tmp_yellow_alpha ); } } }
/* * CG_Init */ void CG_Init( const char *serverName, unsigned int playerNum, int vidWidth, int vidHeight, qboolean demoplaying, const char *demoName, qboolean pure, unsigned int snapFrameTime, int protocol, int sharedSeed ) { CG_InitGameShared(); memset( &cg, 0, sizeof( cg_state_t ) ); memset( &cgs, 0, sizeof( cg_static_t ) ); memset( cg_entities, 0, sizeof( cg_entities ) ); #ifdef PURE_CHEAT CG_Printf( S_COLOR_MAGENTA"Hi, I'm an unpure bitch 7\n" ); #endif // save server name cgs.serverName = CG_CopyString( serverName ); // save local player number cgs.playerNum = playerNum; // save current width and height cgs.vidWidth = vidWidth; cgs.vidHeight = vidHeight; // demo cgs.demoPlaying = demoplaying == qtrue; cgs.demoName = demoName; // whether to only allow pure files cgs.pure = pure == qtrue; // whether we are connected to a tv-server cgs.tv = false; cgs.tvRequested = false; // game protocol number cgs.gameProtocol = protocol; cgs.snapFrameTime = snapFrameTime; cgs.initialSharedSeed = sharedSeed; cg.sharedSeed = cgs.initialSharedSeed; cgs.hasGametypeMenu = false; // this will update as soon as we receive configstrings CG_RegisterVariables(); CG_InitTemporaryBoneposesCache(); CG_PModelsInit(); CG_ScreenInit(); // get configstrings CG_RegisterConfigStrings(); // register fonts here so loading screen works CG_RegisterFonts(); cgs.shaderWhite = trap_R_RegisterPic( "$whiteimage" ); // l10n CG_InitL10n(); CG_RegisterLevelMinimap(); CG_RegisterModels(); CG_RegisterSounds(); CG_RegisterShaders(); CG_RegisterSkinFiles(); CG_RegisterClients(); CG_RegisterCGameCommands(); CG_ValidateItemList(); CG_LoadStatusBar(); CG_LoadingString( "" ); CG_ClearDecals(); CG_ClearPolys(); CG_ClearEffects(); CG_ClearLocalEntities(); CG_InitChat( &cg.chat ); CG_RegisterLightStyles(); // start up announcer events queue from clean CG_ClearAnnouncerEvents(); cgs.precacheDone = true; cgs.demoTutorial = cgs.demoPlaying && (strstr( cgs.demoName, "tutorials/" ) != NULL); cg.firstFrame = true; // think of the next frame in CG_NewFrameSnap as of the first one // now that we're done with precaching, let the autorecord actions do something CG_ConfigString( CS_AUTORECORDSTATE, cgs.configStrings[CS_AUTORECORDSTATE] ); CG_DemocamInit(); }
/* * CG_MediaShader */ struct shader_s *CG_MediaShader( cgs_media_handle_t *mediashader ) { if( !mediashader->data ) mediashader->data = ( void * )trap_R_RegisterPic( mediashader->name ); return ( struct shader_s * )mediashader->data; }
/* * CG_ConfigString */ void CG_ConfigString( int i, const char *s ) { size_t len; // wsw : jal : warn if configstring overflow len = strlen( s ); if( len >= MAX_CONFIGSTRING_CHARS ) CG_Printf( "%sWARNING:%s Configstring %i overflowed\n", S_COLOR_YELLOW, S_COLOR_WHITE, i ); if( i < 0 || i >= MAX_CONFIGSTRINGS ) CG_Error( "configstring > MAX_CONFIGSTRINGS" ); Q_strncpyz( cgs.configStrings[i], s, sizeof( cgs.configStrings[i] ) ); // do something apropriate if( i == CS_MAPNAME ) { CG_RegisterLevelMinimap(); } else if( i == CS_TVSERVER ) { CG_UpdateTVServerString(); } else if( i == CS_GAMETYPETITLE ) { } else if( i == CS_GAMETYPENAME ) { GS_SetGametypeName( cgs.configStrings[CS_GAMETYPENAME] ); } else if( i == CS_AUTORECORDSTATE ) { CG_SC_AutoRecordAction( cgs.configStrings[i] ); } else if( i >= CS_MODELS && i < CS_MODELS+MAX_MODELS ) { if( cgs.configStrings[i][0] == '$' ) // indexed pmodel cgs.pModelsIndex[i-CS_MODELS] = CG_RegisterPlayerModel( cgs.configStrings[i]+1 ); else cgs.modelDraw[i-CS_MODELS] = CG_RegisterModel( cgs.configStrings[i] ); } else if( i >= CS_SOUNDS && i < CS_SOUNDS+MAX_SOUNDS ) { if( cgs.configStrings[i][0] != '*' ) cgs.soundPrecache[i-CS_SOUNDS] = trap_S_RegisterSound( cgs.configStrings[i] ); } else if( i >= CS_IMAGES && i < CS_IMAGES+MAX_IMAGES ) { cgs.imagePrecache[i-CS_IMAGES] = trap_R_RegisterPic( cgs.configStrings[i] ); } else if( i >= CS_SKINFILES && i < CS_SKINFILES+MAX_SKINFILES ) { cgs.skinPrecache[i-CS_SKINFILES] = trap_R_RegisterSkinFile( cgs.configStrings[i] ); } else if( i >= CS_LIGHTS && i < CS_LIGHTS+MAX_LIGHTSTYLES ) { CG_SetLightStyle( i - CS_LIGHTS ); } else if( i >= CS_ITEMS && i < CS_ITEMS+MAX_ITEMS ) { CG_ValidateItemDef( i - CS_ITEMS, cgs.configStrings[i] ); } else if( i >= CS_PLAYERINFOS && i < CS_PLAYERINFOS+MAX_CLIENTS ) { CG_LoadClientInfo( &cgs.clientInfo[i-CS_PLAYERINFOS], cgs.configStrings[i], i-CS_PLAYERINFOS ); } else if( i >= CS_GAMECOMMANDS && i < CS_GAMECOMMANDS+MAX_GAMECOMMANDS ) { if( !cgs.demoPlaying ) { trap_Cmd_AddCommand( cgs.configStrings[i], NULL ); if( !Q_stricmp( cgs.configStrings[i], "gametypemenu" ) ) { cgs.hasGametypeMenu = qtrue; } } } else if( i >= CS_WEAPONDEFS && i < CS_WEAPONDEFS + MAX_WEAPONDEFS ) { CG_OverrideWeapondef( i - CS_WEAPONDEFS, cgs.configStrings[i] ); } }
/* * UI_DrawConnectScreen */ void UI_DrawConnectScreen( const char *serverName, const char *rejectmessage, int downloadType, const char *downloadFilename, float downloadPercent, int downloadSpeed, int connectCount, qboolean demoplaying, qboolean backGround ) { qboolean localhost, design = qfalse; char str[MAX_QPATH]; int x, y, xoffset, yoffset, width, height; unsigned int maxwidth; qboolean downloadFromWeb; char hostName[MAX_CONFIGSTRING_CHARS], mapname[MAX_CONFIGSTRING_CHARS], mapmessage[MAX_CONFIGSTRING_CHARS], gametype[MAX_CONFIGSTRING_CHARS], gametypeTitle[MAX_CONFIGSTRING_CHARS], gametypeVersion[MAX_CONFIGSTRING_CHARS], gametypeAuthor[MAX_CONFIGSTRING_CHARS], matchName[MAX_CONFIGSTRING_CHARS]; uis.demoplaying = demoplaying; //trap_S_StopBackgroundTrack(); localhost = (qboolean)( !serverName || !serverName[0] || !Q_stricmp( serverName, "localhost" ) ); trap_GetConfigString( CS_MAPNAME, mapname, sizeof( mapname ) ); trap_GetConfigString( CS_MESSAGE, mapmessage, sizeof( mapmessage ) ); if( backGround ) { Q_snprintfz( str, sizeof( str ), UI_SHADER_BACKGROUND, uis.backgroundNum ); trap_R_DrawStretchPic( 0, 0, uis.vidWidth, uis.vidHeight, 0, 0, 1, 1, colorWhite, trap_R_RegisterPic( str ) ); } // // not yet connected // x = 64; y = 64; xoffset = yoffset = 0; if( demoplaying ) Q_snprintfz( str, sizeof( str ), "Loading demo: %s", serverName ); else if( localhost ) Q_strncpyz( str, "Loading...", sizeof( str ) ); else if( mapname[0] ) Q_snprintfz( str, sizeof( str ), "Connecting to %s", serverName ); else Q_snprintfz( str, sizeof( str ), "Awaiting connection... %i", connectCount ); trap_SCR_DrawString( x + xoffset, y + yoffset, ALIGN_LEFT_TOP, str, uis.fontSystemBig, colorWhite ); yoffset += trap_SCR_strHeight( uis.fontSystemBig ); if( design && !rejectmessage ) rejectmessage = "Connection was interrupted because the weather sux :P"; if( rejectmessage ) { x = uis.vidWidth / 2; y = uis.vidHeight / 3; height = trap_SCR_strHeight( uis.fontSystemMedium ) * 4; Q_strncpyz( str, "Refused: ", sizeof( str ) ); width = max( trap_SCR_strWidth( str, uis.fontSystemMedium, 0 ), trap_SCR_strWidth( rejectmessage, uis.fontSystemSmall, 0 ) ); width += 32 * 2; xoffset = UISCR_HorizontalAlignOffset( ALIGN_CENTER_MIDDLE, width ); yoffset = UISCR_VerticalAlignOffset( ALIGN_CENTER_MIDDLE, height ); UI_DrawBox( x + xoffset, y + yoffset, width, height, colorWarsowOrange, colorWhite, NULL, colorDkGrey ); yoffset += trap_SCR_strHeight( uis.fontSystemMedium ); xoffset += 32; trap_SCR_DrawString( x + xoffset, y + yoffset, ALIGN_LEFT_TOP, str, uis.fontSystemMedium, colorWhite ); yoffset += trap_SCR_strHeight( uis.fontSystemMedium ); trap_SCR_DrawString( x + xoffset, y + yoffset, ALIGN_LEFT_TOP, rejectmessage, uis.fontSystemSmall, colorBlack ); return; } if( mapname[0] ) { char levelshot[MAX_QPATH]; struct shader_s *levelshotShader; qboolean isDefaultlevelshot = qtrue; // // connected // x = 64; y = uis.vidHeight - 300; xoffset = yoffset = 0; width = uis.vidWidth; height = 200; UI_DrawBox( x + xoffset, y + yoffset, width, height, colorWarsowPurple, colorWhite, NULL, colorDkGrey ); xoffset += 16; yoffset += 16 + 4; maxwidth = uis.vidWidth - ( x + xoffset ); trap_GetConfigString( CS_HOSTNAME, hostName, sizeof( hostName ) ); trap_GetConfigString( CS_GAMETYPENAME, gametype, sizeof( gametype ) ); trap_GetConfigString( CS_GAMETYPETITLE, gametypeTitle, sizeof( gametypeTitle ) ); trap_GetConfigString( CS_GAMETYPEVERSION, gametypeVersion, sizeof( gametypeVersion ) ); trap_GetConfigString( CS_GAMETYPEAUTHOR, gametypeAuthor, sizeof( gametypeAuthor ) ); trap_GetConfigString( CS_MATCHNAME, matchName, sizeof( matchName ) ); Q_snprintfz( levelshot, sizeof( levelshot ), "levelshots/%s.jpg", mapname ); levelshotShader = trap_R_RegisterLevelshot( levelshot, uis.whiteShader, &isDefaultlevelshot ); if( !isDefaultlevelshot ) { int lw, lh, lx, ly; lh = height - 8; lw = lh * ( 4.0f/3.0f ); lx = uis.vidWidth - lw; ly = y + 4; trap_R_DrawStretchPic( lx, ly, lw, lh, 0, 0, 1, 1, colorWhite, levelshotShader ); } if( !localhost && !demoplaying ) { Q_snprintfz( str, sizeof( str ), "Server: %s", hostName ); trap_SCR_DrawStringWidth( x + xoffset, y + yoffset, ALIGN_LEFT_TOP, str, maxwidth, uis.fontSystemSmall, colorWhite ); yoffset += trap_SCR_strHeight( uis.fontSystemSmall ) + 8; } if( mapmessage[0] && Q_stricmp( mapname, mapmessage ) ) { Q_snprintfz( str, sizeof( str ), "Level: "S_COLOR_ORANGE"%s", COM_RemoveColorTokens( mapmessage ) ); trap_SCR_DrawStringWidth( x + xoffset, y + yoffset, ALIGN_LEFT_TOP, str, maxwidth, uis.fontSystemSmall, colorWhite ); yoffset += trap_SCR_strHeight( uis.fontSystemSmall ) + 8; } Q_snprintfz( str, sizeof( str ), "Map: %s", mapname ); trap_SCR_DrawStringWidth( x + xoffset, y + yoffset, ALIGN_LEFT_TOP, str, maxwidth, uis.fontSystemSmall, colorWhite ); yoffset += trap_SCR_strHeight( uis.fontSystemSmall ) + 8; if( matchName[0] ) { Q_snprintfz( str, sizeof( str ), "Match: %s", matchName ); trap_SCR_DrawStringWidth( x + xoffset, y + yoffset, ALIGN_LEFT_TOP, str, maxwidth, uis.fontSystemSmall, colorWhite ); yoffset += trap_SCR_strHeight( uis.fontSystemSmall ) + 8; } yoffset += trap_SCR_strHeight( uis.fontSystemSmall ) + 8; Q_snprintfz( str, sizeof( str ), "Gametype: "S_COLOR_ORANGE"%s", COM_RemoveColorTokens( gametypeTitle ) ); trap_SCR_DrawStringWidth( x + xoffset, y + yoffset, ALIGN_LEFT_TOP, str, maxwidth, uis.fontSystemSmall, colorWhite ); yoffset += trap_SCR_strHeight( uis.fontSystemSmall ) + 8; Q_snprintfz( str, sizeof( str ), "Version: %s", COM_RemoveColorTokens( gametypeVersion ) ); trap_SCR_DrawStringWidth( x + xoffset, y + yoffset, ALIGN_LEFT_TOP, str, maxwidth, uis.fontSystemSmall, colorWhite ); yoffset += trap_SCR_strHeight( uis.fontSystemSmall ) + 8; Q_snprintfz( str, sizeof( str ), "Author: %s", gametypeAuthor ); trap_SCR_DrawStringWidth( x + xoffset, y + yoffset, ALIGN_LEFT_TOP, str, maxwidth, uis.fontSystemSmall, colorWhite ); yoffset += trap_SCR_strHeight( uis.fontSystemSmall ) + 8; } // downloading if( design && !downloadFilename ) { downloadFilename = "http://www.warsow.net/autoupdate/basewsw/map_wdm9a.pk3"; downloadType = 2; downloadPercent = 65.8; downloadSpeed = 325; } if( downloadType && downloadFilename ) { size_t len; const char *s; downloadFromWeb = ( downloadType == 2 ); x = uis.vidWidth / 2; y = uis.vidHeight / 3; width = 400; height = 128 - trap_SCR_strHeight( uis.fontSystemSmall ); if( uis.vidWidth <= width ) width = uis.vidWidth - 64; maxwidth = width - 48; xoffset = UISCR_HorizontalAlignOffset( ALIGN_CENTER_MIDDLE, width ); yoffset = UISCR_VerticalAlignOffset( ALIGN_CENTER_MIDDLE, height ); // adjust the box size for the extra number of lines needed to draw the file path s = downloadFilename; while( ( len = trap_SCR_StrlenForWidth( s, uis.fontSystemSmall, maxwidth ) ) > 0 ) { s += len; height += trap_SCR_strHeight( uis.fontSystemSmall ); } UI_DrawBox( x + xoffset, y + yoffset, width, height, colorWarsowPurple, colorWhite, NULL, colorDkGrey ); xoffset += 24; yoffset += 24; trap_SCR_DrawStringWidth( x + xoffset, y + yoffset, ALIGN_LEFT_TOP, downloadFromWeb ? "Downloading from web" : "Downloading from server", maxwidth, uis.fontSystemSmall, colorWhite ); yoffset += trap_SCR_strHeight( uis.fontSystemSmall ); s = downloadFilename; while( ( len = trap_SCR_DrawStringWidth( x + xoffset, y + yoffset, ALIGN_LEFT_TOP, s, maxwidth, uis.fontSystemSmall, colorWhite ) ) > 0 ) { s += len; yoffset += trap_SCR_strHeight( uis.fontSystemSmall ); } yoffset += 16; UI_DrawPicBar( x + xoffset, y + yoffset, maxwidth, 24, ALIGN_LEFT_TOP, downloadPercent, trap_R_RegisterPic( "gfx/ui/progressbar" ),colorDkGrey, colorOrange ); Q_snprintfz( str, sizeof( str ), "%3.1f%c", downloadPercent, '%' ); trap_SCR_DrawStringWidth( x + xoffset + 12, y + yoffset + 12, ALIGN_LEFT_MIDDLE, str, maxwidth, uis.fontSystemSmall, colorWhite ); Q_snprintfz( str, sizeof( str ), "%ik/s", downloadSpeed ); trap_SCR_DrawStringWidth( x + xoffset + maxwidth - 12, y + yoffset + 12, ALIGN_RIGHT_MIDDLE, str, maxwidth, uis.fontSystemSmall, colorWhite ); yoffset += 24 + 8; } }
static void M_Cache( void ) { // precache sounds trap_S_RegisterSound( S_UI_MENU_IN_SOUND ); trap_S_RegisterSound( S_UI_MENU_MOVE_SOUND ); trap_S_RegisterSound( S_UI_MENU_OUT_SOUND ); uis.whiteShader = trap_R_RegisterPic( "gfx/ui/white" ); UI_RegisterFonts(); trap_R_RegisterPic( UI_SHADER_FXBACK ); trap_R_RegisterPic( UI_SHADER_BIGLOGO ); trap_R_RegisterPic( UI_SHADER_CURSOR ); uis.gfxSlidebar_1 = trap_R_RegisterPic( "gfx/ui/slidebar_1" ); uis.gfxSlidebar_2 = trap_R_RegisterPic( "gfx/ui/slidebar_2" ); uis.gfxSlidebar_3 = trap_R_RegisterPic( "gfx/ui/slidebar_3" ); uis.gfxSlidebar_4 = trap_R_RegisterPic( "gfx/ui/slidebar_4" ); uis.gfxScrollbar_1 = trap_R_RegisterPic( "gfx/ui/scrollbar_1" ); uis.gfxScrollbar_2 = trap_R_RegisterPic( "gfx/ui/scrollbar_2" ); uis.gfxScrollbar_3 = trap_R_RegisterPic( "gfx/ui/scrollbar_3" ); uis.gfxScrollbar_4 = trap_R_RegisterPic( "gfx/ui/scrollbar_4" ); uis.gfxArrowUp = trap_R_RegisterPic( "gfx/ui/arrow_up" ); uis.gfxArrowDown = trap_R_RegisterPic( "gfx/ui/arrow_down" ); uis.gfxArrowRight = trap_R_RegisterPic( "gfx/ui/arrow_right" ); // precache box images uis.gfxBoxUpLeft = trap_R_RegisterPic( "gfx/ui/ui_box_upleft" ); uis.gfxBoxBorderUpLeft = trap_R_RegisterPic( "gfx/ui/ui_box_border_upleft" ); uis.gfxBoxBorderLeft = trap_R_RegisterPic( "gfx/ui/ui_box_border_left" ); uis.gfxBoxLeft = trap_R_RegisterPic( "gfx/ui/ui_box_left" ); uis.gfxBoxBorderBottomLeft = trap_R_RegisterPic( "gfx/ui/ui_box_border_bottomleft" ); uis.gfxBoxBottomLeft = trap_R_RegisterPic( "gfx/ui/ui_box_bottomleft" ); uis.gfxBoxBorderUp = trap_R_RegisterPic( "gfx/ui/ui_box_border_up" ); uis.gfxBoxUp = trap_R_RegisterPic( "gfx/ui/ui_box_up" ); uis.gfxBoxBorderBottom = trap_R_RegisterPic( "gfx/ui/ui_box_border_bottom" ); uis.gfxBoxBottom = trap_R_RegisterPic( "gfx/ui/ui_box_bottom" ); uis.gfxBoxBorderUp = trap_R_RegisterPic( "gfx/ui/ui_box_border_up" ); uis.gfxBoxUp = trap_R_RegisterPic( "gfx/ui/ui_box_up" ); uis.gfxBoxBorderBottom = trap_R_RegisterPic( "gfx/ui/ui_box_border_bottom" ); uis.gfxBoxBottom = trap_R_RegisterPic( "gfx/ui/ui_box_bottom" ); uis.gfxBoxBorderUpRight = trap_R_RegisterPic( "gfx/ui/ui_box_border_upright" ); uis.gfxBoxUpRight = trap_R_RegisterPic( "gfx/ui/ui_box_upright" ); uis.gfxBoxBorderRight = trap_R_RegisterPic( "gfx/ui/ui_box_border_right" ); uis.gfxBoxRight = trap_R_RegisterPic( "gfx/ui/ui_box_right" ); uis.gfxBoxBorderBottomRight = trap_R_RegisterPic( "gfx/ui/ui_box_border_bottomright" ); uis.gfxBoxBottomRight = trap_R_RegisterPic( "gfx/ui/ui_box_bottomright" ); }