/* =========================================================================== Wolfenstein: Enemy Territory GPL Source Code Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company. This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”). Wolf ET Source Code 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 3 of the License, or (at your option) any later version. Wolf ET Source Code 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 Wolf ET Source Code. If not, see . In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. =========================================================================== */ /* ======================================================================= USER INTERFACE MAIN ======================================================================= */ #include "ui_local.h" // NERVE - SMF #define AXIS_TEAM 0 #define ALLIES_TEAM 1 #define SPECT_TEAM 2 // -NERVE - SMF extern qboolean g_waitingForKey; extern qboolean g_editingField; extern itemDef_t *g_editItem; uiInfo_t uiInfo; static const char *MonthAbbrev[] = { "Jan","Feb","Mar", "Apr","May","Jun", "Jul","Aug","Sep", "Oct","Nov","Dec" }; static const serverFilter_t serverFilters[] = { {"All", "" } }; // For server browser /*static const char *ETGameTypes[] = { "Single Player", "Cooperative", "Objective", "Stopwatch", "Campaign", "Last Man Standing" }; static const char *shortETGameTypes[] = { "SP", "Coop", "Obj", "SW", "Cmpgn", "LMS" }; static int const numETGameTypes = sizeof(ETGameTypes) / sizeof(const char*);*/ 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 int uitogamecode[] = {4,6,2,3,1,5,7}; // NERVE - SMF - enabled for multiplayer static void UI_StartServerRefresh( qboolean full ); static void UI_StopServerRefresh( void ); static void UI_DoServerRefresh( void ); static void UI_FeederSelection( float feederID, int index ); qboolean UI_FeederSelectionClick( itemDef_t *item ); static void UI_BuildServerDisplayList( qboolean 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 const char *UI_SelectedMap( qboolean singlePlayer, int index, int *actual ); static int UI_GetIndexFromSelection( int actual ); static const char *UI_SelectedCampaign( int index, int *actual ); static int UI_CampaignCount( qboolean singlePlayer ); qboolean UI_CheckExecKey( int key ); // -NERVE - SMF - enabled for multiplayer static void UI_ParseGameInfo( const char *teamFile ); //static void UI_ParseTeamInfo(const char *teamFile); // TTimo: unused //int ProcessNewUI( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6 ); itemDef_t *Menu_FindItemByName( menuDef_t *menu, const char *p ); void Menu_ShowItemByName( menuDef_t *menu, const char *p, qboolean bShow ); #define ITEM_GRENADES 1 #define ITEM_MEDKIT 2 #define ITEM_PISTOL 1 #define DEFAULT_PISTOL #define PT_KNIFE ( 1 ) #define PT_PISTOL ( 1 << 2 ) #define PT_RIFLE ( 1 << 3 ) #define PT_LIGHTONLY ( 1 << 4 ) #define PT_GRENADES ( 1 << 5 ) #define PT_EXPLOSIVES ( 1 << 6 ) #define PT_MEDKIT ( 1 << 7 ) // TTimo static char translated_yes[4], translated_no[4]; typedef struct { const char *name; int items; } playerType_t; static playerType_t playerTypes[] = { { "player_window_soldier", PT_KNIFE | PT_PISTOL | PT_RIFLE | PT_GRENADES }, { "player_window_medic", PT_KNIFE | PT_PISTOL | PT_MEDKIT }, { "player_window_engineer", PT_KNIFE | PT_PISTOL | PT_LIGHTONLY | PT_GRENADES }, { "player_window_lieutenant", PT_KNIFE | PT_PISTOL | PT_RIFLE | PT_EXPLOSIVES }, { "player_window_covertops", PT_KNIFE | PT_PISTOL | PT_GRENADES } }; int numPlayerTypes = sizeof( playerTypes ) / sizeof( playerTypes[0] ); /*typedef struct { int weapindex; const char *desc; // int flags; const char *cvar; int value; const char *shadername; const char *torso_anim; const char *legs_anim; // const char *large_shader; } weaponType_t;*/ #define ENG_WEAPMASK_1 ( 0 | 1 | 2 ) #define ENG_WEAPMASK_2 ( 4 | 8 ) // NERVE - SMF - this is the weapon info list [what can and can't be used by character classes] // - This list is seperate from the actual text names in the listboxes for localization purposes. // - The list boxes look up this list by the cvar value. // Gordon: stripped out some useless stuff, and moved some other stuff to generic class stuff /*static weaponType_t weaponTypes[] = { { 0, "NULL", "none", -1, "none", "", "" }, { WP_COLT, "1911 pistol", "mp_weapon", -1, "ui/assets/weapon_colt1911.tga", "firing_pistolB_1", "stand_pistolB" }, { WP_LUGER, "Luger pistol", "mp_weapon", -1, "ui/assets/weapon_luger.tga", "firing_pistolB_1", "stand_pistolB" }, { WP_MP40, "MP 40", "mp_weapon", 0, "ui/assets/weapon_mp40.tga", "relaxed_idle_2h_1", "relaxed_idle_2h_1" }, { WP_THOMPSON, "Thompson", "mp_weapon", 1, "ui/assets/weapon_thompson.tga", "relaxed_idle_2h_1", "relaxed_idle_2h_1" }, { WP_STEN, "Sten", "mp_weapon", 2, "ui/assets/weapon_sten.tga", "relaxed_idle_2h_1", "relaxed_idle_2h_1" }, { WP_PANZERFAUST, "Panzerfaust", "mp_weapon", 4, "ui/assets/weapon_panzerfaust.tga", "stand_panzer", "stand_panzer" }, { WP_FLAMETHROWER, "Flamethrower", "mp_weapon", 6, "ui/assets/weapon_flamethrower.tga", "stand_machinegun", "stand_machinegun" }, { WP_GRENADE_PINEAPPLE, "Pineapple grenade", "mp_weapon_2", 8, "ui/assets/weapon_grenade.tga", "firing_pistolB_1", "stand_pistolB" }, { WP_GRENADE_LAUNCHER, "Stick grenade", "mp_weapon_2", 8, "ui/assets/weapon_grenade_ger.tga", "firing_pistolB_1", "stand_pistolB" }, { WP_DYNAMITE, "Explosives", "mp_item2", -1, "ui/assets/weapon_dynamite.tga", "firing_pistolB_1", "stand_pistolB" }, { WP_KAR98, "Kar98", "mp_weapon", 2, "ui/assets/weapon_kar98.tga", "stand_rifle", "stand_rifle" }, { WP_CARBINE, "M1 Garand", "mp_weapon", 2, "ui/assets/weapon_carbine.tga", "stand_rifle", "stand_rifle" }, { WP_FG42, "FG42", "mp_weapon", 7, "ui/assets/weapon_fg42.tga", "stand_rifle", "stand_rifle" }, { WP_GARAND, "M1 Garand", "mp_weapon", 8, "ui/assets/weapon_carbine.tga", "stand_rifle", "stand_rifle" }, { WP_MOBILE_MG42, "Mobile MG42", "mp_weapon", 9, "ui/assets/weapon_mg42.tga", "stand_rifle", "stand_rifle" }, { WP_LANDMINE, "Land Mines", "mp_weapon_2", 4, "ui/assets/weapon_landmine.tga", "firing_pistolB_1", "stand_pistolB" }, { WP_K43, "K43", "mp_weapon", 8, "ui/assets/weapon_kar98.tga", "stand_rifle", "stand_rifle" }, // { WP_SATCHEL, "Satchel Charges", "mp_weapon", 10, "ui/assets/weapon_satchel.tga", "firing_pistolB_1", "stand_pistolB" }, { WP_TRIPMINE, "Trip Mines", "mp_weapon", 9, "ui/assets/weapon_tripmine.tga", "firing_pistolB_1", "stand_pistolB" }, { 0, NULL, NULL, -1, NULL, NULL }, };*/ typedef struct { char *name; int flags; char *shader; } uiitemType_t; #define UI_KNIFE_PIC "window_knife_pic" #define UI_PISTOL_PIC "window_pistol_pic" #define UI_WEAPON_PIC "window_weapon_pic" #define UI_ITEM1_PIC "window_item1_pic" #define UI_ITEM2_PIC "window_item2_pic" #if 0 // rain - not used static uiitemType_t itemTypes[] = { { UI_KNIFE_PIC, PT_KNIFE, "ui/assets/weapon_knife.tga" }, { UI_PISTOL_PIC, PT_PISTOL, "ui/assets/weapon_colt1911.tga" }, { UI_WEAPON_PIC, PT_RIFLE, "ui/assets/weapon_mauser.tga" }, { UI_ITEM1_PIC, PT_MEDKIT, "ui/assets/item_medkit.tga" }, { UI_ITEM1_PIC, PT_GRENADES, "ui/assets/weapon_grenade.tga" }, { UI_ITEM2_PIC, PT_EXPLOSIVES, "ui/assets/weapon_dynamite.tga" }, { NULL, 0, NULL } }; #endif extern displayContextDef_t *DC; /* ================ vmMain 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; extern itemDef_t* g_bindItem; void _UI_Init( qboolean ); void _UI_Shutdown( void ); void _UI_KeyEvent( int key, qboolean down ); void _UI_MouseEvent( int dx, int dy ); void _UI_Refresh( int realtime ); qboolean _UI_IsFullscreen( void ); #if __GNUC__ >= 4 #pragma GCC visibility push(default) #endif int 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 ) { #if __GNUC__ >= 4 #pragma GCC visibility pop #endif 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; case UI_REFRESH: _UI_Refresh( arg0 ); return 0; case UI_IS_FULLSCREEN: return _UI_IsFullscreen(); case UI_SET_ACTIVE_MENU: _UI_SetActiveMenu( arg0 ); return 0; case UI_GET_ACTIVE_MENU: return _UI_GetActiveMenu(); case UI_CONSOLE_COMMAND: return UI_ConsoleCommand( arg0 ); case UI_DRAW_CONNECT_SCREEN: UI_DrawConnectScreen( arg0 ); return 0; case UI_HASUNIQUECDKEY: // mod authors need to observe this return qtrue; // NERVE - SMF case UI_CHECKEXECKEY: return UI_CheckExecKey( arg0 ); case UI_WANTSBINDKEYS: return ( g_waitingForKey && g_bindItem ) ? qtrue : qfalse; } return -1; } void AssetCache() { int n; //if (Assets.textFont == NULL) { //} //Assets.background = trap_R_RegisterShaderNoMip( ASSET_BACKGROUND ); //Com_Printf("Menu Size: %i bytes\n", sizeof(Menus)); uiInfo.uiDC.Assets.gradientBar = trap_R_RegisterShaderNoMip( ASSET_GRADIENTBAR ); uiInfo.uiDC.Assets.fxBasePic = trap_R_RegisterShaderNoMip( ART_FX_BASE ); uiInfo.uiDC.Assets.fxPic[0] = trap_R_RegisterShaderNoMip( ART_FX_RED ); uiInfo.uiDC.Assets.fxPic[1] = trap_R_RegisterShaderNoMip( ART_FX_YELLOW ); uiInfo.uiDC.Assets.fxPic[2] = trap_R_RegisterShaderNoMip( ART_FX_GREEN ); uiInfo.uiDC.Assets.fxPic[3] = trap_R_RegisterShaderNoMip( ART_FX_TEAL ); uiInfo.uiDC.Assets.fxPic[4] = trap_R_RegisterShaderNoMip( ART_FX_BLUE ); uiInfo.uiDC.Assets.fxPic[5] = trap_R_RegisterShaderNoMip( ART_FX_CYAN ); uiInfo.uiDC.Assets.fxPic[6] = trap_R_RegisterShaderNoMip( ART_FX_WHITE ); 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 ); uiInfo.uiDC.Assets.checkboxCheck = trap_R_RegisterShaderNoMip( ASSET_CHECKBOX_CHECK ); uiInfo.uiDC.Assets.checkboxCheckNot = trap_R_RegisterShaderNoMip( ASSET_CHECKBOX_CHECK_NOT ); uiInfo.uiDC.Assets.checkboxCheckNo = trap_R_RegisterShaderNoMip( ASSET_CHECKBOX_CHECK_NO ); for ( n = 0; n < NUM_CROSSHAIRS; n++ ) { uiInfo.uiDC.Assets.crosshairShader[n] = trap_R_RegisterShaderNoMip( va( "gfx/2d/crosshair%c", 'a' + n ) ); uiInfo.uiDC.Assets.crosshairAltShader[n] = trap_R_RegisterShaderNoMip( va( "gfx/2d/crosshair%c_alt", 'a' + n ) ); } //uiInfo.newHighScoreSound = trap_S_RegisterSound("sound/feedback/voc_newhighscore.wav"); /* for ( n = 1; weaponTypes[n].shadername; n++ ) { if ( weaponTypes[n].shadername ) trap_R_RegisterShaderNoMip( weaponTypes[n].shadername ); }*/ // -NERVE - SMF } 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_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 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 ); _UI_DrawTopBottom( x, y, width, height, size ); _UI_DrawSides( x, y, width, height, size ); trap_R_SetColor( NULL ); } // NERVE - SMF void Text_SetActiveFont( int font ) { uiInfo.activeFont = font; } int Text_Width_Ext( const char *text, float scale, int limit, fontInfo_t* font ) { int count, len; float out = 0; glyphInfo_t *glyph; const char* s = text; 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[(unsigned char)*s]; out += glyph->xSkip; s++; count++; } } } return out * scale * font->glyphScale; } int Text_Width( const char *text, float scale, int limit ) { fontInfo_t *font = &uiInfo.uiDC.Assets.fonts[uiInfo.activeFont]; return Text_Width_Ext( text, scale, limit, font ); } int Multiline_Text_Width( const char *text, float scale, int limit ) { int count, len; float out = 0; float width, widest = 0; glyphInfo_t *glyph; const char* s = text; fontInfo_t *font = &uiInfo.uiDC.Assets.fonts[uiInfo.activeFont]; 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 { if ( *s == '\n' ) { width = out * scale * font->glyphScale; if ( width > widest ) { widest = width; } out = 0; } else { glyph = &font->glyphs[(unsigned char)*s]; out += glyph->xSkip; } s++; count++; } } } if ( widest > 0 ) { width = out * scale * font->glyphScale; if ( width > widest ) { widest = width; } return widest; } else { return out * scale * font->glyphScale; } } int Text_Height_Ext( const char *text, float scale, int limit, fontInfo_t* font ) { int len, count; float max; glyphInfo_t *glyph; const char *s = text; 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[(unsigned char)*s]; // NERVE - SMF - this needs to be an unsigned cast for localization if ( max < glyph->height ) { max = glyph->height; } s++; count++; } } } return max * scale * font->glyphScale; } int Text_Height( const char *text, float scale, int limit ) { fontInfo_t *font = &uiInfo.uiDC.Assets.fonts[uiInfo.activeFont]; return Text_Height_Ext( text, scale, limit, font ); } int Multiline_Text_Height( const char *text, float scale, int limit ) { int len, count; float max; float totalheight = 0; glyphInfo_t *glyph; const char *s = text; fontInfo_t *font = &uiInfo.uiDC.Assets.fonts[uiInfo.activeFont]; 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 { if ( *s == '\n' ) { if ( !totalheight ) { totalheight += 5; // 5 is the vertical spacing that autowrap painting uses } totalheight += max; max = 0; } else { glyph = &font->glyphs[(unsigned char)*s]; // NERVE - SMF - this needs to be an unsigned cast for localization if ( max < glyph->height ) { max = glyph->height; } } s++; count++; } } } if ( totalheight > 0 ) { if ( !totalheight ) { totalheight += 5; // 5 is the vertical spacing that autowrap painting uses } totalheight += max; return totalheight * scale * font->glyphScale; } else { return max * scale * font->glyphScale; } } void Text_PaintCharExt( float x, float y, float w, float h, float scalex, float scaley, float s, float t, float s2, float t2, qhandle_t hShader ) { w *= scalex; h *= scaley; UI_AdjustFrom640( &x, &y, &w, &h ); trap_R_DrawStretchPic( x, y, w, h, s, t, s2, t2, hShader ); } void Text_PaintChar( float x, float y, float w, float h, float scale, float s, float t, float s2, float t2, qhandle_t hShader ) { w *= scale; h *= scale; UI_AdjustFrom640( &x, &y, &w, &h ); trap_R_DrawStretchPic( x, y, w, h, s, t, s2, t2, hShader ); } void Text_Paint_Ext( float x, float y, float scalex, float scaley, vec4_t color, const char *text, float adjust, int limit, int style, fontInfo_t* font ) { int len, count; vec4_t newColor; glyphInfo_t *glyph; int index; scalex *= font->glyphScale; scaley *= font->glyphScale; if ( text ) { const char *s = text; 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 ) { index = (unsigned char)*s; // NERVE - SMF - don't draw tabs and newlines if ( index < 20 ) { s++; count++; continue; } glyph = &font->glyphs[index]; if ( Q_IsColorString( s ) ) { if ( *( s + 1 ) == COLOR_NULL ) { memcpy( &newColor[0], &color[0], sizeof( vec4_t ) ); } else { memcpy( newColor, g_color_table[ColorIndex( *( s + 1 ) )], sizeof( newColor ) ); newColor[3] = color[3]; } trap_R_SetColor( newColor ); s += 2; continue; } else { float yadj = scaley * 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_PaintCharExt( x + ( glyph->pitch * scalex ) + ofs, y - yadj + ofs, glyph->imageWidth, glyph->imageHeight, scalex, scaley, glyph->s, glyph->t, glyph->s2, glyph->t2, glyph->glyph ); trap_R_SetColor( newColor ); colorBlack[3] = 1.0; } Text_PaintCharExt( x + ( glyph->pitch * scalex ), y - yadj, glyph->imageWidth, glyph->imageHeight, scalex, scaley, glyph->s, glyph->t, glyph->s2, glyph->t2, glyph->glyph ); x += ( glyph->xSkip * scalex ) + adjust; s++; count++; } } trap_R_SetColor( NULL ); } } void Text_Paint( float x, float y, float scale, vec4_t color, const char *text, float adjust, int limit, int style ) { fontInfo_t *font = &uiInfo.uiDC.Assets.fonts[uiInfo.activeFont]; Text_Paint_Ext( x, y, scale, scale, color, text, adjust, limit, style, font ); } // copied over from Text_Paint // we use the bulk of Text_Paint to determine were we will hit the max width // can be used for actual text printing, or dummy run to get the number of lines // returns the next char to be printed after wrap, or the ending \0 of the string // NOTE: this is clearly non-optimal implementation, see Item_Text_AutoWrap_Paint for one // if color_save != NULL, use to keep track of the current color between wraps char* Text_AutoWrap_Paint_Chunk( float x, float y, int width, float scale, vec4_t color, char *text, float adjust, int limit, int style, qboolean dummy, vec4_t color_save ) { int len, count; vec4_t newColor; glyphInfo_t *glyph; float useScale; fontInfo_t *font = &uiInfo.uiDC.Assets.fonts[uiInfo.activeFont]; int index; char *wrap_point = NULL; float wrap_x = x + width; useScale = scale * font->glyphScale; if ( text ) { char *s = text; 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 ) { index = (unsigned char)*s; if ( *s == ' ' || *s == '\t' || *s == '\n' ) { wrap_point = s; } // NERVE - SMF - don't draw tabs and newlines if ( index < 20 ) { s++; count++; continue; } glyph = &font->glyphs[index]; // NERVE - SMF - this needs to be an unsigned cast for localization if ( Q_IsColorString( s ) ) { if ( *( s + 1 ) == COLOR_NULL ) { memcpy( &newColor[0], &color[0], sizeof( vec4_t ) ); } else { memcpy( newColor, g_color_table[ColorIndex( *( s + 1 ) )], sizeof( newColor ) ); newColor[3] = color[3]; } if ( !dummy ) { trap_R_SetColor( newColor ); } if ( color_save ) { memcpy( &color_save[0], &newColor[0], sizeof( vec4_t ) ); } s += 2; continue; } else { float yadj = useScale * glyph->top; if ( x + ( glyph->xSkip * useScale ) + adjust > wrap_x ) { if ( wrap_point ) { return wrap_point + 1; // the next char to be printed after line wrap } // we haven't found the wrap point .. cut return s; } if ( !dummy ) { 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; } 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++; } } if ( !dummy ) { trap_R_SetColor( NULL ); } } return text + strlen( text ); } // count the lines that we will need to have to print with the given wrap parameters int Count_Text_AutoWrap_Paint( float x, float y, int width, float scale, vec4_t color, const char *text, float adjust, int style ) { const char *ret, *end; int i = 0; ret = text; end = text + strlen( text ); do { ret = Text_AutoWrap_Paint_Chunk( x, y, width, scale, color, (char *)ret, adjust, 0, style, qtrue, NULL ); i++; } while ( ret < end ); return i; } void Text_AutoWrap_Paint( float x, float y, int width, int height, float scale, vec4_t color, const char *l_text, float adjust, int style ) { char text[1024]; char *ret, *end, *next; char s; vec4_t aux_color, next_color; Q_strncpyz( text, l_text, sizeof( text ) - 1 ); ret = text; end = text + strlen( text ); memcpy( &aux_color[0], &color[0], sizeof( vec4_t ) ); do { // one run to get the word wrap next = Text_AutoWrap_Paint_Chunk( x, y, width, scale, aux_color, ret, adjust, 0, style, qtrue, next_color ); // now print - hack around a bit to avoid the word wrapped chars s = *next; *next = '\0'; Text_Paint( x, y, scale, aux_color, ret, adjust, 0, style ); *next = s; ret = next; memcpy( &aux_color[0], &next_color[0], sizeof( vec4_t ) ); y += height; } while ( ret < end ); } 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.fonts[uiInfo.activeFont]; useScale = scale * font->glyphScale; if ( text ) { const char *s = text; 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[(unsigned char)cursor]; while ( s && *s && count < len ) { glyph = &font->glyphs[(unsigned char)*s]; // NERVE - SMF - this needs to be an unsigned cast for localization //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*/{ 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 + ( glyph->pitch * useScale ) + 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 ); } Text_PaintChar( x + ( glyph->pitch * useScale ), 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 + ( glyph->pitch * useScale ), 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 + ( glyph2->pitch * useScale ), y - yadj, glyph2->imageWidth, glyph2->imageHeight, useScale, glyph2->s, glyph2->t, glyph2->s2, glyph2->t2, glyph2->glyph ); } trap_R_SetColor( NULL ); } } 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; float max = *maxX; float useScale; fontInfo_t *font = &uiInfo.uiDC.Assets.fonts[uiInfo.activeFont]; 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[(unsigned char)*s]; // NERVE - SMF - this needs to be an unsigned cast for localization if ( Q_IsColorString( s ) ) { if ( *( s + 1 ) == COLOR_NULL ) { memcpy( &newColor[0], &color[0], sizeof( vec4_t ) ); } else { 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 + ( glyph->pitch * useScale ), 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++; } } trap_R_SetColor( NULL ); } } 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 ); } /* ================= _UI_Refresh ================= */ 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 ); } 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 ) { 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 ( trap_Cvar_VariableValue( "ui_connecting" ) ) { UI_DrawLoadPanel( qtrue, qfalse, qtrue ); if ( !trap_Cvar_VariableValue( "ui_connecting" ) ) { trap_Cvar_Set( "ui_connecting", "1" ); } return; } // OSP - blackout if speclocked if ( ui_blackout.integer > 0 ) { UI_FillRect( -10, -10, 650, 490, colorBlack ); } 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 ); if ( Menu_Count() > 0 ) { uiClientState_t cstate; trap_GetClientState( &cstate ); if ( cstate.connState <= CA_DISCONNECTED || cstate.connState >= CA_ACTIVE ) { UI_DrawHandlePic( uiInfo.uiDC.cursorx, uiInfo.uiDC.cursory, 32, 32, uiInfo.uiDC.Assets.cursor ); } } } /* ================= _UI_Shutdown ================= */ void _UI_Shutdown( void ) { trap_LAN_SaveCachedServers(); } 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; } qboolean Asset_Parse( int handle ) { pc_token_t token; const char *tempStr; if ( !trap_PC_ReadToken( handle, &token ) ) { return qfalse; } if ( Q_stricmp( token.string, "{" ) != 0 ) { return qfalse; } while ( 1 ) { memset( &token, 0, sizeof( pc_token_t ) ); if ( !trap_PC_ReadToken( handle, &token ) ) { return qfalse; } if ( Q_stricmp( token.string, "}" ) == 0 ) { return qtrue; } // font if ( Q_stricmp( token.string, "font" ) == 0 ) { int pointSize, fontIndex; if ( !PC_Int_Parse( handle, &fontIndex ) || !PC_String_Parse( handle, &tempStr ) || !PC_Int_Parse( handle, &pointSize ) ) { return qfalse; } if ( fontIndex < 0 || fontIndex >= 6 ) { return qfalse; } trap_R_RegisterFont( tempStr, pointSize, &uiInfo.uiDC.Assets.fonts[fontIndex] ); uiInfo.uiDC.Assets.fontRegistered = qtrue; continue; } // 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; } // enterMenuSound if ( Q_stricmp( token.string, "menuEnterSound" ) == 0 ) { if ( !PC_String_Parse( handle, &tempStr ) ) { return qfalse; } uiInfo.uiDC.Assets.menuEnterSound = trap_S_RegisterSound( tempStr, qtrue ); continue; } // exitMenuSound if ( Q_stricmp( token.string, "menuExitSound" ) == 0 ) { if ( !PC_String_Parse( handle, &tempStr ) ) { return qfalse; } uiInfo.uiDC.Assets.menuExitSound = trap_S_RegisterSound( tempStr, qtrue ); 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, qtrue ); continue; } // menuBuzzSound if ( Q_stricmp( token.string, "menuBuzzSound" ) == 0 ) { if ( !PC_String_Parse( handle, &tempStr ) ) { return qfalse; } uiInfo.uiDC.Assets.menuBuzzSound = trap_S_RegisterSound( tempStr, qtrue ); continue; } 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; } continue; } if ( Q_stricmp( token.string, "fadeCycle" ) == 0 ) { if ( !PC_Int_Parse( handle, &uiInfo.uiDC.Assets.fadeCycle ) ) { return qfalse; } continue; } if ( Q_stricmp( token.string, "fadeAmount" ) == 0 ) { if ( !PC_Float_Parse( handle, &uiInfo.uiDC.Assets.fadeAmount ) ) { return qfalse; } continue; } 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; } 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; } } return qfalse; } void UI_Report() { String_Report(); } void QDECL Com_DPrintf( const char *fmt, ... ); qboolean UI_ParseMenu( const char *menuFile ) { int handle; pc_token_t token; Com_DPrintf( "Parsing menu file: %s\n", menuFile ); handle = trap_PC_LoadSource( menuFile ); if ( !handle ) { return qfalse; } while ( 1 ) { memset( &token, 0, sizeof( pc_token_t ) ); if ( !trap_PC_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; //} 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 ); } } trap_PC_FreeSource( handle ); return qtrue; } qboolean Load_Menu( int handle ) { pc_token_t token; #ifdef LOCALIZATION_SUPPORT int cl_language; // NERVE - SMF #endif // LOCALIZATION_SUPPORT if ( !trap_PC_ReadToken( handle, &token ) ) { return qfalse; } if ( token.string[0] != '{' ) { return qfalse; } while ( 1 ) { if ( !trap_PC_ReadToken( handle, &token ) ) { return qfalse; } if ( token.string[0] == 0 ) { return qfalse; } if ( token.string[0] == '}' ) { return qtrue; } #ifdef LOCALIZATION_SUPPORT // NERVE - SMF - localization crap cl_language = atoi( UI_Cvar_VariableString( "cl_language" ) ); if ( cl_language ) { const char *s = NULL; // TTimo: init const char *filename; char out[256]; // char filename[256]; COM_StripFilename( token.string, out ); filename = COM_SkipPath( token.string ); if ( cl_language == 1 ) { s = va( "%s%s", out, "french/" ); } else if ( cl_language == 2 ) { s = va( "%s%s", out, "german/" ); } else if ( cl_language == 3 ) { s = va( "%s%s", out, "italian/" ); } else if ( cl_language == 4 ) { s = va( "%s%s", out, "spanish/" ); } if ( UI_ParseMenu( va( "%s%s", s, filename ) ) ) { continue; } } // -NERVE #endif // LOCALIZATION_SUPPORT UI_ParseMenu( token.string ); } return qfalse; } void UI_LoadMenus( const char *menuFile, qboolean reset ) { pc_token_t token; int handle; int start; uiClientState_t cstate; start = trap_Milliseconds(); trap_GetClientState( &cstate ); if ( cstate.connState <= CA_DISCONNECTED ) { trap_PC_AddGlobalDefine( "FUI" ); } handle = trap_PC_LoadSource( menuFile ); if ( !handle ) { trap_Error( va( S_COLOR_YELLOW "menu file not found: %s, using default\n", menuFile ) ); handle = trap_PC_LoadSource( "ui/menus.txt" ); if ( !handle ) { trap_Error( S_COLOR_RED "default menu file not found: ui_mp/menus.txt, unable to continue!\n" ); } } ui_new.integer = 1; if ( reset ) { Menu_Reset(); } while ( 1 ) { if ( !trap_PC_ReadToken( handle, &token ) ) { break; } 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_DPrintf( "UI menu load time = %d milli seconds\n", trap_Milliseconds() - start ); trap_PC_FreeSource( handle ); } void UI_Load() { 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"; } String_Init(); UI_ParseGameInfo( "gameinfo.txt" ); UI_LoadArenas(); UI_LoadCampaigns(); UI_LoadMenus( menuSet, qtrue ); Menus_CloseAll(); Menus_ActivateByName( lastName, qtrue ); } 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}; //static int numHandicaps = sizeof(handicapValues) / sizeof(const char*); // TTimo: unused static void UI_DrawHandicap( rectDef_t *rect, float scale, vec4_t color, int textStyle ) { int i, h; h = Com_Clamp( 5, 100, trap_Cvar_VariableValue( "handicap" ) ); i = 20 - h / 5; Text_Paint( rect->x, rect->y, scale, color, handicapValues[i], 0, 0, textStyle ); } 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 ); } static void UI_SetCapFragLimits( qboolean uiVars ) { } // 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 ); } /*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); }*/ /*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, trap_TranslateString( uiInfo.joinGameTypes[ui_joinGameType.integer].gameType ), 0, 0, textStyle); }*/ static int UI_TeamIndexFromName( const char *name ) { int i; if ( name && *name ) { for ( i = 0; i < uiInfo.teamCount; i++ ) { if ( Q_stricmp( name, uiInfo.teamList[i].teamName ) == 0 ) { return i; } } } return 0; } /* ============== UI_DrawSaveGameShot ============== */ static void UI_DrawSaveGameShot( rectDef_t *rect, float scale, vec4_t color ) { trap_R_SetColor( color ); UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.savegameList[uiInfo.savegameIndex].sshotImage ); trap_R_SetColor( NULL ); } /* ============== UI_DrawClanLogo ============== */ 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 ); 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_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.teamList[i].teamIcon ); trap_R_SetColor( NULL ); } } /* ============== UI_DrawClanCinematic ============== */ 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 ) { 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 { 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 ); } } } 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; } } } /*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); }*/ 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 ); } } static void UI_DrawTeamMember( rectDef_t *rect, float scale, vec4_t color, qboolean blue, int num, int textStyle ) { } static void UI_DrawEffects( rectDef_t *rect, float scale, vec4_t color ) { UI_DrawHandlePic( rect->x, rect->y, 128, 8, uiInfo.uiDC.Assets.fxBasePic ); UI_DrawHandlePic( rect->x + uiInfo.effectsColor * 16 + 8, rect->y, 16, 12, uiInfo.uiDC.Assets.fxPic[uiInfo.effectsColor] ); } void UI_DrawMapPreview( rectDef_t *rect, float scale, vec4_t color, qboolean net ) { int map = ( net ) ? ui_currentNetMap.integer : ui_currentMap.integer; int game = net ? ui_netGameType.integer : uiInfo.gameTypes[ui_gameType.integer].gtEnum; if ( game == GT_WOLF_CAMPAIGN ) { if ( map < 0 || map > uiInfo.campaignCount ) { 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 ( uiInfo.campaignList[map].mapTC[0][0] && uiInfo.campaignList[map].mapTC[1][0] ) { float x, y, w, h; int i; x = rect->x; y = rect->y; w = rect->w; h = rect->h; UI_AdjustFrom640( &x, &y, &w, &h ); trap_R_DrawStretchPic( x, y, w, h, uiInfo.campaignList[map].mapTC[0][0] / 1024.f, uiInfo.campaignList[map].mapTC[0][1] / 1024.f, uiInfo.campaignList[map].mapTC[1][0] / 1024.f, uiInfo.campaignList[map].mapTC[1][1] / 1024.f, uiInfo.campaignMap ); for ( i = 0; i < uiInfo.campaignList[map].mapCount; i++ ) { vec4_t colourFadedBlack = { 0.f, 0.f, 0.f, 0.4f }; x = rect->x + ( ( uiInfo.campaignList[map].mapInfos[i]->mappos[0] - uiInfo.campaignList[map].mapTC[0][0] ) / 650.f * rect->w ); y = rect->y + ( ( uiInfo.campaignList[map].mapInfos[i]->mappos[1] - uiInfo.campaignList[map].mapTC[0][1] ) / 650.f * rect->h ); w = Text_Width( uiInfo.campaignList[map].mapInfos[i]->mapName, scale, 0 ); if ( x + 10 + w > rect->x + rect->w ) { UI_FillRect( x - w - 12 + 1, y - 6 + 1, 12 + w, 12, colourFadedBlack ); UI_FillRect( x - w - 12, y - 6, 12 + w, 12, colorBlack ); } else { UI_FillRect( x + 1, y - 6 + 1, 12 + w, 12, colourFadedBlack ); UI_FillRect( x, y - 6, 12 + w, 12, colorBlack ); } UI_DrawHandlePic( x - 8, y - 8, 16, 16, trap_R_RegisterShaderNoMip( "gfx/loading/pin_neutral" ) ); if ( x + 10 + w > rect->x + rect->w ) { Text_Paint( x - w - 10, y + 3, scale, colorWhite, uiInfo.campaignList[map].mapInfos[i]->mapName, 0, 0, 0 ); } else { Text_Paint( x + 10, y + 3, scale, colorWhite, uiInfo.campaignList[map].mapInfos[i]->mapName, 0, 0, 0 ); } } } else { UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, trap_R_RegisterShaderNoMip( "levelshots/unknownmap" ) ); } return; } 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 ( uiInfo.mapList[map].mappos[0] && uiInfo.mapList[map].mappos[1] ) { float x, y, w, h; vec2_t tl, br; vec4_t colourFadedBlack = { 0.f, 0.f, 0.f, 0.4f }; tl[0] = uiInfo.mapList[map].mappos[0] - .5 * 650.f; if ( tl[0] < 0 ) { tl[0] = 0; } br[0] = tl[0] + 650.f; if ( br[0] > 1024.f ) { br[0] = 1024.f; tl[0] = br[0] - 650.f; } tl[1] = uiInfo.mapList[map].mappos[1] - .5 * 650.f; if ( tl[1] < 0 ) { tl[1] = 0; } br[1] = tl[1] + 650.f; if ( br[1] > 1024.f ) { br[1] = 1024.f; tl[1] = br[1] - 650.f; } x = rect->x; y = rect->y; w = rect->w; h = rect->h; UI_AdjustFrom640( &x, &y, &w, &h ); trap_R_DrawStretchPic( x, y, w, h, tl[0] / 1024.f, tl[1] / 1024.f, br[0] / 1024.f, br[1] / 1024.f, uiInfo.campaignMap ); x = rect->x + ( ( uiInfo.mapList[map].mappos[0] - tl[0] ) / 650.f * rect->w ); y = rect->y + ( ( uiInfo.mapList[map].mappos[1] - tl[1] ) / 650.f * rect->h ); w = Text_Width( uiInfo.mapList[map].mapName, scale, 0 ); if ( x + 10 + w > rect->x + rect->w ) { UI_FillRect( x - w - 12 + 1, y - 6 + 1, 12 + w, 12, colourFadedBlack ); UI_FillRect( x - w - 12, y - 6, 12 + w, 12, colorBlack ); } else { UI_FillRect( x + 1, y - 6 + 1, 12 + w, 12, colourFadedBlack ); UI_FillRect( x, y - 6, 12 + w, 12, colorBlack ); } UI_DrawHandlePic( x - 8, y - 8, 16, 16, trap_R_RegisterShaderNoMip( "gfx/loading/pin_neutral" ) ); if ( x + 10 + w > rect->x + rect->w ) { Text_Paint( x - w - 10, y + 3, scale, colorWhite, uiInfo.mapList[map].mapName, 0, 0, 0 ); } else { Text_Paint( x + 10, y + 3, scale, colorWhite, uiInfo.mapList[map].mapName, 0, 0, 0 ); } } else { UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, trap_R_RegisterShaderNoMip( "levelshots/unknownmap" ) ); } /*if (uiInfo.mapList[map].levelShot == -1) { uiInfo.mapList[map].levelShot = trap_R_RegisterShaderNoMip(uiInfo.mapList[map].imageName); } 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("levelshots/unknownmap")); }*/ } void UI_DrawNetMapPreview( rectDef_t *rect, float scale, vec4_t color, qboolean net ) { 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( "levelshots/unknownmap" ) ); } } /*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"); } time = uiInfo.mapList[ui_currentMap.integer].timeToBeat[uiInfo.gameTypes[ui_gameType.integer].gtEnum]; minutes = time / 60; seconds = time % 60; Text_Paint(rect->x, rect->y, scale, color, va("%02i:%02i", minutes, seconds), 0, 0, textStyle); }*/ static void UI_DrawMapCinematic( rectDef_t *rect, float scale, vec4_t color, qboolean net ) { int map = ( net ) ? ui_currentNetMap.integer : ui_currentMap.integer; int game = net ? ui_netGameType.integer : uiInfo.gameTypes[ui_gameType.integer].gtEnum; if ( game == GT_WOLF_CAMPAIGN ) { if ( map < 0 || map > uiInfo.campaignCount ) { 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( uiInfo.campaignList[map].campaignCinematic >= -1 ) { if( uiInfo.campaignList[map].campaignCinematic == -1 ) { uiInfo.campaignList[map].campaignCinematic = trap_CIN_PlayCinematic(va("%s.roq", uiInfo.campaignList[map].campaignShortName), 0, 0, 0, 0, (CIN_loop | CIN_silent) ); } if( uiInfo.campaignList[map].campaignCinematic >= 0 ) { trap_CIN_RunCinematic( uiInfo.campaignList[map].campaignCinematic ); trap_CIN_SetExtents( uiInfo.campaignList[map].campaignCinematic, rect->x, rect->y, rect->w, rect->h ); trap_CIN_DrawCinematic( uiInfo.campaignList[map].campaignCinematic ); } else { uiInfo.campaignList[map].campaignCinematic = -2; } } else*/{ UI_DrawMapPreview( rect, scale, color, net ); } return; } 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 ( 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 ); } } static void UI_DrawCampaignPreview( rectDef_t *rect, float scale, vec4_t color, qboolean net ) { int campaign = ( net ) ? ui_currentNetCampaign.integer : ui_currentCampaign.integer; if ( campaign < 0 || campaign > uiInfo.campaignCount ) { if ( net ) { ui_currentNetCampaign.integer = 0; trap_Cvar_Set( "ui_currentNetCampaign", "0" ); } else { ui_currentCampaign.integer = 0; trap_Cvar_Set( "ui_currentCampaign", "0" ); } campaign = 0; } if ( uiInfo.campaignList[campaign].campaignShot == -1 ) { uiInfo.campaignList[campaign].campaignShot = trap_R_RegisterShaderNoMip( uiInfo.campaignList[campaign].campaignShotName ); } if ( uiInfo.campaignList[campaign].campaignShot > 0 ) { UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.campaignList[campaign].campaignShot ); } else { UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, trap_R_RegisterShaderNoMip( "levelshots/unknownmap" ) ); } } static void UI_DrawCampaignCinematic( rectDef_t *rect, float scale, vec4_t color, qboolean net ) { int campaign = ( net ) ? ui_currentNetCampaign.integer : ui_currentCampaign.integer; if ( campaign < 0 || campaign > uiInfo.campaignCount ) { if ( net ) { ui_currentNetCampaign.integer = 0; trap_Cvar_Set( "ui_currentNetCampaign", "0" ); } else { ui_currentCampaign.integer = 0; trap_Cvar_Set( "ui_currentCampaign", "0" ); } campaign = 0; } if ( uiInfo.campaignList[campaign].campaignCinematic >= -1 ) { if ( uiInfo.campaignList[campaign].campaignCinematic == -1 ) { uiInfo.campaignList[campaign].campaignCinematic = trap_CIN_PlayCinematic( va( "%s.roq", uiInfo.campaignList[campaign].campaignShortName ), 0, 0, 0, 0, ( CIN_loop | CIN_silent ) ); } if ( uiInfo.campaignList[campaign].campaignCinematic >= 0 ) { trap_CIN_RunCinematic( uiInfo.campaignList[campaign].campaignCinematic ); trap_CIN_SetExtents( uiInfo.campaignList[campaign].campaignCinematic, rect->x, rect->y, rect->w, rect->h ); trap_CIN_DrawCinematic( uiInfo.campaignList[campaign].campaignCinematic ); } else { uiInfo.campaignList[campaign].campaignCinematic = -2; } } else { UI_DrawCampaignPreview( rect, scale, color, net ); } } static void UI_DrawCampaignName( rectDef_t *rect, float scale, vec4_t color, int textStyle, qboolean net ) { int campaign = ( net ) ? ui_currentNetCampaign.integer : ui_currentCampaign.integer; if ( campaign < 0 || campaign > uiInfo.campaignCount ) { if ( net ) { ui_currentNetCampaign.integer = 0; trap_Cvar_Set( "ui_currentNetCampaign", "0" ); } else { ui_currentCampaign.integer = 0; trap_Cvar_Set( "ui_currentCampaign", "0" ); } campaign = 0; } if ( !uiInfo.campaignList[campaign].unlocked ) { return; } Text_Paint( rect->x, rect->y, scale, color, va( "%s", uiInfo.campaignList[campaign].campaignName ), 0, 0, textStyle ); } void UI_DrawCampaignDescription( rectDef_t *rect, float scale, vec4_t color, float text_x, float text_y, int textStyle, int align, qboolean net ) { const char *p, *textPtr, *newLinePtr = NULL; char buff[1024]; int height, len, textWidth, newLine, newLineWidth; float y; rectDef_t textRect; int game = ( net ) ? ui_netGameType.integer : ui_netGameType.integer; if ( game == GT_WOLF_CAMPAIGN ) { int campaign = ( net ) ? ui_currentNetMap.integer : ui_currentMap.integer; textPtr = uiInfo.campaignList[campaign].campaignDescription; } else if ( game == GT_WOLF_LMS ) { int map = ( net ) ? ui_currentNetMap.integer : ui_currentMap.integer; textPtr = uiInfo.mapList[map].lmsbriefing; } else { int map = ( net ) ? ui_currentNetMap.integer : ui_currentMap.integer; textPtr = uiInfo.mapList[map].briefing; } if ( !textPtr || !*textPtr ) { textPtr = "^1No text supplied"; } height = Text_Height( textPtr, scale, 0 ); textRect.x = 0; textRect.y = 0; textRect.w = rect->w; textRect.h = rect->h; //y = text_y; y = 0; len = 0; buff[0] = '\0'; newLine = 0; newLineWidth = 0; p = textPtr; while ( p ) { textWidth = DC->textWidth( buff, scale, 0 ); if ( *p == ' ' || *p == '\t' || *p == '\n' || *p == '\0' || *p == '*' ) { newLine = len; newLinePtr = p + 1; newLineWidth = textWidth; }/* else if( *p == '*' && *(p+1) == '*' ) { newLine = len; newLinePtr = p+2; newLineWidth = textWidth; }*/ if ( ( newLine && textWidth > rect->w ) || *p == '\n' || *p == '\0' || *p == '*' /*( *p == '*' && *(p+1) == '*' )*/ ) { if ( len ) { if ( align == ITEM_ALIGN_LEFT ) { textRect.x = text_x; } else if ( align == ITEM_ALIGN_RIGHT ) { textRect.x = text_x - newLineWidth; } else if ( align == ITEM_ALIGN_CENTER ) { textRect.x = text_x - newLineWidth / 2; } textRect.y = y; textRect.x += rect->x; textRect.y += rect->y; // buff[newLine] = '\0'; DC->drawText( textRect.x, textRect.y, scale, color, buff, 0, 0, textStyle ); } if ( *p == '\0' ) { break; } // y += height + 5; p = newLinePtr; len = 0; newLine = 0; newLineWidth = 0; continue; } buff[len++] = *p++; if ( buff[len - 1] == 13 ) { buff[len - 1] = ' '; } buff[len] = '\0'; } } void UI_DrawGametypeDescription( rectDef_t *rect, float scale, vec4_t color, float text_x, float text_y, int textStyle, int align, qboolean net ) { const char *p, *textPtr = NULL, *newLinePtr = NULL; char buff[1024]; int height, len, textWidth, newLine, newLineWidth, i; float y; rectDef_t textRect; int game = ( net ) ? ui_netGameType.integer : ui_netGameType.integer; for ( i = 0; i < uiInfo.numGameTypes; i++ ) { if ( uiInfo.gameTypes[i].gtEnum == game ) { textPtr = uiInfo.gameTypes[i].gameTypeDescription; break; } } if ( i == uiInfo.numGameTypes ) { textPtr = "Unknown"; } height = Text_Height( textPtr, scale, 0 ); textRect.x = 0; textRect.y = 0; textRect.w = rect->w; textRect.h = rect->h; //y = text_y; y = 0; len = 0; buff[0] = '\0'; newLine = 0; newLineWidth = 0; p = textPtr; while ( p ) { textWidth = DC->textWidth( buff, scale, 0 ); if ( *p == ' ' || *p == '\t' || *p == '\n' || *p == '\0' ) { newLine = len; newLinePtr = p + 1; newLineWidth = textWidth; } else if ( *p == '*' && *( p + 1 ) == '*' ) { newLine = len; newLinePtr = p + 2; newLineWidth = textWidth; } if ( ( newLine && textWidth > rect->w ) || *p == '\n' || *p == '\0' || ( *p == '*' && *( p + 1 ) == '*' ) ) { if ( len ) { if ( align == ITEM_ALIGN_LEFT ) { textRect.x = text_x; } else if ( align == ITEM_ALIGN_RIGHT ) { textRect.x = text_x - newLineWidth; } else if ( align == ITEM_ALIGN_CENTER ) { textRect.x = text_x - newLineWidth / 2; } textRect.y = y; textRect.x += rect->x; textRect.y += rect->y; // buff[newLine] = '\0'; DC->drawText( textRect.x, textRect.y, scale, color, buff, 0, 0, textStyle ); } if ( *p == '\0' ) { break; } // y += height + 5; p = newLinePtr; len = 0; newLine = 0; newLineWidth = 0; continue; } buff[len++] = *p++; if ( buff[len - 1] == 13 ) { buff[len - 1] = ' '; } buff[len] = '\0'; } } static void UI_DrawCampaignMapDescription( rectDef_t *rect, float scale, vec4_t color, float text_x, float text_y, int textStyle, int align, qboolean net, int number ) { int campaign = ( net ) ? ui_currentNetCampaign.integer : ui_currentCampaign.integer; const char *p, *textPtr, *newLinePtr; char buff[1024]; int height, len, textWidth, newLine, newLineWidth; float y; rectDef_t textRect; if ( campaign < 0 || campaign > uiInfo.campaignCount ) { if ( net ) { ui_currentNetCampaign.integer = 0; trap_Cvar_Set( "ui_currentNetCampaign", "0" ); } else { ui_currentCampaign.integer = 0; trap_Cvar_Set( "ui_currentCampaign", "0" ); } campaign = 0; } if ( !uiInfo.campaignList[campaign].unlocked || uiInfo.campaignList[campaign].progress < number || !uiInfo.campaignList[campaign].mapInfos[number] ) { textPtr = "No information is available for this region."; } else { textPtr = uiInfo.campaignList[campaign].mapInfos[number]->briefing; } if ( !textPtr || !*textPtr ) { textPtr = "^1No text supplied"; } height = Text_Height( textPtr, scale, 0 ); textRect.x = 0; textRect.y = 0; textRect.w = rect->w; textRect.h = rect->h; textWidth = 0; newLinePtr = NULL; y = text_y; len = 0; buff[0] = '\0'; newLine = 0; newLineWidth = 0; p = textPtr; while ( p ) { if ( *p == ' ' || *p == '\t' || *p == '\n' || *p == '\0' ) { newLine = len; newLinePtr = p + 1; newLineWidth = textWidth; } textWidth = Text_Width( buff, scale, 0 ); if ( ( newLine && textWidth > rect->w ) || *p == '\n' || *p == '\0' ) { if ( len ) { if ( align == ITEM_ALIGN_LEFT ) { textRect.x = text_x; } else if ( align == ITEM_ALIGN_RIGHT ) { textRect.x = text_x - newLineWidth; } else if ( align == ITEM_ALIGN_CENTER ) { textRect.x = text_x - newLineWidth / 2; } textRect.y = y; textRect.x += rect->x; textRect.y += rect->y; // buff[newLine] = '\0'; Text_Paint( textRect.x, textRect.y, scale, color, buff, 0, 0, textStyle ); } if ( *p == '\0' ) { break; } // y += height + 5; p = newLinePtr; len = 0; newLine = 0; newLineWidth = 0; continue; } buff[len++] = *p++; if ( buff[len - 1] == 13 ) { buff[len - 1] = ' '; } buff[len] = '\0'; } } static void UI_DrawCampaignMapPreview( rectDef_t *rect, float scale, vec4_t color, qboolean net, int map ) { int campaign = ( net ) ? ui_currentNetCampaign.integer : ui_currentCampaign.integer; if ( campaign < 0 || campaign > uiInfo.campaignCount ) { if ( net ) { ui_currentNetCampaign.integer = 0; trap_Cvar_Set( "ui_currentNetCampaign", "0" ); } else { ui_currentCampaign.integer = 0; trap_Cvar_Set( "ui_currentCampaign", "0" ); } campaign = 0; } if ( uiInfo.campaignList[campaign].mapInfos[map] && uiInfo.campaignList[campaign].mapInfos[map]->levelShot == -1 ) { uiInfo.campaignList[campaign].mapInfos[map]->levelShot = trap_R_RegisterShaderNoMip( uiInfo.campaignList[campaign].mapInfos[map]->imageName ); } if ( uiInfo.campaignList[campaign].mapInfos[map] && uiInfo.campaignList[campaign].mapInfos[map]->levelShot > 0 ) { UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.campaignList[campaign].mapInfos[map]->levelShot ); if ( uiInfo.campaignList[campaign].progress < map ) { UI_DrawHandlePic( rect->x + 8, rect->y + 8, rect->w - 16, rect->h - 16, trap_R_RegisterShaderNoMip( "gfx/2d/friendlycross.tga" ) ); } } else { UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, trap_R_RegisterShaderNoMip( "levelshots/unknownmap" ) ); if ( uiInfo.campaignList[campaign].progress < map ) { UI_DrawHandlePic( rect->x + 8, rect->y + 8, rect->w - 16, rect->h - 16, trap_R_RegisterShaderNoMip( "gfx/2d/friendlycross.tga" ) ); } } } static void UI_DrawMissionBriefingMap( rectDef_t* rect ) { char buffer[64]; static qhandle_t image = -1; if ( image == -1 ) { trap_Cvar_VariableStringBuffer( "mapname", buffer, 64 ); image = trap_R_RegisterShaderNoMip( va( "levelshots/%s_cc.tga", buffer ) ); } if ( image ) { UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, image ); } else { UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, trap_R_RegisterShaderNoMip( "levelshots/unknownmap" ) ); } } static void UI_DrawMissionBriefingTitle( rectDef_t *rect, float scale, vec4_t color, int textStyle ) { char buffer[64]; mapInfo* mi; trap_Cvar_VariableStringBuffer( "mapname", buffer, 64 ); mi = UI_FindMapInfoByMapname( buffer ); if ( !mi ) { return; } Text_Paint( rect->x, rect->y, scale, color, va( "%s Objectives", mi->mapName ), 0, 0, textStyle ); } static void UI_DrawMissionBriefingObjectives( rectDef_t *rect, float scale, vec4_t color, float text_x, float text_y, int textStyle, int align ) { const char *p, *textPtr, *newLinePtr; char buff[1024]; int height, len, textWidth, newLine, newLineWidth; float y; rectDef_t textRect; char buffer[64]; mapInfo* mi; trap_Cvar_VariableStringBuffer( "mapname", buffer, 64 ); mi = UI_FindMapInfoByMapname( buffer ); if ( !mi ) { return; } textPtr = mi->objectives; height = Text_Height( textPtr, scale, 0 ); textRect.x = 0; textRect.y = 0; textRect.w = rect->w; textRect.h = rect->h; textWidth = 0; newLinePtr = NULL; y = text_y; len = 0; buff[0] = '\0'; newLine = 0; newLineWidth = 0; p = textPtr; while ( p ) { if ( *p == ' ' || *p == '\t' || *p == '\n' || *p == '\0' ) { newLine = len; newLinePtr = p + 1; newLineWidth = textWidth; } textWidth = Text_Width( buff, scale, 0 ); if ( ( newLine && textWidth > rect->w ) || *p == '\n' || *p == '\0' ) { if ( len ) { if ( align == ITEM_ALIGN_LEFT ) { textRect.x = text_x; } else if ( align == ITEM_ALIGN_RIGHT ) { textRect.x = text_x - newLineWidth; } else if ( align == ITEM_ALIGN_CENTER ) { textRect.x = text_x - newLineWidth / 2; } textRect.y = y; textRect.x += rect->x; textRect.y += rect->y; // buff[newLine] = '\0'; Text_Paint( textRect.x, textRect.y, scale, color, buff, 0, 0, textStyle ); } if ( *p == '\0' ) { break; } // y += height + 5; p = newLinePtr; len = 0; newLine = 0; newLineWidth = 0; continue; } buff[len++] = *p++; if ( buff[len - 1] == 13 ) { buff[len - 1] = ' '; } buff[len] = '\0'; } } 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; static vec3_t moveangles = { 0, 0, 0 }; if ( trap_Cvar_VariableValue( "ui_Q3Model" ) ) { // NERVE - SMF int teamval; teamval = trap_Cvar_VariableValue( "mp_team" ); if ( teamval == ALLIES_TEAM ) { strcpy( model, "multi" ); } else { strcpy( model, "multi_axis" ); } // -NERVE - SMF strcpy( head, UI_Cvar_VariableString( "headmodel" ) ); if ( !q3Model ) { q3Model = qtrue; updateModel = qtrue; } team[0] = '\0'; } else { strcpy( model, UI_Cvar_VariableString( "team_model" ) ); strcpy( head, UI_Cvar_VariableString( "team_headmodel" ) ); strcpy( team, UI_Cvar_VariableString( "ui_teamName" ) ); if ( q3Model ) { q3Model = qfalse; updateModel = qtrue; } } moveangles[YAW] += 1; // NERVE - SMF - TEMPORARY // compare new cvars to old cvars and see if we need to update { int v1, v2; v1 = trap_Cvar_VariableValue( "mp_team" ); v2 = trap_Cvar_VariableValue( "ui_prevTeam" ); if ( v1 != v2 ) { trap_Cvar_Set( "ui_prevTeam", va( "%i", v1 ) ); updateModel = qtrue; } v1 = trap_Cvar_VariableValue( "mp_playerType" ); v2 = trap_Cvar_VariableValue( "ui_prevClass" ); if ( v1 != v2 ) { trap_Cvar_Set( "ui_prevClass", va( "%i", v1 ) ); updateModel = qtrue; } v1 = trap_Cvar_VariableValue( "mp_weapon" ); v2 = trap_Cvar_VariableValue( "ui_prevWeapon" ); if ( v1 != v2 ) { trap_Cvar_Set( "ui_prevWeapon", va( "%i", v1 ) ); updateModel = qtrue; } } if ( updateModel ) { // NERVE - SMF - TEMPORARY memset( &info, 0, sizeof( playerInfo_t ) ); viewangles[YAW] = 180 - 10; viewangles[PITCH] = 0; viewangles[ROLL] = 0; // VectorClear( moveangles ); UI_PlayerInfo_SetModel( &info, model ); UI_PlayerInfo_SetInfo( &info, LEGS_IDLE, TORSO_STAND, viewangles, moveangles, -1, qfalse ); // UI_RegisterClientModelname( &info, model, head, team); updateModel = qfalse; } else { VectorCopy( moveangles, info.moveAngles ); } // info.moveAngles[YAW] += 1; // UI_PlayerInfo_SetInfo( &info, LEGS_IDLE, TORSO_STAND, viewangles, moveangles, WP_MP40, qfalse ); UI_DrawPlayer( rect->x, rect->y, rect->w, rect->h, &info, uiInfo.uiDC.realTime / 2 ); } /*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, trap_TranslateString( va("Source: %s", netSources[ui_netSource.integer]) ), 0, 0, textStyle); }*/ /*static void UI_DrawNetMapPreview(rectDef_t *rect, float scale, vec4_t color) { 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("levelshots/unknownmap")); } }*/ /*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); } }*/ 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 ); } /*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); } 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; } if (uiInfo.tierList[i].mapHandles[index] == -1) { uiInfo.tierList[i].mapHandles[index] = trap_R_RegisterShaderNoMip(va("levelshots/%s", uiInfo.tierList[i].maps[index])); } UI_DrawHandlePic( rect->x, rect->y, rect->w, rect->h, uiInfo.tierList[i].mapHandles[index]); } 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; } } 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); } 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); }*/ /* // TTimo: unused static const char *UI_OpponentLeaderName() { int i = UI_TeamIndexFromName(UI_Cvar_VariableString("ui_opponentName")); return uiInfo.teamList[i].teamMembers[0]; } */ /* // TTimo: unused 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; } } return "James"; } */ /* // TTimo: unused static const int UI_AIIndex(const char *name) { int j; for (j = 0; j < uiInfo.characterCount; j++) { if (Q_stricmp(name, uiInfo.characterList[j].name) == 0) { return j; } } return 0; } */ /* // TTimo: unused static const int UI_AIIndexFromName(const char *name) { int j; for (j = 0; j < uiInfo.aliasCount; j++) { if (Q_stricmp(uiInfo.aliasList[j].name, name) == 0) { return UI_AIIndex(uiInfo.aliasList[j].ai); } } return 0; } */ /* // TTimo: unused static const char *UI_OpponentLeaderHead() { const char *leader = UI_OpponentLeaderName(); return UI_AIFromName(leader); } */ /* // TTimo: unused static const char *UI_OpponentLeaderModel() { int i; const char *head = UI_OpponentLeaderHead(); for (i = 0; i < uiInfo.characterCount; i++) { if (Q_stricmp(head, uiInfo.characterList[i].name) == 0) { if (uiInfo.characterList[i].female) { return "Janet"; } else { return "James"; } } } return "James"; } */ /*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); UI_PlayerInfo_SetInfo( &info2, LEGS_IDLE, TORSO_STAND, viewangles, vec3_origin, WP_MP40, qfalse ); UI_RegisterClientModelname( &info2, model); updateOpponentModel = qfalse; } UI_DrawPlayer( rect->x, rect->y, rect->w, rect->h, &info2, uiInfo.uiDC.realTime / 2); }*/ static void UI_NextOpponent() { 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 ); } static void UI_PriorOpponent() { 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 ); } static void UI_DrawPlayerLogo( 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 ); trap_R_SetColor( NULL ); } 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 ); } 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 ); } 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 ); } 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 ); } 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 ); } static void UI_DrawAllMapsSelection( rectDef_t *rect, float scale, vec4_t color, int textStyle, qboolean net ) { } 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 ); } 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_OPPONENT_NAME: break; case UI_KEYBINDSTATUS: if ( Display_KeyBindPending() ) { s = trap_TranslateString( "Waiting for new key... Press ESCAPE to cancel" ); } else { s = trap_TranslateString( "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; } static void UI_DrawBotName( rectDef_t *rect, float scale, vec4_t color, int textStyle ) { } /*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); } }*/ 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 ); } static void UI_DrawCrosshair( rectDef_t *rect, float scale, vec4_t color ) { float size = cg_crosshairSize.integer; if ( uiInfo.currentCrosshair < 0 || uiInfo.currentCrosshair >= NUM_CROSSHAIRS ) { uiInfo.currentCrosshair = 0; } size = ( rect->w / 96.0f ) * ( ( size > 96.0f ) ? 96.0f : ( ( size < 24.0f ) ? 24.0f : size ) ); trap_R_SetColor( uiInfo.xhairColor ); UI_DrawHandlePic( rect->x + ( rect->w - size ) / 2, rect->y + ( rect->h - size ) / 2, size, size, uiInfo.uiDC.Assets.crosshairShader[uiInfo.currentCrosshair] ); trap_R_SetColor( uiInfo.xhairColorAlt ); UI_DrawHandlePic( rect->x + ( rect->w - size ) / 2, rect->y + ( rect->h - size ) / 2, size, size, uiInfo.uiDC.Assets.crosshairAltShader[uiInfo.currentCrosshair] ); trap_R_SetColor( NULL ); } /* =============== UI_BuildPlayerList =============== */ static void UI_BuildPlayerList() { uiClientState_t cs; int n, count, team, team2, playerTeamNumber, muted; char info[MAX_INFO_STRING]; char namebuf[64]; 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; playerTeamNumber = 0; for ( n = 0; n < count; n++ ) { trap_GetConfigString( CS_PLAYERS + n, info, MAX_INFO_STRING ); if ( info[0] ) { Q_strncpyz( namebuf, Info_ValueForKey( info, "n" ), sizeof( namebuf ) ); // fretn - dont expand colors twice, so: foo^^xbar -> foo^bar -> fooar // Q_CleanStr( namebuf ); Q_strncpyz( uiInfo.playerNames[uiInfo.playerCount], namebuf, sizeof( uiInfo.playerNames[0] ) ); muted = atoi( Info_ValueForKey( info, "mu" ) ); if ( muted ) { uiInfo.playerMuted[uiInfo.playerCount] = qtrue; } else { uiInfo.playerMuted[uiInfo.playerCount] = qfalse; } uiInfo.playerRefereeStatus[uiInfo.playerCount] = atoi( Info_ValueForKey( info, "ref" ) ); uiInfo.playerCount++; team2 = atoi( Info_ValueForKey( info, "t" ) ); if ( team2 == team ) { Q_strncpyz( namebuf, Info_ValueForKey( info, "n" ), sizeof( namebuf ) ); // fretn - dont expand colors twice, so: foo^^xbar -> foo^bar -> fooar // Q_CleanStr( namebuf ); Q_strncpyz( uiInfo.teamNames[uiInfo.myTeamCount], namebuf, sizeof( uiInfo.teamNames[0] ) ); uiInfo.teamClientNums[uiInfo.myTeamCount] = n; if ( uiInfo.playerNumber == n ) { playerTeamNumber = uiInfo.myTeamCount; } uiInfo.myTeamCount++; } } } if ( !uiInfo.teamLeader ) { trap_Cvar_Set( "cg_selectedPlayer", va( "%d", playerTeamNumber ) ); } 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] ); } } static void UI_DrawSelectedPlayer( rectDef_t *rect, float scale, vec4_t color, int textStyle ) { if ( uiInfo.uiDC.realTime > uiInfo.playerRefresh ) { uiInfo.playerRefresh = uiInfo.uiDC.realTime + 3000; UI_BuildPlayerList(); } Text_Paint( rect->x, rect->y, scale, color, ( uiInfo.teamLeader ) ? UI_Cvar_VariableString( "cg_selectedPlayerName" ) : UI_Cvar_VariableString( "name" ), 0, 0, textStyle ); } static void UI_DrawServerRefreshDate( rectDef_t *rect, float scale, vec4_t color, int textStyle ) { int serverCount; // NERVE - SMF 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 ) ); // NERVE - SMF serverCount = trap_LAN_GetServerCount( ui_netSource.integer ); if ( serverCount >= 0 ) { Text_Paint( rect->x, rect->y, scale, newColor, va( trap_TranslateString( "Getting info for %d servers (ESC to cancel)" ), serverCount ), 0, 0, textStyle ); } else { Text_Paint( rect->x, rect->y, scale, newColor, trap_TranslateString( "Waiting for response from Master Server" ), 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( trap_TranslateString( "Refresh Time: %s" ), buff ), 0, 0, textStyle ); } } static void UI_DrawServerMOTD( rectDef_t *rect, float scale, vec4_t color ) { if ( uiInfo.serverStatus.motdLen ) { float maxX; if ( uiInfo.serverStatus.motdWidth == -1 ) { uiInfo.serverStatus.motdWidth = 0; uiInfo.serverStatus.motdPaintX = rect->x + 1; uiInfo.serverStatus.motdPaintX2 = -1; } if ( uiInfo.serverStatus.motdOffset > uiInfo.serverStatus.motdLen ) { uiInfo.serverStatus.motdOffset = 0; uiInfo.serverStatus.motdPaintX = rect->x + 1; uiInfo.serverStatus.motdPaintX2 = -1; } 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; } } } maxX = rect->x + rect->w - 2; Text_Paint_Limit( &maxX, uiInfo.serverStatus.motdPaintX, rect->y, 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, 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; } } } static void UI_DrawKeyBindStatus( rectDef_t *rect, float scale, vec4_t color, int textStyle, float text_x, float text_y ) { //int ofs = 0; // TTimo: unused if ( Display_KeyBindPending() ) { Text_Paint( rect->x + text_x, rect->y + text_y, scale, color, trap_TranslateString( "Waiting for new key... Press ESCAPE to cancel" ), 0, 0, textStyle ); } else { Text_Paint( rect->x + text_x, rect->y + text_y, scale, color, trap_TranslateString( "Press ENTER or CLICK to change, Press BACKSPACE to clear" ), 0, 0, textStyle ); } } static void UI_ParseGLConfig( void ) { char *eptr; uiInfo.numGlInfoLines = 0; eptr = uiInfo.uiDC.glconfig.extensions_string; while ( *eptr ) { while ( *eptr && *eptr == ' ' ) *eptr++ = '\0'; // track start of valid string if ( *eptr && *eptr != ' ' ) { uiInfo.glInfoLines[uiInfo.numGlInfoLines++] = eptr; } if ( uiInfo.numGlInfoLines == GLINFO_LINES ) { break; // Arnout: failsafe } while ( *eptr && *eptr != ' ' ) eptr++; } uiInfo.numGlInfoLines += 4; // vendor, version and pixelformat + a whiteline } // 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; rect.x = x + text_x; rect.y = y + text_y; rect.w = w; rect.h = h; switch ( ownerDraw ) { /* case UI_TEAMFLAG: UI_DrawFlag( &rect ); break;*/ case UI_HANDICAP: UI_DrawHandicap( &rect, scale, color, textStyle ); break; case UI_EFFECTS: UI_DrawEffects( &rect, scale, color ); break; case UI_PLAYERMODEL: UI_DrawPlayerModel( &rect ); break; case UI_CLANNAME: UI_DrawClanName( &rect, scale, color, textStyle ); break; case UI_SAVEGAME_SHOT: // (SA) UI_DrawSaveGameShot( &rect, scale, color ); 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_NETMAPPREVIEW: UI_DrawNetMapPreview( &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_CAMPAIGNCINEMATIC: UI_DrawCampaignCinematic( &rect, scale, color, qfalse ); break; case UI_CAMPAIGNNAME: UI_DrawCampaignName( &rect, scale, color, textStyle, qfalse ); break; case UI_CAMPAIGNDESCRIPTION: UI_DrawCampaignDescription( &rect, scale, color, text_x, text_y, textStyle, align, qtrue ); break; case UI_GAMETYPEDESCRIPTION: UI_DrawGametypeDescription( &rect, scale, color, text_x, text_y, textStyle, align, qtrue ); break; case UI_CAMPAIGNMAP1_SHOT: case UI_CAMPAIGNMAP2_SHOT: case UI_CAMPAIGNMAP3_SHOT: case UI_CAMPAIGNMAP4_SHOT: case UI_CAMPAIGNMAP5_SHOT: case UI_CAMPAIGNMAP6_SHOT: UI_DrawCampaignMapPreview( &rect, scale, color, qfalse, ownerDraw - UI_CAMPAIGNMAP1_SHOT ); break; case UI_CAMPAIGNMAP1_TEXT: case UI_CAMPAIGNMAP2_TEXT: case UI_CAMPAIGNMAP3_TEXT: case UI_CAMPAIGNMAP4_TEXT: case UI_CAMPAIGNMAP5_TEXT: case UI_CAMPAIGNMAP6_TEXT: UI_DrawCampaignMapDescription( &rect, scale, color, text_x, text_y, textStyle, align, qfalse, ownerDraw - UI_CAMPAIGNMAP1_TEXT ); break; case UI_MB_MAP: UI_DrawMissionBriefingMap( &rect ); break; case UI_MB_TITLE: UI_DrawMissionBriefingTitle( &rect, scale, color, textStyle ); break; case UI_MB_OBJECTIVES: UI_DrawMissionBriefingObjectives( &rect, scale, color, text_x, text_y, textStyle, align ); 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_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_CROSSHAIR: UI_DrawCrosshair( &rect, scale, color ); 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_KEYBINDSTATUS: UI_DrawKeyBindStatus( &rect, scale, color, textStyle, text_x, text_y ); break; case UI_LOADPANEL: UI_DrawLoadPanel( qfalse, qtrue, qfalse ); break; default: break; } } qboolean UI_OwnerDrawVisible( int flags ) { qboolean vis = qtrue; while ( flags ) { if ( flags & UI_SHOW_FFA ) { flags &= ~UI_SHOW_FFA; } if ( flags & UI_SHOW_NOTFFA ) { vis = qfalse; flags &= ~UI_SHOW_NOTFFA; } 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; } } 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_ANYTEAMGAME ) { flags &= ~UI_SHOW_ANYTEAMGAME; } if ( flags & UI_SHOW_ANYNONTEAMGAME ) { vis = qfalse; flags &= ~UI_SHOW_ANYNONTEAMGAME; } if ( flags & UI_SHOW_NETANYTEAMGAME ) { flags &= ~UI_SHOW_NETANYTEAMGAME; } if ( flags & UI_SHOW_NETANYNONTEAMGAME ) { vis = qfalse; flags &= ~UI_SHOW_NETANYNONTEAMGAME; } 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_CAMPAIGNMAP1EXISTS ) { if ( uiInfo.campaignList[ui_currentCampaign.integer].mapCount < 1 ) { vis = qfalse; } flags &= ~UI_SHOW_CAMPAIGNMAP1EXISTS; } if ( flags & UI_SHOW_CAMPAIGNMAP2EXISTS ) { if ( uiInfo.campaignList[ui_currentCampaign.integer].mapCount < 2 ) { vis = qfalse; } flags &= ~UI_SHOW_CAMPAIGNMAP2EXISTS; } if ( flags & UI_SHOW_CAMPAIGNMAP3EXISTS ) { if ( uiInfo.campaignList[ui_currentCampaign.integer].mapCount < 3 ) { vis = qfalse; } flags &= ~UI_SHOW_CAMPAIGNMAP3EXISTS; } if ( flags & UI_SHOW_CAMPAIGNMAP4EXISTS ) { if ( uiInfo.campaignList[ui_currentCampaign.integer].mapCount < 4 ) { vis = qfalse; } flags &= ~UI_SHOW_CAMPAIGNMAP4EXISTS; } if ( flags & UI_SHOW_CAMPAIGNMAP5EXISTS ) { if ( uiInfo.campaignList[ui_currentCampaign.integer].mapCount < 5 ) { vis = qfalse; } flags &= ~UI_SHOW_CAMPAIGNMAP5EXISTS; } if ( flags & UI_SHOW_CAMPAIGNMAP6EXISTS ) { if ( uiInfo.campaignList[ui_currentCampaign.integer].mapCount < 6 ) { vis = qfalse; } flags &= ~UI_SHOW_CAMPAIGNMAP6EXISTS; } if ( flags & UI_SHOW_SELECTEDCAMPAIGNMAPPLAYABLE ) { int map = trap_Cvar_VariableValue( "ui_campaignmap" ); if ( map > uiInfo.campaignList[ui_currentCampaign.integer].progress ) { vis = qfalse; } flags &= ~UI_SHOW_SELECTEDCAMPAIGNMAPPLAYABLE; } if ( flags & UI_SHOW_SELECTEDCAMPAIGNMAPNOTPLAYABLE ) { int map = trap_Cvar_VariableValue( "ui_campaignmap" ); if ( map <= uiInfo.campaignList[ui_currentCampaign.integer].progress ) { vis = qfalse; } flags &= ~UI_SHOW_SELECTEDCAMPAIGNMAPNOTPLAYABLE; } if ( flags & UI_SHOW_PLAYERMUTED ) { if ( !uiInfo.playerMuted[uiInfo.playerIndex] ) { vis = qfalse; } flags &= ~UI_SHOW_PLAYERMUTED; } if ( flags & UI_SHOW_PLAYERNOTMUTED ) { if ( uiInfo.playerMuted[uiInfo.playerIndex] ) { vis = qfalse; } flags &= ~UI_SHOW_PLAYERNOTMUTED; } if ( flags & UI_SHOW_PLAYERNOREFEREE ) { if ( uiInfo.playerRefereeStatus[uiInfo.playerIndex] != RL_NONE ) { vis = qfalse; } flags &= ~UI_SHOW_PLAYERNOREFEREE; } if ( flags & UI_SHOW_PLAYERREFEREE ) { if ( uiInfo.playerRefereeStatus[uiInfo.playerIndex] != RL_REFEREE ) { vis = qfalse; } flags &= ~UI_SHOW_PLAYERREFEREE; } if ( flags & UI_SHOW_DEMOAVAILABLE ) { if ( !uiInfo.demoAvailable ) { vis = qfalse; } flags &= ~UI_SHOW_DEMOAVAILABLE; } else { flags = 0; } } 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 qboolean UI_Effects_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.effectsColor--; } else { uiInfo.effectsColor++; } if ( uiInfo.effectsColor > 6 ) { uiInfo.effectsColor = 0; } else if ( uiInfo.effectsColor < 0 ) { uiInfo.effectsColor = 6; } trap_Cvar_SetValue( "color", uitogamecode[uiInfo.effectsColor] ); return qtrue; } return qfalse; } 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 ); updateModel = qtrue; return qtrue; } return qfalse; } 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; } } trap_Cvar_Set( "ui_Q3Model", "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; } /*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) { if (key == K_MOUSE2) { ui_netGameType.integer--; } else { ui_netGameType.integer++; } if (ui_netGameType.integer < 0) { ui_netGameType.integer = uiInfo.numGameTypes - 1; } else if (ui_netGameType.integer >= uiInfo.numGameTypes) { ui_netGameType.integer = 0; } 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"); trap_Cvar_Set( "ui_currentNetCampaign", "0"); UI_MapCountByGameType(qfalse); Menu_SetFeederSelection(NULL, FEEDER_ALLMAPS, 0, NULL); Menu_SetFeederSelection(NULL, FEEDER_ALLCAMPAIGNS, 0, NULL); return qtrue; } return qfalse; }*/ /*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) { if (key == K_MOUSE2) { ui_joinGameType.integer--; } else { ui_joinGameType.integer++; } if (ui_joinGameType.integer < 0) { ui_joinGameType.integer = uiInfo.numJoinGameTypes - 1; } else if (ui_joinGameType.integer >= uiInfo.numJoinGameTypes) { ui_joinGameType.integer = 0; } trap_Cvar_Set( "ui_joinGameType", va("%d", ui_joinGameType.integer)); UI_BuildServerDisplayList(qtrue); return qtrue; } return qfalse; }*/ /*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++; } if (i < 1) { i = numSkillLevels; } else if (i > numSkillLevels) { i = 1; } trap_Cvar_Set("g_spSkill", va("%i", i)); return qtrue; } return qfalse; }*/ 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" ) ); if ( key == K_MOUSE2 ) { i--; } else { i++; } if ( i >= uiInfo.teamCount ) { i = 0; } else if ( i < 0 ) { i = uiInfo.teamCount - 1; } trap_Cvar_Set( ( blue ) ? "ui_blueTeam" : "ui_redTeam", uiInfo.teamList[i].teamName ); return qtrue; } return qfalse; } 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 ( key == K_MOUSE2 ) { value--; } else { value++; } if ( value >= uiInfo.characterCount + 2 ) { value = 0; } else if ( value < 0 ) { value = uiInfo.characterCount + 2 - 1; } trap_Cvar_Set( cvar, va( "%i", value ) ); return qtrue; } return qfalse; } /*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) { if (key == K_MOUSE2) { ui_netSource.integer--; } else { ui_netSource.integer++; } if (ui_netSource.integer >= numNetSources) { ui_netSource.integer = 0; } else if (ui_netSource.integer < 0) { ui_netSource.integer = numNetSources - 1; } 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_NetFilter_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_serverFilterType.integer--; } else { ui_serverFilterType.integer++; } 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; } 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; } 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 game = trap_Cvar_VariableValue("g_gametype"); int value = uiInfo.botIndex; if ( key == K_MOUSE2 ) { value--; } else { value++; } if ( value >= uiInfo.characterCount + 2 ) { value = 0; } else if ( value < 0 ) { value = uiInfo.characterCount + 2 - 1; } uiInfo.botIndex = value; return qtrue; } return 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; }*/ 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; } static qboolean UI_Crosshair_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.currentCrosshair--; } else { uiInfo.currentCrosshair++; } if ( uiInfo.currentCrosshair >= NUM_CROSSHAIRS ) { uiInfo.currentCrosshair = 0; } else if ( uiInfo.currentCrosshair < 0 ) { uiInfo.currentCrosshair = NUM_CROSSHAIRS - 1; } trap_Cvar_Set( "cg_drawCrosshair", va( "%d", uiInfo.currentCrosshair ) ); return qtrue; } return qfalse; } 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; UI_BuildPlayerList(); if ( !uiInfo.teamLeader ) { return qfalse; } selected = trap_Cvar_VariableValue( "cg_selectedPlayer" ); if ( key == K_MOUSE2 ) { selected--; } else { selected++; } if ( selected > uiInfo.myTeamCount ) { selected = 0; } else if ( selected < 0 ) { selected = uiInfo.myTeamCount; } if ( selected == uiInfo.myTeamCount ) { trap_Cvar_Set( "cg_selectedPlayerName", "Everyone" ); } else { trap_Cvar_Set( "cg_selectedPlayerName", uiInfo.teamNames[selected] ); } trap_Cvar_Set( "cg_selectedPlayer", va( "%d", selected ) ); } return qfalse; } 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_EFFECTS: return UI_Effects_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_CROSSHAIR: UI_Crosshair_HandleKey( flags, special, key ); break; case UI_SELECTEDPLAYER: UI_SelectedPlayer_HandleKey( flags, special, key ); break; default: break; } return qfalse; } static float UI_GetValue( int ownerDraw, int type ) { return 0; } /* ================= 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 ); } /* ================= UI_ServersSort ================= */ 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 ); } /* =============== UI_LoadMods =============== */ static void UI_LoadMods() { 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; } } } /* =============== UI_LoadProfiles =============== */ static void UI_LoadProfiles() { int numdirs; char dirlist[2048]; char *dirptr; //char *descptr; int i; int dirlen; uiInfo.profileCount = 0; uiInfo.profileIndex = -1; numdirs = trap_FS_GetFileList( "profiles", "/", dirlist, sizeof( dirlist ) ); dirptr = dirlist; for ( i = 0; i < numdirs; i++ ) { dirlen = strlen( dirptr ) + 1; if ( dirptr[0] && Q_stricmp( dirptr, "." ) && Q_stricmp( dirptr,".." ) ) { int handle; pc_token_t token; if ( !( handle = trap_PC_LoadSource( va( "profiles/%s/profile.dat", dirptr ) ) ) ) { dirptr += dirlen; continue; } if ( !trap_PC_ReadToken( handle, &token ) ) { trap_PC_FreeSource( handle ); dirptr += dirlen; continue; } uiInfo.profileList[uiInfo.profileCount].name = String_Alloc( token.string ); trap_PC_FreeSource( handle ); uiInfo.profileList[uiInfo.profileCount].dir = String_Alloc( dirptr ); uiInfo.profileCount++; /*if( uiInfo.profileCount == 1 ) { int j; uiInfo.profileIndex = 0; trap_Cvar_Set( "ui_profile", token.string ); for( j = 0; j < Menu_Count(); j++ ) { Menu_SetFeederSelection( Menu_Get(j), FEEDER_PROFILES, 0, NULL ); } }*/ if ( uiInfo.profileIndex == -1 ) { Q_CleanStr( token.string ); Q_CleanDirName( token.string ); if ( !Q_stricmp( token.string, cl_profile.string ) ) { int j; uiInfo.profileIndex = i; trap_Cvar_Set( "ui_profile", uiInfo.profileList[0].name ); trap_Cvar_Update( &ui_profile ); for ( j = 0; j < Menu_Count(); j++ ) { Menu_SetFeederSelection( Menu_Get( j ), FEEDER_PROFILES, uiInfo.profileIndex, NULL ); } } } if ( uiInfo.profileCount >= MAX_PROFILES ) { break; } } dirptr += dirlen; } if ( uiInfo.profileIndex == -1 ) { int j; uiInfo.profileIndex = 0; trap_Cvar_Set( "ui_profile", uiInfo.profileList[0].name ); trap_Cvar_Update( &ui_profile ); for ( j = 0; j < Menu_Count(); j++ ) { Menu_SetFeederSelection( Menu_Get( j ), FEEDER_PROFILES, 0, NULL ); } } } /* =============== UI_LoadTeams =============== */ /* // TTimo: unused static void UI_LoadTeams() { char teamList[4096]; char *teamName; int i, len, count; count = trap_FS_GetFileList( "", "team", teamList, 4096 ); if (count) { teamName = teamList; for ( i = 0; i < count; i++ ) { len = strlen( teamName ); UI_ParseTeamInfo(teamName); teamName += len + 1; } } } */ /* ============== UI_DelSavegame ============== */ static void UI_DelSavegame() { int ret; ret = trap_FS_Delete( va( "save/%s.svg", uiInfo.savegameList[uiInfo.savegameIndex].name ) ); trap_FS_Delete( va( "save/images/%s.tga", uiInfo.savegameList[uiInfo.savegameIndex].name ) ); if ( ret ) { Com_Printf( "Deleted savegame: %s.svg\n", uiInfo.savegameList[uiInfo.savegameIndex].name ); } else { Com_Printf( "Unable to delete savegame: %s.svg\n", uiInfo.savegameList[uiInfo.savegameIndex].name ); } } /* ============== UI_LoadSavegames ============== */ static void UI_LoadSavegames() { char sglist[4096]; char *sgname; int i, len; uiInfo.savegameCount = trap_FS_GetFileList( "save", "svg", sglist, 4096 ); if ( uiInfo.savegameCount ) { if ( uiInfo.savegameCount > MAX_SAVEGAMES ) { uiInfo.savegameCount = MAX_SAVEGAMES; } sgname = sglist; for ( i = 0; i < uiInfo.savegameCount; i++ ) { len = strlen( sgname ); if ( !Q_strncmp( sgname, "current", 7 ) ) { // ignore current.svg since it has special uses and shouldn't be loaded directly i--; uiInfo.savegameCount -= 1; sgname += len + 1; continue; } if ( !Q_stricmp( sgname + len - 4,".svg" ) ) { sgname[len - 4] = '\0'; } Q_strupr( sgname ); uiInfo.savegameList[i].name = String_Alloc( sgname ); uiInfo.savegameList[i].sshotImage = trap_R_RegisterShaderNoMip( va( "save/images/%s.tga",uiInfo.savegameList[i].name ) ); sgname += len + 1; } } } /* =============== UI_LoadMovies =============== */ static void UI_LoadMovies() { 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() { char demolist[30000]; char demoExt[32]; char *demoname; int i, len; Com_sprintf( demoExt, sizeof( demoExt ), "dm_%d", (int)trap_Cvar_VariableValue( "protocol" ) ); uiInfo.demoCount = trap_FS_GetFileList( "demos", demoExt, demolist, sizeof( demolist ) ); Com_sprintf( demoExt, sizeof( demoExt ), ".dm_%d", (int)trap_Cvar_VariableValue( "protocol" ) ); 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; } } } /* ============== UI_SetNextMap ============== */ /* // TTimo: unused 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; } */ /* ============== UI_StartSkirmish ============== */ static void UI_StartSkirmish( qboolean next ) { } void WM_setItemPic( char *name, const char *shader ) { menuDef_t *menu = Menu_GetFocused(); itemDef_t *item; item = Menu_FindItemByName( menu, name ); if ( item ) { item->window.background = DC->registerShaderNoMip( shader ); } } void WM_setVisibility( char *name, qboolean show ) { menuDef_t *menu = Menu_GetFocused(); itemDef_t *item; item = Menu_FindItemByName( menu, name ); if ( item ) { if ( show ) { item->window.flags |= WINDOW_VISIBLE; } else { item->window.flags &= ~( WINDOW_VISIBLE | WINDOW_MOUSEOVER ); } } } qboolean UI_CheckExecKey( int key ) { menuDef_t *menu = Menu_GetFocused(); if ( g_editingField ) { return qtrue; } if ( key > 256 ) { return qfalse; } if ( !menu ) { if ( cl_bypassMouseInput.integer ) { if ( !trap_Key_GetCatcher() ) { trap_Cvar_Set( "cl_bypassMouseInput", "0" ); } } return qfalse; } if ( menu->onKey[key] ) { return qtrue; } return qfalse; } void WM_ActivateLimboChat() { menuDef_t *menu; itemDef_t *itemdef; menu = Menu_GetFocused(); menu = Menus_ActivateByName( "wm_limboChat", qtrue ); if ( !menu || g_editItem ) { return; } itemdef = Menu_FindItemByName( menu, "window_limbo_chat" ); if ( itemdef ) { itemdef->cursorPos = 0; g_editingField = qtrue; g_editItem = itemdef; DC->setOverstrikeMode( qtrue ); } } // -NERVE - SMF /* ============== UI_Update ============== */ 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( "ui_rate" ); if ( rate >= 5000 ) { trap_Cvar_Set( "ui_cl_maxpackets", "30" ); trap_Cvar_Set( "ui_cl_packetdup", "1" ); } else if ( rate >= 4000 ) { trap_Cvar_Set( "ui_cl_maxpackets", "15" ); trap_Cvar_Set( "ui_cl_packetdup", "2" ); // favor less prediction errors when there's packet loss } else { trap_Cvar_Set( "ui_cl_maxpackets", "15" ); trap_Cvar_Set( "ui_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, "ui_r_lodbias" ) == 0 ) { switch ( val ) { case 0: trap_Cvar_SetValue( "ui_r_subdivisions", 4 ); break; case 1: trap_Cvar_SetValue( "ui_r_subdivisions", 12 ); break; case 2: trap_Cvar_SetValue( "ui_r_subdivisions", 20 ); break; } } else if ( Q_stricmp( name, "ui_glCustom" ) == 0 ) { switch ( val ) { case 0: // high quality trap_Cmd_ExecuteText( EXEC_APPEND, "exec preset_high_ui.cfg\n" ); break; case 1: // normal trap_Cmd_ExecuteText( EXEC_APPEND, "exec preset_normal_ui.cfg\n" ); break; case 2: // fast trap_Cmd_ExecuteText( EXEC_APPEND, "exec preset_fast_ui.cfg\n" ); break; case 3: // fastest trap_Cmd_ExecuteText( EXEC_APPEND, "exec preset_fastest_ui.cfg\n" ); 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 ); } } } /* ============== UI_RunMenuScript ============== */ void UI_RunMenuScript( char **args ) { const char *name, *name2; char *s; char buff[1024]; int val; // NERVE - SMF menuDef_t *menu; if ( String_Parse( args, &name ) ) { if ( Q_stricmp( name, "StartServer" ) == 0 ) { float skill; int pb_sv, pb_cl; // DHM - Nerve if ( !ui_dedicated.integer ) { pb_sv = (int)trap_Cvar_VariableValue( "sv_punkbuster" ); pb_cl = (int)trap_Cvar_VariableValue( "cl_punkbuster" ); if ( pb_sv && !pb_cl ) { trap_Cvar_Set( "com_errorMessage", "You must either disable PunkBuster on the Server, or enable PunkBuster on the Client before starting a non-dedicated server." ); Menus_ActivateByName( "hostGamePopupError", qtrue ); return; } } // dhm - Nerve trap_Cvar_Set( "ui_connecting", "1" ); 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, ui_netGameType.integer ) ); if ( ui_netGameType.integer == GT_WOLF_CAMPAIGN ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait ; wait ; map %s\n", uiInfo.campaignList[ui_currentNetMap.integer].mapInfos[0]->mapLoadName ) ); } else { trap_Cmd_ExecuteText( EXEC_APPEND, va( "wait ; wait ; map %s\n", uiInfo.mapList[ui_currentNetMap.integer].mapLoadName ) ); } skill = trap_Cvar_VariableValue( "g_spSkill" ); // NERVE - SMF - set user cvars here // set timelimit val = trap_Cvar_VariableValue( "ui_userTimelimit" ); if ( val && val != uiInfo.mapList[ui_mapIndex.integer].Timelimit ) { trap_Cvar_Set( "g_userTimelimit", va( "%i", val ) ); } else { trap_Cvar_Set( "g_userTimelimit", "0" ); } // set axis respawn time val = trap_Cvar_VariableValue( "ui_userAxisRespawnTime" ); if ( val && val != uiInfo.mapList[ui_mapIndex.integer].AxisRespawnTime ) { trap_Cvar_Set( "g_userAxisRespawnTime", va( "%i", val ) ); } else { trap_Cvar_Set( "g_userAxisRespawnTime", "0" ); } // set allied respawn time val = trap_Cvar_VariableValue( "ui_userAlliedRespawnTime" ); if ( val && val != uiInfo.mapList[ui_mapIndex.integer].AlliedRespawnTime ) { trap_Cvar_Set( "g_userAlliedRespawnTime", va( "%i", val ) ); } else { trap_Cvar_Set( "g_userAlliedRespawnTime", "0" ); } // -NERVE - SMF } 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_campaignIndex.integer = UI_GetIndexFromSelection( ui_currentCampaign.integer ); trap_Cvar_Set( "ui_campaignIndex", va( "%d", ui_campaignIndex.integer ) ); Menu_SetFeederSelection( NULL, FEEDER_CAMPAIGNS, ui_campaignIndex.integer, "selectcampaign" ); UI_GameType_HandleKey( 0, 0, K_MOUSE1, qfalse ); UI_GameType_HandleKey( 0, 0, K_MOUSE2, qfalse ); } else if ( Q_stricmp( name, "resetDefaults" ) == 0 ) { trap_Cmd_ExecuteText( EXEC_APPEND, "cvar_restart\n" ); // NERVE - SMF - changed order trap_Cmd_ExecuteText( EXEC_APPEND, "exec default.cfg\n" ); trap_Cmd_ExecuteText( EXEC_APPEND, "exec language.cfg\n" ); // NERVE - SMF trap_Cmd_ExecuteText( EXEC_APPEND, "setRecommended\n" ); // NERVE - SMF Controls_SetDefaults( qfalse ); trap_Cvar_Set( "com_introPlayed", "1" ); trap_Cvar_Set( "com_recommendedSet", "1" ); // NERVE - SMF trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart\n" ); } else if ( Q_stricmp( name, "getCDKey" ) == 0 ) { char out[17]; trap_GetCDKey( buff, 17 ); trap_Cvar_Set( "cdkey1", "" ); trap_Cvar_Set( "cdkey2", "" ); trap_Cvar_Set( "cdkey3", "" ); trap_Cvar_Set( "cdkey4", "" ); if ( strlen( buff ) == CDKEY_LEN ) { Q_strncpyz( out, buff, 5 ); trap_Cvar_Set( "cdkey1", out ); Q_strncpyz( out, buff + 4, 5 ); trap_Cvar_Set( "cdkey2", out ); Q_strncpyz( out, buff + 8, 5 ); trap_Cvar_Set( "cdkey3", out ); Q_strncpyz( out, buff + 12, 5 ); trap_Cvar_Set( "cdkey4", out ); } } else if ( Q_stricmp( name, "verifyCDKey" ) == 0 ) { buff[0] = '\0'; Q_strcat( buff, 1024, UI_Cvar_VariableString( "cdkey1" ) ); Q_strcat( buff, 1024, UI_Cvar_VariableString( "cdkey2" ) ); Q_strcat( buff, 1024, UI_Cvar_VariableString( "cdkey3" ) ); Q_strcat( buff, 1024, UI_Cvar_VariableString( "cdkey4" ) ); trap_Cvar_Set( "cdkey", buff ); if ( trap_VerifyCDKey( buff, UI_Cvar_VariableString( "cdkeychecksum" ) ) ) { trap_Cvar_Set( "ui_cdkeyvalid", trap_TranslateString( "CD key appears to be valid." ) ); trap_SetCDKey( buff ); } else { trap_Cvar_Set( "ui_cdkeyvalid", trap_TranslateString( "CD key does not appear to be valid." ) ); } } else if ( Q_stricmp( name, "loadArenas" ) == 0 ) { UI_LoadArenas(); UI_MapCountByGameType( qfalse ); Menu_SetFeederSelection( NULL, FEEDER_ALLMAPS, 0, NULL ); UI_LoadCampaigns(); Menu_SetFeederSelection( NULL, FEEDER_ALLCAMPAIGNS, 0, NULL ); } else if ( Q_stricmp( name, "updateNetMap" ) == 0 ) { Menu_SetFeederSelection( NULL, FEEDER_ALLMAPS, ui_currentNetMap.integer, NULL ); } 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", "" ); trap_Cvar_Set( "com_errorDiagnoseIP", "" ); trap_Cvar_Set( "com_missingFiles", "" ); } 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, "RefreshFilter" ) == 0 ) { //UI_StartServerRefresh(qfalse); UI_StartServerRefresh( uiInfo.serverStatus.numDisplayServers ? qfalse : qtrue ); // if we don't have any valid servers, it's kinda safe to assume we would like to get a full new list UI_BuildServerDisplayList( qtrue ); } else if ( Q_stricmp( name, "RunSPDemo" ) == 0 ) { if ( uiInfo.demoAvailable ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "demo %s_%i", 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(); //----(SA) added } else if ( Q_stricmp( name, "LoadSaveGames" ) == 0 ) { // get the list UI_LoadSavegames(); } else if ( Q_stricmp( name, "Loadgame" ) == 0 ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "loadgame %s\n", uiInfo.savegameList[uiInfo.savegameIndex].name ) ); } else if ( Q_stricmp( name, "Savegame" ) == 0 ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "savegame %s\n", UI_Cvar_VariableString( "ui_savegame" ) ) ); } else if ( Q_stricmp( name, "DelSavegame" ) == 0 ) { UI_DelSavegame(); //----(SA) end } else if ( Q_stricmp( name, "LoadMods" ) == 0 ) { UI_LoadMods(); } 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 ) { if ( uiInfo.demoIndex >= 0 && uiInfo.demoIndex < uiInfo.demoCount ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "demo \"%s\"\n", uiInfo.demoList[uiInfo.demoIndex] ) ); } } else if ( Q_stricmp( name, "deleteDemo" ) == 0 ) { if ( uiInfo.demoIndex >= 0 && uiInfo.demoIndex < uiInfo.demoCount ) { trap_FS_Delete( va( "demos/%s.dm_%d", uiInfo.demoList[uiInfo.demoIndex], (int)trap_Cvar_VariableValue( "protocol" ) ) ); } } 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 ) { trap_Cvar_Update( &ui_netSource ); if ( ui_netSource.integer == AS_LOCAL || !uiInfo.serverStatus.numDisplayServers ) { UI_StartServerRefresh( qtrue ); } UI_BuildServerDisplayList( qtrue ); UI_FeederSelection( FEEDER_SERVERS, 0 ); } else if ( Q_stricmp( name, "check_ServerStatus" ) == 0 ) { s = UI_Cvar_VariableString( "com_errorDiagnoseIP" ); menu = Menus_FindByName( "ingame_options" ); if ( strlen( s ) && strcmp( s, "localhost" ) ) { if ( menu ) { Menu_ShowItemByName( menu, "ctr_serverinfo", qtrue ); } } else { if ( menu ) { Menu_ShowItemByName( menu, "ctr_serverinfo", qfalse ); } } } else if ( Q_stricmp( name, "ServerStatus" ) == 0 ) { // the server info dialog has been turned into a modal thing // it can be called in several situations if ( trap_Cvar_VariableValue( "ui_serverBrowser" ) == 1 ) { // legacy, from the server browser trap_LAN_GetServerAddressString( ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], uiInfo.serverStatusAddress, sizeof( uiInfo.serverStatusAddress ) ); UI_BuildServerStatus( qtrue ); } else { // use com_errorDiagnoseIP otherwise s = UI_Cvar_VariableString( "com_errorDiagnoseIP" ); if ( strlen( s ) && strcmp( s, "localhost" ) ) { trap_Cvar_VariableStringBuffer( "com_errorDiagnoseIP", uiInfo.serverStatusAddress, sizeof( uiInfo.serverStatusAddress ) ); uiInfo.serverStatus.numDisplayServers = 1; // this is ugly, have to force a non zero display server count to emit the query UI_BuildServerStatus( qtrue ); } else { // we can't close the menu from here, it's not open yet .. (that's the onOpen script) Com_Printf( "Can't show Server Info (not found, or local server)\n" ); } } } else if ( Q_stricmp( name, "InGameServerStatus" ) == 0 ) { uiClientState_t cstate; trap_GetClientState( &cstate ); Q_strncpyz( uiInfo.serverStatusAddress, cstate.servername, sizeof( uiInfo.serverStatusAddress ) ); UI_BuildServerStatus( qtrue ); } else if ( Q_stricmp( name, "ServerStatus_diagnose" ) == 0 ) { // query server and display the URL buttons if the error happened during a server connection situation s = UI_Cvar_VariableString( "com_errorDiagnoseIP" ); menu = Menus_FindByName( "error_popmenu_diagnose" ); if ( strlen( s ) && strcmp( s, "localhost" ) ) { trap_Cvar_VariableStringBuffer( "com_errorDiagnoseIP", uiInfo.serverStatusAddress, sizeof( uiInfo.serverStatusAddress ) ); uiInfo.serverStatus.numDisplayServers = 1; // this is ugly, have to force a non zero display server count to emit the query // toggle the "Server Info" button if ( menu ) { Menu_ShowItemByName( menu, "serverinfo", qtrue ); } UI_BuildServerStatus( qtrue ); } else { // don't send getinfo packet, hide "Server Info" button if ( menu ) { Menu_ShowItemByName( menu, "serverinfo", qfalse ); } } } 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 ) { Menus_CloseAll(); trap_Cvar_Set( "ui_connecting", "1" ); trap_Cvar_Set( "cg_thirdPerson", "0 " ); trap_Cvar_Set( "cg_cameraOrbit", "0" ); trap_Cvar_Set( "ui_singlePlayerActive", "0" ); 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, "JoinDirectServer" ) == 0 ) { Menus_CloseAll(); trap_Cvar_Set( "ui_connecting", "1" ); trap_Cvar_Set( "cg_thirdPerson", "0" ); trap_Cvar_Set( "cg_cameraOrbit", "0" ); trap_Cvar_Set( "ui_singlePlayerActive", "0" ); trap_Cmd_ExecuteText( EXEC_APPEND, va( "connect %s\n", UI_Cvar_VariableString( "ui_connectToIPAddress" ) ) ); } 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", qtrue ); } else if ( Q_stricmp( name, "Leave" ) == 0 ) { // ATVI Wolfenstein Misc #460 // if we are running a local server, make sure we kill it cleanly for other clients if ( trap_Cvar_VariableValue( "sv_running" ) ) { trap_Cvar_Set( "sv_killserver", "1" ); } else { trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect\n" ); trap_Key_SetCatcher( KEYCATCH_UI ); Menus_CloseAll(); // Menus_ActivateByName( "background_1", qtrue ); Menus_ActivateByName( "backgroundmusic", qtrue ); Menus_ActivateByName( "main_opener", qtrue ); } } 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 ); } } else if ( Q_stricmp( name, "ServerSortDown" ) == 0 ) { int sortColumn; if ( Int_Parse( args, &sortColumn ) ) { uiInfo.serverStatus.sortDir = 0; // make sure we sort again UI_ServersSort( sortColumn, 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_netGameType.integer == GT_WOLF_CAMPAIGN ) { if ( ui_currentNetMap.integer >= 0 && ui_currentNetMap.integer < uiInfo.campaignCount ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "callvote campaign %s\n", uiInfo.campaignList[ui_currentNetMap.integer].campaignShortName ) ); } } else { 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 \"%s\"\n", uiInfo.playerNames[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 \"%s\"\n", uiInfo.playerNames[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 \"%s\"\n", uiInfo.playerNames[uiInfo.playerIndex] ) ); } } else if ( Q_stricmp( name, "voteReferee" ) == 0 ) { if ( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "callvote referee \"%s\"\n", uiInfo.playerNames[uiInfo.playerIndex] ) ); } } else if ( Q_stricmp( name, "voteUnReferee" ) == 0 ) { if ( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "callvote unreferee \"%s\"\n", uiInfo.playerNames[uiInfo.playerIndex] ) ); } } else if ( Q_stricmp( name, "voteGame" ) == 0 ) { int ui_voteGameType = trap_Cvar_VariableValue( "ui_voteGameType" ); if ( ui_voteGameType >= 0 && ui_voteGameType < uiInfo.numGameTypes ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "callvote gametype %i\n", ui_voteGameType ) ); } } else if ( Q_stricmp( name, "refGame" ) == 0 ) { int ui_voteGameType = trap_Cvar_VariableValue( "ui_voteGameType" ); if ( ui_voteGameType >= 0 && ui_voteGameType < uiInfo.numGameTypes ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "ref gametype %i\n", ui_voteGameType ) ); } } else if ( Q_stricmp( name, "voteTimelimit" ) == 0 ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "callvote timelimit %f\n", trap_Cvar_VariableValue( "ui_voteTimelimit" ) ) ); } else if ( Q_stricmp( name, "voteWarmupDamage" ) == 0 ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "callvote warmupdamage %d\n", (int)trap_Cvar_VariableValue( "ui_voteWarmupDamage" ) ) ); } else if ( Q_stricmp( name, "refTimelimit" ) == 0 ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "ref timelimit %f\n", trap_Cvar_VariableValue( "ui_voteTimelimit" ) ) ); } else if ( Q_stricmp( name, "refWarmupDamage" ) == 0 ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "ref warmupdamage %d\n", (int)trap_Cvar_VariableValue( "ui_voteWarmupDamage" ) ) ); } else if ( Q_stricmp( name, "voteInitToggles" ) == 0 ) { char info[MAX_INFO_STRING]; trap_GetConfigString( CS_SERVERTOGGLES, info, sizeof( info ) ); trap_Cvar_Set( "ui_voteWarmupDamage", va( "%d", ( ( atoi( info ) & CV_SVS_WARMUPDMG ) >> 2 ) ) ); trap_GetConfigString( CS_SERVERINFO, info, sizeof( info ) ); trap_Cvar_Set( "ui_voteTimelimit", va( "%i", atoi( Info_ValueForKey( info, "timelimit" ) ) ) ); } else if ( Q_stricmp( name, "voteLeader" ) == 0 ) { if ( uiInfo.teamIndex >= 0 && uiInfo.teamIndex < uiInfo.myTeamCount ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "callteamvote leader %s\n", uiInfo.teamNames[uiInfo.teamIndex] ) ); } } else if ( Q_stricmp( name, "addBot" ) == 0 ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "addbot %s %i %s\n", uiInfo.characterList[uiInfo.botIndex].name, uiInfo.skillIndex + 1, ( uiInfo.redBlue == 0 ) ? "Red" : "Blue" ) ); } 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( trap_TranslateString( "Favorite already in list\n" ) ); } else if ( res == -1 ) { // list full Com_Printf( trap_TranslateString( "Favorite list full\n" ) ); } else { // successfully added Com_Printf( trap_TranslateString( "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( trap_TranslateString( "Favorite already in list\n" ) ); } else if ( res == -1 ) { // list full Com_Printf( trap_TranslateString( "Favorite list full\n" ) ); } else { // successfully added Com_Printf( trap_TranslateString( "Added favorite server %s\n" ), addr ); } } } } else if ( Q_stricmp( name, "createFavoriteIngame" ) == 0 ) { uiClientState_t cstate; char name[MAX_NAME_LENGTH]; char addr[MAX_NAME_LENGTH]; int res; trap_GetClientState( &cstate ); addr[0] = '\0'; name[0] = '\0'; Q_strncpyz( addr, cstate.servername, MAX_NAME_LENGTH ); Q_strncpyz( name, cstate.servername, MAX_NAME_LENGTH ); if ( *name && *addr && Q_stricmp( addr, "localhost" ) ) { res = trap_LAN_AddServer( AS_FAVORITES, name, addr ); if ( res == 0 ) { // server already in the list Com_Printf( trap_TranslateString( "Favorite already in list\n" ) ); } else if ( res == -1 ) { // list full Com_Printf( trap_TranslateString( "Favorite list full\n" ) ); } else { // successfully added Com_Printf( trap_TranslateString( "Added favorite server %s\n" ), addr ); } } } 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" ); } } 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 ); } // NERVE - SMF } else if ( Q_stricmp( name, "startSingleplayer" ) == 0 ) { trap_Cmd_ExecuteText( EXEC_APPEND, "startSingleplayer\n" ); } else if ( Q_stricmp( name, "showSpecScores" ) == 0 ) { if ( atoi( UI_Cvar_VariableString( "ui_isSpectator" ) ) ) { trap_Cmd_ExecuteText( EXEC_APPEND, "+scores\n" ); } } else if ( Q_stricmp( name, "setPbClStatus" ) == 0 ) { int stat; if ( Int_Parse( args, &stat ) ) { trap_SetPbClStatus( stat ); } // DHM - Nerve } else if ( Q_stricmp( name, "rconGame" ) == 0 ) { if ( ui_netGameType.integer >= 0 && ui_netGameType.integer < uiInfo.numGameTypes ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "rcon g_gametype %i\n", ui_netGameType.integer ) ); } } else if ( Q_stricmp( name, "rconMap" ) == 0 ) { if ( ui_currentNetMap.integer >= 0 && ui_currentNetMap.integer < uiInfo.mapCount ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "rcon map %s\n",uiInfo.mapList[ui_currentNetMap.integer].mapLoadName ) ); } } else if ( Q_stricmp( name, "refMap" ) == 0 ) { if ( ui_netGameType.integer == GT_WOLF_CAMPAIGN ) { if ( ui_currentNetMap.integer >= 0 && ui_currentNetMap.integer < uiInfo.campaignCount ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "ref campaign %s\n", uiInfo.campaignList[ui_currentNetMap.integer].campaignShortName ) ); } } else { if ( ui_currentNetMap.integer >= 0 && ui_currentNetMap.integer < uiInfo.mapCount ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "ref map %s\n", uiInfo.mapList[ui_currentNetMap.integer].mapLoadName ) ); } } } else if ( Q_stricmp( name, "rconKick" ) == 0 ) { if ( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "rcon kick \"%s\"\n",uiInfo.playerNames[uiInfo.playerIndex] ) ); } } else if ( Q_stricmp( name, "refKick" ) == 0 ) { if ( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "ref kick \"%s\"\n",uiInfo.playerNames[uiInfo.playerIndex] ) ); } } else if ( Q_stricmp( name, "rconBan" ) == 0 ) { if ( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "rcon ban \"%s\"\n",uiInfo.playerNames[uiInfo.playerIndex] ) ); } } else if ( Q_stricmp( name, "refMute" ) == 0 ) { if ( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "ref mute \"%s\"\n",uiInfo.playerNames[uiInfo.playerIndex] ) ); } } else if ( Q_stricmp( name, "refUnMute" ) == 0 ) { if ( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "ref unmute \"%s\"\n",uiInfo.playerNames[uiInfo.playerIndex] ) ); } } else if ( Q_stricmp( name, "refMakeAxis" ) == 0 ) { if ( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "ref putaxis \"%s\"\n",uiInfo.playerNames[uiInfo.playerIndex] ) ); } } else if ( Q_stricmp( name, "refMakeAllied" ) == 0 ) { if ( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "ref putallies \"%s\"\n",uiInfo.playerNames[uiInfo.playerIndex] ) ); } } else if ( Q_stricmp( name, "refMakeSpec" ) == 0 ) { if ( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "ref remove \"%s\"\n",uiInfo.playerNames[uiInfo.playerIndex] ) ); } } else if ( Q_stricmp( name, "refUnReferee" ) == 0 ) { if ( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "ref unreferee \"%s\"\n",uiInfo.playerNames[uiInfo.playerIndex] ) ); } } else if ( Q_stricmp( name, "refMakeReferee" ) == 0 ) { if ( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "ref referee \"%s\"\n",uiInfo.playerNames[uiInfo.playerIndex] ) ); } } else if ( Q_stricmp( name, "rconMakeReferee" ) == 0 ) { if ( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "rcon makeReferee \"%s\"\n",uiInfo.playerNames[uiInfo.playerIndex] ) ); } } else if ( Q_stricmp( name, "rconRemoveReferee" ) == 0 ) { if ( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "rcon removeReferee \"%s\"\n",uiInfo.playerNames[uiInfo.playerIndex] ) ); } } else if ( Q_stricmp( name, "rconMute" ) == 0 ) { if ( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "rcon mute \"%s\"\n",uiInfo.playerNames[uiInfo.playerIndex] ) ); } } else if ( Q_stricmp( name, "rconUnMute" ) == 0 ) { if ( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "rcon unmute \"%s\"\n",uiInfo.playerNames[uiInfo.playerIndex] ) ); } } else if ( Q_stricmp( name, "refWarning" ) == 0 ) { if ( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) { char buffer[128]; trap_Cvar_VariableStringBuffer( "ui_warnreason", buffer, 128 ); trap_Cmd_ExecuteText( EXEC_APPEND, va( "ref warn \"%s\" \"%s\"\n",uiInfo.playerNames[uiInfo.playerIndex], buffer ) ); } } else if ( Q_stricmp( name, "refWarmup" ) == 0 ) { char buffer[128]; trap_Cvar_VariableStringBuffer( "ui_warmup", buffer, 128 ); trap_Cmd_ExecuteText( EXEC_APPEND, va( "ref warmup \"%s\"\n", buffer ) ); } else if ( Q_stricmp( name, "ignorePlayer" ) == 0 ) { if ( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "ignore \"%s\"\n",uiInfo.playerNames[uiInfo.playerIndex] ) ); } } else if ( Q_stricmp( name, "unIgnorePlayer" ) == 0 ) { if ( uiInfo.playerIndex >= 0 && uiInfo.playerIndex < uiInfo.playerCount ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "unignore \"%s\"\n",uiInfo.playerNames[uiInfo.playerIndex] ) ); } } else if ( Q_stricmp( name, "loadCachedServers" ) == 0 ) { trap_LAN_LoadCachedServers(); // load servercache.dat } else if ( Q_stricmp( name, "setupCampaign" ) == 0 ) { trap_Cvar_Set( "ui_campaignmap", va( "%i", uiInfo.campaignList[ui_currentCampaign.integer].progress ) ); } else if ( Q_stricmp( name, "playCampaign" ) == 0 ) { int map = trap_Cvar_VariableValue( "ui_campaignmap" ); if ( map <= uiInfo.campaignList[ui_currentCampaign.integer].progress ) { //trap_Cmd_ExecuteText( EXEC_APPEND, va("spmap \"%s\"\n", uiInfo.campaignList[ui_currentCampaign.integer].mapInfos[uiInfo.campaignList[ui_currentCampaign.integer].progress]->mapLoadName)); trap_Cmd_ExecuteText( EXEC_APPEND, va( "spmap \"%s\"\n", uiInfo.campaignList[ui_currentCampaign.integer].mapInfos[map]->mapLoadName ) ); } } else if ( Q_stricmp( name, "loadProfiles" ) == 0 ) { UI_LoadProfiles(); } else if ( Q_stricmp( name, "createProfile" ) == 0 ) { fileHandle_t f; char buff[MAX_CVAR_VALUE_STRING]; /*Q_strncpyz( cl_profile.string, ui_profile.string, sizeof(cl_profile.string) ); Q_CleanStr( cl_profile.string ); Q_CleanDirName( cl_profile.string ); trap_Cvar_Set( "cl_profile", cl_profile.string ); if( trap_FS_FOpenFile( va( "profiles/%s/profile.dat", cl_profile.string ), &f, FS_WRITE ) >= 0 ) { trap_FS_Write( va( "\"%s\"", ui_profile.string ), strlen(ui_profile.string) + 2, f ); trap_FS_FCloseFile( f ); }*/ Q_strncpyz( buff, ui_profile.string, sizeof( buff ) ); Q_CleanStr( buff ); Q_CleanDirName( buff ); if ( trap_FS_FOpenFile( va( "profiles/%s/profile.dat", buff ), &f, FS_WRITE ) >= 0 ) { trap_FS_Write( va( "\"%s\"", ui_profile.string ), strlen( ui_profile.string ) + 2, f ); trap_FS_FCloseFile( f ); } trap_Cvar_Set( "name", ui_profile.string ); } else if ( Q_stricmp( name, "clearPID" ) == 0 ) { fileHandle_t f; // delete profile.pid from current profile if ( trap_FS_FOpenFile( va( "profiles/%s/profile.pid", cl_profile.string ), &f, FS_READ ) >= 0 ) { trap_FS_FCloseFile( f ); trap_FS_Delete( va( "profiles/%s/profile.pid", cl_profile.string ) ); } } else if ( Q_stricmp( name, "applyProfile" ) == 0 ) { Q_strncpyz( cl_profile.string, ui_profile.string, sizeof( cl_profile.string ) ); Q_CleanStr( cl_profile.string ); Q_CleanDirName( cl_profile.string ); trap_Cvar_Set( "cl_profile", cl_profile.string ); } else if ( Q_stricmp( name, "setDefaultProfile" ) == 0 ) { fileHandle_t f; Q_strncpyz( cl_defaultProfile.string, ui_profile.string, sizeof( cl_profile.string ) ); Q_CleanStr( cl_defaultProfile.string ); Q_CleanDirName( cl_defaultProfile.string ); trap_Cvar_Set( "cl_defaultProfile", cl_defaultProfile.string ); if ( trap_FS_FOpenFile( "profiles/defaultprofile.dat", &f, FS_WRITE ) >= 0 ) { trap_FS_Write( va( "\"%s\"", cl_defaultProfile.string ), strlen( cl_defaultProfile.string ) + 2, f ); trap_FS_FCloseFile( f ); } } else if ( Q_stricmp( name, "deleteProfile" ) == 0 ) { char buff[MAX_CVAR_VALUE_STRING]; Q_strncpyz( buff, ui_profile.string, sizeof( buff ) ); Q_CleanStr( buff ); Q_CleanDirName( buff ); // can't delete active profile if ( Q_stricmp( buff, cl_profile.string ) ) { if ( !Q_stricmp( buff, cl_defaultProfile.string ) ) { // if deleting the default profile, set the default to the current active profile fileHandle_t f; trap_Cvar_Set( "cl_defaultProfile", cl_profile.string ); if ( trap_FS_FOpenFile( "profiles/defaultprofile.dat", &f, FS_WRITE ) >= 0 ) { trap_FS_Write( va( "\"%s\"", cl_profile.string ), strlen( cl_profile.string ) + 2, f ); trap_FS_FCloseFile( f ); } } trap_FS_Delete( va( "profiles/%s", buff ) ); } } else if ( Q_stricmp( name, "renameProfileInit" ) == 0 ) { trap_Cvar_Set( "ui_profile_renameto", ui_profile.string ); } else if ( Q_stricmp( name, "renameProfile" ) == 0 ) { fileHandle_t f, f2; int len; char buff[MAX_CVAR_VALUE_STRING]; char ui_renameprofileto[MAX_CVAR_VALUE_STRING]; char uiprofile[MAX_CVAR_VALUE_STRING]; trap_Cvar_VariableStringBuffer( "ui_profile_renameto", ui_renameprofileto, sizeof( ui_renameprofileto ) ); Q_strncpyz( buff, ui_renameprofileto, sizeof( buff ) ); Q_CleanStr( buff ); Q_CleanDirName( buff ); Q_strncpyz( uiprofile, ui_profile.string, sizeof( uiprofile ) ); Q_CleanStr( uiprofile ); Q_CleanDirName( uiprofile ); if ( trap_FS_FOpenFile( va( "profiles/%s/profile.dat", buff ), &f, FS_WRITE ) >= 0 ) { trap_FS_Write( va( "\"%s\"", ui_renameprofileto ), strlen( ui_renameprofileto ) + 2, f ); trap_FS_FCloseFile( f ); } // FIXME: make this copying handle all files in the profiles directory if ( Q_stricmp( uiprofile, buff ) ) { if ( trap_FS_FOpenFile( va( "profiles/%s/%s", buff, CONFIG_NAME ), &f, FS_WRITE ) >= 0 ) { if ( ( len = trap_FS_FOpenFile( va( "profiles/%s/%s", uiprofile, CONFIG_NAME ), &f2, FS_READ ) ) >= 0 ) { int i; for ( i = 0; i < len; i++ ) { byte b; trap_FS_Read( &b, 1, f2 ); trap_FS_Write( &b, 1, f ); } trap_FS_FCloseFile( f2 ); } trap_FS_FCloseFile( f ); } if ( trap_FS_FOpenFile( va( "profiles/%s/servercache.dat", buff ), &f, FS_WRITE ) >= 0 ) { if ( ( len = trap_FS_FOpenFile( va( "profiles/%s/servercache.dat", cl_profile.string ), &f2, FS_READ ) ) >= 0 ) { int i; for ( i = 0; i < len; i++ ) { byte b; trap_FS_Read( &b, 1, f2 ); trap_FS_Write( &b, 1, f ); } trap_FS_FCloseFile( f2 ); } trap_FS_FCloseFile( f ); } if ( !Q_stricmp( uiprofile, cl_defaultProfile.string ) ) { // if renaming the default profile, set the default to the new profile trap_Cvar_Set( "cl_defaultProfile", buff ); if ( trap_FS_FOpenFile( "profiles/defaultprofile.dat", &f, FS_WRITE ) >= 0 ) { trap_FS_Write( va( "\"%s\"", buff ), strlen( buff ) + 2, f ); trap_FS_FCloseFile( f ); } } // if renaming the active profile, set active to new name if ( !Q_stricmp( uiprofile, cl_profile.string ) ) { trap_Cvar_Set( "cl_profile", buff ); } // delete the old profile trap_FS_Delete( va( "profiles/%s", uiprofile ) ); } trap_Cvar_Set( "ui_profile", ui_renameprofileto ); trap_Cvar_Set( "ui_profile_renameto", "" ); } else if ( Q_stricmp( name, "togglePbSvStatus" ) == 0 ) { // TTimo int sv_pb = trap_Cvar_VariableValue( "sv_punkbuster" ); if ( sv_pb ) { trap_SetPbSvStatus( 0 ); } else { trap_SetPbSvStatus( 1 ); } } else if ( Q_stricmp( name, "initHostGameFeatures" ) == 0 ) { int cvar = trap_Cvar_VariableValue( "g_maxlives" ); if ( cvar ) { trap_Cvar_Set( "ui_maxlives", "1" ); } else { trap_Cvar_Set( "ui_maxlives", "0" ); } cvar = trap_Cvar_VariableValue( "g_heavyWeaponRestriction" ); if ( cvar == 100 ) { trap_Cvar_Set( "ui_heavyWeaponRestriction", "0" ); } else { trap_Cvar_Set( "ui_heavyWeaponRestriction", "1" ); } } else if ( Q_stricmp( name, "toggleMaxLives" ) == 0 ) { int ui_ml = trap_Cvar_VariableValue( "ui_maxlives" ); if ( ui_ml ) { trap_Cvar_Set( "g_maxlives", "5" ); } else { trap_Cvar_Set( "g_maxlives", "0" ); } } else if ( Q_stricmp( name, "toggleWeaponRestriction" ) == 0 ) { int ui_hwr = trap_Cvar_VariableValue( "ui_heavyWeaponRestriction" ); if ( ui_hwr ) { trap_Cvar_Set( "g_heavyWeaponRestriction", "10" ); } else { trap_Cvar_Set( "g_heavyWeaponRestriction", "100" ); } } else if ( Q_stricmp( name, "openModURL" ) == 0 ) { trap_Cvar_Set( "ui_finalURL", UI_Cvar_VariableString( "ui_modURL" ) ); } else if ( Q_stricmp( name, "openServerURL" ) == 0 ) { trap_Cvar_Set( "ui_finalURL", UI_Cvar_VariableString( "ui_URL" ) ); } else if ( Q_stricmp( name, "validate_openURL" ) == 0 ) { // this is the only one that effectively triggers the URL, after the disclaimers are done with // we use ui_finalURL as an auxiliary variable to gather URLs from various sources trap_openURL( UI_Cvar_VariableString( "ui_finalURL" ) ); } else if ( Q_stricmp( name, "clientCheckVote" ) == 0 ) { int flags = trap_Cvar_VariableValue( "cg_ui_voteFlags" ); if ( flags == VOTING_DISABLED ) { trap_Cvar_SetValue( "cg_ui_novote", 1 ); } else { trap_Cvar_SetValue( "cg_ui_novote", 0 );} } else if ( Q_stricmp( name, "reconnect" ) == 0 ) { // TODO: if dumped because of cl_allowdownload problem, toggle on first (we don't have appropriate support for this yet) trap_Cmd_ExecuteText( EXEC_APPEND, "reconnect\n" ); } else if ( Q_stricmp( name, "redirect" ) == 0 ) { // fretn char buf[MAX_STRING_CHARS]; trap_Cvar_VariableStringBuffer( "com_errorMessage", buf, sizeof( buf ) ); trap_Cmd_ExecuteText( EXEC_APPEND, va( "connect %s\n", buf ) ); trap_Cvar_Set( "com_errorMessage", "" ); } else if ( Q_stricmp( name, "updateGameType" ) == 0 ) { trap_Cvar_Update( &ui_netGameType ); /*if( ui_netGameType.integer == GT_WOLF_CAMPAIGN ) { if( ui_mapIndex.integer >= UI_MapCountByGameType( qfalse ) ) } else { }*/ if ( ui_mapIndex.integer >= UI_MapCountByGameType( qfalse ) ) { Menu_SetFeederSelection( NULL, FEEDER_MAPS, 0, NULL ); Menu_SetFeederSelection( NULL, FEEDER_ALLMAPS, 0, NULL ); } } // ydnar else if ( Q_stricmp( name, "vidSave" ) == 0 ) { int mode; // get mode mode = trap_Cvar_VariableValue( "r_mode" ); // save mode to old mode trap_Cvar_SetValue( "r_oldMode", mode ); } else if ( Q_stricmp( name, "vidReset" ) == 0 ) { int oldMode; // get old mode oldMode = trap_Cvar_VariableValue( "r_oldMode" ); if ( oldMode == 0 ) { oldMode = 3; } // reset mode to old mode trap_Cvar_SetValue( "r_mode", oldMode ); trap_Cvar_Set( "r_oldMode", "" ); } else if ( Q_stricmp( name, "vidConfirm" ) == 0 ) { trap_Cvar_Set( "r_oldMode", "" ); } else if ( Q_stricmp( name, "systemCvarsGet" ) == 0 ) { int ui_r_mode = trap_Cvar_VariableValue( "r_mode" ); float ui_r_gamma = trap_Cvar_VariableValue( "r_gamma" ); int ui_rate = trap_Cvar_VariableValue( "rate" ); int ui_cl_maxpackets = trap_Cvar_VariableValue( "cl_maxpackets" ); int ui_cl_packetdup = trap_Cvar_VariableValue( "cl_packetdup" ); float ui_sensitivity = trap_Cvar_VariableValue( "sensitivity" ); int ui_r_colorbits = trap_Cvar_VariableValue( "r_colorbits" ); int ui_r_fullscreen = trap_Cvar_VariableValue( "r_fullscreen" ); int ui_r_lodbias = trap_Cvar_VariableValue( "r_lodbias" ); int ui_r_subdivisions = trap_Cvar_VariableValue( "r_subdivisions" ); int ui_r_picmip = trap_Cvar_VariableValue( "r_picmip" ); int ui_r_texturebits = trap_Cvar_VariableValue( "r_texturebits" ); int ui_r_depthbits = trap_Cvar_VariableValue( "r_depthbits" ); int ui_r_ext_compressed_textures = trap_Cvar_VariableValue( "r_ext_compressed_textures" ); int ui_r_finish = trap_Cvar_VariableValue( "r_finish" ); int ui_r_dynamiclight = trap_Cvar_VariableValue( "r_dynamiclight" ); int ui_r_allowextensions = trap_Cvar_VariableValue( "r_allowextensions" ); int ui_m_filter = trap_Cvar_VariableValue( "m_filter" ); int ui_s_khz = trap_Cvar_VariableValue( "s_khz" ); int ui_r_detailtextures = trap_Cvar_VariableValue( "r_detailtextures" ); char ui_r_texturemode[MAX_CVAR_VALUE_STRING]; trap_Cvar_VariableStringBuffer( "r_texturemode", ui_r_texturemode, sizeof( ui_r_texturemode ) ); trap_Cvar_Set( "ui_r_mode", va( "%i",ui_r_mode ) ); trap_Cvar_Set( "ui_r_gamma", va( "%f",ui_r_gamma ) ); trap_Cvar_Set( "ui_rate", va( "%i",ui_rate ) ); trap_Cvar_Set( "ui_cl_maxpackets", va( "%i",ui_cl_maxpackets ) ); trap_Cvar_Set( "ui_cl_packetdup", va( "%i",ui_cl_packetdup ) ); trap_Cvar_Set( "ui_sensitivity", va( "%f",ui_sensitivity ) ); trap_Cvar_Set( "ui_r_colorbits", va( "%i",ui_r_colorbits ) ); trap_Cvar_Set( "ui_r_fullscreen", va( "%i",ui_r_fullscreen ) ); trap_Cvar_Set( "ui_r_lodbias", va( "%i",ui_r_lodbias ) ); trap_Cvar_Set( "ui_r_subdivisions", va( "%i",ui_r_subdivisions ) ); trap_Cvar_Set( "ui_r_picmip", va( "%i",ui_r_picmip ) ); trap_Cvar_Set( "ui_r_texturebits", va( "%i",ui_r_texturebits ) ); trap_Cvar_Set( "ui_r_depthbits", va( "%i",ui_r_depthbits ) ); trap_Cvar_Set( "ui_r_ext_compressed_textures", va( "%i",ui_r_ext_compressed_textures ) ); trap_Cvar_Set( "ui_r_finish", va( "%i",ui_r_finish ) ); trap_Cvar_Set( "ui_r_dynamiclight", va( "%i",ui_r_dynamiclight ) ); trap_Cvar_Set( "ui_r_allowextensions", va( "%i",ui_r_allowextensions ) ); trap_Cvar_Set( "ui_m_filter", va( "%i",ui_m_filter ) ); trap_Cvar_Set( "ui_s_khz", va( "%i",ui_s_khz ) ); trap_Cvar_Set( "ui_r_detailtextures", va( "%i",ui_r_detailtextures ) ); trap_Cvar_Set( "ui_r_texturemode", ui_r_texturemode ); } else if ( Q_stricmp( name, "systemCvarsReset" ) == 0 ) { trap_Cvar_Set( "ui_r_mode", "" ); trap_Cvar_Set( "ui_r_gamma", "" ); trap_Cvar_Set( "ui_rate", "" ); trap_Cvar_Set( "ui_cl_maxpackets", "" ); trap_Cvar_Set( "ui_cl_packetdup", "" ); trap_Cvar_Set( "ui_sensitivity", "" ); trap_Cvar_Set( "ui_r_colorbits", "" ); trap_Cvar_Set( "ui_r_fullscreen", "" ); trap_Cvar_Set( "ui_r_lodbias", "" ); trap_Cvar_Set( "ui_r_subdivisions", "" ); trap_Cvar_Set( "ui_r_picmip", "" ); trap_Cvar_Set( "ui_r_texturebits", "" ); trap_Cvar_Set( "ui_r_depthbits", "" ); trap_Cvar_Set( "ui_r_ext_compressed_textures", "" ); trap_Cvar_Set( "ui_r_finish", "" ); trap_Cvar_Set( "ui_r_dynamiclight", "" ); trap_Cvar_Set( "ui_r_allowextensions", "" ); trap_Cvar_Set( "ui_m_filter", "" ); trap_Cvar_Set( "ui_s_khz", "" ); trap_Cvar_Set( "ui_r_detailtextures", "" ); trap_Cvar_Set( "ui_r_texturemode", "" ); } else if ( Q_stricmp( name, "systemCvarsApply" ) == 0 ) { int ui_r_mode = trap_Cvar_VariableValue( "ui_r_mode" ); float ui_r_gamma = trap_Cvar_VariableValue( "ui_r_gamma" ); int ui_rate = trap_Cvar_VariableValue( "ui_rate" ); int ui_cl_maxpackets = trap_Cvar_VariableValue( "ui_cl_maxpackets" ); int ui_cl_packetdup = trap_Cvar_VariableValue( "ui_cl_packetdup" ); float ui_sensitivity = trap_Cvar_VariableValue( "ui_sensitivity" ); int ui_r_colorbits = trap_Cvar_VariableValue( "ui_r_colorbits" ); int ui_r_fullscreen = trap_Cvar_VariableValue( "ui_r_fullscreen" ); int ui_r_lodbias = trap_Cvar_VariableValue( "ui_r_lodbias" ); int ui_r_subdivisions = trap_Cvar_VariableValue( "ui_r_subdivisions" ); int ui_r_picmip = trap_Cvar_VariableValue( "ui_r_picmip" ); int ui_r_texturebits = trap_Cvar_VariableValue( "ui_r_texturebits" ); int ui_r_depthbits = trap_Cvar_VariableValue( "ui_r_depthbits" ); int ui_r_ext_compressed_textures = trap_Cvar_VariableValue( "ui_r_ext_compressed_textures" ); int ui_r_finish = trap_Cvar_VariableValue( "ui_r_finish" ); int ui_r_dynamiclight = trap_Cvar_VariableValue( "ui_r_dynamiclight" ); int ui_r_allowextensions = trap_Cvar_VariableValue( "ui_r_allowextensions" ); int ui_m_filter = trap_Cvar_VariableValue( "ui_m_filter" ); int ui_s_khz = trap_Cvar_VariableValue( "ui_s_khz" ); int ui_r_detailtextures = trap_Cvar_VariableValue( "ui_r_detailtextures" ); char ui_r_texturemode[MAX_CVAR_VALUE_STRING]; trap_Cvar_VariableStringBuffer( "ui_r_texturemode", ui_r_texturemode, sizeof( ui_r_texturemode ) ); // failsafe if ( ui_rate == 0 ) { ui_rate = 5000; ui_cl_maxpackets = 30; ui_cl_packetdup = 1; } trap_Cvar_Set( "r_mode", va( "%i",ui_r_mode ) ); trap_Cvar_Set( "r_gamma", va( "%f",ui_r_gamma ) ); trap_Cvar_Set( "rate", va( "%i",ui_rate ) ); trap_Cvar_Set( "cl_maxpackets", va( "%i",ui_cl_maxpackets ) ); trap_Cvar_Set( "cl_packetdup", va( "%i",ui_cl_packetdup ) ); trap_Cvar_Set( "sensitivity", va( "%f",ui_sensitivity ) ); trap_Cvar_Set( "r_colorbits", va( "%i",ui_r_colorbits ) ); trap_Cvar_Set( "r_fullscreen", va( "%i",ui_r_fullscreen ) ); trap_Cvar_Set( "r_lodbias", va( "%i",ui_r_lodbias ) ); trap_Cvar_Set( "r_subdivisions", va( "%i",ui_r_subdivisions ) ); trap_Cvar_Set( "r_picmip", va( "%i",ui_r_picmip ) ); trap_Cvar_Set( "r_texturebits", va( "%i",ui_r_texturebits ) ); trap_Cvar_Set( "r_depthbits", va( "%i",ui_r_depthbits ) ); trap_Cvar_Set( "r_ext_compressed_textures", va( "%i",ui_r_ext_compressed_textures ) ); trap_Cvar_Set( "r_finish", va( "%i",ui_r_finish ) ); trap_Cvar_Set( "r_dynamiclight", va( "%i",ui_r_dynamiclight ) ); trap_Cvar_Set( "r_allowextensions", va( "%i",ui_r_allowextensions ) ); trap_Cvar_Set( "m_filter", va( "%i",ui_m_filter ) ); trap_Cvar_Set( "s_khz", va( "%i",ui_s_khz ) ); trap_Cvar_Set( "r_detailtextures", va( "%i",ui_r_detailtextures ) ); trap_Cvar_Set( "r_texturemode", ui_r_texturemode ); trap_Cvar_Set( "ui_r_mode", "" ); trap_Cvar_Set( "ui_r_gamma", "" ); trap_Cvar_Set( "ui_rate", "" ); trap_Cvar_Set( "ui_cl_maxpackets", "" ); trap_Cvar_Set( "ui_cl_packetdup", "" ); trap_Cvar_Set( "ui_sensitivity", "" ); trap_Cvar_Set( "ui_r_colorbits", "" ); trap_Cvar_Set( "ui_r_fullscreen", "" ); trap_Cvar_Set( "ui_r_lodbias", "" ); trap_Cvar_Set( "ui_r_subdivisions", "" ); trap_Cvar_Set( "ui_r_picmip", "" ); trap_Cvar_Set( "ui_r_texturebits", "" ); trap_Cvar_Set( "ui_r_depthbits", "" ); trap_Cvar_Set( "ui_r_ext_compressed_textures", "" ); trap_Cvar_Set( "ui_r_finish", "" ); trap_Cvar_Set( "ui_r_dynamiclight", "" ); trap_Cvar_Set( "ui_r_allowextensions", "" ); trap_Cvar_Set( "ui_m_filter", "" ); trap_Cvar_Set( "ui_s_khz", "" ); trap_Cvar_Set( "ui_r_detailtextures", "" ); trap_Cvar_Set( "ui_r_texturemode", "" ); } else if ( Q_stricmp( name, "profileCvarsGet" ) == 0 ) { int ui_profile_mousePitch = trap_Cvar_VariableValue( "ui_mousePitch" ); trap_Cvar_Set( "ui_profile_mousePitch", va( "%i",ui_profile_mousePitch ) ); } else if ( Q_stricmp( name, "profileCvarsApply" ) == 0 ) { int ui_handedness = trap_Cvar_VariableValue( "ui_handedness" ); int ui_profile_mousePitch = trap_Cvar_VariableValue( "ui_profile_mousePitch" ); trap_Cvar_Set( "ui_mousePitch", va( "%i",ui_profile_mousePitch ) ); if ( ui_profile_mousePitch == 0 ) { trap_Cvar_SetValue( "m_pitch", 0.022f ); } else { trap_Cvar_SetValue( "m_pitch", -0.022f ); } if ( ui_handedness == 0 ) { // exec default.cfg trap_Cmd_ExecuteText( EXEC_APPEND, "exec default.cfg\n" ); Controls_SetDefaults( qfalse ); } else { // exec default_left.cfg trap_Cmd_ExecuteText( EXEC_APPEND, "exec default_left.cfg\n" ); Controls_SetDefaults( qtrue ); } trap_Cvar_Set( "ui_handedness", "" ); trap_Cvar_Set( "ui_profile_mousePitch", "" ); } else if ( Q_stricmp( name, "profileCvarsReset" ) == 0 ) { trap_Cvar_Set( "ui_handedness", "" ); trap_Cvar_Set( "ui_profile_mousePitch", "" ); } else if ( Q_stricmp( name, "defaultControls" ) == 0 ) { int ui_handedness = trap_Cvar_VariableValue( "ui_handedness" ); if ( ui_handedness == 0 ) { // exec default.cfg trap_Cmd_ExecuteText( EXEC_APPEND, "exec default.cfg\n" ); Controls_SetDefaults( qfalse ); } else { // exec default_left.cfg trap_Cmd_ExecuteText( EXEC_APPEND, "exec default_left.cfg\n" ); Controls_SetDefaults( qtrue ); } } else { Com_Printf( "^3WARNING: unknown UI script %s\n", name ); } } } static void UI_GetTeamColor( vec4_t *color ) { } /* ================== UI_MapCountByGameType ================== */ static int UI_MapCountByGameType( qboolean singlePlayer ) { int i, c, game; c = 0; game = singlePlayer ? uiInfo.gameTypes[ui_gameType.integer].gtEnum : ui_netGameType.integer; if ( game == GT_WOLF_CAMPAIGN ) { for ( i = 0; i < uiInfo.campaignCount; i++ ) { if ( uiInfo.campaignList[i].typeBits & ( 1 << GT_WOLF ) ) { c++; } } } else { for ( i = 0; i < uiInfo.mapCount; i++ ) { uiInfo.mapList[i].active = qfalse; if ( uiInfo.mapList[i].typeBits & ( 1 << game ) ) { if ( singlePlayer ) { continue; } c++; uiInfo.mapList[i].active = qtrue; } } } return c; } /* ================== UI_MapCountByCampaign ================== */ #if 0 // rain - unused static int UI_MapCountByCampaign( qboolean singlePlayer ) { int campaign; int i, count = 0; campaign = singlePlayer ? ui_currentCampaign.integer : ui_currentNetCampaign.integer; for ( i = 0; i < uiInfo.campaignList[campaign].mapCount; i++ ) { if ( singlePlayer && ( uiInfo.campaignList[i].typeBits & ( 1 << GT_SINGLE_PLAYER ) ) ) { count++; } else if ( !singlePlayer && !( uiInfo.campaignList[i].typeBits & ( 1 << GT_SINGLE_PLAYER ) ) ) { count++; } } return( count ); } #endif /* ================== UI_CampaignCount ================== */ static int UI_CampaignCount( 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.campaignCount; i++ ) { if ( singlePlayer && !( uiInfo.campaignList[i].typeBits & ( 1 << GT_SINGLE_PLAYER ) ) ) { continue; } if ( uiInfo.campaignList[i].unlocked ) { c++; } } return c; //return uiInfo.campaignCount; } /* ================== 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; } /* ================== 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; } } } /* ================== 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 ); } /* ================== UI_BuildServerDisplayList ================== */ static void UI_BuildServerDisplayList( qboolean force ) { int i, count, clients, maxClients, ping, game, len, visible, friendlyFire, maxlives, punkbuster, antilag, password, weaponrestricted, balancedteams; char info[MAX_STRING_CHARS]; //qboolean startRefresh = qtrue; // TTimo: unused static int numinvisible; game = 0; // NERVE - SMF - shut up compiler warning 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 == 0 ) { strcpy( uiInfo.serverStatus.motd, va( "Enemy Territory - Version: %s", Q3_VERSION ) ); 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 ); } // 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; uiInfo.serverStatus.currentServerPreview = 0; return; } if ( !uiInfo.serverStatus.numDisplayServers ) { uiInfo.serverStatus.currentServerPreview = 0; } 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; } visible = qtrue; // get the ping for this server ping = trap_LAN_GetServerPing( ui_netSource.integer, i ); if ( ping > /*=*/ 0 || ui_netSource.integer == AS_FAVORITES ) { trap_LAN_GetServerInfo( ui_netSource.integer, i, info, MAX_STRING_CHARS ); clients = atoi( Info_ValueForKey( info, "clients" ) ); uiInfo.serverStatus.numPlayersOnServers += clients; trap_Cvar_Update( &ui_browserShowEmptyOrFull ); if ( ui_browserShowEmptyOrFull.integer ) { maxClients = atoi( Info_ValueForKey( info, "sv_maxclients" ) ); if ( clients != maxClients && ( ( !clients && ui_browserShowEmptyOrFull.integer == 2 ) || ( clients && ui_browserShowEmptyOrFull.integer == 1 ) ) ) { trap_LAN_MarkServerVisible( ui_netSource.integer, i, qfalse ); continue; } if ( clients && ( ( clients == maxClients && ui_browserShowEmptyOrFull.integer == 2 ) || ( clients != maxClients && ui_browserShowEmptyOrFull.integer == 1 ) ) ) { trap_LAN_MarkServerVisible( ui_netSource.integer, i, qfalse ); continue; } } trap_Cvar_Update( &ui_browserShowPasswordProtected ); if ( ui_browserShowPasswordProtected.integer ) { password = atoi( Info_ValueForKey( info, "needpass" ) ); if ( ( password && ui_browserShowPasswordProtected.integer == 2 ) || ( !password && ui_browserShowPasswordProtected.integer == 1 ) ) { trap_LAN_MarkServerVisible( ui_netSource.integer, i, qfalse ); continue; } } trap_Cvar_Update( &ui_browserShowFriendlyFire ); if ( ui_browserShowFriendlyFire.integer ) { friendlyFire = atoi( Info_ValueForKey( info, "friendlyFire" ) ); if ( ( friendlyFire && ui_browserShowFriendlyFire.integer == 2 ) || ( !friendlyFire && ui_browserShowFriendlyFire.integer == 1 ) ) { trap_LAN_MarkServerVisible( ui_netSource.integer, i, qfalse ); continue; } } trap_Cvar_Update( &ui_browserShowMaxlives ); if ( ui_browserShowMaxlives.integer ) { maxlives = atoi( Info_ValueForKey( info, "maxlives" ) ); if ( ( maxlives && ui_browserShowMaxlives.integer == 2 ) || ( !maxlives && ui_browserShowMaxlives.integer == 1 ) ) { trap_LAN_MarkServerVisible( ui_netSource.integer, i, qfalse ); continue; } } trap_Cvar_Update( &ui_browserShowPunkBuster ); if ( ui_browserShowPunkBuster.integer ) { punkbuster = atoi( Info_ValueForKey( info, "punkbuster" ) ); if ( ( punkbuster && ui_browserShowPunkBuster.integer == 2 ) || ( !punkbuster && ui_browserShowPunkBuster.integer == 1 ) ) { trap_LAN_MarkServerVisible( ui_netSource.integer, i, qfalse ); continue; } } trap_Cvar_Update( &ui_browserShowAntilag ); if ( ui_browserShowAntilag.integer ) { antilag = atoi( Info_ValueForKey( info, "g_antilag" ) ); if ( ( antilag && ui_browserShowAntilag.integer == 2 ) || ( !antilag && ui_browserShowAntilag.integer == 1 ) ) { trap_LAN_MarkServerVisible( ui_netSource.integer, i, qfalse ); continue; } } trap_Cvar_Update( &ui_browserShowWeaponsRestricted ); if ( ui_browserShowWeaponsRestricted.integer ) { weaponrestricted = atoi( Info_ValueForKey( info, "weaprestrict" ) ); if ( ( weaponrestricted != 100 && ui_browserShowWeaponsRestricted.integer == 2 ) || ( weaponrestricted == 100 && ui_browserShowWeaponsRestricted.integer == 1 ) ) { trap_LAN_MarkServerVisible( ui_netSource.integer, i, qfalse ); continue; } } trap_Cvar_Update( &ui_browserShowTeamBalanced ); if ( ui_browserShowTeamBalanced.integer ) { balancedteams = atoi( Info_ValueForKey( info, "balancedteams" ) ); if ( ( balancedteams && ui_browserShowTeamBalanced.integer == 2 ) || ( !balancedteams && ui_browserShowTeamBalanced.integer == 1 ) ) { trap_LAN_MarkServerVisible( ui_netSource.integer, i, qfalse ); continue; } } trap_Cvar_Update( &ui_joinGameType ); if ( ui_joinGameType.integer != -1 ) { game = atoi( Info_ValueForKey( info, "gametype" ) ); if ( game != ui_joinGameType.integer ) { trap_LAN_MarkServerVisible( ui_netSource.integer, i, qfalse ); continue; } } /*trap_Cvar_Update( &ui_serverFilterType ); if (ui_serverFilterType.integer > 0) { if (Q_stricmp(Info_ValueForKey(info, "game"), serverFilters[ui_serverFilterType.integer].basedir) != 0) { trap_LAN_MarkServerVisible(ui_netSource.integer, i, qfalse); continue; } }*/ // make sure we never add a favorite server twice if ( ui_netSource.integer == AS_FAVORITES ) { UI_RemoveServerFromDisplayList( i ); } // insert the server into the list if ( uiInfo.serverStatus.numDisplayServers == 0 ) { char *s = Info_ValueForKey( info, "mapname" ); if ( s && *s ) { uiInfo.serverStatus.currentServerPreview = trap_R_RegisterShaderNoMip( va( "levelshots/%s", Info_ValueForKey( info, "mapname" ) ) ); } else { uiInfo.serverStatus.currentServerPreview = trap_R_RegisterShaderNoMip( "levelshots/unknownmap" ); } } UI_BinaryServerInsertion( i ); // done with this server if ( ping > /*=*/ 0 ) { trap_LAN_MarkServerVisible( ui_netSource.integer, i, qfalse ); numinvisible++; } } } uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime; // if there were no servers visible for ping updates if ( !visible ) { // UI_StopServerRefresh(); // uiInfo.serverStatus.nextDisplayRefresh = 0; } } typedef struct { 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} }; /* ================== 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++; } } } } /* ================== UI_GetServerStatusInfo ================== */ static int UI_GetServerStatusInfo( const char *serverAddress, serverStatusInfo_t *info ) { char *p, *score, *ping, *name, *p_val = NULL, *p_name = NULL; menuDef_t *menu, *menu2; // we use the URL buttons in several menus int i, len; 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 ) ) ) { menu = Menus_FindByName( "serverinfo_popmenu" ); menu2 = Menus_FindByName( "popupError" ); 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++; // cleanup of the URL cvars trap_Cvar_Set( "ui_URL", "" ); trap_Cvar_Set( "ui_modURL", "" ); // get the cvars while ( p && *p ) { p = strchr( p, '\\' ); if ( !p ) { break; } *p++ = '\0'; if ( p_name ) { if ( !Q_stricmp( p_name, "url" ) ) { trap_Cvar_Set( "ui_URL", p_val ); if ( menu ) { Menu_ShowItemByName( menu, "serverURL", qtrue ); } if ( menu2 ) { Menu_ShowItemByName( menu2, "serverURL", qtrue ); } } else if ( !Q_stricmp( p_name, "mod_url" ) ) { trap_Cvar_Set( "ui_modURL", p_val ); if ( menu ) { Menu_ShowItemByName( menu, "modURL", qtrue ); } if ( menu2 ) { Menu_ShowItemByName( menu2, "modURL", qtrue ); } } } if ( *p == '\\' ) { break; } p_name = p; info->lines[info->numLines][0] = p; info->lines[info->numLines][1] = ""; info->lines[info->numLines][2] = ""; p = strchr( p, '\\' ); if ( !p ) { break; } *p++ = '\0'; p_val = p; 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++; } } UI_SortServerStatusInfo( info ); return qtrue; } return qfalse; } /* ================== stristr ================== */ static char *stristr( char *str, char *charset ) { int i; 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_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++; } 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...", 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 ); } } } 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 ); } } /* ================== UI_BuildServerStatus ================== */ static void UI_BuildServerStatus( qboolean force ) { menuDef_t *menu; uiClientState_t cstate; trap_GetClientState( &cstate ); 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; // TTimo - reset the server URL / mod URL till we get the new ones // the URL buttons are used in the two menus, serverinfo_popmenu and error_popmenu_diagnose menu = Menus_FindByName( "serverinfo_popmenu" ); if ( menu ) { Menu_ShowItemByName( menu, "serverURL", qfalse ); Menu_ShowItemByName( menu, "modURL", qfalse ); } menu = Menus_FindByName( "popupError" ); if ( menu ) { Menu_ShowItemByName( menu, "serverURL", qfalse ); Menu_ShowItemByName( menu, "modURL", qfalse ); } // reset all server status requests trap_LAN_ServerStatus( NULL, NULL, 0 ); } if ( cstate.connState < CA_CONNECTED ) { 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; } } /* ================== UI_FeederCount ================== */ static int UI_FeederCount( float feederID ) { if ( feederID == FEEDER_HEADS ) { return uiInfo.characterCount; } else if ( feederID == FEEDER_Q3HEADS ) { return uiInfo.q3HeadCount; } else if ( feederID == FEEDER_CINEMATICS ) { return uiInfo.movieCount; } else if ( feederID == FEEDER_SAVEGAMES ) { return uiInfo.savegameCount; } else if ( feederID == FEEDER_MAPS || feederID == FEEDER_ALLMAPS ) { return UI_MapCountByGameType( feederID == FEEDER_MAPS ? qtrue : qfalse ); } else if ( feederID == FEEDER_CAMPAIGNS || feederID == FEEDER_ALLCAMPAIGNS ) { return UI_CampaignCount( feederID == FEEDER_CAMPAIGNS ? qtrue : qfalse ); } else if ( feederID == FEEDER_GLINFO ) { return uiInfo.numGlInfoLines; } else if ( feederID == FEEDER_PROFILES ) { return uiInfo.profileCount; } 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_MODS ) { return uiInfo.modCount; } else if ( feederID == FEEDER_DEMOS ) { return uiInfo.demoCount; } return 0; } static const char *UI_SelectedMap( qboolean singlePlayer, int index, int *actual ) { int i, c, game; c = 0; game = singlePlayer ? uiInfo.gameTypes[ui_gameType.integer].gtEnum : ui_netGameType.integer; *actual = 0; if ( game == GT_WOLF_CAMPAIGN ) { for ( i = 0; i < uiInfo.mapCount; i++ ) { if ( uiInfo.campaignList[i].typeBits & ( 1 << GT_WOLF ) ) { if ( c == index ) { *actual = i; return uiInfo.campaignList[i].campaignName; } else { c++; } } } } else { 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 ""; } static const char *UI_SelectedCampaign( int index, int *actual ) { int i, c; c = 0; *actual = 0; for ( i = 0; i < uiInfo.campaignCount; i++ ) { if ( ( uiInfo.campaignList[i].order == index ) && uiInfo.campaignList[i].unlocked ) { *actual = i; //if(uiInfo.campaignList[i].unlocked) { return uiInfo.campaignList[i].campaignName; //} else { // return va( "^1%s", uiInfo.campaignList[i].campaignName); //} } } return ""; } 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 0; } static void UI_UpdatePendingPings() { trap_LAN_ResetPings( ui_netSource.integer ); uiInfo.serverStatus.refreshActive = qtrue; uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 1000; } // NERVE - SMF static void UI_FeederAddItem( float feederID, const char *name, int index ) { } // -NERVE - SMF //----(SA) added (whoops, this got nuked in a check-in...) static const char *UI_FileText( char *fileName ) { int len; fileHandle_t f; static char buf[MAX_MENUDEFFILE]; // return "flubber"; len = trap_FS_FOpenFile( fileName, &f, FS_READ ); if ( !f ) { return NULL; } trap_FS_Read( buf, len, f ); buf[len] = 0; trap_FS_FCloseFile( f ); return &buf[0]; } //----(SA) end const char *UI_FeederItemText( float feederID, int index, int column, qhandle_t *handles, int *numhandles ) { static char info[MAX_STRING_CHARS]; static char hostname[1024]; static char clientBuff[32]; static char pingstr[10]; static int lastColumn = -1; static int lastTime = 0; *numhandles = 0; if ( feederID == FEEDER_HEADS ) { if ( index >= 0 && index < uiInfo.characterCount ) { return uiInfo.characterList[index].name; } } 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( feederID == FEEDER_MAPS ? qtrue : qfalse, index, &actual ); } else if ( feederID == FEEDER_CAMPAIGNS || feederID == FEEDER_ALLCAMPAIGNS ) { int actual; return UI_SelectedCampaign( index, &actual ); } else if ( feederID == FEEDER_GLINFO ) { if ( index == 0 ) { return( va( "Vendor: %s", uiInfo.uiDC.glconfig.vendor_string ) ); } else if ( index == 1 ) { return va( "Version: %s: %s", uiInfo.uiDC.glconfig.version_string,uiInfo.uiDC.glconfig.renderer_string ); } else if ( index == 2 ) { return va( "Pixelformat: color(%d-bits) Z(%d-bits) stencil(%d-bits)", uiInfo.uiDC.glconfig.colorBits, uiInfo.uiDC.glconfig.depthBits, uiInfo.uiDC.glconfig.stencilBits ); } else if ( index >= 4 && index < uiInfo.numGlInfoLines ) { return uiInfo.glInfoLines[index - 4]; } else {return "";} } else if ( feederID == FEEDER_SERVERS ) { if ( index >= 0 && index < uiInfo.serverStatus.numDisplayServers ) { int ping, game, antilag, needpass, friendlyfire, maxlives, punkbuster, weaponrestrictions, balancedteams, serverload; 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; } 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 ) { 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 { return Info_ValueForKey( info, "hostname" ); } } 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_GAME: game = atoi( Info_ValueForKey( info, "gametype" ) ); if ( ping > /*=*/ 0 && game >= 0 && game < uiInfo.numGameTypes ) { int i; //return ETGameTypes[game]; //return shortETGameTypes[game]; for ( i = 0; i < uiInfo.numGameTypes; i++ ) { if ( uiInfo.gameTypes[i].gtEnum == game ) { return uiInfo.gameTypes[i].gameTypeShort; } } if ( i == uiInfo.numGameTypes ) { return "???"; } } else { return "???"; } case SORT_PING: //if (ping < 0) { if ( ping <= 0 ) { return "..."; } else { /*antilag = atoi(Info_ValueForKey(info, "g_antilag")); if (!antilag) Com_sprintf( pingstr, sizeof(pingstr), "^3%3i", ping ); else*/ serverload = atoi( Info_ValueForKey( info, "serverload" ) ); if ( serverload == -1 ) { Com_sprintf( pingstr, sizeof( pingstr ), " %3i", ping ); } else if ( serverload > 75 ) { Com_sprintf( pingstr, sizeof( pingstr ), "^1 %3i", ping ); } else if ( serverload > 40 ) { Com_sprintf( pingstr, sizeof( pingstr ), "^3 %3i", ping ); } else { Com_sprintf( pingstr, sizeof( pingstr ), "^2 %3i", ping ); } return pingstr; } case SORT_FILTERS: if ( ping <= 0 ) { *numhandles = 0; return ""; } else { *numhandles = 7; needpass = atoi( Info_ValueForKey( info, "needpass" ) ); friendlyfire = atoi( Info_ValueForKey( info, "friendlyFire" ) ); maxlives = atoi( Info_ValueForKey( info, "maxlives" ) ); punkbuster = atoi( Info_ValueForKey( info, "punkbuster" ) ); weaponrestrictions = atoi( Info_ValueForKey( info, "weaprestrict" ) ); antilag = atoi( Info_ValueForKey( info, "g_antilag" ) ); balancedteams = atoi( Info_ValueForKey( info, "balancedteams" ) ); if ( needpass ) { handles[0] = uiInfo.passwordFilter; } else { handles[0] = -1;} if ( friendlyfire ) { handles[1] = uiInfo.friendlyFireFilter; } else { handles[1] = -1;} if ( maxlives ) { handles[2] = uiInfo.maxLivesFilter; } else { handles[2] = -1;} if ( punkbuster ) { handles[3] = uiInfo.punkBusterFilter; } else { handles[3] = -1;} if ( weaponrestrictions < 100 ) { handles[4] = uiInfo.weaponRestrictionsFilter; } else { handles[4] = -1;} if ( antilag ) { handles[5] = uiInfo.antiLagFilter; } else { handles[5] = -1;} if ( balancedteams ) { handles[6] = uiInfo.teamBalanceFilter; } else { handles[6] = -1;} return ""; } case SORT_FAVOURITES: *numhandles = 1; if ( trap_LAN_ServerIsInFavoriteList( ui_netSource.integer, uiInfo.serverStatus.displayServers[index] ) ) { handles[0] = uiInfo.uiDC.Assets.checkboxCheck; } else { handles[0] = uiInfo.uiDC.Assets.checkboxCheckNot; } return ""; } } } 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]; } } 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_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_SAVEGAMES ) { if ( index >= 0 && index < uiInfo.savegameCount ) { return uiInfo.savegameList[index].name; } } else if ( feederID == FEEDER_DEMOS ) { if ( index >= 0 && index < uiInfo.demoCount ) { return uiInfo.demoList[index]; } } else if ( feederID == FEEDER_PROFILES ) { if ( index >= 0 && index < uiInfo.profileCount ) { char buff[MAX_CVAR_VALUE_STRING]; Q_strncpyz( buff, uiInfo.profileList[index].name, sizeof( buff ) ); Q_CleanStr( buff ); Q_CleanDirName( buff ); if ( !Q_stricmp( buff, cl_profile.string ) ) { if ( !Q_stricmp( buff, cl_defaultProfile.string ) ) { return( va( "^7(Default) %s", uiInfo.profileList[index].name ) ); } else { return( va( "^7%s", uiInfo.profileList[index].name ) ); } } else if ( !Q_stricmp( buff, cl_defaultProfile.string ) ) { return( va( "(Default) %s", uiInfo.profileList[index].name ) ); } else { return uiInfo.profileList[index].name; } } } // -NERVE - SMF return ""; } static qhandle_t UI_FeederItemImage( float feederID, int index ) { if ( feederID == FEEDER_HEADS ) { 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; int game; UI_SelectedMap( feederID == FEEDER_MAPS ? qtrue : qfalse, index, &actual ); index = actual; game = feederID == FEEDER_MAPS ? uiInfo.gameTypes[ui_gameType.integer].gtEnum : ui_netGameType.integer; if ( game == GT_WOLF_CAMPAIGN ) { if ( index >= 0 && index < uiInfo.campaignCount ) { if ( uiInfo.campaignList[index].campaignShot == -1 ) { uiInfo.campaignList[index].campaignShot = trap_R_RegisterShaderNoMip( uiInfo.campaignList[index].campaignShortName ); } return uiInfo.campaignList[index].campaignShot; } } else 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; } } else if ( feederID == FEEDER_ALLCAMPAIGNS || feederID == FEEDER_CAMPAIGNS ) { int actual; UI_SelectedCampaign( index, &actual ); index = actual; if ( index >= 0 && index < uiInfo.campaignCount ) { if ( uiInfo.campaignList[index].campaignShot == -1 ) { uiInfo.campaignList[index].campaignShot = trap_R_RegisterShaderNoMip( uiInfo.campaignList[index].campaignShortName ); } return uiInfo.campaignList[index].campaignShot; } } else if ( feederID == FEEDER_SAVEGAMES ) { if ( index >= 0 && index < uiInfo.savegameCount ) { if ( uiInfo.savegameList[index].sshotImage == -1 ) { uiInfo.savegameList[index].sshotImage = trap_R_RegisterShaderNoMip( va( "save/images/%s.tga", uiInfo.savegameList[index].name ) ); } return uiInfo.savegameList[index].sshotImage; } } return 0; } void UI_FeederSelection( float feederID, int index ) { static char info[MAX_STRING_CHARS]; if ( feederID == FEEDER_HEADS ) { if ( index >= 0 && index < uiInfo.characterCount ) { trap_Cvar_Set( "team_model", uiInfo.characterList[index].female ? "janet" : "james" ); 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; int game; map = ( feederID == FEEDER_ALLMAPS ) ? ui_currentNetMap.integer : ui_currentMap.integer; game = feederID == FEEDER_MAPS ? uiInfo.gameTypes[ui_gameType.integer].gtEnum : ui_netGameType.integer; /*if( game == GT_WOLF_CAMPAIGN ) { if (uiInfo.campaignList[map].campaignCinematic >= 0) { trap_CIN_StopCinematic(uiInfo.campaignList[map].campaignCinematic); uiInfo.campaignList[map].campaignCinematic = -1; } } else if (uiInfo.mapList[map].cinematic >= 0) { trap_CIN_StopCinematic(uiInfo.mapList[map].cinematic); uiInfo.mapList[map].cinematic = -1; }*/ UI_SelectedMap( feederID == FEEDER_MAPS ? qtrue : qfalse, index, &actual ); trap_Cvar_Set( "ui_mapIndex", va( "%d", index ) ); ui_mapIndex.integer = index; // NERVE - SMF - setup advanced server vars if ( feederID == FEEDER_ALLMAPS && game != GT_WOLF_CAMPAIGN ) { ui_currentMap.integer = actual; trap_Cvar_Set( "ui_currentMap", va( "%d", actual ) ); /* trap_Cvar_Set( "ui_userTimelimit", va( "%d", uiInfo.mapList[ui_currentMap.integer].Timelimit ) ); trap_Cvar_Set( "ui_userAxisRespawnTime", va( "%d", uiInfo.mapList[ui_currentMap.integer].AxisRespawnTime ) ); trap_Cvar_Set( "ui_userAlliedRespawnTime", va( "%d", uiInfo.mapList[ui_currentMap.integer].AlliedRespawnTime ) );*/ } // -NERVE - SMF 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) ); } } else if ( feederID == FEEDER_CAMPAIGNS || feederID == FEEDER_ALLCAMPAIGNS ) { int actual, campaign, campaignCount; campaign = ( feederID == FEEDER_ALLCAMPAIGNS ) ? ui_currentNetCampaign.integer : ui_currentCampaign.integer; campaignCount = UI_CampaignCount( feederID == FEEDER_CAMPAIGNS ); if ( uiInfo.campaignList[campaign].campaignCinematic >= 0 ) { trap_CIN_StopCinematic( uiInfo.campaignList[campaign].campaignCinematic ); uiInfo.campaignList[campaign].campaignCinematic = -1; } trap_Cvar_Set( "ui_campaignIndex", va( "%d", index ) ); ui_campaignIndex.integer = index; if ( index < 0 ) { index = 0; } else if ( index >= campaignCount ) { index = campaignCount - 1; } UI_SelectedCampaign( index, &actual ); if ( feederID == FEEDER_ALLCAMPAIGNS ) { ui_currentCampaign.integer = actual; trap_Cvar_Set( "ui_currentCampaign", va( "%d", actual ) ); } if ( feederID == FEEDER_CAMPAIGNS ) { ui_currentCampaign.integer = actual; trap_Cvar_Set( "ui_currentCampaign", va( "%d", actual ) ); // uiInfo.campaignList[ui_currentCampaign.integer].campaignCinematic = trap_CIN_PlayCinematic(va("%s.roq", uiInfo.campaignList[ui_currentCampaign.integer].campaignShortName), 0, 0, 0, 0, (CIN_loop | CIN_silent) ); // UI_LoadBestScores(uiInfo.mapList[ui_currentCampaign.integer].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum); // trap_Cvar_Set("ui_opponentModel", uiInfo.mapList[ui_currentMap.integer].opponentName); // updateOpponentModel = qtrue; /* if (uiInfo.campaignList[ui_currentCampaign.integer].campaignCinematic < 0) { uiInfo.campaignList[ui_currentCampaign.integer].campaignCinematic = -2; }*/ ui_currentCampaignCompleted.integer = ( uiInfo.campaignList[ui_currentCampaign.integer].progress == uiInfo.campaignList[campaignCount - 1].mapCount ); trap_Cvar_Set( "ui_currentCampaignCompleted", va( "%i", ( uiInfo.campaignList[ui_currentCampaign.integer].progress == uiInfo.campaignList[campaignCount - 1].mapCount ) ) ); } else { ui_currentNetCampaign.integer = actual; trap_Cvar_Set( "ui_currentNetCampaign", va( "%d", actual ) ); uiInfo.campaignList[ui_currentNetCampaign.integer].campaignCinematic = trap_CIN_PlayCinematic( va( "%s.roq", uiInfo.campaignList[ui_currentNetCampaign.integer].campaignShortName ), 0, 0, 0, 0, ( CIN_loop | CIN_silent ) ); } } else if ( feederID == FEEDER_GLINFO ) { // } 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 ); mapName = Info_ValueForKey( info, "mapname" ); if ( mapName && *mapName ) { uiInfo.serverStatus.currentServerPreview = trap_R_RegisterShaderNoMip( va( "levelshots/%s", Info_ValueForKey( info, "mapname" ) ) ); } else { uiInfo.serverStatus.currentServerPreview = trap_R_RegisterShaderNoMip( "levelshots/unknownmap" ); } /* 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_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_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_SAVEGAMES ) { uiInfo.savegameIndex = index; } else if ( feederID == FEEDER_DEMOS ) { uiInfo.demoIndex = index; } else if ( feederID == FEEDER_PROFILES ) { uiInfo.profileIndex = index; trap_Cvar_Set( "ui_profile", uiInfo.profileList[index].name ); } } extern void Item_ListBox_MouseEnter( itemDef_t *item, float x, float y, qboolean click ); qboolean UI_FeederSelectionClick( itemDef_t *item ) { listBoxDef_t *listPtr = (listBoxDef_t*)item->typeData; if ( item->special == FEEDER_SERVERS && !Menus_CaptureFuncActive() ) { // ugly hack for favourites handling rectDef_t rect; Item_ListBox_MouseEnter( item, DC->cursorx, DC->cursory, qtrue ); rect.x = item->window.rect.x + listPtr->columnInfo[SORT_FAVOURITES].pos; rect.y = item->window.rect.y + ( listPtr->cursorPos - listPtr->startPos ) * listPtr->elementHeight; rect.w = listPtr->columnInfo[SORT_FAVOURITES].width; rect.h = listPtr->columnInfo[SORT_FAVOURITES].width; if ( BG_CursorInRect( &rect ) ) { char buff[MAX_STRING_CHARS]; char addr[MAX_NAME_LENGTH]; if ( trap_LAN_ServerIsInFavoriteList( ui_netSource.integer, uiInfo.serverStatus.displayServers[listPtr->cursorPos] ) ) { 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 ); if ( ui_netSource.integer == AS_FAVORITES ) { UI_BuildServerDisplayList( qtrue ); UI_FeederSelection( FEEDER_SERVERS, 0 ); } } } else { char name[MAX_NAME_LENGTH]; trap_LAN_GetServerInfo( ui_netSource.integer, uiInfo.serverStatus.displayServers[uiInfo.serverStatus.currentServer], buff, MAX_STRING_CHARS ); addr[0] = '\0'; name[0] = '\0'; Q_strncpyz( addr, Info_ValueForKey( buff, "addr" ), MAX_NAME_LENGTH ); Q_strncpyz( name, Info_ValueForKey( buff, "hostname" ), MAX_NAME_LENGTH ); if ( *name && *addr ) { trap_LAN_AddServer( AS_FAVORITES, name, addr ); } } return qtrue; } } return qfalse; } /* // TTimo: unused static qboolean Team_Parse(char **p) { char *token; const char *tempStr; int i; token = COM_ParseExt(p, qtrue); if (token[0] != '{') { return qfalse; } while ( 1 ) { token = COM_ParseExt(p, qtrue); if (Q_stricmp(token, "}") == 0) { return qtrue; } if ( !token || token[0] == 0 ) { return qfalse; } if (token[0] == '{') { // seven tokens per line, team name and icon, and 5 team member names if (!String_Parse(p, &uiInfo.teamList[uiInfo.teamCount].teamName) || !String_Parse(p, &tempStr)) { return qfalse; } uiInfo.teamList[uiInfo.teamCount].imageName = tempStr; uiInfo.teamList[uiInfo.teamCount].teamIcon = trap_R_RegisterShaderNoMip(uiInfo.teamList[uiInfo.teamCount].imageName); uiInfo.teamList[uiInfo.teamCount].teamIcon_Metal = trap_R_RegisterShaderNoMip(va("%s_metal",uiInfo.teamList[uiInfo.teamCount].imageName)); uiInfo.teamList[uiInfo.teamCount].teamIcon_Name = trap_R_RegisterShaderNoMip(va("%s_name", uiInfo.teamList[uiInfo.teamCount].imageName)); uiInfo.teamList[uiInfo.teamCount].cinematic = -1; for (i = 0; i < TEAM_MEMBERS; i++) { uiInfo.teamList[uiInfo.teamCount].teamMembers[i] = NULL; if (!String_Parse(p, &uiInfo.teamList[uiInfo.teamCount].teamMembers[i])) { return qfalse; } } Com_Printf("Loaded team %s with team icon %s.\n", uiInfo.teamList[uiInfo.teamCount].teamName, tempStr); if (uiInfo.teamCount < MAX_TEAMS) { uiInfo.teamCount++; } else { Com_Printf("Too many teams, last team replaced!\n"); } token = COM_ParseExt(p, qtrue); if (token[0] != '}') { return qfalse; } } } return qfalse; } */ /* // TTimo: unused static qboolean Character_Parse(char **p) { char *token; const char *tempStr; token = COM_ParseExt(p, qtrue); if (token[0] != '{') { return qfalse; } while ( 1 ) { token = COM_ParseExt(p, qtrue); if (Q_stricmp(token, "}") == 0) { return qtrue; } if ( !token || token[0] == 0 ) { return qfalse; } if (token[0] == '{') { // two tokens per line, character name and sex if (!String_Parse(p, &uiInfo.characterList[uiInfo.characterCount].name) || !String_Parse(p, &tempStr)) { return qfalse; } uiInfo.characterList[uiInfo.characterCount].headImage = -1; uiInfo.characterList[uiInfo.characterCount].imageName = String_Alloc(va("models/players/heads/%s/icon_default.tga", uiInfo.characterList[uiInfo.characterCount].name)); if (tempStr && (tempStr[0] == 'f' || tempStr[0] == 'F')) { uiInfo.characterList[uiInfo.characterCount].female = qtrue; } else { uiInfo.characterList[uiInfo.characterCount].female = qfalse; } Com_Printf("Loaded %s character %s.\n", tempStr, uiInfo.characterList[uiInfo.characterCount].name); if (uiInfo.characterCount < MAX_HEADS) { uiInfo.characterCount++; } else { Com_Printf("Too many characters, last character replaced!\n"); } token = COM_ParseExt(p, qtrue); if (token[0] != '}') { return qfalse; } } } return qfalse; } */ /* // TTimo: unused static qboolean Alias_Parse(char **p) { char *token; token = COM_ParseExt(p, qtrue); if (token[0] != '{') { return qfalse; } while ( 1 ) { token = COM_ParseExt(p, qtrue); if (Q_stricmp(token, "}") == 0) { return qtrue; } if ( !token || token[0] == 0 ) { return qfalse; } if (token[0] == '{') { // three tokens per line, character name, bot alias, and preferred action a - all purpose, d - defense, o - offense if (!String_Parse(p, &uiInfo.aliasList[uiInfo.aliasCount].name) || !String_Parse(p, &uiInfo.aliasList[uiInfo.aliasCount].ai) || !String_Parse(p, &uiInfo.aliasList[uiInfo.aliasCount].action)) { return qfalse; } Com_Printf("Loaded character alias %s using character ai %s.\n", uiInfo.aliasList[uiInfo.aliasCount].name, uiInfo.aliasList[uiInfo.aliasCount].ai); if (uiInfo.aliasCount < MAX_ALIASES) { uiInfo.aliasCount++; } else { Com_Printf("Too many aliases, last alias replaced!\n"); } token = COM_ParseExt(p, qtrue); if (token[0] != '}') { return qfalse; } } } return qfalse; } */ // mode // 0 - high level parsing // 1 - team parsing // 2 - character parsing /* // TTimo: unused static void UI_ParseTeamInfo(const char *teamFile) { char *token; char *p; char *buff = NULL; //int mode = 0; // TTimo: unused buff = GetMenuBuffer(teamFile); if (!buff) { return; } p = buff; while ( 1 ) { token = COM_ParseExt( &p, qtrue ); if( !token || token[0] == 0 || token[0] == '}') { break; } if ( Q_stricmp( token, "}" ) == 0 ) { break; } if (Q_stricmp(token, "teams") == 0) { if (Team_Parse(&p)) { continue; } else { break; } } if (Q_stricmp(token, "characters") == 0) { Character_Parse(&p); } if (Q_stricmp(token, "aliases") == 0) { Alias_Parse(&p); } } } */ /* ============== GameType_Parse ============== */ static qboolean GameType_Parse( char **p, qboolean join ) { char *token; token = COM_ParseExt( p, qtrue ); if ( token[0] != '{' ) { return qfalse; } if ( join ) { uiInfo.numJoinGameTypes = 0; } else { uiInfo.numGameTypes = 0; } while ( 1 ) { token = COM_ParseExt( p, qtrue ); if ( Q_stricmp( token, "}" ) == 0 ) { return qtrue; } if ( !token || token[0] == 0 ) { return qfalse; } if ( token[0] == '{' ) { if ( join ) { if ( !String_Parse( p, &uiInfo.joinGameTypes[uiInfo.numJoinGameTypes].gameType ) || !Int_Parse( p, &uiInfo.joinGameTypes[uiInfo.numJoinGameTypes].gtEnum ) ) { return qfalse; } } else { if ( !Int_Parse( p, &uiInfo.gameTypes[uiInfo.numGameTypes].gtEnum ) ) { return qfalse; } if ( !String_Parse( p, &uiInfo.gameTypes[uiInfo.numGameTypes].gameType ) ) { return qfalse; } if ( !String_Parse( p, &uiInfo.gameTypes[uiInfo.numGameTypes].gameTypeShort ) ) { return qfalse; } if ( !String_Parse( p, &uiInfo.gameTypes[uiInfo.numGameTypes].gameTypeDescription ) ) { return qfalse; } } if ( join ) { if ( uiInfo.numJoinGameTypes < MAX_GAMETYPES ) { uiInfo.numJoinGameTypes++; } else { Com_Printf( "Too many net game types, last one replace!\n" ); } } else { if ( uiInfo.numGameTypes < MAX_GAMETYPES ) { uiInfo.numGameTypes++; } else { Com_Printf( "Too many game types, last one replace!\n" ); } } token = COM_ParseExt( p, qtrue ); if ( token[0] != '}' ) { return qfalse; } } } return qfalse; } #if 0 static qboolean MapList_Parse( char **p ) { char *token; token = COM_ParseExt( p, qtrue ); if ( token[0] != '{' ) { return qfalse; } uiInfo.mapCount = 0; while ( 1 ) { token = COM_ParseExt( p, qtrue ); if ( Q_stricmp( token, "}" ) == 0 ) { return qtrue; } if ( !token || token[0] == 0 ) { return qfalse; } if ( token[0] == '{' ) { if ( !String_Parse( p, &uiInfo.mapList[uiInfo.mapCount].mapName ) || !String_Parse( p, &uiInfo.mapList[uiInfo.mapCount].mapLoadName ) || !Int_Parse( p, &uiInfo.mapList[uiInfo.mapCount].teamMembers ) ) { return qfalse; } if ( !String_Parse( p, &uiInfo.mapList[uiInfo.mapCount].opponentName ) ) { return qfalse; } uiInfo.mapList[uiInfo.mapCount].typeBits = 0; while ( 1 ) { token = COM_ParseExt( p, qtrue ); if ( token[0] >= '0' && token[0] <= '9' ) { uiInfo.mapList[uiInfo.mapCount].typeBits |= ( 1 << ( token[0] - 0x030 ) ); if ( !Int_Parse( p, &uiInfo.mapList[uiInfo.mapCount].timeToBeat[token[0] - 0x30] ) ) { return qfalse; } } else { break; } } //mapList[mapCount].imageName = String_Alloc(va("levelshots/%s", mapList[mapCount].mapLoadName)); //if (uiInfo.mapCount == 0) { // only load the first cinematic, selection loads the others // uiInfo.mapList[uiInfo.mapCount].cinematic = trap_CIN_PlayCinematic(va("%s.roq",uiInfo.mapList[uiInfo.mapCount].mapLoadName), qfalse, qfalse, qtrue, 0, 0, 0, 0); //} uiInfo.mapList[uiInfo.mapCount].cinematic = -1; uiInfo.mapList[uiInfo.mapCount].levelShot = trap_R_RegisterShaderNoMip( va( "levelshots/%s_small", uiInfo.mapList[uiInfo.mapCount].mapLoadName ) ); if ( uiInfo.mapCount < MAX_MAPS ) { uiInfo.mapCount++; } else { Com_Printf( "Too many maps, last one replaced!\n" ); } } } return qfalse; } #endif static void UI_ParseGameInfo( const char *teamFile ) { char *token; char *p; char *buff = NULL; // int mode = 0; // TTimo: unused buff = GetMenuBuffer( teamFile ); if ( !buff ) { return; } p = buff; while ( 1 ) { token = COM_ParseExt( &p, qtrue ); if ( !token || token[0] == 0 || token[0] == '}' ) { break; } if ( Q_stricmp( token, "}" ) == 0 ) { break; } if ( Q_stricmp( token, "gametypes" ) == 0 ) { if ( GameType_Parse( &p, qfalse ) ) { continue; } else { break; } } // if (Q_stricmp(token, "maps") == 0) { // start a new menu // MapList_Parse(&p); // } } } 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" ); } } /* // TTimo: unused static int UI_OwnerDraw_Width(int ownerDraw) { return 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 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; } } } } } 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 ); } /* ================= PlayerModel_BuildList ================= */ /* // TTimo: unused static void UI_BuildQ3Model_List( void ) { int numdirs; int numfiles; char dirlist[2048]; char filelist[2048]; char skinname[64]; char* dirptr; char* fileptr; int i; int j; int dirlen; int filelen; uiInfo.q3HeadCount = 0; // iterate directory of all player models numdirs = trap_FS_GetFileList("models/players", "/", dirlist, 2048 ); dirptr = dirlist; for (i=0; i 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.drawTextExt = &Text_Paint_Ext; uiInfo.uiDC.textWidth = &Text_Width; uiInfo.uiDC.textWidthExt = &Text_Width_Ext; uiInfo.uiDC.multiLineTextWidth = &Multiline_Text_Width; uiInfo.uiDC.textHeight = &Text_Height; uiInfo.uiDC.textHeightExt = &Text_Height_Ext; uiInfo.uiDC.multiLineTextHeight = &Multiline_Text_Height; uiInfo.uiDC.textFont = &Text_SetActiveFont; 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.fileText = &UI_FileText; //----(SA) re-added uiInfo.uiDC.feederSelection = &UI_FeederSelection; uiInfo.uiDC.feederSelectionClick = &UI_FeederSelectionClick; uiInfo.uiDC.feederAddItem = &UI_FeederAddItem; // NERVE - SMF uiInfo.uiDC.setBinding = &trap_Key_SetBinding; uiInfo.uiDC.getBindingBuf = &trap_Key_GetBindingBuf; uiInfo.uiDC.getKeysForBinding = &trap_Key_KeysForBinding; uiInfo.uiDC.keynumToStringBuf = &trap_Key_KeynumToStringBuf; uiInfo.uiDC.keyIsDown = &trap_Key_IsDown; 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; uiInfo.uiDC.translateString = &trap_TranslateString; // NERVE - SMF uiInfo.uiDC.checkAutoUpdate = &trap_CheckAutoUpdate; // DHM - Nerve uiInfo.uiDC.getAutoUpdate = &trap_GetAutoUpdate; // DHM - Nerve uiInfo.uiDC.descriptionForCampaign = &UI_DescriptionForCampaign; uiInfo.uiDC.nameForCampaign = &UI_NameForCampaign; uiInfo.uiDC.add2dPolys = &trap_R_Add2dPolys; uiInfo.uiDC.updateScreen = &trap_UpdateScreen; uiInfo.uiDC.getHunkData = &trap_GetHunkData; uiInfo.uiDC.getConfigString = &trap_GetConfigString; Init_Display( &uiInfo.uiDC ); String_Init(); uiInfo.uiDC.whiteShader = trap_R_RegisterShaderNoMip( "white" ); AssetCache(); uiInfo.passwordFilter = trap_R_RegisterShaderNoMip( "ui/assets/filter_pass.tga" ); uiInfo.friendlyFireFilter = trap_R_RegisterShaderNoMip( "ui/assets/filter_ff.tga" ); uiInfo.maxLivesFilter = trap_R_RegisterShaderNoMip( "ui/assets/filter_lives.tga" ); uiInfo.punkBusterFilter = trap_R_RegisterShaderNoMip( "ui/assets/filter_pb.tga" ); uiInfo.weaponRestrictionsFilter = trap_R_RegisterShaderNoMip( "ui/assets/filter_weap.tga" ); uiInfo.antiLagFilter = trap_R_RegisterShaderNoMip( "ui/assets/filter_antilag.tga" ); uiInfo.teamBalanceFilter = trap_R_RegisterShaderNoMip( "ui/assets/filter_balance.tga" ); uiInfo.campaignMap = trap_R_RegisterShaderNoMip( "gfx/loading/camp_map.tga" ); start = trap_Milliseconds(); uiInfo.teamCount = 0; uiInfo.characterCount = 0; uiInfo.aliasCount = 0; UI_ParseGameInfo( "gameinfo.txt" ); UI_LoadMenus( "ui/menus.txt", qfalse ); Menus_CloseAll(); trap_LAN_LoadCachedServers(); UI_LoadBestScores( uiInfo.mapList[0].mapLoadName, uiInfo.gameTypes[ui_gameType.integer].gtEnum ); // sets defaults for ui temp cvars // rain - bounds check array index, although I'm pretty sure this // stuff isn't used anymore... x = (int)trap_Cvar_VariableValue( "color" ) - 1; if ( x < 0 || x >= sizeof( gamecodetoui ) / sizeof( gamecodetoui[0] ) ) { x = 0; } uiInfo.effectsColor = gamecodetoui[x]; uiInfo.currentCrosshair = (int)trap_Cvar_VariableValue( "cg_drawCrosshair" ); trap_Cvar_Set( "ui_mousePitch", ( trap_Cvar_VariableValue( "m_pitch" ) >= 0 ) ? "0" : "1" ); uiInfo.serverStatus.currentServerCinematic = -1; uiInfo.previewMovie = -1; 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" ); } trap_Cvar_Register( NULL, "debug_protocol", "", 0 ); // Arnout: default to Campaign //trap_Cvar_Set("ui_netGameType", "4"); // init Yes/No once for cl_language -> server browser (punkbuster) Q_strncpyz( translated_yes, DC->translateString( "Yes" ), sizeof( translated_yes ) ); Q_strncpyz( translated_no, DC->translateString( "NO" ), sizeof( translated_no ) ); trap_AddCommand( "campaign" ); trap_AddCommand( "listcampaigns" ); } /* ================= UI_KeyEvent ================= */ void _UI_KeyEvent( int key, qboolean down ) { static qboolean bypassKeyClear = qfalse; if ( Menu_Count() > 0 ) { menuDef_t *menu = Menu_GetFocused(); if ( menu ) { if ( trap_Cvar_VariableValue( "cl_bypassMouseInput" ) ) { bypassKeyClear = qtrue; } // if (key == K_ESCAPE && down && !Menus_AnyFullScreenVisible()) { // Menus_CloseAll(); // } else { // Menu_HandleKey(menu, key, down ); // } // always have the menus do the proper handling Menu_HandleKey( menu, key, down ); } else { trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_UI ); // NERVE - SMF - we don't want to clear key states if bypassing input if ( !bypassKeyClear ) { trap_Key_ClearStates(); } if ( cl_bypassMouseInput.integer ) { if ( !trap_Key_GetCatcher() ) { trap_Cvar_Set( "cl_bypassMouseInput", 0 ); } } bypassKeyClear = qfalse; trap_Cvar_Set( "cl_paused", "0" ); } } //if ((s > 0) && (s != menu_null_sound)) { // trap_S_StartLocalSound( s, CHAN_LOCAL_SOUND ); //} } /* ================= UI_MouseEvent ================= */ 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 ); } } void UI_LoadNonIngame() { 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; } //----(SA) added static uiMenuCommand_t menutype = UIMENU_NONE; uiMenuCommand_t _UI_GetActiveMenu( void ) { return menutype; } //----(SA) end #define MISSING_FILES_MSG "The following packs are missing:" void _UI_SetActiveMenu( uiMenuCommand_t menu ) { char buf[4096]; // com_errorMessage can go up to 4096 char *missing_files; // 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; menutype = menu; //----(SA) added 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_Key_SetCatcher( KEYCATCH_UI ); Menus_CloseAll(); //Menus_ActivateByName( "background_1", qtrue ); Menus_ActivateByName( "backgroundmusic", qtrue ); // Arnout: not nice, but best way to do it - putting the music in it's own menudef // makes sure it doesn't get restarted every time you reach the main menu if ( !cl_profile.string[0] ) { //Menus_ActivateByName( "profilelogin", qtrue ); // FIXME: initial profile popup // FIXED: handled in opener now Menus_ActivateByName( "main_opener", qtrue ); } else { Menus_ActivateByName( "main_opener", qtrue ); } trap_Cvar_VariableStringBuffer( "com_errorMessage", buf, sizeof( buf ) ); // JPW NERVE stricmp() is silly but works, take a look at error.menu to see why. I think this is bustified in q3ta // NOTE TTimo - I'm not sure Q_stricmp is useful to anything anymore // show_bug.cgi?id=507 // TTimo - improved and tweaked that area a whole bunch if ( ( *buf ) && ( Q_stricmp( buf,";" ) ) ) { trap_Cvar_Set( "ui_connecting", "0" ); if ( !Q_stricmpn( buf, "Invalid password", 16 ) ) { trap_Cvar_Set( "com_errorMessage", trap_TranslateString( buf ) ); // NERVE - SMF Menus_ActivateByName( "popupPassword", qtrue ); } else if ( strlen( buf ) > 5 && !Q_stricmpn( buf, "ET://", 5 ) ) { // fretn Q_strncpyz( buf, buf + 5, sizeof( buf ) ); Com_Printf( "Server is full, redirect to: %s\n", buf ); switch ( ui_autoredirect.integer ) { //auto-redirect case 1: trap_Cvar_Set( "com_errorMessage", "" ); trap_Cmd_ExecuteText( EXEC_APPEND, va( "connect %s\n", buf ) ); break; //prompt (default) default: trap_Cvar_Set( "com_errorMessage", buf ); Menus_ActivateByName( "popupServerRedirect", qtrue ); break; } } else { qboolean pb_enable = qfalse; if ( strstr( buf, "must be Enabled" ) ) { pb_enable = qtrue; } trap_Cvar_Set( "com_errorMessage", trap_TranslateString( buf ) ); // NERVE - SMF // hacky, wanted to have the printout of missing files // text printing limitations force us to keep it all in a single message // NOTE: this works thanks to flip flop in UI_Cvar_VariableString if ( UI_Cvar_VariableString( "com_errorDiagnoseIP" )[0] ) { missing_files = UI_Cvar_VariableString( "com_missingFiles" ); if ( missing_files[0] ) { trap_Cvar_Set( "com_errorMessage", va( "%s\n\n%s\n%s", UI_Cvar_VariableString( "com_errorMessage" ), trap_TranslateString( MISSING_FILES_MSG ), missing_files ) ); } } if ( pb_enable ) { Menus_ActivateByName( "popupError_pbenable", qtrue ); } else { Menus_ActivateByName( "popupError", qtrue ); } } } trap_S_FadeAllSound( 1.0f, 1000, qfalse ); // make sure sound fades up #ifdef SAVEGAME_SUPPORT // ensure savegames are loadable trap_Cvar_Set( "g_reloading", "0" ); #endif // SAVEGAME_SUPPORT return; case UIMENU_TEAM: trap_Key_SetCatcher( KEYCATCH_UI ); Menus_ActivateByName( "team", qtrue ); return; case UIMENU_NEED_CD: trap_Key_SetCatcher( KEYCATCH_UI ); Menus_ActivateByName( "needcd", qtrue ); return; case UIMENU_BAD_CD_KEY: trap_Key_SetCatcher( KEYCATCH_UI ); Menus_ActivateByName( "badcd", qtrue ); return; case UIMENU_INGAME: if ( g_gameType.integer == GT_SINGLE_PLAYER ) { trap_Cvar_Set( "cl_paused", "1" ); } trap_Key_SetCatcher( KEYCATCH_UI ); UI_BuildPlayerList(); Menu_SetFeederSelection( NULL, FEEDER_PLAYER_LIST, 0, NULL ); Menus_CloseAll(); //trap_Cvar_Set( "authLevel", "0" ); // just used for testing... Menus_ActivateByName( "ingame_main", qtrue ); return; // NERVE - SMF case UIMENU_WM_QUICKMESSAGE: uiInfo.uiDC.cursorx = 639; uiInfo.uiDC.cursory = 479; trap_Key_SetCatcher( KEYCATCH_UI ); Menus_CloseAll(); Menus_OpenByName( "wm_quickmessage" ); return; case UIMENU_WM_QUICKMESSAGEALT: uiInfo.uiDC.cursorx = 639; uiInfo.uiDC.cursory = 479; trap_Key_SetCatcher( KEYCATCH_UI ); Menus_CloseAll(); Menus_OpenByName( "wm_quickmessageAlt" ); return; case UIMENU_WM_FTQUICKMESSAGE: uiInfo.uiDC.cursorx = 639; uiInfo.uiDC.cursory = 479; trap_Key_SetCatcher( KEYCATCH_UI ); Menus_CloseAll(); Menus_OpenByName( "wm_ftquickmessage" ); return; case UIMENU_WM_FTQUICKMESSAGEALT: uiInfo.uiDC.cursorx = 639; uiInfo.uiDC.cursory = 479; trap_Key_SetCatcher( KEYCATCH_UI ); Menus_CloseAll(); Menus_OpenByName( "wm_ftquickmessageAlt" ); return; case UIMENU_WM_TAPOUT: uiInfo.uiDC.cursorx = 639; uiInfo.uiDC.cursory = 479; trap_Key_SetCatcher( KEYCATCH_UI ); Menus_CloseAll(); Menus_OpenByName( "tapoutmsg" ); return; case UIMENU_WM_TAPOUT_LMS: uiInfo.uiDC.cursorx = 639; uiInfo.uiDC.cursory = 479; trap_Key_SetCatcher( KEYCATCH_UI ); Menus_CloseAll(); Menus_OpenByName( "tapoutmsglms" ); return; case UIMENU_WM_AUTOUPDATE: // TTimo - changing the auto-update strategy to a modal prompt Menus_OpenByName( "wm_autoupdate_modal" ); return; // -NERVE - SMF // ydnar: say, team say, etc case UIMENU_INGAME_MESSAGEMODE: //trap_Cvar_Set( "cl_paused", "1" ); trap_Key_SetCatcher( KEYCATCH_UI ); Menus_OpenByName( "ingame_messagemode" ); return; default: return; // TTimo: a lot of not handled } } } qboolean _UI_IsFullscreen( void ) { return Menus_AnyFullScreenVisible(); } //static connstate_t lastConnState; //static char lastLoadingText[MAX_INFO_VALUE]; 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 ); } } // Assumes time is in sec 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 ); } #if 0 // rain - unused #define ESTIMATES 80 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:"; static int tleEstimates[ESTIMATES] = { 60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60, 60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60, 60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60, 60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60 }; static int tleIndex = 0; int downloadSize, downloadCount, downloadTime; char dlSizeBuf[64], totalSizeBuf[64], xferRateBuf[64], dlTimeBuf[64]; int xferRate; const char *s; vec4_t bg_color = { 0.3f, 0.3f, 0.3f, 0.8f }; downloadSize = trap_Cvar_VariableValue( "cl_downloadSize" ); downloadCount = trap_Cvar_VariableValue( "cl_downloadCount" ); downloadTime = trap_Cvar_VariableValue( "cl_downloadTime" ); // Background UI_FillRect( 0, yStart + 185, 640, 83, bg_color ); UI_SetColor( colorYellow ); Text_Paint( 92, yStart + 210, scale, colorYellow, dlText, 0, 64, ITEM_TEXTSTYLE_SHADOWEDMORE ); Text_Paint( 35, yStart + 235, scale, colorYellow, etaText, 0, 64, ITEM_TEXTSTYLE_SHADOWEDMORE ); Text_Paint( 86, yStart + 260, scale, colorYellow, xferText, 0, 64, ITEM_TEXTSTYLE_SHADOWEDMORE ); if ( downloadSize > 0 ) { s = va( "%s (%d%%)", downloadName, downloadCount * 100 / downloadSize ); } else { s = downloadName; } Text_Paint( 260, yStart + 210, scale, colorYellow, s, 0, 0, ITEM_TEXTSTYLE_SHADOWEDMORE ); UI_ReadableSize( dlSizeBuf, sizeof dlSizeBuf, downloadCount ); UI_ReadableSize( totalSizeBuf, sizeof totalSizeBuf, downloadSize ); if ( downloadCount < 4096 || !downloadTime ) { Text_PaintCenter( centerPoint, yStart + 235, scale, colorYellow, "estimating", 0 ); Text_PaintCenter( centerPoint, yStart + 340, scale, colorYellow, 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 int timeleft = 0, i; // We do it in K (/1024) because we'd overflow around 4MB tleEstimates[ tleIndex ] = ( n - ( ( ( downloadCount / 1024 ) * n ) / ( downloadSize / 1024 ) ) ); tleIndex++; if ( tleIndex >= ESTIMATES ) { tleIndex = 0; } for ( i = 0; i < ESTIMATES; i++ ) timeleft += tleEstimates[ i ]; timeleft /= ESTIMATES; UI_PrintTime( dlTimeBuf, sizeof dlTimeBuf, timeleft ); Text_Paint( 260, yStart + 235, scale, colorYellow, dlTimeBuf, 0, 0, ITEM_TEXTSTYLE_SHADOWEDMORE ); Text_PaintCenter( centerPoint, yStart + 340, scale, colorYellow, va( "(%s of %s copied)", dlSizeBuf, totalSizeBuf ), 0 ); } else { Text_PaintCenter( centerPoint, yStart + 235, scale, colorYellow, "estimating", 0 ); if ( downloadSize ) { Text_PaintCenter( centerPoint, yStart + 340, scale, colorYellow, va( "(%s of %s copied)", dlSizeBuf, totalSizeBuf ), 0 ); } else { Text_PaintCenter( centerPoint, yStart + 340, scale, colorYellow, va( "(%s copied)", dlSizeBuf ), 0 ); } } if ( xferRate ) { Text_Paint( 260, yStart + 260, scale, colorYellow, va( "%s/Sec", xferRateBuf ), 0, 0, ITEM_TEXTSTYLE_SHADOWEDMORE ); } } } #endif /* ======================== 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. ======================== */ #define CP_LINEWIDTH 50 void UI_DrawConnectScreen( qboolean overlay ) { // static qboolean playingMusic = qfalse; if ( !overlay ) { UI_DrawLoadPanel( qfalse, qfalse, qfalse ); } else { // if( !playingMusic ) { // trap_S_StartBackgroundTrack( "sound/music/level_load.wav", "", 1000 ); // playingMusic = qtrue; // } } /* if( !overlay ) { BG_DrawConnectScreen( qfalse ); }*/ /* char *s; uiClientState_t cstate; char info[MAX_INFO_VALUE]; char text[256]; float centerPoint, yStart, scale; vec4_t color = { 0.3f, 0.3f, 0.3f, 0.8f }; // static qboolean playingMusic = qfalse; char downloadName[MAX_INFO_VALUE]; menuDef_t *menu = Menus_FindByName("Connect"); if ( !overlay && menu ) { Menu_Paint(menu, qtrue); } if (!overlay) { centerPoint = 320; yStart = 130; scale = 0.4f; } else { centerPoint = 320; yStart = 32; scale = 0.6f; // see what information we should display trap_GetClientState( &cstate ); return; } // playingMusic = qfalse; // see what information we should display trap_GetClientState( &cstate ); info[0] = '\0'; if (!Q_stricmp(cstate.servername,"localhost")) { Text_PaintCenter(centerPoint, yStart + 48, scale, colorWhite,va( "Enemy Territory - Version: %s", Q3_VERSION ), ITEM_TEXTSTYLE_SHADOWEDMORE); } else { strcpy(text, va( trap_TranslateString( "Connecting to %s" ), cstate.servername)); Text_PaintCenter(centerPoint, yStart + 48, scale, colorWhite,text , ITEM_TEXTSTYLE_SHADOWEDMORE); } // display global MOTD at bottom (don't draw during download, the space is already used) // moved downloadName query up, this is used in CA_CONNECTED trap_Cvar_VariableStringBuffer( "cl_downloadName", downloadName, sizeof(downloadName) ); if (!*downloadName) { Text_PaintCenter(centerPoint, 475, scale, colorWhite, Info_ValueForKey( cstate.updateInfoString, "motd" ), 0); } // print any server info (server full, bad version, etc) // DHM - Nerve :: This now accepts strings up to 256 chars long, and will break them up into multiple lines. // They are also now printed in Yellow for readability. if ( cstate.connState < CA_CONNECTED ) { char *s; char ps[60]; int i, len, index = 0, yPrint = yStart + 210; qboolean neednewline = qfalse; s = trap_TranslateString( cstate.messageString ); len = strlen( s ); for ( i = 0; i < len; i++, index++ ) { // copy to temp buffer ps[index] = s[i]; if ( index > (CP_LINEWIDTH - 10) && i > 0 ) neednewline = qtrue; // if out of temp buffer room OR end of string OR it is time to linebreak & we've found a space if ( (index >= 58) || (i == (len-1)) || (neednewline && s[i] == ' ') ) { ps[index+1] = '\0'; DC->fillRect(0, yPrint - 17, 640, 22, color); Text_PaintCenter(centerPoint, yPrint, scale, colorYellow, ps, 0); neednewline = qfalse; yPrint += 22; // next line index = -1; // sigh, for loop will increment to 0 } } } if ( lastConnState > cstate.connState ) { lastLoadingText[0] = '\0'; } lastConnState = cstate.connState; switch ( cstate.connState ) { case CA_CONNECTING: s = va( trap_TranslateString( "Awaiting connection...%i" ), cstate.connectPacketCount); break; case CA_CHALLENGING: s = va( trap_TranslateString( "Awaiting challenge...%i" ), cstate.connectPacketCount); break; case CA_CONNECTED: if (*downloadName) { UI_DisplayDownloadInfo( downloadName, centerPoint, yStart, scale ); return; } s = trap_TranslateString( "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 */ } /* ================ cvars ================ */ typedef struct { vmCvar_t *vmCvar; char *cvarName; char *defaultString; int cvarFlags; int modificationCount; // for tracking changes } cvarTable_t; vmCvar_t ui_ffa_fraglimit; vmCvar_t ui_ffa_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_master; vmCvar_t ui_brassTime; vmCvar_t ui_drawCrosshair; vmCvar_t ui_drawCrosshairNames; vmCvar_t ui_drawCrosshairPickups; //----(SA) added vmCvar_t ui_marks; // JOSEPH 12-3-99 vmCvar_t ui_autoactivate; // END JOSEPH 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_cdkeychecked; vmCvar_t ui_selectedPlayer; vmCvar_t ui_selectedPlayerName; vmCvar_t ui_netSource; vmCvar_t ui_menuFiles; vmCvar_t ui_gameType; vmCvar_t ui_netGameType; //vmCvar_t ui_actualNetGameType; vmCvar_t ui_joinGameType; vmCvar_t ui_dedicated; vmCvar_t ui_clipboardName; // the name of the group for the current clipboard item //----(SA) added vmCvar_t ui_notebookCurrentPage; //----(SA) added vmCvar_t ui_clipboardName; // the name of the group for the current clipboard item //----(SA) added // NERVE - SMF - cvars for multiplayer vmCvar_t ui_serverFilterType; vmCvar_t ui_currentNetMap; vmCvar_t ui_currentMap; vmCvar_t ui_mapIndex; vmCvar_t ui_browserMaster; vmCvar_t ui_browserGameType; vmCvar_t ui_browserSortKey; vmCvar_t ui_browserShowEmptyOrFull; vmCvar_t ui_browserShowPasswordProtected; vmCvar_t ui_browserShowFriendlyFire; // NERVE - SMF vmCvar_t ui_browserShowMaxlives; // NERVE - SMF vmCvar_t ui_browserShowPunkBuster; // DHM - Nerve vmCvar_t ui_browserShowAntilag; // TTimo vmCvar_t ui_browserShowWeaponsRestricted; vmCvar_t ui_browserShowTeamBalanced; vmCvar_t ui_serverStatusTimeOut; vmCvar_t ui_Q3Model; vmCvar_t ui_headModel; vmCvar_t ui_model; vmCvar_t ui_limboOptions; vmCvar_t ui_limboPrevOptions; vmCvar_t ui_limboObjective; vmCvar_t ui_cmd; vmCvar_t ui_prevTeam; vmCvar_t ui_prevClass; vmCvar_t ui_prevWeapon; vmCvar_t ui_limboMode; vmCvar_t ui_objective; vmCvar_t ui_team; vmCvar_t ui_class; vmCvar_t ui_weapon; vmCvar_t ui_isSpectator; vmCvar_t ui_friendlyFire; vmCvar_t ui_userTimeLimit; vmCvar_t ui_userAlliedRespawnTime; vmCvar_t ui_userAxisRespawnTime; vmCvar_t ui_glCustom; // JPW NERVE missing from q3ta // -NERVE - SMF vmCvar_t g_gameType; vmCvar_t cl_profile; vmCvar_t cl_defaultProfile; vmCvar_t ui_profile; vmCvar_t ui_currentNetCampaign; vmCvar_t ui_currentCampaign; vmCvar_t ui_campaignIndex; vmCvar_t ui_currentCampaignCompleted; // OSP // cgame mappings vmCvar_t ui_blackout; // For speclock vmCvar_t cg_crosshairColor; vmCvar_t cg_crosshairColorAlt; vmCvar_t cg_crosshairAlpha; vmCvar_t cg_crosshairAlphaAlt; vmCvar_t cg_crosshairSize; // OSP vmCvar_t cl_bypassMouseInput; //bani vmCvar_t ui_autoredirect; cvarTable_t cvarTable[] = { { &ui_glCustom, "ui_glCustom", "4", CVAR_ARCHIVE }, // JPW NERVE missing from q3ta { &ui_ffa_fraglimit, "ui_ffa_fraglimit", "20", CVAR_ARCHIVE }, { &ui_ffa_timelimit, "ui_ffa_timelimit", "0", 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 | CVAR_LATCH }, // NERVE - SMF { &ui_friendlyFire, "g_friendlyFire", "1", CVAR_ARCHIVE }, { &ui_userTimeLimit, "ui_userTimeLimit", "0", 0 }, { &ui_userAlliedRespawnTime, "ui_userAlliedRespawnTime", "0", 0 }, { &ui_userAxisRespawnTime, "ui_userAxisRespawnTime", "0", 0 }, // -NERVE - SMF // JPW NERVE { &ui_teamArenaFirstRun, "ui_teamArenaFirstRun", "0", CVAR_ARCHIVE}, // so sound stuff latches, strange as that seems // jpw { &ui_spSelection, "ui_spSelection", "", CVAR_ROM }, { &ui_master, "ui_master", "0", CVAR_ARCHIVE }, { &ui_brassTime, "cg_brassTime", "2500", CVAR_ARCHIVE }, // JPW NERVE { &ui_drawCrosshair, "cg_drawCrosshair", "4", CVAR_ARCHIVE }, { &ui_drawCrosshairNames, "cg_drawCrosshairNames", "1", CVAR_ARCHIVE }, { &ui_drawCrosshairPickups, "cg_drawCrosshairPickups", "1", CVAR_ARCHIVE }, //----(SA) added { &ui_marks, "cg_marktime", "20000", CVAR_ARCHIVE }, // JOSEPH 12-2-99 { &ui_autoactivate, "cg_autoactivate", "1", CVAR_ARCHIVE }, // END JOSEPH { &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_dedicated, "ui_dedicated", "0", CVAR_ARCHIVE }, { &ui_cdkeychecked, "ui_cdkeychecked", "0", CVAR_ROM }, { &ui_selectedPlayer, "cg_selectedPlayer", "0", CVAR_ARCHIVE}, { &ui_selectedPlayerName, "cg_selectedPlayerName", "", CVAR_ARCHIVE}, { &ui_netSource, "ui_netSource", "1", CVAR_ARCHIVE }, { &ui_menuFiles, "ui_menuFiles", "ui/menus.txt", CVAR_ARCHIVE }, { &ui_gameType, "ui_gametype", "3", CVAR_ARCHIVE }, { &ui_joinGameType, "ui_joinGametype", "-1", CVAR_ARCHIVE }, { &ui_netGameType, "ui_netGametype", "4", CVAR_ARCHIVE }, // NERVE - SMF - hardwired for now // { &ui_actualNetGameType, "ui_actualNetGametype", "5", CVAR_ARCHIVE }, // NERVE - SMF - hardwired for now { &ui_notebookCurrentPage, "ui_notebookCurrentPage", "1", CVAR_ROM}, { &ui_clipboardName, "cg_clipboardName", "", CVAR_ROM }, // NERVE - SMF - multiplayer cvars { &ui_mapIndex, "ui_mapIndex", "0", CVAR_ARCHIVE }, { &ui_currentMap, "ui_currentMap", "0", CVAR_ARCHIVE }, { &ui_currentNetMap, "ui_currentNetMap", "0", CVAR_ARCHIVE }, { &ui_browserMaster, "ui_browserMaster", "0", CVAR_ARCHIVE }, { &ui_browserGameType, "ui_browserGameType", "0", CVAR_ARCHIVE }, { &ui_browserSortKey, "ui_browserSortKey", "4", CVAR_ARCHIVE }, { &ui_browserShowEmptyOrFull, "ui_browserShowEmptyOrFull", "0", CVAR_ARCHIVE }, { &ui_browserShowPasswordProtected, "ui_browserShowPasswordProtected", "0", CVAR_ARCHIVE }, { &ui_browserShowFriendlyFire, "ui_browserShowFriendlyFire", "0", CVAR_ARCHIVE }, { &ui_browserShowMaxlives, "ui_browserShowMaxlives", "0", CVAR_ARCHIVE }, { &ui_browserShowPunkBuster, "ui_browserShowPunkBuster", "0", CVAR_ARCHIVE }, { &ui_browserShowAntilag, "ui_browserShowAntilag", "0", CVAR_ARCHIVE }, { &ui_browserShowWeaponsRestricted, "ui_browserShowWeaponsRestricted", "0", CVAR_ARCHIVE }, { &ui_browserShowTeamBalanced, "ui_browserShowTeamBalanced", "0", CVAR_ARCHIVE }, { &ui_serverStatusTimeOut, "ui_serverStatusTimeOut", "7000", CVAR_ARCHIVE}, { &ui_Q3Model, "ui_Q3Model", "1", 0 }, { &ui_headModel, "headModel", "", 0 }, { &ui_limboOptions, "ui_limboOptions", "0", 0 }, { &ui_limboPrevOptions, "ui_limboPrevOptions", "0", 0 }, { &ui_limboObjective, "ui_limboObjective", "0", 0 }, { &ui_cmd, "ui_cmd", "", 0 }, { &ui_prevTeam, "ui_prevTeam", "-1", 0 }, { &ui_prevClass, "ui_prevClass", "-1", 0 }, { &ui_prevWeapon, "ui_prevWeapon", "-1", 0 }, { &ui_limboMode, "ui_limboMode", "0", 0 }, { &ui_objective, "ui_objective", "", 0 }, { &ui_team, "ui_team", "Axis", 0 }, { &ui_class, "ui_class", "Soldier", 0 }, { &ui_weapon, "ui_weapon", "MP 40", 0 }, { &ui_isSpectator, "ui_isSpectator", "1", 0 }, // -NERVE - SMF { &g_gameType, "g_gameType", "4", CVAR_SERVERINFO | CVAR_LATCH }, { NULL, "cg_drawBuddies", "1", CVAR_ARCHIVE }, { NULL, "cg_drawRoundTimer", "1", CVAR_ARCHIVE }, { NULL, "cg_showblood", "1", CVAR_ARCHIVE }, { NULL, "cg_bloodFlash", "1.0", CVAR_ARCHIVE }, { NULL, "cg_autoReload", "1", CVAR_ARCHIVE }, { NULL, "cg_noAmmoAutoSwitch", "1", CVAR_ARCHIVE }, { NULL, "cg_useWeapsForZoom", "1", CVAR_ARCHIVE }, { NULL, "cg_zoomDefaultSniper", "20", CVAR_ARCHIVE }, { NULL, "cg_zoomstepsniper", "2", CVAR_ARCHIVE }, { NULL, "cg_voicespritetime", "6000", CVAR_ARCHIVE }, { NULL, "cg_complaintPopUp", "1", CVAR_ARCHIVE }, { NULL, "cg_announcer", "1", CVAR_ARCHIVE }, { NULL, "cg_printObjectiveInfo", "1", CVAR_ARCHIVE }, { NULL, "cg_useScreenshotJPEG", "1", CVAR_ARCHIVE }, { NULL, "cg_drawGun", "1", CVAR_ARCHIVE }, { NULL, "cg_drawCompass", "1", CVAR_ARCHIVE }, { NULL, "cg_drawRoundTimer", "1", CVAR_ARCHIVE }, { NULL, "cg_drawReinforcementTime", "1", CVAR_ARCHIVE }, { NULL, "cg_cursorHints", "1", CVAR_ARCHIVE }, { NULL, "cg_crosshairPulse", "1", CVAR_ARCHIVE }, { NULL, "cg_drawCrosshairNames", "1", CVAR_ARCHIVE }, { NULL, "cg_crosshairColor", "White", CVAR_ARCHIVE }, { NULL, "cg_crosshairAlpha", "1.0", CVAR_ARCHIVE }, { NULL, "cg_crosshairColorAlt", "White", CVAR_ARCHIVE }, { NULL, "cg_coronafardist", "1536", CVAR_ARCHIVE }, { NULL, "cg_wolfparticles", "1", CVAR_ARCHIVE }, { NULL, "g_password", "none", CVAR_USERINFO }, { NULL, "g_antilag", "1", CVAR_SERVERINFO | CVAR_ARCHIVE }, { NULL, "g_warmup", "60", CVAR_ARCHIVE }, { NULL, "g_lms_roundlimit", "3", CVAR_ARCHIVE }, { NULL, "g_lms_matchlimit", "2", CVAR_ARCHIVE }, { NULL, "g_lms_followTeamOnly", "1", CVAR_ARCHIVE }, { NULL, "g_heavyWeaponRestriction", "100", CVAR_ARCHIVE | CVAR_SERVERINFO }, { &cl_profile, "cl_profile", "", CVAR_ROM }, { &cl_defaultProfile, "cl_defaultProfile", "", CVAR_ROM }, { &ui_profile, "ui_profile", "", CVAR_ROM }, { &ui_currentCampaign, "ui_currentCampaign", "0", CVAR_ARCHIVE }, { &ui_currentNetCampaign, "ui_currentNetCampaign", "0", CVAR_ARCHIVE }, { &ui_campaignIndex, "ui_campaignIndex", "0", CVAR_ARCHIVE }, { &ui_currentCampaignCompleted, "ui_currentCampaignCompleted", "0", CVAR_ARCHIVE }, // START - TAT 9/16/2002 // cvar used to implement context sensitive bot menu // if this is set to "engineer", for instance, then only engineer commands will show up { NULL, "cg_botMenuType", "0", CVAR_TEMP }, // END - TAT 9/15/2002 // OSP // cgame mappings { &ui_blackout, "ui_blackout", "0", CVAR_ROM }, { &cg_crosshairAlpha, "cg_crosshairAlpha", "1.0", CVAR_ARCHIVE }, { &cg_crosshairAlphaAlt, "cg_crosshairAlphaAlt", "1.0", CVAR_ARCHIVE }, { &cg_crosshairColor, "cg_crosshairColor", "White", CVAR_ARCHIVE }, { &cg_crosshairColorAlt, "cg_crosshairColorAlt", "White", CVAR_ARCHIVE }, { &cg_crosshairSize, "cg_crosshairSize", "48", CVAR_ARCHIVE }, // game mappings (for create server option) { NULL, "bot_enable", "1", CVAR_ARCHIVE }, { NULL, "bot_minplayers", "0", CVAR_ARCHIVE }, { NULL, "g_altStopwatchMode", "0", CVAR_ARCHIVE }, { NULL, "g_ipcomplaintlimit", "3", CVAR_ARCHIVE }, { NULL, "g_complaintlimit", "6", CVAR_ARCHIVE }, { NULL, "g_doWarmup", "0", CVAR_ARCHIVE }, { NULL, "g_inactivity", "0", CVAR_ARCHIVE }, { NULL, "g_maxLives", "0", CVAR_ARCHIVE }, { NULL, "refereePassword", "none", CVAR_ARCHIVE }, { NULL, "g_teamForceBalance", "0", CVAR_ARCHIVE }, { NULL, "sv_maxRate", "0", CVAR_ARCHIVE }, { NULL, "g_spectatorInactivity", "0", CVAR_ARCHIVE }, { NULL, "match_latejoin", "1", CVAR_ARCHIVE }, { NULL, "match_minplayers", MATCH_MINPLAYERS, CVAR_ARCHIVE }, { NULL, "match_mutespecs", "0", CVAR_ARCHIVE }, { NULL, "match_readypercent", "100", CVAR_ARCHIVE }, { NULL, "match_timeoutcount", "3", CVAR_ARCHIVE }, { NULL, "match_timeoutlength", "180", CVAR_ARCHIVE }, { NULL, "match_warmupDamage", "1", CVAR_ARCHIVE }, { NULL, "server_autoconfig", "0", CVAR_ARCHIVE }, { NULL, "server_motd0", " ^NEnemy Territory ^7MOTD ", CVAR_ARCHIVE }, { NULL, "server_motd1", "", CVAR_ARCHIVE }, { NULL, "server_motd2", "", CVAR_ARCHIVE }, { NULL, "server_motd3", "", CVAR_ARCHIVE }, { NULL, "server_motd4", "", CVAR_ARCHIVE }, { NULL, "server_motd5", "", CVAR_ARCHIVE }, { NULL, "team_maxPanzers", "-1", CVAR_ARCHIVE }, { NULL, "team_maxplayers", "0", CVAR_ARCHIVE }, { NULL, "team_nocontrols", "0", CVAR_ARCHIVE }, { NULL, "vote_allow_comp", "1", CVAR_ARCHIVE }, { NULL, "vote_allow_gametype", "1", CVAR_ARCHIVE }, { NULL, "vote_allow_kick", "1", CVAR_ARCHIVE }, { NULL, "vote_allow_map", "1", CVAR_ARCHIVE }, { NULL, "vote_allow_mutespecs", "1", CVAR_ARCHIVE }, { NULL, "vote_allow_nextmap", "1", CVAR_ARCHIVE }, { NULL, "vote_allow_pub", "1", CVAR_ARCHIVE }, { NULL, "vote_allow_referee", "0", CVAR_ARCHIVE }, { NULL, "vote_allow_shuffleteamsxp", "1", CVAR_ARCHIVE }, { NULL, "vote_allow_swapteams", "1", CVAR_ARCHIVE }, { NULL, "vote_allow_friendlyfire", "1", CVAR_ARCHIVE }, { NULL, "vote_allow_timelimit", "0", CVAR_ARCHIVE }, { NULL, "vote_allow_warmupdamage", "1", CVAR_ARCHIVE }, { NULL, "vote_allow_antilag", "1", CVAR_ARCHIVE }, { NULL, "vote_allow_muting", "1", CVAR_ARCHIVE }, { NULL, "vote_allow_kick", "1", CVAR_ARCHIVE }, { NULL, "vote_limit", "5", CVAR_ARCHIVE }, { NULL, "vote_percent", "50", CVAR_ARCHIVE }, // OSP //{ NULL, "ui_creatingprofile", "", CVAR_ARCHIVE }, { NULL, "ui_r_mode", "", CVAR_ARCHIVE }, { NULL, "ui_r_gamma", "", CVAR_ARCHIVE }, { NULL, "ui_rate", "", CVAR_ARCHIVE }, { NULL, "ui_handedness", "", CVAR_ARCHIVE }, { NULL, "ui_sensitivity", "", CVAR_ARCHIVE }, { NULL, "ui_profile_mousePitch", "", CVAR_ARCHIVE }, { &cl_bypassMouseInput, "cl_bypassMouseInput", "0", CVAR_TEMP }, { NULL, "g_oldCampaign", "", CVAR_ROM, }, { NULL, "g_currentCampaign", "", CVAR_WOLFINFO | CVAR_ROM, }, { NULL, "g_currentCampaignMap", "0", CVAR_WOLFINFO | CVAR_ROM, }, { NULL, "ui_showtooltips", "1", CVAR_ARCHIVE }, //bani { &ui_autoredirect, "ui_autoredirect", "0", CVAR_ARCHIVE }, }; int cvarTableSize = sizeof( cvarTable ) / sizeof( cvarTable[0] ); /* ================= UI_RegisterCvars ================= */ void UI_RegisterCvars( void ) { int i; cvarTable_t *cv; for ( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ ) { trap_Cvar_Register( cv->vmCvar, cv->cvarName, cv->defaultString, cv->cvarFlags ); if ( cv->vmCvar != NULL ) { cv->modificationCount = cv->vmCvar->modificationCount; } } // OSP - Always force this to 0 on init trap_Cvar_Set( "ui_blackout", "0" ); BG_setCrosshair( cg_crosshairColor.string, uiInfo.xhairColor, cg_crosshairAlpha.value, "cg_crosshairColor" ); BG_setCrosshair( cg_crosshairColorAlt.string, uiInfo.xhairColorAlt, cg_crosshairAlphaAlt.value, "cg_crosshairColorAlt" ); } /* ================= UI_UpdateCvars ================= */ void UI_UpdateCvars( void ) { int i; cvarTable_t *cv; for ( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ ) { if ( cv->vmCvar ) { trap_Cvar_Update( cv->vmCvar ); if ( cv->modificationCount != cv->vmCvar->modificationCount ) { cv->modificationCount = cv->vmCvar->modificationCount; // OSP if ( cv->vmCvar == &cg_crosshairColor || cv->vmCvar == &cg_crosshairAlpha ) { BG_setCrosshair( cg_crosshairColor.string, uiInfo.xhairColor, cg_crosshairAlpha.value, "cg_crosshairColor" ); } if ( cv->vmCvar == &cg_crosshairColorAlt || cv->vmCvar == &cg_crosshairAlphaAlt ) { BG_setCrosshair( cg_crosshairColorAlt.string, uiInfo.xhairColorAlt, cg_crosshairAlphaAlt.value, "cg_crosshairColorAlt" ); } } } } } // NERVE - SMF /* ================= ArenaServers_StopRefresh ================= */ static void UI_StopServerRefresh( 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 ) { // TTimo - used to be about cl_maxping filtering, that was Q3 legacy, RTCW browser has much more filtering options Com_Printf( "%d servers not listed (filtered out by game browser settings)\n", count - uiInfo.serverStatus.numDisplayServers ); } } /* ================= UI_DoServerRefresh ================= */ static void UI_DoServerRefresh( void ) { 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; } } } if ( uiInfo.uiDC.realTime < uiInfo.serverStatus.refreshtime ) { if ( wait ) { return; } } // 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_StartServerRefresh ================= */ static void UI_StartServerRefresh( qboolean full ) { char *ptr; char buff[64]; qtime_t q; trap_RealTime( &q ); Com_sprintf( buff, sizeof( buff ), "%s-%i, %i at %s:%s", MonthAbbrev[q.tm_mon],q.tm_mday, 1900 + q.tm_year,q.tm_hour < 10 ? va( "0%i",q.tm_hour ) : va( "%i",q.tm_hour ), q.tm_min < 10 ? va( "0%i",q.tm_min ) : va( "%i",q.tm_min ) ); trap_Cvar_Set( va( "ui_lastServerRefresh_%i", ui_netSource.integer ), buff ); 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_APPEND, "localservers\n" ); uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 1000; return; } uiInfo.serverStatus.refreshtime = uiInfo.uiDC.realTime + 5000; if ( ui_netSource.integer == AS_GLOBAL ) { ptr = UI_Cvar_VariableString( "debug_protocol" ); if ( *ptr ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "globalservers %d %s\n", 0, ptr ) ); } else { trap_Cmd_ExecuteText( EXEC_APPEND, va( "globalservers %d %d\n", 0, (int)trap_Cvar_VariableValue( "protocol" ) ) ); } } } // -NERVE - SMF void UI_Campaign_f( void ) { char str[MAX_TOKEN_CHARS]; int i; campaignInfo_t *campaign = NULL; UI_LoadArenas(); UI_MapCountByGameType( qfalse ); UI_LoadCampaigns(); // find the campaign trap_Argv( 1, str, sizeof( str ) ); for ( i = 0; i < uiInfo.campaignCount; i++ ) { campaign = &uiInfo.campaignList[i]; if ( !Q_stricmp( campaign->campaignShortName, str ) ) { break; } } if ( i == uiInfo.campaignCount || !( campaign->typeBits & ( 1 << GT_WOLF ) ) ) { Com_Printf( "Can't find campaign '%s'\n", str ); return; } if ( !campaign->mapInfos[0] ) { Com_Printf( "Corrupted campaign '%s'\n", str ); return; } trap_Cvar_Set( "g_oldCampaign", "" ); trap_Cvar_Set( "g_currentCampaign", campaign->campaignShortName ); trap_Cvar_Set( "g_currentCampaignMap", "0" ); // we got a campaign, start it trap_Cvar_Set( "g_gametype", va( "%i", GT_WOLF_CAMPAIGN ) ); #if 0 if ( trap_Cvar_VariableValue( "developer" ) ) { trap_Cmd_ExecuteText( EXEC_APPEND, va( "devmap %s\n", campaign->mapInfos[0]->mapLoadName ) ); } else #endif trap_Cmd_ExecuteText( EXEC_APPEND, va( "map %s\n", campaign->mapInfos[0]->mapLoadName ) ); } void UI_ListCampaigns_f( void ) { int i, mpCampaigns; UI_LoadArenas(); UI_MapCountByGameType( qfalse ); UI_LoadCampaigns(); mpCampaigns = 0; for ( i = 0; i < uiInfo.campaignCount; i++ ) { if ( uiInfo.campaignList[i].typeBits & ( 1 << GT_WOLF ) ) { mpCampaigns++; } } if ( mpCampaigns ) { Com_Printf( "%i campaigns found:\n", mpCampaigns ); } else { Com_Printf( "No campaigns found.\n" ); return; } for ( i = 0; i < uiInfo.campaignCount; i++ ) { if ( uiInfo.campaignList[i].typeBits & ( 1 << GT_WOLF ) ) { Com_Printf( " %s\n", uiInfo.campaignList[i].campaignShortName ); } } }